diff --git a/erpnext/manufacturing/doctype/work_order/work_order.py b/erpnext/manufacturing/doctype/work_order/work_order.py index c26af9a74af..b4fe97a7c42 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 - 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), )[0][0] @@ -325,13 +325,13 @@ class WorkOrder(Document): # get qty from Sales Order Item table so_item_qty = frappe.db.sql( """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), )[0][0] # get qty from Packing Item table dnpi_qty = frappe.db.sql( """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), )[0][0] # total qty in SO @@ -343,8 +343,10 @@ class WorkOrder(Document): if total_qty > so_qty + (allowance_percentage / 100 * so_qty): frappe.throw( - _("Cannot produce more Item {0} than Sales Order quantity {1}").format( - self.production_item, so_qty + _("Cannot produce more Item {0} than Sales Order quantity {1} {2}").format( + get_link_to_form("Item", self.production_item), + frappe.bold(so_qty), + frappe.bold(frappe.get_value("Item", self.production_item, "stock_uom")), ), OverProductionError, ) diff --git a/erpnext/selling/doctype/sales_order/sales_order.js b/erpnext/selling/doctype/sales_order/sales_order.js index 18b4bab4188..d97d3097346 100644 --- a/erpnext/selling/doctype/sales_order/sales_order.js +++ b/erpnext/selling/doctype/sales_order/sales_order.js @@ -842,10 +842,12 @@ erpnext.selling.SalesOrderController = class SalesOrderController extends erpnex }, freeze: true, callback: function (r) { - if (!r.message) { + if (r.message.length === 0) { frappe.msgprint({ 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", }); return; @@ -855,15 +857,29 @@ erpnext.selling.SalesOrderController = class SalesOrderController extends erpnex label: __("Items"), fieldtype: "Table", fieldname: "items", + cannot_add_rows: true, description: __("Select BOM and Qty for Production"), fields: [ { - fieldtype: "Read Only", + fieldtype: "Link", fieldname: "item_code", + options: "Item", label: __("Item Code"), in_list_view: 1, + read_only: 1, }, { +<<<<<<< HEAD +======= + fieldtype: "Data", + fieldname: "item_name", + label: __("Item Name"), + in_list_view: 1, + read_only: 1, + fetch_from: "item_code.item_name", + }, + { +>>>>>>> edba9efb5e (fix: overproduction % not considered when making WO from SO) fieldtype: "Link", fieldname: "bom", options: "BOM", @@ -887,6 +903,7 @@ erpnext.selling.SalesOrderController = class SalesOrderController extends erpnex reqd: 1, label: __("Sales Order Item"), hidden: 1, + read_only: 1, }, ], data: r.message, diff --git a/erpnext/selling/doctype/sales_order/sales_order.py b/erpnext/selling/doctype/sales_order/sales_order.py index a757efffa4e..76ac678320c 100755 --- a/erpnext/selling/doctype/sales_order/sales_order.py +++ b/erpnext/selling/doctype/sales_order/sales_order.py @@ -1861,6 +1861,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 i in table: bom = get_default_bom(i.item_code) @@ -1874,7 +1878,7 @@ def get_work_order_items(sales_order, for_raw_material_request=0): (wo.production_item == i.item_code) & (wo.sales_order == so.name) & (wo.sales_order_item == i.name) - & (wo.docstatus.lt(2)) + & (wo.docstatus == 1) & (wo.status != "Closed") ) .run()[0][0] @@ -1883,7 +1887,10 @@ def get_work_order_items(sales_order, for_raw_material_request=0): else: 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( dict( name=i.name,