Fetch operations from all sub-assembly BOMs in Pro Order if multi-level BOM is checked
diff --git a/erpnext/manufacturing/doctype/production_order/production_order.js b/erpnext/manufacturing/doctype/production_order/production_order.js
index 836024c..1217790 100644
--- a/erpnext/manufacturing/doctype/production_order/production_order.js
+++ b/erpnext/manufacturing/doctype/production_order/production_order.js
@@ -272,6 +272,12 @@
 			}
 		});
 	},
+	
+	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 907a4b3..2d9a067 100644
--- a/erpnext/manufacturing/doctype/production_order/production_order.py
+++ b/erpnext/manufacturing/doctype/production_order/production_order.py
@@ -213,12 +213,29 @@
 
 	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 @@
 		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 @@
 		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 @@
 			'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 @@
 
 @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 00bf934..618235f 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