From 5b60ef2dcec0f4c2b0ac32f3301a9bfe8e9380b1 Mon Sep 17 00:00:00 2001 From: Nabin Hait Date: Mon, 27 Mar 2017 16:29:51 +0530 Subject: [PATCH] Fetch operations from all sub-assembly BOMs in Pro Order if multi-level BOM is checked --- .../production_order/production_order.js | 6 + .../production_order/production_order.py | 49 ++++++-- .../production_order_operation.json | 118 +++++++++++++++++- 3 files changed, 158 insertions(+), 15 deletions(-) diff --git a/erpnext/manufacturing/doctype/production_order/production_order.js b/erpnext/manufacturing/doctype/production_order/production_order.js index 836024c3b0..1217790113 100644 --- a/erpnext/manufacturing/doctype/production_order/production_order.js +++ b/erpnext/manufacturing/doctype/production_order/production_order.js @@ -272,6 +272,12 @@ $.extend(cur_frm.cscript, { } }); }, + + use_multi_level_bom: function() { + if(this.frm.doc.bom_no) { + this.frm.trigger("bom_no"); + } + }, qty: function() { frappe.ui.form.trigger("Production Order", 'bom_no') diff --git a/erpnext/manufacturing/doctype/production_order/production_order.py b/erpnext/manufacturing/doctype/production_order/production_order.py index 907a4b324a..2d9a06711a 100644 --- a/erpnext/manufacturing/doctype/production_order/production_order.py +++ b/erpnext/manufacturing/doctype/production_order/production_order.py @@ -213,12 +213,29 @@ class ProductionOrder(Document): def set_production_order_operations(self): """Fetch operations from BOM and set in 'Production Order'""" - if not self.bom_no or cint(frappe.db.get_single_value("Manufacturing Settings", "disable_capacity_planning")): - return + + if not self.bom_no \ + or cint(frappe.db.get_single_value("Manufacturing Settings", "disable_capacity_planning")): + return + self.set('operations', []) - operations = frappe.db.sql("""select operation, description, workstation, idx, - base_hour_rate as hour_rate, time_in_mins, "Pending" as status from `tabBOM Operation` - where parent = %s order by idx""", self.bom_no, as_dict=1) + + if self.use_multi_level_bom: + bom_list = frappe.get_doc("BOM", self.bom_no).traverse_tree() + else: + bom_list = [self.bom_no] + + operations = frappe.db.sql(""" + select + operation, description, workstation, idx, + base_hour_rate as hour_rate, time_in_mins, + "Pending" as status, parent as bom + from + `tabBOM Operation` + where + parent in (%s) order by idx + """ % ", ".join(["%s"]*len(bom_list)), tuple(bom_list), as_dict=1) + self.set('operations', operations) self.calculate_time() @@ -257,14 +274,15 @@ class ProductionOrder(Document): plan_days = frappe.db.get_single_value("Manufacturing Settings", "capacity_planning_for_days") or 30 timesheet = make_timesheet(self.name) - workstation_list = [] timesheet.set('time_logs', []) for i, d in enumerate(self.operations): - if d.workstation and d.status != 'Completed': - self.set_start_end_time_for_workstation(d, workstation_list, i) + + if d.status != 'Completed': + self.set_start_end_time_for_workstation(d, i) args = self.get_operations_data(d) + add_timesheet_detail(timesheet, args) original_start_time = d.planned_start_time @@ -291,7 +309,7 @@ class ProductionOrder(Document): if timesheet and open_new: return timesheet - if timesheet: + if timesheet and timesheet.get("time_logs"): timesheet.save() timesheets.append(timesheet.name) @@ -312,7 +330,7 @@ class ProductionOrder(Document): 'completed_qty': flt(self.qty) - flt(data.completed_qty) } - def set_start_end_time_for_workstation(self, data, workstation_list, index): + def set_start_end_time_for_workstation(self, data, index): """Set start and end time for given operation. If first operation, set start as `planned_start_date`, else add time diff to end time of earlier operation.""" @@ -449,9 +467,14 @@ class ProductionOrder(Document): @frappe.whitelist() def get_item_details(item, project = None): - res = frappe.db.sql("""select stock_uom, description - from `tabItem` where disabled=0 and (end_of_life is null or end_of_life='0000-00-00' or end_of_life > %s) - and name=%s""", (nowdate(), item), as_dict=1) + res = frappe.db.sql(""" + select stock_uom, description + from `tabItem` + where disabled=0 + and (end_of_life is null or end_of_life='0000-00-00' or end_of_life > %s) + and name=%s + """, (nowdate(), item), as_dict=1) + if not res: return {} diff --git a/erpnext/manufacturing/doctype/production_order_operation/production_order_operation.json b/erpnext/manufacturing/doctype/production_order_operation/production_order_operation.json index 00bf934d83..618235f002 100644 --- a/erpnext/manufacturing/doctype/production_order_operation/production_order_operation.json +++ b/erpnext/manufacturing/doctype/production_order_operation/production_order_operation.json @@ -1,5 +1,6 @@ { "allow_copy": 0, + "allow_guest_to_view": 0, "allow_import": 0, "allow_rename": 0, "beta": 0, @@ -9,18 +10,22 @@ "doctype": "DocType", "document_type": "", "editable_grid": 1, + "engine": "InnoDB", "fields": [ { "allow_on_submit": 0, "bold": 0, "collapsible": 0, + "columns": 0, "fieldname": "details", "fieldtype": "Section Break", "hidden": 0, "ignore_user_permissions": 0, "ignore_xss_filter": 0, "in_filter": 0, + "in_global_search": 0, "in_list_view": 0, + "in_standard_filter": 0, "label": "", "length": 0, "no_copy": 0, @@ -29,6 +34,7 @@ "print_hide": 0, "print_hide_if_no_value": 0, "read_only": 0, + "remember_last_selected_value": 0, "report_hide": 0, "reqd": 0, "search_index": 0, @@ -39,13 +45,16 @@ "allow_on_submit": 0, "bold": 0, "collapsible": 0, + "columns": 0, "fieldname": "operation", "fieldtype": "Link", "hidden": 0, "ignore_user_permissions": 0, "ignore_xss_filter": 0, "in_filter": 0, + "in_global_search": 0, "in_list_view": 1, + "in_standard_filter": 0, "label": "Operation", "length": 0, "no_copy": 0, @@ -57,6 +66,7 @@ "print_hide": 0, "print_hide_if_no_value": 0, "read_only": 1, + "remember_last_selected_value": 0, "report_hide": 0, "reqd": 1, "search_index": 0, @@ -67,13 +77,46 @@ "allow_on_submit": 0, "bold": 0, "collapsible": 0, + "columns": 0, + "fieldname": "bom", + "fieldtype": "Link", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_global_search": 0, + "in_list_view": 1, + "in_standard_filter": 0, + "label": "BOM", + "length": 0, + "no_copy": 1, + "options": "BOM", + "permlevel": 0, + "precision": "", + "print_hide": 1, + "print_hide_if_no_value": 0, + "read_only": 1, + "remember_last_selected_value": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, + "unique": 0 + }, + { + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, "fieldname": "description", "fieldtype": "Text Editor", "hidden": 0, "ignore_user_permissions": 0, "ignore_xss_filter": 0, "in_filter": 0, + "in_global_search": 0, "in_list_view": 0, + "in_standard_filter": 0, "label": "Operation Description", "length": 0, "no_copy": 0, @@ -84,6 +127,7 @@ "print_hide": 0, "print_hide_if_no_value": 0, "read_only": 1, + "remember_last_selected_value": 0, "report_hide": 0, "reqd": 0, "search_index": 0, @@ -94,13 +138,16 @@ "allow_on_submit": 0, "bold": 0, "collapsible": 0, + "columns": 0, "fieldname": "col_break1", "fieldtype": "Column Break", "hidden": 0, "ignore_user_permissions": 0, "ignore_xss_filter": 0, "in_filter": 0, + "in_global_search": 0, "in_list_view": 0, + "in_standard_filter": 0, "length": 0, "no_copy": 0, "permlevel": 0, @@ -108,6 +155,7 @@ "print_hide": 0, "print_hide_if_no_value": 0, "read_only": 0, + "remember_last_selected_value": 0, "report_hide": 0, "reqd": 0, "search_index": 0, @@ -118,6 +166,7 @@ "allow_on_submit": 0, "bold": 0, "collapsible": 0, + "columns": 0, "description": "Operation completed for how many finished goods?", "fieldname": "completed_qty", "fieldtype": "Float", @@ -125,7 +174,9 @@ "ignore_user_permissions": 0, "ignore_xss_filter": 0, "in_filter": 0, + "in_global_search": 0, "in_list_view": 0, + "in_standard_filter": 0, "label": "Completed Qty", "length": 0, "no_copy": 1, @@ -134,6 +185,7 @@ "print_hide": 0, "print_hide_if_no_value": 0, "read_only": 1, + "remember_last_selected_value": 0, "report_hide": 0, "reqd": 0, "search_index": 0, @@ -144,6 +196,7 @@ "allow_on_submit": 0, "bold": 0, "collapsible": 0, + "columns": 0, "default": "Pending", "fieldname": "status", "fieldtype": "Select", @@ -151,7 +204,9 @@ "ignore_user_permissions": 0, "ignore_xss_filter": 0, "in_filter": 0, + "in_global_search": 0, "in_list_view": 1, + "in_standard_filter": 0, "label": "Status", "length": 0, "no_copy": 1, @@ -161,6 +216,7 @@ "print_hide": 0, "print_hide_if_no_value": 0, "read_only": 1, + "remember_last_selected_value": 0, "report_hide": 0, "reqd": 0, "search_index": 0, @@ -171,13 +227,16 @@ "allow_on_submit": 0, "bold": 0, "collapsible": 0, + "columns": 0, "fieldname": "workstation", "fieldtype": "Link", "hidden": 0, "ignore_user_permissions": 0, "ignore_xss_filter": 0, "in_filter": 0, + "in_global_search": 0, "in_list_view": 1, + "in_standard_filter": 0, "label": "Workstation", "length": 0, "no_copy": 0, @@ -189,6 +248,7 @@ "print_hide": 0, "print_hide_if_no_value": 0, "read_only": 0, + "remember_last_selected_value": 0, "report_hide": 0, "reqd": 0, "search_index": 0, @@ -199,13 +259,16 @@ "allow_on_submit": 0, "bold": 0, "collapsible": 0, + "columns": 0, "fieldname": "estimated_time_and_cost", "fieldtype": "Section Break", "hidden": 0, "ignore_user_permissions": 0, "ignore_xss_filter": 0, "in_filter": 0, + "in_global_search": 0, "in_list_view": 0, + "in_standard_filter": 0, "label": "Estimated Time and Cost", "length": 0, "no_copy": 0, @@ -214,6 +277,7 @@ "print_hide": 0, "print_hide_if_no_value": 0, "read_only": 0, + "remember_last_selected_value": 0, "report_hide": 0, "reqd": 0, "search_index": 0, @@ -224,13 +288,16 @@ "allow_on_submit": 0, "bold": 0, "collapsible": 0, + "columns": 0, "fieldname": "planned_start_time", "fieldtype": "Datetime", "hidden": 0, "ignore_user_permissions": 0, "ignore_xss_filter": 0, "in_filter": 0, + "in_global_search": 0, "in_list_view": 0, + "in_standard_filter": 0, "label": "Planned Start Time", "length": 0, "no_copy": 1, @@ -239,6 +306,7 @@ "print_hide": 0, "print_hide_if_no_value": 0, "read_only": 1, + "remember_last_selected_value": 0, "report_hide": 0, "reqd": 0, "search_index": 0, @@ -249,13 +317,16 @@ "allow_on_submit": 0, "bold": 0, "collapsible": 0, + "columns": 0, "fieldname": "planned_end_time", "fieldtype": "Datetime", "hidden": 0, "ignore_user_permissions": 0, "ignore_xss_filter": 0, "in_filter": 0, + "in_global_search": 0, "in_list_view": 0, + "in_standard_filter": 0, "label": "Planned End Time", "length": 0, "no_copy": 1, @@ -264,6 +335,7 @@ "print_hide": 0, "print_hide_if_no_value": 0, "read_only": 1, + "remember_last_selected_value": 0, "report_hide": 0, "reqd": 0, "search_index": 0, @@ -274,13 +346,16 @@ "allow_on_submit": 0, "bold": 0, "collapsible": 0, + "columns": 0, "fieldname": "column_break_10", "fieldtype": "Column Break", "hidden": 0, "ignore_user_permissions": 0, "ignore_xss_filter": 0, "in_filter": 0, + "in_global_search": 0, "in_list_view": 0, + "in_standard_filter": 0, "length": 0, "no_copy": 0, "permlevel": 0, @@ -288,6 +363,7 @@ "print_hide": 0, "print_hide_if_no_value": 0, "read_only": 0, + "remember_last_selected_value": 0, "report_hide": 0, "reqd": 0, "search_index": 0, @@ -298,6 +374,7 @@ "allow_on_submit": 0, "bold": 0, "collapsible": 0, + "columns": 0, "description": "in Minutes", "fieldname": "time_in_mins", "fieldtype": "Float", @@ -305,7 +382,9 @@ "ignore_user_permissions": 0, "ignore_xss_filter": 0, "in_filter": 0, + "in_global_search": 0, "in_list_view": 1, + "in_standard_filter": 0, "label": "Operation Time", "length": 0, "no_copy": 0, @@ -316,6 +395,7 @@ "print_hide": 0, "print_hide_if_no_value": 0, "read_only": 0, + "remember_last_selected_value": 0, "report_hide": 0, "reqd": 1, "search_index": 0, @@ -326,13 +406,16 @@ "allow_on_submit": 0, "bold": 0, "collapsible": 0, + "columns": 0, "fieldname": "hour_rate", "fieldtype": "Float", "hidden": 0, "ignore_user_permissions": 0, "ignore_xss_filter": 0, "in_filter": 0, + "in_global_search": 0, "in_list_view": 0, + "in_standard_filter": 0, "label": "Hour Rate", "length": 0, "no_copy": 0, @@ -343,6 +426,7 @@ "print_hide": 0, "print_hide_if_no_value": 0, "read_only": 1, + "remember_last_selected_value": 0, "report_hide": 0, "reqd": 0, "search_index": 0, @@ -353,13 +437,16 @@ "allow_on_submit": 0, "bold": 0, "collapsible": 0, + "columns": 0, "fieldname": "planned_operating_cost", "fieldtype": "Currency", "hidden": 0, "ignore_user_permissions": 0, "ignore_xss_filter": 0, "in_filter": 0, + "in_global_search": 0, "in_list_view": 0, + "in_standard_filter": 0, "label": "Planned Operating Cost", "length": 0, "no_copy": 0, @@ -369,6 +456,7 @@ "print_hide": 0, "print_hide_if_no_value": 0, "read_only": 1, + "remember_last_selected_value": 0, "report_hide": 0, "reqd": 0, "search_index": 0, @@ -379,13 +467,16 @@ "allow_on_submit": 0, "bold": 0, "collapsible": 0, + "columns": 0, "fieldname": "section_break_9", "fieldtype": "Section Break", "hidden": 0, "ignore_user_permissions": 0, "ignore_xss_filter": 0, "in_filter": 0, + "in_global_search": 0, "in_list_view": 0, + "in_standard_filter": 0, "label": "Actual Time and Cost", "length": 0, "no_copy": 0, @@ -394,6 +485,7 @@ "print_hide": 0, "print_hide_if_no_value": 0, "read_only": 0, + "remember_last_selected_value": 0, "report_hide": 0, "reqd": 0, "search_index": 0, @@ -404,13 +496,16 @@ "allow_on_submit": 0, "bold": 0, "collapsible": 0, + "columns": 0, "fieldname": "actual_start_time", "fieldtype": "Datetime", "hidden": 0, "ignore_user_permissions": 0, "ignore_xss_filter": 0, "in_filter": 0, + "in_global_search": 0, "in_list_view": 0, + "in_standard_filter": 0, "label": "Actual Start Time", "length": 0, "no_copy": 1, @@ -419,6 +514,7 @@ "print_hide": 0, "print_hide_if_no_value": 0, "read_only": 1, + "remember_last_selected_value": 0, "report_hide": 0, "reqd": 0, "search_index": 0, @@ -429,6 +525,7 @@ "allow_on_submit": 0, "bold": 0, "collapsible": 0, + "columns": 0, "description": "Updated via 'Time Log'", "fieldname": "actual_end_time", "fieldtype": "Datetime", @@ -436,7 +533,9 @@ "ignore_user_permissions": 0, "ignore_xss_filter": 0, "in_filter": 0, + "in_global_search": 0, "in_list_view": 0, + "in_standard_filter": 0, "label": "Actual End Time", "length": 0, "no_copy": 1, @@ -445,6 +544,7 @@ "print_hide": 0, "print_hide_if_no_value": 0, "read_only": 1, + "remember_last_selected_value": 0, "report_hide": 0, "reqd": 0, "search_index": 0, @@ -455,13 +555,16 @@ "allow_on_submit": 0, "bold": 0, "collapsible": 0, + "columns": 0, "fieldname": "column_break_11", "fieldtype": "Column Break", "hidden": 0, "ignore_user_permissions": 0, "ignore_xss_filter": 0, "in_filter": 0, + "in_global_search": 0, "in_list_view": 0, + "in_standard_filter": 0, "length": 0, "no_copy": 0, "permlevel": 0, @@ -469,6 +572,7 @@ "print_hide": 0, "print_hide_if_no_value": 0, "read_only": 0, + "remember_last_selected_value": 0, "report_hide": 0, "reqd": 0, "search_index": 0, @@ -479,6 +583,7 @@ "allow_on_submit": 0, "bold": 0, "collapsible": 0, + "columns": 0, "description": "in Minutes\nUpdated via 'Time Log'", "fieldname": "actual_operation_time", "fieldtype": "Float", @@ -486,7 +591,9 @@ "ignore_user_permissions": 0, "ignore_xss_filter": 0, "in_filter": 0, + "in_global_search": 0, "in_list_view": 0, + "in_standard_filter": 0, "label": "Actual Operation Time", "length": 0, "no_copy": 1, @@ -495,6 +602,7 @@ "print_hide": 0, "print_hide_if_no_value": 0, "read_only": 1, + "remember_last_selected_value": 0, "report_hide": 0, "reqd": 0, "search_index": 0, @@ -505,6 +613,7 @@ "allow_on_submit": 0, "bold": 0, "collapsible": 0, + "columns": 0, "description": "(Hour Rate / 60) * Actual Operation Time", "fieldname": "actual_operating_cost", "fieldtype": "Currency", @@ -512,7 +621,9 @@ "ignore_user_permissions": 0, "ignore_xss_filter": 0, "in_filter": 0, + "in_global_search": 0, "in_list_view": 0, + "in_standard_filter": 0, "label": "Actual Operating Cost", "length": 0, "no_copy": 1, @@ -522,6 +633,7 @@ "print_hide": 0, "print_hide_if_no_value": 0, "read_only": 1, + "remember_last_selected_value": 0, "report_hide": 0, "reqd": 0, "search_index": 0, @@ -529,17 +641,17 @@ "unique": 0 } ], + "has_web_view": 0, "hide_heading": 0, "hide_toolbar": 0, "idx": 0, "image_view": 0, "in_create": 0, - "in_dialog": 0, "is_submittable": 0, "issingle": 0, "istable": 1, "max_attachments": 0, - "modified": "2016-08-22 03:41:42.356833", + "modified": "2017-03-27 15:56:29.010336", "modified_by": "Administrator", "module": "Manufacturing", "name": "Production Order Operation", @@ -549,7 +661,9 @@ "quick_entry": 0, "read_only": 0, "read_only_onload": 0, + "show_name_in_global_search": 0, "sort_field": "modified", "sort_order": "DESC", + "track_changes": 1, "track_seen": 0 } \ No newline at end of file