From bc6445fdec5ec53740ff28f0391f07878051b633 Mon Sep 17 00:00:00 2001 From: Assem Bahnasy Date: Tue, 11 Nov 2025 07:23:25 +0300 Subject: [PATCH 1/2] Fix: Product Bundle Purchase Order Creation Logic (#49831) Co-authored-by: Mihir Kandoi (cherry picked from commit 5b643433e51954d0030b9d2a4ed8fef9d63fcd1c) --- erpnext/selling/doctype/sales_order/sales_order.js | 11 ++++++----- erpnext/selling/doctype/sales_order/sales_order.py | 6 ++++-- 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/erpnext/selling/doctype/sales_order/sales_order.js b/erpnext/selling/doctype/sales_order/sales_order.js index 0150477dab..149b1ffd0e 100644 --- a/erpnext/selling/doctype/sales_order/sales_order.js +++ b/erpnext/selling/doctype/sales_order/sales_order.js @@ -1605,8 +1605,8 @@ erpnext.selling.SalesOrderController = class SalesOrderController extends erpnex make_purchase_order() { let pending_items = this.frm.doc.items.some((item) => { - let pending_qty = flt(item.stock_qty) - flt(item.ordered_qty); - return item.item_code && pending_qty > 0; // @dokos + const pending_qty = flt(item.stock_qty) - this.get_ordered_qty(item, this.frm.doc); + return pending_qty > 0; }); if (!pending_items) { frappe.throw({ @@ -1763,9 +1763,10 @@ erpnext.selling.SalesOrderController = class SalesOrderController extends erpnex // calculate ordered qty based on packed items in case of product bundle let packed_items = so.packed_items.filter((pi) => pi.parent_detail_docname == item.name); if (packed_items && packed_items.length) { - const pi_qty = packed_items.reduce((sum, pi) => sum + flt(pi.qty), 0); - const pi_ordered_qty = packed_items.reduce((sum, pi) => sum + flt(pi.ordered_qty), 0); - ordered_qty = item.stock_qty * (pi_ordered_qty / pi_qty); + const all_packed_items_ordered = packed_items.every( + (pi) => flt(pi.ordered_qty) >= flt(pi.qty) + ); + ordered_qty = all_packed_items_ordered ? item.stock_qty : 0; } } return ordered_qty; diff --git a/erpnext/selling/doctype/sales_order/sales_order.py b/erpnext/selling/doctype/sales_order/sales_order.py index 47eecf858f..541321b976 100755 --- a/erpnext/selling/doctype/sales_order/sales_order.py +++ b/erpnext/selling/doctype/sales_order/sales_order.py @@ -1830,7 +1830,8 @@ def make_purchase_order_for_default_supplier(source_name, selected_items=None, t "pricing_rules", ], "postprocess": update_item_for_packed_item, - "condition": lambda doc: doc.parent_item in items_to_map, + "condition": lambda doc: doc.parent_item in items_to_map + and flt(doc.ordered_qty) < flt(doc.qty), }, }, target_doc, @@ -1974,7 +1975,8 @@ def make_purchase_order(source_name, selected_items=None, target_doc=None): "pricing_rules", ], "postprocess": update_item_for_packed_item, - "condition": lambda doc: doc.parent_item in items_to_map, + "condition": lambda doc: doc.parent_item in items_to_map + and flt(doc.ordered_qty) < flt(doc.qty), }, }, target_doc, -- GitLab From dea23d09ac6685ae3ea940b535729d9a9199dc2a Mon Sep 17 00:00:00 2001 From: Charles-Henri Decultot Date: Wed, 12 Nov 2025 09:14:49 +0100 Subject: [PATCH 2/2] fix: keep Dokos rule --- erpnext/selling/doctype/sales_order/sales_order.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/erpnext/selling/doctype/sales_order/sales_order.js b/erpnext/selling/doctype/sales_order/sales_order.js index 149b1ffd0e..4d849cbec3 100644 --- a/erpnext/selling/doctype/sales_order/sales_order.js +++ b/erpnext/selling/doctype/sales_order/sales_order.js @@ -1606,7 +1606,7 @@ erpnext.selling.SalesOrderController = class SalesOrderController extends erpnex make_purchase_order() { let pending_items = this.frm.doc.items.some((item) => { const pending_qty = flt(item.stock_qty) - this.get_ordered_qty(item, this.frm.doc); - return pending_qty > 0; + return item.item_code && pending_qty > 0; // @dokos }); if (!pending_items) { frappe.throw({ -- GitLab