From dddf42560fa23f0b3a447c4bcf62dac4f1a52b12 Mon Sep 17 00:00:00 2001 From: Neil Trini Lasrado Date: Wed, 10 Feb 2016 13:09:09 +0530 Subject: [PATCH] Added code to update Material Request on Submission of Production Order --- .../doctype/purchase_order/purchase_order.py | 1 - .../production_order/production_order.json | 29 +++++- .../production_order/production_order.py | 14 ++- .../material_request/material_request.js | 62 ++----------- .../material_request/material_request.py | 92 +++++++++++-------- 5 files changed, 99 insertions(+), 99 deletions(-) diff --git a/erpnext/buying/doctype/purchase_order/purchase_order.py b/erpnext/buying/doctype/purchase_order/purchase_order.py index caefe53ac3d..44fe7cf600a 100644 --- a/erpnext/buying/doctype/purchase_order/purchase_order.py +++ b/erpnext/buying/doctype/purchase_order/purchase_order.py @@ -145,7 +145,6 @@ class PurchaseOrder(BuyingController): and frappe.db.get_value("Item", d.item_code, "is_stock_item") \ and d.warehouse and not d.delivered_by_supplier: item_wh_list.append([d.item_code, d.warehouse]) - for item_code, warehouse in item_wh_list: update_bin_qty(item_code, warehouse, { "ordered_qty": get_ordered_qty(item_code, warehouse) diff --git a/erpnext/manufacturing/doctype/production_order/production_order.json b/erpnext/manufacturing/doctype/production_order/production_order.json index 997a6179e02..2ad2a3ba28f 100644 --- a/erpnext/manufacturing/doctype/production_order/production_order.json +++ b/erpnext/manufacturing/doctype/production_order/production_order.json @@ -928,7 +928,31 @@ "precision": "", "print_hide": 0, "print_hide_if_no_value": 0, - "read_only": 0, + "read_only": 1, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, + "unique": 0 + }, + { + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "fieldname": "material_request_item", + "fieldtype": "Data", + "hidden": 1, + "ignore_user_permissions": 0, + "in_filter": 0, + "in_list_view": 0, + "label": "Material Request Item", + "length": 0, + "no_copy": 0, + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 1, "report_hide": 0, "reqd": 0, "search_index": 0, @@ -972,7 +996,7 @@ "issingle": 0, "istable": 0, "max_attachments": 0, - "modified": "2016-01-21 04:30:33.561347", + "modified": "2016-02-08 04:36:35.071206", "modified_by": "Administrator", "module": "Manufacturing", "name": "Production Order", @@ -1021,5 +1045,6 @@ ], "read_only": 0, "read_only_onload": 0, + "sort_order": "ASC", "title_field": "production_item" } \ No newline at end of file diff --git a/erpnext/manufacturing/doctype/production_order/production_order.py b/erpnext/manufacturing/doctype/production_order/production_order.py index 59d371a7c1b..ead8105a923 100644 --- a/erpnext/manufacturing/doctype/production_order/production_order.py +++ b/erpnext/manufacturing/doctype/production_order/production_order.py @@ -152,17 +152,19 @@ class ProductionOrder(Document): frappe.throw(_("Work-in-Progress Warehouse is required before Submit")) if not self.fg_warehouse: frappe.throw(_("For Warehouse is required before Submit")) + frappe.db.set(self,'status', 'Submitted') self.make_time_logs() self.update_planned_qty() - + self.update_completed_qty_in_material_request() def on_cancel(self): self.validate_cancel() frappe.db.set(self,'status', 'Cancelled') - self.update_planned_qty() self.delete_time_logs() + self.update_planned_qty() + self.update_completed_qty_in_material_request() def validate_cancel(self): if self.status == "Stopped": @@ -178,6 +180,14 @@ class ProductionOrder(Document): update_bin_qty(self.production_item, self.fg_warehouse, { "planned_qty": get_planned_qty(self.production_item, self.fg_warehouse) }) + + if self.material_request: + mr_obj = frappe.get_doc("Material Request", self.material_request) + mr_obj.update_requested_qty([self.material_request_item]) + + def update_completed_qty_in_material_request(self): + if self.material_request: + frappe.get_doc("Material Request", self.material_request).update_completed_qty([self.material_request_item]) def set_production_order_operations(self): """Fetch operations from BOM and set in 'Production Order'""" diff --git a/erpnext/stock/doctype/material_request/material_request.js b/erpnext/stock/doctype/material_request/material_request.js index 29968d8d68b..559b954963e 100644 --- a/erpnext/stock/doctype/material_request/material_request.js +++ b/erpnext/stock/doctype/material_request/material_request.js @@ -55,7 +55,7 @@ erpnext.buying.MaterialRequestController = erpnext.buying.BuyingController.exten if(doc.material_request_type === "Manufacture" && doc.status === "Submitted") cur_frm.add_custom_button(__("Production Order"), - this.make_production_order, __("Make")); + this.raise_production_orders, __("Make")); cur_frm.page.set_inner_btn_group_as_primary(__("Make")); @@ -172,61 +172,13 @@ erpnext.buying.MaterialRequestController = erpnext.buying.BuyingController.exten }, - make_production_order: function() { - var items = [] - $.each(cur_frm.doc["items"] || [], function(i, d) { - items.push(d.item_code); + raise_production_orders: function() { + frappe.call({ + method:"erpnext.stock.doctype.material_request.material_request.raise_production_orders", + args: { + "source_name": cur_frm.doc.name + } }); - var d = new frappe.ui.Dialog({ - title: __("Production Order"), - fields: [ - { - "fieldtype": "Link", - "label": __("Production Item"), - "fieldname": "item", - "options": "Item", - "reqd": 1, - "get_query": function() { - return { - "filters": [ - ['item_code', 'in', items], - ] - } - } - } - ] - - }); - - d.set_primary_action(__("Make"), function() { - frappe.call({ - method:"erpnext.stock.doctype.material_request.material_request.validate_production_item", - args: { - "item_code": d.get_values().item - }, - callback: function(r) { - if(!r.message) { - msgprint("Cannot create Production Order for selected Item.") - } - else { - frappe.call({ - method:"erpnext.stock.doctype.material_request.material_request.make_production_order", - args: { - "source_name": cur_frm.doc.name, - "item_code": d.get_values().item, - }, - callback: function(r) { - if(!r.exe) { - var doclist = frappe.model.sync(r.message); - frappe.set_route("Form", doclist[0].doctype, doclist[0].name); - } - } - }); - } - } - }); - }); - d.show(); } }); diff --git a/erpnext/stock/doctype/material_request/material_request.py b/erpnext/stock/doctype/material_request/material_request.py index f7dee98b3b9..80ec589d469 100644 --- a/erpnext/stock/doctype/material_request/material_request.py +++ b/erpnext/stock/doctype/material_request/material_request.py @@ -7,8 +7,8 @@ from __future__ import unicode_literals import frappe -from frappe.utils import cstr, flt, getdate -from frappe import _ +from frappe.utils import cstr, flt, getdate, comma_and +from frappe import msgprint, _ from frappe.model.mapper import get_mapped_doc from erpnext.stock.stock_balance import update_bin_qty, get_indented_qty from erpnext.controllers.buying_controller import BuyingController @@ -107,35 +107,41 @@ class MaterialRequest(BuyingController): frappe.db.set(self,'status','Cancelled') - def update_completed_qty(self, mr_items=None): + def update_completed_qty(self, mr_items=None, update_modified=True): if self.material_request_type == "Purchase": return if not mr_items: mr_items = [d.name for d in self.get("items")] - per_ordered = 0.0 for d in self.get("items"): if d.name in mr_items: - d.ordered_qty = flt(frappe.db.sql("""select sum(transfer_qty) - from `tabStock Entry Detail` where material_request = %s - and material_request_item = %s and docstatus = 1""", - (self.name, d.name))[0][0]) + if self.material_request_type in ("Material Issue", "Material Transfer"): + d.ordered_qty = flt(frappe.db.sql("""select sum(transfer_qty) + from `tabStock Entry Detail` where material_request = %s + and material_request_item = %s and docstatus = 1""", + (self.name, d.name))[0][0]) - if d.ordered_qty and d.ordered_qty > d.qty: - frappe.throw(_("The total Issue / Transfer quantity {0} in Material Request {1} cannot be greater than requested quantity {2} for Item {3}").format(d.ordered_qty, d.parent, d.qty, d.item_code)) + if d.ordered_qty and d.ordered_qty > d.qty: + frappe.throw(_("The total Issue / Transfer quantity {0} in Material Request {1} \ + cannot be greater than requested quantity {2} for Item {3}").format(d.ordered_qty, d.parent, d.qty, d.item_code)) + + elif self.material_request_type == "Manufacture": + d.ordered_qty = flt(frappe.db.sql("""select sum(qty) + from `tabProduction Order` where material_request = %s + and material_request_item = %s and docstatus = 1""", + (self.name, d.name))[0][0]) frappe.db.set_value(d.doctype, d.name, "ordered_qty", d.ordered_qty) - - # note: if qty is 0, its row is still counted in len(self.get("items")) - # hence adding 1 to per_ordered - if (d.ordered_qty > d.qty) or not d.qty: - per_ordered += 1.0 - elif d.qty > 0: - per_ordered += flt(d.ordered_qty / flt(d.qty)) - - self.per_ordered = flt((per_ordered / flt(len(self.get("items")))) * 100.0, 2) - frappe.db.set_value(self.doctype, self.name, "per_ordered", self.per_ordered) + + self._update_percent_field({ + "target_dt": "Material Request Item", + "target_parent_dt": self.doctype, + "target_parent_field": "per_ordered", + "target_ref_field": "qty", + "target_field": "ordered_qty", + "name": self.name, + }, update_modified) def update_requested_qty(self, mr_item_rows=None): """update requested qty (before ordered_qty is updated)""" @@ -329,25 +335,33 @@ def make_stock_entry(source_name, target_doc=None): return doclist - @frappe.whitelist() -def validate_production_item(item_code): - return frappe.db.get_value("Item", item_code, "is_pro_applicable") - -@frappe.whitelist() -def make_production_order(source_name, item_code): +def raise_production_orders(source_name): material_request= frappe.get_doc("Material Request", source_name) - prod_order = frappe.new_doc("Production Order") - prod_order.production_item = item_code - prod_order.qty = 0 + errors =[] + production_orders = [] for d in material_request.items: - if d.item_code == item_code: - prod_order.qty = d.qty - d.ordered_qty - prod_order.fg_warehouse = d.warehouse - prod_order.description = d.description - prod_order.stock_uom = d.uom - prod_order.expected_delivery_date = d.schedule_date - prod_order.sales_order = d.sales_order - prod_order.bom_no = get_item_details(item_code).bom_no - prod_order.material_request = material_request.name - return prod_order + if (d.qty - d.ordered_qty) >0 : + if frappe.db.get_value("Item", d.item_code, "is_pro_applicable"): + prod_order = frappe.new_doc("Production Order") + prod_order.production_item = d.item_code + prod_order.qty = d.qty - d.ordered_qty + prod_order.fg_warehouse = d.warehouse + prod_order.description = d.description + prod_order.stock_uom = d.uom + prod_order.expected_delivery_date = d.schedule_date + prod_order.sales_order = d.sales_order + prod_order.bom_no = get_item_details(d.item_code).bom_no + prod_order.material_request = material_request.name + prod_order.material_request_item = d.name + prod_order.planned_start_date = material_request.transaction_date + prod_order.save() + production_orders.append(prod_order.name) + else: + errors.append(d.item_code + " in Row " + cstr(d.idx)) + if production_orders: + message = ["""%s""" % \ + (p, p) for p in production_orders] + msgprint(_("Production Orders {0} created").format(comma_and(message))) + if errors: + msgprint(_("Could not Raise Production Orders for {0}").format(comma_and(errors))) \ No newline at end of file