mirror of
https://github.com/frappe/erpnext.git
synced 2026-08-26 13:25:20 +00:00
test: add end-to-end procure-to-pay flow coverage
Cross-document integration tests for the purchase cycle: - full chain: Purchase Order -> Receipt -> Invoice -> Payment, asserting received/billed status propagation and that outstanding clears on payment - partial receipt and billing propagates the right percentages and status - a submitted Purchase Order marks its source Material Request as Ordered - a purchase return reduces the received qty on the originating order
This commit is contained in:
92
erpnext/tests/test_procure_to_pay_flow.py
Normal file
92
erpnext/tests/test_procure_to_pay_flow.py
Normal file
@@ -0,0 +1,92 @@
|
|||||||
|
# Copyright (c) 2026, Frappe Technologies Pvt. Ltd. and Contributors
|
||||||
|
# See license.txt
|
||||||
|
|
||||||
|
"""End-to-end procure-to-pay flow tests.
|
||||||
|
|
||||||
|
These exercise the full purchase cycle across module boundaries and assert that
|
||||||
|
quantity/billing status propagates between documents and that the money and
|
||||||
|
stock invariants hold (outstanding cleared on payment, received qty reduced on
|
||||||
|
return).
|
||||||
|
"""
|
||||||
|
|
||||||
|
import frappe
|
||||||
|
from frappe.utils import flt
|
||||||
|
|
||||||
|
from erpnext.accounts.doctype.payment_entry.payment_entry import get_payment_entry
|
||||||
|
from erpnext.buying.doctype.purchase_order.mapper import make_purchase_receipt
|
||||||
|
from erpnext.buying.doctype.purchase_order.test_purchase_order import create_purchase_order
|
||||||
|
from erpnext.controllers.sales_and_purchase_return import make_return_doc
|
||||||
|
from erpnext.stock.doctype.material_request.mapper import make_purchase_order
|
||||||
|
from erpnext.stock.doctype.material_request.test_material_request import make_material_request
|
||||||
|
from erpnext.stock.doctype.purchase_receipt.mapper import make_purchase_invoice
|
||||||
|
from erpnext.tests.utils import ERPNextTestSuite
|
||||||
|
|
||||||
|
|
||||||
|
class TestProcureToPayFlow(ERPNextTestSuite):
|
||||||
|
def test_full_chain_po_to_receipt_to_invoice_to_payment(self):
|
||||||
|
po = create_purchase_order(qty=10, rate=100) # total 1000
|
||||||
|
|
||||||
|
pr = make_purchase_receipt(po.name)
|
||||||
|
pr.submit()
|
||||||
|
po.reload()
|
||||||
|
self.assertEqual(po.per_received, 100)
|
||||||
|
|
||||||
|
pi = make_purchase_invoice(pr.name)
|
||||||
|
pi.submit()
|
||||||
|
po.reload()
|
||||||
|
self.assertEqual(po.per_billed, 100)
|
||||||
|
self.assertEqual(flt(pi.outstanding_amount), 1000)
|
||||||
|
|
||||||
|
pe = get_payment_entry("Purchase Invoice", pi.name, bank_account="_Test Cash - _TC")
|
||||||
|
pe.submit()
|
||||||
|
|
||||||
|
outstanding, status = frappe.db.get_value(
|
||||||
|
"Purchase Invoice", pi.name, ["outstanding_amount", "status"]
|
||||||
|
)
|
||||||
|
self.assertEqual(flt(outstanding), 0)
|
||||||
|
self.assertEqual(status, "Paid")
|
||||||
|
|
||||||
|
def test_partial_receipt_and_billing_propagates_status(self):
|
||||||
|
po = create_purchase_order(qty=10, rate=100)
|
||||||
|
|
||||||
|
pr = make_purchase_receipt(po.name)
|
||||||
|
pr.items[0].qty = 6
|
||||||
|
pr.submit()
|
||||||
|
po.reload()
|
||||||
|
self.assertEqual(po.per_received, 60)
|
||||||
|
# still has qty left to receive and nothing billed yet
|
||||||
|
self.assertEqual(po.status, "To Receive and Bill")
|
||||||
|
|
||||||
|
pi = make_purchase_invoice(pr.name)
|
||||||
|
pi.submit()
|
||||||
|
po.reload()
|
||||||
|
self.assertEqual(po.per_billed, 60)
|
||||||
|
|
||||||
|
def test_material_request_to_purchase_order_marks_it_ordered(self):
|
||||||
|
mr = make_material_request(qty=10)
|
||||||
|
|
||||||
|
po = make_purchase_order(mr.name)
|
||||||
|
po.supplier = "_Test Supplier"
|
||||||
|
for item in po.items:
|
||||||
|
item.rate = 100
|
||||||
|
po.submit()
|
||||||
|
|
||||||
|
mr.reload()
|
||||||
|
self.assertEqual(mr.per_ordered, 100)
|
||||||
|
self.assertEqual(mr.status, "Ordered")
|
||||||
|
|
||||||
|
def test_purchase_return_reduces_received_qty_on_order(self):
|
||||||
|
po = create_purchase_order(qty=10, rate=100)
|
||||||
|
|
||||||
|
pr = make_purchase_receipt(po.name)
|
||||||
|
pr.submit()
|
||||||
|
po.reload()
|
||||||
|
self.assertEqual(po.per_received, 100)
|
||||||
|
|
||||||
|
return_pr = make_return_doc("Purchase Receipt", pr.name)
|
||||||
|
return_pr.items[0].qty = -4
|
||||||
|
return_pr.items[0].received_qty = -4
|
||||||
|
return_pr.submit()
|
||||||
|
|
||||||
|
po.reload()
|
||||||
|
self.assertEqual(po.per_received, 60)
|
||||||
Reference in New Issue
Block a user