Fixes and cleanups of reserve qty for subcontracting
diff --git a/erpnext/accounts/doctype/account/account.py b/erpnext/accounts/doctype/account/account.py
index b0a59d0..b3d1d55 100644
--- a/erpnext/accounts/doctype/account/account.py
+++ b/erpnext/accounts/doctype/account/account.py
@@ -169,10 +169,10 @@
 		# Add company abbr if not provided
 		from erpnext.setup.doctype.company.company import get_name_with_abbr
 		new_account = get_name_with_abbr(new, self.company)
-		new_account = get_name_with_number(new_account, self.account_number)
-
-		# Validate properties before merging
-		if merge:
+		if not merge:
+			new_account = get_name_with_number(new_account, self.account_number)
+		else:
+			# Validate properties before merging
 			if not frappe.db.exists("Account", new):
 				throw(_("Account {0} does not exist").format(new))
 
diff --git a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py
index 07853d0..3f9bca7 100644
--- a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py
+++ b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py
@@ -350,7 +350,6 @@
 		self.negative_expense_to_be_booked = 0.0
 		gl_entries = []
 
-
 		self.make_supplier_gl_entry(gl_entries)
 		self.make_item_gl_entries(gl_entries)
 		self.make_tax_gl_entries(gl_entries)
@@ -424,7 +423,10 @@
 
 					# sub-contracting warehouse
 					if flt(item.rm_supp_cost):
-						supplier_warehouse_account = warehouse_account[self.supplier_warehouse]["name"]
+						supplier_warehouse_account = warehouse_account[self.supplier_warehouse]["account"]
+						if not supplier_warehouse_account:
+							frappe.throw(_("Please set account in Warehouse {0}")
+								.format(self.supplier_warehouse))
 						gl_entries.append(self.get_gl_dict({
 							"account": supplier_warehouse_account,
 							"against": item.expense_account,
diff --git a/erpnext/buying/doctype/purchase_order/purchase_order.js b/erpnext/buying/doctype/purchase_order/purchase_order.js
index 0394f74..ef59cd8 100644
--- a/erpnext/buying/doctype/purchase_order/purchase_order.js
+++ b/erpnext/buying/doctype/purchase_order/purchase_order.js
@@ -12,6 +12,15 @@
 			'Purchase Invoice': 'Invoice',
 			'Stock Entry': 'Material to Supplier'
 		}
+		
+		frm.set_query("reserve_warehouse", "supplied_items", function() {
+			return {
+				filters: {
+					"company": frm.doc.company,
+					"is_group": 0
+				}
+			}
+		});
 	},
 
 	onload: function(frm) {
@@ -289,7 +298,8 @@
 		filters: [
 			['BOM', 'item', '=', d.item_code],
 			['BOM', 'is_active', '=', '1'],
-			['BOM', 'docstatus', '=', '1']
+			['BOM', 'docstatus', '=', '1'],
+			['BOM', 'company', '=', doc.company]
 		]
 	}
 }
diff --git a/erpnext/buying/doctype/purchase_order/purchase_order.json b/erpnext/buying/doctype/purchase_order/purchase_order.json
index 2191a55..2325a8c 100644
--- a/erpnext/buying/doctype/purchase_order/purchase_order.json
+++ b/erpnext/buying/doctype/purchase_order/purchase_order.json
@@ -3071,6 +3071,38 @@
    "bold": 0, 
    "collapsible": 0, 
    "columns": 0, 
