From c2f19036f3cab2cb13346639c7476d79a52228be Mon Sep 17 00:00:00 2001 From: Shllokkk Date: Fri, 20 Feb 2026 19:58:23 +0530 Subject: [PATCH 1/4] fix: correct fields being updated on material request and purchase order creation from sales order --- .../doctype/sales_order_item/sales_order_item.json | 11 ++++++++++- .../doctype/sales_order_item/sales_order_item.py | 1 + .../doctype/material_request/material_request.py | 2 +- 3 files changed, 12 insertions(+), 2 deletions(-) diff --git a/erpnext/selling/doctype/sales_order_item/sales_order_item.json b/erpnext/selling/doctype/sales_order_item/sales_order_item.json index d57bb04d13f..d12f5fa6fba 100644 --- a/erpnext/selling/doctype/sales_order_item/sales_order_item.json +++ b/erpnext/selling/doctype/sales_order_item/sales_order_item.json @@ -95,6 +95,7 @@ "ordered_qty", "planned_qty", "production_plan_qty", + "requested_qty", "column_break_69", "work_order_qty", "delivered_qty", @@ -1010,13 +1011,21 @@ "fieldtype": "Float", "label": "Finished Good Qty", "mandatory_depends_on": "eval:parent.is_subcontracted" + }, + { + "fieldname": "requested_qty", + "fieldtype": "Float", + "label": "Requested Qty", + "no_copy": 1, + "print_hide": 1, + "read_only": 1 } ], "grid_page_length": 50, "idx": 1, "istable": 1, "links": [], - "modified": "2025-10-13 10:57:43.378448", + "modified": "2026-02-20 14:18:00.736068", "modified_by": "Administrator", "module": "Selling", "name": "Sales Order Item", diff --git a/erpnext/selling/doctype/sales_order_item/sales_order_item.py b/erpnext/selling/doctype/sales_order_item/sales_order_item.py index 9128f8a3e41..98298f22036 100644 --- a/erpnext/selling/doctype/sales_order_item/sales_order_item.py +++ b/erpnext/selling/doctype/sales_order_item/sales_order_item.py @@ -80,6 +80,7 @@ class SalesOrderItem(Document): quotation_item: DF.Data | None rate: DF.Currency rate_with_margin: DF.Currency + requested_qty: DF.Float reserve_stock: DF.Check returned_qty: DF.Float stock_qty: DF.Float diff --git a/erpnext/stock/doctype/material_request/material_request.py b/erpnext/stock/doctype/material_request/material_request.py index 1868730ffd3..401151d6c34 100644 --- a/erpnext/stock/doctype/material_request/material_request.py +++ b/erpnext/stock/doctype/material_request/material_request.py @@ -90,7 +90,7 @@ class MaterialRequest(BuyingController): { "source_dt": "Material Request Item", "target_dt": "Sales Order Item", - "target_field": "ordered_qty", + "target_field": "requested_qty", "target_parent_dt": "Sales Order", "target_parent_field": "", "join_field": "sales_order_item", From 1a4d7ad9376bc790c0479c1eac6b8d0877da9867 Mon Sep 17 00:00:00 2001 From: Shllokkk Date: Fri, 20 Feb 2026 20:09:18 +0530 Subject: [PATCH 2/4] fix: correct ordered_qty and requested_qty for Sales Order Item through a patch --- erpnext/patches.txt | 3 +- ...ty_and_requested_qty_based_on_mr_and_po.py | 39 +++++++++++++++++++ 2 files changed, 41 insertions(+), 1 deletion(-) create mode 100644 erpnext/patches/v16_0/update_order_qty_and_requested_qty_based_on_mr_and_po.py diff --git a/erpnext/patches.txt b/erpnext/patches.txt index bbb33de29db..9a7697d74ff 100644 --- a/erpnext/patches.txt +++ b/erpnext/patches.txt @@ -467,4 +467,5 @@ erpnext.patches.v16_0.update_company_custom_field_in_bin erpnext.patches.v15_0.replace_http_with_https_in_sales_partner erpnext.patches.v16_0.migrate_asset_type_checkboxes_to_select erpnext.patches.v15_0.delete_quotation_lost_record_detail -erpnext.patches.v16_0.add_portal_redirects \ No newline at end of file +erpnext.patches.v16_0.add_portal_redirects +erpnext.patches.v16_0.update_order_qty_and_requested_qty_based_on_mr_and_po \ No newline at end of file diff --git a/erpnext/patches/v16_0/update_order_qty_and_requested_qty_based_on_mr_and_po.py b/erpnext/patches/v16_0/update_order_qty_and_requested_qty_based_on_mr_and_po.py new file mode 100644 index 00000000000..47bb94dcc88 --- /dev/null +++ b/erpnext/patches/v16_0/update_order_qty_and_requested_qty_based_on_mr_and_po.py @@ -0,0 +1,39 @@ +import frappe +from frappe.query_builder import DocType +from frappe.query_builder.functions import Sum + + +def execute(): + PurchaseOrderItem = DocType("Purchase Order Item") + MaterialRequestItem = DocType("Material Request Item") + + poi_query = ( + frappe.qb.from_(PurchaseOrderItem) + .select(PurchaseOrderItem.sales_order_item, Sum(PurchaseOrderItem.qty)) + .where(PurchaseOrderItem.sales_order_item.isnotnull() & PurchaseOrderItem.docstatus != 2) + .groupby(PurchaseOrderItem.sales_order_item) + ) + + mri_query = ( + frappe.qb.from_(MaterialRequestItem) + .select(MaterialRequestItem.sales_order_item, Sum(MaterialRequestItem.qty)) + .where(MaterialRequestItem.sales_order_item.isnotnull() & MaterialRequestItem.docstatus != 2) + .groupby(MaterialRequestItem.sales_order_item) + ) + + poi_data = poi_query.run() + mri_data = mri_query.run() + + updates_against_poi = {} + updates_against_mri = {} + + for data in poi_data: + updates_against_poi[data[0]] = {"ordered_qty": data[1]} + + for data in mri_data: + updates_against_mri[data[0]] = {"requested_qty": data[1], "ordered_qty": 0} + + frappe.db.auto_commit_on_many_writes = 1 + frappe.db.bulk_update("Sales Order Item", updates_against_mri) + frappe.db.bulk_update("Sales Order Item", updates_against_poi) + frappe.db.auto_commit_on_many_writes = 0 From d0323dea6543bbb985de181b4e4323da5fcc24c3 Mon Sep 17 00:00:00 2001 From: Shllokkk Date: Fri, 20 Feb 2026 20:23:24 +0530 Subject: [PATCH 3/4] fix: add missing logic to update requested qty on cancel of a material request --- .../update_order_qty_and_requested_qty_based_on_mr_and_po.py | 4 ++-- erpnext/stock/doctype/material_request/material_request.py | 2 ++ 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/erpnext/patches/v16_0/update_order_qty_and_requested_qty_based_on_mr_and_po.py b/erpnext/patches/v16_0/update_order_qty_and_requested_qty_based_on_mr_and_po.py index 47bb94dcc88..dc5930e9bb1 100644 --- a/erpnext/patches/v16_0/update_order_qty_and_requested_qty_based_on_mr_and_po.py +++ b/erpnext/patches/v16_0/update_order_qty_and_requested_qty_based_on_mr_and_po.py @@ -10,14 +10,14 @@ def execute(): poi_query = ( frappe.qb.from_(PurchaseOrderItem) .select(PurchaseOrderItem.sales_order_item, Sum(PurchaseOrderItem.qty)) - .where(PurchaseOrderItem.sales_order_item.isnotnull() & PurchaseOrderItem.docstatus != 2) + .where(PurchaseOrderItem.sales_order_item.isnotnull() & PurchaseOrderItem.docstatus == 1) .groupby(PurchaseOrderItem.sales_order_item) ) mri_query = ( frappe.qb.from_(MaterialRequestItem) .select(MaterialRequestItem.sales_order_item, Sum(MaterialRequestItem.qty)) - .where(MaterialRequestItem.sales_order_item.isnotnull() & MaterialRequestItem.docstatus != 2) + .where(MaterialRequestItem.sales_order_item.isnotnull() & MaterialRequestItem.docstatus == 1) .groupby(MaterialRequestItem.sales_order_item) ) diff --git a/erpnext/stock/doctype/material_request/material_request.py b/erpnext/stock/doctype/material_request/material_request.py index 401151d6c34..e66dc792622 100644 --- a/erpnext/stock/doctype/material_request/material_request.py +++ b/erpnext/stock/doctype/material_request/material_request.py @@ -280,6 +280,8 @@ class MaterialRequest(BuyingController): def on_cancel(self): self.update_requested_qty_in_production_plan(cancel=True) self.update_requested_qty() + if self.material_request_type == "Purchase": + self.update_prevdoc_status() def get_mr_items_ordered_qty(self, mr_items): mr_items_ordered_qty = {} From 91c6475f1c0f7d6e4391800a0db73f0cb2f43fec Mon Sep 17 00:00:00 2001 From: Shllokkk Date: Mon, 2 Mar 2026 16:25:02 +0530 Subject: [PATCH 4/4] fix: update select query field in patch and code refactor --- ...der_qty_and_requested_qty_based_on_mr_and_po.py | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/erpnext/patches/v16_0/update_order_qty_and_requested_qty_based_on_mr_and_po.py b/erpnext/patches/v16_0/update_order_qty_and_requested_qty_based_on_mr_and_po.py index dc5930e9bb1..59a84ec11d0 100644 --- a/erpnext/patches/v16_0/update_order_qty_and_requested_qty_based_on_mr_and_po.py +++ b/erpnext/patches/v16_0/update_order_qty_and_requested_qty_based_on_mr_and_po.py @@ -9,14 +9,14 @@ def execute(): poi_query = ( frappe.qb.from_(PurchaseOrderItem) - .select(PurchaseOrderItem.sales_order_item, Sum(PurchaseOrderItem.qty)) + .select(PurchaseOrderItem.sales_order_item, Sum(PurchaseOrderItem.stock_qty)) .where(PurchaseOrderItem.sales_order_item.isnotnull() & PurchaseOrderItem.docstatus == 1) .groupby(PurchaseOrderItem.sales_order_item) ) mri_query = ( frappe.qb.from_(MaterialRequestItem) - .select(MaterialRequestItem.sales_order_item, Sum(MaterialRequestItem.qty)) + .select(MaterialRequestItem.sales_order_item, Sum(MaterialRequestItem.stock_qty)) .where(MaterialRequestItem.sales_order_item.isnotnull() & MaterialRequestItem.docstatus == 1) .groupby(MaterialRequestItem.sales_order_item) ) @@ -24,14 +24,8 @@ def execute(): poi_data = poi_query.run() mri_data = mri_query.run() - updates_against_poi = {} - updates_against_mri = {} - - for data in poi_data: - updates_against_poi[data[0]] = {"ordered_qty": data[1]} - - for data in mri_data: - updates_against_mri[data[0]] = {"requested_qty": data[1], "ordered_qty": 0} + updates_against_poi = {data[0]: {"ordered_qty": data[1]} for data in poi_data} + updates_against_mri = {data[0]: {"requested_qty": data[1], "ordered_qty": 0} for data in mri_data} frappe.db.auto_commit_on_many_writes = 1 frappe.db.bulk_update("Sales Order Item", updates_against_mri)