feat: sync account created for a group company to all its descendants
diff --git a/erpnext/accounts/doctype/account/account.py b/erpnext/accounts/doctype/account/account.py
index d699146..dea82d8 100644
--- a/erpnext/accounts/doctype/account/account.py
+++ b/erpnext/accounts/doctype/account/account.py
@@ -5,7 +5,7 @@
import frappe
from frappe.utils import cint, cstr
from frappe import throw, _
-from frappe.utils.nestedset import NestedSet
+from frappe.utils.nestedset import NestedSet, get_ancestors_of, get_descendants_of
class RootNotEditable(frappe.ValidationError): pass
class BalanceMismatchError(frappe.ValidationError): pass
@@ -34,7 +34,6 @@
return
self.validate_parent()
self.validate_root_details()
- self.validate_root_company()
validate_field_number("Account", self.name, self.account_number, self.company, "account_number")
self.validate_group_or_ledger()
self.set_root_and_report_type()
@@ -42,6 +41,7 @@
self.validate_frozen_accounts_modifier()
self.validate_balance_must_be_debit_or_credit()
self.validate_account_currency()
+ self.validate_root_company_and_sync_account_to_children()
def validate_parent(self):
"""Fetch Parent Details and validate parent account"""
@@ -91,12 +91,30 @@
if not self.parent_account and not self.is_group:
frappe.throw(_("Root Account must be a group"))
- def validate_root_company(self):
- # fetch all ancestors in top-down hierarchy
- if frappe.local.flags.ignore_root_company_validation: return
+ def validate_root_company_and_sync_account_to_children(self):
+ # ignore validation while creating new compnay or while syncing to child companies
+ if frappe.local.flags.ignore_root_company_validation or self.flags.ignore_root_company_validation:
+ return
+
ancestors = get_root_company(self.company)
if ancestors:
frappe.throw(_("Please add the account to root level Company - %s" % ancestors[0]))
+ else:
+ descendants = get_descendants_of('Company', self.company)
+ acc_name = frappe.db.get_value('Account', self.parent_account, "account_name")
+
+ acc_name_map = {}
+ for d in frappe.db.get_values('Account',
+ {"company": ["in", descendants], "account_name": acc_name},
+ ["company", "name"], as_dict=True):
+ acc_name_map[d["company"]] = d["name"]
+
+ for company in descendants:
+ doc = frappe.copy_doc(self)
+ doc.flags.ignore_root_company_validation = True
+ doc.update({"company": company, "account_currency": None,
+ "parent": acc_name_map[company], "parent_account": acc_name_map[company]})
+ doc.save()
def validate_group_or_ledger(self):
if self.get("__islocal"):
@@ -262,5 +280,5 @@
@frappe.whitelist()
def get_root_company(company):
# return the topmost company in the hierarchy
- ancestors = frappe.utils.nestedset.get_ancestors_of('Company', company, "lft asc")
+ ancestors = get_ancestors_of('Company', company, "lft asc")
return [ancestors[0]] if ancestors else []