+   "depends_on": "eval:doc.is_subcontracted", 
+   "fieldname": "supplied_items_section", 
+   "fieldtype": "Section Break", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_global_search": 0, 
+   "in_list_view": 0, 
+   "in_standard_filter": 0, 
+   "label": "Supplied Items", 
+   "length": 0, 
+   "no_copy": 0, 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 0, 
+   "remember_last_selected_value": 0, 
+   "report_hide": 0, 
+   "reqd": 0, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "unique": 0
+  }, 
+  {
+   "allow_bulk_edit": 0, 
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "columns": 0, 
+   "depends_on": "", 
    "fieldname": "supplied_items", 
    "fieldtype": "Table", 
    "hidden": 0, 
@@ -3261,8 +3293,8 @@
  "issingle": 0, 
  "istable": 0, 
  "max_attachments": 0, 
- "modified": "2017-12-19 14:53:03.986840", 
- "modified_by": "nabinhait@gmail.com", 
+ "modified": "2018-01-05 14:44:56.132189", 
+ "modified_by": "Administrator", 
  "module": "Buying", 
  "name": "Purchase Order", 
  "owner": "Administrator", 
diff --git a/erpnext/buying/doctype/purchase_order/purchase_order.py b/erpnext/buying/doctype/purchase_order/purchase_order.py
index de77b24..c6e21ad 100644
--- a/erpnext/buying/doctype/purchase_order/purchase_order.py
+++ b/erpnext/buying/doctype/purchase_order/purchase_order.py
@@ -71,8 +71,10 @@
 	def validate_supplier(self):
 		prevent_po = frappe.db.get_value("Supplier", self.supplier, 'prevent_pos')
 		if prevent_po:
-			standing = frappe.db.get_value("Supplier Scorecard",self.supplier, 'status')
-			frappe.throw(_("Purchase Orders are not allowed for {0} due to a scorecard standing of {1}.").format(self.supplier, standing))
+			standing = frappe.db.get_value("Supplier Scorecard", self.supplier, 'status')
+			if standing:
+				frappe.throw(_("Purchase Orders are not allowed for {0} due to a scorecard standing of {1}.")
+					.format(self.supplier, standing))
 
 		warn_po = frappe.db.get_value("Supplier", self.supplier, 'warn_pos')
 		if warn_po:
@@ -184,6 +186,9 @@
 		self.set_status(update=True, status=status)
 		self.update_requested_qty()
 		self.update_ordered_qty()
+		if self.is_subcontracted == "Yes":
+			self.update_reserved_qty_for_subcontract()
+
 		self.notify_update()
 		clear_doctype_notifications(self)
 
diff --git a/erpnext/buying/doctype/purchase_order/test_purchase_order.py b/erpnext/buying/doctype/purchase_order/test_purchase_order.py
index cb7d226..5ae4d3b 100644
--- a/erpnext/buying/doctype/purchase_order/test_purchase_order.py
+++ b/erpnext/buying/doctype/purchase_order/test_purchase_order.py
@@ -6,8 +6,8 @@
 import frappe
 import frappe.defaults
 from frappe.utils import flt, add_days, nowdate
-from erpnext.buying.doctype.purchase_order.purchase_order import make_purchase_receipt, make_purchase_invoice
-
+from erpnext.buying.doctype.purchase_order.purchase_order import (make_purchase_receipt, make_purchase_invoice, make_stock_entry as make_subcontract_transfer_entry)
+from erpnext.stock.doctype.stock_entry.test_stock_entry import make_stock_entry
 
 class TestPurchaseOrder(unittest.TestCase):
 	def test_make_purchase_receipt(self):
@@ -183,37 +183,128 @@
 		self.assertTrue(pi.get('payment_schedule'))
 
 	def test_reserved_qty_subcontract_po(self):
-		bin = frappe.get_all("Bin", filters={"warehouse": "_Test Warehouse - _TC"},
-			fields=["item_code","reserved_qty_for_sub_contract"])
+		# Make stock available for raw materials
+		make_stock_entry(target="_Test Warehouse - _TC", qty=10, basic_rate=100)
+		make_stock_entry(target="_Test Warehouse - _TC", item_code="_Test Item Home Desktop 100",
+			qty=20, basic_rate=100)
 
-		item_supplied = frappe.get_all("Purchase Order Item Supplied", filters={"main_item_code": "_Test FG Item", "reserve_warehouse": "_Test Warehouse - _TC"},
-			fields=["rm_item_code","required_qty"])
+		bin1 = frappe.db.get_value("Bin",
+			filters={"warehouse": "_Test Warehouse - _TC", "item_code": "_Test Item"},
+			fieldname=["reserved_qty_for_sub_contract", "projected_qty"], as_dict=1)
 
-		for item_bin in bin:
-			total_sup_qty = 0
-			for item_sup in item_supplied:
-				if item_bin["item_code"] == item_sup["rm_item_code"]:
-					total_sup_qty = total_sup_qty + item_sup["required_qty"]
+		# Submit PO
+		po = create_purchase_order(item_code="_Test FG Item", is_subcontracted="Yes")
 
-		self.assertEquals(item_bin["reserved_qty_for_sub_contract"],total_sup_qty)
+		bin2 = frappe.db.get_value("Bin",
+			filters={"warehouse": "_Test Warehouse - _TC", "item_code": "_Test Item"},
+			fieldname=["reserved_qty_for_sub_contract", "projected_qty"], as_dict=1)
+		self.assertEquals(bin2.reserved_qty_for_sub_contract, bin1.reserved_qty_for_sub_contract + 10)
+		self.assertEquals(bin2.projected_qty, bin1.projected_qty - 10)
+
+		# Create stock transfer
+		se = frappe.get_doc(make_subcontract_transfer_entry(po.name, "_Test FG Item"))
+		se.to_warehouse = "_Test Warehouse 1 - _TC"
+		for d in se.get("items"):
+			if d.item_code == "_Test Item":
+				d.qty = 6
+		se.save()
+		se.submit()
+
+		bin3 = frappe.db.get_value("Bin",
+			filters={"warehouse": "_Test Warehouse - _TC", "item_code": "_Test Item"},
+			fieldname="reserved_qty_for_sub_contract", as_dict=1)
+
+		self.assertEquals(bin3.reserved_qty_for_sub_contract, bin2.reserved_qty_for_sub_contract - 6)
+
+		# close PO
+		po.update_status("Closed")
+		bin4 = frappe.db.get_value("Bin",
+			filters={"warehouse": "_Test Warehouse - _TC", "item_code": "_Test Item"},
+			fieldname="reserved_qty_for_sub_contract", as_dict=1)
+
+		self.assertEquals(bin4.reserved_qty_for_sub_contract, bin1.reserved_qty_for_sub_contract)
+
+		# Re-open PO
+		po.update_status("Submitted")
+		bin5 = frappe.db.get_value("Bin",
+			filters={"warehouse": "_Test Warehouse - _TC", "item_code": "_Test Item"},
+			fieldname="reserved_qty_for_sub_contract", as_dict=1)
+
+		self.assertEquals(bin5.reserved_qty_for_sub_contract, bin2.reserved_qty_for_sub_contract - 6)
+
+		# make Purchase Receipt against PO
+		pr = make_purchase_receipt(po.name)
+		pr.supplier_warehouse = "_Test Warehouse 1 - _TC"
+		pr.save()
+		pr.submit()
+
+		bin6 = frappe.db.get_value("Bin",
+			filters={"warehouse": "_Test Warehouse - _TC", "item_code": "_Test Item"},
+			fieldname="reserved_qty_for_sub_contract", as_dict=1)
+
+		self.assertEquals(bin6.reserved_qty_for_sub_contract, bin1.reserved_qty_for_sub_contract)
+
+		# Cancel PR
+		pr.cancel()
+		bin7 = frappe.db.get_value("Bin",
+			filters={"warehouse": "_Test Warehouse - _TC", "item_code": "_Test Item"},
+			fieldname="reserved_qty_for_sub_contract", as_dict=1)
+
+		self.assertEquals(bin7.reserved_qty_for_sub_contract, bin2.reserved_qty_for_sub_contract - 6)
+
+		# Make Purchase Invoice
+		pi = make_purchase_invoice(po.name)
+		pi.update_stock = 1
+		pi.supplier_warehouse = "_Test Warehouse 1 - _TC"
+		pi.insert()
+		pi.submit()
+		bin8 = frappe.db.get_value("Bin",
+			filters={"warehouse": "_Test Warehouse - _TC", "item_code": "_Test Item"},
+			fieldname="reserved_qty_for_sub_contract", as_dict=1)
+
+		self.assertEquals(bin8.reserved_qty_for_sub_contract, bin1.reserved_qty_for_sub_contract)
+
+		# Cancel PR
+		pi.cancel()
+		bin9 = frappe.db.get_value("Bin",
+			filters={"warehouse": "_Test Warehouse - _TC", "item_code": "_Test Item"},
+			fieldname="reserved_qty_for_sub_contract", as_dict=1)
+
+		self.assertEquals(bin9.reserved_qty_for_sub_contract, bin2.reserved_qty_for_sub_contract - 6)
+
+		# Cancel Stock Entry
+		se.cancel()
+		bin10 = frappe.db.get_value("Bin",
+			filters={"warehouse": "_Test Warehouse - _TC", "item_code": "_Test Item"},
+			fieldname="reserved_qty_for_sub_contract", as_dict=1)
+		self.assertEquals(bin10.reserved_qty_for_sub_contract, bin1.reserved_qty_for_sub_contract + 10)
+
+		# Cancel PO
+		po.reload()
+		po.cancel()
+		bin11 = frappe.db.get_value("Bin",
+			filters={"warehouse": "_Test Warehouse - _TC", "item_code": "_Test Item"},
+			fieldname="reserved_qty_for_sub_contract", as_dict=1)
+
+		self.assertEquals(bin11.reserved_qty_for_sub_contract, bin1.reserved_qty_for_sub_contract)
 
 def get_same_items():
 	return [
-				{
-					"item_code": "_Test FG Item",
-					"warehouse": "_Test Warehouse - _TC",
-					"qty": 1,
-					"rate": 500,
-					"schedule_date": add_days(nowdate(), 1)
-				},
-				{
-					"item_code": "_Test FG Item",
-					"warehouse": "_Test Warehouse - _TC",
-					"qty": 4,
-					"rate": 500,
-					"schedule_date": add_days(nowdate(), 1)
-				}
-			]		
+		{
+			"item_code": "_Test FG Item",
+			"warehouse": "_Test Warehouse - _TC",
+			"qty": 1,
+			"rate": 500,
+			"schedule_date": add_days(nowdate(), 1)
+		},
+		{
+			"item_code": "_Test FG Item",
+			"warehouse": "_Test Warehouse - _TC",
+			"qty": 4,
+			"rate": 500,
+			"schedule_date": add_days(nowdate(), 1)
+		}
+	]
 
 def create_purchase_order(**args):
 	po = frappe.new_doc("Purchase Order")
