From 9901746e029c36c73689f777e0d34969a271ee83 Mon Sep 17 00:00:00 2001 From: Nabin Hait Date: Fri, 3 Jul 2026 11:43:02 +0530 Subject: [PATCH 1/3] test: add coverage for Repost Payment Ledger --- .../test_repost_payment_ledger.py | 47 +++++++++++++++++-- 1 file changed, 43 insertions(+), 4 deletions(-) diff --git a/erpnext/accounts/doctype/repost_payment_ledger/test_repost_payment_ledger.py b/erpnext/accounts/doctype/repost_payment_ledger/test_repost_payment_ledger.py index 8c2b8946121..3ba4ec15de7 100644 --- a/erpnext/accounts/doctype/repost_payment_ledger/test_repost_payment_ledger.py +++ b/erpnext/accounts/doctype/repost_payment_ledger/test_repost_payment_ledger.py @@ -1,11 +1,50 @@ -# Copyright (c) 2022, Frappe Technologies Pvt. Ltd. and Contributors +# Copyright (c) 2026, Frappe Technologies Pvt. Ltd. and Contributors # See license.txt -# import frappe - +import frappe +from erpnext.accounts.doctype.sales_invoice.test_sales_invoice import create_sales_invoice from erpnext.tests.utils import ERPNextTestSuite +COMPANY = "_Test Company" + class TestRepostPaymentLedger(ERPNextTestSuite): - pass + """Repost Payment Ledger auto-selects submitted vouchers on/after a cutoff date + (unless rows are added manually) and queues them for a ledger rebuild.""" + + def setUp(self): + frappe.set_user("Administrator") + + def make_repost(self, **args): + args = frappe._dict(args) + doc = frappe.new_doc("Repost Payment Ledger") + doc.company = COMPANY + doc.posting_date = args.get("posting_date", "2026-06-01") + doc.voucher_type = args.get("voucher_type", "Sales Invoice") + doc.add_manually = args.get("add_manually", 0) + return doc + + def test_loads_submitted_vouchers_on_or_after_cutoff(self): + in_range = create_sales_invoice(company=COMPANY, posting_date="2026-06-15", rate=100, qty=1) + before_cutoff = create_sales_invoice(company=COMPANY, posting_date="2026-01-15", rate=100, qty=1) + + doc = self.make_repost(posting_date="2026-06-01", voucher_type="Sales Invoice") + doc.save() # before_validate loads the vouchers and sets status + + loaded = {v.voucher_no for v in doc.repost_vouchers} + self.assertIn(in_range.name, loaded) + self.assertNotIn(before_cutoff.name, loaded) + self.assertEqual(doc.repost_status, "Queued") + + def test_add_manually_preserves_user_rows(self): + # a Sales Invoice that WOULD match the filter, to prove manual mode ignores it + si = create_sales_invoice(company=COMPANY, posting_date="2026-06-15", rate=100, qty=1) + + doc = self.make_repost(add_manually=1) + doc.append("repost_vouchers", {"voucher_type": "Sales Invoice", "voucher_no": si.name}) + doc.save() + + rows = [(v.voucher_type, v.voucher_no) for v in doc.repost_vouchers] + # the row is kept exactly as entered; no filter-based auto-loading happens + self.assertEqual(rows, [("Sales Invoice", si.name)]) From f68f53dec008727f7a17ad69692d0788d8848e3f Mon Sep 17 00:00:00 2001 From: Nabin Hait Date: Fri, 3 Jul 2026 12:09:10 +0530 Subject: [PATCH 2/3] test: cover on-cutoff boundary in voucher loading --- .../repost_payment_ledger/test_repost_payment_ledger.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/erpnext/accounts/doctype/repost_payment_ledger/test_repost_payment_ledger.py b/erpnext/accounts/doctype/repost_payment_ledger/test_repost_payment_ledger.py index 3ba4ec15de7..98c7929f09a 100644 --- a/erpnext/accounts/doctype/repost_payment_ledger/test_repost_payment_ledger.py +++ b/erpnext/accounts/doctype/repost_payment_ledger/test_repost_payment_ledger.py @@ -26,14 +26,17 @@ class TestRepostPaymentLedger(ERPNextTestSuite): return doc def test_loads_submitted_vouchers_on_or_after_cutoff(self): - in_range = create_sales_invoice(company=COMPANY, posting_date="2026-06-15", rate=100, qty=1) + after_cutoff = create_sales_invoice(company=COMPANY, posting_date="2026-06-15", rate=100, qty=1) + on_cutoff = create_sales_invoice(company=COMPANY, posting_date="2026-06-01", rate=100, qty=1) before_cutoff = create_sales_invoice(company=COMPANY, posting_date="2026-01-15", rate=100, qty=1) doc = self.make_repost(posting_date="2026-06-01", voucher_type="Sales Invoice") doc.save() # before_validate loads the vouchers and sets status loaded = {v.voucher_no for v in doc.repost_vouchers} - self.assertIn(in_range.name, loaded) + self.assertIn(after_cutoff.name, loaded) + # the filter is >= so an invoice posted exactly on the cutoff is included + self.assertIn(on_cutoff.name, loaded) self.assertNotIn(before_cutoff.name, loaded) self.assertEqual(doc.repost_status, "Queued") From 4c26ec8cd9a3e22c2d290d36c09063d4bdc88e68 Mon Sep 17 00:00:00 2001 From: Nabin Hait Date: Fri, 3 Jul 2026 14:26:00 +0530 Subject: [PATCH 3/3] test: make add_manually test distinguish manual mode from auto-loading --- .../test_repost_payment_ledger.py | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/erpnext/accounts/doctype/repost_payment_ledger/test_repost_payment_ledger.py b/erpnext/accounts/doctype/repost_payment_ledger/test_repost_payment_ledger.py index 98c7929f09a..c0498adb8a4 100644 --- a/erpnext/accounts/doctype/repost_payment_ledger/test_repost_payment_ledger.py +++ b/erpnext/accounts/doctype/repost_payment_ledger/test_repost_payment_ledger.py @@ -41,13 +41,15 @@ class TestRepostPaymentLedger(ERPNextTestSuite): self.assertEqual(doc.repost_status, "Queued") def test_add_manually_preserves_user_rows(self): - # a Sales Invoice that WOULD match the filter, to prove manual mode ignores it - si = create_sales_invoice(company=COMPANY, posting_date="2026-06-15", rate=100, qty=1) + # manually add a BEFORE-cutoff invoice (which the filter would never load) while a + # matching after-cutoff invoice also exists. If auto-loading wrongly ran it would + # drop the manual row and pull the after-cutoff one, so this distinguishes the modes. + manual_si = create_sales_invoice(company=COMPANY, posting_date="2026-01-15", rate=100, qty=1) + create_sales_invoice(company=COMPANY, posting_date="2026-06-15", rate=100, qty=1) - doc = self.make_repost(add_manually=1) - doc.append("repost_vouchers", {"voucher_type": "Sales Invoice", "voucher_no": si.name}) + doc = self.make_repost(add_manually=1, posting_date="2026-06-01") + doc.append("repost_vouchers", {"voucher_type": "Sales Invoice", "voucher_no": manual_si.name}) doc.save() rows = [(v.voucher_type, v.voucher_no) for v in doc.repost_vouchers] - # the row is kept exactly as entered; no filter-based auto-loading happens - self.assertEqual(rows, [("Sales Invoice", si.name)]) + self.assertEqual(rows, [("Sales Invoice", manual_si.name)])