fix: overproduction % not considered when making WO from SO

(cherry picked from commit edba9efb5e)
This commit is contained in:
Mihir Kandoi
2026-01-20 12:37:12 +05:30
committed by Mergify
parent 232225d753
commit fb669eb6f4
3 changed files with 28 additions and 11 deletions

View File

@@ -503,7 +503,7 @@ class WorkOrder(Document):
# already ordered qty # already ordered qty
ordered_qty_against_so = frappe.db.sql( ordered_qty_against_so = frappe.db.sql(
"""select sum(qty - process_loss_qty) from `tabWork Order` """select sum(qty - process_loss_qty) from `tabWork Order`
where production_item = %s and sales_order = %s and docstatus < 2 and status != 'Closed' and name != %s""", where production_item = %s and sales_order = %s and docstatus = 1 and status != 'Closed' and name != %s""",
(self.production_item, self.sales_order, self.name), (self.production_item, self.sales_order, self.name),
)[0][0] )[0][0]
@@ -512,13 +512,13 @@ class WorkOrder(Document):
# get qty from Sales Order Item table # get qty from Sales Order Item table
so_item_qty = frappe.db.sql( so_item_qty = frappe.db.sql(
"""select sum(stock_qty) from `tabSales Order Item` """select sum(stock_qty) from `tabSales Order Item`
where parent = %s and item_code = %s""", where parent = %s and item_code = %s and docstatus = 1""",
(self.sales_order, self.production_item), (self.sales_order, self.production_item),
)[0][0] )[0][0]
# get qty from Packing Item table # get qty from Packing Item table
dnpi_qty = frappe.db.sql( dnpi_qty = frappe.db.sql(
"""select sum(qty) from `tabPacked Item` """select sum(qty) from `tabPacked Item`
where parent = %s and parenttype = 'Sales Order' and item_code = %s""", where parent = %s and parenttype = 'Sales Order' and item_code = %s and docstatus = 1""",
(self.sales_order, self.production_item), (self.sales_order, self.production_item),
)[0][0] )[0][0]
# total qty in SO # total qty in SO
@@ -530,8 +530,10 @@ class WorkOrder(Document):
if total_qty > so_qty + (allowance_percentage / 100 * so_qty): if total_qty > so_qty + (allowance_percentage / 100 * so_qty):
frappe.throw( frappe.throw(
_("Cannot produce more Item {0} than Sales Order quantity {1}").format( _("Cannot produce more Item {0} than Sales Order quantity {1} {2}").format(
self.production_item, so_qty get_link_to_form("Item", self.production_item),
frappe.bold(so_qty),
frappe.bold(frappe.get_value("Item", self.production_item, "stock_uom")),
), ),
OverProductionError, OverProductionError,
) )

View File

@@ -1220,10 +1220,12 @@ erpnext.selling.SalesOrderController = class SalesOrderController extends erpnex
}, },
freeze: true, freeze: true,
callback: function (r) { callback: function (r) {
if (!r.message) { if (r.message.length === 0) {
frappe.msgprint({ frappe.msgprint({
title: __("Work Order not created"), title: __("Work Order not created"),
message: __("No Items with Bill of Materials to Manufacture"), message: __(
"No Items with Bill of Materials to Manufacture or all items already manufactured"
),
indicator: "orange", indicator: "orange",
}); });
return; return;
@@ -1233,19 +1235,24 @@ erpnext.selling.SalesOrderController = class SalesOrderController extends erpnex
label: __("Items"), label: __("Items"),
fieldtype: "Table", fieldtype: "Table",
fieldname: "items", fieldname: "items",
cannot_add_rows: true,
description: __("Select BOM and Qty for Production"), description: __("Select BOM and Qty for Production"),
fields: [ fields: [
{ {
fieldtype: "Read Only", fieldtype: "Link",
fieldname: "item_code", fieldname: "item_code",
options: "Item",
label: __("Item Code"), label: __("Item Code"),
in_list_view: 1, in_list_view: 1,
read_only: 1,
}, },
{ {
fieldtype: "Read Only", fieldtype: "Data",
fieldname: "item_name", fieldname: "item_name",
label: __("Item Name"), label: __("Item Name"),
in_list_view: 1, in_list_view: 1,
read_only: 1,
fetch_from: "item_code.item_name",
}, },
{ {
fieldtype: "Link", fieldtype: "Link",
@@ -1271,6 +1278,7 @@ erpnext.selling.SalesOrderController = class SalesOrderController extends erpnex
reqd: 1, reqd: 1,
label: __("Sales Order Item"), label: __("Sales Order Item"),
hidden: 1, hidden: 1,
read_only: 1,
}, },
], ],
data: r.message, data: r.message,

View File

@@ -1981,6 +1981,10 @@ def get_work_order_items(sales_order, for_raw_material_request=0):
) )
] ]
overproduction_percentage_for_sales_order = (
frappe.get_single_value("Manufacturing Settings", "overproduction_percentage_for_sales_order")
/ 100
)
for table in [so.items, so.packed_items]: for table in [so.items, so.packed_items]:
for i in table: for i in table:
bom = get_default_bom(i.item_code) bom = get_default_bom(i.item_code)
@@ -1994,7 +1998,7 @@ def get_work_order_items(sales_order, for_raw_material_request=0):
(wo.production_item == i.item_code) (wo.production_item == i.item_code)
& (wo.sales_order == so.name) & (wo.sales_order == so.name)
& (wo.sales_order_item == i.name) & (wo.sales_order_item == i.name)
& (wo.docstatus.lt(2)) & (wo.docstatus == 1)
& (wo.status != "Closed") & (wo.status != "Closed")
) )
.run()[0][0] .run()[0][0]
@@ -2003,7 +2007,10 @@ def get_work_order_items(sales_order, for_raw_material_request=0):
else: else:
pending_qty = stock_qty pending_qty = stock_qty
if pending_qty and i.item_code not in product_bundle_parents: if not pending_qty:
pending_qty = stock_qty * overproduction_percentage_for_sales_order
if pending_qty > 0 and i.item_code not in product_bundle_parents:
items.append( items.append(
dict( dict(
name=i.name, name=i.name,