Merge pull request #13310 from manassolanki/student-report-card

addition of student report card generation tool
diff --git a/erpnext/__init__.py b/erpnext/__init__.py
index 99981bd..416aaf4 100644
--- a/erpnext/__init__.py
+++ b/erpnext/__init__.py
@@ -5,7 +5,7 @@
 from erpnext.hooks import regional_overrides
 from frappe.utils import getdate
 
-__version__ = '10.1.6'
+__version__ = '10.1.13'
 
 def get_default_company(user=None):
 	'''Get default company for user'''
diff --git a/erpnext/accounts/doctype/account/account.py b/erpnext/accounts/doctype/account/account.py
index 448cc83..ac19690 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/payment_entry/payment_entry.js b/erpnext/accounts/doctype/payment_entry/payment_entry.js
index 9e3fa71..776bacf 100644
--- a/erpnext/accounts/doctype/payment_entry/payment_entry.js
+++ b/erpnext/accounts/doctype/payment_entry/payment_entry.js
@@ -676,30 +676,17 @@
 			function(d) { return flt(d.amount) }));
 
 		if(frm.doc.party) {
-			var party_amount = frm.doc.payment_type=="Receive" ?
-				frm.doc.paid_amount : frm.doc.received_amount;
-			var company_currency = frm.doc.company? frappe.get_doc(":Company", frm.doc.company).default_currency: "";
-
-			if (frm.doc.party_account_currency == company_currency) {
-				if(frm.doc.payment_type == "Receive" && frm.doc.total_allocated_amount <= party_amount + total_deductions) {
-					unallocated_amount = party_amount - (frm.doc.total_allocated_amount - total_deductions);
-				} else if (frm.doc.payment_type == "Pay" && frm.doc.total_allocated_amount <= party_amount - total_deductions) {
-					unallocated_amount = party_amount - (frm.doc.total_allocated_amount + total_deductions);
-				}
-			} else {
-				if(frm.doc.payment_type == "Receive"
-					&& frm.doc.base_total_allocated_amount <= frm.doc.base_received_amount + total_deductions
-					&& frm.doc.total_allocated_amount < frm.doc.paid_amount) {
-						unallocated_amount = (frm.doc.base_received_amount + total_deductions
-							- frm.doc.base_total_allocated_amount) / frm.doc.source_exchange_rate;
-				} else if (frm.doc.payment_type == "Pay"
-					&& frm.doc.base_total_allocated_amount < frm.doc.base_paid_amount - total_deductions
-					&& frm.doc.total_allocated_amount < frm.doc.received_amount) {
-						unallocated_amount = (frm.doc.base_paid_amount - (total_deductions
-							+ frm.doc.base_total_allocated_amount)) / frm.doc.target_exchange_rate;
-				}
+			if(frm.doc.payment_type == "Receive"
+				&& frm.doc.base_total_allocated_amount < frm.doc.base_received_amount + total_deductions
+				&& frm.doc.total_allocated_amount < frm.doc.paid_amount + (total_deductions / frm.doc.source_exchange_rate)) {
+					unallocated_amount = (frm.doc.base_received_amount + total_deductions
+						- frm.doc.base_total_allocated_amount) / frm.doc.source_exchange_rate;
+			} else if (frm.doc.payment_type == "Pay"
+				&& frm.doc.base_total_allocated_amount < frm.doc.base_paid_amount - total_deductions
+				&& frm.doc.total_allocated_amount < frm.doc.received_amount + (total_deductions / frm.doc.target_exchange_rate)) {
+					unallocated_amount = (frm.doc.base_paid_amount - (total_deductions
+						+ frm.doc.base_total_allocated_amount)) / frm.doc.target_exchange_rate;
 			}
-			
 		}
 		frm.set_value("unallocated_amount", unallocated_amount);
 		frm.trigger("set_difference_amount");
diff --git a/erpnext/accounts/doctype/payment_entry/payment_entry.py b/erpnext/accounts/doctype/payment_entry/payment_entry.py
index 7dfa5c8..eafdac3 100644
--- a/erpnext/accounts/doctype/payment_entry/payment_entry.py
+++ b/erpnext/accounts/doctype/payment_entry/payment_entry.py
@@ -292,30 +292,18 @@
 
 	def set_unallocated_amount(self):
 		self.unallocated_amount = 0
-
 		if self.party:
 			total_deductions = sum([flt(d.amount) for d in self.get("deductions")])
-
-			if self.party_account_currency == self.company_currency:
-				if self.payment_type == "Receive" \
-					and self.total_allocated_amount <= self.paid_amount + total_deductions:
-						self.unallocated_amount = self.paid_amount - \
-							(self.total_allocated_amount - total_deductions)
-				elif self.payment_type == "Pay" \
-					and self.total_allocated_amount <= self.received_amount - total_deductions:
-						self.unallocated_amount = self.received_amount - \
-							(self.total_allocated_amount + total_deductions)
-			else:
-				if self.payment_type == "Receive" \
-					and self.base_total_allocated_amount <= self.base_received_amount + total_deductions \
-					and self.total_allocated_amount < self.paid_amount:
-						self.unallocated_amount = (self.base_received_amount + total_deductions - 
-							self.base_total_allocated_amount) / self.source_exchange_rate
-				elif self.payment_type == "Pay" \
-					and self.base_total_allocated_amount < (self.base_paid_amount - total_deductions) \
-					and self.total_allocated_amount < self.received_amount:
-						self.unallocated_amount = (self.base_paid_amount - (total_deductions + 
-							self.base_total_allocated_amount)) / self.target_exchange_rate
+			if self.payment_type == "Receive" \
+				and self.base_total_allocated_amount < self.base_received_amount + total_deductions \
+				and self.total_allocated_amount < self.paid_amount + (total_deductions / self.source_exchange_rate):
+					self.unallocated_amount = (self.base_received_amount + total_deductions - 
+						self.base_total_allocated_amount) / self.source_exchange_rate
+			elif self.payment_type == "Pay" \
+				and self.base_total_allocated_amount < (self.base_paid_amount - total_deductions) \
+				and self.total_allocated_amount < self.received_amount + (total_deductions / self.target_exchange_rate):
+					self.unallocated_amount = (self.base_paid_amount - (total_deductions + 
+						self.base_total_allocated_amount)) / self.target_exchange_rate
 
 	def set_difference_amount(self):
 		base_unallocated_amount = flt(self.unallocated_amount) * (flt(self.source_exchange_rate)
diff --git a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py
index 28d51ce..21b71ff 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/accounts/doctype/sales_invoice/sales_invoice.json b/erpnext/accounts/doctype/sales_invoice/sales_invoice.json
index e00f075..2bd1447 100644
--- a/erpnext/accounts/doctype/sales_invoice/sales_invoice.json
+++ b/erpnext/accounts/doctype/sales_invoice/sales_invoice.json
@@ -687,12 +687,12 @@
    "in_standard_filter": 0,
    "label": "Customer's Purchase Order",
    "length": 0,
-   "no_copy": 0,
+   "no_copy": 1,
    "permlevel": 0,
    "precision": "",
    "print_hide": 1,
    "print_hide_if_no_value": 0,
-   "read_only": 1,
+   "read_only": 0,
    "remember_last_selected_value": 0,
    "report_hide": 0,
    "reqd": 0,
@@ -4683,7 +4683,7 @@
  "istable": 0,
  "max_attachments": 0,
  "menu_index": 0,
- "modified": "2018-01-12 15:19:54.711885",
+ "modified": "2018-03-13 15:19:54.711885",
  "modified_by": "Administrator",
  "module": "Accounts",
  "name": "Sales Invoice",
diff --git a/erpnext/accounts/party.py b/erpnext/accounts/party.py
index 5237a71..7fc0f67 100644
--- a/erpnext/accounts/party.py
+++ b/erpnext/accounts/party.py
@@ -4,12 +4,11 @@
 from __future__ import unicode_literals
 
 import frappe
-import datetime
 from frappe import _, msgprint, scrub
 from frappe.defaults import get_user_permissions
 from frappe.model.utils import get_fetch_values
-from frappe.utils import (add_days, getdate, formatdate, get_first_day, date_diff,
-                          add_years, get_timestamp, nowdate, flt, add_months, get_last_day)
+from frappe.utils import (add_days, getdate, formatdate, date_diff,
+	add_years, get_timestamp, nowdate, flt, add_months, get_last_day)
 from frappe.contacts.doctype.address.address import (get_address_display,
 	get_default_address, get_company_address)
 from frappe.contacts.doctype.contact.contact import get_contact_details, get_default_contact
diff --git a/erpnext/accounts/report/sales_register/sales_register.py b/erpnext/accounts/report/sales_register/sales_register.py
index ace8d54..f74ccc7 100644
--- a/erpnext/accounts/report/sales_register/sales_register.py
+++ b/erpnext/accounts/report/sales_register/sales_register.py
@@ -25,8 +25,6 @@
 	#Cost Center & Warehouse Map
 	invoice_cc_wh_map = get_invoice_cc_wh_map(invoice_list)
 	invoice_so_dn_map = get_invoice_so_dn_map(invoice_list)
-	customers = list(set([inv.customer for inv in invoice_list]))
-	customer_map = get_customer_details(customers)
 	company_currency = frappe.db.get_value("Company", filters.get("company"), "default_currency")
 	mode_of_payments = get_mode_of_payments([inv.name for inv in invoice_list])
 
@@ -38,7 +36,6 @@
 		cost_center = list(set(invoice_cc_wh_map.get(inv.name, {}).get("cost_center", [])))
 		warehouse = list(set(invoice_cc_wh_map.get(inv.name, {}).get("warehouse", [])))
 
-		customer_details = customer_map.get(inv.customer, {})
 		row = [
 			inv.name, inv.posting_date, inv.customer, inv.customer_name
 		]
@@ -48,8 +45,8 @@
 				row.append(inv.get(col))
 
 		row +=[
-			customer_details.get("customer_group"),
-			customer_details.get("territory"),
+			inv.get("customer_group"),
+			inv.get("territory"),
 			inv.debit_to, ", ".join(mode_of_payments.get(inv.name, [])),
 			inv.project, inv.owner, inv.remarks,
 			", ".join(sales_order), ", ".join(delivery_note),", ".join(cost_center),
@@ -162,7 +159,9 @@
 		additional_query_columns = ', ' + ', '.join(additional_query_columns)
 
 	conditions = get_conditions(filters)
-	return frappe.db.sql("""select name, posting_date, debit_to, project, customer, customer_name, owner, remarks,
+	return frappe.db.sql("""
+		select name, posting_date, debit_to, project, customer, 
+		customer_name, owner, remarks, territory, customer_group,
 		base_net_total, base_grand_total, base_rounded_total, outstanding_amount {0}
 		from `tabSales Invoice`
 		where docstatus = 1 %s order by posting_date desc, name desc""".format(additional_query_columns or '') %
@@ -241,15 +240,6 @@
 
 	return invoice_cc_wh_map
 
-def get_customer_details(customers):
-	customer_map = {}
-	for cust in frappe.db.sql("""select name, territory, customer_group from `tabCustomer`
-		where name in (%s)""" % ", ".join(["%s"]*len(customers)), tuple(customers), as_dict=1):
-			customer_map.setdefault(cust.name, cust)
-
-	return customer_map
-
-
 def get_mode_of_payments(invoice_list):
 	mode_of_payments = {}
 	if invoice_list:
diff --git a/erpnext/agriculture/doctype/crop/crop.py b/erpnext/agriculture/doctype/crop/crop.py
index 7eeb8af..ca928f8 100644
--- a/erpnext/agriculture/doctype/crop/crop.py
+++ b/erpnext/agriculture/doctype/crop/crop.py
@@ -5,6 +5,7 @@
 from __future__ import unicode_literals
 import frappe
 from frappe.model.document import Document
+from frappe import _
 
 class Crop(Document):
 	def validate(self):
@@ -12,7 +13,7 @@
 		for task in self.agriculture_task:
 			# validate start_day is not > end_day
 			if task.start_day > task.end_day:
-				frappe.throw("Start day is greater than end day in task '{0}'".format(task.subject))
+				frappe.throw(_("Start day is greater than end day in task '{0}'").format(task.task_name))
 			# to calculate the period of the Crop Cycle
 			if task.end_day > max_period: max_period = task.end_day
 		if max_period > self.period: self.period = max_period
diff --git a/erpnext/agriculture/doctype/disease/disease.py b/erpnext/agriculture/doctype/disease/disease.py
index 42005d6..f7cd7df 100644
--- a/erpnext/agriculture/doctype/disease/disease.py
+++ b/erpnext/agriculture/doctype/disease/disease.py
@@ -5,6 +5,7 @@
 from __future__ import unicode_literals
 import frappe
 from frappe.model.document import Document
+from frappe import _
 
 class Disease(Document):
 	def validate(self):
@@ -12,7 +13,7 @@
 		for task in self.treatment_task:
 			# validate start_day is not > end_day
 			if task.start_day > task.end_day:
-				frappe.throw("Start day is greater than end day in task '{0}'".format(task.task_name))
+				frappe.throw(_("Start day is greater than end day in task '{0}'").format(task.task_name))
 			# to calculate the period of the Crop Cycle
 			if task.end_day > max_period: max_period = task.end_day
 		self.treatment_period = max_period
\ No newline at end of file
diff --git a/erpnext/agriculture/doctype/soil_texture/soil_texture.py b/erpnext/agriculture/doctype/soil_texture/soil_texture.py
index 7345e86..26c5d5c 100644
--- a/erpnext/agriculture/doctype/soil_texture/soil_texture.py
+++ b/erpnext/agriculture/doctype/soil_texture/soil_texture.py
@@ -6,6 +6,7 @@
 import frappe
 from frappe.model.document import Document
 from frappe.utils import flt, cint
+from frappe import _
 
 class SoilTexture(Document):
 	soil_edit_order = [2, 1, 0]
@@ -20,9 +21,9 @@
 		self.update_soil_edit('sand_composition')
 		for soil_type in self.soil_types:
 			if self.get(soil_type) > 100 or self.get(soil_type) < 0:
-				frappe.throw("{0} should be a value between 0 and 100".format(soil_type))
+				frappe.throw(_("{0} should be a value between 0 and 100").format(soil_type))
 		if sum(self.get(soil_type) for soil_type in self.soil_types) != 100:
-			frappe.throw('Soil compositions do not add up to 100')
+			frappe.throw(_('Soil compositions do not add up to 100'))
 
 	def update_soil_edit(self, soil_type):
 		self.soil_edit_order[self.soil_types.index(soil_type)] = max(self.soil_edit_order)+1
diff --git a/erpnext/agriculture/doctype/water_analysis/water_analysis.py b/erpnext/agriculture/doctype/water_analysis/water_analysis.py
index 81fdf14..4d3cde0 100644
--- a/erpnext/agriculture/doctype/water_analysis/water_analysis.py
+++ b/erpnext/agriculture/doctype/water_analysis/water_analysis.py
@@ -5,6 +5,7 @@
 from __future__ import unicode_literals
 import frappe
 from frappe.model.document import Document
+from frappe import _
 
 class WaterAnalysis(Document):
 	def load_contents(self):
@@ -18,6 +19,6 @@
 
 	def validate(self):
 		if self.collection_datetime > self.laboratory_testing_datetime:
-			frappe.throw('Lab testing datetime cannot be before collection datetime')
+			frappe.throw(_('Lab testing datetime cannot be before collection datetime'))
 		if self.laboratory_testing_datetime > self.result_datetime:
-			frappe.throw('Lab result datetime cannot be before testing datetime')
\ No newline at end of file
+			frappe.throw(_('Lab result datetime cannot be before testing datetime'))
\ No newline at end of file
diff --git a/erpnext/buying/doctype/purchase_order/purchase_order.js b/erpnext/buying/doctype/purchase_order/purchase_order.js
index d012dee..0940288 100644
--- a/erpnext/buying/doctype/purchase_order/purchase_order.js
+++ b/erpnext/buying/doctype/purchase_order/purchase_order.js
@@ -15,6 +15,15 @@
 
 		frm.set_indicator_formatter('item_code',
 			function(doc) { return (doc.qty<=doc.received_qty) ? "green" : "orange" })
+
+		frm.set_query("reserve_warehouse", "supplied_items", function() {
+			return {
+				filters: {
+					"company": frm.doc.company,
+					"is_group": 0
+				}
+			}
+		});
 	},
 
 	onload: function(frm) {
@@ -134,23 +143,124 @@
 		var items = $.map(cur_frm.doc.items, function(d) { return d.bom ? d.item_code : false; });
 		var me = this;
 
-		if(items.length===1) {
-			me._make_stock_entry(items[0]);
-			return;
+		if(items.length >= 1){
+			me.raw_material_data = [];
+			me.show_dialog = 1;
+			let title = "";
+			let fields = [
+			{fieldtype:'Section Break', label: __('Raw Materials')},
+			{fieldname: 'sub_con_rm_items', fieldtype: 'Table',
+				fields: [
+					{
+						fieldtype:'Data',
+						fieldname:'item_code',
+						label: __('Item'),
+						read_only:1,
+						in_list_view:1
+					},
+					{
+						fieldtype:'Data',
+						fieldname:'rm_item_code',
+						label: __('Raw Material'),
+						read_only:1,
+						in_list_view:1
+					},
+					{
+						fieldtype:'Float',
+						read_only:1,
+						fieldname:'qty',
+						label: __('Quantity'),
+						read_only:1,
+						in_list_view:1
+					},
+					{
+						fieldtype:'Data',
+						read_only:1,
+						fieldname:'warehouse',
+						label: __('Reserve Warehouse'),
+						in_list_view:1
+					},
+					{
+						fieldtype:'Float',
+						read_only:1,
+						fieldname:'rate',
+						label: __('Rate'),
+						hidden:1
+					},
+					{
+						fieldtype:'Float',
+						read_only:1,
+						fieldname:'amount',
+						label: __('Amount'),
+						hidden:1
+					},
+					{
+						fieldtype:'Link',
+						read_only:1,
+						fieldname:'uom',
+						label: __('UOM'),
+						hidden:1
+					}
+				],
+				data: me.raw_material_data,
+				get_data: function() {
+					return me.raw_material_data;
+				}
+			}
+		]
+
+		me.dialog = new frappe.ui.Dialog({
+			title: title, fields: fields
+			});
+
+		if (me.frm.doc['supplied_items']) {
+			me.frm.doc['supplied_items'].forEach((item, index) => {
+			if (item.rm_item_code && item.main_item_code) {
+					me.raw_material_data.push ({
+						'name':index,
+						'item_code': item.main_item_code,
+						'rm_item_code': item.rm_item_code,
+						'item_name': item.rm_item_code,
+						'qty': item.required_qty,
+						'warehouse':item.reserve_warehouse,
+						'rate':item.rate,
+						'amount':item.amount,
+						'stock_uom':item.stock_uom
+					});
+					me.dialog.fields_dict.sub_con_rm_items.grid.refresh();
+				}
+			})
 		}
-		frappe.prompt({fieldname:"item", options: items, fieldtype:"Select",
-			label: __("Select Item for Transfer"), reqd: 1}, function(data) {
-			me._make_stock_entry(data.item);
-		}, __("Select Item"), __("Make"));
+
+		me.dialog.show()
+		this.dialog.set_primary_action(__('Transfer'), function() {
+			me.values = me.dialog.get_values();
+			if(me.values) {
+				me.values.sub_con_rm_items.map((row,i) => {
+					if (!row.item_code || !row.rm_item_code || !row.warehouse || !row.qty || row.qty === 0) {
+						frappe.throw(__("Item Code, warehouse, quantity are required on row" + (i+1)));
+					}
+				})
+				me._make_rm_stock_entry(me.dialog.fields_dict.sub_con_rm_items.grid.get_selected_children())
+				me.dialog.hide()
+				}
+			});
+		}
+
+		me.dialog.get_close_btn().on('click', () => {
+			me.dialog.hide();
+		});
+
 	},
 
-	_make_stock_entry: function(item) {
+	_make_rm_stock_entry: function(rm_items) {
 		frappe.call({
-			method:"erpnext.buying.doctype.purchase_order.purchase_order.make_stock_entry",
+			method:"erpnext.buying.doctype.purchase_order.purchase_order.make_rm_stock_entry",
 			args: {
 				purchase_order: cur_frm.doc.name,
-				item_code: item
-			},
+				rm_items: rm_items
+			}
+			,
 			callback: function(r) {
 				var doclist = frappe.model.sync(r.message);
 				frappe.set_route("Form", doclist[0].doctype, doclist[0].name);
@@ -284,7 +394,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 53771d1..95aca6b 100644
--- a/erpnext/buying/doctype/purchase_order/purchase_order.json
+++ b/erpnext/buying/doctype/purchase_order/purchase_order.json
@@ -3133,6 +3133,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, 
diff --git a/erpnext/buying/doctype/purchase_order/purchase_order.py b/erpnext/buying/doctype/purchase_order/purchase_order.py
index 9e890f6..b9e7075 100644
--- a/erpnext/buying/doctype/purchase_order/purchase_order.py
+++ b/erpnext/buying/doctype/purchase_order/purchase_order.py
@@ -12,7 +12,7 @@
 from erpnext.stock.stock_balance import update_bin_qty, get_ordered_qty
 from frappe.desk.notifications import clear_doctype_notifications
 from erpnext.buying.utils import validate_for_items, check_for_closed_status
-
+from erpnext.stock.utils import get_bin
 
 form_grid_templates = {
 	"items": "templates/form_grid/item_grid.html"
@@ -80,8 +80,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:
@@ -192,6 +194,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)
 
@@ -204,6 +209,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)
@@ -217,6 +224,9 @@
 		if self.has_drop_ship_item():
 			self.update_delivered_qty_in_sales_order()
 
+		if self.is_subcontracted == "Yes":
+			self.update_reserved_qty_for_subcontract()
+
 		self.check_for_closed_status()
 
 		frappe.db.set(self,'status','Cancelled')
@@ -268,6 +278,12 @@
 			if item.delivered_by_supplier == 1:
 				item.received_qty = item.qty
 
+	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()
+
 def item_last_purchase_rate(name, conversion_rate, item_code, conversion_factor= 1.0):
 	"""get last purchase rate for an item"""
 	if cint(frappe.db.get_single_value("Buying Settings", "disable_fetch_last_purchase_rate")): return
@@ -388,23 +404,52 @@
 	return doc
 
 @frappe.whitelist()
-def make_stock_entry(purchase_order, item_code):
-	purchase_order = frappe.get_doc("Purchase Order", purchase_order)
+def make_rm_stock_entry(purchase_order, rm_items):
+	if isinstance(rm_items, basestring):
+		rm_items_list = json.loads(rm_items)
+	else:
+		frappe.throw(_("No Items available for transfer"))
 
-	stock_entry = frappe.new_doc("Stock Entry")
-	stock_entry.purpose = "Subcontract"
-	stock_entry.purchase_order = purchase_order.name
-	stock_entry.supplier = purchase_order.supplier
-	stock_entry.supplier_name = purchase_order.supplier_name
-	stock_entry.supplier_address = purchase_order.supplier_address
-	stock_entry.address_display = purchase_order.address_display
-	stock_entry.company = purchase_order.company
-	stock_entry.from_bom = 1
-	po_item = [d for d in purchase_order.items if d.item_code == item_code][0]
-	stock_entry.fg_completed_qty = po_item.qty
-	stock_entry.bom_no = po_item.bom
-	stock_entry.get_items()
-	return stock_entry.as_dict()
+	if rm_items_list:
+		fg_items = list(set(d["item_code"] for d in rm_items_list))
+	else:
+		frappe.throw(_("No Items selected for transfer"))
+
+	if purchase_order:
+		purchase_order = frappe.get_doc("Purchase Order", purchase_order)
+
+	if fg_items:
+		items = tuple(set(d["rm_item_code"] for d in rm_items_list))
+		item_wh = frappe._dict(frappe.db.sql("""
+			select item_code, description
+			from `tabItem` where name in ({0})
+		""".format(", ".join(["%s"] * len(items))), items))
+
+		stock_entry = frappe.new_doc("Stock Entry")
+		stock_entry.purpose = "Subcontract"
+		stock_entry.purchase_order = purchase_order.name
+		stock_entry.supplier = purchase_order.supplier
+		stock_entry.supplier_name = purchase_order.supplier_name
+		stock_entry.supplier_address = purchase_order.supplier_address
+		stock_entry.address_display = purchase_order.address_display
+		stock_entry.company = purchase_order.company
+		for item_code in fg_items:
+			for rm_item_data in rm_items_list:
+				if rm_item_data["item_code"] == item_code:
+					items_dict = {
+						rm_item_data["rm_item_code"]: {
+							"item_name":rm_item_data["item_name"],
+							"description":item_wh.get(rm_item_data["rm_item_code"]),
+							'qty':rm_item_data["qty"],
+							'from_warehouse':rm_item_data["warehouse"],
+							'stock_uom':rm_item_data["stock_uom"]
+						}
+					}
+					stock_entry.add_to_stock_entry_detail(items_dict)
+		return stock_entry.as_dict()
+	else:
+		frappe.throw(_("No Items selected for transfer"))
+	return purchase_order.name
 
 @frappe.whitelist()
 def update_status(status, name):
diff --git a/erpnext/buying/doctype/purchase_order/test_purchase_order.py b/erpnext/buying/doctype/purchase_order/test_purchase_order.py
index d31b230..86a1337 100644
--- a/erpnext/buying/doctype/purchase_order/test_purchase_order.py
+++ b/erpnext/buying/doctype/purchase_order/test_purchase_order.py
@@ -6,8 +6,9 @@
 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_rm_stock_entry as make_subcontract_transfer_entry)
+from erpnext.stock.doctype.stock_entry.test_stock_entry import make_stock_entry
+import json
 
 class TestPurchaseOrder(unittest.TestCase):
 	def test_make_purchase_receipt(self):
@@ -182,24 +183,129 @@
 		pi.insert()
 		self.assertTrue(pi.get('payment_schedule'))
 
-		
+	def test_reserved_qty_subcontract_po(self):
+		# 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)
+
+		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)
+
+		# Submit PO
+		po = create_purchase_order(item_code="_Test FG Item", is_subcontracted="Yes")
+
+		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
+		rm_item = [{"item_code":"_Test FG Item","rm_item_code":"_Test Item","item_name":"_Test Item",
+					"qty":6,"warehouse":"_Test Warehouse - _TC","rate":100,"amount":600,"stock_uom":"Nos"}]
+		rm_item_string = json.dumps(rm_item)
+		se = frappe.get_doc(make_subcontract_transfer_entry(po.name, rm_item_string))
+		se.to_warehouse = "_Test Warehouse 1 - _TC"
+		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")
@@ -224,6 +330,10 @@
 	if not args.do_not_save:
 		po.insert()
 		if not args.do_not_submit:
+			if po.is_subcontracted == "Yes":
+				supp_items = po.get("supplied_items")
+				for d in supp_items:
+					d.reserve_warehouse = args.warehouse or "_Test Warehouse - _TC"
 			po.submit()
 
 	return po
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 4a87037..7288bca 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
@@ -1,5 +1,6 @@
 {
  "allow_copy": 0, 
+ "allow_guest_to_view": 0, 
  "allow_import": 0, 
  "allow_rename": 0, 
  "beta": 0, 
@@ -10,68 +11,86 @@
  "editable_grid": 1, 
  "fields": [
   {
+   "allow_bulk_edit": 0, 
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
+   "columns": 2, 
    "fieldname": "main_item_code", 
-   "fieldtype": "Data", 
+   "fieldtype": "Link", 
    "hidden": 0, 
    "ignore_user_permissions": 0, 
    "ignore_xss_filter": 0, 
    "in_filter": 0, 
+   "in_global_search": 0, 
    "in_list_view": 1, 
+   "in_standard_filter": 0, 
    "label": "Item Code", 
    "length": 0, 
    "no_copy": 0, 
    "oldfieldname": "main_item_code", 
    "oldfieldtype": "Data", 
+   "options": "Item", 
    "permlevel": 0, 
    "print_hide": 0, 
    "print_hide_if_no_value": 0, 
    "read_only": 1, 
+   "remember_last_selected_value": 0, 
    "report_hide": 0, 
    "reqd": 0, 
    "search_index": 0, 
    "set_only_once": 0, 
+   "translatable": 0, 
    "unique": 0
   }, 
   {
+   "allow_bulk_edit": 0, 
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
+   "columns": 2, 
    "fieldname": "rm_item_code", 
-   "fieldtype": "Data", 
+   "fieldtype": "Link", 
    "hidden": 0, 
    "ignore_user_permissions": 0, 
    "ignore_xss_filter": 0, 
    "in_filter": 0, 
+   "in_global_search": 0, 
    "in_list_view": 1, 
+   "in_standard_filter": 0, 
    "label": "Raw Material Item Code", 
    "length": 0, 
    "no_copy": 0, 
    "oldfieldname": "rm_item_code", 
    "oldfieldtype": "Data", 
+   "options": "Item", 
    "permlevel": 0, 
    "print_hide": 0, 
    "print_hide_if_no_value": 0, 
    "read_only": 1, 
+   "remember_last_selected_value": 0, 
    "report_hide": 0, 
    "reqd": 0, 
    "search_index": 0, 
    "set_only_once": 0, 
+   "translatable": 0, 
    "unique": 0
   }, 
   {
+   "allow_bulk_edit": 0, 
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
+   "columns": 2, 
    "fieldname": "required_qty", 
    "fieldtype": "Float", 
    "hidden": 0, 
    "ignore_user_permissions": 0, 
    "ignore_xss_filter": 0, 
    "in_filter": 0, 
+   "in_global_search": 0, 
    "in_list_view": 1, 
+   "in_standard_filter": 0, 
    "label": "Supplied Qty", 
    "length": 0, 
    "no_copy": 0, 
@@ -81,23 +100,29 @@
    "print_hide": 0, 
    "print_hide_if_no_value": 0, 
    "read_only": 1, 
+   "remember_last_selected_value": 0, 
    "report_hide": 0, 
    "reqd": 0, 
    "search_index": 0, 
    "set_only_once": 0, 
+   "translatable": 0, 
    "unique": 0
   }, 
   {
+   "allow_bulk_edit": 0, 
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
+   "columns": 2, 
    "fieldname": "rate", 
    "fieldtype": "Currency", 
    "hidden": 0, 
    "ignore_user_permissions": 0, 
    "ignore_xss_filter": 0, 
    "in_filter": 0, 
+   "in_global_search": 0, 
    "in_list_view": 1, 
+   "in_standard_filter": 0, 
    "label": "Rate", 
    "length": 0, 
    "no_copy": 0, 
@@ -108,23 +133,29 @@
    "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, 
+   "translatable": 0, 
    "unique": 0
   }, 
   {
+   "allow_bulk_edit": 0, 
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
+   "columns": 0, 
    "fieldname": "amount", 
    "fieldtype": "Currency", 
    "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": "Amount", 
    "length": 0, 
    "no_copy": 0, 
@@ -135,23 +166,59 @@
    "print_hide": 0, 
    "print_hide_if_no_value": 0, 
    "read_only": 1, 
+   "remember_last_selected_value": 0, 
    "report_hide": 0, 
    "reqd": 0, 
    "search_index": 0, 
    "set_only_once": 0, 
+   "translatable": 0, 
    "unique": 0
   }, 
   {
+   "allow_bulk_edit": 0, 
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
+   "columns": 0, 
+   "fieldname": "column_break_6", 
+   "fieldtype": "Column 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, 
+   "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, 
+   "translatable": 0, 
+   "unique": 0
+  }, 
+  {
+   "allow_bulk_edit": 0, 
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "columns": 0, 
    "fieldname": "bom_detail_no", 
    "fieldtype": "Data", 
    "hidden": 0, 
    "ignore_user_permissions": 0, 
    "ignore_xss_filter": 0, 
    "in_filter": 0, 
-   "in_list_view": 1, 
+   "in_global_search": 0, 
+   "in_list_view": 0, 
+   "in_standard_filter": 0, 
    "label": "BOM Detail No", 
    "length": 0, 
    "no_copy": 0, 
@@ -161,23 +228,29 @@
    "print_hide": 0, 
    "print_hide_if_no_value": 0, 
    "read_only": 1, 
+   "remember_last_selected_value": 0, 
    "report_hide": 0, 
    "reqd": 0, 
    "search_index": 0, 
    "set_only_once": 0, 
+   "translatable": 0, 
    "unique": 0
   }, 
   {
+   "allow_bulk_edit": 0, 
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
+   "columns": 0, 
    "fieldname": "reference_name", 
    "fieldtype": "Data", 
    "hidden": 0, 
    "ignore_user_permissions": 0, 
    "ignore_xss_filter": 0, 
    "in_filter": 0, 
-   "in_list_view": 1, 
+   "in_global_search": 0, 
+   "in_list_view": 0, 
+   "in_standard_filter": 0, 
    "label": "Reference Name", 
    "length": 0, 
    "no_copy": 0, 
@@ -187,23 +260,29 @@
    "print_hide": 0, 
    "print_hide_if_no_value": 0, 
    "read_only": 1, 
+   "remember_last_selected_value": 0, 
    "report_hide": 0, 
    "reqd": 0, 
    "search_index": 0, 
    "set_only_once": 0, 
+   "translatable": 0, 
    "unique": 0
   }, 
   {
+   "allow_bulk_edit": 0, 
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
+   "columns": 0, 
    "fieldname": "conversion_factor", 
    "fieldtype": "Float", 
    "hidden": 1, 
    "ignore_user_permissions": 0, 
    "ignore_xss_filter": 0, 
    "in_filter": 0, 
+   "in_global_search": 0, 
    "in_list_view": 0, 
+   "in_standard_filter": 0, 
    "label": "Conversion Factor", 
    "length": 0, 
    "no_copy": 0, 
@@ -213,23 +292,29 @@
    "print_hide": 0, 
    "print_hide_if_no_value": 0, 
    "read_only": 1, 
+   "remember_last_selected_value": 0, 
    "report_hide": 0, 
    "reqd": 0, 
    "search_index": 0, 
    "set_only_once": 0, 
+   "translatable": 0, 
    "unique": 0
   }, 
   {
+   "allow_bulk_edit": 0, 
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
+   "columns": 0, 
    "fieldname": "stock_uom", 
    "fieldtype": "Link", 
    "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": "Stock Uom", 
    "length": 0, 
    "no_copy": 0, 
@@ -240,24 +325,58 @@
    "print_hide": 0, 
    "print_hide_if_no_value": 0, 
    "read_only": 1, 
+   "remember_last_selected_value": 0, 
    "report_hide": 0, 
    "reqd": 0, 
    "search_index": 0, 
    "set_only_once": 0, 
+   "translatable": 0, 
+   "unique": 0
+  }, 
+  {
+   "allow_bulk_edit": 0, 
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "columns": 2, 
+   "fieldname": "reserve_warehouse", 
+   "fieldtype": "Link", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_global_search": 0, 
+   "in_list_view": 1, 
+   "in_standard_filter": 0, 
+   "label": "Reserve Warehouse", 
+   "length": 0, 
+   "no_copy": 0, 
+   "options": "Warehouse", 
+   "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, 
+   "translatable": 0, 
    "unique": 0
   }
  ], 
+ "has_web_view": 0, 
  "hide_heading": 0, 
  "hide_toolbar": 1, 
  "idx": 1, 
  "image_view": 0, 
  "in_create": 0, 
- "in_dialog": 0, 
  "is_submittable": 0, 
  "issingle": 0, 
  "istable": 1, 
  "max_attachments": 0, 
- "modified": "2016-07-11 03:28:05.533063", 
+ "modified": "2018-03-13 12:37:57.150914", 
  "modified_by": "Administrator", 
  "module": "Buying", 
  "name": "Purchase Order Item Supplied", 
@@ -266,5 +385,7 @@
  "quick_entry": 0, 
  "read_only": 0, 
  "read_only_onload": 0, 
+ "show_name_in_global_search": 0, 
+ "track_changes": 0, 
  "track_seen": 0
 }
\ No newline at end of file
diff --git a/erpnext/buying/doctype/purchase_receipt_item_supplied/purchase_receipt_item_supplied.json b/erpnext/buying/doctype/purchase_receipt_item_supplied/purchase_receipt_item_supplied.json
index 85130a1..e8ec062 100644
--- a/erpnext/buying/doctype/purchase_receipt_item_supplied/purchase_receipt_item_supplied.json
+++ b/erpnext/buying/doctype/purchase_receipt_item_supplied/purchase_receipt_item_supplied.json
@@ -1,5 +1,6 @@
 {
  "allow_copy": 0, 
+ "allow_guest_to_view": 0, 
  "allow_import": 0, 
  "allow_rename": 0, 
  "beta": 0, 
@@ -11,12 +12,13 @@
  "engine": "InnoDB", 
  "fields": [
   {
+   "allow_bulk_edit": 0, 
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
    "columns": 0, 
    "fieldname": "main_item_code", 
-   "fieldtype": "Data", 
+   "fieldtype": "Link", 
    "hidden": 0, 
    "ignore_user_permissions": 0, 
    "ignore_xss_filter": 0, 
@@ -29,6 +31,7 @@
    "no_copy": 0, 
    "oldfieldname": "main_item_code", 
    "oldfieldtype": "Data", 
+   "options": "Item", 
    "permlevel": 0, 
    "print_hide": 0, 
    "print_hide_if_no_value": 0, 
@@ -38,15 +41,17 @@
    "reqd": 0, 
    "search_index": 0, 
    "set_only_once": 0, 
+   "translatable": 0, 
    "unique": 0
   }, 
   {
+   "allow_bulk_edit": 0, 
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
    "columns": 0, 
    "fieldname": "rm_item_code", 
-   "fieldtype": "Data", 
+   "fieldtype": "Link", 
    "hidden": 0, 
    "ignore_user_permissions": 0, 
    "ignore_xss_filter": 0, 
@@ -59,6 +64,7 @@
    "no_copy": 0, 
    "oldfieldname": "rm_item_code", 
    "oldfieldtype": "Data", 
+   "options": "Item", 
    "permlevel": 0, 
    "print_hide": 0, 
    "print_hide_if_no_value": 0, 
@@ -68,9 +74,11 @@
    "reqd": 0, 
    "search_index": 0, 
    "set_only_once": 0, 
+   "translatable": 0, 
    "unique": 0
   }, 
   {
+   "allow_bulk_edit": 0, 
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
@@ -99,10 +107,12 @@
    "reqd": 0, 
    "search_index": 0, 
    "set_only_once": 0, 
+   "translatable": 0, 
    "unique": 0, 
    "width": "300px"
   }, 
   {
+   "allow_bulk_edit": 0, 
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
@@ -129,9 +139,11 @@
    "reqd": 0, 
    "search_index": 0, 
    "set_only_once": 0, 
+   "translatable": 0, 
    "unique": 0
   }, 
   {
+   "allow_bulk_edit": 0, 
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
@@ -157,9 +169,11 @@
    "reqd": 0, 
    "search_index": 0, 
    "set_only_once": 0, 
+   "translatable": 0, 
    "unique": 0
   }, 
   {
+   "allow_bulk_edit": 0, 
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
@@ -184,9 +198,11 @@
    "reqd": 0, 
    "search_index": 0, 
    "set_only_once": 0, 
+   "translatable": 0, 
    "unique": 0
   }, 
   {
+   "allow_bulk_edit": 0, 
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
@@ -214,9 +230,11 @@
    "reqd": 0, 
    "search_index": 0, 
    "set_only_once": 0, 
+   "translatable": 0, 
    "unique": 0
   }, 
   {
+   "allow_bulk_edit": 0, 
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
@@ -244,9 +262,11 @@
    "reqd": 1, 
    "search_index": 0, 
    "set_only_once": 0, 
+   "translatable": 0, 
    "unique": 0
   }, 
   {
+   "allow_bulk_edit": 0, 
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
@@ -275,9 +295,11 @@
    "reqd": 0, 
    "search_index": 0, 
    "set_only_once": 0, 
+   "translatable": 0, 
    "unique": 0
   }, 
   {
+   "allow_bulk_edit": 0, 
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
@@ -306,9 +328,11 @@
    "reqd": 0, 
    "search_index": 0, 
    "set_only_once": 0, 
+   "translatable": 0, 
    "unique": 0
   }, 
   {
+   "allow_bulk_edit": 0, 
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
@@ -337,9 +361,11 @@
    "reqd": 0, 
    "search_index": 0, 
    "set_only_once": 0, 
+   "translatable": 0, 
    "unique": 0
   }, 
   {
+   "allow_bulk_edit": 0, 
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
@@ -367,9 +393,11 @@
    "reqd": 0, 
    "search_index": 0, 
    "set_only_once": 0, 
+   "translatable": 0, 
    "unique": 0
   }, 
   {
+   "allow_bulk_edit": 0, 
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
@@ -397,9 +425,11 @@
    "reqd": 0, 
    "search_index": 0, 
    "set_only_once": 0, 
+   "translatable": 0, 
    "unique": 0
   }, 
   {
+   "allow_bulk_edit": 0, 
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
@@ -427,9 +457,11 @@
    "reqd": 0, 
    "search_index": 0, 
    "set_only_once": 0, 
+   "translatable": 0, 
    "unique": 0
   }, 
   {
+   "allow_bulk_edit": 0, 
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
@@ -457,20 +489,21 @@
    "reqd": 0, 
    "search_index": 0, 
    "set_only_once": 0, 
+   "translatable": 0, 
    "unique": 0
   }
  ], 
+ "has_web_view": 0, 
  "hide_heading": 0, 
  "hide_toolbar": 0, 
  "idx": 1, 
  "image_view": 0, 
  "in_create": 0, 
- "in_dialog": 0, 
  "is_submittable": 0, 
  "issingle": 0, 
  "istable": 1, 
  "max_attachments": 0, 
- "modified": "2017-02-17 16:43:21.668443", 
+ "modified": "2018-03-13 12:38:40.807453", 
  "modified_by": "Administrator", 
  "module": "Buying", 
  "name": "Purchase Receipt Item Supplied", 
diff --git a/erpnext/controllers/buying_controller.py b/erpnext/controllers/buying_controller.py
index 63e55ee..4b7b43c 100644
--- a/erpnext/controllers/buying_controller.py
+++ b/erpnext/controllers/buying_controller.py
@@ -163,6 +163,11 @@
 				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))
 
+			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"):
 				if item.bom:
@@ -192,8 +197,16 @@
 	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:
+			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):
@@ -213,6 +226,8 @@
 			rm.rm_item_code = bom_item.item_code
 			rm.stock_uom = bom_item.stock_uom
 			rm.required_qty = required_qty
+			if self.doctype == "Purchase Order" and not rm.reserve_warehouse:
+				rm.reserve_warehouse = reserve_warehouse
 
 			rm.conversion_factor = item.conversion_factor
 
@@ -264,7 +279,7 @@
 	def get_items_from_bom(self, item_code, bom):
 		bom_items = frappe.db.sql("""select t2.item_code,
 			t2.stock_qty / ifnull(t1.quantity, 1) as qty_consumed_per_unit,
-			t2.rate, t2.stock_uom, t2.name, t2.description
+			t2.rate, t2.stock_uom, t2.name, t2.description, t2.source_warehouse
 			from `tabBOM` t1, `tabBOM Item` t2, tabItem t3
 			where t2.parent = t1.name and t1.item = %s
 			and t1.docstatus = 1 and t1.is_active = 1 and t1.name = %s
@@ -339,7 +354,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()
@@ -381,7 +396,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" \
@@ -400,6 +415,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/controllers/sales_and_purchase_return.py b/erpnext/controllers/sales_and_purchase_return.py
index 4b8bbee..ab189cf 100644
--- a/erpnext/controllers/sales_and_purchase_return.py
+++ b/erpnext/controllers/sales_and_purchase_return.py
@@ -239,6 +239,7 @@
 			target_doc.received_qty = -1* source_doc.received_qty
 			target_doc.rejected_qty = -1* source_doc.rejected_qty
 			target_doc.qty = -1* source_doc.qty
+			target_doc.stock_qty = -1 * source_doc.stock_qty
 			target_doc.purchase_order = source_doc.purchase_order
 			target_doc.purchase_order_item = source_doc.purchase_order_item
 			target_doc.rejected_warehouse = source_doc.rejected_warehouse
@@ -246,6 +247,7 @@
 			target_doc.received_qty = -1* source_doc.received_qty
 			target_doc.rejected_qty = -1* source_doc.rejected_qty
 			target_doc.qty = -1* source_doc.qty
+			target_doc.stock_qty = -1 * source_doc.stock_qty
 			target_doc.purchase_order = source_doc.purchase_order
 			target_doc.purchase_receipt = source_doc.purchase_receipt
 			target_doc.rejected_warehouse = source_doc.rejected_warehouse
diff --git a/erpnext/controllers/selling_controller.py b/erpnext/controllers/selling_controller.py
index 6b18b82..606cc90 100644
--- a/erpnext/controllers/selling_controller.py
+++ b/erpnext/controllers/selling_controller.py
@@ -38,6 +38,7 @@
 		self.validate_max_discount()
 		self.validate_selling_price()
 		self.set_qty_as_per_stock_uom()
+		self.set_po_nos()
 		check_active_sales_items(self)
 
 	def set_missing_values(self, for_validate=False):
@@ -326,9 +327,16 @@
 							"actual_qty": -1*flt(d.qty),
 							"incoming_rate": return_rate
 						}))
-
 		self.make_sl_entries(sl_entries)
 
+	def set_po_nos(self):
+		if self.doctype in ("Delivery Note", "Sales Invoice"):
+			ref_fieldname = "against_sales_order" if self.doctype == "Delivery Note" else "sales_order"
+			sales_orders = list(set([d.get(ref_fieldname) for d in self.items if d.get(ref_fieldname)]))
+			if sales_orders:
+				po_nos = frappe.get_all('Sales Order', 'po_no', filters = {'name': ('in', sales_orders)})
+				self.po_no = ', '.join(list(set([d.po_no for d in po_nos if d.po_no])))
+
 def check_active_sales_items(obj):
 	for d in obj.get("items"):
 		if d.item_code:
diff --git a/erpnext/controllers/status_updater.py b/erpnext/controllers/status_updater.py
index b46c752..df0fec8 100644
--- a/erpnext/controllers/status_updater.py
+++ b/erpnext/controllers/status_updater.py
@@ -156,6 +156,9 @@
 
 			# get unique transactions to update
 			for d in self.get_all_children():
+				if hasattr(d, 'qty') and d.qty < 0 and not self.get('is_return'):
+					frappe.throw(_("For an item {0}, quantity must be positive number").format(d.item_code))
+
 				if d.doctype == args['source_dt'] and d.get(args["join_field"]):
 					args['name'] = d.get(args['join_field'])
 
diff --git a/erpnext/healthcare/doctype/physician/physician.json b/erpnext/healthcare/doctype/physician/physician.json
index 3edad0b..a4d2bd6 100644
--- a/erpnext/healthcare/doctype/physician/physician.json
+++ b/erpnext/healthcare/doctype/physician/physician.json
@@ -40,6 +40,7 @@
    "reqd": 1, 
    "search_index": 0, 
    "set_only_once": 0, 
+   "translatable": 0, 
    "unique": 0
   }, 
   {
@@ -70,6 +71,7 @@
    "reqd": 0, 
    "search_index": 0, 
    "set_only_once": 0, 
+   "translatable": 0, 
    "unique": 0
   }, 
   {
@@ -100,6 +102,7 @@
    "reqd": 0, 
    "search_index": 0, 
    "set_only_once": 0, 
+   "translatable": 0, 
    "unique": 0
   }, 
   {
@@ -126,10 +129,11 @@
    "print_hide_if_no_value": 0, 
    "read_only": 0, 
    "remember_last_selected_value": 0, 
-   "report_hide": 1, 
+   "report_hide": 0, 
    "reqd": 0, 
    "search_index": 0, 
    "set_only_once": 0, 
+   "translatable": 0, 
    "unique": 0
   }, 
   {
@@ -161,6 +165,7 @@
    "reqd": 0, 
    "search_index": 0, 
    "set_only_once": 0, 
+   "translatable": 0, 
    "unique": 0
   }, 
   {
@@ -192,6 +197,7 @@
    "reqd": 0, 
    "search_index": 0, 
    "set_only_once": 0, 
+   "translatable": 0, 
    "unique": 0
   }, 
   {
@@ -223,6 +229,7 @@
    "reqd": 0, 
    "search_index": 0, 
    "set_only_once": 0, 
+   "translatable": 0, 
    "unique": 0
   }, 
   {
@@ -254,6 +261,7 @@
    "reqd": 0, 
    "search_index": 0, 
    "set_only_once": 0, 
+   "translatable": 0, 
    "unique": 0
   }, 
   {
@@ -283,6 +291,7 @@
    "reqd": 0, 
    "search_index": 0, 
    "set_only_once": 0, 
+   "translatable": 0, 
    "unique": 0
   }, 
   {
@@ -313,6 +322,7 @@
    "reqd": 0, 
    "search_index": 0, 
    "set_only_once": 0, 
+   "translatable": 0, 
    "unique": 0
   }, 
   {
@@ -343,6 +353,7 @@
    "reqd": 0, 
    "search_index": 0, 
    "set_only_once": 0, 
+   "translatable": 0, 
    "unique": 0
   }, 
   {
@@ -373,6 +384,7 @@
    "reqd": 0, 
    "search_index": 0, 
    "set_only_once": 0, 
+   "translatable": 0, 
    "unique": 0
   }, 
   {
@@ -403,6 +415,7 @@
    "reqd": 0, 
    "search_index": 0, 
    "set_only_once": 0, 
+   "translatable": 0, 
    "unique": 0
   }, 
   {
@@ -433,6 +446,7 @@
    "reqd": 0, 
    "search_index": 0, 
    "set_only_once": 0, 
+   "translatable": 0, 
    "unique": 0
   }, 
   {
@@ -464,6 +478,7 @@
    "reqd": 0, 
    "search_index": 0, 
    "set_only_once": 0, 
+   "translatable": 0, 
    "unique": 0
   }, 
   {
@@ -493,6 +508,7 @@
    "reqd": 0, 
    "search_index": 0, 
    "set_only_once": 0, 
+   "translatable": 0, 
    "unique": 0
   }, 
   {
@@ -524,6 +540,7 @@
    "reqd": 0, 
    "search_index": 0, 
    "set_only_once": 0, 
+   "translatable": 0, 
    "unique": 0
   }, 
   {
@@ -554,6 +571,7 @@
    "reqd": 0, 
    "search_index": 0, 
    "set_only_once": 0, 
+   "translatable": 0, 
    "unique": 0
   }, 
   {
@@ -585,6 +603,7 @@
    "reqd": 0, 
    "search_index": 0, 
    "set_only_once": 0, 
+   "translatable": 0, 
    "unique": 0
   }, 
   {
@@ -615,6 +634,7 @@
    "reqd": 0, 
    "search_index": 0, 
    "set_only_once": 0, 
+   "translatable": 0, 
    "unique": 0
   }, 
   {
@@ -645,6 +665,7 @@
    "reqd": 0, 
    "search_index": 0, 
    "set_only_once": 0, 
+   "translatable": 0, 
    "unique": 0
   }, 
   {
@@ -674,6 +695,7 @@
    "reqd": 0, 
    "search_index": 0, 
    "set_only_once": 0, 
+   "translatable": 0, 
    "unique": 0
   }, 
   {
@@ -704,6 +726,7 @@
    "reqd": 0, 
    "search_index": 0, 
    "set_only_once": 0, 
+   "translatable": 0, 
    "unique": 0
   }, 
   {
@@ -734,6 +757,7 @@
    "reqd": 0, 
    "search_index": 0, 
    "set_only_once": 0, 
+   "translatable": 0, 
    "unique": 0
   }, 
   {
@@ -765,6 +789,7 @@
    "reqd": 0, 
    "search_index": 0, 
    "set_only_once": 0, 
+   "translatable": 0, 
    "unique": 0
   }, 
   {
@@ -796,6 +821,7 @@
    "reqd": 0, 
    "search_index": 0, 
    "set_only_once": 0, 
+   "translatable": 0, 
    "unique": 0
   }
  ], 
