perf: improved gle map init

This commit is contained in:
Sagar Vora
2025-04-23 20:26:36 +05:30
parent 593ecb3d68
commit af283d0d9e

View File

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