major(manufacturing): fixes to ux, material requests to purchase order based on default supplier etc (#15267)

* major(manufacturing): fixes to ux, material requests to purchase order based on default supplier etc

* fix: remove debug
diff --git a/erpnext/accounts/doctype/sales_invoice/sales_invoice.js b/erpnext/accounts/doctype/sales_invoice/sales_invoice.js
index 194c364..5fefd6e 100644
--- a/erpnext/accounts/doctype/sales_invoice/sales_invoice.js
+++ b/erpnext/accounts/doctype/sales_invoice/sales_invoice.js
@@ -497,15 +497,15 @@
 }
 
 cur_frm.cscript.income_account = function(doc, cdt, cdn) {
-	erpnext.utils.copy_value_in_all_row(doc, cdt, cdn, "items", "income_account");
+	erpnext.utils.copy_value_in_all_rows(doc, cdt, cdn, "items", "income_account");
 }
 
 cur_frm.cscript.expense_account = function(doc, cdt, cdn) {
-	erpnext.utils.copy_value_in_all_row(doc, cdt, cdn, "items", "expense_account");
+	erpnext.utils.copy_value_in_all_rows(doc, cdt, cdn, "items", "expense_account");
 }
 
 cur_frm.cscript.cost_center = function(doc, cdt, cdn) {
-	erpnext.utils.copy_value_in_all_row(doc, cdt, cdn, "items", "cost_center");
+	erpnext.utils.copy_value_in_all_rows(doc, cdt, cdn, "items", "cost_center");
 }
 
 cur_frm.set_query("debit_to", function(doc) {
diff --git a/erpnext/buying/doctype/purchase_order/purchase_order.js b/erpnext/buying/doctype/purchase_order/purchase_order.js
index d7ffe04..74af4ce 100644
--- a/erpnext/buying/doctype/purchase_order/purchase_order.js
+++ b/erpnext/buying/doctype/purchase_order/purchase_order.js
@@ -64,7 +64,7 @@
 		var row = locals[cdt][cdn];
 		if (row.schedule_date) {
 			if(!frm.doc.schedule_date) {
-				erpnext.utils.copy_value_in_all_row(frm.doc, cdt, cdn, "items", "schedule_date");
+				erpnext.utils.copy_value_in_all_rows(frm.doc, cdt, cdn, "items", "schedule_date");
 			} else {
 				set_schedule_date(frm);
 			}
@@ -309,6 +309,7 @@
 					method: "erpnext.stock.doctype.material_request.material_request.make_purchase_order",
 					source_doctype: "Material Request",
 					target: me.frm,
+					args: args,
 					setters: {
 						company: me.frm.doc.company
 					},
@@ -319,7 +320,7 @@
 						per_ordered: ["<", 99.99],
 					}
 				})
-			}, __("Add items from"));
+			}, __("Get items from"));
 
 		this.frm.add_custom_button(__('Supplier Quotation'),
 			function() {
@@ -335,7 +336,7 @@
 						status: ["!=", "Stopped"],
 					}
 				})