@@ -810,7 +836,7 @@
  "issingle": 0, 
  "istable": 0, 
  "max_attachments": 0, 
- "modified": "2017-10-05 16:08:24.624644", 
+ "modified": "2018-03-09 07:05:24.984224", 
  "modified_by": "Administrator", 
  "module": "Healthcare", 
  "name": "Physician", 
diff --git a/erpnext/manufacturing/doctype/bom/bom.py b/erpnext/manufacturing/doctype/bom/bom.py
index 5e1e52a..862b4ee 100644
--- a/erpnext/manufacturing/doctype/bom/bom.py
+++ b/erpnext/manufacturing/doctype/bom/bom.py
@@ -597,9 +597,16 @@
 	if bom.docstatus != 1:
 		if not getattr(frappe.flags, "in_test", False):
 			frappe.throw(_("BOM {0} must be submitted").format(bom_no))
-	if item and not (bom.item.lower() == item.lower() or \
-		bom.item.lower() == cstr(frappe.db.get_value("Item", item, "variant_of")).lower()):
-		frappe.throw(_("BOM {0} does not belong to Item {1}").format(bom_no, item))
+	if item:
+		rm_item_exists = False
+		for d in bom.items:
+			if (d.item_code.lower() == item.lower()):
+				rm_item_exists = True
+		if bom.item.lower() == item.lower() or \
+			bom.item.lower() == cstr(frappe.db.get_value("Item", item, "variant_of")).lower():
+ 				rm_item_exists = True
+		if not rm_item_exists:
+			frappe.throw(_("BOM {0} does not belong to Item {1}").format(bom_no, item))
 
 @frappe.whitelist()
 def get_children(doctype, parent=None, is_root=False, **filters):
