Compare commits

...

2 Commits

Author SHA1 Message Date
Nabin Hait
824415d50e test: cover AR/AP show-remarks, delivery notes and group-by-party filters
Add coverage for previously untested checkbox filters: Show Remarks (the
invoice remark appears in the row) and Show Linked Delivery Notes on the
receivable report, and Show Remarks and Group By Supplier on the payable
report.
2026-06-23 11:32:31 +05:30
Nabin Hait
8c124ed4a9 test: cover AR/AP journal-entry payments and credit notes
The receivable/payable reports lacked coverage for settling invoices via a
Journal Entry (rather than a Payment Entry) and for credit notes raised via
JE. Add: an invoice partially and fully paid via JE on the receivable side,
a standalone JE credit note showing as negative outstanding, and a supplier
invoice partially paid via JE on the payable side.
2026-06-23 11:04:17 +05:30
2 changed files with 191 additions and 0 deletions

View File

@@ -54,6 +54,84 @@ class TestAccountsPayable(ERPNextTestSuite, AccountsTestMixin):
pi = pi.submit()
return pi
def test_invoice_partially_paid_via_journal_entry(self):
pi = self.create_purchase_invoice() # outstanding 300
je = frappe.new_doc("Journal Entry")
je.company = self.company
je.posting_date = today()
je.append(
"accounts",
{
"account": "Creditors - _TC",
"party_type": "Supplier",
"party": self.supplier,
"debit": 120,
"debit_in_account_currency": 120,
"reference_type": "Purchase Invoice",
"reference_name": pi.name,
"cost_center": "Main - _TC",
},
)
je.append(
"accounts",
{
"account": "Cash - _TC",
"credit": 120,
"credit_in_account_currency": 120,
"cost_center": "Main - _TC",
},
)
je.save().submit()
filters = {
"company": self.company,
"party_type": "Supplier",
"party": [self.supplier],
"report_date": today(),
"range": "30, 60, 90, 120",
}
row = next(row for row in execute(filters)[1] if row.voucher_no == pi.name)
self.assertEqual(row.paid, 120)
self.assertEqual(row.outstanding, 180)
def test_show_remarks_includes_invoice_remark(self):
pi = self.create_purchase_invoice(do_not_submit=True)
pi.remarks = "AP test remark"
pi.save().submit()
filters = {
"company": self.company,
"party_type": "Supplier",
"party": [self.supplier],
"report_date": today(),
"range": "30, 60, 90, 120",
"show_remarks": 1,
}
row = next(row for row in execute(filters)[1] if row.voucher_no == pi.name)
self.assertIn("AP test remark", row.remarks or "")
def test_group_by_supplier_totals(self):
self.create_purchase_invoice() # outstanding 300
filters = {
"company": self.company,
"party_type": "Supplier",
"party": [self.supplier],
"report_date": today(),
"range": "30, 60, 90, 120",
"group_by_party": True,
}
report = execute(filters)[1]
# a per-supplier subtotal row plus a grand total row
party_subtotal = next(
row for row in report if row.get("party") == self.supplier and not row.get("voucher_no")
)
grand_total = next(row for row in report if row.get("party") == "Total")
self.assertEqual(party_subtotal.get("invoiced"), 300)
self.assertEqual(grand_total.get("outstanding"), 300)
def test_payment_terms_template_filters(self):
from erpnext.controllers.accounts_controller import get_payment_terms

View File

@@ -568,6 +568,119 @@ class TestAccountsReceivable(ERPNextTestSuite, AccountsTestMixin):
report = execute(filters)
self.assertEqual(report[1], [])
def pay_invoice_via_journal_entry(self, si, amount):
je = frappe.new_doc("Journal Entry")
je.company = self.company
je.posting_date = today()
je.append(
"accounts",
{
"account": self.cash,
"debit": amount,
"debit_in_account_currency": amount,
"cost_center": self.cost_center,
},
)
je.append(
"accounts",
{
"account": self.debit_to,
"party_type": "Customer",
"party": self.customer,
"credit": amount,
"credit_in_account_currency": amount,
"reference_type": "Sales Invoice",
"reference_name": si.name,
"cost_center": self.cost_center,
},
)
return je.save().submit()
def ar_rows(self):
filters = {"company": self.company, "report_date": today(), "range": "30, 60, 90, 120"}
return execute(filters)[1]
def test_invoice_partially_paid_via_journal_entry(self):
si = self.create_sales_invoice(no_payment_schedule=True) # outstanding 100
self.pay_invoice_via_journal_entry(si, 40)
row = next(row for row in self.ar_rows() if row.voucher_no == si.name)
self.assertEqual(row.paid, 40)
self.assertEqual(row.outstanding, 60)
def test_invoice_fully_paid_via_journal_entry(self):
si = self.create_sales_invoice(no_payment_schedule=True) # outstanding 100
self.pay_invoice_via_journal_entry(si, 100)
# a fully settled invoice drops out of the receivable report
self.assertEqual([row for row in self.ar_rows() if row.voucher_no == si.name], [])
def test_credit_note_via_journal_entry_shows_negative_outstanding(self):
je = frappe.new_doc("Journal Entry")
je.company = self.company
je.voucher_type = "Credit Note"
je.posting_date = today()
je.append(
"accounts",
{
"account": self.income_account,
"debit": 100,
"debit_in_account_currency": 100,
"cost_center": self.cost_center,
},
)
je.append(
"accounts",
{
"account": self.debit_to,
"party_type": "Customer",
"party": self.customer,
"credit": 100,
"credit_in_account_currency": 100,
"cost_center": self.cost_center,
},
)
je = je.save().submit()
row = next(row for row in self.ar_rows() if row.voucher_no == je.name)
self.assertEqual(row.outstanding, -100)
def test_show_remarks_includes_invoice_remark(self):
si = self.create_sales_invoice(no_payment_schedule=True, do_not_submit=True)
si.remarks = "AR test remark"
si.save().submit()
filters = {
"company": self.company,
"report_date": today(),
"range": "30, 60, 90, 120",
"show_remarks": 1,
}
row = next(row for row in execute(filters)[1] if row.voucher_no == si.name)
self.assertIn("AR test remark", row.remarks or "")
def test_show_delivery_notes_links_delivery_note(self):
from erpnext.stock.doctype.delivery_note.mapper import make_sales_invoice
from erpnext.stock.doctype.delivery_note.test_delivery_note import create_delivery_note
from erpnext.stock.doctype.stock_entry.stock_entry_utils import make_stock_entry
make_stock_entry(item_code=self.item, qty=5, to_warehouse=self.warehouse, basic_rate=100)
dn = create_delivery_note(
customer=self.customer, item=self.item, warehouse=self.warehouse, cost_center=self.cost_center
)
si = make_sales_invoice(dn.name)
si.insert()
si.submit()
filters = {
"company": self.company,
"report_date": today(),
"range": "30, 60, 90, 120",
"show_delivery_notes": 1,
}
row = next(row for row in execute(filters)[1] if row.voucher_no == si.name)
self.assertIn(dn.name, row.delivery_notes or "")
def test_group_by_party(self):
si1 = self.create_sales_invoice(do_not_submit=True)
si1.posting_date = add_days(today(), -1)