Merge pull request #9839 from rmehta/regional-decorators
[feature] override a function regionally by adding a decorator
diff --git a/erpnext/__init__.py b/erpnext/__init__.py
index ef9b89c..0761c1e 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.4.2'
@@ -65,3 +67,34 @@
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 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__
+ 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 0966485..6777a71 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 @@
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 84e5f3e..437465a 100644
--- a/erpnext/regional/india/utils.py
+++ b/erpnext/regional/india/utils.py
@@ -22,3 +22,8 @@
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
diff --git a/erpnext/tests/test_regional.py b/erpnext/tests/test_regional.py
new file mode 100644
index 0000000..5d9628f
--- /dev/null
+++ b/erpnext/tests/test_regional.py
@@ -0,0 +1,13 @@
+import unittest, frappe, erpnext
+
+@erpnext.allow_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