bom code cleanup
diff --git a/manufacturing/doctype/bom/bom.py b/manufacturing/doctype/bom/bom.py
index 857458e..ea596db 100644
--- a/manufacturing/doctype/bom/bom.py
+++ b/manufacturing/doctype/bom/bom.py
@@ -60,7 +60,6 @@
 		return ret
 
 
-
 	def get_workstation_details(self,workstation):
 		""" Fetch hour rate from workstation master"""
 
@@ -83,7 +82,6 @@
 			msgprint("Item %s does not exist in system" % item[0]['item_code'], raise_exception = 1)
 
 
-
 	def get_bom_material_detail(self):
 		""" Get raw material details like uom, desc and rate"""
 
@@ -146,7 +144,6 @@
 		return rate and flt(sum(rate))/len(rate) or 0
 
 
-
 	def manage_default_bom(self):
 		""" Uncheck others if current one is selected as default, 
 			update default bom in item master
@@ -156,68 +153,16 @@
 			sql("update `tabBOM` set is_default = 0 where name != %s and item=%s", 
 				(self.doc.name, self.doc.item))
 
-			# update default bom in Item Master
-			sql("update `tabItem` set default_bom = %s where name = %s", 
-				(self.doc.name, self.doc.item))
+			webnotes.conn.set_value("Item", self.doc.item, "default_bom", self.doc.name)
 		else:
 			sql("update `tabItem` set default_bom = '' where name = %s and default_bom = %s", 
 			 	(self.doc.item, self.doc.name))
 
 
-	def manage_active_bom(self):
-		""" Manage active/inactive """
-		if self.doc.is_active == 'Yes':
-			self.validate()
-		else:
-			self.check_active_parent_boms()
-
-
-
-	def check_active_parent_boms(self):
-		""" Check parent BOM before making it inactive """
-		act_pbom = sql("""select distinct t1.parent from `tabBOM Item` t1, `tabBOM` t2 
-			where t1.bom_no =%s and t2.name = t1.parent and t2.is_active = 'Yes' 
-			and t2.docstatus = 1 and t1.docstatus =1 """, self.doc.name)
-		if act_pbom and act_pbom[0][0]:
-			msgprint("""Sorry cannot inactivate as BOM: %s is child 
-				of one or many other active parent BOMs""" % self.doc.name, raise_exception=1)
-
-
-
-	def calculate_cost(self):
-		"""Calculate bom totals"""
-		self.calculate_op_cost()
-		self.calculate_rm_cost()
-		self.doc.total_cost = self.doc.raw_material_cost + self.doc.operating_cost
-		self.doc.modified = now()
-		self.doc.save()
-	
-
-	def calculate_op_cost(self):
-		"""Update workstation rate and calculates totals"""
-		total_op_cost = 0
-		for d in getlist(self.doclist, 'bom_operations'):
-			if d.hour_rate and d.time_in_mins:
-				d.operating_cost = flt(d.hour_rate) * flt(d.time_in_mins) / 60.0
-			d.save()
-			total_op_cost += flt(d.operating_cost)
-		self.doc.operating_cost = total_op_cost
-		
-
-
-	def calculate_rm_cost(self):
-		"""Fetch RM rate as per today's valuation rate and calculate totals"""
-		total_rm_cost = 0
-		for d in getlist(self.doclist, 'bom_materials'):
-			if d.bom_no:
-				d.rate = self.get_bom_unitcost(d.bom_no)
-			d.amount = flt(d.rate) * flt(d.qty)
-			d.qty_consumed_per_unit = flt(d.qty) / flt(self.doc.quantity)
-			d.save()
-			total_rm_cost += d.amount
-		self.doc.raw_material_cost = total_rm_cost
-
-
+	def validate(self):
+		self.validate_main_item()
+		self.validate_operations()
+		self.validate_materials()
 
 	def validate_main_item(self):
 		""" Validate main FG item"""
@@ -283,7 +228,6 @@
 			msgprint("""Incorrect BOM No: %s against item: %s at row no: %s.
 				It may be inactive or cancelled or for some other item.""" % 
 				(bom_no, item, idx), raise_exception = 1)
-				
 
 
 	def check_if_item_repeated(self, item, op, check_list):
@@ -294,10 +238,9 @@
 			check_list.append([cstr(item), cstr(op)])
 
 
