From 2dd0e20003f9da13d51ced0da5ee5c492e621230 Mon Sep 17 00:00:00 2001 From: Deepesh Garg Date: Thu, 17 Mar 2022 12:56:43 +0530 Subject: [PATCH] fix: Clean and fixes in Dimension-wise Accounts Balance Report (cherry picked from commit 08a06ce5c68023c41f53b584082b5e1c4ddb1f59) --- .../dimension_wise_accounts_balance_report.js | 5 +- .../dimension_wise_accounts_balance_report.py | 154 ++++++++---------- 2 files changed, 76 insertions(+), 83 deletions(-) diff --git a/erpnext/accounts/report/dimension_wise_accounts_balance_report/dimension_wise_accounts_balance_report.js b/erpnext/accounts/report/dimension_wise_accounts_balance_report/dimension_wise_accounts_balance_report.js index 6a0394861b..ea05a35b25 100644 --- a/erpnext/accounts/report/dimension_wise_accounts_balance_report/dimension_wise_accounts_balance_report.js +++ b/erpnext/accounts/report/dimension_wise_accounts_balance_report/dimension_wise_accounts_balance_report.js @@ -39,12 +39,14 @@ frappe.require("assets/erpnext/js/financial_statements.js", function() { "label": __("From Date"), "fieldtype": "Date", "default": frappe.defaults.get_user_default("year_start_date"), + "reqd": 1 }, { "fieldname": "to_date", "label": __("To Date"), "fieldtype": "Date", "default": frappe.defaults.get_user_default("year_end_date"), + "reqd": 1 }, { "fieldname": "finance_book", @@ -56,6 +58,7 @@ frappe.require("assets/erpnext/js/financial_statements.js", function() { "fieldname": "dimension", "label": __("Select Dimension"), "fieldtype": "Select", + "default": "Cost Center", "options": get_accounting_dimension_options(), "reqd": 1, }, @@ -70,7 +73,7 @@ frappe.require("assets/erpnext/js/financial_statements.js", function() { }); function get_accounting_dimension_options() { - let options =["", "Cost Center", "Project"]; + let options =["Cost Center", "Project"]; frappe.db.get_list('Accounting Dimension', {fields:['document_type']}).then((res) => { res.forEach((dimension) => { diff --git a/erpnext/accounts/report/dimension_wise_accounts_balance_report/dimension_wise_accounts_balance_report.py b/erpnext/accounts/report/dimension_wise_accounts_balance_report/dimension_wise_accounts_balance_report.py index d547470bf3..d39e320f3c 100644 --- a/erpnext/accounts/report/dimension_wise_accounts_balance_report/dimension_wise_accounts_balance_report.py +++ b/erpnext/accounts/report/dimension_wise_accounts_balance_report/dimension_wise_accounts_balance_report.py @@ -15,20 +15,22 @@ from erpnext.accounts.report.trial_balance.trial_balance import validate_filters def execute(filters=None): - validate_filters(filters) - dimension_items_list = get_dimension_items_list(filters.dimension, filters.company) - if not dimension_items_list: + validate_filters(filters) + dimension_list = get_dimensions(filters) + + if not dimension_list: return [], [] - dimension_items_list = [''.join(d) for d in dimension_items_list] - columns = get_columns(dimension_items_list) - data = get_data(filters, dimension_items_list) + # dimension_items_list = [''.join(d) for d in dimension_items_list] + columns = get_columns(dimension_list) + data = get_data(filters, dimension_list) return columns, data -def get_data(filters, dimension_items_list): +def get_data(filters, dimension_list): company_currency = erpnext.get_company_currency(filters.company) + acc = frappe.db.sql(""" select name, account_number, parent_account, lft, rgt, root_type, @@ -51,60 +53,54 @@ def get_data(filters, dimension_items_list): where lft >= %s and rgt <= %s and company = %s""", (min_lft, max_rgt, filters.company)) gl_entries_by_account = {} - set_gl_entries_by_account(dimension_items_list, filters, account, gl_entries_by_account) - format_gl_entries(gl_entries_by_account, accounts_by_name, dimension_items_list) - accumulate_values_into_parents(accounts, accounts_by_name, dimension_items_list) - out = prepare_data(accounts, filters, parent_children_map, company_currency, dimension_items_list) + set_gl_entries_by_account(dimension_list, filters, account, gl_entries_by_account) + format_gl_entries(gl_entries_by_account, accounts_by_name, dimension_list, + frappe.scrub(filters.get('dimension'))) + accumulate_values_into_parents(accounts, accounts_by_name, dimension_list) + out = prepare_data(accounts, filters, company_currency, dimension_list) out = filter_out_zero_value_rows(out, parent_children_map) return out -def set_gl_entries_by_account(dimension_items_list, filters, account, gl_entries_by_account): - for item in dimension_items_list: - condition = get_condition(filters.from_date, item, filters.dimension) - if account: - condition += " and account in ({})"\ - .format(", ".join([frappe.db.escape(d) for d in account])) +def set_gl_entries_by_account(dimension_list, filters, account, gl_entries_by_account): + condition = get_condition(filters.get('dimension')) - gl_filters = { - "company": filters.get("company"), - "from_date": filters.get("from_date"), - "to_date": filters.get("to_date"), - "finance_book": cstr(filters.get("finance_book")) - } + if account: + condition += " and account in ({})"\ + .format(", ".join([frappe.db.escape(d) for d in account])) - gl_filters['item'] = ''.join(item) + gl_filters = { + "company": filters.get("company"), + "from_date": filters.get("from_date"), + "to_date": filters.get("to_date"), + "finance_book": cstr(filters.get("finance_book")) + } - if filters.get("include_default_book_entries"): - gl_filters["company_fb"] = frappe.db.get_value("Company", - filters.company, 'default_finance_book') + gl_filters['dimensions'] = set(dimension_list) - for key, value in filters.items(): - if value: - gl_filters.update({ - key: value - }) + if filters.get("include_default_book_entries"): + gl_filters["company_fb"] = frappe.db.get_value("Company", + filters.company, 'default_finance_book') - gl_entries = frappe.db.sql(""" + gl_entries = frappe.db.sql(""" select - posting_date, account, debit, credit, is_opening, fiscal_year, + posting_date, account, {dimension}, debit, credit, is_opening, fiscal_year, debit_in_account_currency, credit_in_account_currency, account_currency from `tabGL Entry` where company=%(company)s {condition} + and posting_date >= %(from_date)s and posting_date <= %(to_date)s and is_cancelled = 0 order by account, posting_date""".format( - condition=condition), - gl_filters, as_dict=True) #nosec + dimension = frappe.scrub(filters.get('dimension')), condition=condition), gl_filters, as_dict=True) #nosec - for entry in gl_entries: - entry['dimension_item'] = ''.join(item) - gl_entries_by_account.setdefault(entry.account, []).append(entry) + for entry in gl_entries: + gl_entries_by_account.setdefault(entry.account, []).append(entry) -def format_gl_entries(gl_entries_by_account, accounts_by_name, dimension_items_list): +def format_gl_entries(gl_entries_by_account, accounts_by_name, dimension_list, dimension_type): for entries in gl_entries_by_account.values(): for entry in entries: @@ -114,11 +110,12 @@ def format_gl_entries(gl_entries_by_account, accounts_by_name, dimension_items_l _("Could not retrieve information for {0}.").format(entry.account), title="Error", raise_exception=1 ) - for item in dimension_items_list: - if item == entry.dimension_item: - d[frappe.scrub(item)] = d.get(frappe.scrub(item), 0.0) + flt(entry.debit) - flt(entry.credit) -def prepare_data(accounts, filters, parent_children_map, company_currency, dimension_items_list): + for dimension in dimension_list: + if dimension == entry.get(dimension_type): + d[frappe.scrub(dimension)] = d.get(frappe.scrub(dimension), 0.0) + flt(entry.debit) - flt(entry.credit) + +def prepare_data(accounts, filters, company_currency, dimension_list): data = [] for d in accounts: @@ -135,13 +132,13 @@ def prepare_data(accounts, filters, parent_children_map, company_currency, dimen if d.account_number else d.account_name) } - for item in dimension_items_list: - row[frappe.scrub(item)] = flt(d.get(frappe.scrub(item), 0.0), 3) + for dimension in dimension_list: + row[frappe.scrub(dimension)] = flt(d.get(frappe.scrub(dimension), 0.0), 3) - if abs(row[frappe.scrub(item)]) >= 0.005: + if abs(row[frappe.scrub(dimension)]) >= 0.005: # ignore zero values has_value = True - total += flt(d.get(frappe.scrub(item), 0.0), 3) + total += flt(d.get(frappe.scrub(dimension), 0.0), 3) row["has_value"] = has_value row["total"] = total @@ -149,62 +146,55 @@ def prepare_data(accounts, filters, parent_children_map, company_currency, dimen return data -def accumulate_values_into_parents(accounts, accounts_by_name, dimension_items_list): +def accumulate_values_into_parents(accounts, accounts_by_name, dimension_list): """accumulate children's values in parent accounts""" for d in reversed(accounts): if d.parent_account: - for item in dimension_items_list: - accounts_by_name[d.parent_account][frappe.scrub(item)] = \ - accounts_by_name[d.parent_account].get(frappe.scrub(item), 0.0) + d.get(frappe.scrub(item), 0.0) + for dimension in dimension_list: + accounts_by_name[d.parent_account][frappe.scrub(dimension)] = \ + accounts_by_name[d.parent_account].get(frappe.scrub(dimension), 0.0) + d.get(frappe.scrub(dimension), 0.0) -def get_condition(from_date, item, dimension): +def get_condition(dimension): conditions = [] - if from_date: - conditions.append("posting_date >= %(from_date)s") - if dimension: - if dimension not in ['Cost Center', 'Project']: - if dimension in ['Customer', 'Supplier']: - dimension = 'Party' - else: - dimension = 'Voucher No' - txt = "{0} = %(item)s".format(frappe.scrub(dimension)) - conditions.append(txt) + conditions.append("{0} in %(dimensions)s".format(frappe.scrub(dimension))) return " and {}".format(" and ".join(conditions)) if conditions else "" -def get_dimension_items_list(dimension, company): - meta = frappe.get_meta(dimension, cached=False) - fieldnames = [d.fieldname for d in meta.get("fields")] - filters = {} - if 'company' in fieldnames: - filters['company'] = company - return frappe.get_all(dimension, filters, as_list=True) +def get_dimensions(filters): + meta = frappe.get_meta(filters.get('dimension'), cached=False) + query_filters = {} -def get_columns(dimension_items_list, accumulated_values=1, company=None): + if meta.has_field('company'): + query_filters = {'company': filters.get('company')} + + return frappe.get_all(filters.get('dimension'), filters=query_filters, pluck='name') + +def get_columns(dimension_list): columns = [{ "fieldname": "account", "label": _("Account"), "fieldtype": "Link", "options": "Account", "width": 300 + }, + { + "fieldname": "currency", + "label": _("Currency"), + "fieldtype": "Link", + "options": "Currency", + "hidden": 1 }] - if company: + + for dimension in dimension_list: columns.append({ - "fieldname": "currency", - "label": _("Currency"), - "fieldtype": "Link", - "options": "Currency", - "hidden": 1 - }) - for item in dimension_items_list: - columns.append({ - "fieldname": frappe.scrub(item), - "label": item, + "fieldname": frappe.scrub(dimension), + "label": dimension, "fieldtype": "Currency", "options": "currency", "width": 150 }) + columns.append({ "fieldname": "total", "label": "Total",