diff --git a/erpnext/buying/doctype/purchase_order_item_supplied/purchase_order_item_supplied.json b/erpnext/buying/doctype/purchase_order_item_supplied/purchase_order_item_supplied.json
index 5e8754f..d4a02fb 100644
--- a/erpnext/buying/doctype/purchase_order_item_supplied/purchase_order_item_supplied.json
+++ b/erpnext/buying/doctype/purchase_order_item_supplied/purchase_order_item_supplied.json
@@ -15,7 +15,7 @@
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
-   "columns": 0, 
+   "columns": 2, 
    "fieldname": "main_item_code", 
    "fieldtype": "Data", 
    "hidden": 0, 
@@ -46,7 +46,7 @@
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
-   "columns": 0, 
+   "columns": 2, 
    "fieldname": "rm_item_code", 
    "fieldtype": "Data", 
    "hidden": 0, 
@@ -77,7 +77,7 @@
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
-   "columns": 0, 
+   "columns": 2, 
    "fieldname": "required_qty", 
    "fieldtype": "Float", 
    "hidden": 0, 
@@ -108,7 +108,7 @@
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
-   "columns": 0, 
+   "columns": 2, 
    "fieldname": "rate", 
    "fieldtype": "Currency", 
    "hidden": 0, 
@@ -209,7 +209,7 @@
    "ignore_xss_filter": 0, 
    "in_filter": 0, 
    "in_global_search": 0, 