-	def validate(self):
-		self.validate_main_item()
-		self.validate_operations()
-		self.validate_materials()
+	def on_update(self):
+		self.check_recursion()
+		self.update_cost_and_exploded_items()
 
 	def check_recursion(self):
 		""" Check whether recursion occurs in any bom"""
@@ -315,27 +258,91 @@
 							""" % (cstr(b), cstr(d[2]), self.doc.name), raise_exception = 1)
 					if b[0]:
 						bom_list.append(b[0])
+						
+	
+	def update_cost_and_exploded_items(self, calculate_cost=True):
+		bom_list = self.traverse_tree()
+		bom_list.reverse()
+		for bom in bom_list:
+			bom_obj = get_obj("BOM", bom, with_children=1)
+			if calculate_cost:
+				bom_obj.calculate_cost()
+			bom_obj.update_flat_bom()
+			
 
+	def traverse_tree(self):
+		def _get_childs(bom_no):
+			return [cstr(d[0]) for d in webnotes.conn.sql("""select bom_no from `tabBOM Item` 
+				where parent = %s and ifnull(bom_no, '') != ''""", bom_no)]
+				
+		bom_list, count = [self.doc.name], 0		
+		while(count < len(bom_list)):
+			for child_bom in _get_childs(bom_list[count]):
+				if child_bom not in bom_list:
+					bom_list.append(child_bom)
+			count += 1
+		return bom_list
+	
+	
+	def calculate_cost(self):
+		"""Calculate bom totals"""
+		self.calculate_op_cost()
+		self.calculate_rm_cost()
+		self.doc.total_cost = self.doc.raw_material_cost + self.doc.operating_cost
+		self.doc.modified = now()
+		self.doc.save()
+	
 
-	def on_update(self):
-		self.check_recursion()
-		self.update_cost_by_traversing()
-		self.update_flat_bom_by_traversing()
+	def calculate_op_cost(self):
+		"""Update workstation rate and calculates totals"""
+		total_op_cost = 0
+		for d in getlist(self.doclist, 'bom_operations'):
+			if d.hour_rate and d.time_in_mins:
+				d.operating_cost = flt(d.hour_rate) * flt(d.time_in_mins) / 60.0
+			d.save()
+			total_op_cost += flt(d.operating_cost)
+		self.doc.operating_cost = total_op_cost
 		
 
-
-	def add_to_flat_bom_detail(self):
-		"Add items to Flat BOM table"
-		self.doclist = self.doc.clear_table(self.doclist, 'flat_bom_details', 1)
-		for d in self.cur_flat_bom_items:
-			ch = addchild(self.doc, 'flat_bom_details', 'BOM Explosion Item', 1, self.doclist)
-			for i in d.keys():
-				ch.fields[i] = d[i]
-			ch.docstatus = self.doc.docstatus
-			ch.save(1)
-		self.doc.save()
+	def calculate_rm_cost(self):
+		"""Fetch RM rate as per today's valuation rate and calculate totals"""
+		total_rm_cost = 0
+		for d in getlist(self.doclist, 'bom_materials'):
+			if d.bom_no:
+				d.rate = self.get_bom_unitcost(d.bom_no)
+			d.amount = flt(d.rate) * flt(d.qty)
+			d.qty_consumed_per_unit = flt(d.qty) / flt(self.doc.quantity)
+			d.save()
+			total_rm_cost += d.amount
+		self.doc.raw_material_cost = total_rm_cost
 
 
+	def update_flat_bom(self):
+		""" Update Flat BOM, following will be correct data"""
+		self.get_flat_bom_items()
+		self.add_to_flat_bom_detail()
+
+
+	def get_flat_bom_items(self):
+		""" Get all raw materials including items from child bom"""
+		self.cur_flat_bom_items = []
+		for d in getlist(self.doclist, 'bom_materials'):
+			if d.bom_no:
+				self.get_child_flat_bom_items(d.bom_no, d.qty)
+			else:
+				self.cur_flat_bom_items.append({
+					'item_code'				: d.item_code, 
+					'description'			: d.description, 
+					'stock_uom'				: d.stock_uom, 
+					'qty'					: flt(d.qty),
+					'rate'					: flt(d.rate), 
+					'amount'				: flt(d.amount),
+					'parent_bom'			: d.parent,
+					'mat_detail_no'			: d.name,
+					'qty_consumed_per_unit' : flt(d.qty_consumed_per_unit)
+				})
+	
+	
 	def get_child_flat_bom_items(self, bom_no, qty):
 		""" Add all items from Flat BOM of child BOM"""
 		
