From 7231f29e78f9b8787ee9d1a2ddb3ce20cc6c83ef Mon Sep 17 00:00:00 2001 From: Rushabh Mehta Date: Thu, 13 Jul 2017 15:00:56 +0530 Subject: [PATCH 1/3] [feature] override a function regionally by adding a decorator --- erpnext/__init__.py | 27 +++++++++++++++++++++++++++ erpnext/hooks.py | 7 ++++++- erpnext/regional/india/utils.py | 5 +++++ 3 files changed, 38 insertions(+), 1 deletion(-) diff --git a/erpnext/__init__.py b/erpnext/__init__.py index 5a368384e6..1558bcd483 100644 --- a/erpnext/__init__.py +++ b/erpnext/__init__.py @@ -1,6 +1,8 @@ # -*- coding: utf-8 -*- from __future__ import unicode_literals +import inspect import frappe +from erpnext.hooks import regional_overrides __version__ = '8.3.6' @@ -65,3 +67,28 @@ def is_perpetual_inventory_enabled(company): company, "enable_perpetual_inventory") or 0 return frappe.local.enable_perpetual_inventory[company] + +def get_region(company=None): + '''Return the default country based on flag, company or global settings + + You can also set global company flag in `frappe.flags.company` + ''' + if company or frappe.flags.company: + return frappe.db.get_value('Company', + company or frappe.flags.company, 'country') + elif frappe.flags.country: + return frappe.flags.country + else: + return frappe.get_system_settings('country') + +def regional(fn): + def caller(*args, **kwargs): + region = get_region() + fn_name = inspect.getmodule(fn).__name__ + '.' + fn.__name__ + if region in regional_overrides and fn_name in regional_overrides[region]: + return frappe.get_attr(regional_overrides[region][fn_name])(*args, **kwargs) + else: + return fn(*args, **kwargs) + + return caller + diff --git a/erpnext/hooks.py b/erpnext/hooks.py index 0966485cfe..6777a71694 100644 --- a/erpnext/hooks.py +++ b/erpnext/hooks.py @@ -1,6 +1,5 @@ from __future__ import unicode_literals from frappe import _ -from . import __version__ as app_version app_name = "erpnext" app_title = "ERPNext" @@ -211,3 +210,9 @@ bot_parsers = [ get_site_info = 'erpnext.utilities.get_site_info' payment_gateway_enabled = "erpnext.accounts.utils.create_payment_gateway_account" + +regional_overrides = { + 'India': { + 'erpnext.tests.test_regional.test_method': 'erpnext.regional.india.utils.test_method' + } +} diff --git a/erpnext/regional/india/utils.py b/erpnext/regional/india/utils.py index 84e5f3ea50..437465a6a2 100644 --- a/erpnext/regional/india/utils.py +++ b/erpnext/regional/india/utils.py @@ -22,3 +22,8 @@ def validate_gstin_for_india(doc, method): if doc.gstin != "NA" and doc.gst_state_number != doc.gstin[:2]: frappe.throw(_("First 2 digits of GSTIN should match with State number {0}") .format(doc.gst_state_number)) + +# don't remove this function it is used in tests +def test_method(): + '''test function''' + return 'overridden' \ No newline at end of file From 8f2e21def28b126a10762da1667db4863d50b43a Mon Sep 17 00:00:00 2001 From: Rushabh Mehta Date: Thu, 13 Jul 2017 15:07:51 +0530 Subject: [PATCH 2/3] [feature] override a function regionally by adding a decorator --- erpnext/tests/test_regional.py | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 erpnext/tests/test_regional.py diff --git a/erpnext/tests/test_regional.py b/erpnext/tests/test_regional.py new file mode 100644 index 0000000000..d2c96201a9 --- /dev/null +++ b/erpnext/tests/test_regional.py @@ -0,0 +1,13 @@ +import unittest, frappe, erpnext + +@erpnext.regional +def test_method(): + return 'original' + +class TestInit(unittest.TestCase): + def test_regional_overrides(self): + frappe.flags.country = 'India' + self.assertEqual(test_method(), 'overridden') + + frappe.flags.country = 'Nepal' + self.assertEqual(test_method(), 'original') \ No newline at end of file From 393becce0ba0d121d9f6a0f39d2654c5afd1c805 Mon Sep 17 00:00:00 2001 From: Rushabh Mehta Date: Thu, 13 Jul 2017 15:49:37 +0530 Subject: [PATCH 3/3] [fix] name decorator as allow_regional --- erpnext/__init__.py | 8 +++++++- erpnext/tests/test_regional.py | 2 +- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/erpnext/__init__.py b/erpnext/__init__.py index 1558bcd483..206399c276 100644 --- a/erpnext/__init__.py +++ b/erpnext/__init__.py @@ -81,7 +81,13 @@ def get_region(company=None): else: return frappe.get_system_settings('country') -def regional(fn): +def allow_regional(fn): + '''Decorator to make a function regionally overridable + + Example: + @erpnext.allow_regional + def myfunction(): + pass''' def caller(*args, **kwargs): region = get_region() fn_name = inspect.getmodule(fn).__name__ + '.' + fn.__name__ diff --git a/erpnext/tests/test_regional.py b/erpnext/tests/test_regional.py index d2c96201a9..5d9628f64e 100644 --- a/erpnext/tests/test_regional.py +++ b/erpnext/tests/test_regional.py @@ -1,6 +1,6 @@ import unittest, frappe, erpnext -@erpnext.regional +@erpnext.allow_regional def test_method(): return 'original'