[fix] production_order.py via error report
diff --git a/erpnext/manufacturing/doctype/production_order/production_order.py b/erpnext/manufacturing/doctype/production_order/production_order.py
index 1147570..f04fddf 100644
--- a/erpnext/manufacturing/doctype/production_order/production_order.py
+++ b/erpnext/manufacturing/doctype/production_order/production_order.py
@@ -51,9 +51,9 @@
 	def validate_sales_order(self):
 		if self.sales_order:
 			so = frappe.db.sql("""
-				select so.name, so_item.delivery_date, so.project 
+				select so.name, so_item.delivery_date, so.project
 				from `tabSales Order` so, `tabSales Order Item` so_item
-				where so.name=%s and so.name=so_item.parent 
+				where so.name=%s and so.name=so_item.parent
 					and so.docstatus = 1 and so_item.item_code=%s
 			""", (self.sales_order, self.production_item), as_dict=1)
 
@@ -112,7 +112,7 @@
 
 		allowance_percentage = flt(frappe.db.get_single_value("Manufacturing Settings",
 			"over_production_allowance_percentage"))
-			
+
 		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), OverProductionError)
@@ -217,27 +217,27 @@
 	def set_production_order_operations(self):
 		"""Fetch operations from BOM and set in 'Production Order'"""
 		self.set('operations', [])
-		
+
 		if not self.bom_no \
 			or cint(frappe.db.get_single_value("Manufacturing Settings", "disable_capacity_planning")):
 				return
-		
+
 		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 
+			select
 				operation, description, workstation, idx,
-				base_hour_rate as hour_rate, time_in_mins, 
+				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()
 
@@ -277,7 +277,7 @@
 		timesheet.set('time_logs', [])
 
 		for i, d in enumerate(self.operations):
-			
+
 			if d.status != 'Completed':
 				self.set_start_end_time_for_workstation(d, i)
 
@@ -370,8 +370,8 @@
 		self.actual_start_date = None
 		self.actual_end_date = None
 		if self.get("operations"):
-			self.actual_start_date = min([d.actual_start_time for d in self.get("operations")])
-			self.actual_end_date = max([d.actual_end_time for d in self.get("operations")])
+			self.actual_start_date = min([d.actual_start_time for d in self.get("operations") if d.actual_start_time])
+			self.actual_end_date = max([d.actual_end_time for d in self.get("operations") if d.actual_end_time])
 
 	def delete_timesheet(self):
 		for timesheet in frappe.get_all("Timesheet", ["name"], {"production_order": self.name}):
@@ -411,18 +411,18 @@
 			if d.source_warehouse:
 				stock_bin = get_bin(d.item_code, d.source_warehouse)
 				stock_bin.update_reserved_qty_for_production()
-			
+
 	def get_items_and_operations_from_bom(self):
 		self.set_required_items()
 		self.set_production_order_operations()
-		
+
 		return check_if_scrap_warehouse_mandatory(self.bom_no)
-		
+
 	def set_available_qty(self):
 		for d in self.get("required_items"):
 			if d.source_warehouse:
 				d.available_qty_at_source_warehouse = get_latest_stock_qty(d.item_code, d.source_warehouse)
-				
+
 			if self.wip_warehouse:
 				d.available_qty_at_wip_warehouse = get_latest_stock_qty(d.item_code, self.wip_warehouse)
 
@@ -439,7 +439,7 @@
 					'required_qty': item.qty,
 					'source_warehouse': item.source_warehouse or item.default_warehouse
 				})
-			
+
 			self.set_available_qty()
 
 	def update_transaferred_qty_for_required_items(self):
@@ -463,12 +463,12 @@
 def get_item_details(item, project = None):
 	res = frappe.db.sql("""
 		select stock_uom, description
-		from `tabItem` 
-		where disabled=0 
+		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 {}
 
@@ -611,14 +611,14 @@
 @frappe.whitelist()
 def stop_unstop(production_order, status):
 	""" Called from client side on Stop/Unstop event"""
-	
+
 	if not frappe.has_permission("Production Order", "write"):
 		frappe.throw(_("Not permitted"), frappe.PermissionError)
-		
+
 	pro_order = frappe.get_doc("Production Order", production_order)
 	pro_order.update_status(status)
 	pro_order.update_planned_qty()
 	frappe.msgprint(_("Production Order has been {0}").format(status))
 	pro_order.notify_update()
-	
+
 	return pro_order.status
\ No newline at end of file