-   "in_list_view": 1, 
+   "in_list_view": 0, 
    "in_standard_filter": 0, 
    "label": "BOM Detail No", 
    "length": 0, 
@@ -240,7 +240,7 @@
    "ignore_xss_filter": 0, 
    "in_filter": 0, 
    "in_global_search": 0, 
-   "in_list_view": 1, 
+   "in_list_view": 0, 
    "in_standard_filter": 0, 
    "label": "Reference Name", 
    "length": 0, 
@@ -326,7 +326,7 @@
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
-   "columns": 0, 
+   "columns": 2, 
    "fieldname": "reserve_warehouse", 
    "fieldtype": "Link", 
    "hidden": 0, 
@@ -334,7 +334,7 @@
    "ignore_xss_filter": 0, 
    "in_filter": 0, 
    "in_global_search": 0, 
-   "in_list_view": 0, 
+   "in_list_view": 1, 
    "in_standard_filter": 0, 
    "label": "Reserve Warehouse", 
    "length": 0, 
@@ -363,7 +363,7 @@
  "issingle": 0, 
  "istable": 1, 
  "max_attachments": 0, 
- "modified": "2017-11-29 21:10:40.431423", 
+ "modified": "2018-01-05 14:47:15.400785", 
  "modified_by": "Administrator", 
  "module": "Buying", 
  "name": "Purchase Order Item Supplied", 
