From e9bcb1bbb2a16a713627f06539f1c29e70421fb9 Mon Sep 17 00:00:00 2001 From: ruthra kumar Date: Fri, 2 Aug 2024 15:43:04 +0530 Subject: [PATCH 1/6] refactor: ignore filter in general ledger for cr / dr notes (cherry picked from commit 59d5beee20f4a3837b1bcd74e6826d4b7290c0fb) --- erpnext/accounts/report/general_ledger/general_ledger.js | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/erpnext/accounts/report/general_ledger/general_ledger.js b/erpnext/accounts/report/general_ledger/general_ledger.js index 1894e958552..e202d5dfffd 100644 --- a/erpnext/accounts/report/general_ledger/general_ledger.js +++ b/erpnext/accounts/report/general_ledger/general_ledger.js @@ -209,6 +209,11 @@ frappe.query_reports["General Ledger"] = { label: __("Ignore Exchange Rate Revaluation Journals"), fieldtype: "Check", }, + { + fieldname: "ignore_cr_dr_notes", + label: __("Ignore System Generated Credit / Debit Notes"), + fieldtype: "Check", + }, ], }; From 17a6224a3f13a434ee954ba7f6b3b53cf7e4a892 Mon Sep 17 00:00:00 2001 From: ruthra kumar Date: Fri, 2 Aug 2024 15:47:27 +0530 Subject: [PATCH 2/6] refactor: ignore system generated cr / dr notes on general ledger (cherry picked from commit bb8c9b5a5845d2db3cd96f0264132c0e9b4a1e6e) --- .../report/general_ledger/general_ledger.py | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/erpnext/accounts/report/general_ledger/general_ledger.py b/erpnext/accounts/report/general_ledger/general_ledger.py index 4b20746286a..63e57438fca 100644 --- a/erpnext/accounts/report/general_ledger/general_ledger.py +++ b/erpnext/accounts/report/general_ledger/general_ledger.py @@ -236,6 +236,20 @@ def get_conditions(filters): if err_journals: filters.update({"voucher_no_not_in": [x[0] for x in err_journals]}) + if filters.get("ignore_cr_dr_notes"): + system_generated_cr_dr_journals = frappe.db.get_all( + "Journal Entry", + filters={ + "company": filters.get("company"), + "docstatus": 1, + "voucher_type": ("in", ["Credit Note", "Debit Note"]), + "is_system_generated": 1, + }, + as_list=True, + ) + if system_generated_cr_dr_journals: + filters.update({"voucher_no_not_in": [x[0] for x in system_generated_cr_dr_journals]}) + if filters.get("voucher_no_not_in"): conditions.append("voucher_no not in %(voucher_no_not_in)s") From 7ec7e11634fea52be14e68b279f9fef38b078c0e Mon Sep 17 00:00:00 2001 From: ruthra kumar Date: Mon, 5 Aug 2024 09:56:16 +0530 Subject: [PATCH 3/6] test: ignore filter for system generated cr / dr note journals (cherry picked from commit 3ffac735985a1b0d55b3265d5299ff6d0cf6e93a) --- .../general_ledger/test_general_ledger.py | 72 +++++++++++++++++++ 1 file changed, 72 insertions(+) diff --git a/erpnext/accounts/report/general_ledger/test_general_ledger.py b/erpnext/accounts/report/general_ledger/test_general_ledger.py index 33b356feb33..682eef8f419 100644 --- a/erpnext/accounts/report/general_ledger/test_general_ledger.py +++ b/erpnext/accounts/report/general_ledger/test_general_ledger.py @@ -5,7 +5,9 @@ import frappe from frappe.tests.utils import FrappeTestCase from frappe.utils import flt, today +from erpnext.accounts.doctype.sales_invoice.test_sales_invoice import create_sales_invoice from erpnext.accounts.report.general_ledger.general_ledger import execute +from erpnext.controllers.sales_and_purchase_return import make_return_doc class TestGeneralLedger(FrappeTestCase): @@ -248,3 +250,73 @@ class TestGeneralLedger(FrappeTestCase): ) ) self.assertIn(revaluation_jv.name, set([x.voucher_no for x in data])) + + def test_ignore_cr_dr_notes_filter(self): + si = create_sales_invoice() + + cr_note = make_return_doc(si.doctype, si.name) + cr_note.submit() + + pr = frappe.get_doc("Payment Reconciliation") + pr.company = si.company + pr.party_type = "Customer" + pr.party = si.customer + pr.receivable_payable_account = si.debit_to + + pr.get_unreconciled_entries() + self.assertEqual(len(pr.invoices), 1) + self.assertEqual(len(pr.payments), 1) + + invoices = [invoice.as_dict() for invoice in pr.invoices] + payments = [payment.as_dict() for payment in pr.payments] + pr.allocate_entries(frappe._dict({"invoices": invoices, "payments": payments})) + pr.reconcile() + + self.assertEqual(len(pr.invoices), 0) + self.assertEqual(len(pr.payments), 0) + + system_generated_journal = frappe.db.get_all( + "Journal Entry", + filters={ + "docstatus": 1, + "reference_type": si.doctype, + "reference_name": si.name, + "voucher_type": "Credit Note", + "is_system_generated": True, + }, + fields=["name"], + ) + self.assertEqual(len(system_generated_journal), 1) + expected = set([si.name, cr_note.name, system_generated_journal[0].name]) + # Without ignore_cr_dr_notes + columns, data = execute( + frappe._dict( + { + "company": si.company, + "from_date": si.posting_date, + "to_date": si.posting_date, + "account": [si.debit_to], + "group_by": "Group by Voucher (Consolidated)", + "ignore_cr_dr_notes": False, + } + ) + ) + actual = set([x.voucher_no for x in data if x.voucher_no]) + self.assertEqual(expected, actual) + + # Without ignore_cr_dr_notes + expected = set([si.name, cr_note.name]) + columns, data = execute( + frappe._dict( + { + "company": si.company, + "from_date": si.posting_date, + "to_date": si.posting_date, + "account": [si.debit_to], + "group_by": "Group by Voucher (Consolidated)", + "ignore_cr_dr_notes": True, + } + ) + ) + actual = set([x.voucher_no for x in data if x.voucher_no]) + self.assertEqual(expected, actual) From 3ee59918965f301a5d3d74c084e05729eb420963 Mon Sep 17 00:00:00 2001 From: ruthra kumar Date: Mon, 5 Aug 2024 09:58:50 +0530 Subject: [PATCH 4/6] refactor: make use of date filters on ignore filterss (cherry picked from commit 03f3ab522f54612f557a7d2f715367daf8bc370e) --- erpnext/accounts/report/general_ledger/general_ledger.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/erpnext/accounts/report/general_ledger/general_ledger.py b/erpnext/accounts/report/general_ledger/general_ledger.py index 63e57438fca..02ecc24dea1 100644 --- a/erpnext/accounts/report/general_ledger/general_ledger.py +++ b/erpnext/accounts/report/general_ledger/general_ledger.py @@ -230,6 +230,7 @@ def get_conditions(filters): "company": filters.get("company"), "docstatus": 1, "voucher_type": ("in", ["Exchange Rate Revaluation", "Exchange Gain Or Loss"]), + "posting_date": ["between", [filters.get("from_date"), filters.get("to_date")]], }, as_list=True, ) @@ -244,6 +245,7 @@ def get_conditions(filters): "docstatus": 1, "voucher_type": ("in", ["Credit Note", "Debit Note"]), "is_system_generated": 1, + "posting_date": ["between", [filters.get("from_date"), filters.get("to_date")]], }, as_list=True, ) From 155ca14b19568c62ae1ee3d9964d3f900b62c9b9 Mon Sep 17 00:00:00 2001 From: ruthra kumar Date: Mon, 5 Aug 2024 10:23:52 +0530 Subject: [PATCH 5/6] test: clear old data (cherry picked from commit 991069bfbcfba4ef46bae028dcdc908e785f693f) --- .../accounts/report/general_ledger/test_general_ledger.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/erpnext/accounts/report/general_ledger/test_general_ledger.py b/erpnext/accounts/report/general_ledger/test_general_ledger.py index 682eef8f419..094da52e68a 100644 --- a/erpnext/accounts/report/general_ledger/test_general_ledger.py +++ b/erpnext/accounts/report/general_ledger/test_general_ledger.py @@ -2,6 +2,7 @@ # MIT License. See license.txt import frappe +from frappe import qb from frappe.tests.utils import FrappeTestCase from frappe.utils import flt, today @@ -252,6 +253,10 @@ class TestGeneralLedger(FrappeTestCase): self.assertIn(revaluation_jv.name, set([x.voucher_no for x in data])) def test_ignore_cr_dr_notes_filter(self): + # Clear old data + sinv_doctype = qb.DocType("Sales Invoice") + qb.from_(sinv_doctype).delete().where(sinv_doctype.company.eq("_Test Company")).run() + si = create_sales_invoice() cr_note = make_return_doc(si.doctype, si.name) From c1bfa0a31a1ecd2256060f5cb5bbef5e946117c9 Mon Sep 17 00:00:00 2001 From: ruthra kumar Date: Mon, 5 Aug 2024 10:46:35 +0530 Subject: [PATCH 6/6] refactor(test): filter and reconcile concerned vouchers (cherry picked from commit 9ade269b7a66a72a7858aad47704da6038a26094) --- .../report/general_ledger/test_general_ledger.py | 13 ++----------- 1 file changed, 2 insertions(+), 11 deletions(-) diff --git a/erpnext/accounts/report/general_ledger/test_general_ledger.py b/erpnext/accounts/report/general_ledger/test_general_ledger.py index 094da52e68a..1a935bd05d7 100644 --- a/erpnext/accounts/report/general_ledger/test_general_ledger.py +++ b/erpnext/accounts/report/general_ledger/test_general_ledger.py @@ -253,10 +253,6 @@ class TestGeneralLedger(FrappeTestCase): self.assertIn(revaluation_jv.name, set([x.voucher_no for x in data])) def test_ignore_cr_dr_notes_filter(self): - # Clear old data - sinv_doctype = qb.DocType("Sales Invoice") - qb.from_(sinv_doctype).delete().where(sinv_doctype.company.eq("_Test Company")).run() - si = create_sales_invoice() cr_note = make_return_doc(si.doctype, si.name) @@ -269,17 +265,12 @@ class TestGeneralLedger(FrappeTestCase): pr.receivable_payable_account = si.debit_to pr.get_unreconciled_entries() - self.assertEqual(len(pr.invoices), 1) - self.assertEqual(len(pr.payments), 1) - invoices = [invoice.as_dict() for invoice in pr.invoices] - payments = [payment.as_dict() for payment in pr.payments] + invoices = [invoice.as_dict() for invoice in pr.invoices if invoice.invoice_number == si.name] + payments = [payment.as_dict() for payment in pr.payments if payment.reference_name == cr_note.name] pr.allocate_entries(frappe._dict({"invoices": invoices, "payments": payments})) pr.reconcile() - self.assertEqual(len(pr.invoices), 0) - self.assertEqual(len(pr.payments), 0) - system_generated_journal = frappe.db.get_all( "Journal Entry", filters={