mirror of
https://github.com/frappe/erpnext.git
synced 2026-05-23 23:19:20 +00:00
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:
@@ -7,10 +7,10 @@ import frappe
|
|||||||
from frappe import qb
|
from frappe import qb
|
||||||
from frappe.model.document import Document
|
from frappe.model.document import Document
|
||||||
from frappe.query_builder.functions import Sum
|
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
|
from frappe.utils.scheduler import is_scheduler_inactive
|
||||||
|
|
||||||
BACKGROUND = True
|
BACKGROUND = False
|
||||||
|
|
||||||
|
|
||||||
class ProcessPeriodClosingVoucher(Document):
|
class ProcessPeriodClosingVoucher(Document):
|
||||||
@@ -76,13 +76,16 @@ def start_pcv_processing(docname: str):
|
|||||||
|
|
||||||
@frappe.whitelist()
|
@frappe.whitelist()
|
||||||
def pause_pcv_processing(docname: str):
|
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(
|
queued_dates = frappe.db.get_all(
|
||||||
"Process Period Closing Voucher Detail",
|
"Process Period Closing Voucher Detail",
|
||||||
filters={"parent": docname, "status": "Queued"},
|
filters={"parent": docname, "status": "Queued"},
|
||||||
fields=["name"],
|
pluck="name",
|
||||||
)
|
)
|
||||||
ppcv = qb.DocType("Process Period Closing Voucher")
|
ppcvd = qb.DocType("Process Period Closing Voucher Detail")
|
||||||
qb.update(ppcv).set(ppcv.status, "Paused").where(ppcv.name.isin(queued_dates)).run()
|
qb.update(ppcvd).set(ppcvd.status, "Paused").where(ppcvd.name.isin(queued_dates)).run()
|
||||||
|
|
||||||
|
|
||||||
def call_next_date(docname: str):
|
def call_next_date(docname: str):
|
||||||
@@ -121,32 +124,101 @@ def call_next_date(docname: str):
|
|||||||
limit=1,
|
limit=1,
|
||||||
)
|
)
|
||||||
if not running:
|
if not running:
|
||||||
|
# TODO: Generate GL and Account Closing Balance
|
||||||
frappe.db.set_value("Process Period Closing Voucher", docname, "status", "Completed")
|
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):
|
def process_individual_date(docname: str, date: str):
|
||||||
if frappe.db.get_value("Process Period Closing Voucher", docname, "status") == "Running":
|
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_name = frappe.db.get_value("Process Period Closing Voucher", docname, "parent_pcv")
|
||||||
pcv = frappe.get_doc("Period Closing Voucher", pcv_name)
|
pcv = frappe.get_doc("Period Closing Voucher", pcv_name)
|
||||||
gle = qb.DocType("GL Entry")
|
|
||||||
res = (
|
dimensions = get_dimensions()
|
||||||
qb.from_(gle)
|
|
||||||
.select(gle.account, Sum(gle.debit).as_("debit"), Sum(gle.credit).as_("credit"))
|
p_l_accounts = frappe.db.get_all(
|
||||||
.where((gle.company.eq(pcv.company)) & (gle.is_cancelled.eq(False)) & (gle.posting_date.eq(date)))
|
"Account", filters={"company": pcv.company, "report_type": "Profit and Loss"}, pluck="name"
|
||||||
.groupby(gle.account)
|
|
||||||
.run(as_dict=True)
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
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(
|
frappe.db.set_value(
|
||||||
"Process Period Closing Voucher Detail",
|
"Process Period Closing Voucher Detail",
|
||||||
{"processing_date": date, "parent": docname},
|
{"processing_date": date, "parent": docname},
|
||||||
"status",
|
"status",
|
||||||
"Completed",
|
"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(
|
frappe.db.set_value(
|
||||||
"Process Period Closing Voucher Detail",
|
"Process Period Closing Voucher Detail",
|
||||||
{"processing_date": date, "parent": docname},
|
{"processing_date": date, "parent": docname},
|
||||||
"closing_balance",
|
"closing_balance",
|
||||||
frappe.json.dumps(res),
|
frappe.json.dumps(json_dict),
|
||||||
)
|
)
|
||||||
|
|
||||||
call_next_date(docname)
|
call_next_date(docname)
|
||||||
|
|||||||
Reference in New Issue
Block a user