diff --git a/erpnext/patches.txt b/erpnext/patches.txt
index dd707da..d06b405 100644
--- a/erpnext/patches.txt
+++ b/erpnext/patches.txt
@@ -493,4 +493,5 @@
 erpnext.patches.v10_0.update_status_for_multiple_source_in_po
 erpnext.patches.v10_0.set_auto_created_serial_no_in_stock_entry
 erpnext.patches.v10_0.update_territory_and_customer_group
-erpnext.patches.v10_0.update_warehouse_address_details
\ No newline at end of file
+erpnext.patches.v10_0.update_warehouse_address_details
+erpnext.patches.v10_0.update_reserved_qty_for_purchase_order
diff --git a/erpnext/patches/v10_0/update_reserved_qty_for_purchase_order.py b/erpnext/patches/v10_0/update_reserved_qty_for_purchase_order.py
new file mode 100644
index 0000000..b0df918
--- /dev/null
+++ b/erpnext/patches/v10_0/update_reserved_qty_for_purchase_order.py
@@ -0,0 +1,52 @@
+import frappe
+from erpnext.stock.utils import get_bin
+
+def execute():
+	po_item = list(frappe.db.sql(("""
+		select distinct po.name as poname, poitem.rm_item_code as rm_item_code, po.company
+		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))
+	if not po_item:
+		return
+
+	frappe.reload_doc("stock", "doctype", "bin")
+	frappe.reload_doc("buying", "doctype", "purchase_order_item_supplied")
+	company_warehouse = frappe._dict(frappe.db.sql("""select company, min(name) from `tabWarehouse`
+		where is_group = 0 group by company"""))
+
+	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 = get_warehouse(item.rm_item_code, item.company, company_warehouse, item_wh)
+		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:
+		try:
+			stock_bin = get_bin(d["rm_item_code"], d["reserve_warehouse"])
+			stock_bin.update_reserved_qty_for_sub_contracting()
+		except:
+			pass
+
+def get_warehouse(item_code, company, company_warehouse, item_wh):
+	reserve_warehouse = item_wh.get(item_code)
+	if frappe.db.get_value("Warehouse", reserve_warehouse, "company") != company:
+		reserve_warehouse = None
+	if not reserve_warehouse:
+		reserve_warehouse = company_warehouse.get(company)
+	return reserve_warehouse
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/public/js/shopping_cart.js b/erpnext/public/js/shopping_cart.js
index 0a3e0af..7755141 100644
--- a/erpnext/public/js/shopping_cart.js
+++ b/erpnext/public/js/shopping_cart.js
@@ -64,7 +64,7 @@
 	},
 
 	set_cart_count: function() {
-		var cart_count = getCookie("cart_count");
+		var cart_count = frappe.get_cookie("cart_count");
 		if(frappe.session.user==="Guest") {
 			cart_count = 0;
 		}
diff --git a/erpnext/selling/doctype/sales_order/sales_order.js b/erpnext/selling/doctype/sales_order/sales_order.js
index 03e519a..0657f9f 100644
--- a/erpnext/selling/doctype/sales_order/sales_order.js
+++ b/erpnext/selling/doctype/sales_order/sales_order.js
@@ -54,7 +54,7 @@
 			row.delivery_date = frm.doc.delivery_date;
 			refresh_field("delivery_date", cdn, "items");
 		} else {
-			this.frm.script_manager.copy_from_first_row("items", row, ["delivery_date"]);
+			frm.script_manager.copy_from_first_row("items", row, ["delivery_date"]);
 		}
 	},
 	delivery_date: function(frm, cdt, cdn) {
diff --git a/erpnext/selling/doctype/sales_order/sales_order.py b/erpnext/selling/doctype/sales_order/sales_order.py
index 2f41307..9e30939 100644
--- a/erpnext/selling/doctype/sales_order/sales_order.py
+++ b/erpnext/selling/doctype/sales_order/sales_order.py
@@ -5,7 +5,7 @@
 import frappe
 import json
 import frappe.utils
-from frappe.utils import cstr, flt, getdate, comma_and, cint, nowdate, add_days
+from frappe.utils import cstr, flt, getdate, comma_and, cint
 from frappe import _
 from frappe.model.utils import get_fetch_values
 from frappe.model.mapper import get_mapped_doc
@@ -477,13 +477,9 @@
 @frappe.whitelist()
 def make_delivery_note(source_name, target_doc=None):
 	def set_missing_values(source, target):
-		so = [d.against_sales_order for d in target.items]
-		if so:
-			po_no_list = frappe.get_all('Sales Order', 'po_no', filters = {'name': ('in', so)})
-			target.po_no = ', '.join(d.po_no for d in po_no_list if d.po_no)
-
 		target.ignore_pricing_rule = 1
 		target.run_method("set_missing_values")
+		target.run_method("set_po_nos")
 		target.run_method("calculate_taxes_and_totals")
 
 		# set company address
@@ -544,6 +540,7 @@
 		target.ignore_pricing_rule = 1
 		target.flags.ignore_permissions = True
 		target.run_method("set_missing_values")
+		target.run_method("set_po_nos")
 		target.run_method("calculate_taxes_and_totals")
 
 		# set company address
diff --git a/erpnext/stock/dashboard/item_dashboard.js b/erpnext/stock/dashboard/item_dashboard.js
index 4a52526..2748436 100644
--- a/erpnext/stock/dashboard/item_dashboard.js
+++ b/erpnext/stock/dashboard/item_dashboard.js
@@ -90,7 +90,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/batch/batch.json b/erpnext/stock/doctype/batch/batch.json
index b17e106..2fb4b12 100644
--- a/erpnext/stock/doctype/batch/batch.json
+++ b/erpnext/stock/doctype/batch/batch.json
@@ -3,7 +3,7 @@
  "allow_guest_to_view": 0,
  "allow_import": 1,
  "allow_rename": 0,
- "autoname": "",
+ "autoname": "field:batch_id",
  "beta": 0,
  "creation": "2013-03-05 14:50:38",
  "custom": 0,
@@ -27,7 +27,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": "Batch ID",
    "length": 0,
@@ -58,7 +58,7 @@
    "ignore_xss_filter": 0,
    "in_filter": 0,
    "in_global_search": 0,
-   "in_list_view": 0,
+   "in_list_view": 1,
    "in_standard_filter": 1,
    "label": "Item",
    "length": 0,
@@ -425,7 +425,7 @@
  "issingle": 0,
  "istable": 0,
  "max_attachments": 5,
- "modified": "2017-05-21 21:00:11.096038",
+ "modified": "2018-03-12 16:37:20.144750",
  "modified_by": "Administrator",
  "module": "Stock",
  "name": "Batch",
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 f2c214d..430d9fb 100644
--- a/erpnext/stock/doctype/bin/bin.py
+++ b/erpnext/stock/doctype/bin/bin.py
@@ -61,7 +61,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("""
@@ -90,6 +90,42 @@
 		self.db_set('reserved_qty_for_production', flt(self.reserved_qty_for_production))
 		self.db_set('projected_qty', self.projected_qty)
 
+	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)
+			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(transfer_qty),0)
+			from
+				`tabStock Entry` se, `tabStock Entry Detail` sed, `tabPurchase Order` po
+			where
+				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 po.docstatus = 1
+				and po.is_subcontracted = 'Yes'
+				and po.status != 'Closed'
+				and po.per_received < 100
+		""", (self.item_code))[0][0]
+
+		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 on_doctype_update():
 	frappe.db.add_index("Bin", ["item_code", "warehouse"])
diff --git a/erpnext/stock/doctype/delivery_note/delivery_note.json b/erpnext/stock/doctype/delivery_note/delivery_note.json
index f126b58..9c1373b 100644
--- a/erpnext/stock/doctype/delivery_note/delivery_note.json
+++ b/erpnext/stock/doctype/delivery_note/delivery_note.json
@@ -493,7 +493,7 @@
   }, 
   {
    "allow_bulk_edit": 0, 
-   "allow_on_submit": 0, 
+   "allow_on_submit": 1, 
    "bold": 0, 
    "collapsible": 0, 
    "columns": 0, 
@@ -508,14 +508,14 @@
    "in_standard_filter": 0, 
    "label": "Customer's Purchase Order No", 
    "length": 0, 
-   "no_copy": 0, 
+   "no_copy": 1, 
    "oldfieldname": "po_no", 
    "oldfieldtype": "Data", 
    "permlevel": 0, 
    "print_hide": 1, 
    "print_hide_if_no_value": 0, 
    "print_width": "100px", 
-   "read_only": 1, 
+   "read_only": 0, 
    "remember_last_selected_value": 0, 
    "report_hide": 0, 
    "reqd": 0, 
@@ -3701,7 +3701,7 @@
  "istable": 0, 
  "max_attachments": 0, 
  "menu_index": 0, 
- "modified": "2018-01-12 15:27:44.471335", 
+ "modified": "2018-03-13 15:35:02.234116", 
  "modified_by": "Administrator", 
  "module": "Stock", 
  "name": "Delivery Note", 
diff --git a/erpnext/stock/doctype/delivery_note/delivery_note.py b/erpnext/stock/doctype/delivery_note/delivery_note.py
index 65f384f..07c105c 100644
--- a/erpnext/stock/doctype/delivery_note/delivery_note.py
+++ b/erpnext/stock/doctype/delivery_note/delivery_note.py
@@ -387,6 +387,7 @@
 		target.is_pos = 0
 		target.ignore_pricing_rule = 1
 		target.run_method("set_missing_values")
+		target.run_method("set_po_nos")
 
 		if len(target.get("items")) == 0:
 			frappe.throw(_("All these items have already been invoiced"))
diff --git a/erpnext/stock/doctype/purchase_receipt/purchase_receipt.py b/erpnext/stock/doctype/purchase_receipt/purchase_receipt.py
index 29f3553..2a962cc 100644
--- a/erpnext/stock/doctype/purchase_receipt/purchase_receipt.py
+++ b/erpnext/stock/doctype/purchase_receipt/purchase_receipt.py
@@ -122,7 +122,8 @@
 			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 7d5af5f..5aeba7c 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, get_batch_qty
 from erpnext.manufacturing.doctype.bom.bom import validate_bom_no
+from erpnext.stock.utils import get_bin
 import json
 
 class IncorrectValuationRateError(frappe.ValidationError): pass
@@ -63,17 +64,22 @@
 		self.calculate_rate_and_amount(update_finished_item_rate=False)
 
 	def on_submit(self):
+
 		self.update_stock_ledger()
 
 		from erpnext.stock.doctype.serial_no.serial_no import update_serial_nos_after_submit
 		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):
 		self.update_stock_ledger()
 		self.update_production_order()
+		if self.purchase_order and self.purpose == "Subcontract":
+			self.update_purchase_order_supplied_items()
 		self.make_gl_entries_on_cancel()
 
 	def validate_purpose(self):
@@ -403,7 +409,7 @@
 		"""validation: finished good quantity should be same as manufacturing quantity"""
 		items_with_target_warehouse = []
 		for d in self.get('items'):
-			if d.bom_no and flt(d.transfer_qty) != flt(self.fg_completed_qty) and (d.t_warehouse != getattr(self, "pro_doc", frappe._dict()).scrap_warehouse):
+			if self.purpose != "Subcontract" and d.bom_no and flt(d.transfer_qty) != flt(self.fg_completed_qty) and (d.t_warehouse != getattr(self, "pro_doc", frappe._dict()).scrap_warehouse):
 				frappe.throw(_("Quantity in row {0} ({1}) must be same as manufactured quantity {2}"). \
 					format(d.idx, d.transfer_qty, self.fg_completed_qty))
 
@@ -582,19 +588,32 @@
 						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))
 					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
-
+						#Get Reserve Warehouse from PO
+						if self.purchase_order and self.purpose=="Subcontract":
+							item["from_warehouse"] = item_wh.get(item.item_code)
 						item["to_warehouse"] = self.to_warehouse if self.purpose=="Subcontract" else ""
 
 					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":
@@ -782,7 +801,7 @@
 	def add_to_stock_entry_detail(self, item_dict, bom_no=None):
 		expense_account, cost_center = frappe.db.get_values("Company", self.company, \
 			["default_expense_account", "cost_center"])[0]
-				
+
 		for d in item_dict:
 			stock_uom = item_dict[d].get("stock_uom") or frappe.db.get_value("Item", d, "stock_uom")
 			
@@ -833,7 +852,20 @@
 						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):
+		#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):
diff --git a/erpnext/stock/doctype/stock_entry/test_stock_entry.py b/erpnext/stock/doctype/stock_entry/test_stock_entry.py
index b590822..a5814f7 100644
--- a/erpnext/stock/doctype/stock_entry/test_stock_entry.py
+++ b/erpnext/stock/doctype/stock_entry/test_stock_entry.py
@@ -562,9 +562,8 @@
 
 		rm_cost = 0
 		for d in stock_entry.get("items"):
-			if d.s_warehouse:
+			if d.item_code != "_Test FG Item 2":
 				rm_cost += flt(d.amount)
-
 		fg_cost = filter(lambda x: x.item_code=="_Test FG Item 2", stock_entry.get("items"))[0].amount
 		self.assertEqual(fg_cost,
 			flt(rm_cost + bom_operation_cost + production_order.additional_operating_cost, 2))
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/report/itemwise_recommended_reorder_level/itemwise_recommended_reorder_level.py b/erpnext/stock/report/itemwise_recommended_reorder_level/itemwise_recommended_reorder_level.py
index e1249ea..cc47ad9 100644
--- a/erpnext/stock/report/itemwise_recommended_reorder_level/itemwise_recommended_reorder_level.py
+++ b/erpnext/stock/report/itemwise_recommended_reorder_level/itemwise_recommended_reorder_level.py
@@ -51,7 +51,7 @@
 			sum(se_item.transfer_qty) as 'consume_qty'
 		from `tabStock Entry` se, `tabStock Entry Detail` se_item
 		where se.name = se_item.parent and se.docstatus = 1
-		and ifnull(se_item.t_warehouse, '') = '' %s
+		and (ifnull(se_item.t_warehouse, '') = '' or se.purpose = 'Subcontract') %s
 		group by se_item.item_code""" % (condition), as_dict=1)
 
 	cn_items_map = {}
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)
 
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()