Merge pull request #7050 from nabinhait/coa_based_on_existing_company

Create Chart of Accounts based on existing company
This commit is contained in:
Nabin Hait 2016-11-24 13:28:11 +05:30 committed by GitHub
commit 3247db4827
5 changed files with 388 additions and 71 deletions

View File

@ -6,9 +6,8 @@ import frappe, os, json
from frappe.utils import cstr
from unidecode import unidecode
def create_charts(chart_name, company):
chart = get_chart(chart_name)
def create_charts(company, chart_template=None, existing_company=None):
chart = get_chart(chart_template, existing_company)
if chart:
accounts = []
@ -17,7 +16,7 @@ def create_charts(chart_name, company):
if root_account:
root_type = child.get("root_type")
if account_name not in ["account_type", "root_type", "is_group"]:
if account_name not in ["account_type", "root_type", "is_group", "tax_rate"]:
account_name_in_db = unidecode(account_name.strip().lower())
if account_name_in_db in accounts:
@ -57,16 +56,19 @@ def create_charts(chart_name, company):
def identify_is_group(child):
if child.get("is_group"):
is_group = child.get("is_group")
elif len(set(child.keys()) - set(["account_type", "root_type", "is_group"])):
elif len(set(child.keys()) - set(["account_type", "root_type", "is_group", "tax_rate"])):
is_group = 1
else:
is_group = 0
return is_group
def get_chart(chart_name):
def get_chart(chart_template, existing_company=None):
chart = {}
if chart_name == "Standard":
if existing_company:
return get_account_tree_from_existing_company(existing_company)
elif chart_template == "Standard":
from erpnext.accounts.doctype.account.chart_of_accounts.verified import standard_chart_of_accounts
return standard_chart_of_accounts.get()
else:
@ -79,7 +81,7 @@ def get_chart(chart_name):
if fname.endswith(".json"):
with open(os.path.join(path, fname), "r") as f:
chart = f.read()
if chart and json.loads(chart).get("name") == chart_name:
if chart and json.loads(chart).get("name") == chart_template:
return json.loads(chart).get("tree")
@frappe.whitelist()
@ -111,3 +113,47 @@ def get_charts_for_country(country):
charts.append("Standard")
return charts
def get_account_tree_from_existing_company(existing_company):
all_accounts = frappe.get_all('Account',
filters={'company': existing_company},
fields = ["name", "account_name", "parent_account", "account_type",
"is_group", "root_type", "tax_rate"],
order_by="lft, rgt")
account_tree = {}
# fill in tree starting with root accounts (those with no parent)
build_account_tree(account_tree, None, all_accounts)
return account_tree
def build_account_tree(tree, parent, all_accounts):
# find children
parent_account = parent.name if parent else None
children = [acc for acc in all_accounts if acc.parent_account == parent_account]
# if no children, but a group account
if not children and parent.is_group:
tree["is_group"] = 1
# build a subtree for each child
for child in children:
if child.account_type == "Stock" and not child.is_group:
tree["is_group"] = 1
continue
# start new subtree
tree[child.account_name] = {}
# assign account_type and root_type
if child.account_type:
tree[child.account_name]["account_type"] = child.account_type
if child.tax_rate:
tree[child.account_name]["tax_rate"] = child.tax_rate
if not parent:
tree[child.account_name]["root_type"] = child.root_type
# call recursively to build a subtree for current account
build_account_tree(tree[child.account_name], child, all_accounts)

File diff suppressed because it is too large Load Diff

View File

@ -30,6 +30,7 @@ class Company(Document):
self.validate_abbr()
self.validate_default_accounts()
self.validate_currency()
self.validate_coa_input()
def validate_abbr(self):
if not self.abbr:
@ -113,17 +114,26 @@ class Company(Document):
warehouse.insert()
def create_default_accounts(self):
if not self.chart_of_accounts:
self.chart_of_accounts = "Standard"
from erpnext.accounts.doctype.account.chart_of_accounts.chart_of_accounts import create_charts
create_charts(self.chart_of_accounts, self.name)
create_charts(self.name, self.chart_of_accounts, self.existing_company)
frappe.db.set(self, "default_receivable_account", frappe.db.get_value("Account",
{"company": self.name, "account_type": "Receivable", "is_group": 0}))
frappe.db.set(self, "default_payable_account", frappe.db.get_value("Account",
{"company": self.name, "account_type": "Payable", "is_group": 0}))
def validate_coa_input(self):
if self.create_chart_of_accounts_based_on == "Existing Company":
self.chart_of_accounts = None
if not self.existing_company:
frappe.throw(_("Please select Existing Company for creating Chart of Accounts"))
else:
self.existing_company = None
self.create_chart_of_accounts_based_on = "Standard Template"
if not self.chart_of_accounts:
self.chart_of_accounts = "Standard"
def set_default_accounts(self):
self._set_default_account("default_cash_account", "Cash")
self._set_default_account("default_bank_account", "Bank")

View File

@ -7,8 +7,40 @@ test_ignore = ["Account", "Cost Center"]
import frappe
import unittest
class TestCompany(unittest.TestCase):
pass
test_records = frappe.get_test_records('Company')
class TestCompany(unittest.TestCase):
def test_coa_based_on_existing_company(self):
make_company()
expected_results = {
"Debtors - CFEC": {
"account_type": "Receivable",
"is_group": 0,
"root_type": "Asset",
"parent_account": "Accounts Receivable - CFEC",
},
"_Test Cash - CFEC": {
"account_type": "Cash",
"is_group": 0,
"root_type": "Asset",
"parent_account": "Cash In Hand - CFEC"
}
}
for account, acc_property in expected_results.items():
acc = frappe.get_doc("Account", account)
for prop, val in acc_property.items():
self.assertEqual(acc.get(prop), val)
def make_company():
company = frappe.new_doc("Company")
company.company_name = "COA from Existing Company"
company.abbr = "CFEC"
company.default_currency = "INR"
company.create_chart_of_accounts_based_on = "Existing Company"
company.existing_company = "_Test Company"
company.save()

View File

@ -88,6 +88,7 @@ def create_fiscal_year_and_company(args):
'abbr':args.get('company_abbr'),
'default_currency':args.get('currency'),
'country': args.get('country'),
'create_chart_of_accounts_based_on': 'Standard Template',
'chart_of_accounts': args.get(('chart_of_accounts')),
'domain': args.get('domain')
}).insert()