diff --git a/erpnext/controllers/buying_controller.py b/erpnext/controllers/buying_controller.py
index c533202..d3bcebc 100644
--- a/erpnext/controllers/buying_controller.py
+++ b/erpnext/controllers/buying_controller.py
@@ -160,9 +160,10 @@
 				if item in self.sub_contracted_items and not item.bom:
 					frappe.throw(_("Please select BOM in BOM field for Item {0}").format(item.item_code))
 
-			for supplied_item in self.get("supplied_items"):
-				if not supplied_item.reserve_warehouse:
-					frappe.throw(_("Reserved Warehouse is mandatory for Item {0} in Raw Materials supplied").format(frappe.bold(supplied_item.rm_item_code)))
+			if self.doctype == "Purchase Order":
+				for supplied_item in self.get("supplied_items"):
+					if not supplied_item.reserve_warehouse:
+						frappe.throw(_("Reserved Warehouse is mandatory for Item {0} in Raw Materials supplied").format(frappe.bold(supplied_item.rm_item_code)))
 
 		else:
 			for item in self.get("items"):
@@ -195,9 +196,14 @@
 		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))
+			from `tabItem` where name in ({0})""".format(", ".join(["%s"] * len(items))), items))
 
 		for bom_item in bom_items:
+			if self.doctype == "Purchase Order":
+				reserve_warehouse = bom_item.source_warehouse or item_wh.get(bom_item.item_code)
+				if frappe.db.get_value("Warehouse", reserve_warehouse, "company") != self.company:
+					reserve_warehouse = None
+
 			# check if exists
 			exists = 0
 			for d in self.get(raw_material_table):
@@ -217,7 +223,8 @@
 			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)
+			if self.doctype == "Purchase Order" and not rm.reserve_warehouse:
+				rm.reserve_warehouse = reserve_warehouse
 
 			rm.conversion_factor = item.conversion_factor
 
@@ -344,7 +351,7 @@
 					frappe.get_meta(item_row.doctype).get_label(fieldname), item_row['item_code'])))
 
 	def update_stock_ledger(self, allow_negative_stock=False, via_landed_cost_voucher=False):
-		self.update_ordered_qty()
+		self.update_ordered_and_reserved_qty()
 
 		sl_entries = []
 		stock_items = self.get_stock_items()
@@ -386,7 +393,7 @@
 		self.make_sl_entries(sl_entries, allow_negative_stock=allow_negative_stock,
 			via_landed_cost_voucher=via_landed_cost_voucher)
 
-	def update_ordered_qty(self):
+	def update_ordered_and_reserved_qty(self):
 		po_map = {}
 		for d in self.get("items"):
 			if self.doctype=="Purchase Receipt" \
@@ -405,6 +412,8 @@
 						frappe.InvalidStatusError)
 
 				po_obj.update_ordered_qty(po_item_rows)
+				if self.is_subcontracted:
+					po_obj.update_reserved_qty_for_subcontract()
 
 	def make_sl_entries_for_supplier_warehouse(self, sl_entries):
 		if hasattr(self, 'supplied_items'):
diff --git a/erpnext/patches.txt b/erpnext/patches.txt
index 5976915..5c2c112 100644
--- a/erpnext/patches.txt
+++ b/erpnext/patches.txt
@@ -484,4 +484,5 @@
 erpnext.patches.v10_0.enabled_regional_print_format_based_on_country
 erpnext.patches.v10_0.update_asset_calculate_depreciation
 erpnext.patches.v10_0.add_guardian_role_for_parent_portal
-erpnext.patches.v10_0.set_numeric_ranges_in_template_if_blank
\ No newline at end of file
+erpnext.patches.v10_0.set_numeric_ranges_in_template_if_blank
+erpnext.patches.v10_0.update_reserved_qty_for_purchase_order
\ No newline at end of file
diff --git a/erpnext/patches/v5_8/update_order_reference_in_return_entries.py b/erpnext/patches/v5_8/update_order_reference_in_return_entries.py
index d7972dc..5032638 100644
--- a/erpnext/patches/v5_8/update_order_reference_in_return_entries.py
+++ b/erpnext/patches/v5_8/update_order_reference_in_return_entries.py
@@ -10,6 +10,7 @@
 	frappe.reload_doctype("Purchase Receipt")
 	frappe.reload_doctype("Sales Order Item")
 	frappe.reload_doctype("Purchase Order Item")
+	frappe.reload_doctype("Purchase Order Item Supplied")
 
 	# sales return
 	return_entries = list(frappe.db.sql("""
