default warehouse / remove validation / change sql
diff --git a/erpnext/buying/doctype/purchase_order/purchase_order.py b/erpnext/buying/doctype/purchase_order/purchase_order.py
index 942a2e6..bb78579 100644
--- a/erpnext/buying/doctype/purchase_order/purchase_order.py
+++ b/erpnext/buying/doctype/purchase_order/purchase_order.py
@@ -257,8 +257,9 @@
 	def update_reserved_qty_for_subcontract(self):
 		for d in self.supplied_items:
 			if d.rm_item_code:
-					stock_bin = get_bin(d.rm_item_code, d.reserve_warehouse)
-					stock_bin.update_reserved_qty_for_sub_contracting()
+				warehouse = d.reserve_warehouse or bom_item_wh.get(d.rm_item_code) or item_wh.get(d.rm_item_code)
+				stock_bin = get_bin(d.rm_item_code, warehouse)
+				stock_bin.update_reserved_qty_for_sub_contracting()
 
 @frappe.whitelist()
 def close_or_unclose_purchase_orders(names, status):
diff --git a/erpnext/controllers/buying_controller.py b/erpnext/controllers/buying_controller.py
index 6697e32..6956023 100644
--- a/erpnext/controllers/buying_controller.py
+++ b/erpnext/controllers/buying_controller.py
@@ -193,6 +193,9 @@
 	def update_raw_materials_supplied(self, item, raw_material_table):
 		bom_items = self.get_items_from_bom(item.item_code, item.bom)
 		raw_materials_cost = 0
+		items = list(set([d.item_code for d in bom_items]))
+		item_wh = frappe._dict(frappe.db.sql("""select item_code, default_warehouse
+						from `tabItem` where name in ({0})""".format(", ".join(["%s"] * len(items))), items))
 
 		for bom_item in bom_items:
 			# check if exists
@@ -213,6 +216,7 @@
 			rm.rm_item_code = bom_item.item_code
 			rm.stock_uom = bom_item.stock_uom
 			rm.required_qty = required_qty
+			rm.reserve_warehouse = bom_item.source_warehouse or item_wh.get(bom_item.item_code)
 
 			rm.conversion_factor = item.conversion_factor
 
diff --git a/erpnext/stock/doctype/bin/bin.py b/erpnext/stock/doctype/bin/bin.py
index efda055..0599db6 100644
--- a/erpnext/stock/doctype/bin/bin.py
+++ b/erpnext/stock/doctype/bin/bin.py
@@ -104,38 +104,20 @@
 				and po.docstatus = 1
 				and po.is_subcontracted = 'Yes'
 				and itemsup.reserve_warehouse = %s''', (self.item_code, self.warehouse))[0][0]
-		#cancelled qty
-		reserved_qty_cancelled = frappe.db.sql('''select ifnull(sum(itemsup.required_qty),0)
-			from `tabPurchase Order` po, `tabPurchase Order Item Supplied` itemsup
-			where
-				itemsup.rm_item_code = %s
-				and itemsup.parent = po.name
-				and po.docstatus = 2
-				and po.is_subcontracted = 'Yes'
-				and itemsup.reserve_warehouse = %s''', (self.item_code, self.warehouse))[0][0]
 		#Get Transferred Entries
 		materials_transferred = frappe.db.sql("""
 			select
 				ifnull(sum(qty),0)
 			from
-				`tabStock Entry` se, `tabStock Entry Detail` sed
+				`tabStock Entry` se, `tabStock Entry Detail` sed, `tabPurchase Order` po
 			where
-				sed.item_code = %s and sed.s_warehouse = %s
+				sed.item_code = %s
 				and se.name = sed.parent and se.docstatus=1 and se.purpose='Subcontract'
-				and ifnull(se.purchase_order, '') !=''""", (self.item_code, self.warehouse))[0][0]
-		#Material Transfer Cancelled
-		materials_transfer_cancelled = frappe.db.sql("""
-			select
-				ifnull(sum(qty),0)
-			from
-				`tabStock Entry` se, `tabStock Entry Detail` sed
-			where
-				sed.item_code = %s and sed.s_warehouse = %s
-				and se.name = sed.parent and se.docstatus=2 and se.purpose='Subcontract'
-				and ifnull(se.purchase_order, '') !=''""", (self.item_code, self.warehouse))[0][0]
+				and se.purchase_order = po.name
+				and ifnull(se.purchase_order, '') !=''""", (self.item_code))[0][0]
 
 		self.set_projected_qty()
-		self.db_set('reserved_qty_for_sub_contract', (reserved_qty_for_sub_contract - reserved_qty_cancelled - materials_transferred + materials_transfer_cancelled))
+		self.db_set('reserved_qty_for_sub_contract', (reserved_qty_for_sub_contract - materials_transferred))
 		self.db_set('projected_qty', self.projected_qty)
 
 def update_item_projected_qty(item_code):
diff --git a/erpnext/stock/doctype/stock_entry/stock_entry.py b/erpnext/stock/doctype/stock_entry/stock_entry.py
index 3ed1570..6528c28 100644
--- a/erpnext/stock/doctype/stock_entry/stock_entry.py
+++ b/erpnext/stock/doctype/stock_entry/stock_entry.py
@@ -822,14 +822,10 @@
 						from `tabPurchase Order` po, `tabPurchase Order Item Supplied` poitemsup
 						where po.name = poitemsup.parent
 						and po.name = %s""",self.purchase_order))
-		#Validate source warehouse is same as reserved warehouse
-		for item in self.get("items"):
-			reserve_warehouse = item_wh.get(item.item_code)
-			if item.s_warehouse != reserve_warehouse:
-				frappe.throw(_("In case of Sub Contract Stock Entry, Source Warehouse: {0} should match with Reserved Warehouse: {1} entered on Purchase Order {2}").format(frappe.bold(item.s_warehouse),frappe.bold(reserve_warehouse),frappe.bold(self.purchase_order)))
 		#Update reserved sub contracted quantity in bin based on Supplied Item Details
 		for d in self.get("items"):
-			stock_bin = get_bin(d.item_code, d.s_warehouse)
+			reserve_warehouse = item_wh.get(item.item_code)
+			stock_bin = get_bin(d.item_code, reserve_warehouse)
 			stock_bin.update_reserved_qty_for_sub_contracting()
 
 @frappe.whitelist()