From 2c6749a46b76a1a24a6a6e5d5c1cd7405f7551b8 Mon Sep 17 00:00:00 2001 From: Pugazhendhi Velu Date: Thu, 6 Nov 2025 19:59:42 +0000 Subject: [PATCH 1/2] fix: material request item quantity validation against sales order with over-receipt allowance --- .../material_request/material_request.py | 23 +++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/erpnext/stock/doctype/material_request/material_request.py b/erpnext/stock/doctype/material_request/material_request.py index 2738f4d849..96d19c0c85 100644 --- a/erpnext/stock/doctype/material_request/material_request.py +++ b/erpnext/stock/doctype/material_request/material_request.py @@ -81,6 +81,21 @@ class MaterialRequest(BuyingController): work_order: DF.Link | None # end: auto-generated types + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + self.status_updater = [ + { + "source_dt": "Material Request Item", + "target_dt": "Sales Order Item", + "target_field": "ordered_qty", + "target_parent_dt": "Sales Order", + "target_parent_field": "", + "join_field": "sales_order_item", + "target_ref_field": "stock_qty", + "source_field": "stock_qty", + } + ] + def check_if_already_pulled(self): pass @@ -204,10 +219,10 @@ class MaterialRequest(BuyingController): def on_submit(self): self.update_requested_qty_in_production_plan() self.update_requested_qty() - if self.material_request_type == "Purchase" and frappe.db.exists( - "Budget", {"applicable_on_material_request": 1, "docstatus": 1} - ): - self.validate_budget() + if self.material_request_type == "Purchase": + self.update_prevdoc_status() + if frappe.db.exists("Budget", {"applicable_on_material_request": 1, "docstatus": 1}): + self.validate_budget() def before_save(self): self.set_status(update=True) -- GitLab From 32c6aeab9be91ad2f9042034c168d1dc1f855ea8 Mon Sep 17 00:00:00 2001 From: Pugazhendhi Velu Date: Thu, 6 Nov 2025 20:06:07 +0000 Subject: [PATCH 2/2] test: add test for validate mr item qty against so with over-receipt allowance --- .../material_request/test_material_request.py | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/erpnext/stock/doctype/material_request/test_material_request.py b/erpnext/stock/doctype/material_request/test_material_request.py index 0ee49ecf0f..46191bb389 100644 --- a/erpnext/stock/doctype/material_request/test_material_request.py +++ b/erpnext/stock/doctype/material_request/test_material_request.py @@ -931,6 +931,18 @@ class TestMaterialRequest(IntegrationTestCase): self.assertEqual(mr.per_ordered, 100) self.assertEqual(mr.status, "Ordered") + def test_material_request_qty_over_sales_order_limit(self): + from erpnext.controllers.status_updater import OverAllowanceError + from erpnext.selling.doctype.sales_order.test_sales_order import make_sales_order + + so = make_sales_order() + mr = make_material_request(qty=100, do_not_submit=True) + mr.items[0].sales_order = so.name + mr.items[0].sales_order_item = so.items[0].name + mr.save() + + self.assertRaises(OverAllowanceError, mr.submit) + def get_in_transit_warehouse(company): if not frappe.db.exists("Warehouse Type", "Transit"): -- GitLab