sub-contracting rewrite with testcases
diff --git a/accounts/doctype/purchase_invoice/purchase_invoice.py b/accounts/doctype/purchase_invoice/purchase_invoice.py
index 96cfc00..01359d3 100644
--- a/accounts/doctype/purchase_invoice/purchase_invoice.py
+++ b/accounts/doctype/purchase_invoice/purchase_invoice.py
@@ -320,6 +320,7 @@
 		 	self.doc.posting_date,'Posting Date')
 		
 		self.validate_write_off_account()
+		self.update_raw_material_cost()
 
 	def check_prev_docstatus(self):
 		for d in getlist(self.doclist,'entries'):
@@ -494,3 +495,16 @@
 	def on_update(self):
 		pass
 
+	def update_raw_material_cost(self):
+		if self.sub_contracted_items:
+			for d in self.doclist.get({"parentfield": "entries"}):
+				rm_cost = webnotes.conn.sql(""" select raw_material_cost / quantity 
+					from `tabBOM` where item = %s and is_default = 1 and docstatus = 1 
+					and is_active = 1 """, (d.item_code,))
+				rm_cost = rm_cost and flt(rm_cost[0][0]) or 0
+			
+				d.conversion_factor = d.conversion_factor or webnotes.conn.get_value(
+					"UOM Conversion Detail", {"parent": d.item_code, "uom": d.uom}, 
+					"conversion_factor") or 1
+			
+				d.rm_supp_cost = rm_cost * flt(d.qty) * flt(d.conversion_factor)
\ No newline at end of file
diff --git a/accounts/doctype/purchase_invoice_item/purchase_invoice_item.txt b/accounts/doctype/purchase_invoice_item/purchase_invoice_item.txt
index ecd981d..553041e 100755
--- a/accounts/doctype/purchase_invoice_item/purchase_invoice_item.txt
+++ b/accounts/doctype/purchase_invoice_item/purchase_invoice_item.txt
@@ -1,8 +1,8 @@
 [
  {
-  "creation": "2013-01-29 20:53:00", 
+  "creation": "2013-02-11 10:54:51", 
   "docstatus": 0, 
-  "modified": "2013-02-08 14:06:17", 
+  "modified": "2013-02-27 18:10:04", 
   "modified_by": "Administrator", 
   "owner": "Administrator"
  }, 
@@ -283,6 +283,35 @@
   "width": "150px"
  }, 
  {
+  "doctype": "DocField", 
+  "fieldname": "valuation_rate", 
+  "fieldtype": "Currency", 
+  "hidden": 1, 
+  "label": "Valuation Rate", 
+  "no_copy": 1, 
+  "options": "Company:company:default_currency", 
+  "print_hide": 1, 
+  "read_only": 1
+ }, 
+ {
+  "doctype": "DocField", 
+  "fieldname": "conversion_factor", 
+  "fieldtype": "Float", 
+  "label": "Conversion Factor", 
+  "print_hide": 1
+ }, 
+ {
+  "doctype": "DocField", 
+  "fieldname": "rm_supp_cost", 
+  "fieldtype": "Currency", 
+  "hidden": 1, 
+  "label": "Raw Materials Supplied Cost", 
+  "no_copy": 1, 
+  "options": "Company:company:default_currency", 
+  "print_hide": 1, 
+  "read_only": 1
+ }, 
+ {
   "allow_on_submit": 1, 
   "doctype": "DocField", 
   "fieldname": "page_break", 
diff --git a/controllers/buying_controller.py b/controllers/buying_controller.py
index bbcd492..2b76ad1 100644
--- a/controllers/buying_controller.py
+++ b/controllers/buying_controller.py
@@ -232,7 +232,7 @@
 		else:
 			self.doc.grand_total = flt(self.doc.net_total,
 				self.precision.main.grand_total)
-			self.doc.grand_total_print = flt(
+			self.doc.grand_total_import = flt(
 				self.doc.grand_total / self.doc.conversion_rate,
 				self.precision.main.grand_total_import)
 
@@ -336,3 +336,25 @@
 				self._precision.tax = self.meta.get_precision_map(parentfield = \
 					"purchase_tax_details")
 		return self._precision
+
+	@property
+	def sub_contracted_items(self):
+		if not hasattr(self, "_sub_contracted_items"):
+			item_codes = list(set(item.item_code for item in 
+				self.doclist.get({"parentfield": self.fname})))
+			self._sub_contracted_items = [r[0] for r in webnotes.conn.sql("""select name
+				from `tabItem` where name in (%s) and is_sub_contracted_item='Yes'""" % \
+				(", ".join((["%s"]*len(item_codes))),), item_codes)]
+
+		return self._sub_contracted_items
+		
+	@property
+	def purchase_items(self):
+		if not hasattr(self, "_purchase_items"):
+			item_codes = list(set(item.item_code for item in 
+				self.doclist.get({"parentfield": self.fname})))
+			self._purchase_items = [r[0] for r in webnotes.conn.sql("""select name
+				from `tabItem` where name in (%s) and is_purchase_item='Yes'""" % \
+				(", ".join((["%s"]*len(item_codes))),), item_codes)]
+
+		return self._purchase_items
\ No newline at end of file
diff --git a/manufacturing/doctype/bom/test_bom.py b/manufacturing/doctype/bom/test_bom.py
index 68d9ce8..e742c0c 100644
--- a/manufacturing/doctype/bom/test_bom.py
+++ b/manufacturing/doctype/bom/test_bom.py
@@ -18,130 +18,164 @@
 from __future__ import unicode_literals
 import unittest
 import webnotes
-import webnotes.model
-from webnotes.utils import nowdate, flt
-from accounts.utils import get_fiscal_year
-from webnotes.model.doclist import DocList
-import copy
 
-company = webnotes.conn.get_default("company")
-
-
-def load_data():
-	
-	# create default warehouse
-	if not webnotes.conn.exists("Warehouse", "Default Warehouse"):
-		webnotes.insert({"doctype": "Warehouse", 
-			"warehouse_name": "Default Warehouse",
-			"warehouse_type": "Stores"})
-			
-	# create UOM: Nos.
-	if not webnotes.conn.exists("UOM", "Nos"):
-		webnotes.insert({"doctype": "UOM", "uom_name": "Nos"})
-	
-	from webnotes.tests import insert_test_data
-	# create item groups and items
-	insert_test_data("Item Group", 
-		sort_fn=lambda ig: (ig[0].get('parent_item_group'), ig[0].get('name')))
-	insert_test_data("Item")
-
-base_bom_fg = [
-	{"doctype": "BOM", "item": "Android Jack D", "quantity": 1,
-		"is_active": "Yes", "is_default": 1, "uom": "Nos"},
-	{"doctype": "BOM Operation", "operation_no": 1, "parentfield": "bom_operations",
-		"opn_description": "Development", "hour_rate": 10, "time_in_mins": 90}, 
-	{"doctype": "BOM Item", "item_code": "Home Desktop 300", "operation_no": 1, 
-		"qty": 2, "rate": 20, "stock_uom": "Nos", "parentfield": "bom_materials"},
-	{"doctype": "BOM Item", "item_code": "Home Desktop 100", "operation_no": 1, 
-		"qty": 1, "rate": 300, "stock_uom": "Nos", "parentfield": "bom_materials"},
-	{"doctype": "BOM Item", "item_code": "Nebula 7", "operation_no": 1, 
-			"qty": 5, "stock_uom": "Nos", "parentfield": "bom_materials"},
-]
-
-base_bom_child = [
-	{"doctype": "BOM", "item": "Nebula 7", "quantity": 5,
-		"is_active": "Yes", "is_default": 1, "uom": "Nos"},
-	{"doctype": "BOM Operation", "operation_no": 1, "parentfield": "bom_operations",
-		"opn_description": "Development"}, 
-	{"doctype": "BOM Item", "item_code": "Android Jack S", "operation_no": 1, 
-		"qty": 10, "stock_uom": "Nos", "parentfield": "bom_materials"}
-]
-	
-base_bom_grandchild = [
-	{"doctype": "BOM", "item": "Android Jack S", "quantity": 1,
-		"is_active": "Yes", "is_default": 1, "uom": "Nos"},
-	{"doctype": "BOM Operation", "operation_no": 1, "parentfield": "bom_operations",
-		"opn_description": "Development"}, 
-	{"doctype": "BOM Item", "item_code": "Home Desktop 300", "operation_no": 1, 
-		"qty": 3, "rate": 10, "stock_uom": "Nos", 	"parentfield": "bom_materials"}
-]
-
-
-class TestPurchaseReceipt(unittest.TestCase):
-	def setUp(self):
-		webnotes.conn.begin()
-		load_data()
-		
-	def test_bom_validation(self):
-		# show throw error bacause bom no missing for sub-assembly item
-		bom_fg = copy.deepcopy(base_bom_fg)
-		self.assertRaises(webnotes.ValidationError, webnotes.insert, DocList(bom_fg))
-
-		# main item is not a manufacturing item
-		bom_fg = copy.deepcopy(base_bom_fg)
-		bom_fg[0]["item"] = "Home Desktop 200"
-		bom_fg.pop(4)
-		self.assertRaises(webnotes.ValidationError, webnotes.insert, DocList(bom_fg))
-		
-		# operation no mentioed in material table not matching with operation table
-		bom_fg = copy.deepcopy(base_bom_fg)
-		bom_fg.pop(4)
-		bom_fg[2]["operation_no"] = 2
-		self.assertRaises(webnotes.ValidationError, webnotes.insert, DocList(bom_fg))
-		
-	
-	def test_bom(self):
-		gc_wrapper = webnotes.insert(DocList(base_bom_grandchild))
-		gc_wrapper.submit()
-		
-		bom_child = copy.deepcopy(base_bom_child)
-		bom_child[2]["bom_no"] = gc_wrapper.doc.name
-		child_wrapper = webnotes.insert(DocList(bom_child))
-		child_wrapper.submit()
-		
-		bom_fg = copy.deepcopy(base_bom_fg)
-		bom_fg[4]["bom_no"] = child_wrapper.doc.name
-		fg_wrapper = webnotes.insert(DocList(bom_fg))
-		fg_wrapper.load_from_db()
-		
-		self.check_bom_cost(fg_wrapper)
-		
-		self.check_flat_bom(fg_wrapper, child_wrapper, gc_wrapper)
-		
-	def check_bom_cost(self, fg_wrapper):
-		expected_values = {
-			"operating_cost": 15,
-			"raw_material_cost": 640,
-			"total_cost": 655
+test_records = [
+	[
+		{
+			"doctype": "BOM", 
+			"item": "_Test FG Item", 
+			"quantity": 1.0,
+			"is_active": 1,
+			"is_default": 1,
+			"docstatus": 1
+		}, 
+		{
+			"doctype": "BOM Item", 
+			"item_code": "_Test Item", 
+			"parentfield": "bom_materials", 
+			"qty": 1.0, 
+			"rate": 5000.0, 
+			"amount": 5000.0, 
+			"stock_uom": "No."
+		}, 
+		{
+			"doctype": "BOM Item", 
+			"item_code": "_Test Item Home Desktop 100", 
+			"parentfield": "bom_materials", 
+			"qty": 2.0, 
+			"rate": 1000.0,
+			"amount": 2000.0,
+			"stock_uom": "No."
 		}
+	]
+]
 
-		for key in expected_values:
-			self.assertEqual(flt(expected_values[key]), flt(fg_wrapper.doc.fields.get(key)))
-			
-	def check_flat_bom(self, fg_wrapper, child_wrapper, gc_wrapper):
-		expected_flat_bom_items = {
-			("Home Desktop 300", fg_wrapper.doc.name): (2, 20),
-			("Home Desktop 100", fg_wrapper.doc.name): (1, 300),
-			("Home Desktop 300", gc_wrapper.doc.name): (30, 10)
-		}
-		
-		self.assertEqual(len(fg_wrapper.doclist.get({"parentfield": "flat_bom_details"})), 3)
-		
-		for key, val in expected_flat_bom_items.items():
-			flat_bom = fg_wrapper.doclist.get({"parentfield": "flat_bom_details", 
-				"item_code": key[0], "parent_bom": key[1]})[0]
-			self.assertEqual(val, (flat_bom.qty, flat_bom.rate))
-		
-		
-	def tearDown(self):
-		webnotes.conn.rollback()
\ No newline at end of file
+
+
+# import webnotes.model
+# from webnotes.utils import nowdate, flt
+# from accounts.utils import get_fiscal_year
+# from webnotes.model.doclist import DocList
+# import copy
+# 
+# company = webnotes.conn.get_default("company")
+# 
+# 
+# def load_data():
+# 	
+# 	# create default warehouse
+# 	if not webnotes.conn.exists("Warehouse", "Default Warehouse"):
+# 		webnotes.insert({"doctype": "Warehouse", 
+# 			"warehouse_name": "Default Warehouse",
+# 			"warehouse_type": "Stores"})
+# 			
+# 	# create UOM: Nos.
+# 	if not webnotes.conn.exists("UOM", "Nos"):
+# 		webnotes.insert({"doctype": "UOM", "uom_name": "Nos"})
+# 	
+# 	from webnotes.tests import insert_test_data
+# 	# create item groups and items
+# 	insert_test_data("Item Group", 
+# 		sort_fn=lambda ig: (ig[0].get('parent_item_group'), ig[0].get('name')))
+# 	insert_test_data("Item")
+# 
+# base_bom_fg = [
+# 	{"doctype": "BOM", "item": "Android Jack D", "quantity": 1,
+# 		"is_active": "Yes", "is_default": 1, "uom": "Nos"},
+# 	{"doctype": "BOM Operation", "operation_no": 1, "parentfield": "bom_operations",
+# 		"opn_description": "Development", "hour_rate": 10, "time_in_mins": 90}, 
+# 	{"doctype": "BOM Item", "item_code": "Home Desktop 300", "operation_no": 1, 
+# 		"qty": 2, "rate": 20, "stock_uom": "Nos", "parentfield": "bom_materials"},
+# 	{"doctype": "BOM Item", "item_code": "Home Desktop 100", "operation_no": 1, 
+# 		"qty": 1, "rate": 300, "stock_uom": "Nos", "parentfield": "bom_materials"},
+# 	{"doctype": "BOM Item", "item_code": "Nebula 7", "operation_no": 1, 
+# 			"qty": 5, "stock_uom": "Nos", "parentfield": "bom_materials"},
+# ]
+# 
+# base_bom_child = [
+# 	{"doctype": "BOM", "item": "Nebula 7", "quantity": 5,
+# 		"is_active": "Yes", "is_default": 1, "uom": "Nos"},
+# 	{"doctype": "BOM Operation", "operation_no": 1, "parentfield": "bom_operations",
+# 		"opn_description": "Development"}, 
+# 	{"doctype": "BOM Item", "item_code": "Android Jack S", "operation_no": 1, 
+# 		"qty": 10, "stock_uom": "Nos", "parentfield": "bom_materials"}
+# ]
+# 	
+# base_bom_grandchild = [
+# 	{"doctype": "BOM", "item": "Android Jack S", "quantity": 1,
+# 		"is_active": "Yes", "is_default": 1, "uom": "Nos"},
+# 	{"doctype": "BOM Operation", "operation_no": 1, "parentfield": "bom_operations",
+# 		"opn_description": "Development"}, 
+# 	{"doctype": "BOM Item", "item_code": "Home Desktop 300", "operation_no": 1, 
+# 		"qty": 3, "rate": 10, "stock_uom": "Nos", 	"parentfield": "bom_materials"}
+# ]
+# 
+# 
+# class TestPurchaseReceipt(unittest.TestCase):
+# 	def setUp(self):
+# 		webnotes.conn.begin()
+# 		load_data()
+# 		
+# 	def test_bom_validation(self):
+# 		# show throw error bacause bom no missing for sub-assembly item
+# 		bom_fg = copy.deepcopy(base_bom_fg)
+# 		self.assertRaises(webnotes.ValidationError, webnotes.insert, DocList(bom_fg))
+# 
+# 		# main item is not a manufacturing item
+# 		bom_fg = copy.deepcopy(base_bom_fg)
+# 		bom_fg[0]["item"] = "Home Desktop 200"
+# 		bom_fg.pop(4)
+# 		self.assertRaises(webnotes.ValidationError, webnotes.insert, DocList(bom_fg))
+# 		
+# 		# operation no mentioed in material table not matching with operation table
+# 		bom_fg = copy.deepcopy(base_bom_fg)
+# 		bom_fg.pop(4)
+# 		bom_fg[2]["operation_no"] = 2
+# 		self.assertRaises(webnotes.ValidationError, webnotes.insert, DocList(bom_fg))
+# 		
+# 	
+# 	def test_bom(self):
+# 		gc_wrapper = webnotes.insert(DocList(base_bom_grandchild))
+# 		gc_wrapper.submit()
+# 		
+# 		bom_child = copy.deepcopy(base_bom_child)
+# 		bom_child[2]["bom_no"] = gc_wrapper.doc.name
+# 		child_wrapper = webnotes.insert(DocList(bom_child))
+# 		child_wrapper.submit()
+# 		
+# 		bom_fg = copy.deepcopy(base_bom_fg)
+# 		bom_fg[4]["bom_no"] = child_wrapper.doc.name
+# 		fg_wrapper = webnotes.insert(DocList(bom_fg))
+# 		fg_wrapper.load_from_db()
+# 		
+# 		self.check_bom_cost(fg_wrapper)
+# 		
+# 		self.check_flat_bom(fg_wrapper, child_wrapper, gc_wrapper)
+# 		
+# 	def check_bom_cost(self, fg_wrapper):
+# 		expected_values = {
+# 			"operating_cost": 15,
+# 			"raw_material_cost": 640,
+# 			"total_cost": 655
+# 		}
+# 
+# 		for key in expected_values:
+# 			self.assertEqual(flt(expected_values[key]), flt(fg_wrapper.doc.fields.get(key)))
+# 			
+# 	def check_flat_bom(self, fg_wrapper, child_wrapper, gc_wrapper):
+# 		expected_flat_bom_items = {
+# 			("Home Desktop 300", fg_wrapper.doc.name): (2, 20),
+# 			("Home Desktop 100", fg_wrapper.doc.name): (1, 300),
+# 			("Home Desktop 300", gc_wrapper.doc.name): (30, 10)
+# 		}
+# 		
+# 		self.assertEqual(len(fg_wrapper.doclist.get({"parentfield": "flat_bom_details"})), 3)
+# 		
+# 		for key, val in expected_flat_bom_items.items():
+# 			flat_bom = fg_wrapper.doclist.get({"parentfield": "flat_bom_details", 
+# 				"item_code": key[0], "parent_bom": key[1]})[0]
+# 			self.assertEqual(val, (flat_bom.qty, flat_bom.rate))
+# 		
+# 		
+# 	def tearDown(self):
+# 		webnotes.conn.rollback()
\ No newline at end of file
diff --git a/stock/doctype/item/test_item.py b/stock/doctype/item/test_item.py
index 853283e..035774b 100644
--- a/stock/doctype/item/test_item.py
+++ b/stock/doctype/item/test_item.py
@@ -17,64 +17,8 @@
 from __future__ import unicode_literals
 import unittest
 import webnotes
-import copy
 
-from webnotes.model.bean import Bean
-from webnotes.model.doc import Document
-from webnotes.utils import flt
-
-sql = webnotes.conn.sql
-
-
-class TestItem(unittest.TestCase):
-	def setUp(self):
-		webnotes.conn.begin()
-
-	def tearDown(self):
-		webnotes.conn.rollback()
-		
-	def testInsert(self):
-		d = Bean()
-
-		count_before =  flt(sql("select count(*) from tab"+_doctype)[0][0])
-		if docok:
-			for i in docok:
-				d.doc = i
-				d.children = None
-				d.doc.fields['__islocal']=1
-				d.save(1)
-		count_after = flt(sql("select count(*) from tab"+_doctype)[0][0])
-		self.assertTrue(count_before+len(docok)==count_after)
-	
-	def testFailAssert(self):
-		if docnotok:
-			with self.assertRaises(Exception) as context:
-				d = Bean()
-				d.doc = docnotok[0]
-				d.children = None
-				d.doc.fields['__islocal']=1
-				d.save(1)
-
-# Test Data
-
-tabOK = [
-		{'is_purchase_item': None, 'is_pro_applicable': 'No', 'is_manufactured_item': None, 'description': 'Gel Ink', 'default_warehouse': None, 'item_name': 'Gel Ink', 'item_group': 'Ink', 'item_code': 'GELINK', 'is_sub_contracted_item': None, 'is_stock_item': 'Yes', 'stock_uom': 'Nos', 'docstatus': '0'}, 
-		{'is_purchase_item': None, 'is_pro_applicable': 'No', 'is_manufactured_item': None, 'description': 'Gel Refill', 'default_warehouse': None, 'item_name': 'Gel Refill', 'item_group': 'Refill', 'item_code': 'GELREF', 'is_sub_contracted_item': None, 'is_stock_item': 'Yes', 'stock_uom': 'Nos', 'docstatus': '0'}, 
-		{'is_purchase_item': None, 'is_pro_applicable': 'No', 'is_manufactured_item': None, 'description': 'Gel Pen', 'default_warehouse': None, 'item_name': 'Gel Pen', 'item_group': 'Pen', 'item_code': 'GELPEN', 'is_sub_contracted_item': None, 'is_stock_item': 'Yes', 'stock_uom': 'Nos', 'docstatus': '0'}
-	]
-
-tabNotOK =	[
-			{'is_purchase_item': None, 'is_pro_applicable': None, 'is_manufactured_item': None, 'description': 'F Ink', 'default_warehouse': None, 'item_name': 'F Ink', 'item_group': 'F Ink', 'item_code': None, 'is_sub_contracted_item': None, 'is_stock_item': 'No', 'stock_uom': 'Nos', 'docstatus': '0'}
-		]
-	      
-_doctype = 'Item'
-
-for i in tabOK: i['doctype']=_doctype
-for i in tabNotOK: i['doctype']=_doctype
-
-docok = [Document(fielddata=r) for r in tabOK]
-docnotok = [Document(fielddata=r) for r in tabNotOK]
-
+test_ignore = ["BOM"]
 
 test_records = [
 	[{
@@ -164,4 +108,23 @@
 		"is_sub_contracted_item": "No",
 		"stock_uom": "_Test UOM"
 	}],
+	[{
+		"doctype": "Item",
+		"item_code": "_Test FG Item",
+		"item_name": "_Test FG Item",
+		"description": "_Test FG Item",
+		"item_group": "_Test Item Group Desktops",
+		"is_stock_item": "Yes",
+		"is_asset_item": "No",
+		"has_batch_no": "No",
+		"has_serial_no": "No",
+		"is_purchase_item": "Yes",
+		"is_sales_item": "Yes",
+		"is_service_item": "No",
+		"is_sample_item": "No",
+		"inspection_required": "No",
+		"is_pro_applicable": "Yes",
+		"is_sub_contracted_item": "Yes",
+		"stock_uom": "_Test UOM"
+	}],
 ]
\ No newline at end of file
diff --git a/stock/doctype/purchase_receipt/purchase_receipt.py b/stock/doctype/purchase_receipt/purchase_receipt.py
index a957468..ef4fc30 100644
--- a/stock/doctype/purchase_receipt/purchase_receipt.py
+++ b/stock/doctype/purchase_receipt/purchase_receipt.py
@@ -18,10 +18,10 @@
 import webnotes
 
 from webnotes.utils import cstr, flt, cint
-from webnotes.model.doc import addchild
 from webnotes.model.bean import getlist
 from webnotes.model.code import get_obj
-from webnotes import msgprint
+from webnotes.model.doc import Document
+from webnotes import msgprint, _
 
 sql = webnotes.conn.sql
 
@@ -89,8 +89,6 @@
 				webnotes.msgprint("Another Purchase Receipt using the same Challan No. already exists.\
 			Please enter a valid Challan No.", raise_exception=1)
 
-
-	# update valuation rate
 	def update_valuation_rate(self):
 		for d in self.doclist.get({"parentfield": "purchase_receipt_details"}):
 			if d.qty:
@@ -99,8 +97,6 @@
 			else:
 				d.valuation_rate = 0.0
 
-	#check in manage account if purchase order required or not.
-	# ====================================================================================
 	def po_required(self):
 		res = sql("select value from `tabSingles` where doctype = 'Global Defaults' and field = 'po_required'")
 		if res and res[0][0]== 'Yes':
@@ -109,8 +105,6 @@
 					 msgprint("Purchse Order No. required against item %s"%d.item_code)
 					 raise Exception
 
-
-	# validate
 	def validate(self):
 		super(DocType, self).validate()
 		
@@ -136,16 +130,15 @@
 
 		# update valuation rate
 		self.update_valuation_rate()
+		# sub-contracting
+		self.validate_for_subcontracting()
+		self.update_raw_materials_supplied()
 
-
-	# On Update
-	# ----------------------------------------------------------------------------------------------------
 	def on_update(self):
 		if self.doc.rejected_warehouse:
 			for d in getlist(self.doclist,'purchase_receipt_details'):
 				d.rejected_warehouse = self.doc.rejected_warehouse
 
-		self.update_rw_material_detail()
 		get_obj('Stock Ledger').scrub_serial_nos(self)
 		self.scrub_rejected_serial_nos()
 
@@ -303,118 +296,66 @@
 		
 		self.make_gl_entries()
 
+	def validate_for_subcontracting(self):
+		if self.sub_contracted_items and self.purchase_items and not self.doc.is_subcontracted:
+			webnotes.msgprint(_("""Please enter whether Purchase Recipt is made for subcontracting 
+				or purchasing, in 'Is Subcontracted' field"""), raise_exception=1)
+			
+		if self.doc.is_subcontracted and not self.doc.supplier_warehouse:
+			webnotes.msgprint(_("Please Enter Supplier Warehouse for subcontracted Items"), 
+				raise_exception=1)
+				
+	def update_raw_materials_supplied(self):
+		self.doclist = self.doc.clear_table(self.doclist, 'pr_raw_material_details')
+		if self.sub_contracted_items:
+			for item in self.doclist.get({"parentfield": "purchase_receipt_details"}):
+				if item.item_code in self.sub_contracted_items:
+					self.add_bom_items(item)
 
-	def update_rw_material_detail(self):
+	def add_bom_items(self, d):
+		bom_items = self.get_items_from_default_bom(d.item_code)
+		raw_materials_cost = 0
+		for item in bom_items:
+			required_qty = flt(item.qty_consumed_per_unit) * flt(d.qty) * flt(d.conversion_factor)
+			self.doclist.append({
+				"parentfield": "pr_raw_material_details",
+				"doctype": "Purchase Receipt Item Supplied",
+				"reference_name": d.name,
+				"bom_detail_no": item.name,
+				"main_item_code": d.item_code,
+				"rm_item_code": item.item_code,
+				"description": item.description,
+				"stock_uom": item.stock_uom,
+				"required_qty": required_qty,
+				"consumed_qty": required_qty,
+				"conversion_factor": d.conversion_factor,
+				"rate": item.rate,
+				"amount": required_qty * flt(item.rate)
+			})
+			
+			raw_materials_cost += required_qty * flt(item.rate)
+			
+		d.rm_supp_cost = raw_materials_cost
 
-		for d in getlist(self.doclist,'purchase_receipt_details'):
-			item_det = sql("select is_sub_contracted_item, is_purchase_item from `tabItem` where name = '%s'"%(d.item_code))
-
-			if item_det[0][0] == 'Yes':
-				if item_det[0][1] == 'Yes':
-					if not self.doc.is_subcontracted:
-						msgprint("Please enter whether purchase receipt to be made for subcontracting or for purchase in 'Is Subcontracted' field .")
-						raise Exception
-					if self.doc.is_subcontracted == 'Yes':
-						if not self.doc.supplier_warehouse:
-							msgprint("Please Enter Supplier Warehouse for subcontracted Items")
-							raise Exception
-						self.add_bom(d)
-					else:
-						self.doclist = self.doc.clear_table(self.doclist,'pr_raw_material_details',1)
-						self.doc.save()
-				elif item_det[0][1] == 'No':
-					if not self.doc.supplier_warehouse:
-						msgprint("Please Enter Supplier Warehouse for subcontracted Items")
-						raise Exception
-					self.add_bom(d)
-
-			self.delete_irrelevant_raw_material()
-			#---------------calculate amt in	Purchase Receipt Item Supplied-------------
-			self.calculate_amount(d)
-
-
-	def add_bom(self, d):
-		#----- fetching default bom from Bill of Materials instead of Item Master --
-		bom_det = sql("""select t1.item, t2.item_code, t2.qty_consumed_per_unit, 
-			t2.moving_avg_rate, t2.value_as_per_mar, t2.stock_uom, t2.name, t2.description 
+	def get_items_from_default_bom(self, item_code):
+		# print webnotes.conn.sql("""select name from `tabBOM` where item = '_Test FG Item'""")
+		bom_items = sql("""select t2.item_code, t2.qty_consumed_per_unit, 
+			t2.rate, t2.stock_uom, t2.name, t2.description 
 			from `tabBOM` t1, `tabBOM Item` t2 
 			where t2.parent = t1.name and t1.item = %s and t1.is_default = 1 
-			and t1.docstatus = 1 and t2.docstatus =1 and t1.is_active = 1""", d.item_code)
-		if not bom_det:
-			msgprint("No default BOM exists for item: %s" % d.item_code)
-			raise Exception
-		else:
-			#-------------- add child function--------------------
-			chgd_rqd_qty = []
-			for i in bom_det:
+			and t1.docstatus = 1 and t1.is_active = 1""", item_code, as_dict=1)
+		if not bom_items:
+			msgprint(_("No default BOM exists for item: ") + item_code, raise_exception=1)
+		
+		return bom_items
 
-				if i and not sql("select name from `tabPurchase Receipt Item Supplied` where reference_name = '%s' and bom_detail_no = '%s' and parent = '%s' " %(d.name, i[6], self.doc.name)):
-
-					rm_child = addchild(self.doc, 'pr_raw_material_details', 'Purchase Receipt Item Supplied', self.doclist)
-
-					rm_child.reference_name = d.name
-					rm_child.bom_detail_no = i and i[6] or ''
-					rm_child.main_item_code = i and i[0] or ''
-					rm_child.rm_item_code = i and i[1] or ''
-					rm_child.description = i and i[7] or ''
-					rm_child.stock_uom = i and i[5] or ''
-					rm_child.rate = i and flt(i[3]) or flt(i[4])
-					rm_child.conversion_factor = d.conversion_factor
-					rm_child.required_qty = flt(i	and flt(i[2]) or 0) * flt(d.qty) * flt(d.conversion_factor)
-					rm_child.consumed_qty = flt(i	and flt(i[2]) or 0) * flt(d.qty) * flt(d.conversion_factor)
-					rm_child.amount = flt(flt(rm_child.consumed_qty)*flt(rm_child.rate))
-					rm_child.save()
-					chgd_rqd_qty.append(cstr(i[1]))
-				else:
-					act_qty = flt(i	and flt(i[2]) or 0) * flt(d.qty) * flt(d.conversion_factor)
-					for pr_rmd in getlist(self.doclist, 'pr_raw_material_details'):
-						if i and i[6] == pr_rmd.bom_detail_no and (flt(act_qty) != flt(pr_rmd.required_qty) or i[1] != pr_rmd.rm_item_code or i[7] != pr_rmd.description):
-							chgd_rqd_qty.append(cstr(i[1]))
-							pr_rmd.main_item_code = i[0]
-							pr_rmd.rm_item_code = i[1]
-							pr_rmd.description = i[7]
-							pr_rmd.stock_uom = i[5]
-							pr_rmd.required_qty = flt(act_qty)
-							pr_rmd.consumed_qty = flt(act_qty)
-							pr_rmd.rate = i and flt(i[3]) or flt(i[4])
-							pr_rmd.amount = flt(flt(pr_rmd.consumed_qty)*flt(pr_rmd.rate))
-							pr_rmd.save()
-			if chgd_rqd_qty:
-				msgprint("Please check consumed quantity for Raw Material Item Code: '%s'in Raw materials Detail Table" % ((len(chgd_rqd_qty) > 1 and ','.join(chgd_rqd_qty[:-1]) +' and ' + cstr(chgd_rqd_qty[-1:][0]) ) or cstr(chgd_rqd_qty[0])))
-
-
-	# Delete irrelevant raw material from PR Raw material details
-	#--------------------------------------------------------------
-	def delete_irrelevant_raw_material(self):
-		for d in getlist(self.doclist,'pr_raw_material_details'):
-			if not sql("select name from `tabPurchase Receipt Item` where name = '%s' and parent = '%s' and item_code = '%s'" % (d.reference_name, self.doc.name, d.main_item_code)):
-				d.parent = 'old_par:'+self.doc.name
-				d.save()
-
-	def calculate_amount(self, d):
-		amt = 0
-		for i in getlist(self.doclist,'pr_raw_material_details'):
-
-			if(i.reference_name == d.name):
-				#if i.consumed_qty == 0:
-				 # msgprint("consumed qty cannot be 0. Please Enter consumed qty ")
-					#raise Exception
-				i.amount = flt(i.consumed_qty)* flt(i.rate)
-				amt += i.amount
-		d.rm_supp_cost = amt
-		d.save()
-
-
-	# --------------- Back Flush function called on submit and on cancel from update stock
 	def bk_flush_supp_wh(self, is_submit):
 		for d in getlist(self.doclist, 'pr_raw_material_details'):
-			#--------- -ve quantity is passed as raw material qty has to be decreased when PR is submitted and it has to be increased when PR is cancelled
+			# negative quantity is passed as raw material qty has to be decreased 
+			# when PR is submitted and it has to be increased when PR is cancelled
 			consumed_qty = - flt(d.consumed_qty)
 			self.make_sl_entry(d, self.doc.supplier_warehouse, flt(consumed_qty), 0, is_submit)
 
-
-	# get current_stock
-	# ----------------
 	def get_current_stock(self):
 		for d in getlist(self.doclist, 'pr_raw_material_details'):
 			if self.doc.supplier_warehouse:
diff --git a/stock/doctype/purchase_receipt/test_purchase_receipt.py b/stock/doctype/purchase_receipt/test_purchase_receipt.py
index d833d65..6c317c4 100644
--- a/stock/doctype/purchase_receipt/test_purchase_receipt.py
+++ b/stock/doctype/purchase_receipt/test_purchase_receipt.py
@@ -64,6 +64,17 @@
 			self.assertEquals(expected_values[i][2], gle.credit)
 			
 		webnotes.defaults.set_global_default("auto_inventory_accounting", 0)
+		
+	def test_subcontracting(self):
+		pr = webnotes.bean(copy=test_records[1])
+		pr.run_method("calculate_taxes_and_totals")
+		pr.insert()
+		
+		self.assertEquals(pr.doclist[1].rm_supp_cost, 70000.0)
+		self.assertEquals(len(pr.doclist.get({"parentfield": "pr_raw_material_details"})), 2)
+
+
+test_dependencies = ["BOM"]
 
 test_records = [
 	[
@@ -129,4 +140,36 @@
 			"tax_amount": 150.0,
 		},
 	],
+	[
+		{
+			"company": "_Test Company", 
+			"conversion_rate": 1.0, 
+			"currency": "INR", 
+			"doctype": "Purchase Receipt", 
+			"fiscal_year": "_Test Fiscal Year 2013", 
+			"posting_date": "2013-02-12", 
+			"posting_time": "15:33:30", 
+			"is_subcontracted": "Yes",
+			"supplier_warehouse": "_Test Warehouse", 
+			"supplier": "_Test Supplier",
+			"net_total": 5000.0, 
+			"grand_total": 5000.0,
+		}, 
+		{
+			"conversion_factor": 1.0, 
+			"description": "_Test FG Item", 
+			"doctype": "Purchase Receipt Item", 
+			"item_code": "_Test FG Item", 
+			"item_name": "_Test FG Item", 
+			"parentfield": "purchase_receipt_details", 
+			"received_qty": 10.0,
+			"qty": 10.0,
+			"rejected_qty": 0.0,
+			"import_rate": 500.0,
+			"amount": 5000.0,
+			"warehouse": "_Test Warehouse", 
+			"stock_uom": "Nos", 
+			"uom": "_Test UOM",
+		}
+	],
 ]
\ No newline at end of file