@@ -86,6 +87,6 @@
 			""", (order_details[0].purchase_order, order_details[0].po_detail, d.row_id))
 
 			pr = frappe.get_doc("Purchase Receipt", d.name)
-			pr.update_ordered_qty()
+			pr.update_ordered_and_reserved_qty()
 			pr.update_prevdoc_status()
 
diff --git a/erpnext/patches/v9_2/update_reserved_qty_for_purchase_order.py b/erpnext/patches/v9_2/update_reserved_qty_for_purchase_order.py
deleted file mode 100644
index 805c347..0000000
--- a/erpnext/patches/v9_2/update_reserved_qty_for_purchase_order.py
+++ /dev/null
@@ -1,33 +0,0 @@
-import frappe
-from frappe import _
-from erpnext.stock.utils import get_bin
-
-def execute():
-	def_warehouse = frappe.db.sql("""select min(name) from `tabWarehouse` where is_group = 0""")[0][0]
-
-	po_item = list(frappe.db.sql(("""select distinct po.name as poname, poitem.rm_item_code as rm_item_code
-					from `tabPurchase Order` po, `tabPurchase Order Item Supplied` poitem
-					where po.name = poitem.parent
-					and po.is_subcontracted = "Yes"
-					and po.docstatus = 1"""),as_dict=1))
-
-	items = list(set([d.rm_item_code for d in po_item]))
-	item_wh = frappe._dict(frappe.db.sql("""select item_code, default_warehouse
-					from `tabItem` where name in ({0})""".format(", ".join(["%s"] * len(items))), items))
-	#Update reserved warehouse
-	for item in po_item:
-		reserve_warehouse = item_wh.get(item.rm_item_code) or def_warehouse
-		update_res_warehouse = frappe.db.sql("""update `tabPurchase Order Item Supplied`
-								set reserve_warehouse = %s
-								where parent = %s and rm_item_code = %s""",(reserve_warehouse
-								,item["poname"],item["rm_item_code"]))
-	#Update bin
-	item_wh_bin = frappe.db.sql(("""select distinct poitemsup.rm_item_code as rm_item_code, 
-					poitemsup.reserve_warehouse as reserve_warehouse
-					from `tabPurchase Order` po, `tabPurchase Order Item Supplied` poitemsup
-					where po.name = poitemsup.parent
-					and po.is_subcontracted = "Yes"
-					and po.docstatus = 1"""),as_dict=1)
-	for d in item_wh_bin:
-		stock_bin = get_bin(d["rm_item_code"], d["reserve_warehouse"])
-		stock_bin.update_reserved_qty_for_sub_contracting()
\ No newline at end of file
diff --git a/erpnext/stock/doctype/bin/bin.py b/erpnext/stock/doctype/bin/bin.py
index e5b4fdf..fd34423 100644
--- a/erpnext/stock/doctype/bin/bin.py
+++ b/erpnext/stock/doctype/bin/bin.py
@@ -64,7 +64,7 @@
 	def set_projected_qty(self):
 		self.projected_qty = (flt(self.actual_qty) + flt(self.ordered_qty)
 			+ flt(self.indented_qty) + flt(self.planned_qty) - flt(self.reserved_qty)
-			- flt(self.reserved_qty_for_production))
+			- flt(self.reserved_qty_for_production) - flt(self.reserved_qty_for_sub_contract))
 
 	def get_first_sle(self):
 		sle = frappe.db.sql("""
@@ -95,28 +95,39 @@
 
 	def update_reserved_qty_for_sub_contracting(self):
 		#reserved qty
