[fix] #8540
diff --git a/erpnext/buying/doctype/purchase_order/purchase_order.js b/erpnext/buying/doctype/purchase_order/purchase_order.js
index 51cec69..501bab0 100644
--- a/erpnext/buying/doctype/purchase_order/purchase_order.js
+++ b/erpnext/buying/doctype/purchase_order/purchase_order.js
@@ -140,18 +140,126 @@
 	},
 
 	make_stock_entry: function() {
-		var items = $.map(cur_frm.doc.items, function(d) { return d.bom ? d.item_code : false; });
-		var me = this;
+				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;
-		}
-		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"));
-	},
+				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:'Link',
+								fieldname:'item_code',
+								options: 'Item',
+								label: __('Item'),
+								read_only:1,
+								in_list_view:1
+							},
+							{
+								fieldtype:'Link',
+								fieldname:'rm_item_code',
+								options:'Item',
+								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:'Link',
+								read_only:1,
+								fieldname:'warehouse',
+								label: __('Reserve Warehouse'),
+								read_only:1,
+								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();
+						}
+					})
+				}
+
+				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) {
 		frappe.call({
@@ -167,6 +275,20 @@
 		});
 	},
 
+	_make_rm_stock_entry: function(rm_items) {
+		frappe.call({
+			method:"erpnext.buying.doctype.purchase_order.purchase_order.make_rm_stock_entry",
+			args: {
+				purchase_order: cur_frm.doc.name,
+				rm_items: rm_items
+			}
+			,
+			callback: function(r) {
+				frappe.set_route("List", "Stock Entry", "List",{"purchase_order":r.message,"doc_status":0})
+			}
+		});
+	},
+
 	make_purchase_receipt: function() {
 		frappe.model.open_mapped_doc({
 			method: "erpnext.buying.doctype.purchase_order.purchase_order.make_purchase_receipt",
diff --git a/erpnext/buying/doctype/purchase_order/purchase_order.py b/erpnext/buying/doctype/purchase_order/purchase_order.py
index 8075ab3..b8e76b0 100644
--- a/erpnext/buying/doctype/purchase_order/purchase_order.py
+++ b/erpnext/buying/doctype/purchase_order/purchase_order.py
@@ -34,12 +34,6 @@
 			'overflow_type': 'order'
 		}]
 
-	def onload(self):
-		super(PurchaseOrder, self).onload()
-
-		self.set_onload('disable_fetch_last_purchase_rate',
-			cint(frappe.db.get_single_value("Buying Settings", "disable_fetch_last_purchase_rate")))
-
 	def validate(self):
 		super(PurchaseOrder, self).validate()
 
@@ -399,7 +393,6 @@
 @frappe.whitelist()
 def make_stock_entry(purchase_order, item_code):
 	purchase_order = frappe.get_doc("Purchase Order", purchase_order)
-
 	stock_entry = frappe.new_doc("Stock Entry")
 	stock_entry.purpose = "Subcontract"
 	stock_entry.purchase_order = purchase_order.name
@@ -416,6 +409,53 @@
 	return stock_entry.as_dict()
 
 @frappe.whitelist()
+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"))
+
+	if rm_items_list:
+		item_code_list = 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 item_code_list:
+		item_wh = frappe._dict(frappe.db.sql("""select item_code, description
+										from `tabItem` where name in ({0})""".
+										format(", ".join(["%s"] * len(item_code_list))), item_code_list))
+		for item_code in item_code_list:
+			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
+			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)
+			stock_entry.save()
+	else:
+		frappe.throw(_("No Items selected for transfer"))
+	return purchase_order.name
+
+@frappe.whitelist()
 def update_status(status, name):
 	po = frappe.get_doc("Purchase Order", name)
 	po.update_status(status)
diff --git a/erpnext/stock/doctype/stock_entry/stock_entry.py b/erpnext/stock/doctype/stock_entry/stock_entry.py
index dd8d998..beea97a 100644
--- a/erpnext/stock/doctype/stock_entry/stock_entry.py
+++ b/erpnext/stock/doctype/stock_entry/stock_entry.py
@@ -126,7 +126,11 @@
 		"""perform various (sometimes conditional) validations on warehouse"""
 
 		source_mandatory = ["Material Issue", "Material Transfer", "Subcontract", "Material Transfer for Manufacture"]
-		target_mandatory = ["Material Receipt", "Material Transfer", "Subcontract", "Material Transfer for Manufacture"]
+		#Allow creation of draft subcontract entries without target warehouse
+		if self.purpose == "Subcontract" and not frappe.db.exists("Stock Entry",{"name": self.name}):
+			target_mandatory = ["Material Receipt", "Material Transfer", "Material Transfer for Manufacture"]
+		else:
+			target_mandatory = ["Material Receipt", "Material Transfer", "Subcontract", "Material Transfer for Manufacture"]
 
 		validate_for_manufacture_repack = any([d.bom_no for d in self.get("items")])
 
@@ -672,7 +676,7 @@
 		# item dict = { item_code: {qty, description, stock_uom} }
 		item_dict = get_bom_items_as_dict(self.bom_no, self.company, qty=qty,
 			fetch_exploded = self.use_multi_level_bom)
-
+		print item_dict
 		for item in item_dict.values():
 			# if source warehouse presents in BOM set from_warehouse as bom source_warehouse
 			item.from_warehouse = self.from_warehouse or item.source_warehouse or item.default_warehouse