[fix] #8427
diff --git a/erpnext/buying/doctype/purchase_order/purchase_order.py b/erpnext/buying/doctype/purchase_order/purchase_order.py
index bbaa043..0386830 100644
--- a/erpnext/buying/doctype/purchase_order/purchase_order.py
+++ b/erpnext/buying/doctype/purchase_order/purchase_order.py
@@ -13,7 +13,7 @@
 from frappe.desk.notifications import clear_doctype_notifications
 from erpnext.buying.utils import (validate_for_items, check_for_closed_status,
 	update_last_purchase_rate)
-
+from erpnext.stock.utils import get_bin
 
 form_grid_templates = {
 	"items": "templates/form_grid/item_grid.html"
@@ -187,6 +187,8 @@
 		self.update_prevdoc_status()
 		self.update_requested_qty()
 		self.update_ordered_qty()
+		if self.is_subcontracted == "Yes":
+			self.update_reserved_qty_for_subcontract()
 
 		frappe.get_doc('Authorization Control').validate_approving_authority(self.doctype,
 			self.company, self.base_grand_total)
@@ -249,6 +251,17 @@
 			if item.delivered_by_supplier == 1:
 				item.received_qty = item.qty
 
+	def update_reserved_qty_for_subcontract(self):
+		items = list(set([d.rm_item_code for d in self.get("supplied_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 d in self.supplied_items:
+			if d.rm_item_code:
+				warehouse = item_wh.get(d.rm_item_code)
+				stock_bin = get_bin(d.rm_item_code, warehouse)
+				stock_bin.update_reserved_qty_for_sub_contracting(self.name, transferred_qty=0, transaction_type = "Reserve")
+
 @frappe.whitelist()
 def close_or_unclose_purchase_orders(names, status):
 	if not frappe.has_permission("Purchase Order", "write"):
diff --git a/erpnext/stock/dashboard/item_dashboard.js b/erpnext/stock/dashboard/item_dashboard.js
index 3c334c4..23820d3 100644
--- a/erpnext/stock/dashboard/item_dashboard.js
+++ b/erpnext/stock/dashboard/item_dashboard.js
@@ -89,7 +89,7 @@
 		data.forEach(function(d) {
 			d.actual_or_pending = d.projected_qty + d.reserved_qty + d.reserved_qty_for_production;
 			d.pending_qty = 0;
-			d.total_reserved = d.reserved_qty + d.reserved_qty_for_production;
+			d.total_reserved = d.reserved_qty + d.reserved_qty_for_production + d.reserved_qty_for_sub_contract;
 			if(d.actual_or_pending > d.actual_qty) {
 				d.pending_qty = d.actual_or_pending - d.actual_qty;
 			}
diff --git a/erpnext/stock/dashboard/item_dashboard.py b/erpnext/stock/dashboard/item_dashboard.py
index 0d75a9a..f95daaf 100644
--- a/erpnext/stock/dashboard/item_dashboard.py
+++ b/erpnext/stock/dashboard/item_dashboard.py
@@ -26,13 +26,14 @@
 	return frappe.db.sql('''
 	select
 		b.item_code, b.warehouse, b.projected_qty, b.reserved_qty,
-		b.reserved_qty_for_production, b.actual_qty, b.valuation_rate, i.item_name
+		b.reserved_qty_for_production, b.reserved_qty_for_sub_contract, b.actual_qty, b.valuation_rate, i.item_name
 	from
 		tabBin b, tabItem i
 	where
 		b.item_code = i.name
 		and
-		(b.projected_qty != 0 or b.reserved_qty != 0 or b.reserved_qty_for_production != 0 or b.actual_qty != 0)
+		(b.projected_qty != 0 or b.reserved_qty != 0 or b.reserved_qty_for_production != 0 
+		or b.reserved_qty_for_sub_contract != 0 or b.actual_qty != 0)
 		{conditions}
 	order by
 		{sort_by} {sort_order}
diff --git a/erpnext/stock/doctype/bin/bin.json b/erpnext/stock/doctype/bin/bin.json
index 1f6e9e1..def817b 100644
--- a/erpnext/stock/doctype/bin/bin.json
+++ b/erpnext/stock/doctype/bin/bin.json
@@ -302,6 +302,36 @@
    "bold": 0, 
    "collapsible": 0, 
    "columns": 0, 
+   "fieldname": "reserved_qty_for_sub_contract", 
+   "fieldtype": "Float", 
+   "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": "Reserved Qty for sub contract", 
+   "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, 
    "fieldname": "ma_rate", 
    "fieldtype": "Float", 
    "hidden": 1, 
@@ -463,7 +493,7 @@
  "issingle": 0, 
  "istable": 0, 
  "max_attachments": 0, 
- "modified": "2017-06-13 13:06:32.601505", 
+ "modified": "2017-11-22 08:14:30.615638", 
  "modified_by": "Administrator", 
  "module": "Stock", 
  "name": "Bin", 
diff --git a/erpnext/stock/doctype/bin/bin.py b/erpnext/stock/doctype/bin/bin.py
index 626a9db..b3e89dc 100644
--- a/erpnext/stock/doctype/bin/bin.py
+++ b/erpnext/stock/doctype/bin/bin.py
@@ -94,6 +94,28 @@
 			self.db_set('reserved_qty_for_production', self.reserved_qty_for_production)
 			self.db_set('projected_qty', self.projected_qty)
 
+	def update_reserved_qty_for_sub_contracting(self, po_name, transferred_qty, transaction_type):
+		#Update Reserved Quantity for Sub Contracting in Bin
+		if transaction_type == "Reserve":
+			required_qty = frappe.db.sql('''select sum(itemsup.required_qty)
+				from `tabItem` item, `tabPurchase Order` po, `tabPurchase Order Item Supplied` itemsup
+				where
+					item.name = itemsup.rm_item_code
+					and po.name = %s
+					and itemsup.rm_item_code = %s
+					and itemsup.parent = po.name
+					and po.docstatus = 1
+					and po.is_subcontracted = 'Yes'
+					and item.default_warehouse = %s''', (po_name, self.item_code, self.warehouse))[0][0]
+		elif transaction_type == "Transfer":
+			required_qty = 0
+
+		reserved_qty_bin = self.reserved_qty_for_sub_contract
+		reserved_qty_for_sub_contract = reserved_qty_bin + required_qty - transferred_qty
+
+		self.set_projected_qty()
+		self.db_set('reserved_qty_for_sub_contract', reserved_qty_for_sub_contract)
+		self.db_set('projected_qty', self.projected_qty)
 
 def update_item_projected_qty(item_code):
 	'''Set total_projected_qty in Item as sum of projected qty in all warehouses'''
diff --git a/erpnext/stock/doctype/stock_entry/stock_entry.py b/erpnext/stock/doctype/stock_entry/stock_entry.py
index 4d79e13..40e386e 100644
--- a/erpnext/stock/doctype/stock_entry/stock_entry.py
+++ b/erpnext/stock/doctype/stock_entry/stock_entry.py
@@ -11,6 +11,7 @@
 from erpnext.stock.get_item_details import get_bin_details, get_default_cost_center, get_conversion_factor
 from erpnext.stock.doctype.batch.batch import get_batch_no, set_batch_nos
 from erpnext.manufacturing.doctype.bom.bom import validate_bom_no
+from erpnext.stock.utils import get_bin
 import json
 
 class IncorrectValuationRateError(frappe.ValidationError): pass
@@ -64,6 +65,8 @@
 		update_serial_nos_after_submit(self, "items")
 		self.update_production_order()
 		self.validate_purchase_order()
+		if self.purchase_order and self.purpose == "Subcontract":
+			self.update_purchase_order_supplied_items()
 		self.make_gl_entries()
 
 	def on_cancel(self):
@@ -803,6 +806,30 @@
 						if getdate(self.posting_date) > getdate(expiry_date):
 							frappe.throw(_("Batch {0} of Item {1} has expired.").format(item.batch_no, item.item_code))
 
+	def update_purchase_order_supplied_items(self):
+		materials_transferred = frappe._dict(frappe.db.sql("""
+			select
+				concat(item_code, sed.s_warehouse), sum(qty)
+			from
+				`tabStock Entry` se, `tabStock Entry Detail` sed
+			where
+				se.name = sed.parent and se.docstatus=1 and se.purpose='Subcontract'
+				and se.purchase_order= %s and ifnull(sed.s_warehouse, '') != ''
+			group by sed.item_code, sed.s_warehouse
+		""", self.purchase_order))
+		#Get PO Supplied Items Details
+		po_doc =  frappe.get_doc("Purchase Order",self.purchase_order)
+		po_supplied_items = po_doc.get("supplied_items")
+		items = list(set([d.rm_item_code for d in po_supplied_items]))
+		item_wh = frappe._dict(frappe.db.sql("""select item_code as "item_code", default_warehouse as "warehouse"
+			from tabItem where name in ({0})""".format(", ".join(["%s"] * len(items))), items))
+		#Update reserved sub contracted quantity in bin based on Supplied Item Details
+		for d in po_supplied_items:
+			warehouse = item_wh.get(d.rm_item_code)
+			transferred_qty = materials_transferred.get(d.rm_item_code + warehouse)
+			stock_bin = get_bin(d.rm_item_code, warehouse)
+			stock_bin.update_reserved_qty_for_sub_contracting(self.purchase_order, transferred_qty, transaction_type = "Transfer")
+
 @frappe.whitelist()
 def get_production_order_details(production_order):
 	production_order = frappe.get_doc("Production Order", production_order)
diff --git a/erpnext/stock/page/stock_balance/stock_balance.js b/erpnext/stock/page/stock_balance/stock_balance.js
index 16a85fa..85ea5b1 100644
--- a/erpnext/stock/page/stock_balance/stock_balance.js
+++ b/erpnext/stock/page/stock_balance/stock_balance.js
@@ -48,6 +48,7 @@
 				{fieldname: 'projected_qty', label: __('Projected qty')},
 				{fieldname: 'reserved_qty', label: __('Reserved for sale')},
 				{fieldname: 'reserved_qty_for_production', label: __('Reserved for manufacturing')},
+				{fieldname: 'reserved_qty_for_sub_contract', label: __('Reserved for sub contracting')},
 				{fieldname: 'actual_qty', label: __('Actual qty in stock')},
 			]
 		},
diff --git a/erpnext/stock/stock_balance.py b/erpnext/stock/stock_balance.py
index 6a4ac43..49909d9 100644
--- a/erpnext/stock/stock_balance.py
+++ b/erpnext/stock/stock_balance.py
@@ -150,7 +150,7 @@
 	if mismatch:
 		bin.projected_qty = (flt(bin.actual_qty) + flt(bin.ordered_qty) +
 			flt(bin.indented_qty) + flt(bin.planned_qty) - flt(bin.reserved_qty)
-			- flt(bin.reserved_qty_for_production))
+			- flt(bin.reserved_qty_for_production)) - flt(bin.reserved_qty_for_sub_contract)
 
 		bin.save()