@@ -357,31 +364,16 @@
 
 			})
 
-
-	def get_flat_bom_items(self):
-		""" Get all raw materials including items from child bom"""
-		self.cur_flat_bom_items = []
-		for d in getlist(self.doclist, 'bom_materials'):
-			if d.bom_no:
-				self.get_child_flat_bom_items(d.bom_no, d.qty)
-			else:
-				self.cur_flat_bom_items.append({
-					'item_code'				: d.item_code, 
-					'description'			: d.description, 
-					'stock_uom'				: d.stock_uom, 
-					'qty'					: flt(d.qty),
-					'rate'					: flt(d.rate), 
-					'amount'				: flt(d.amount),
-					'parent_bom'			: d.parent,
-					'mat_detail_no'			: d.name,
-					'qty_consumed_per_unit' : flt(d.qty_consumed_per_unit)
-				})
-
-
-	def update_flat_bom(self):
-		""" Update Flat BOM, following will be correct data"""
-		self.get_flat_bom_items()
-		self.add_to_flat_bom_detail()
+	def add_to_flat_bom_detail(self):
+		"Add items to Flat BOM table"
+		self.doclist = self.doc.clear_table(self.doclist, 'flat_bom_details', 1)
+		for d in self.cur_flat_bom_items:
+			ch = addchild(self.doc, 'flat_bom_details', 'BOM Explosion Item', 1, self.doclist)
+			for i in d.keys():
+				ch.fields[i] = d[i]
+			ch.docstatus = self.doc.docstatus
+			ch.save(1)
+		self.doc.save()
 
 
 	def get_parent_bom_list(self, bom_no):
@@ -392,6 +384,7 @@
 	def on_submit(self):
 		self.manage_default_bom()
 
+
 	def on_cancel(self):
 		# check if used in any other bom
 		par = sql("""select t1.parent from `tabBOM Item` t1, `tabBOM` t2 
@@ -404,30 +397,19 @@
 		webnotes.conn.set(self.doc, "is_active", "No")
 		webnotes.conn.set(self.doc, "is_default", 0)
 		self.manage_default_bom()
-		self.update_flat_bom_by_traversing()
-		
-	def traverse_tree(self):
-		def _get_childs(bom_no):
-			return [cstr(d[0]) for d in webnotes.conn.sql("""select bom_no from `tabBOM Item` 
-				where parent = %s and ifnull(bom_no, '') != ''""", bom_no)]
+		self.update_cost_and_exploded_items(calculate_cost=False)
 				
-		bom_list, count = [self.doc.name], 0		
-		while(count < len(bom_list)):
-			for child_bom in _get_childs(bom_list[count]):
-				if child_bom not in bom_list:
-					bom_list.append(child_bom)
-			count += 1
-			
-		return bom_list
-		
-	def update_cost_by_traversing(self):
-		bom_list = self.traverse_tree()
-		bom_list.reverse()
-		for bom in bom_list:
-			get_obj("BOM", bom, with_children=1).calculate_cost()
-			
-	def update_flat_bom_by_traversing(self):
-		bom_list = self.traverse_tree()
-		bom_list.reverse()
-		for bom in bom_list:
-			get_obj("BOM", bom, with_children=1).update_flat_bom()
\ No newline at end of file
+
+	def on_update_after_submit(self):
+		self.manage_default_bom()
+		self.validate_inactive_bom()
+	
+	
+	def validate_inactive_bom(self):
+		if self.doc.is_active == 'No':
+			act_pbom = sql("""select distinct t1.parent from `tabBOM Item` t1, `tabBOM` t2 
+				where t1.bom_no =%s and t2.name = t1.parent and t2.is_active = 'Yes' 
+				and t2.docstatus = 1 and t1.docstatus =1 """, self.doc.name)
+			if act_pbom and act_pbom[0][0]:
+				msgprint("""Sorry cannot inactivate as BOM: %s is child 
+					of one or many other active parent BOMs""" % self.doc.name, raise_exception=1)
\ No newline at end of file