refactor(postgres): port Dimension-wise Account Balance report query to the query builder

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Mihir Kandoi
2026-06-17 17:35:59 +05:30
parent 18c1f0f04d
commit 6a60f072a8

View File

@@ -4,7 +4,7 @@
import frappe import frappe
from frappe import _ from frappe import _
from frappe.utils import cstr, flt from frappe.utils import flt
import erpnext import erpnext
from erpnext.accounts.report.financial_statements import ( from erpnext.accounts.report.financial_statements import (
@@ -31,18 +31,23 @@ def execute(filters=None):
def get_data(filters, dimension_list): def get_data(filters, dimension_list):
company_currency = erpnext.get_company_currency(filters.company) company_currency = erpnext.get_company_currency(filters.company)
acc = frappe.db.sql( acc = frappe.get_all(
""" "Account",
select filters={"company": filters.company},
name, account_number, parent_account, lft, rgt, root_type, fields=[
report_type, account_name, include_in_gross, account_type, is_group "name",
from "account_number",
`tabAccount` "parent_account",
where "lft",
company=%s "rgt",
order by lft""", "root_type",
(filters.company), "report_type",
as_dict=True, "account_name",
"include_in_gross",
"account_type",
"is_group",
],
order_by="lft",
) )
if not acc: if not acc:
@@ -50,16 +55,17 @@ def get_data(filters, dimension_list):
accounts, accounts_by_name, parent_children_map = filter_accounts(acc) accounts, accounts_by_name, parent_children_map = filter_accounts(acc)
min_lft, max_rgt = frappe.db.sql( lft_rgt = frappe.get_all(
"""select min(lft), max(rgt) from `tabAccount` "Account",
where company=%s""", filters={"company": filters.company},
(filters.company), fields=[{"MIN": "lft", "as": "min_lft"}, {"MAX": "rgt", "as": "max_rgt"}],
)[0] )[0]
min_lft, max_rgt = lft_rgt.min_lft, lft_rgt.max_rgt
account = frappe.db.sql_list( account = frappe.get_all(
"""select name from `tabAccount` "Account",
where lft >= %s and rgt <= %s and company = %s""", filters={"lft": [">=", min_lft], "rgt": ["<=", max_rgt], "company": filters.company},
(min_lft, max_rgt, filters.company), pluck="name",
) )
gl_entries_by_account = {} gl_entries_by_account = {}
@@ -75,42 +81,34 @@ def get_data(filters, dimension_list):
def set_gl_entries_by_account(dimension_list, filters, account, gl_entries_by_account): def set_gl_entries_by_account(dimension_list, filters, account, gl_entries_by_account):
condition = get_condition(filters.get("dimension")) dimension_field = frappe.scrub(filters.get("dimension"))
if account:
condition += " and account in ({})".format(", ".join([frappe.db.escape(d) for d in account]))
gl_filters = { gl_filters = {
"company": filters.get("company"), "company": filters.get("company"),
"from_date": filters.get("from_date"), dimension_field: ["in", list(set(dimension_list))],
"to_date": filters.get("to_date"), "posting_date": ["between", [filters.get("from_date"), filters.get("to_date")]],
"finance_book": cstr(filters.get("finance_book")), "is_cancelled": 0,
} }
if account:
gl_filters["account"] = ["in", account]
gl_filters["dimensions"] = tuple(set(dimension_list)) gl_entries = frappe.get_all(
"GL Entry",
if filters.get("include_default_book_entries"): filters=gl_filters,
gl_filters["company_fb"] = frappe.get_cached_value("Company", filters.company, "default_finance_book") fields=[
"posting_date",
gl_entries = frappe.db.sql( "account",
""" dimension_field,
select "debit",
posting_date, account, {dimension}, debit, credit, is_opening, fiscal_year, "credit",
debit_in_account_currency, credit_in_account_currency, account_currency "is_opening",
from "fiscal_year",
`tabGL Entry` "debit_in_account_currency",
where "credit_in_account_currency",
company=%(company)s "account_currency",
{condition} ],
and posting_date >= %(from_date)s order_by="account, posting_date",
and posting_date <= %(to_date)s )
and is_cancelled = 0
order by account, posting_date""".format(
dimension=frappe.scrub(filters.get("dimension")), condition=condition
),
gl_filters,
as_dict=True,
) # nosec
for entry in gl_entries: for entry in gl_entries:
gl_entries_by_account.setdefault(entry.account, []).append(entry) gl_entries_by_account.setdefault(entry.account, []).append(entry)
@@ -178,14 +176,6 @@ def accumulate_values_into_parents(accounts, accounts_by_name, dimension_list):
].get(frappe.scrub(dimension), 0.0) + d.get(frappe.scrub(dimension), 0.0) ].get(frappe.scrub(dimension), 0.0) + d.get(frappe.scrub(dimension), 0.0)
def get_condition(dimension):
conditions = []
conditions.append(f"{frappe.scrub(dimension)} in %(dimensions)s")
return " and {}".format(" and ".join(conditions)) if conditions else ""
def get_dimensions(filters): def get_dimensions(filters):
meta = frappe.get_meta(filters.get("dimension"), cached=False) meta = frappe.get_meta(filters.get("dimension"), cached=False)
query_filters = {} query_filters = {}