refactor: store daily balances based on dimensions key

dimensions key is manually converted to string

(cherry picked from commit 1846de0d49)
This commit is contained in:
ruthra kumar
2025-10-14 16:31:46 +05:30
committed by Mergify
parent 1999de0b75
commit 76bdf7944c

View File

@@ -7,10 +7,10 @@ import frappe
from frappe import qb
from frappe.model.document import Document
from frappe.query_builder.functions import Sum
from frappe.utils import add_days, get_datetime
from frappe.utils import add_days, flt, get_datetime
from frappe.utils.scheduler import is_scheduler_inactive
BACKGROUND = True
BACKGROUND = False
class ProcessPeriodClosingVoucher(Document):
@@ -76,13 +76,16 @@ def start_pcv_processing(docname: str):
@frappe.whitelist()
def pause_pcv_processing(docname: str):
ppcv = qb.DocType("Process Period Closing Voucher")
qb.update(ppcv).set(ppcv.status, "Paused").where(ppcv.name.eq(docname)).run()
queued_dates = frappe.db.get_all(
"Process Period Closing Voucher Detail",
filters={"parent": docname, "status": "Queued"},
fields=["name"],
pluck="name",
)
ppcv = qb.DocType("Process Period Closing Voucher")
qb.update(ppcv).set(ppcv.status, "Paused").where(ppcv.name.isin(queued_dates)).run()
ppcvd = qb.DocType("Process Period Closing Voucher Detail")
qb.update(ppcvd).set(ppcvd.status, "Paused").where(ppcvd.name.isin(queued_dates)).run()
def call_next_date(docname: str):
@@ -121,32 +124,101 @@ def call_next_date(docname: str):
limit=1,
)
if not running:
# TODO: Generate GL and Account Closing Balance
frappe.db.set_value("Process Period Closing Voucher", docname, "status", "Completed")
def get_dimensions():
from erpnext.accounts.doctype.accounting_dimension.accounting_dimension import (
get_accounting_dimensions,
)
default_dimensions = ["cost_center", "finance_book", "project"]
dimensions = default_dimensions + get_accounting_dimensions()
return dimensions
def get_key(res):
return tuple([res.get(dimension) for dimension in get_dimensions()])
def process_individual_date(docname: str, date: str):
if frappe.db.get_value("Process Period Closing Voucher", docname, "status") == "Running":
pcv_name = frappe.db.get_value("Process Period Closing Voucher", docname, "parent_pcv")
pcv = frappe.get_doc("Period Closing Voucher", pcv_name)
gle = qb.DocType("GL Entry")
res = (
qb.from_(gle)
.select(gle.account, Sum(gle.debit).as_("debit"), Sum(gle.credit).as_("credit"))
.where((gle.company.eq(pcv.company)) & (gle.is_cancelled.eq(False)) & (gle.posting_date.eq(date)))
.groupby(gle.account)
.run(as_dict=True)
dimensions = get_dimensions()
p_l_accounts = frappe.db.get_all(
"Account", filters={"company": pcv.company, "report_type": "Profit and Loss"}, pluck="name"
)
gle = qb.DocType("GL Entry")
query = qb.from_(gle).select(gle.account)
for dim in dimensions:
query = query.select(gle[dim])
query = query.select(
Sum(gle.debit).as_("debit"),
Sum(gle.credit).as_("credit"),
Sum(gle.debit_in_account_currency).as_("debit_in_account_currency"),
Sum(gle.credit_in_account_currency).as_("credit_in_account_currency"),
).where(
(gle.company.eq(pcv.company))
& (gle.is_cancelled.eq(0))
& (gle.posting_date.eq(date))
& (gle.account.isin(p_l_accounts))
)
query = query.groupby(gle.account)
for dim in dimensions:
query = query.groupby(gle[dim])
res = query.run(as_dict=True)
dimension_wise_acc_balances = frappe._dict()
for x in res:
dimension_key = get_key(x)
dimension_wise_acc_balances.setdefault(dimension_key, frappe._dict()).setdefault(
x.account,
frappe._dict(
{
"debit_in_account_currency": 0,
"credit_in_account_currency": 0,
"debit": 0,
"credit": 0,
"account_currency": x.account_currency,
}
),
)
dimension_wise_acc_balances[dimension_key][x.account].debit_in_account_currency += flt(
x.debit_in_account_currency
)
dimension_wise_acc_balances[dimension_key][x.account].credit_in_account_currency += flt(
x.credit_in_account_currency
)
dimension_wise_acc_balances[dimension_key][x.account].debit += flt(x.debit)
dimension_wise_acc_balances[dimension_key][x.account].credit += flt(x.credit)
frappe.db.set_value(
"Process Period Closing Voucher Detail",
{"processing_date": date, "parent": docname},
"status",
"Completed",
)
# convert dict keys to json compliant json dictionary keys
json_dict = {}
for k, v in dimension_wise_acc_balances.items():
str_key = [str(x) for x in k]
str_key = ",".join(str_key)
json_dict[str_key] = v
frappe.db.set_value(
"Process Period Closing Voucher Detail",
{"processing_date": date, "parent": docname},
"closing_balance",
frappe.json.dumps(res),
frappe.json.dumps(json_dict),
)
call_next_date(docname)