Skip to content

Commit 84aa54c

Browse files
committed
test: pcv is excluded from PL accounts
1 parent 0349e7a commit 84aa54c

1 file changed

Lines changed: 208 additions & 0 deletions

File tree

erpnext/accounts/doctype/financial_report_template/test_financial_report_engine.py

Lines changed: 208 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
DependencyResolver,
99
FilterExpressionParser,
1010
FinancialQueryBuilder,
11+
FinancialReportEngine,
1112
FormulaCalculator,
1213
)
1314
from erpnext.accounts.doctype.financial_report_template.test_financial_report_template import (
@@ -2022,3 +2023,210 @@ def test_account_with_gl_entries_but_no_prior_closing_balance(self):
20222023

20232024
finally:
20242025
jv.cancel()
2026+
2027+
def test_pl_pcv_exclusion_and_growth_view_year_over_year(self):
2028+
"""
2029+
Sequence:
2030+
1. Expense JV 2000 in FY 2024, PCV for FY 2024
2031+
→ assert FY 2024 movement = 2000 via FinancialQueryBuilder
2032+
2. Expense JV 3000 in FY 2025, PCV for FY 2025
2033+
3. Run FinancialReportEngine with selected_view="Growth"
2034+
→ assert col_2024 = 2000 (raw), col_2025 = 50.0 (% growth)
2035+
"""
2036+
company = "_Test Company"
2037+
expense_account = "Administrative Expenses - _TC"
2038+
bank_account = "_Test Bank - _TC"
2039+
2040+
template = None
2041+
pcv_2024 = None
2042+
pcv_2025 = None
2043+
jv_2024 = None
2044+
jv_2025 = None
2045+
original_pcv_setting = frappe.db.get_single_value(
2046+
"Accounts Settings", "use_legacy_controller_for_pcv"
2047+
)
2048+
2049+
try:
2050+
closing_account = frappe.db.get_value(
2051+
"Account",
2052+
{
2053+
"company": company,
2054+
"root_type": "Liability",
2055+
"is_group": 0,
2056+
"account_type": ["not in", ["Payable", "Receivable"]],
2057+
},
2058+
"name",
2059+
)
2060+
2061+
frappe.db.set_single_value("Accounts Settings", "use_legacy_controller_for_pcv", 1)
2062+
2063+
accounts = [
2064+
frappe._dict(
2065+
{
2066+
"name": expense_account,
2067+
"account_name": "Administrative Expenses",
2068+
"account_number": "5001",
2069+
}
2070+
),
2071+
]
2072+
2073+
# --- Step 1: FY 2024 expense + PCV, assert PCV reversal excluded ---
2074+
jv_2024 = make_journal_entry(
2075+
account1=expense_account,
2076+
account2=bank_account,
2077+
amount=2000,
2078+
posting_date="2024-06-15",
2079+
company=company,
2080+
submit=True,
2081+
)
2082+
fy_2024 = get_fiscal_year("2024-06-15", company=company)
2083+
pcv_2024 = frappe.get_doc(
2084+
{
2085+
"doctype": "Period Closing Voucher",
2086+
"transaction_date": "2024-12-31",
2087+
"period_start_date": fy_2024[1],
2088+
"period_end_date": fy_2024[2],
2089+
"company": company,
2090+
"fiscal_year": fy_2024[0],
2091+
"cost_center": "_Test Cost Center - _TC",
2092+
"closing_account_head": closing_account,
2093+
"remarks": "Test PCV FY 2024",
2094+
}
2095+
)
2096+
pcv_2024.insert()
2097+
pcv_2024.submit()
2098+
pcv_2024.reload()
2099+
2100+
builder_2024 = FinancialQueryBuilder(
2101+
{
2102+
"company": company,
2103+
"from_fiscal_year": "2024",
2104+
"to_fiscal_year": "2024",
2105+
"period_start_date": "2024-01-01",
2106+
"period_end_date": "2024-12-31",
2107+
"filter_based_on": "Date Range",
2108+
"periodicity": "Yearly",
2109+
},
2110+
[{"key": "2024", "from_date": "2024-01-01", "to_date": "2024-12-31"}],
2111+
)
2112+
data_2024 = builder_2024.fetch_account_balances(accounts)
2113+
expense_2024 = data_2024.get(expense_account)
2114+
self.assertIsNotNone(expense_2024, "Expense account must appear in FY 2024 results")
2115+
year_2024 = expense_2024.get_period("2024")
2116+
self.assertEqual(
2117+
year_2024.movement,
2118+
2000.0,
2119+
"FY 2024 expense movement must equal real expense (PCV reversal excluded)",
2120+
)
2121+
2122+
# --- Step 2: FY 2025 expense + PCV ---
2123+
jv_2025 = make_journal_entry(
2124+
account1=expense_account,
2125+
account2=bank_account,
2126+
amount=3000,
2127+
posting_date="2025-06-15",
2128+
company=company,
2129+
submit=True,
2130+
)
2131+
fy_2025 = get_fiscal_year("2025-06-15", company=company)
2132+
pcv_2025 = frappe.get_doc(
2133+
{
2134+
"doctype": "Period Closing Voucher",
2135+
"transaction_date": "2025-12-31",
2136+
"period_start_date": fy_2025[1],
2137+
"period_end_date": fy_2025[2],
2138+
"company": company,
2139+
"fiscal_year": fy_2025[0],
2140+
"cost_center": "_Test Cost Center - _TC",
2141+
"closing_account_head": closing_account,
2142+
"remarks": "Test PCV FY 2025",
2143+
}
2144+
)
2145+
pcv_2025.insert()
2146+
pcv_2025.submit()
2147+
pcv_2025.reload()
2148+
2149+
# --- Step 3: full pipeline with Growth view across both years ---
2150+
template_name = f"Test Growth Template {frappe.generate_hash()[:8]}"
2151+
template = frappe.get_doc(
2152+
{
2153+
"doctype": "Financial Report Template",
2154+
"template_name": template_name,
2155+
"report_type": "Profit and Loss Statement",
2156+
"rows": [
2157+
{
2158+
"reference_code": "EXP_ADMIN",
2159+
"display_name": "Administrative Expenses",
2160+
"indentation_level": 0,
2161+
"data_source": "Account Data",
2162+
"balance_type": "Closing Balance",
2163+
"calculation_formula": f'["name", "=", "{expense_account}"]',
2164+
},
2165+
],
2166+
}
2167+
)
2168+
template.insert()
2169+
2170+
filters = frappe._dict(
2171+
{
2172+
"company": company,
2173+
"report_template": template_name,
2174+
"from_fiscal_year": fy_2024[0],
2175+
"to_fiscal_year": fy_2025[0],
2176+
"period_start_date": "2024-01-01",
2177+
"period_end_date": "2025-12-31",
2178+
"filter_based_on": "Date Range",
2179+
"periodicity": "Yearly",
2180+
"accumulated_values": 0,
2181+
"selected_view": "Growth",
2182+
}
2183+
)
2184+
2185+
_columns, formatted_data, _msg, _chart = FinancialReportEngine().execute(filters)
2186+
2187+
expense_row = next(
2188+
(row for row in formatted_data if row.get("account_name") == "Administrative Expenses"),
2189+
None,
2190+
)
2191+
self.assertIsNotNone(expense_row, "Administrative Expenses row must appear in growth view")
2192+
2193+
period_keys = expense_row.get("_segment_info", {}).get("period_keys", [])
2194+
self.assertEqual(len(period_keys), 2, "Yearly view must yield exactly two periods")
2195+
first_period_key, second_period_key = period_keys
2196+
2197+
# First column: raw absolute value (FY 2024 expense)
2198+
self.assertEqual(
2199+
flt(expense_row[first_period_key]),
2200+
2000.0,
2201+
"First column in growth view must keep raw FY 2024 expense value",
2202+
)
2203+
# Second column: ((3000 - 2000) / 2000) * 100 = 50.0
2204+
self.assertEqual(
2205+
flt(expense_row[second_period_key]),
2206+
50.0,
2207+
"Second column must be % growth FY 2024 → FY 2025",
2208+
)
2209+
2210+
finally:
2211+
frappe.db.set_single_value(
2212+
"Accounts Settings", "use_legacy_controller_for_pcv", original_pcv_setting or 0
2213+
)
2214+
2215+
if pcv_2025:
2216+
pcv_2025.reload()
2217+
if pcv_2025.docstatus == 1:
2218+
pcv_2025.cancel()
2219+
2220+
if jv_2025 and jv_2025.docstatus == 1:
2221+
jv_2025.cancel()
2222+
2223+
if pcv_2024:
2224+
pcv_2024.reload()
2225+
if pcv_2024.docstatus == 1:
2226+
pcv_2024.cancel()
2227+
2228+
if jv_2024 and jv_2024.docstatus == 1:
2229+
jv_2024.cancel()
2230+
2231+
if template and frappe.db.exists("Financial Report Template", template.name):
2232+
frappe.delete_doc("Financial Report Template", template.name, force=1)

0 commit comments

Comments
 (0)