fix: Check if account exists in parent company on rename
- Check if child company is dependent on parent company
- Check if account-to-be-renamed exists in parent, if yes, block
- Revised Test basd on the same
diff --git a/erpnext/accounts/doctype/account/account.py b/erpnext/accounts/doctype/account/account.py
index 0a88893..2c15144 100644
--- a/erpnext/accounts/doctype/account/account.py
+++ b/erpnext/accounts/doctype/account/account.py
@@ -118,27 +118,7 @@
for d in frappe.db.get_values('Account', filters=filters, fieldname=["company", "name"], as_dict=True):
parent_acc_name_map[d["company"]] = d["name"]
- if not parent_acc_name_map:
- # map can be empty if only one descendant or all descendants without parent account exist(s)
- # or if no descendants exist
- if descendants:
- frappe.throw(_("Parent Account {0} does not exist in any Child Company").format(frappe.bold(parent_acc_name)),
- title=_("Account Missing"))
- else:
- # no descendants and empty map, nothing to sync
- return
-
- companies_missing_account = []
- for company in descendants:
- if not company in parent_acc_name_map:
- companies_missing_account.append(company)
-
- # If atleast any one of the descendants does not have the parent account, block transaction
- if companies_missing_account:
- message = _("Parent Account {0} does not exist in the following companies:").format(frappe.bold(parent_acc_name))
- message += "<br><br><ul><li>" + "</li><li>".join(companies_missing_account) + "</li></ul>"
- message += _("Please make sure the account exists in the child companies as well")
- frappe.throw(message, title=_("Account Missing"))
+ if not parent_acc_name_map: return
self.create_account_for_child_company(parent_acc_name_map, descendants, parent_acc_name)
@@ -318,6 +298,23 @@
old_acc_name, old_acc_number = frappe.db.get_value('Account', name, \
["account_name", "account_number"])
+ # check if account exists in parent company
+ ancestors = get_ancestors_of("Company", account.company)
+ allow_independent_account_creation = frappe.get_value("Company", account.company, "allow_account_creation_against_child_company")
+
+ if ancestors and not allow_independent_account_creation:
+ for ancestor in ancestors:
+ if frappe.db.get_value("Account", {'account_name': old_acc_name, 'company': ancestor}, 'name'):
+ # same account in parent company exists
+ allow_child_account_creation = _("Allow Account Creation Against Child Company")
+
+ message = _("Account {0} exists in parent company {1}.").format(frappe.bold(old_acc_name), frappe.bold(ancestor))
+ message += "<br>" + _("Renaming it is only allowed via parent company {0}, \
+ to avoid mismatch.").format(frappe.bold(ancestor)) + "<br><br>"
+ message += _("To overrule this, enable '{0}' in company {1}").format(allow_child_account_creation, frappe.bold(account.company))
+
+ frappe.throw(message, title=_("Rename Not Allowed"))
+
validate_account_number(name, account_number, account.company)
if account_number:
frappe.db.set_value("Account", name, "account_number", account_number.strip())
diff --git a/erpnext/accounts/doctype/account/test_account.py b/erpnext/accounts/doctype/account/test_account.py
index 6819081..b6a950b 100644
--- a/erpnext/accounts/doctype/account/test_account.py
+++ b/erpnext/accounts/doctype/account/test_account.py
@@ -123,7 +123,7 @@
# Rename account in parent company
update_account_number(acc.name, "Test Rename Sync Account", "1234")
- # Check if renmamed in children
+ # Check if renamed in children
self.assertTrue(frappe.db.exists("Account", {'account_name': "Test Rename Sync Account", "company": "_Test Company 4", "account_number": "1234"}))
self.assertTrue(frappe.db.exists("Account", {'account_name': "Test Rename Sync Account", "company": "_Test Company 5", "account_number": "1234"}))
@@ -131,7 +131,7 @@
frappe.delete_doc("Account", "1234 - Test Rename Sync Account - _TC4")
frappe.delete_doc("Account", "1234 - Test Rename Sync Account - _TC5")
- def test_account_sync_with_missing_parent_account_in_child_company(self):
+ def test_child_company_account_rename_sync(self):
frappe.local.flags.pop("ignore_root_company_validation", None)
acc = frappe.new_doc("Account")
@@ -144,20 +144,19 @@
self.assertTrue(frappe.db.exists("Account", {'account_name': "Test Group Account", "company": "_Test Company 4"}))
self.assertTrue(frappe.db.exists("Account", {'account_name': "Test Group Account", "company": "_Test Company 5"}))
+ # Try renaming child company account
acc_tc_5 = frappe.db.get_value('Account', {'account_name': "Test Group Account", "company": "_Test Company 5"})
- # Rename group account in one child company
+ self.assertRaises(frappe.ValidationError, update_account_number, acc_tc_5, "Test Modified Account")
+
+ # Rename child company account with allow_account_creation_against_child_company enabled
+ frappe.db.set_value("Company", "_Test Company 5", "allow_account_creation_against_child_company", 1)
+
update_account_number(acc_tc_5, "Test Modified Account")
+ self.assertTrue(frappe.db.exists("Account", {'name': "Test Modified Account - _TC5", "company": "_Test Company 5"}))
- # Add child account to test group account in parent company
- # which will try to do the same in child company
- acc = frappe.new_doc("Account")
- acc.account_name = "Test Child Account"
- acc.parent_account = "Test Group Account - _TC3"
- acc.company = "_Test Company 3"
+ frappe.db.set_value("Company", "_Test Company 5", "allow_account_creation_against_child_company", 0)
- self.assertRaises(frappe.ValidationError, acc.insert)
-
- to_delete = ["Test Group Account - _TC3", "Test Group Account - _TC5", "Test Modified Account - _TC5"]
+ to_delete = ["Test Group Account - _TC3", "Test Group Account - _TC4", "Test Modified Account - _TC5"]
for doc in to_delete:
frappe.delete_doc("Account", doc)