From de1e29bf1bca48e38e8557ed7330e34b69688909 Mon Sep 17 00:00:00 2001 From: Nabin Hait Date: Tue, 12 Dec 2017 13:22:48 +0530 Subject: [PATCH] Production Order fixes (#11951) * Production Order from Sales Order fixes: Validate SO and set required items on save * Codacy fixes --- .../production_order/production_order.js | 2 + .../production_order/production_order.py | 44 +++++++++++++------ .../doctype/sales_order/sales_order.py | 7 ++- 3 files changed, 38 insertions(+), 15 deletions(-) diff --git a/erpnext/manufacturing/doctype/production_order/production_order.js b/erpnext/manufacturing/doctype/production_order/production_order.js index c3e6f20b64f..68a5dc4f8f4 100644 --- a/erpnext/manufacturing/doctype/production_order/production_order.js +++ b/erpnext/manufacturing/doctype/production_order/production_order.js @@ -157,6 +157,7 @@ frappe.ui.form.on("Production Order", { item: frm.doc.production_item, project: frm.doc.project }, + freeze: true, callback: function(r) { if(r.message) { erpnext.in_production_item_onchange = true; @@ -184,6 +185,7 @@ frappe.ui.form.on("Production Order", { return frm.call({ doc: frm.doc, method: "get_items_and_operations_from_bom", + freeze: true, callback: function(r) { if(r.message["set_scrap_wh_mandatory"]){ frm.toggle_reqd("scrap_warehouse", true); diff --git a/erpnext/manufacturing/doctype/production_order/production_order.py b/erpnext/manufacturing/doctype/production_order/production_order.py index 34ade1042de..891e6dc53aa 100644 --- a/erpnext/manufacturing/doctype/production_order/production_order.py +++ b/erpnext/manufacturing/doctype/production_order/production_order.py @@ -43,10 +43,7 @@ class ProductionOrder(Document): validate_uom_is_integer(self, "stock_uom", ["qty", "produced_qty"]) - if not self.get("required_items"): - self.set_required_items() - else: - self.set_available_qty() + self.set_required_items(reset_only_qty = len(self.get("required_items"))) def validate_sales_order(self): if self.sales_order: @@ -57,6 +54,19 @@ class ProductionOrder(Document): and so.docstatus = 1 and so_item.item_code=%s """, (self.sales_order, self.production_item), as_dict=1) + if not so: + so = frappe.db.sql(""" + select + so.name, so_item.delivery_date, so.project + from + `tabSales Order` so, `tabSales Order Item` so_item, `tabPacked Item` packed_item + where so.name=%s + and so.name=so_item.parent + and so.name=packed_item.parent + and so_item.item_code = packed_item.parent_item + and so.docstatus = 1 and packed_item.item_code=%s + """, (self.sales_order, self.production_item), as_dict=1) + if len(so): if not self.expected_delivery_date: self.expected_delivery_date = so[0].delivery_date @@ -431,21 +441,27 @@ class ProductionOrder(Document): if self.wip_warehouse: d.available_qty_at_wip_warehouse = get_latest_stock_qty(d.item_code, self.wip_warehouse) - def set_required_items(self): + def set_required_items(self, reset_only_qty=False): '''set required_items for production to keep track of reserved qty''' - self.required_items = [] + if not reset_only_qty: + self.required_items = [] + if self.bom_no and self.qty: item_dict = get_bom_items_as_dict(self.bom_no, self.company, qty=self.qty, fetch_exploded = self.use_multi_level_bom) - for item in sorted(item_dict.values(), key=lambda d: d['idx']): - self.append('required_items', { - 'item_code': item.item_code, - 'item_name': item.item_name, - 'description': item.description, - 'required_qty': item.qty, - 'source_warehouse': item.source_warehouse or item.default_warehouse - }) + if reset_only_qty: + for d in self.get("required_items"): + d.required_qty = item_dict.get(d.item_code).get("qty") + else: + for item in sorted(item_dict.values(), key=lambda d: d['idx']): + self.append('required_items', { + 'item_code': item.item_code, + 'item_name': item.item_name, + 'description': item.description, + 'required_qty': item.qty, + 'source_warehouse': item.source_warehouse or item.default_warehouse + }) self.set_available_qty() diff --git a/erpnext/selling/doctype/sales_order/sales_order.py b/erpnext/selling/doctype/sales_order/sales_order.py index 51e6c61ea3e..d9284050a6c 100644 --- a/erpnext/selling/doctype/sales_order/sales_order.py +++ b/erpnext/selling/doctype/sales_order/sales_order.py @@ -762,10 +762,15 @@ def make_production_orders(items, sales_order, company, project=None): out = [] for i in items: + if not i.get("bom"): + frappe.throw(_("Please select BOM against item {0}").format(i.get("item_code"))) + if not i.get("pending_qty"): + frappe.throw(_("Please select Qty against item {0}").format(i.get("item_code"))) + production_order = frappe.get_doc(dict( doctype='Production Order', production_item=i['item_code'], - bom_no=i['bom'], + bom_no=i.get('bom'), qty=i['pending_qty'], company=company, sales_order=sales_order,