From 5c9ce575f65eb0d0282f38e23e7c5eebd628518b Mon Sep 17 00:00:00 2001 From: Dany Robert Date: Thu, 4 Apr 2024 16:18:20 +0000 Subject: [PATCH 1/4] fix: missing def expense if no exp in first month --- erpnext/accounts/deferred_revenue.py | 74 ++++++++++++++-------------- 1 file changed, 37 insertions(+), 37 deletions(-) diff --git a/erpnext/accounts/deferred_revenue.py b/erpnext/accounts/deferred_revenue.py index 3dc3e7ae1995..aa3cff75bb56 100644 --- a/erpnext/accounts/deferred_revenue.py +++ b/erpnext/accounts/deferred_revenue.py @@ -360,45 +360,45 @@ def _book_deferred_revenue_or_expense( ) if not amount: - return - - gl_posting_date = end_date - prev_posting_date = None - # check if books nor frozen till endate: - if accounts_frozen_upto and getdate(end_date) <= getdate(accounts_frozen_upto): - gl_posting_date = get_last_day(add_days(accounts_frozen_upto, 1)) prev_posting_date = end_date - - if via_journal_entry: - book_revenue_via_journal_entry( - doc, - credit_account, - debit_account, - amount, - base_amount, - gl_posting_date, - project, - account_currency, - item.cost_center, - item, - deferred_process, - submit_journal_entry, - ) else: - make_gl_entries( - doc, - credit_account, - debit_account, - against, - amount, - base_amount, - gl_posting_date, - project, - account_currency, - item.cost_center, - item, - deferred_process, - ) + gl_posting_date = end_date + prev_posting_date = None + # check if books nor frozen till endate: + if accounts_frozen_upto and getdate(end_date) <= getdate(accounts_frozen_upto): + gl_posting_date = get_last_day(add_days(accounts_frozen_upto, 1)) + prev_posting_date = end_date + + if via_journal_entry: + book_revenue_via_journal_entry( + doc, + credit_account, + debit_account, + amount, + base_amount, + gl_posting_date, + project, + account_currency, + item.cost_center, + item, + deferred_process, + submit_journal_entry, + ) + else: + make_gl_entries( + doc, + credit_account, + debit_account, + against, + amount, + base_amount, + gl_posting_date, + project, + account_currency, + item.cost_center, + item, + deferred_process, + ) # Returned in case of any errors because it tries to submit the same record again and again in case of errors if frappe.flags.deferred_accounting_error: From 7ef4dbcaf66e213bfd06c9e75cf7c0828f89dd63 Mon Sep 17 00:00:00 2001 From: Dany Robert Date: Fri, 5 Apr 2024 17:59:48 +0000 Subject: [PATCH 2/4] fix: test case for zero deferred expense --- .../test_deferred_revenue_and_expense.py | 75 +++++++++++++++++++ 1 file changed, 75 insertions(+) diff --git a/erpnext/accounts/report/deferred_revenue_and_expense/test_deferred_revenue_and_expense.py b/erpnext/accounts/report/deferred_revenue_and_expense/test_deferred_revenue_and_expense.py index f8a965b699cb..983eb0ee6af7 100644 --- a/erpnext/accounts/report/deferred_revenue_and_expense/test_deferred_revenue_and_expense.py +++ b/erpnext/accounts/report/deferred_revenue_and_expense/test_deferred_revenue_and_expense.py @@ -279,3 +279,78 @@ def test_zero_months(self): {"key": "aug_2021", "total": 0, "actual": 0}, ] self.assertEqual(report.period_total, expected) + + @change_settings("Accounts Settings", {"book_deferred_entries_based_on": "Months"}) + def test_zero_amount(self): + self.create_item("_Test Office Desk", 0, self.warehouse, self.company) + item = frappe.get_doc("Item", self.item) + item.enable_deferred_expense = 1 + item.item_defaults[0].deferred_expense_account = self.deferred_expense_account + item.no_of_months_exp = 12 + item.save() + + pi = make_purchase_invoice( + item=self.item, + company=self.company, + supplier=self.supplier, + is_return=False, + update_stock=False, + posting_date=frappe.utils.datetime.date(2023, 12, 30), + parent_cost_center=self.cost_center, + cost_center=self.cost_center, + do_not_save=True, + rate=3910, + price_list_rate=3910, + warehouse=self.warehouse, + qty=1, + ) + pi.set_posting_time = True + pi.items[0].enable_deferred_expense = 1 + pi.items[0].service_start_date = "2023-12-30" + pi.items[0].service_end_date = "2024-12-30" + pi.items[0].deferred_expense_account = self.deferred_expense_account + pi.items[0].expense_account = self.expense_account + pi.save() + pi.submit() + + pda = frappe.get_doc( + dict( + doctype="Process Deferred Accounting", + posting_date=nowdate(), + start_date="2024-01-01", + end_date="2024-01-31", + type="Expense", + company=self.company, + ) + ) + pda.insert() + pda.submit() + + # execute report + fiscal_year = frappe.get_doc("Fiscal Year", get_fiscal_year(date="2024-01-31")) + self.filters = frappe._dict( + { + "company": self.company, + "filter_based_on": "Date Range", + "period_start_date": "2024-01-01", + "period_end_date": "2024-01-31", + "from_fiscal_year": fiscal_year.year, + "to_fiscal_year": fiscal_year.year, + "periodicity": "Monthly", + "type": "Expense", + "with_upcoming_postings": False, + } + ) + + report = Deferred_Revenue_and_Expense_Report(filters=self.filters) + report.run() + + # fetch the invoice from deferred invoices list + inv = [d for d in report.deferred_invoices if d.name == pi.name] + # make sure the list isn't empty + self.assertTrue(inv) + # calculate the total deferred expense for the period + inv = inv[0].calculate_invoice_revenue_expense_for_period() + deferred_exp = sum([inv[idx].actual for idx in range(len(report.period_total))]) + # make sure the total deferred expense is greater than 0 + self.assertGreater(deferred_exp, 0) From 581af4ecedc3a8e134a8a1d545a789329d26fccc Mon Sep 17 00:00:00 2001 From: Dany Robert Date: Fri, 5 Apr 2024 18:16:26 +0000 Subject: [PATCH 3/4] chore: semgrep --- .../test_deferred_revenue_and_expense.py | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/erpnext/accounts/report/deferred_revenue_and_expense/test_deferred_revenue_and_expense.py b/erpnext/accounts/report/deferred_revenue_and_expense/test_deferred_revenue_and_expense.py index 983eb0ee6af7..5b848ac29556 100644 --- a/erpnext/accounts/report/deferred_revenue_and_expense/test_deferred_revenue_and_expense.py +++ b/erpnext/accounts/report/deferred_revenue_and_expense/test_deferred_revenue_and_expense.py @@ -314,14 +314,12 @@ def test_zero_amount(self): pi.submit() pda = frappe.get_doc( - dict( - doctype="Process Deferred Accounting", - posting_date=nowdate(), - start_date="2024-01-01", - end_date="2024-01-31", - type="Expense", - company=self.company, - ) + doctype="Process Deferred Accounting", + posting_date=nowdate(), + start_date="2024-01-01", + end_date="2024-01-31", + type="Expense", + company=self.company, ) pda.insert() pda.submit() @@ -351,6 +349,6 @@ def test_zero_amount(self): self.assertTrue(inv) # calculate the total deferred expense for the period inv = inv[0].calculate_invoice_revenue_expense_for_period() - deferred_exp = sum([inv[idx].actual for idx in range(len(report.period_total))]) + deferred_exp = sum([inv[idx].actual for idx in range(len(report.period_list))]) # make sure the total deferred expense is greater than 0 - self.assertGreater(deferred_exp, 0) + self.assertLess(deferred_exp, 0) From 01888c98bc8a9aaca42840381ce26bab7351510a Mon Sep 17 00:00:00 2001 From: Dany Robert Date: Sat, 6 Apr 2024 06:13:42 +0000 Subject: [PATCH 4/4] fix: expense causing p&l test case to fail --- .../test_deferred_revenue_and_expense.py | 21 +++++++++++-------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/erpnext/accounts/report/deferred_revenue_and_expense/test_deferred_revenue_and_expense.py b/erpnext/accounts/report/deferred_revenue_and_expense/test_deferred_revenue_and_expense.py index 5b848ac29556..4ca65dc04e5c 100644 --- a/erpnext/accounts/report/deferred_revenue_and_expense/test_deferred_revenue_and_expense.py +++ b/erpnext/accounts/report/deferred_revenue_and_expense/test_deferred_revenue_and_expense.py @@ -280,7 +280,10 @@ def test_zero_months(self): ] self.assertEqual(report.period_total, expected) - @change_settings("Accounts Settings", {"book_deferred_entries_based_on": "Months"}) + @change_settings( + "Accounts Settings", + {"book_deferred_entries_based_on": "Months", "book_deferred_entries_via_journal_entry": 0}, + ) def test_zero_amount(self): self.create_item("_Test Office Desk", 0, self.warehouse, self.company) item = frappe.get_doc("Item", self.item) @@ -295,7 +298,7 @@ def test_zero_amount(self): supplier=self.supplier, is_return=False, update_stock=False, - posting_date=frappe.utils.datetime.date(2023, 12, 30), + posting_date=frappe.utils.datetime.date(2021, 12, 30), parent_cost_center=self.cost_center, cost_center=self.cost_center, do_not_save=True, @@ -306,8 +309,8 @@ def test_zero_amount(self): ) pi.set_posting_time = True pi.items[0].enable_deferred_expense = 1 - pi.items[0].service_start_date = "2023-12-30" - pi.items[0].service_end_date = "2024-12-30" + pi.items[0].service_start_date = "2021-12-30" + pi.items[0].service_end_date = "2022-12-30" pi.items[0].deferred_expense_account = self.deferred_expense_account pi.items[0].expense_account = self.expense_account pi.save() @@ -316,8 +319,8 @@ def test_zero_amount(self): pda = frappe.get_doc( doctype="Process Deferred Accounting", posting_date=nowdate(), - start_date="2024-01-01", - end_date="2024-01-31", + start_date="2022-01-01", + end_date="2022-01-31", type="Expense", company=self.company, ) @@ -325,13 +328,13 @@ def test_zero_amount(self): pda.submit() # execute report - fiscal_year = frappe.get_doc("Fiscal Year", get_fiscal_year(date="2024-01-31")) + fiscal_year = frappe.get_doc("Fiscal Year", get_fiscal_year(date="2022-01-31")) self.filters = frappe._dict( { "company": self.company, "filter_based_on": "Date Range", - "period_start_date": "2024-01-01", - "period_end_date": "2024-01-31", + "period_start_date": "2022-01-01", + "period_end_date": "2022-01-31", "from_fiscal_year": fiscal_year.year, "to_fiscal_year": fiscal_year.year, "periodicity": "Monthly",