[feature] Allowed custom root accounts in Chart of Accounts

This commit is contained in:
Nabin Hait 2015-11-30 17:53:08 +05:30
parent 3617942ff7
commit 8c4e043747
4 changed files with 46 additions and 14 deletions

View File

@ -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")):

View File

@ -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,

View File

@ -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)

View File

@ -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