Merge pull request #2297 from neilLasrado/bom-issue

 Fix - BOM calculated wrong cost on update cost
diff --git a/erpnext/manufacturing/doctype/bom/bom.py b/erpnext/manufacturing/doctype/bom/bom.py
index 75c4ffb..e8a8682 100644
--- a/erpnext/manufacturing/doctype/bom/bom.py
+++ b/erpnext/manufacturing/doctype/bom/bom.py
@@ -115,6 +115,9 @@
 		return rate
 
 	def update_cost(self):
+		if self.docstatus == 2:
+			return
+
 		for d in self.get("bom_materials"):
 			d.rate = self.get_bom_material_detail({
 				'item_code': d.item_code,
@@ -122,9 +125,10 @@
 				'qty': d.qty
 			})["rate"]
 
-		if self.docstatus in (0, 1):
+		if self.docstatus == 1:
 			self.ignore_validate_update_after_submit = True
-			self.save()
+			self.calculate_cost()
+		self.save()
 
 	def get_bom_unitcost(self, bom_no):
 		bom = frappe.db.sql("""select name, total_variable_cost/quantity as unit_cost from `tabBOM`
@@ -269,29 +273,27 @@
 		"""Calculate bom totals"""
 		self.calculate_op_cost()
 		self.calculate_rm_cost()
-		self.calculate_fixed_cost()
 		self.total_variable_cost = self.raw_material_cost + self.operating_cost
+		self.total_cost = self.total_variable_cost + self.total_fixed_cost
 
 	def calculate_op_cost(self):
 		"""Update workstation rate and calculates totals"""
-		total_op_cost = 0
+		total_op_cost, fixed_cost = 0, 0
 		for d in self.get('bom_operations'):
-			if d.workstation and not d.hour_rate:
-				d.hour_rate = frappe.db.get_value("Workstation", d.workstation, "hour_rate")
+			if d.workstation:
+				w = frappe.db.get_value("Workstation", d.workstation, ["hour_rate", "fixed_cycle_cost"])
+				if not d.hour_rate:
+					d.hour_rate = flt(w[0])
+
+				fixed_cost += flt(w[1])
+
 			if d.hour_rate and d.time_in_mins:
 				d.operating_cost = flt(d.hour_rate) * flt(d.time_in_mins) / 60.0
 			total_op_cost += flt(d.operating_cost)
+
 		self.operating_cost = total_op_cost
-
-	def calculate_fixed_cost(self):
-		"""Update workstation rate and calculates totals"""
-		fixed_cost = 0
-		for d in self.get('bom_operations'):
-			if d.workstation:
-				fixed_cost += flt(frappe.db.get_value("Workstation", d.workstation, "fixed_cycle_cost"))
 		self.total_fixed_cost = fixed_cost
 
-
 	def calculate_rm_cost(self):
 		"""Fetch RM rate as per today's valuation rate and calculate totals"""
 		total_rm_cost = 0
diff --git a/erpnext/patches.txt b/erpnext/patches.txt
index 0dbe444..92f8395 100644
--- a/erpnext/patches.txt
+++ b/erpnext/patches.txt
@@ -85,3 +85,4 @@
 execute:frappe.delete_doc("Report", "Warehouse-Wise Stock Balance")
 execute:frappe.delete_doc("DocType", "Purchase Request")
 execute:frappe.delete_doc("DocType", "Purchase Request Item")
+erpnext.patches.v4_2.recalculate_bom_cost
\ No newline at end of file
diff --git a/erpnext/patches/v4_2/recalculate_bom_cost.py b/erpnext/patches/v4_2/recalculate_bom_cost.py
new file mode 100644
index 0000000..3a194ff
--- /dev/null
+++ b/erpnext/patches/v4_2/recalculate_bom_cost.py
@@ -0,0 +1,16 @@
+# Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors
+# License: GNU General Public License v3. See license.txt
+
+from __future__ import unicode_literals
+import frappe
+
+def execute():
+	for d in frappe.db.sql("select name from `tabBOM` where docstatus < 2"):
+		try:	
+			document = frappe.get_doc('BOM', d[0])
+			if document.docstatus == 1:
+				document.ignore_validate_update_after_submit = True
+				document.calculate_cost()
+			document.save()
+		except:
+			pass
\ No newline at end of file