Merge pull request #3467 from anandpdoshi/anand-june-12

Fixes
diff --git a/erpnext/manufacturing/doctype/production_order/production_order.py b/erpnext/manufacturing/doctype/production_order/production_order.py
index 6de0d7b..ca5f6d9 100644
--- a/erpnext/manufacturing/doctype/production_order/production_order.py
+++ b/erpnext/manufacturing/doctype/production_order/production_order.py
@@ -217,12 +217,14 @@
 		for i, d in enumerate(self.operations):
 			self.set_operation_start_end_time(i, d)
 
+			if not d.workstation:
+				continue
+
 			time_log = make_time_log(self.name, d.operation, d.planned_start_time, d.planned_end_time,
 				flt(self.qty) - flt(d.completed_qty), self.project_name, d.workstation, operation_id=d.name)
 
-			if d.workstation:
-				# validate operating hours if workstation [not mandatory] is specified
-				self.check_operation_fits_in_working_hours(d)
+			# validate operating hours if workstation [not mandatory] is specified
+			self.check_operation_fits_in_working_hours(d)
 
 			original_start_time = time_log.from_time
 			while True:
diff --git a/erpnext/projects/doctype/time_log/time_log.py b/erpnext/projects/doctype/time_log/time_log.py
index a0fa23b..aa5647e 100644
--- a/erpnext/projects/doctype/time_log/time_log.py
+++ b/erpnext/projects/doctype/time_log/time_log.py
@@ -128,7 +128,7 @@
 
 	def update_production_order(self):
 		"""Updates `start_date`, `end_date`, `status` for operation in Production Order."""
-		
+
 		if self.production_order and self.for_manufacturing:
 			if not self.operation_id:
 				frappe.throw(_("Operation ID not set"))
@@ -208,22 +208,23 @@
 			self.production_order = None
 			self.operation = None
 			self.quantity = None
-	
+
 	def update_cost(self):
 		rate = get_activity_cost(self.employee, self.activity_type)
 		if rate:
 			self.costing_rate = rate.get('costing_rate')
-			self.billing_rate = rate.get('billing_rate') 
+			self.billing_rate = rate.get('billing_rate')
 			self.costing_amount = self.costing_rate * self.hours
 			if self.billable:
 				self.billing_amount = self.billing_rate * self.hours
 			else:
 				self.billing_amount = 0
-				
+
 	def validate_task(self):
-		if self.project and not self.task:
+		# if a time log is being created against a project without production order
+		if (self.project and not self.production_order) and not self.task:
 			frappe.throw(_("Task is Mandatory if Time Log is against a project"))
-	
+
 	def update_task(self):
 		if self.task and frappe.db.exists("Task", self.task):
 			task = frappe.get_doc("Task", self.task)
@@ -266,7 +267,7 @@
 			d.title += " for Project: " + d.project
 
 	return data
-	
+
 @frappe.whitelist()
 def get_activity_cost(employee=None, activity_type=None):
 	rate = frappe.db.sql("""select costing_rate, billing_rate from `tabActivity Cost` where employee= %s