From d83365734e988d241ce03ffa14f4ac1ecf627e1d Mon Sep 17 00:00:00 2001 From: "mergify[bot]" <37929162+mergify[bot]@users.noreply.github.com> Date: Fri, 9 Jan 2026 09:48:28 +0000 Subject: [PATCH] Merge pull request #51624 from frappe/mergify/bp/version-15-hotfix/pr-50869 fix: do cancellation procedures on WO close (backport #50869) --- erpnext/manufacturing/doctype/work_order/work_order.py | 9 ++++++--- erpnext/selling/doctype/sales_order/sales_order.py | 1 + .../stock/doctype/material_request/material_request.py | 3 +++ 3 files changed, 10 insertions(+), 3 deletions(-) diff --git a/erpnext/manufacturing/doctype/work_order/work_order.py b/erpnext/manufacturing/doctype/work_order/work_order.py index 41716b015a3..b904d2f13f4 100644 --- a/erpnext/manufacturing/doctype/work_order/work_order.py +++ b/erpnext/manufacturing/doctype/work_order/work_order.py @@ -316,7 +316,7 @@ class WorkOrder(Document): # already ordered qty ordered_qty_against_so = frappe.db.sql( """select sum(qty) from `tabWork Order` - where production_item = %s and sales_order = %s and docstatus < 2 and name != %s""", + where production_item = %s and sales_order = %s and docstatus < 2 and status != 'Closed' and name != %s""", (self.production_item, self.sales_order, self.name), )[0][0] @@ -516,6 +516,9 @@ class WorkOrder(Document): self.validate_cancel() self.db_set("status", "Cancelled") + self.on_close_or_cancel() + + def on_close_or_cancel(self): if self.production_plan and frappe.db.exists( "Production Plan Item Reference", {"parent": self.production_plan} ): @@ -843,7 +846,7 @@ class WorkOrder(Document): qty = frappe.db.sql( f""" select sum(qty) from - `tabWork Order` where sales_order = %s and docstatus = 1 and {cond} + `tabWork Order` where sales_order = %s and docstatus = 1 and status <> 'Closed' and {cond} """, (self.sales_order, (self.product_bundle_item or self.production_item)), as_list=1, @@ -1604,8 +1607,8 @@ def close_work_order(work_order, status): ) ) + work_order.on_close_or_cancel() work_order.update_status(status) - work_order.update_planned_qty() frappe.msgprint(_("Work Order has been {0}").format(status)) work_order.notify_update() return work_order.status diff --git a/erpnext/selling/doctype/sales_order/sales_order.py b/erpnext/selling/doctype/sales_order/sales_order.py index 8be426fa1a5..0079db289a5 100755 --- a/erpnext/selling/doctype/sales_order/sales_order.py +++ b/erpnext/selling/doctype/sales_order/sales_order.py @@ -1875,6 +1875,7 @@ def get_work_order_items(sales_order, for_raw_material_request=0): & (wo.sales_order == so.name) & (wo.sales_order_item == i.name) & (wo.docstatus.lt(2)) + & (wo.status != "Closed") ) .run()[0][0] ) diff --git a/erpnext/stock/doctype/material_request/material_request.py b/erpnext/stock/doctype/material_request/material_request.py index e9c7a813698..7d160b24e2d 100644 --- a/erpnext/stock/doctype/material_request/material_request.py +++ b/erpnext/stock/doctype/material_request/material_request.py @@ -273,6 +273,9 @@ class MaterialRequest(BuyingController): .groupby(doctype.material_request_item) ) + if self.material_request_type == "Manufacture": + query = query.where(doctype.status != "Closed") + mr_items_ordered_qty = frappe._dict(query.run()) return mr_items_ordered_qty