Merge pull request #4402 from nabinhait/allow_root_accounts
[feature] Allowed custom root accounts in Chart of Accounts
This commit is contained in:
commit
37d9d6fdea
@ -65,12 +65,19 @@ class Account(Document):
|
||||
if self.root_type != db_value.root_type:
|
||||
frappe.db.sql("update `tabAccount` set root_type=%s where lft > %s and rgt < %s",
|
||||
(self.root_type, self.lft, self.rgt))
|
||||
|
||||
if self.root_type and not self.report_type:
|
||||
self.report_type = "Balance Sheet" \
|
||||
if self.root_type in ("Asset", "Liability", "Equity") else "Profit and Loss"
|
||||
|
||||
def validate_root_details(self):
|
||||
# does not exists parent
|
||||
if frappe.db.exists("Account", self.name):
|
||||
if not frappe.db.get_value("Account", self.name, "parent_account"):
|
||||
throw(_("Root cannot be edited."), RootNotEditable)
|
||||
|
||||
if not self.parent_account and not self.is_group:
|
||||
frappe.throw(_("Root Account must be a group"))
|
||||
|
||||
def validate_frozen_accounts_modifier(self):
|
||||
old_value = frappe.db.get_value("Account", self.name, "freeze_account")
|
||||
@ -127,11 +134,11 @@ class Account(Document):
|
||||
and docstatus != 2""", self.name)
|
||||
|
||||
def validate_mandatory(self):
|
||||
if not self.report_type:
|
||||
throw(_("Report Type is mandatory"))
|
||||
|
||||
if not self.root_type:
|
||||
throw(_("Root Type is mandatory"))
|
||||
|
||||
if not self.report_type:
|
||||
throw(_("Report Type is mandatory"))
|
||||
|
||||
def validate_warehouse_account(self):
|
||||
if not cint(frappe.defaults.get_global_default("auto_accounting_for_stock")):
|
||||
|
@ -117,7 +117,7 @@ erpnext.AccountsChart = Class.extend({
|
||||
}
|
||||
},
|
||||
{
|
||||
condition: function(node) { return !node.root && node.expandable; },
|
||||
condition: function(node) { return node.expandable; },
|
||||
label: __("Add Child"),
|
||||
click: function() {
|
||||
me.make_new()
|
||||
@ -208,6 +208,9 @@ erpnext.AccountsChart = Class.extend({
|
||||
description: __("Name of new Account. Note: Please don't create accounts for Customers and Suppliers")},
|
||||
{fieldtype:'Check', fieldname:'is_group', label:__('Is Group'),
|
||||
description: __('Further accounts can be made under Groups, but entries can be made against non-Groups')},
|
||||
{fieldtype:'Select', fieldname:'root_type', label:__('Root Type'),
|
||||
options: ['Asset', 'Liability', 'Equity', 'Income', 'Expense'].join('\n'),
|
||||
},
|
||||
{fieldtype:'Select', fieldname:'account_type', label:__('Account Type'),
|
||||
options: ['', 'Bank', 'Cash', 'Warehouse', 'Tax', 'Chargeable'].join('\n'),
|
||||
description: __("Optional. This setting will be used to filter in various transactions.") },
|
||||
@ -237,6 +240,9 @@ erpnext.AccountsChart = Class.extend({
|
||||
$(fd.tax_rate.wrapper).toggle(fd.account_type.get_value()==='Tax');
|
||||
$(fd.warehouse.wrapper).toggle(fd.account_type.get_value()==='Warehouse');
|
||||
})
|
||||
|
||||
// root type if root
|
||||
$(fd.root_type.wrapper).toggle(node.root);
|
||||
|
||||
// create
|
||||
d.set_primary_action(__("Create New"), function() {
|
||||
@ -252,6 +258,14 @@ erpnext.AccountsChart = Class.extend({
|
||||
var node = me.tree.get_selected_node();
|
||||
v.parent_account = node.label;
|
||||
v.company = me.company;
|
||||
|
||||
if(node.root) {
|
||||
v.is_root = true;
|
||||
v.parent_account = null;
|
||||
} else {
|
||||
v.is_root = false;
|
||||
v.root_type = null;
|
||||
}
|
||||
|
||||
return frappe.call({
|
||||
args: v,
|
||||
|
@ -80,8 +80,13 @@ def get_data(company, root_type, balance_must_be, period_list, ignore_closing_en
|
||||
return None
|
||||
|
||||
accounts, accounts_by_name = filter_accounts(accounts)
|
||||
gl_entries_by_account = get_gl_entries(company, period_list[0]["from_date"], period_list[-1]["to_date"],
|
||||
accounts[0].lft, accounts[0].rgt, ignore_closing_entries=ignore_closing_entries)
|
||||
|
||||
gl_entries_by_account = {}
|
||||
for root in frappe.db.sql("""select lft, rgt from tabAccount
|
||||
where root_type=%s and ifnull(parent_account, '') = ''""", root_type, as_dict=1):
|
||||
set_gl_entries_by_account(company, period_list[0]["from_date"],
|
||||
period_list[-1]["to_date"],root.lft, root.rgt, gl_entries_by_account,
|
||||
ignore_closing_entries=ignore_closing_entries)
|
||||
|
||||
calculate_values(accounts_by_name, gl_entries_by_account, period_list)
|
||||
accumulate_values_into_parents(accounts, accounts_by_name, period_list)
|
||||
@ -101,7 +106,6 @@ def calculate_values(accounts_by_name, gl_entries_by_account, period_list):
|
||||
if entry.posting_date <= period.to_date:
|
||||
d[period.key] = d.get(period.key, 0.0) + flt(entry.debit) - flt(entry.credit)
|
||||
|
||||
|
||||
def accumulate_values_into_parents(accounts, accounts_by_name, period_list):
|
||||
"""accumulate children's values in parent accounts"""
|
||||
for d in reversed(accounts):
|
||||
@ -143,15 +147,20 @@ def prepare_data(accounts, balance_must_be, period_list):
|
||||
return out
|
||||
|
||||
def add_total_row(out, balance_must_be, period_list):
|
||||
row = {
|
||||
total_row = {
|
||||
"account_name": "'" + _("Total ({0})").format(balance_must_be) + "'",
|
||||
"account": None
|
||||
}
|
||||
for period in period_list:
|
||||
row[period.key] = out[0].get(period.key, 0.0)
|
||||
out[0][period.key] = ""
|
||||
|
||||
for row in out:
|
||||
if not row.get("parent_account"):
|
||||
for period in period_list:
|
||||
total_row.setdefault(period.key, 0.0)
|
||||
total_row[period.key] += row.get(period.key, 0.0)
|
||||
|
||||
out.append(row)
|
||||
row[period.key] = ""
|
||||
|
||||
out.append(total_row)
|
||||
|
||||
# blank row after Total
|
||||
out.append({})
|
||||
@ -200,7 +209,8 @@ def sort_root_accounts(roots):
|
||||
|
||||
roots.sort(compare_roots)
|
||||
|
||||
def get_gl_entries(company, from_date, to_date, root_lft, root_rgt, ignore_closing_entries=False):
|
||||
def set_gl_entries_by_account(company, from_date, to_date, root_lft, root_rgt, gl_entries_by_account,
|
||||
ignore_closing_entries=False):
|
||||
"""Returns a dict like { "account": [gl entries], ... }"""
|
||||
additional_conditions = []
|
||||
|
||||
@ -226,7 +236,6 @@ def get_gl_entries(company, from_date, to_date, root_lft, root_rgt, ignore_closi
|
||||
},
|
||||
as_dict=True)
|
||||
|
||||
gl_entries_by_account = {}
|
||||
for entry in gl_entries:
|
||||
gl_entries_by_account.setdefault(entry.account, []).append(entry)
|
||||
|
||||
|
@ -134,6 +134,8 @@ def add_ac(args=None):
|
||||
ac.update(args)
|
||||
ac.old_parent = ""
|
||||
ac.freeze_account = "No"
|
||||
if ac.get("is_root"):
|
||||
ac.flags.ignore_mandatory = True
|
||||
ac.insert()
|
||||
|
||||
return ac.name
|
||||
|
Loading…
x
Reference in New Issue
Block a user