-			}, __("Add items from"));
+			}, __("Get items from"));
 
 		this.frm.add_custom_button(__('Update rate as per last purchase'),
 			function() {
@@ -364,7 +365,7 @@
 				},
 				callback: function(r) {
 					if(r.exc) return;
-	
+
 					var i = 0;
 					var item_length = me.frm.doc.items.length;
 					while (i < item_length) {
@@ -379,17 +380,17 @@
 								d.qty = d.qty  - my_qty;
 								me.frm.doc.items[i].stock_qty = my_qty * me.frm.doc.items[i].conversion_factor;
 								me.frm.doc.items[i].qty = my_qty;
-	
+
 								frappe.msgprint("Assigning " + d.mr_name + " to " + d.item_code + " (row " + me.frm.doc.items[i].idx + ")");
 								if (qty > 0) {
 									frappe.msgprint("Splitting " + qty + " units of " + d.item_code);
 									var new_row = frappe.model.add_child(me.frm.doc, me.frm.doc.items[i].doctype, "items");
 									item_length++;
-	
+
 									for (var key in me.frm.doc.items[i]) {
 										new_row[key] = me.frm.doc.items[i][key];
 									}
-	
+
 									new_row.idx = item_length;
 									new_row["stock_qty"] = new_row.conversion_factor * qty;
 									new_row["qty"] = qty;
@@ -477,7 +478,7 @@
 
 function set_schedule_date(frm) {
 	if(frm.doc.schedule_date){
-		erpnext.utils.copy_value_in_all_row(frm.doc, frm.doc.doctype, frm.doc.name, "items", "schedule_date");
+		erpnext.utils.copy_value_in_all_rows(frm.doc, frm.doc.doctype, frm.doc.name, "items", "schedule_date");
 	}
 }
 
diff --git a/erpnext/manufacturing/doctype/bom/bom.py b/erpnext/manufacturing/doctype/bom/bom.py
index e2e9209..77df650 100644
--- a/erpnext/manufacturing/doctype/bom/bom.py
+++ b/erpnext/manufacturing/doctype/bom/bom.py
@@ -173,7 +173,7 @@
 
 				if not rate:
 					frappe.msgprint(_("{0} not found for Item {1}")
-						.format(self.rm_cost_as_per, arg["item_code"]))
+						.format(self.rm_cost_as_per, arg["item_code"]), alert=True)
 
 		return flt(rate)
 
@@ -561,7 +561,6 @@
 			where
 				bom_item.docstatus < 2
 				and bom.name = %(bom)s
-				and is_stock_item = 1
 				{where_conditions}
 				group by item_code, stock_uom
 				order by idx"""
diff --git a/erpnext/manufacturing/doctype/production_plan/production_plan.py b/erpnext/manufacturing/doctype/production_plan/production_plan.py
index 46fdb85..12f2f04 100644
--- a/erpnext/manufacturing/doctype/production_plan/production_plan.py
+++ b/erpnext/manufacturing/doctype/production_plan/production_plan.py
@@ -280,7 +280,7 @@
 				item_dict[(d.item_code, d.sales_order, d.warehouse)] = item_details
 
 		return item_dict
-		
+
 	def get_items_for_material_requests(self):
 		self.mr_items = []
 
@@ -295,15 +295,15 @@
 						bei.description, bei.stock_uom, item.min_order_qty, bei.source_warehouse,
 						item.default_material_request_type, item.min_order_qty, item_default.default_warehouse
 					from
-						`tabBOM Explosion Item` bei 
+						`tabBOM Explosion Item` bei
 						JOIN `tabBOM` bom ON bom.name = bei.parent
 						JOIN `tabItem` item ON item.name = bei.item_code
 						LEFT JOIN `tabItem Default` item_default
 							ON item_default.parent = item.name and item_default.company=%s
 					where
-						bei.docstatus < 2 
+						bei.docstatus < 2
 						and bom.name=%s and item.is_stock_item in (1, {0})
-					group by bei.item_code, bei.stock_uom""".format(self.include_non_stock_items),
+					group by bei.item_code, bei.stock_uom""".format(0 if self.include_non_stock_items else 1),
 					(self.company, data.bom_no), as_dict=1):
 						bom_wise_item_details.setdefault(d.item_code, d)
 			else:
@@ -332,7 +332,7 @@
 				bom.name = %(bom)s
 				and bom_item.docstatus < 2
 				and item.is_stock_item in (1, {0})
-			group by bom_item.item_code""".format(self.include_non_stock_items),{
+			group by bom_item.item_code""".format(0 if self.include_non_stock_items else 1),{
 				'bom': bom_no,
 				'parent_qty': parent_qty,
 				'company': self.company
@@ -412,61 +412,60 @@
 			pass
 
 	def make_material_request(self):
+		'''Create Material Requests grouped by Sales Order and Material Request Type'''
 		material_request_list = []
+		material_request_map = {}
 
-		item_details = self.get_itemwise_qty()
-		for item_code, rows in item_details.items():
-			item_doc = frappe.get_doc("Item", item_code)
+		for item in self.mr_items:
+			item_doc = frappe.get_cached_doc('Item', item.item_code)
+
+			# key for Sales Order:Material Request Type
+			key = '{}:{}'.format(item.sales_order, item_doc.default_material_request_type)
 			schedule_date = add_days(nowdate(), cint(item_doc.lead_time_days))
 
-			material_request = frappe.new_doc("Material Request")
-			material_request.update({
-				"transaction_date": nowdate(),
-				"status": "Draft",
-				"company": self.company,
-				"requested_by": frappe.session.user,
+			if not key in material_request_map:
+				# make a new MR for the combination
+				material_request_map[key] = frappe.new_doc("Material Request")
+				material_request = material_request_map[key]
+				material_request.update({
+					"transaction_date": nowdate(),
+					"status": "Draft",
+					"company": self.company,
+					"requested_by": frappe.session.user,
+					'material_request_type': item_doc.default_material_request_type
+				})
+				material_request_list.append(material_request)
+			else:
+				material_request = material_request_map[key]
+
+			# add item
+			material_request.append("items", {
+				"item_code": item.item_code,
+				"qty": item.quantity,
 				"schedule_date": schedule_date,
-				'material_request_type': item_doc.default_material_request_type
+				"warehouse": item.warehouse,
+				"sales_order": item.sales_order,
+				'production_plan': self.name,
+				'material_request_plan_item': item.name,
+				"project": frappe.db.get_value("Sales Order", item.sales_order, "project") \
+					if item.sales_order else None
 			})
 
-			for idx in rows:
-				child = self.mr_items[cint(idx)-1]
-				material_request.append("items", {
-					"item_code": item_code,
-					"qty": child.quantity,
-					"schedule_date": schedule_date,
-					"warehouse": child.warehouse,
-					"sales_order": child.sales_order,
-					'production_plan': self.name,
-					'material_request_plan_item': child.name,
-					"project": frappe.db.get_value("Sales Order", child.sales_order, "project") \
-						if child.sales_order else None
-				})
-
+		for material_request in material_request_list:
+			# submit
 			material_request.flags.ignore_permissions = 1
 			material_request.run_method("set_missing_values")
 			material_request.submit()
-			material_request_list.append(material_request.name)
-		
+
 		frappe.flags.mute_messages = False
 
 		if material_request_list:
-			material_request_list = ["""<a href="#Form/Material Request/%s" target="_blank">%s</a>""" % \
-				(p, p) for p in material_request_list]
+			material_request_list = ["""<a href="#Form/Material Request/{0}">{1}</a>""".format(m.name, m.name) \
+				for m in material_request_list]
 			msgprint(_("{0} created").format(comma_and(material_request_list)))
 		else :
 			msgprint(_("No material request created"))
 
-	def get_itemwise_qty(self):
-		item_details = {}
-		for data in self.get('mr_items'):
-			if data.item_code in item_details:
-				item_details[data.item_code].append(data.idx)
-			else:
-				item_details.setdefault(data.item_code, [data.idx])
-
-		return item_details
-
 def get_sales_orders(self):
 	so_filter = item_filter = ""
 	if self.from_date:
@@ -516,7 +515,7 @@
 		conditions = " and warehouse='{0}'".format(frappe.db.escape(warehouse))
 
 	item_projected_qty = frappe.db.sql(""" select ifnull(sum(projected_qty),0) as projected_qty,
-		ifnull(sum(actual_qty),0) as actual_qty from `tabBin` 
+		ifnull(sum(actual_qty),0) as actual_qty from `tabBin`
 		where item_code = %(item_code)s {conditions}
 	""".format(conditions=conditions), { "item_code": row.item_code }, as_list=1)
 
diff --git a/erpnext/public/js/utils.js b/erpnext/public/js/utils.js
index e4c1d53..682577b 100644
--- a/erpnext/public/js/utils.js
+++ b/erpnext/public/js/utils.js
@@ -118,7 +118,7 @@
 		return dict[party_type];
 	},
 
-	copy_value_in_all_row: function(doc, dt, dn, table_fieldname, fieldname) {
+	copy_value_in_all_rows: function(doc, dt, dn, table_fieldname, fieldname) {
 		var d = locals[dt][dn];
 		if(d[fieldname]){
 			var cl = doc[table_fieldname] || [];
@@ -487,6 +487,7 @@
 				"method": opts.method,
 				"source_names": opts.source_name,
 				"target_doc": cur_frm.doc,
+				'args': opts.args
 			},
 			callback: function(r) {
 				if(!r.exc) {
diff --git a/erpnext/selling/doctype/sales_order/sales_order.js b/erpnext/selling/doctype/sales_order/sales_order.js
index 9de9c6b..e8698f1 100644
--- a/erpnext/selling/doctype/sales_order/sales_order.js
+++ b/erpnext/selling/doctype/sales_order/sales_order.js
@@ -82,7 +82,7 @@
 	},
 	delivery_date: function(frm, cdt, cdn) {
 		if(!frm.doc.delivery_date) {
-			erpnext.utils.copy_value_in_all_row(frm.doc, cdt, cdn, "items", "delivery_date");
+			erpnext.utils.copy_value_in_all_rows(frm.doc, cdt, cdn, "items", "delivery_date");
 		}
 	}
 });
diff --git a/erpnext/setup/doctype/company/company_dashboard.py b/erpnext/setup/doctype/company/company_dashboard.py
index 7526dd6..868284a 100644
--- a/erpnext/setup/doctype/company/company_dashboard.py
+++ b/erpnext/setup/doctype/company/company_dashboard.py
@@ -2,9 +2,6 @@
 
 def get_data():
 	return {
-		'heatmap': True,
-		'heatmap_message': _('This is based on transactions against this Company. See timeline below for details'),
-
 		'graph': True,
 		'graph_method': "frappe.utils.goal.get_monthly_goal_graph_data",
 		'graph_method_args': {
diff --git a/erpnext/stock/doctype/item/item.json b/erpnext/stock/doctype/item/item.json
index 9161f2d..2851537 100644
--- a/erpnext/stock/doctype/item/item.json
+++ b/erpnext/stock/doctype/item/item.json
@@ -1841,7 +1841,7 @@
    "in_global_search": 0,
    "in_list_view": 0,
    "in_standard_filter": 0,
-   "label": "Defaults",
+   "label": "Sales, Purchase, Accounting Defaults",
    "length": 0,
    "no_copy": 0,
    "permlevel": 0,
@@ -3951,7 +3951,7 @@
  "issingle": 0,
  "istable": 0,
  "max_attachments": 1,
- "modified": "2018-08-29 06:27:10.198002",
+ "modified": "2018-08-30 05:28:12.312880",
  "modified_by": "Administrator",
  "module": "Stock",
  "name": "Item",
diff --git a/erpnext/stock/doctype/material_request/material_request.js b/erpnext/stock/doctype/material_request/material_request.js
index 9a80a9a..5fd7a6a 100644
--- a/erpnext/stock/doctype/material_request/material_request.js
+++ b/erpnext/stock/doctype/material_request/material_request.js
@@ -1,6 +1,7 @@
 // Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
 // License: GNU General Public License v3. See license.txt
 
+// eslint-disable-next-line
 {% include 'erpnext/public/js/controllers/buying.js' %};
 
 frappe.ui.form.on('Material Request', {
@@ -11,24 +12,122 @@
 			'Request for Quotation': 'Request for Quotation',
 			'Supplier Quotation': 'Supplier Quotation',
 			'Work Order': 'Work Order'
-		}
+		};
 
 		// formatter for material request item
 		frm.set_indicator_formatter('item_code',
-			function(doc) { return (doc.qty<=doc.ordered_qty) ? "green" : "orange" })
+			function(doc) { return (doc.qty<=doc.ordered_qty) ? "green" : "orange"; });
+
+		frm.set_query("item_code", "items", function() {
+			return {
+				query: "erpnext.controllers.queries.item_query"
+			};
+		});
 	},
+
 	onload: function(frm) {
 		// add item, if previous view was item
 		erpnext.utils.add_item(frm);
 
-		//set schedule_date
+		// set schedule_date
 		set_schedule_date(frm);
-		frm.fields_dict["items"].grid.get_field("warehouse").get_query = function(doc, cdt, cdn){
-			return{
+		frm.fields_dict["items"].grid.get_field("warehouse").get_query = function(doc) {
+			return {
 				filters: {'company': doc.company}
+			};
+		};
+	},
+
+	refresh: function(frm) {
+		frm.events.make_custom_buttons(frm);
+	},
+
+	make_custom_buttons: function(frm) {
+		if (frm.doc.docstatus==0) {
+			frm.add_custom_button(__("Bill of Materials"),
+				() => frm.events.get_items_from_bom(frm), __("Get items from"));
+		}
+
+		if (frm.doc.docstatus == 1 && frm.doc.status != 'Stopped') {
+			if (flt(frm.doc.per_ordered, 2) < 100) {
+				// make
+				if (frm.doc.material_request_type === "Material Transfer") {
+					frm.add_custom_button(__("Transfer Material"),
+						() => frm.events.make_stock_entry(frm), __("Make"));
+				}
+
+				if (frm.doc.material_request_type === "Material Issue") {
+					frm.add_custom_button(__("Issue Material"),
+						() => frm.events.make_stock_entry(frm), __("Make"));
+				}
+
+				if (frm.doc.material_request_type === "Purchase") {
+					frm.add_custom_button(__('Purchase Order'),
+						() => frm.events.make_purchase_order(frm), __("Make"));
+				}
+
+				if (frm.doc.material_request_type === "Purchase") {
+					frm.add_custom_button(__("Request for Quotation"),
+						() => frm.events.make_request_for_quotation(frm), __("Make"));
+				}
+
+				if (frm.doc.material_request_type === "Purchase") {
+					frm.add_custom_button(__("Supplier Quotation"),
+						() => frm.events.make_supplier_quotation(frm), __("Make"));
+				}
+
+				if (frm.doc.material_request_type === "Manufacture") {
+					frm.add_custom_button(__("Work Order"),
+						() => frm.events.raise_work_orders(frm), __("Make"));
+				}
+
+				frm.page.set_inner_btn_group_as_primary(__("Make"));
+
+				// stop
+				frm.add_custom_button(__('Stop'),
+					() => frm.events.update_status(frm, 'Stop'));
+
 			}
 		}
+
+		if (frm.doc.docstatus===0) {
+			frm.add_custom_button(__('Sales Order'), () => frm.events.get_items_from_sales_order(frm),
+				__("Get items from"));
+		}
+
+		if (frm.doc.docstatus == 1 && frm.doc.status == 'Stopped') {
+			frm.add_custom_button(__('Re-open'), () => frm.events.update_status(frm, 'Submitted'));
+		}
 	},
+
+	update_status: function(frm, stop_status) {
+		frappe.call({
+			method: 'erpnext.stock.material_request.material_request.update_status',
+			args: { name: frm.doc.name, status: stop_status },
+			callback(r) {
+				if (!r.exc) {
+					frm.reload_doc();
+				}
+			}
+		});
+	},
+
+	get_items_from_sales_order: function(frm) {
+		erpnext.utils.map_current_doc({
+			method: "erpnext.selling.doctype.sales_order.sales_order.make_material_request",
+			source_doctype: "Sales Order",
+			target: frm,
+			setters: {
+				company: frm.doc.company
+			},
+			get_query_filters: {
+				docstatus: 1,
+				status: ["!=", "Closed"],
+				per_delivered: ["<", 99.99],
+			}
+		});
+	},
+
 	get_item_data: function(frm, item) {
 		frm.call({
 			method: "erpnext.stock.get_item_details.get_item_details",
@@ -45,7 +144,6 @@
 					stock_qty: item.stock_qty,
 					company: frm.doc.company,
 					conversion_rate: 1,
-					name: frm.doc.name,
 					material_request_type: frm.doc.material_request_type,
 					plc_conversion_rate: 1,
 					rate: item.rate,
@@ -62,133 +160,19 @@
 			}
 		});
 	},
-});
 
-frappe.ui.form.on("Material Request Item", {
-	qty: function (frm, doctype, name) {
-		var d = locals[doctype][name];
-		if (flt(d.qty) < flt(d.min_order_qty)) {
-			frappe.msgprint(__("Warning: Material Requested Qty is less than Minimum Order Qty"));
-		}
-
-		const item = locals[doctype][name];
-		frm.events.get_item_data(frm, item);
-	},
-
-	rate: function(frm, doctype, name) {
-		const item = locals[doctype][name];
-		frm.events.get_item_data(frm, item);
-	},
-
-	item_code: function(frm, doctype, name) {
-		const item = locals[doctype][name];
-		item.rate = 0
-		set_schedule_date(frm);
-		frm.events.get_item_data(frm, item);
-	},
-
-	schedule_date: function(frm, cdt, cdn) {
-		var row = locals[cdt][cdn];
-		if (row.schedule_date) {
-			if(!frm.doc.schedule_date) {
-				erpnext.utils.copy_value_in_all_row(frm.doc, cdt, cdn, "items", "schedule_date");
-			} else {
-				set_schedule_date(frm);
-			}
-		}
-	}
-});
-
-erpnext.buying.MaterialRequestController = erpnext.buying.BuyingController.extend({
-	onload: function(doc) {
-		this._super();
-		this.frm.set_query("item_code", "items", function() {
-			return {
-				query: "erpnext.controllers.queries.item_query"
-			}
-		});
-	},
-
-	refresh: function(doc) {
-		var me = this;
-		this._super();
-
-		if(doc.docstatus==0) {
-			cur_frm.add_custom_button(__("Get Items from BOM"),
-				cur_frm.cscript.get_items_from_bom, "fa fa-sitemap", "btn-default");
-		}
-
-		if(doc.docstatus == 1 && doc.status != 'Stopped') {
-			if(flt(doc.per_ordered, 2) < 100) {
-				// make
-				if(doc.material_request_type === "Material Transfer")
-					cur_frm.add_custom_button(__("Transfer Material"),
-					this.make_stock_entry, __("Make"));
-
-				if(doc.material_request_type === "Material Issue")
-					cur_frm.add_custom_button(__("Issue Material"),
-					this.make_stock_entry, __("Make"));
-
-				if(doc.material_request_type === "Purchase")
-					cur_frm.add_custom_button(__('Purchase Order'),
-						this.make_purchase_order, __("Make"));
-
-				if(doc.material_request_type === "Purchase")
-					cur_frm.add_custom_button(__("Request for Quotation"),
-						this.make_request_for_quotation, __("Make"));
-
-				if(doc.material_request_type === "Purchase")
-					cur_frm.add_custom_button(__("Supplier Quotation"),
-					this.make_supplier_quotation, __("Make"));
-
-				if(doc.material_request_type === "Manufacture")
-					cur_frm.add_custom_button(__("Work Order"),
-					function() { me.raise_work_orders() }, __("Make"));
-
-				cur_frm.page.set_inner_btn_group_as_primary(__("Make"));
-
-				// stop
-				me.frm.add_custom_button(__('Stop'),
-					me.frm.cscript['Stop Material Request']);
-
-			}
-		}
-
-		if (this.frm.doc.docstatus===0) {
-			this.frm.add_custom_button(__('Sales Order'),
-				function() {
-					erpnext.utils.map_current_doc({
-						method: "erpnext.selling.doctype.sales_order.sales_order.make_material_request",
-						source_doctype: "Sales Order",
-						target: me.frm,
-						setters: {
-							company: me.frm.doc.company
-						},
-						get_query_filters: {
-							docstatus: 1,
-							status: ["!=", "Closed"],
-							per_delivered: ["<", 99.99],
-						}
-					})
-				}, __("Get items from"));
-		}
-
-		if(doc.docstatus == 1 && doc.status == 'Stopped')
-			me.frm.add_custom_button(__('Re-open'),
-				me.frm.cscript['Unstop Material Request']);
-
-	},
-
-	get_items_from_bom: function() {
+	get_items_from_bom: function(frm) {
 		var d = new frappe.ui.Dialog({
 			title: __("Get Items from BOM"),
 			fields: [
 				{"fieldname":"bom", "fieldtype":"Link", "label":__("BOM"),
-					options:"BOM", reqd: 1, get_query: function(){
-						return {filters: { docstatus:1 }}
+					options:"BOM", reqd: 1, get_query: function() {
+						return {filters: { docstatus:1 }};
 					}},
 				{"fieldname":"warehouse", "fieldtype":"Link", "label":__("Warehouse"),
 					options:"Warehouse", reqd: 1},
+				{"fieldname":"qty", "fieldtype":"Float", "label":__("Quantity"),
+					reqd: 1, "default": 1},
 				{"fieldname":"fetch_exploded", "fieldtype":"Check",
 					"label":__("Fetch exploded BOM (including sub-assemblies)"), "default":1},
 				{fieldname:"fetch", "label":__("Get Items from BOM"), "fieldtype":"Button"}
@@ -197,15 +181,15 @@
 		d.get_input("fetch").on("click", function() {
 			var values = d.get_values();
 			if(!values) return;
-			values["company"] = cur_frm.doc.company;
+			values["company"] = frm.doc.company;
 			frappe.call({
 				method: "erpnext.manufacturing.doctype.bom.bom.get_bom_items",
 				args: values,
 				callback: function(r) {
-					if(!r.message) {
-						frappe.throw(__("BOM does not contain any stock item"))
+					if (!r.message) {
+						frappe.throw(__("BOM does not contain any stock item"));
 					} else {
-						erpnext.utils.remove_empty_first_row(cur_frm, "items");
+						erpnext.utils.remove_empty_first_row(frm, "items");
 						$.each(r.message, function(i, item) {
 							var d = frappe.model.add_child(cur_frm.doc, "Material Request Item", "items");
 							d.item_code = item.item_code;
@@ -226,6 +210,94 @@
 		d.show();
 	},
 
+	make_purchase_order: function(frm) {
+		frappe.prompt(
+			{fieldname:'default_supplier', label: __('For Default Supplier (optional)'), fieldtype: 'Link', options: 'Supplier'},
+			(values) => {
+				frappe.model.open_mapped_doc({
+					method: "erpnext.stock.doctype.material_request.material_request.make_purchase_order",
+					frm: frm,
+					args: { default_supplier: values.default_supplier },
+					run_link_triggers: true
+				});
+			}
+		)
+	},
+
+	make_request_for_quotation: function(frm) {
+		frappe.model.open_mapped_doc({
+			method: "erpnext.stock.doctype.material_request.material_request.make_request_for_quotation",
+			frm: frm,
+			run_link_triggers: true
+		});
+	},
+
+	make_supplier_quotation: function(frm) {
+		frappe.model.open_mapped_doc({
+			method: "erpnext.stock.doctype.material_request.material_request.make_supplier_quotation",
+			frm: frm
+		});
+	},
+
+	make_stock_entry: function(frm) {
+		frappe.model.open_mapped_doc({
+			method: "erpnext.stock.doctype.material_request.material_request.make_stock_entry",
+			frm: frm
+		});
+	},
+
+	raise_work_orders: function(frm) {
+		frappe.call({
+			method:"erpnext.stock.doctype.material_request.material_request.raise_work_orders",
+			args: {
+				"material_request": frm.doc.name
+			},
+			callback: function(r) {
+				if(r.message.length) {
+					frm.reload_doc();
+				}
+			}
+		});
+	},
+
+});
+
+frappe.ui.form.on("Material Request Item", {
+	qty: function (frm, doctype, name) {
+		var d = locals[doctype][name];
+		if (flt(d.qty) < flt(d.min_order_qty)) {
+			frappe.msgprint(__("Warning: Material Requested Qty is less than Minimum Order Qty"));
+		}
+
+		const item = locals[doctype][name];
+		frm.events.get_item_data(frm, item);
+	},
+
+	rate: function(frm, doctype, name) {
+		const item = locals[doctype][name];
+		frm.events.get_item_data(frm, item);
+	},
+
+	item_code: function(frm, doctype, name) {
+		const item = locals[doctype][name];
+		item.rate = 0;
+		set_schedule_date(frm);
+		frm.events.get_item_data(frm, item);
+	},
+
+	schedule_date: function(frm, cdt, cdn) {
+		var row = locals[cdt][cdn];
+		if (row.schedule_date) {
+			if(!frm.doc.schedule_date) {
+				erpnext.utils.copy_value_in_all_rows(frm.doc, cdt, cdn, "items", "schedule_date");
+			} else {
+				set_schedule_date(frm);
+			}
+		}
+	}
+});
+
+erpnext.buying.MaterialRequestController = erpnext.buying.BuyingController.extend({
 	tc_name: function() {
 		this.get_terms();
 	},
@@ -234,7 +306,7 @@
 		// to override item code trigger from transaction.js
 	},
 
-	validate_company_and_party: function(party_field) {
+	validate_company_and_party: function() {
 		return true;
 	},
 
@@ -242,51 +314,6 @@
 		return;
 	},
 
-	make_purchase_order: function() {
-		frappe.model.open_mapped_doc({
-			method: "erpnext.stock.doctype.material_request.material_request.make_purchase_order",
-			frm: cur_frm,
-			run_link_triggers: true
-		});
-	},
-
-	make_request_for_quotation: function(){
-		frappe.model.open_mapped_doc({
-			method: "erpnext.stock.doctype.material_request.material_request.make_request_for_quotation",
-			frm: cur_frm,
-			run_link_triggers: true
-		});
-	},
-
-	make_supplier_quotation: function() {
-		frappe.model.open_mapped_doc({
-			method: "erpnext.stock.doctype.material_request.material_request.make_supplier_quotation",
-			frm: cur_frm
-		});
-	},
-
-	make_stock_entry: function() {
-		frappe.model.open_mapped_doc({
-			method: "erpnext.stock.doctype.material_request.material_request.make_stock_entry",
-			frm: cur_frm
-		});
-	},
-
-	raise_work_orders: function() {
-		var me = this;
-		frappe.call({
-			method:"erpnext.stock.doctype.material_request.material_request.raise_work_orders",
-			args: {
-				"material_request": me.frm.doc.name
-			},
-			callback: function(r) {
-				if(r.message.length) {
-					me.frm.reload_doc();
-				}
-			}
-		});
-	},
-
 	validate: function() {
 		set_schedule_date(this.frm);
 	},
@@ -313,22 +340,8 @@
 // for backward compatibility: combine new and previous states
 $.extend(cur_frm.cscript, new erpnext.buying.MaterialRequestController({frm: cur_frm}));
 
-cur_frm.cscript['Stop Material Request'] = function() {
-	var doc = cur_frm.doc;
-	$c('runserverobj', {'method':'update_status', 'arg': 'Stopped', 'docs': doc}, function(r,rt) {
-		cur_frm.refresh();
-	});
-};
-
-cur_frm.cscript['Unstop Material Request'] = function(){
-	var doc = cur_frm.doc;
-	$c('runserverobj', {'method':'update_status', 'arg': 'Submitted','docs': doc}, function(r,rt) {
-		cur_frm.refresh();
-	});
-};
-
 function set_schedule_date(frm) {
 	if(frm.doc.schedule_date){
-		erpnext.utils.copy_value_in_all_row(frm.doc, frm.doc.doctype, frm.doc.name, "items", "schedule_date");
+		erpnext.utils.copy_value_in_all_rows(frm.doc, frm.doc.doctype, frm.doc.name, "items", "schedule_date");
 	}
 }
diff --git a/erpnext/stock/doctype/material_request/material_request.json b/erpnext/stock/doctype/material_request/material_request.json
index 14e7955..9927265 100644
--- a/erpnext/stock/doctype/material_request/material_request.json
+++ b/erpnext/stock/doctype/material_request/material_request.json
@@ -59,7 +59,7 @@
    "ignore_xss_filter": 0,
    "in_filter": 0,
    "in_global_search": 0,
-   "in_list_view": 1,
+   "in_list_view": 0,
    "in_standard_filter": 0,
    "label": "Series",
    "length": 0,
@@ -793,7 +793,7 @@
  "istable": 0,
  "max_attachments": 0,
  "menu_index": 0,
- "modified": "2018-08-29 06:28:35.129352",
+ "modified": "2018-08-30 07:28:01.070112",
  "modified_by": "Administrator",
  "module": "Stock",
  "name": "Material Request",
diff --git a/erpnext/stock/doctype/material_request/material_request.py b/erpnext/stock/doctype/material_request/material_request.py
index df40654..730ec3e 100644
--- a/erpnext/stock/doctype/material_request/material_request.py
+++ b/erpnext/stock/doctype/material_request/material_request.py
@@ -14,6 +14,7 @@
 from erpnext.controllers.buying_controller import BuyingController
 from erpnext.manufacturing.doctype.work_order.work_order import get_item_details
 from erpnext.buying.utils import check_for_closed_status, validate_for_items
+from erpnext.stock.doctype.item.item import get_item_defaults
 
 from six import string_types
 
@@ -73,21 +74,16 @@
 
 		validate_for_items(self)
 
-		# self.set_title()
+		self.set_title()
 		# self.validate_qty_against_so()
 		# NOTE: Since Item BOM and FG quantities are combined, using current data, it cannot be validated
 		# Though the creation of Material Request from a Production Plan can be rethought to fix this
 
 	def set_title(self):
 		'''Set title as comma separated list of items'''
-		items = []
-		for d in self.items:
-			if d.item_code not in items:
-				items.append(d.item_code)
-			if(len(items)==4):
-				break
+		items = ', '.join([d.item_name for d in self.items][:4])
 
-		self.title = ', '.join(items)
+		self.title = _('{0} for {1}'.format(self.material_request_type, items))[:100]
 
 	def on_submit(self):
 		# frappe.db.set(self, 'status', 'Submitted')
@@ -244,10 +240,29 @@
 	target.stock_qty = (target.qty * target.conversion_factor)
 
 @frappe.whitelist()
+def update_status(name, status):
+	material_request = frappe.get_doc('Material Request', name)
+	material_request.check_permission('write')
+	material_request.update_status(status)
+
+@frappe.whitelist()
 def make_purchase_order(source_name, target_doc=None):
+
 	def postprocess(source, target_doc):
+		if frappe.flags.args and frappe.flags.args.default_supplier:
+			# items only for given default supplier
+			supplier_items = []
+			for d in target_doc.items:
+				default_supplier = get_item_defaults(d.item_code, target_doc.company).get('default_supplier')
+				if frappe.flags.args.default_supplier == default_supplier:
+					supplier_items.append(d)
+			target_doc.items = supplier_items
+
 		set_missing_values(source, target_doc)
 
+	def select_item(d):
+		return d.ordered_qty < d.stock_qty
+
 	doclist = get_mapped_doc("Material Request", source_name, 	{
 		"Material Request": {
 			"doctype": "Purchase Order",
@@ -267,7 +282,7 @@
 				["sales_order_item", "sales_order_item"]
 			],
 			"postprocess": update_item,
-			"condition": lambda doc: doc.ordered_qty < doc.stock_qty
+			"condition": select_item
 		}
 	}, target_doc, postprocess)
 
@@ -334,8 +349,8 @@
 	return target_doc
 
 def get_material_requests_based_on_supplier(supplier):
-	supplier_items = [d[0] for d in frappe.db.get_values("Item",
-		{"default_supplier": supplier})]
+	supplier_items = [d.parent for d in frappe.db.get_all("Item Default",
+		{"default_supplier": supplier}, 'parent')]
 	if supplier_items:
 		material_requests = frappe.db.sql_list("""select distinct mr.name
 			from `tabMaterial Request` mr, `tabMaterial Request Item` mr_item
diff --git a/erpnext/stock/doctype/stock_entry/stock_entry.js b/erpnext/stock/doctype/stock_entry/stock_entry.js
index e468533..fa3501a 100644
--- a/erpnext/stock/doctype/stock_entry/stock_entry.js
+++ b/erpnext/stock/doctype/stock_entry/stock_entry.js
@@ -472,10 +472,10 @@
 		}
 	},
 	expense_account: function(frm, cdt, cdn) {
-		erpnext.utils.copy_value_in_all_row(frm.doc, cdt, cdn, "items", "expense_account");
+		erpnext.utils.copy_value_in_all_rows(frm.doc, cdt, cdn, "items", "expense_account");
 	},
 	cost_center: function(frm, cdt, cdn) {
-		erpnext.utils.copy_value_in_all_row(frm.doc, cdt, cdn, "items", "cost_center");
+		erpnext.utils.copy_value_in_all_rows(frm.doc, cdt, cdn, "items", "cost_center");
 	},
 	sample_quantity: function(frm, cdt, cdn) {
 		validate_sample_quantity(frm, cdt, cdn);
diff --git a/erpnext/stock/get_item_details.py b/erpnext/stock/get_item_details.py
index 420d9d8..cbf8217 100644
--- a/erpnext/stock/get_item_details.py
+++ b/erpnext/stock/get_item_details.py
@@ -333,13 +333,13 @@
 	cost_center = None
 	if args.get('project'):
 		cost_center = frappe.db.get_value("Project", args.get("project"), "cost_center", cache=True)
-	
+
 	if not cost_center:
 		if args.get('customer'):
 			cost_center = item.get('selling_cost_center') or item_group.get('selling_cost_center')
 		else:
 			cost_center = item.get('buying_cost_center') or item_group.get('buying_cost_center')
-	
+
 	return cost_center or args.get("cost_center")
 
 def get_default_supplier(args, item, item_group):
@@ -401,7 +401,7 @@
 				})
 				item_price.insert()
 				frappe.msgprint(_("Item Price added for {0} in Price List {1}").format(args.item_code,
-					args.price_list))
+					args.price_list), alert=True)
 
 def get_item_price(args, item_code):
 	"""
@@ -658,7 +658,7 @@
 def get_bin_details_and_serial_nos(item_code, warehouse, has_batch_no, stock_qty=None, serial_no=None):
 	bin_details_and_serial_nos = {}
 	bin_details_and_serial_nos.update(get_bin_details(item_code, warehouse))
-	if stock_qty > 0:
+	if flt(stock_qty) > 0:
 		if has_batch_no:
 			args = frappe._dict({"item_code":item_code, "warehouse":warehouse, "stock_qty":stock_qty})
 			serial_no = get_serial_no(args)