mirror of
https://github.com/frappe/erpnext.git
synced 2026-05-27 17:04:47 +00:00
fix(custom_financial_template): sum account closing balances across dimensions
This commit is contained in:
@@ -565,18 +565,19 @@ class FinancialQueryBuilder:
|
||||
frappe.qb.from_(acb_table)
|
||||
.select(
|
||||
acb_table.account,
|
||||
(acb_table.debit - acb_table.credit).as_("balance"),
|
||||
Sum(acb_table.debit - acb_table.credit).as_("balance"),
|
||||
)
|
||||
.where(acb_table.company == self.company)
|
||||
.where(acb_table.account.isin(account_names))
|
||||
.where(acb_table.period_closing_voucher == closing_voucher)
|
||||
.groupby(acb_table.account)
|
||||
)
|
||||
|
||||
query = self._apply_standard_filters(query, acb_table, "Account Closing Balance")
|
||||
results = self._execute_with_permissions(query, "Account Closing Balance")
|
||||
|
||||
for row in results:
|
||||
closing_balances[row["account"]] = row["balance"]
|
||||
closing_balances[row["account"]] = row["balance"] or 0.0
|
||||
|
||||
return closing_balances
|
||||
|
||||
|
||||
@@ -16,6 +16,7 @@ from erpnext.accounts.doctype.financial_report_template.test_financial_report_te
|
||||
)
|
||||
from erpnext.accounts.doctype.journal_entry.test_journal_entry import make_journal_entry
|
||||
from erpnext.accounts.utils import get_currency_precision, get_fiscal_year
|
||||
from erpnext.tests.utils import change_settings
|
||||
|
||||
|
||||
class TestDependencyResolver(FinancialReportTemplateTestCase):
|
||||
@@ -1950,6 +1951,104 @@ class TestFinancialQueryBuilder(FinancialReportTemplateTestCase):
|
||||
|
||||
jv_2023.cancel()
|
||||
|
||||
@change_settings("Accounts Settings", {"use_legacy_controller_for_pcv": 1})
|
||||
def test_opening_balance_sums_acb_rows_across_dimensions(self):
|
||||
"""
|
||||
Account Closing Balance stores one row per (account, cost_center,
|
||||
project, finance_book). The closing-balance fetch must sum all rows.
|
||||
"""
|
||||
company = "_Test Company"
|
||||
cash_account = "_Test Cash - _TC"
|
||||
sales_account = "Sales - _TC"
|
||||
cc_1 = "_Test Cost Center - _TC"
|
||||
cc_2 = "_Test Cost Center 2 - _TC"
|
||||
docs = []
|
||||
|
||||
try:
|
||||
jv_2023_cc1 = make_journal_entry(
|
||||
account1=cash_account,
|
||||
account2=sales_account,
|
||||
amount=3000,
|
||||
posting_date="2023-06-15",
|
||||
cost_center=cc_1,
|
||||
company=company,
|
||||
submit=True,
|
||||
)
|
||||
docs.append(jv_2023_cc1)
|
||||
jv_2023_cc2 = make_journal_entry(
|
||||
account1=cash_account,
|
||||
account2=sales_account,
|
||||
amount=2000,
|
||||
posting_date="2023-06-15",
|
||||
cost_center=cc_2,
|
||||
company=company,
|
||||
submit=True,
|
||||
)
|
||||
docs.append(jv_2023_cc2)
|
||||
|
||||
fy_2023 = get_fiscal_year("2023-06-15", company=company)
|
||||
|
||||
pcv = frappe.get_doc(
|
||||
{
|
||||
"doctype": "Period Closing Voucher",
|
||||
"transaction_date": "2023-12-31",
|
||||
"period_start_date": fy_2023[1],
|
||||
"period_end_date": fy_2023[2],
|
||||
"company": company,
|
||||
"fiscal_year": fy_2023[0],
|
||||
"cost_center": cc_1,
|
||||
"closing_account_head": "Deferred Revenue - _TC",
|
||||
"remarks": "Test multi-dim PCV",
|
||||
}
|
||||
)
|
||||
pcv.insert()
|
||||
pcv.submit()
|
||||
docs.append(pcv)
|
||||
|
||||
jv_2024 = make_journal_entry(
|
||||
account1=cash_account,
|
||||
account2=sales_account,
|
||||
amount=100,
|
||||
posting_date="2024-01-15",
|
||||
cost_center=cc_1,
|
||||
company=company,
|
||||
submit=True,
|
||||
)
|
||||
docs.append(jv_2024)
|
||||
|
||||
filters = {
|
||||
"company": company,
|
||||
"from_fiscal_year": "2024",
|
||||
"to_fiscal_year": "2024",
|
||||
"period_start_date": "2024-01-01",
|
||||
"period_end_date": "2024-03-31",
|
||||
"filter_based_on": "Date Range",
|
||||
"periodicity": "Monthly",
|
||||
"ignore_closing_entries": True,
|
||||
}
|
||||
periods = [
|
||||
{"key": "2024_jan", "from_date": "2024-01-01", "to_date": "2024-01-31"},
|
||||
{"key": "2024_feb", "from_date": "2024-02-01", "to_date": "2024-02-29"},
|
||||
{"key": "2024_mar", "from_date": "2024-03-01", "to_date": "2024-03-31"},
|
||||
]
|
||||
|
||||
query_builder = FinancialQueryBuilder(filters, periods)
|
||||
accounts = [
|
||||
frappe._dict({"name": cash_account, "account_name": "Cash", "account_number": "1001"}),
|
||||
]
|
||||
|
||||
balances_data = query_builder.fetch_account_balances(accounts)
|
||||
cash_data = balances_data.get(cash_account)
|
||||
self.assertIsNotNone(cash_data, "Cash account must appear in results")
|
||||
|
||||
jan_cash = cash_data.get_period("2024_jan")
|
||||
self.assertEqual(jan_cash.opening, 5000.0)
|
||||
self.assertEqual(jan_cash.movement, 100.0)
|
||||
self.assertEqual(jan_cash.closing, 5100.0)
|
||||
|
||||
finally:
|
||||
self.cancel_docs(docs)
|
||||
|
||||
def test_opening_entries_roll_into_opening_after_period_closing(self):
|
||||
"""
|
||||
Sequence:
|
||||
|
||||
@@ -9,6 +9,14 @@ from erpnext.tests.utils import ERPNextTestSuite
|
||||
class FinancialReportTemplateTestCase(ERPNextTestSuite):
|
||||
"""Utility class with common setup and helper methods for all test classes"""
|
||||
|
||||
def cancel_docs(self, docs):
|
||||
"""Cancel submitted docs in reverse creation order to avoid dependency issues."""
|
||||
for doc in reversed(docs):
|
||||
if doc:
|
||||
doc.reload()
|
||||
if doc.docstatus == 1:
|
||||
doc.cancel()
|
||||
|
||||
def setUp(self):
|
||||
"""Set up test data"""
|
||||
self.create_test_template()
|
||||
|
||||
Reference in New Issue
Block a user