-		reserved_qty_for_sub_contract = frappe.db.sql('''select ifnull(sum(itemsup.required_qty),0)
+		reserved_qty_for_sub_contract = 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 = 1
 				and po.is_subcontracted = 'Yes'
+				and po.status != 'Closed'
+				and po.per_received < 100
 				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)
+				ifnull(sum(transfer_qty),0)
 			from
 				`tabStock Entry` se, `tabStock Entry Detail` sed, `tabPurchase Order` po
 			where
-				sed.item_code = %s
-				and se.name = sed.parent and se.docstatus=1 and se.purpose='Subcontract'
+				se.docstatus=1
+				and se.purpose='Subcontract'
+				and ifnull(se.purchase_order, '') !=''
+				and sed.item_code = %s
+				and se.name = sed.parent
 				and se.purchase_order = po.name
-				and ifnull(se.purchase_order, '') !=''""", (self.item_code))[0][0]
+				and po.docstatus = 1
+				and po.is_subcontracted = 'Yes'
+				and po.status != 'Closed'
+				and po.per_received < 100
+		""", (self.item_code))[0][0]
 
-		self.set_projected_qty()
 		self.db_set('reserved_qty_for_sub_contract', (reserved_qty_for_sub_contract - materials_transferred))
+		self.set_projected_qty()
 		self.db_set('projected_qty', self.projected_qty)
 
 def update_item_projected_qty(item_code):
diff --git a/erpnext/stock/doctype/purchase_receipt/purchase_receipt.py b/erpnext/stock/doctype/purchase_receipt/purchase_receipt.py
index 29f3553..fb12f19 100644
--- a/erpnext/stock/doctype/purchase_receipt/purchase_receipt.py
+++ b/erpnext/stock/doctype/purchase_receipt/purchase_receipt.py
@@ -121,8 +121,10 @@
 		if self.per_billed < 100:
 			self.update_billing_status()
 
+		
 		# Updating stock ledger should always be called after updating prevdoc status,
-		# because updating ordered qty in bin depends upon updated ordered qty in PO
+		# because updating ordered qty, reserved_qty_for_subcontract in bin
+		# depends upon updated ordered qty in PO
 		self.update_stock_ledger()
 
 		from erpnext.stock.doctype.serial_no.serial_no import update_serial_nos_after_submit
diff --git a/erpnext/stock/doctype/stock_entry/stock_entry.py b/erpnext/stock/doctype/stock_entry/stock_entry.py
index d33fc64..3af8d4e 100644
--- a/erpnext/stock/doctype/stock_entry/stock_entry.py
+++ b/erpnext/stock/doctype/stock_entry/stock_entry.py
@@ -586,13 +586,15 @@
 						frappe.throw(_("Manufacturing Quantity is mandatory"))
 
 					item_dict = self.get_bom_raw_materials(self.fg_completed_qty)
+
 					#Get PO Supplied Items Details
 					if self.purchase_order and self.purpose == "Subcontract":
 						#Get PO Supplied Items Details
-						item_wh = frappe._dict(frappe.db.sql("""select rm_item_code, reserve_warehouse 
-										from `tabPurchase Order` po, `tabPurchase Order Item Supplied` poitemsup
-										where po.name = poitemsup.parent
-										and po.name = %s""",self.purchase_order))
+						item_wh = frappe._dict(frappe.db.sql("""
+							select rm_item_code, reserve_warehouse 
+							from `tabPurchase Order` po, `tabPurchase Order Item Supplied` poitemsup
+							where po.name = poitemsup.parent
+								and po.name = %s""",self.purchase_order))
 					for item in item_dict.values():
 						if self.pro_doc and not self.pro_doc.skip_transfer:
 							item["from_warehouse"] = self.pro_doc.wip_warehouse
@@ -602,11 +604,13 @@
 
 					self.add_to_stock_entry_detail(item_dict)
 
-					scrap_item_dict = self.get_bom_scrap_material(self.fg_completed_qty)
-					for item in scrap_item_dict.values():
-						if self.pro_doc and self.pro_doc.scrap_warehouse:
-							item["to_warehouse"] = self.pro_doc.scrap_warehouse
-					self.add_to_stock_entry_detail(scrap_item_dict, bom_no=self.bom_no)
+					if self.purpose != "Subcontract":
+						scrap_item_dict = self.get_bom_scrap_material(self.fg_completed_qty)
+						for item in scrap_item_dict.values():
+							if self.pro_doc and self.pro_doc.scrap_warehouse:
+								item["to_warehouse"] = self.pro_doc.scrap_warehouse
+
+						self.add_to_stock_entry_detail(scrap_item_dict, bom_no=self.bom_no)
 
 			# fetch the serial_no of the first stock entry for the second stock entry
 			if self.production_order and self.purpose == "Manufacture":
@@ -846,6 +850,20 @@
 							frappe.throw(_("Batch {0} of Item {1} has expired.")
 								.format(item.batch_no, item.item_code))
 
+	def update_purchase_order_supplied_items(self):
+		#Get PO Supplied Items Details
+		item_wh = frappe._dict(frappe.db.sql("""
+			select rm_item_code, reserve_warehouse 
+			from `tabPurchase Order` po, `tabPurchase Order Item Supplied` poitemsup
+			where po.name = poitemsup.parent
+			and po.name = %s""", self.purchase_order))
+
+		#Update reserved sub contracted quantity in bin based on Supplied Item Details
+		for d in self.get("items"):
+			reserve_warehouse = item_wh.get(d.item_code)
+			stock_bin = get_bin(d.item_code, reserve_warehouse)
+			stock_bin.update_reserved_qty_for_sub_contracting()
+	
 @frappe.whitelist()
 def move_sample_to_retention_warehouse(company, items):
 	if isinstance(items, basestring):
@@ -881,18 +899,6 @@
 	if stock_entry.get('items'):
 		return stock_entry.as_dict()
 
-	def update_purchase_order_supplied_items(self):
-		#Get PO Supplied Items Details
-		item_wh = frappe._dict(frappe.db.sql("""select rm_item_code, reserve_warehouse 
-						from `tabPurchase Order` po, `tabPurchase Order Item Supplied` poitemsup
-						where po.name = poitemsup.parent
-						and po.name = %s""",self.purchase_order))
-		#Update reserved sub contracted quantity in bin based on Supplied Item Details
-		for d in self.get("items"):
-			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()
 def get_production_order_details(production_order):
 	production_order = frappe.get_doc("Production Order", production_order)
diff --git a/erpnext/stock/report/stock_projected_qty/stock_projected_qty.py b/erpnext/stock/report/stock_projected_qty/stock_projected_qty.py
index 21287b9..89a256c 100644
--- a/erpnext/stock/report/stock_projected_qty/stock_projected_qty.py
+++ b/erpnext/stock/report/stock_projected_qty/stock_projected_qty.py
@@ -16,6 +16,7 @@
 		_("UOM") + ":Link/UOM:100", _("Actual Qty") + ":Float:100", _("Planned Qty") + ":Float:100",
 		_("Requested Qty") + ":Float:110", _("Ordered Qty") + ":Float:100",
 		_("Reserved Qty") + ":Float:100", _("Reserved Qty for Production") + ":Float:100",
+		_("Reserved for sub contracting") + ":Float:100",
 		_("Projected Qty") + ":Float:100", _("Reorder Level") + ":Float:100", _("Reorder Qty") + ":Float:100",
 		_("Shortage Qty") + ":Float:100"]
 
@@ -33,7 +34,8 @@
 			continue
 
 		# item = item_map.setdefault(bin.item_code, get_item(bin.item_code))
-		company = warehouse_company.setdefault(bin.warehouse, frappe.db.get_value("Warehouse", bin.warehouse, "company"))
+		company = warehouse_company.setdefault(bin.warehouse,
+			frappe.db.get_value("Warehouse", bin.warehouse, "company"))
 
 		if filters.brand and filters.brand != item.brand:
 			continue
@@ -52,7 +54,8 @@
 
 		data.append([item.name, item.item_name, item.description, item.item_group, item.brand, bin.warehouse,
 			item.stock_uom, bin.actual_qty, bin.planned_qty, bin.indented_qty, bin.ordered_qty,
-			bin.reserved_qty, bin.reserved_qty_for_production, bin.projected_qty, re_order_level, re_order_qty, shortage_qty])
+			bin.reserved_qty, bin.reserved_qty_for_production, bin.reserved_qty_for_sub_contract,
+			bin.projected_qty, re_order_level, re_order_qty, shortage_qty])
 
 	return data
 
@@ -71,7 +74,7 @@
 				warehouse_details.rgt))
 
 	bin_list = frappe.db.sql("""select item_code, warehouse, actual_qty, planned_qty, indented_qty,
-		ordered_qty, reserved_qty, reserved_qty_for_production, projected_qty
+		ordered_qty, reserved_qty, reserved_qty_for_production, reserved_qty_for_sub_contract, projected_qty
 		from tabBin bin {conditions} order by item_code, warehouse
 		""".format(conditions=" where " + " and ".join(conditions) if conditions else ""), as_dict=1)