Create Chart of Accounts based on existing company
This commit is contained in:
parent
c097a4fe68
commit
e0089184e6
@ -6,9 +6,8 @@ import frappe, os, json
|
|||||||
from frappe.utils import cstr
|
from frappe.utils import cstr
|
||||||
from unidecode import unidecode
|
from unidecode import unidecode
|
||||||
|
|
||||||
def create_charts(chart_name, company):
|
def create_charts(company, chart_template=None, existing_company=None):
|
||||||
chart = get_chart(chart_name)
|
chart = get_chart(chart_template, existing_company)
|
||||||
|
|
||||||
if chart:
|
if chart:
|
||||||
accounts = []
|
accounts = []
|
||||||
|
|
||||||
@ -17,7 +16,7 @@ def create_charts(chart_name, company):
|
|||||||
if root_account:
|
if root_account:
|
||||||
root_type = child.get("root_type")
|
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())
|
account_name_in_db = unidecode(account_name.strip().lower())
|
||||||
if account_name_in_db in accounts:
|
if account_name_in_db in accounts:
|
||||||
@ -57,21 +56,21 @@ def create_charts(chart_name, company):
|
|||||||
def identify_is_group(child):
|
def identify_is_group(child):
|
||||||
if child.get("is_group"):
|
if child.get("is_group"):
|
||||||
is_group = 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
|
is_group = 1
|
||||||
else:
|
else:
|
||||||
is_group = 0
|
is_group = 0
|
||||||
|
|
||||||
return is_group
|
return is_group
|
||||||
|
|
||||||
def get_chart(chart_name):
|
def get_chart(chart_template, existing_company=None):
|
||||||
chart = {}
|
chart = {}
|
||||||
if chart_name == "Standard Template":
|
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
|
from erpnext.accounts.doctype.account.chart_of_accounts.verified import standard_chart_of_accounts
|
||||||
return standard_chart_of_accounts.get()
|
return standard_chart_of_accounts.get()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
else:
|
else:
|
||||||
folders = ("verified",)
|
folders = ("verified",)
|
||||||
if frappe.local.flags.allow_unverified_charts:
|
if frappe.local.flags.allow_unverified_charts:
|
||||||
@ -82,7 +81,7 @@ def get_chart(chart_name):
|
|||||||
if fname.endswith(".json"):
|
if fname.endswith(".json"):
|
||||||
with open(os.path.join(path, fname), "r") as f:
|
with open(os.path.join(path, fname), "r") as f:
|
||||||
chart = f.read()
|
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")
|
return json.loads(chart).get("tree")
|
||||||
|
|
||||||
@frappe.whitelist()
|
@frappe.whitelist()
|
||||||
@ -114,3 +113,47 @@ def get_charts_for_country(country):
|
|||||||
charts.append("Standard")
|
charts.append("Standard")
|
||||||
|
|
||||||
return charts
|
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)
|
@ -294,6 +294,34 @@
|
|||||||
"set_only_once": 0,
|
"set_only_once": 0,
|
||||||
"unique": 0
|
"unique": 0
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"allow_on_submit": 0,
|
||||||
|
"bold": 0,
|
||||||
|
"collapsible": 0,
|
||||||
|
"columns": 0,
|
||||||
|
"fieldname": "default_currency",
|
||||||
|
"fieldtype": "Link",
|
||||||
|
"hidden": 0,
|
||||||
|
"ignore_user_permissions": 1,
|
||||||
|
"ignore_xss_filter": 0,
|
||||||
|
"in_filter": 0,
|
||||||
|
"in_list_view": 0,
|
||||||
|
"in_standard_filter": 0,
|
||||||
|
"label": "Default Currency",
|
||||||
|
"length": 0,
|
||||||
|
"no_copy": 0,
|
||||||
|
"options": "Currency",
|
||||||
|
"permlevel": 0,
|
||||||
|
"print_hide": 0,
|
||||||
|
"print_hide_if_no_value": 0,
|
||||||
|
"read_only": 0,
|
||||||
|
"remember_last_selected_value": 0,
|
||||||
|
"report_hide": 0,
|
||||||
|
"reqd": 1,
|
||||||
|
"search_index": 0,
|
||||||
|
"set_only_once": 0,
|
||||||
|
"unique": 0
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"allow_on_submit": 0,
|
"allow_on_submit": 0,
|
||||||
"bold": 0,
|
"bold": 0,
|
||||||
@ -349,61 +377,6 @@
|
|||||||
"set_only_once": 0,
|
"set_only_once": 0,
|
||||||
"unique": 0
|
"unique": 0
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"allow_on_submit": 0,
|
|
||||||
"bold": 0,
|
|
||||||
"collapsible": 0,
|
|
||||||
"columns": 0,
|
|
||||||
"fieldname": "default_currency",
|
|
||||||
"fieldtype": "Link",
|
|
||||||
"hidden": 0,
|
|
||||||
"ignore_user_permissions": 1,
|
|
||||||
"ignore_xss_filter": 0,
|
|
||||||
"in_filter": 0,
|
|
||||||
"in_list_view": 0,
|
|
||||||
"in_standard_filter": 0,
|
|
||||||
"label": "Default Currency",
|
|
||||||
"length": 0,
|
|
||||||
"no_copy": 0,
|
|
||||||
"options": "Currency",
|
|
||||||
"permlevel": 0,
|
|
||||||
"print_hide": 0,
|
|
||||||
"print_hide_if_no_value": 0,
|
|
||||||
"read_only": 0,
|
|
||||||
"remember_last_selected_value": 0,
|
|
||||||
"report_hide": 0,
|
|
||||||
"reqd": 1,
|
|
||||||
"search_index": 0,
|
|
||||||
"set_only_once": 0,
|
|
||||||
"unique": 0
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"allow_on_submit": 0,
|
|
||||||
"bold": 0,
|
|
||||||
"collapsible": 0,
|
|
||||||
"columns": 0,
|
|
||||||
"fieldname": "column_break_14",
|
|
||||||
"fieldtype": "Column Break",
|
|
||||||
"hidden": 0,
|
|
||||||
"ignore_user_permissions": 0,
|
|
||||||
"ignore_xss_filter": 0,
|
|
||||||
"in_filter": 0,
|
|
||||||
"in_list_view": 0,
|
|
||||||
"in_standard_filter": 0,
|
|
||||||
"length": 0,
|
|
||||||
"no_copy": 0,
|
|
||||||
"permlevel": 0,
|
|
||||||
"precision": "",
|
|
||||||
"print_hide": 0,
|
|
||||||
"print_hide_if_no_value": 0,
|
|
||||||
"read_only": 0,
|
|
||||||
"remember_last_selected_value": 0,
|
|
||||||
"report_hide": 0,
|
|
||||||
"reqd": 0,
|
|
||||||
"search_index": 0,
|
|
||||||
"set_only_once": 0,
|
|
||||||
"unique": 0
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"allow_on_submit": 0,
|
"allow_on_submit": 0,
|
||||||
"bold": 0,
|
"bold": 0,
|
||||||
@ -449,7 +422,7 @@
|
|||||||
"in_standard_filter": 0,
|
"in_standard_filter": 0,
|
||||||
"label": "Chart Of Accounts Template",
|
"label": "Chart Of Accounts Template",
|
||||||
"length": 0,
|
"length": 0,
|
||||||
"no_copy": 0,
|
"no_copy": 1,
|
||||||
"options": "",
|
"options": "",
|
||||||
"permlevel": 0,
|
"permlevel": 0,
|
||||||
"precision": "",
|
"precision": "",
|
||||||
@ -479,7 +452,7 @@
|
|||||||
"in_standard_filter": 0,
|
"in_standard_filter": 0,
|
||||||
"label": "Existing Company ",
|
"label": "Existing Company ",
|
||||||
"length": 0,
|
"length": 0,
|
||||||
"no_copy": 0,
|
"no_copy": 1,
|
||||||
"options": "Company",
|
"options": "Company",
|
||||||
"permlevel": 0,
|
"permlevel": 0,
|
||||||
"precision": "",
|
"precision": "",
|
||||||
@ -1633,7 +1606,7 @@
|
|||||||
"istable": 0,
|
"istable": 0,
|
||||||
"max_attachments": 0,
|
"max_attachments": 0,
|
||||||
"menu_index": 0,
|
"menu_index": 0,
|
||||||
"modified": "2016-11-22 04:14:51.319655",
|
"modified": "2016-11-23 16:32:04.893315",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Setup",
|
"module": "Setup",
|
||||||
"name": "Company",
|
"name": "Company",
|
||||||
|
@ -30,6 +30,7 @@ class Company(Document):
|
|||||||
self.validate_abbr()
|
self.validate_abbr()
|
||||||
self.validate_default_accounts()
|
self.validate_default_accounts()
|
||||||
self.validate_currency()
|
self.validate_currency()
|
||||||
|
self.validate_coa_input()
|
||||||
|
|
||||||
def validate_abbr(self):
|
def validate_abbr(self):
|
||||||
if not self.abbr:
|
if not self.abbr:
|
||||||
@ -113,17 +114,26 @@ class Company(Document):
|
|||||||
warehouse.insert()
|
warehouse.insert()
|
||||||
|
|
||||||
def create_default_accounts(self):
|
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
|
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",
|
frappe.db.set(self, "default_receivable_account", frappe.db.get_value("Account",
|
||||||
{"company": self.name, "account_type": "Receivable", "is_group": 0}))
|
{"company": self.name, "account_type": "Receivable", "is_group": 0}))
|
||||||
frappe.db.set(self, "default_payable_account", frappe.db.get_value("Account",
|
frappe.db.set(self, "default_payable_account", frappe.db.get_value("Account",
|
||||||
{"company": self.name, "account_type": "Payable", "is_group": 0}))
|
{"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):
|
def set_default_accounts(self):
|
||||||
self._set_default_account("default_cash_account", "Cash")
|
self._set_default_account("default_cash_account", "Cash")
|
||||||
self._set_default_account("default_bank_account", "Bank")
|
self._set_default_account("default_bank_account", "Bank")
|
||||||
|
@ -7,8 +7,40 @@ test_ignore = ["Account", "Cost Center"]
|
|||||||
import frappe
|
import frappe
|
||||||
import unittest
|
import unittest
|
||||||
|
|
||||||
class TestCompany(unittest.TestCase):
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
test_records = frappe.get_test_records('Company')
|
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()
|
||||||
|
|
||||||
|
|
||||||
|
@ -88,6 +88,7 @@ def create_fiscal_year_and_company(args):
|
|||||||
'abbr':args.get('company_abbr'),
|
'abbr':args.get('company_abbr'),
|
||||||
'default_currency':args.get('currency'),
|
'default_currency':args.get('currency'),
|
||||||
'country': args.get('country'),
|
'country': args.get('country'),
|
||||||
|
'create_chart_of_accounts_based_on': 'Standard Template',
|
||||||
'chart_of_accounts': args.get(('chart_of_accounts')),
|
'chart_of_accounts': args.get(('chart_of_accounts')),
|
||||||
'domain': args.get('domain')
|
'domain': args.get('domain')
|
||||||
}).insert()
|
}).insert()
|
||||||
|
Loading…
x
Reference in New Issue
Block a user