From 4d951c1cf8d7811c5d54c329e0f77daf2cfc5d91 Mon Sep 17 00:00:00 2001 From: SandraFrappe Date: Tue, 14 Jul 2026 14:32:06 +0530 Subject: [PATCH] fix: prevent duplicate material request items in purchase order (cherry picked from commit 2d6f89a7f58856b7ee52b646f696adac2483331c) --- .../doctype/purchase_order/purchase_order.py | 1 + .../purchase_order/test_purchase_order.py | 17 +++++++++++++++++ 2 files changed, 18 insertions(+) diff --git a/erpnext/buying/doctype/purchase_order/purchase_order.py b/erpnext/buying/doctype/purchase_order/purchase_order.py index c5975b1a35e..72ae897b745 100644 --- a/erpnext/buying/doctype/purchase_order/purchase_order.py +++ b/erpnext/buying/doctype/purchase_order/purchase_order.py @@ -270,6 +270,7 @@ class PurchaseOrder(BuyingController): "ref_dn_field": "material_request_item", "compare_fields": mri_compare_fields, "is_child_table": True, + "allow_duplicate_prev_row_id": True, }, } ) diff --git a/erpnext/buying/doctype/purchase_order/test_purchase_order.py b/erpnext/buying/doctype/purchase_order/test_purchase_order.py index 7f934489b13..6fcb93fbb96 100644 --- a/erpnext/buying/doctype/purchase_order/test_purchase_order.py +++ b/erpnext/buying/doctype/purchase_order/test_purchase_order.py @@ -166,6 +166,23 @@ class TestPurchaseOrder(ERPNextTestSuite): frappe.db.set_single_value("Buying Settings", "over_order_allowance", 0) frappe.db.set_single_value("Stock Settings", "over_delivery_receipt_allowance", 0) + def test_duplicate_material_request_item_row_allowed(self): + """Splitting a Material Request Item's qty across multiple PO rows must be + allowed, mirroring how Sales Order allows duplicate Quotation Item rows.""" + mr = make_material_request(qty=10) + po = make_purchase_order(mr.name) + po.supplier = "_Test Supplier" + + duplicate_row = po.items[0].as_dict() + duplicate_row.qty = 4 + po.items[0].qty = 6 + + po.append("items", duplicate_row) + po.save() + + self.assertEqual(len(po.items), 2) + self.assertEqual(po.items[0].material_request_item, po.items[1].material_request_item) + def test_update_remove_child_linked_to_mr(self): """Test impact on linked PO and MR on deleting/updating row.""" mr = make_material_request(qty=10)