Merge pull request #38969 from ruthra-kumar/bug_in_p_l_report
fix: incorrect net profit in Profit and Loss Statement
This commit is contained in:
commit
915d864166
@ -211,7 +211,13 @@ def get_data(
|
|||||||
ignore_accumulated_values_for_fy,
|
ignore_accumulated_values_for_fy,
|
||||||
)
|
)
|
||||||
accumulate_values_into_parents(accounts, accounts_by_name, period_list)
|
accumulate_values_into_parents(accounts, accounts_by_name, period_list)
|
||||||
out = prepare_data(accounts, balance_must_be, period_list, company_currency)
|
out = prepare_data(
|
||||||
|
accounts,
|
||||||
|
balance_must_be,
|
||||||
|
period_list,
|
||||||
|
company_currency,
|
||||||
|
accumulated_values=filters.accumulated_values,
|
||||||
|
)
|
||||||
out = filter_out_zero_value_rows(out, parent_children_map)
|
out = filter_out_zero_value_rows(out, parent_children_map)
|
||||||
|
|
||||||
if out and total:
|
if out and total:
|
||||||
@ -270,7 +276,7 @@ def accumulate_values_into_parents(accounts, accounts_by_name, period_list):
|
|||||||
) + d.get("opening_balance", 0.0)
|
) + d.get("opening_balance", 0.0)
|
||||||
|
|
||||||
|
|
||||||
def prepare_data(accounts, balance_must_be, period_list, company_currency):
|
def prepare_data(accounts, balance_must_be, period_list, company_currency, accumulated_values):
|
||||||
data = []
|
data = []
|
||||||
year_start_date = period_list[0]["year_start_date"].strftime("%Y-%m-%d")
|
year_start_date = period_list[0]["year_start_date"].strftime("%Y-%m-%d")
|
||||||
year_end_date = period_list[-1]["year_end_date"].strftime("%Y-%m-%d")
|
year_end_date = period_list[-1]["year_end_date"].strftime("%Y-%m-%d")
|
||||||
@ -310,8 +316,14 @@ def prepare_data(accounts, balance_must_be, period_list, company_currency):
|
|||||||
has_value = True
|
has_value = True
|
||||||
total += flt(row[period.key])
|
total += flt(row[period.key])
|
||||||
|
|
||||||
row["has_value"] = has_value
|
if accumulated_values:
|
||||||
row["total"] = total
|
# when 'accumulated_values' is enabled, periods have running balance.
|
||||||
|
# so, last period will have the net amount.
|
||||||
|
row["has_value"] = has_value
|
||||||
|
row["total"] = flt(d.get(period_list[-1].key, 0.0), 3)
|
||||||
|
else:
|
||||||
|
row["has_value"] = has_value
|
||||||
|
row["total"] = total
|
||||||
data.append(row)
|
data.append(row)
|
||||||
|
|
||||||
return data
|
return data
|
||||||
|
@ -82,14 +82,25 @@ def get_report_summary(
|
|||||||
if filters.get("accumulated_in_group_company"):
|
if filters.get("accumulated_in_group_company"):
|
||||||
period_list = get_filtered_list_for_consolidated_report(filters, period_list)
|
period_list = get_filtered_list_for_consolidated_report(filters, period_list)
|
||||||
|
|
||||||
for period in period_list:
|
if filters.accumulated_values:
|
||||||
key = period if consolidated else period.key
|
# when 'accumulated_values' is enabled, periods have running balance.
|
||||||
|
# so, last period will have the net amount.
|
||||||
|
key = period_list[-1].key
|
||||||
if income:
|
if income:
|
||||||
net_income += income[-2].get(key)
|
net_income = income[-2].get(key)
|
||||||
if expense:
|
if expense:
|
||||||
net_expense += expense[-2].get(key)
|
net_expense = expense[-2].get(key)
|
||||||
if net_profit_loss:
|
if net_profit_loss:
|
||||||
net_profit += net_profit_loss.get(key)
|
net_profit = net_profit_loss.get(key)
|
||||||
|
else:
|
||||||
|
for period in period_list:
|
||||||
|
key = period if consolidated else period.key
|
||||||
|
if income:
|
||||||
|
net_income += income[-2].get(key)
|
||||||
|
if expense:
|
||||||
|
net_expense += expense[-2].get(key)
|
||||||
|
if net_profit_loss:
|
||||||
|
net_profit += net_profit_loss.get(key)
|
||||||
|
|
||||||
if len(period_list) == 1 and periodicity == "Yearly":
|
if len(period_list) == 1 and periodicity == "Yearly":
|
||||||
profit_label = _("Profit This Year")
|
profit_label = _("Profit This Year")
|
||||||
|
@ -0,0 +1,94 @@
|
|||||||
|
# Copyright (c) 2023, Frappe Technologies Pvt. Ltd. and Contributors
|
||||||
|
# MIT License. See license.txt
|
||||||
|
|
||||||
|
import frappe
|
||||||
|
from frappe.tests.utils import FrappeTestCase
|
||||||
|
from frappe.utils import add_days, getdate, today
|
||||||
|
|
||||||
|
from erpnext.accounts.doctype.sales_invoice.test_sales_invoice import create_sales_invoice
|
||||||
|
from erpnext.accounts.report.financial_statements import get_period_list
|
||||||
|
from erpnext.accounts.report.profit_and_loss_statement.profit_and_loss_statement import execute
|
||||||
|
from erpnext.accounts.test.accounts_mixin import AccountsTestMixin
|
||||||
|
|
||||||
|
|
||||||
|
class TestProfitAndLossStatement(AccountsTestMixin, FrappeTestCase):
|
||||||
|
def setUp(self):
|
||||||
|
self.create_company()
|
||||||
|
self.create_customer()
|
||||||
|
self.create_item()
|
||||||
|
|
||||||
|
def tearDown(self):
|
||||||
|
frappe.db.rollback()
|
||||||
|
|
||||||
|
def create_sales_invoice(self, qty=1, rate=150, no_payment_schedule=False, do_not_submit=False):
|
||||||
|
frappe.set_user("Administrator")
|
||||||
|
si = create_sales_invoice(
|
||||||
|
item=self.item,
|
||||||
|
company=self.company,
|
||||||
|
customer=self.customer,
|
||||||
|
debit_to=self.debit_to,
|
||||||
|
posting_date=today(),
|
||||||
|
parent_cost_center=self.cost_center,
|
||||||
|
cost_center=self.cost_center,
|
||||||
|
rate=rate,
|
||||||
|
price_list_rate=rate,
|
||||||
|
qty=qty,
|
||||||
|
do_not_save=1,
|
||||||
|
)
|
||||||
|
si = si.save()
|
||||||
|
if not do_not_submit:
|
||||||
|
si = si.submit()
|
||||||
|
return si
|
||||||
|
|
||||||
|
def get_fiscal_year(self):
|
||||||
|
active_fy = frappe.db.get_all(
|
||||||
|
"Fiscal Year",
|
||||||
|
filters={"disabled": 0, "year_start_date": ("<=", today()), "year_end_date": (">=", today())},
|
||||||
|
)[0]
|
||||||
|
return frappe.get_doc("Fiscal Year", active_fy.name)
|
||||||
|
|
||||||
|
def get_report_filters(self):
|
||||||
|
fy = self.get_fiscal_year()
|
||||||
|
return frappe._dict(
|
||||||
|
company=self.company,
|
||||||
|
from_fiscal_year=fy.name,
|
||||||
|
to_fiscal_year=fy.name,
|
||||||
|
period_start_date=fy.year_start_date,
|
||||||
|
period_end_date=fy.year_end_date,
|
||||||
|
filter_based_on="Fiscal Year",
|
||||||
|
periodicity="Monthly",
|
||||||
|
accumulated_vallues=True,
|
||||||
|
)
|
||||||
|
|
||||||
|
def test_profit_and_loss_output_and_summary(self):
|
||||||
|
si = self.create_sales_invoice(qty=1, rate=150)
|
||||||
|
|
||||||
|
filters = self.get_report_filters()
|
||||||
|
period_list = get_period_list(
|
||||||
|
filters.from_fiscal_year,
|
||||||
|
filters.to_fiscal_year,
|
||||||
|
filters.period_start_date,
|
||||||
|
filters.period_end_date,
|
||||||
|
filters.filter_based_on,
|
||||||
|
filters.periodicity,
|
||||||
|
company=filters.company,
|
||||||
|
)
|
||||||
|
|
||||||
|
result = execute(filters)[1]
|
||||||
|
current_period = [x for x in period_list if x.from_date <= getdate() and x.to_date >= getdate()][
|
||||||
|
0
|
||||||
|
]
|
||||||
|
current_period_key = current_period.key
|
||||||
|
without_current_period = [x for x in period_list if x.key != current_period.key]
|
||||||
|
# all period except current period(whence invoice was posted), should be '0'
|
||||||
|
for acc in result:
|
||||||
|
if acc:
|
||||||
|
with self.subTest(acc=acc):
|
||||||
|
for period in without_current_period:
|
||||||
|
self.assertEqual(acc[period.key], 0)
|
||||||
|
|
||||||
|
for acc in result:
|
||||||
|
if acc:
|
||||||
|
with self.subTest(current_period_key=current_period_key):
|
||||||
|
self.assertEqual(acc[current_period_key], 150)
|
||||||
|
self.assertEqual(acc["total"], 150)
|
Loading…
x
Reference in New Issue
Block a user