diff --git a/erpnext/accounts/report/general_ledger/general_ledger.py b/erpnext/accounts/report/general_ledger/general_ledger.py index 6b569359f5b..c1cac812fe2 100644 --- a/erpnext/accounts/report/general_ledger/general_ledger.py +++ b/erpnext/accounts/report/general_ledger/general_ledger.py @@ -2,9 +2,6 @@ # License: GNU General Public License v3. See license.txt -import copy -from collections import OrderedDict - import frappe from frappe import _, _dict from frappe.query_builder import Criterion @@ -19,6 +16,15 @@ from erpnext.accounts.report.financial_statements import get_cost_centers_with_c from erpnext.accounts.report.utils import convert_to_presentation_currency, get_currency from erpnext.accounts.utils import get_account_currency +DEBIT_CREDIT_DICT = { + "debit": 0.0, + "credit": 0.0, + "debit_in_account_currency": 0.0, + "credit_in_account_currency": 0.0, + "debit_in_transaction_currency": None, + "credit_in_transaction_currency": None, +} + def execute(filters=None): if not filters: @@ -361,18 +367,35 @@ def set_bill_no(gl_entries): gl["bill_no"] = inv_details.get(gl.get("against_voucher"), "") +def get_translated_labels_for_totals(): + def wrap_in_quotes(label): + return f"'{label}'" + + return { + "opening": wrap_in_quotes(_("Opening")), + "total": wrap_in_quotes(_("Total")), + "closing": wrap_in_quotes(_("Closing (Opening + Total)")), + } + + def get_data_with_opening_closing(filters, account_details, accounting_dimensions, gl_entries): + def add_total_to_data(totals, key): + row = totals[key] + row["account"] = labels[key] + data.append(row) + + labels = get_translated_labels_for_totals() + data = [] - totals_dict = get_totals_dict() set_bill_no(gl_entries) - gle_map = initialize_gle_map(gl_entries, filters, totals_dict) + gle_map = initialize_gle_map(gl_entries, filters) - totals, entries = get_accountwise_gle(filters, accounting_dimensions, gl_entries, gle_map, totals_dict) + totals, entries = get_accountwise_gle(filters, accounting_dimensions, gl_entries, gle_map) # Opening for filtered account - data.append(totals.opening) + add_total_to_data(totals, "opening") if filters.get("group_by") != "Group by Voucher (Consolidated)": for _acc, acc_dict in gle_map.items(): @@ -383,53 +406,42 @@ def get_data_with_opening_closing(filters, account_details, accounting_dimension if (not filters.get("group_by") and not filters.get("voucher_no")) or ( filters.get("group_by") and filters.get("group_by") != "Group by Voucher" ): - data.append(acc_dict.totals.opening) + add_total_to_data(acc_dict.totals, "opening") data += acc_dict.entries # totals if filters.get("group_by") or not filters.voucher_no: - data.append(acc_dict.totals.total) + add_total_to_data(acc_dict.totals, "total") # closing if (not filters.get("group_by") and not filters.get("voucher_no")) or ( filters.get("group_by") and filters.get("group_by") != "Group by Voucher" ): - data.append(acc_dict.totals.closing) + add_total_to_data(acc_dict.totals, "closing") data.append({"debit_in_transaction_currency": None, "credit_in_transaction_currency": None}) else: data += entries # totals - data.append(totals.total) + add_total_to_data(totals, "total") # closing - data.append(totals.closing) + add_total_to_data(totals, "closing") return data def get_totals_dict(): - def _get_debit_credit_dict(label): - return _dict( - account=f"'{label}'", - debit=0.0, - credit=0.0, - debit_in_account_currency=0.0, - credit_in_account_currency=0.0, - debit_in_transaction_currency=None, - credit_in_transaction_currency=None, - ) - return _dict( - opening=_get_debit_credit_dict(_("Opening")), - total=_get_debit_credit_dict(_("Total")), - closing=_get_debit_credit_dict(_("Closing (Opening + Total)")), + opening=_dict(DEBIT_CREDIT_DICT), + total=_dict(DEBIT_CREDIT_DICT), + closing=_dict(DEBIT_CREDIT_DICT), ) -def group_by_field(group_by): +def get_group_by_field(group_by): if group_by == "Group by Party": return "party" elif group_by in ["Group by Voucher (Consolidated)", "Group by Account"]: @@ -438,19 +450,25 @@ def group_by_field(group_by): return "voucher_no" -def initialize_gle_map(gl_entries, filters, totals_dict): - gle_map = OrderedDict() - group_by = group_by_field(filters.get("group_by")) +def initialize_gle_map(gl_entries, filters): + gle_map = {} + group_by = get_group_by_field(filters.get("group_by")) for gle in gl_entries: - gle_map.setdefault(gle.get(group_by), _dict(totals=copy.deepcopy(totals_dict), entries=[])) + group_by_value = gle.get(group_by) + if group_by_value not in gle_map: + gle_map[group_by_value] = _dict( + totals=get_totals_dict(), + entries=[], + ) + return gle_map -def get_accountwise_gle(filters, accounting_dimensions, gl_entries, gle_map, totals): +def get_accountwise_gle(filters, accounting_dimensions, gl_entries, gle_map): entries = [] - consolidated_gle = OrderedDict() - group_by = group_by_field(filters.get("group_by")) + consolidated_gle = {} + group_by = get_group_by_field(filters.get("group_by")) group_by_voucher_consolidated = filters.get("group_by") == "Group by Voucher (Consolidated)" if filters.get("show_net_values_in_party_account"): @@ -496,6 +514,7 @@ def get_accountwise_gle(filters, accounting_dimensions, gl_entries, gle_map, tot from_date, to_date = getdate(filters.from_date), getdate(filters.to_date) show_opening_entries = filters.get("show_opening_entries") + totals = get_totals_dict() for gle in gl_entries: group_by_value = gle.get(group_by) gle.voucher_subtype = _(gle.voucher_subtype)