From dffd5d9cdd8e2f1d30a69472687de1230575f811 Mon Sep 17 00:00:00 2001 From: Smit Vora Date: Fri, 28 Nov 2025 11:37:25 +0530 Subject: [PATCH] fix: cascade projected quantity across multiple items in material requests (cherry picked from commit d344be32a0d4a1de0225df0f6f9ddcf7949e900c) # Conflicts: # erpnext/manufacturing/doctype/production_plan/production_plan.py --- .../production_plan/production_plan.py | 29 +++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/erpnext/manufacturing/doctype/production_plan/production_plan.py b/erpnext/manufacturing/doctype/production_plan/production_plan.py index 4aa723a2ac4..587988eb3ec 100644 --- a/erpnext/manufacturing/doctype/production_plan/production_plan.py +++ b/erpnext/manufacturing/doctype/production_plan/production_plan.py @@ -1303,14 +1303,33 @@ def get_material_request_items( include_safety_stock, warehouse, bin_dict, +<<<<<<< HEAD +======= + consumed_qty, +>>>>>>> d344be32a0 (fix: cascade projected quantity across multiple items in material requests) ): total_qty = row["qty"] required_qty = 0 +<<<<<<< HEAD if ignore_existing_ordered_qty or bin_dict.get("projected_qty", 0) < 0: required_qty = total_qty elif total_qty > bin_dict.get("projected_qty", 0): required_qty = total_qty - bin_dict.get("projected_qty", 0) +======= + item_code = row.get("item_code") + + if not ignore_existing_ordered_qty or bin_dict.get("projected_qty", 0) < 0: + required_qty = flt(row.get("qty")) + else: + key = (item_code, warehouse) + available_qty = flt(bin_dict.get("projected_qty", 0)) - consumed_qty[key] + if available_qty > 0: + required_qty = max(0, flt(row.get("qty")) - available_qty) + consumed_qty[key] += min(flt(row.get("qty")), available_qty) + else: + required_qty = flt(row.get("qty")) +>>>>>>> d344be32a0 (fix: cascade projected quantity across multiple items in material requests) if doc.get("consider_minimum_order_qty") and required_qty > 0 and required_qty < row["min_order_qty"]: required_qty = row["min_order_qty"] @@ -1648,9 +1667,15 @@ def get_items_for_material_requests(doc, warehouses=None, get_parent_warehouse_d so_item_details[sales_order][item_code] = details mr_items = [] + consumed_qty = defaultdict(float) + for sales_order in so_item_details: item_dict = so_item_details[sales_order] for details in item_dict.values(): +<<<<<<< HEAD +======= + warehouse = warehouse or details.get("source_warehouse") or details.get("default_warehouse") +>>>>>>> d344be32a0 (fix: cascade projected quantity across multiple items in material requests) bin_dict = get_bin_details(details, doc.company, warehouse) bin_dict = bin_dict[0] if bin_dict else {} @@ -1664,6 +1689,10 @@ def get_items_for_material_requests(doc, warehouses=None, get_parent_warehouse_d include_safety_stock, warehouse, bin_dict, +<<<<<<< HEAD +======= + consumed_qty, +>>>>>>> d344be32a0 (fix: cascade projected quantity across multiple items in material requests) ) if items: mr_items.append(items)