Merge pull request #21305 from deepeshgarg007/partial_loan_repayment_fixes

fix: Loan Repayment code clean up and other fixes
diff --git a/erpnext/accounts/doctype/account/account.py b/erpnext/accounts/doctype/account/account.py
index 0a72d4f..c6de641 100644
--- a/erpnext/accounts/doctype/account/account.py
+++ b/erpnext/accounts/doctype/account/account.py
@@ -89,7 +89,7 @@
 				throw(_("Root cannot be edited."), RootNotEditable)
 
 		if not self.parent_account and not self.is_group:
-			frappe.throw(_("Root Account must be a group"))
+			frappe.throw(_("The root account {0} must be a group").format(frappe.bold(self.name)))
 
 	def validate_root_company_and_sync_account_to_children(self):
 		# ignore validation while creating new compnay or while syncing to child companies
diff --git a/erpnext/accounts/doctype/account/test_account.py b/erpnext/accounts/doctype/account/test_account.py
index dc23b2b..89bb018 100644
--- a/erpnext/accounts/doctype/account/test_account.py
+++ b/erpnext/accounts/doctype/account/test_account.py
@@ -69,6 +69,7 @@
 			acc.account_name = "Accumulated Depreciation"
 			acc.parent_account = "Fixed Assets - _TC"
 			acc.company = "_Test Company"
+			acc.account_type = "Accumulated Depreciation"
 			acc.insert()
 
 		doc = frappe.get_doc("Account", "Securities and Deposits - _TC")
@@ -149,7 +150,7 @@
 
 		# fixed asset depreciation
 		["_Test Fixed Asset", "Current Assets", 0, "Fixed Asset", None],
-		["_Test Accumulated Depreciations", "Current Assets", 0, None, None],
+		["_Test Accumulated Depreciations", "Current Assets", 0, "Accumulated Depreciation", None],
 		["_Test Depreciations", "Expenses", 0, None, None],
 		["_Test Gain/Loss on Asset Disposal", "Expenses", 0, None, None],
 
diff --git a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.js b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.js
index c5c5483..9292b63 100644
--- a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.js
+++ b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.js
@@ -174,7 +174,8 @@
 				read_only: 0,
 				fieldtype:'Date',
 				label: __('Release Date'),
-				default: me.frm.doc.release_date
+				default: me.frm.doc.release_date,
+				reqd: 1
 			},
 			{
 				fieldname: 'hold_comment',
diff --git a/erpnext/accounts/doctype/purchase_invoice_item/purchase_invoice_item.json b/erpnext/accounts/doctype/purchase_invoice_item/purchase_invoice_item.json
index 9c97426..db3f72a 100644
--- a/erpnext/accounts/doctype/purchase_invoice_item/purchase_invoice_item.json
+++ b/erpnext/accounts/doctype/purchase_invoice_item/purchase_invoice_item.json
@@ -754,8 +754,7 @@
   {
    "fieldname": "manufacturer_part_no",
    "fieldtype": "Data",
-   "label": "Manufacturer Part Number",
-   "read_only": 1
+   "label": "Manufacturer Part Number"
   },
   {
    "depends_on": "is_fixed_asset",
@@ -777,7 +776,7 @@
  "idx": 1,
  "istable": 1,
  "links": [],
- "modified": "2020-04-01 14:20:17.297284",
+ "modified": "2020-04-07 18:34:35.104178",
  "modified_by": "Administrator",
  "module": "Accounts",
  "name": "Purchase Invoice Item",
diff --git a/erpnext/accounts/doctype/sales_invoice/sales_invoice.py b/erpnext/accounts/doctype/sales_invoice/sales_invoice.py
index 82aedb6..3c40112 100644
--- a/erpnext/accounts/doctype/sales_invoice/sales_invoice.py
+++ b/erpnext/accounts/doctype/sales_invoice/sales_invoice.py
@@ -440,11 +440,12 @@
 			if pos.get("company_address"):
 				self.company_address = pos.get("company_address")
 
-			customer_price_list, customer_group = frappe.get_value("Customer", self.customer, ['default_price_list', 'customer_group'])
-
-			customer_group_price_list = frappe.get_value("Customer Group", customer_group, 'default_price_list')
-
-			selling_price_list = customer_price_list or customer_group_price_list or pos.get('selling_price_list')
+			if self.customer:
+				customer_price_list, customer_group = frappe.get_value("Customer", self.customer, ['default_price_list', 'customer_group'])
+				customer_group_price_list = frappe.get_value("Customer Group", customer_group, 'default_price_list')
+				selling_price_list = customer_price_list or customer_group_price_list or pos.get('selling_price_list')
+			else:
+				selling_price_list = pos.get('selling_price_list')
 
 			if selling_price_list:
 				self.set('selling_price_list', selling_price_list)
diff --git a/erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py b/erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py
index 0e54b62..a2819af 100644
--- a/erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py
+++ b/erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py
@@ -1926,16 +1926,6 @@
 		item.taxes = []
 		item.save()
 
-	def test_customer_provided_parts_si(self):
-		create_item('CUST-0987', is_customer_provided_item = 1, customer = '_Test Customer', is_purchase_item = 0)
-		si = create_sales_invoice(item_code='CUST-0987', rate=0)
-		self.assertEqual(si.get("items")[0].allow_zero_valuation_rate, 1)
-		self.assertEqual(si.get("items")[0].amount, 0)
-
-		# test if Sales Invoice with rate is allowed
-		si2 = create_sales_invoice(item_code='CUST-0987', do_not_save=True)
-		self.assertRaises(frappe.ValidationError, si2.save)
-
 def create_sales_invoice(**args):
 	si = frappe.new_doc("Sales Invoice")
 	args = frappe._dict(args)
diff --git a/erpnext/assets/doctype/asset_category/asset_category.py b/erpnext/assets/doctype/asset_category/asset_category.py
index fc08841..9bf4df4 100644
--- a/erpnext/assets/doctype/asset_category/asset_category.py
+++ b/erpnext/assets/doctype/asset_category/asset_category.py
@@ -11,12 +11,34 @@
 class AssetCategory(Document):
 	def validate(self):
 		self.validate_finance_books()
+		self.validate_accounts()
 
 	def validate_finance_books(self):
 		for d in self.finance_books:
 			for field in ("Total Number of Depreciations", "Frequency of Depreciation"):
 				if cint(d.get(frappe.scrub(field)))<1:
 					frappe.throw(_("Row {0}: {1} must be greater than 0").format(d.idx, field), frappe.MandatoryError)
+	
+	def validate_accounts(self):
+		account_type_map = {
+			'fixed_asset_account': { 'account_type': 'Fixed Asset' },
+			'accumulated_depreciation_account': { 'account_type': 'Accumulated Depreciation' },
+			'depreciation_expense_account': { 'root_type': 'Expense' },
+			'capital_work_in_progress_account': { 'account_type': 'Capital Work in Progress' }
+		}
+		for d in self.accounts:
+			for fieldname in account_type_map.keys():
+				if d.get(fieldname):
+					selected_account = d.get(fieldname)
+					key_to_match = next(iter(account_type_map.get(fieldname))) # acount_type or root_type
+					selected_key_type = frappe.db.get_value('Account', selected_account, key_to_match)
+					expected_key_type = account_type_map[fieldname][key_to_match]
+
+					if selected_key_type != expected_key_type:
+						frappe.throw(_("Row #{}: {} of {} should be {}. Please modify the account or select a different account.")
+							.format(d.idx, frappe.unscrub(key_to_match), frappe.bold(selected_account), frappe.bold(expected_key_type)),
+							title=_("Invalid Account"))
+
 
 @frappe.whitelist()
 def get_asset_category_account(fieldname, item=None, asset=None, account=None, asset_category = None, company = None):
diff --git a/erpnext/buying/doctype/purchase_order_item/purchase_order_item.json b/erpnext/buying/doctype/purchase_order_item/purchase_order_item.json
index 6768dfa..e37e1dd 100644
--- a/erpnext/buying/doctype/purchase_order_item/purchase_order_item.json
+++ b/erpnext/buying/doctype/purchase_order_item/purchase_order_item.json
@@ -702,8 +702,7 @@
   {
    "fieldname": "manufacturer_part_no",
    "fieldtype": "Data",
-   "label": "Manufacturer Part Number",
-   "read_only": 1
+   "label": "Manufacturer Part Number"
   },
   {
    "default": "0",
@@ -723,7 +722,7 @@
  "idx": 1,
  "istable": 1,
  "links": [],
- "modified": "2019-12-06 13:17:12.142799",
+ "modified": "2020-04-07 18:35:17.558928",
  "modified_by": "Administrator",
  "module": "Buying",
  "name": "Purchase Order Item",
diff --git a/erpnext/buying/doctype/supplier_quotation_item/supplier_quotation_item.json b/erpnext/buying/doctype/supplier_quotation_item/supplier_quotation_item.json
index 7d7d6f4..b50e834 100644
--- a/erpnext/buying/doctype/supplier_quotation_item/supplier_quotation_item.json
+++ b/erpnext/buying/doctype/supplier_quotation_item/supplier_quotation_item.json
@@ -1,4 +1,5 @@
 {
+ "actions": [],
  "autoname": "hash",
  "creation": "2013-05-22 12:43:10",
  "doctype": "DocType",
@@ -522,8 +523,7 @@
   {
    "fieldname": "manufacturer_part_no",
    "fieldtype": "Data",
-   "label": "Manufacturer Part Number",
-   "read_only": 1
+   "label": "Manufacturer Part Number"
   },
   {
    "fieldname": "column_break_15",
@@ -532,7 +532,8 @@
  ],
  "idx": 1,
  "istable": 1,
- "modified": "2019-06-02 05:32:46.019237",
+ "links": [],
+ "modified": "2020-04-07 18:35:51.175947",
  "modified_by": "Administrator",
  "module": "Buying",
  "name": "Supplier Quotation Item",
diff --git a/erpnext/controllers/accounts_controller.py b/erpnext/controllers/accounts_controller.py
index d95753d..4045250 100644
--- a/erpnext/controllers/accounts_controller.py
+++ b/erpnext/controllers/accounts_controller.py
@@ -1123,36 +1123,39 @@
 	}
 	return info
 
-def set_sales_order_defaults(parent_doctype, parent_doctype_name, child_docname, item_code):
+def set_sales_order_defaults(parent_doctype, parent_doctype_name, child_docname, trans_item):
 	"""
 	Returns a Sales Order Item child item containing the default values
 	"""
 	p_doc = frappe.get_doc(parent_doctype, parent_doctype_name)
 	child_item = frappe.new_doc('Sales Order Item', p_doc, child_docname)
-	item = frappe.get_doc("Item", item_code)
+	item = frappe.get_doc("Item", trans_item.get('item_code'))
 	child_item.item_code = item.item_code
 	child_item.item_name = item.item_name
 	child_item.description = item.description
-	child_item.reqd_by_date = p_doc.delivery_date
+	child_item.delivery_date = trans_item.get('delivery_date') or p_doc.delivery_date
 	child_item.uom = item.stock_uom
-	child_item.conversion_factor = get_conversion_factor(item_code, item.stock_uom).get("conversion_factor") or 1.0
+	child_item.conversion_factor = get_conversion_factor(item.item_code, item.stock_uom).get("conversion_factor") or 1.0
 	child_item.warehouse = get_item_warehouse(item, p_doc, overwrite_warehouse=True)
+	if not child_item.warehouse:
+		frappe.throw(_("Cannot find {} for item {}. Please set the same in Item Master or Stock Settings.")
+			.format(frappe.bold("default warehouse"), frappe.bold(item.item_code)))
 	return child_item
 
 
-def set_purchase_order_defaults(parent_doctype, parent_doctype_name, child_docname, item_code):
+def set_purchase_order_defaults(parent_doctype, parent_doctype_name, child_docname, trans_item):
 	"""
 	Returns a Purchase Order Item child item containing the default values
 	"""
 	p_doc = frappe.get_doc(parent_doctype, parent_doctype_name)
 	child_item = frappe.new_doc('Purchase Order Item', p_doc, child_docname)
-	item = frappe.get_doc("Item", item_code)
+	item = frappe.get_doc("Item", trans_item.get('item_code'))
 	child_item.item_code = item.item_code
 	child_item.item_name = item.item_name
 	child_item.description = item.description
-	child_item.schedule_date = p_doc.schedule_date
+	child_item.schedule_date = trans_item.get('schedule_date') or p_doc.schedule_date
 	child_item.uom = item.stock_uom
-	child_item.conversion_factor = get_conversion_factor(item_code, item.stock_uom).get("conversion_factor") or 1.0
+	child_item.conversion_factor = get_conversion_factor(item.item_code, item.stock_uom).get("conversion_factor") or 1.0
 	child_item.base_rate = 1 # Initiallize value will update in parent validation
 	child_item.base_amount = 1 # Initiallize value will update in parent validation
 	return child_item
@@ -1196,9 +1199,9 @@
 		if not d.get("docname"):
 			new_child_flag = True
 			if parent_doctype == "Sales Order":
-				child_item  = set_sales_order_defaults(parent_doctype, parent_doctype_name, child_docname, d.get("item_code"))
+				child_item  = set_sales_order_defaults(parent_doctype, parent_doctype_name, child_docname, d)
 			if parent_doctype == "Purchase Order":
-				child_item = set_purchase_order_defaults(parent_doctype, parent_doctype_name, child_docname, d.get("item_code"))
+				child_item = set_purchase_order_defaults(parent_doctype, parent_doctype_name, child_docname, d)
 		else:
 			child_item = frappe.get_doc(parent_doctype + ' Item', d.get("docname"))
 			if flt(child_item.get("rate")) == flt(d.get("rate")) and flt(child_item.get("qty")) == flt(d.get("qty")):
@@ -1243,6 +1246,7 @@
 
 		child_item.flags.ignore_validate_update_after_submit = True
 		if new_child_flag:
+			parent.load_from_db()
 			child_item.idx = len(parent.items) + 1
 			child_item.insert()
 		else:
diff --git a/erpnext/controllers/stock_controller.py b/erpnext/controllers/stock_controller.py
index 4037f2f..55a2c43 100644
--- a/erpnext/controllers/stock_controller.py
+++ b/erpnext/controllers/stock_controller.py
@@ -383,9 +383,6 @@
 			# Customer Provided parts will have zero valuation rate
 			if frappe.db.get_value('Item', d.item_code, 'is_customer_provided_item'):
 				d.allow_zero_valuation_rate = 1
-				if d.parenttype in ["Delivery Note", "Sales Invoice"] and d.rate:
-					frappe.throw(_("Row #{0}: {1} cannot have {2} as it is a Customer Provided Item")
-						.format(d.idx, frappe.bold(d.item_code), frappe.bold("Rate")))
 
 def update_gl_entries_after(posting_date, posting_time, for_warehouses=None, for_items=None,
 		warehouse_account=None, company=None):
diff --git a/erpnext/crm/doctype/opportunity/opportunity.py b/erpnext/crm/doctype/opportunity/opportunity.py
index 5e640e7..1b071ea 100644
--- a/erpnext/crm/doctype/opportunity/opportunity.py
+++ b/erpnext/crm/doctype/opportunity/opportunity.py
@@ -336,3 +336,27 @@
 	link_communication_to_document(doc, "Opportunity", opportunity.name, ignore_communication_links)
 
 	return opportunity.name
+@frappe.whitelist()
+def get_events(start, end, filters=None):
+	"""Returns events for Gantt / Calendar view rendering.
+	:param start: Start date-time.
+	:param end: End date-time.
+	:param filters: Filters (JSON).
+	"""
+	from frappe.desk.calendar import get_event_conditions
+	conditions = get_event_conditions("Opportunity", filters)
+
+	data = frappe.db.sql("""
+		select
+			distinct `tabOpportunity`.name, `tabOpportunity`.customer_name, `tabOpportunity`.opportunity_amount,
+			`tabOpportunity`.title, `tabOpportunity`.contact_date
+		from
+			`tabOpportunity`
+		where
+			(`tabOpportunity`.contact_date between %(start)s and %(end)s)
+			{conditions}
+		""".format(conditions=conditions), {
+			"start": start,
+			"end": end
+		}, as_dict=True, update={"allDay": 0})
+	return data
\ No newline at end of file
diff --git a/erpnext/crm/doctype/opportunity/opportunity_calendar.js b/erpnext/crm/doctype/opportunity/opportunity_calendar.js
new file mode 100644
index 0000000..58fa2b8
--- /dev/null
+++ b/erpnext/crm/doctype/opportunity/opportunity_calendar.js
@@ -0,0 +1,19 @@
+// Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and Contributors
+// License: GNU General Public License v3. See license.txt
+frappe.views.calendar["Opportunity"] = {
+	field_map: {
+		"start": "contact_date",
+		"end": "contact_date",
+		"id": "name",
+		"title": "customer_name",
+		"allDay": "allDay"
+    },
+	options: {
+		header: {
+			left: 'prev,next today',
+			center: 'title',
+			right: 'month'
+		}
+    },
+    get_events_method: 'erpnext.crm.doctype.opportunity.opportunity.get_events'
+}
diff --git a/erpnext/manufacturing/doctype/job_card/job_card.js b/erpnext/manufacturing/doctype/job_card/job_card.js
index 8c7876d..bab0dfb 100644
--- a/erpnext/manufacturing/doctype/job_card/job_card.js
+++ b/erpnext/manufacturing/doctype/job_card/job_card.js
@@ -82,7 +82,9 @@
 			frm.set_value('current_time' , 0);
 		}
 
-		frm.save();
+		frm.save("Save", () => {}, "", () => {
+			frm.doc.time_logs.pop(-1);
+		});
 	},
 
 	complete_job: function(frm, completed_time, completed_qty) {
@@ -105,6 +107,24 @@
 		});
 	},
 
+	validate: function(frm) {
+		if ((!frm.doc.time_logs || !frm.doc.time_logs.length) && frm.doc.started_time) {
+			frm.trigger("reset_timer");
+		}
+	},
+
+	employee: function(frm) {
+		if (frm.doc.job_started && !frm.doc.current_time) {
+			frm.trigger("reset_timer");
+		}
+	},
+
+	reset_timer: function(frm) {
+		frm.set_value('started_time' , '');
+		frm.set_value('job_started', 0);
+		frm.set_value('current_time' , 0);
+	},
+
 	make_dashboard: function(frm) {
 		if(frm.doc.__islocal)
 			return;
@@ -137,12 +157,12 @@
 					updateStopwatch(current);
 				}, 1000);
 			}
-	
+
 			function updateStopwatch(increment) {
 				var hours = Math.floor(increment / 3600);
 				var minutes = Math.floor((increment - (hours * 3600)) / 60);
 				var seconds = increment - (hours * 3600) - (minutes * 60);
-	
+
 				$(section).find(".hours").text(hours < 10 ? ("0" + hours.toString()) : hours.toString());
 				$(section).find(".minutes").text(minutes < 10 ? ("0" + minutes.toString()) : minutes.toString());
 				$(section).find(".seconds").text(seconds < 10 ? ("0" + seconds.toString()) : seconds.toString());
@@ -205,5 +225,10 @@
 frappe.ui.form.on('Job Card Time Log', {
 	completed_qty: function(frm) {
 		frm.events.set_total_completed_qty(frm);
+	},
+
+	to_time: function(frm) {
+		frm.set_value('job_started', 0);
+		frm.set_value('started_time', '');
 	}
 })
\ No newline at end of file
diff --git a/erpnext/manufacturing/doctype/job_card/job_card.py b/erpnext/manufacturing/doctype/job_card/job_card.py
index f8c60f2..e9627a5 100644
--- a/erpnext/manufacturing/doctype/job_card/job_card.py
+++ b/erpnext/manufacturing/doctype/job_card/job_card.py
@@ -9,7 +9,7 @@
 from frappe.model.mapper import get_mapped_doc
 from frappe.model.document import Document
 from frappe.utils import (flt, cint, time_diff_in_hours, get_datetime, getdate,
-	get_time, add_to_date, time_diff, add_days, get_datetime_str)
+	get_time, add_to_date, time_diff, add_days, get_datetime_str, get_link_to_form)
 
 from erpnext.manufacturing.doctype.manufacturing_settings.manufacturing_settings import get_mins_between_operations
 
@@ -189,11 +189,15 @@
 
 	def validate_job_card(self):
 		if not self.time_logs:
-			frappe.throw(_("Time logs are required for job card {0}").format(self.name))
+			frappe.throw(_("Time logs are required for {0} {1}")
+				.format(frappe.bold("Job Card"), get_link_to_form("Job Card", self.name)))
 
 		if self.for_quantity and self.total_completed_qty != self.for_quantity:
-			frappe.throw(_("The total completed qty({0}) must be equal to qty to manufacture({1})"
-				.format(frappe.bold(self.total_completed_qty),frappe.bold(self.for_quantity))))
+			total_completed_qty = frappe.bold(_("Total Completed Qty"))
+			qty_to_manufacture = frappe.bold(_("Qty to Manufacture"))
+
+			frappe.throw(_("The {0} ({1}) must be equal to {2} ({3})"
+				.format(total_completed_qty, frappe.bold(self.total_completed_qty), qty_to_manufacture,frappe.bold(self.for_quantity))))
 
 	def update_work_order(self):
 		if not self.work_order:
diff --git a/erpnext/manufacturing/doctype/work_order/work_order.js b/erpnext/manufacturing/doctype/work_order/work_order.js
index 9c8aa45..d541866 100644
--- a/erpnext/manufacturing/doctype/work_order/work_order.js
+++ b/erpnext/manufacturing/doctype/work_order/work_order.js
@@ -240,6 +240,8 @@
 			});
 		}, __("Job Card"), __("Create"));
 
+		dialog.fields_dict["operations"].grid.wrapper.find('.grid-add-row').hide();
+
 		var pending_qty = 0;
 		frm.doc.operations.forEach(data => {
 			if(data.completed_qty != frm.doc.qty) {
diff --git a/erpnext/public/js/controllers/buying.js b/erpnext/public/js/controllers/buying.js
index 27a9de9..afbdbc6 100644
--- a/erpnext/public/js/controllers/buying.js
+++ b/erpnext/public/js/controllers/buying.js
@@ -379,7 +379,31 @@
 				}
 			});
 		}
-	}
+	},
+
+	manufacturer_part_no: function(doc, cdt, cdn) {
+		const row = locals[cdt][cdn];
+
+		if (row.manufacturer_part_no) {
+			frappe.model.get_value('Item Manufacturer',
+				{
+					'item_code': row.item_code,
+					'manufacturer': row.manufacturer,
+					'manufacturer_part_no': row.manufacturer_part_no
+				},
+				'name',
+				function(data) {
+					if (!data) {
+						let msg = {
+							message: __("Manufacturer Part Number <b>{0}</b> is invalid", [row.manufacturer_part_no]),
+							title: __("Invalid Part Number")
+						}
+						frappe.throw(msg);
+					}
+				});
+
+			}
+		}
 });
 
 cur_frm.add_fetch('project', 'cost_center', 'cost_center');
diff --git a/erpnext/public/js/controllers/transaction.js b/erpnext/public/js/controllers/transaction.js
index 8e8c48f..f126f6a 100644
--- a/erpnext/public/js/controllers/transaction.js
+++ b/erpnext/public/js/controllers/transaction.js
@@ -551,6 +551,10 @@
 											if(!d[k]) d[k] = v;
 										});
 
+										if (d.has_batch_no && d.has_serial_no) {
+											d.batch_no = undefined;
+										}
+
 										erpnext.show_serial_batch_selector(me.frm, d, (item) => {
 											me.frm.script_manager.trigger('qty', item.doctype, item.name);
 											if (!me.frm.doc.set_warehouse)
diff --git a/erpnext/public/js/utils.js b/erpnext/public/js/utils.js
index 4d44eae..58969f2 100755
--- a/erpnext/public/js/utils.js
+++ b/erpnext/public/js/utils.js
@@ -436,6 +436,44 @@
 	const cannot_add_row = (typeof opts.cannot_add_row === 'undefined') ? true : opts.cannot_add_row;
 	const child_docname = (typeof opts.cannot_add_row === 'undefined') ? "items" : opts.child_docname;
 	this.data = [];
+	const fields = [{
+		fieldtype:'Data',
+		fieldname:"docname",
+		read_only: 1,
+		hidden: 1,
+	}, {
+		fieldtype:'Link',
+		fieldname:"item_code",
+		options: 'Item',
+		in_list_view: 1,
+		read_only: 0,
+		disabled: 0,
+		label: __('Item Code')
+	}, {
+		fieldtype:'Float',
+		fieldname:"qty",
+		default: 0,
+		read_only: 0,
+		in_list_view: 1,
+		label: __('Qty')
+	}, {
+		fieldtype:'Currency',
+		fieldname:"rate",
+		default: 0,
+		read_only: 0,
+		in_list_view: 1,
+		label: __('Rate')
+	}];
+
+	if (frm.doc.doctype == 'Sales Order' || frm.doc.doctype == 'Purchase Order' ) {
+		fields.splice(2, 0, {
+			fieldtype: 'Date',
+			fieldname: frm.doc.doctype == 'Sales Order' ? "delivery_date" : "schedule_date",
+			in_list_view: 1,
+			label: frm.doc.doctype == 'Sales Order' ? __("Delivery Date") : __("Reqd by date")
+		})
+	}
+
 	const dialog = new frappe.ui.Dialog({
 		title: __("Update Items"),
 		fields: [
@@ -450,34 +488,7 @@
 				get_data: () => {
 					return this.data;
 				},
-				fields: [{
-					fieldtype:'Data',
-					fieldname:"docname",
-					read_only: 1,
-					hidden: 1,
-				}, {
-					fieldtype:'Link',
-					fieldname:"item_code",
-					options: 'Item',
-					in_list_view: 1,
-					read_only: 0,
-					disabled: 0,
-					label: __('Item Code')
-				}, {
-					fieldtype:'Float',
-					fieldname:"qty",
-					default: 0,
-					read_only: 0,
-					in_list_view: 1,
-					label: __('Qty')
-				}, {
-					fieldtype:'Currency',
-					fieldname:"rate",
-					default: 0,
-					read_only: 0,
-					in_list_view: 1,
-					label: __('Rate')
-				}]
+				fields: fields
 			},
 		],
 		primary_action: function() {
@@ -506,6 +517,8 @@
 			"docname": d.name,
 			"name": d.name,
 			"item_code": d.item_code,
+			"delivery_date": d.delivery_date,
+			"schedule_date": d.schedule_date,
 			"qty": d.qty,
 			"rate": d.rate,
 		});
diff --git a/erpnext/selling/sales_common.js b/erpnext/selling/sales_common.js
index af10069..095b7c3 100644
--- a/erpnext/selling/sales_common.js
+++ b/erpnext/selling/sales_common.js
@@ -228,9 +228,15 @@
 	warehouse: function(doc, cdt, cdn) {
 		var me = this;
 		var item = frappe.get_doc(cdt, cdn);
+
+		if (item.serial_no && item.qty === item.serial_no.split(`\n`).length) {
+			return;
+		}
+
 		if (item.serial_no && !item.batch_no) {
 			item.serial_no = null;
 		}
+
 		var has_batch_no;
 		frappe.db.get_value('Item', {'item_code': item.item_code}, 'has_batch_no', (r) => {
 			has_batch_no = r && r.has_batch_no;
diff --git a/erpnext/stock/doctype/delivery_note/test_delivery_note.py b/erpnext/stock/doctype/delivery_note/test_delivery_note.py
index 47a72b2..d7a93fb 100644
--- a/erpnext/stock/doctype/delivery_note/test_delivery_note.py
+++ b/erpnext/stock/doctype/delivery_note/test_delivery_note.py
@@ -434,15 +434,6 @@
 		update_delivery_note_status(dn.name, "Closed")
 		self.assertEqual(frappe.db.get_value("Delivery Note", dn.name, "Status"), "Closed")
 
-	def test_customer_provided_parts_dn(self):
-		create_item('CUST-0987', is_customer_provided_item = 1, customer = '_Test Customer', is_purchase_item = 0)
-		dn = create_delivery_note(item_code='CUST-0987', rate=0)
-		self.assertEqual(dn.get("items")[0].allow_zero_valuation_rate, 1)
-
-		# test if Delivery Note with rate is allowed against Customer Provided Item
-		dn2 = create_delivery_note(item_code='CUST-0987', do_not_save=True)
-		self.assertRaises(frappe.ValidationError, dn2.save)
-
 	def test_dn_billing_status_case1(self):
 		# SO -> DN -> SI
 		so = make_sales_order()
diff --git a/erpnext/stock/doctype/item/item.json b/erpnext/stock/doctype/item/item.json
index aa6b2fe..7d2e311 100644
--- a/erpnext/stock/doctype/item/item.json
+++ b/erpnext/stock/doctype/item/item.json
@@ -114,6 +114,8 @@
   "is_sub_contracted_item",
   "column_break_74",
   "customer_code",
+  "default_item_manufacturer",
+  "default_manufacturer_part_no",
   "website_section",
   "show_in_website",
   "show_variant_in_website",
@@ -1038,6 +1040,18 @@
    "fieldname": "auto_create_assets",
    "fieldtype": "Check",
    "label": "Auto Create Assets on Purchase"
+  },
+  {
+   "fieldname": "default_item_manufacturer",
+   "fieldtype": "Data",
+   "label": "Default Item Manufacturer",
+   "read_only": 1
+  },
+  {
+   "fieldname": "default_manufacturer_part_no",
+   "fieldtype": "Data",
+   "label": "Default Manufacturer Part No",
+   "read_only": 1
   }
  ],
  "has_web_view": 1,
@@ -1046,7 +1060,7 @@
  "image_field": "image",
  "links": [],
  "max_attachments": 1,
- "modified": "2020-03-24 16:14:36.950677",
+ "modified": "2020-04-07 15:56:06.195722",
  "modified_by": "Administrator",
  "module": "Stock",
  "name": "Item",
diff --git a/erpnext/stock/doctype/item_manufacturer/item_manufacturer.json b/erpnext/stock/doctype/item_manufacturer/item_manufacturer.json
index 956c92e..0cef6ea 100644
--- a/erpnext/stock/doctype/item_manufacturer/item_manufacturer.json
+++ b/erpnext/stock/doctype/item_manufacturer/item_manufacturer.json
@@ -1,4 +1,5 @@
 {
+ "actions": [],
  "allow_import": 1,
  "creation": "2019-06-02 04:41:37.332911",
  "doctype": "DocType",
@@ -10,7 +11,8 @@
   "manufacturer_part_no",
   "column_break_3",
   "item_name",
-  "description"
+  "description",
+  "is_default"
  ],
  "fields": [
   {
@@ -52,9 +54,17 @@
    "fieldtype": "Small Text",
    "label": "Description",
    "read_only": 1
+  },
+  {
+   "default": "0",
+   "fieldname": "is_default",
+   "fieldtype": "Check",
+   "in_list_view": 1,
+   "label": "Is Default"
   }
  ],
- "modified": "2019-06-06 19:07:31.175919",
+ "links": [],
+ "modified": "2020-04-07 20:25:55.507905",
  "modified_by": "Administrator",
  "module": "Stock",
  "name": "Item Manufacturer",
diff --git a/erpnext/stock/doctype/item_manufacturer/item_manufacturer.py b/erpnext/stock/doctype/item_manufacturer/item_manufacturer.py
index 67eab82..c27d1be 100644
--- a/erpnext/stock/doctype/item_manufacturer/item_manufacturer.py
+++ b/erpnext/stock/doctype/item_manufacturer/item_manufacturer.py
@@ -11,6 +11,10 @@
 class ItemManufacturer(Document):
 	def validate(self):
 		self.validate_duplicate_entry()
+		self.manage_default_item_manufacturer()
+
+	def on_trash(self):
+		self.manage_default_item_manufacturer(delete=True)
 
 	def validate_duplicate_entry(self):
 		if self.is_new():
@@ -24,6 +28,40 @@
 				frappe.throw(_("Duplicate entry against the item code {0} and manufacturer {1}")
 					.format(self.item_code, self.manufacturer))
 
+	def manage_default_item_manufacturer(self, delete=False):
+		from frappe.model.utils import set_default
+
+		item = frappe.get_doc("Item", self.item_code)
+		default_manufacturer = item.default_item_manufacturer
+		default_part_no = item.default_manufacturer_part_no
+
+		if not self.is_default:
+			# if unchecked and default in Item master, clear it.
+			if default_manufacturer == self.manufacturer and default_part_no == self.manufacturer_part_no:
+				frappe.db.set_value("Item", item.name,
+					{
+						"default_item_manufacturer": None,
+						"default_manufacturer_part_no": None
+					})
+
+		elif self.is_default:
+			set_default(self, "item_code")
+			manufacturer, manufacturer_part_no = default_manufacturer, default_part_no
+
+			if delete:
+				manufacturer, manufacturer_part_no = None, None
+
+			elif (default_manufacturer != self.manufacturer) or \
+				(default_manufacturer == self.manufacturer and default_part_no != self.manufacturer_part_no):
+				manufacturer = self.manufacturer
+				manufacturer_part_no = self.manufacturer_part_no
+
+			frappe.db.set_value("Item", item.name,
+					{
+						"default_item_manufacturer": manufacturer,
+						"default_manufacturer_part_no": manufacturer_part_no
+					})
+
 @frappe.whitelist()
 def get_item_manufacturer_part_no(item_code, manufacturer):
 	return frappe.db.get_value("Item Manufacturer",
diff --git a/erpnext/stock/doctype/material_request/material_request.py b/erpnext/stock/doctype/material_request/material_request.py
index 5b242a5..2d98557 100644
--- a/erpnext/stock/doctype/material_request/material_request.py
+++ b/erpnext/stock/doctype/material_request/material_request.py
@@ -175,12 +175,11 @@
 
 				frappe.db.set_value(d.doctype, d.name, "ordered_qty", d.ordered_qty)
 
-		target_ref_field = 'qty' if self.material_request_type == "Manufacture" else 'stock_qty'
 		self._update_percent_field({
 			"target_dt": "Material Request Item",
 			"target_parent_dt": self.doctype,
 			"target_parent_field": "per_ordered",
-			"target_ref_field": target_ref_field,
+			"target_ref_field": "stock_qty",
 			"target_field": "ordered_qty",
 			"name": self.name,
 		}, update_modified)
@@ -499,7 +498,7 @@
 	default_wip_warehouse = frappe.db.get_single_value("Manufacturing Settings", "default_wip_warehouse")
 
 	for d in mr.items:
-		if (d.qty - d.ordered_qty) >0:
+		if (d.stock_qty - d.ordered_qty) > 0:
 			if frappe.db.exists("BOM", {"item": d.item_code, "is_default": 1}):
 				wo_order = frappe.new_doc("Work Order")
 				wo_order.update({
@@ -531,7 +530,7 @@
 		msgprint(_("The following Work Orders were created:") + '\n' + new_line_sep(message))
 
 	if errors:
-		frappe.throw(_("Productions Orders cannot be raised for:") + '\n' + new_line_sep(errors))
+		frappe.throw(_("Work Order cannot be created for following reason:") + '\n' + new_line_sep(errors))
 
 	return work_orders
 
diff --git a/erpnext/stock/doctype/material_request/test_material_request.py b/erpnext/stock/doctype/material_request/test_material_request.py
index b925aed..19924b1 100644
--- a/erpnext/stock/doctype/material_request/test_material_request.py
+++ b/erpnext/stock/doctype/material_request/test_material_request.py
@@ -7,7 +7,8 @@
 from __future__ import unicode_literals
 import frappe, unittest, erpnext
 from frappe.utils import flt, today
-from erpnext.stock.doctype.material_request.material_request import raise_work_orders
+from erpnext.stock.doctype.material_request.material_request \
+	import raise_work_orders, make_stock_entry, make_purchase_order, make_supplier_quotation
 from erpnext.stock.doctype.item.test_item import create_item
 
 class TestMaterialRequest(unittest.TestCase):
@@ -15,8 +16,6 @@
 		erpnext.set_perpetual_inventory(0)
 
 	def test_make_purchase_order(self):
-		from erpnext.stock.doctype.material_request.material_request import make_purchase_order
-
 		mr = frappe.copy_doc(test_records[0]).insert()
 
 		self.assertRaises(frappe.ValidationError, make_purchase_order,
@@ -30,8 +29,6 @@
 		self.assertEqual(len(po.get("items")), len(mr.get("items")))
 
 	def test_make_supplier_quotation(self):
-		from erpnext.stock.doctype.material_request.material_request import make_supplier_quotation
-
 		mr = frappe.copy_doc(test_records[0]).insert()
 
 		self.assertRaises(frappe.ValidationError, make_supplier_quotation, mr.name)
@@ -45,12 +42,9 @@
 
 
 	def test_make_stock_entry(self):
-		from erpnext.stock.doctype.material_request.material_request import make_stock_entry
-
 		mr = frappe.copy_doc(test_records[0]).insert()
 
-		self.assertRaises(frappe.ValidationError, make_stock_entry,
-			mr.name)
+		self.assertRaises(frappe.ValidationError, make_stock_entry, mr.name)
 
 		mr = frappe.get_doc("Material Request", mr.name)
 		mr.material_request_type = "Material Transfer"
@@ -62,40 +56,40 @@
 
 	def _insert_stock_entry(self, qty1, qty2, warehouse = None ):
 		se = frappe.get_doc({
-				"company": "_Test Company",
-				"doctype": "Stock Entry",
-				"posting_date": "2013-03-01",
-				"posting_time": "00:00:00",
-				"purpose": "Material Receipt",
-				"items": [
-					{
-						"conversion_factor": 1.0,
-						"doctype": "Stock Entry Detail",
-						"item_code": "_Test Item Home Desktop 100",
-						"parentfield": "items",
-						"basic_rate": 100,
-						"qty": qty1,
-						"stock_uom": "_Test UOM 1",
-						"transfer_qty": qty1,
-						"uom": "_Test UOM 1",
-						"t_warehouse": warehouse or "_Test Warehouse 1 - _TC",
-						"cost_center": "_Test Cost Center - _TC"
-					},
-					{
-						"conversion_factor": 1.0,
-						"doctype": "Stock Entry Detail",
-						"item_code": "_Test Item Home Desktop 200",
-						"parentfield": "items",
-						"basic_rate": 100,
-						"qty": qty2,
-						"stock_uom": "_Test UOM 1",
-						"transfer_qty": qty2,
-						"uom": "_Test UOM 1",
-						"t_warehouse": warehouse or "_Test Warehouse 1 - _TC",
-						"cost_center": "_Test Cost Center - _TC"
-					}
-				]
-			})
+			"company": "_Test Company",
+			"doctype": "Stock Entry",
+			"posting_date": "2013-03-01",
+			"posting_time": "00:00:00",
+			"purpose": "Material Receipt",
+			"items": [
+				{
+					"conversion_factor": 1.0,
+					"doctype": "Stock Entry Detail",
+					"item_code": "_Test Item Home Desktop 100",
+					"parentfield": "items",
+					"basic_rate": 100,
+					"qty": qty1,
+					"stock_uom": "_Test UOM 1",
+					"transfer_qty": qty1,
+					"uom": "_Test UOM 1",
+					"t_warehouse": warehouse or "_Test Warehouse 1 - _TC",
+					"cost_center": "_Test Cost Center - _TC"
+				},
+				{
+					"conversion_factor": 1.0,
+					"doctype": "Stock Entry Detail",
+					"item_code": "_Test Item Home Desktop 200",
+					"parentfield": "items",
+					"basic_rate": 100,
+					"qty": qty2,
+					"stock_uom": "_Test UOM 1",
+					"transfer_qty": qty2,
+					"uom": "_Test UOM 1",
+					"t_warehouse": warehouse or "_Test Warehouse 1 - _TC",
+					"cost_center": "_Test Cost Center - _TC"
+				}
+			]
+		})
 
 		se.set_stock_entry_type()
 		se.insert()
@@ -198,14 +192,7 @@
 		mr.insert()
 		mr.submit()
 
-		# check if per complete is None
-		mr.load_from_db()
-		self.assertEqual(mr.per_ordered, 0)
-		self.assertEqual(mr.get("items")[0].ordered_qty, 0)
-		self.assertEqual(mr.get("items")[1].ordered_qty, 0)
-
 		# map a purchase order
-		from erpnext.stock.doctype.material_request.material_request import make_purchase_order
 		po_doc = make_purchase_order(mr.name)
 		po_doc.supplier = "_Test Supplier"
 		po_doc.transaction_date = "2013-07-07"
@@ -276,10 +263,8 @@
 		current_requested_qty_item1 = self._get_requested_qty("_Test Item Home Desktop 100", "_Test Warehouse - _TC")
 		current_requested_qty_item2 = self._get_requested_qty("_Test Item Home Desktop 200", "_Test Warehouse - _TC")
 
-		self.assertEqual(current_requested_qty_item1, existing_requested_qty_item1 - 54.0)
-		self.assertEqual(current_requested_qty_item2, existing_requested_qty_item2 - 3.0)
-
-		from erpnext.stock.doctype.material_request.material_request import make_stock_entry
+		self.assertEqual(current_requested_qty_item1, existing_requested_qty_item1 + 54.0)
+		self.assertEqual(current_requested_qty_item2, existing_requested_qty_item2 + 3.0)
 
 		# map a stock entry
 		se_doc = make_stock_entry(mr.name)
@@ -331,8 +316,8 @@
 		current_requested_qty_item1 = self._get_requested_qty("_Test Item Home Desktop 100", "_Test Warehouse - _TC")
 		current_requested_qty_item2 = self._get_requested_qty("_Test Item Home Desktop 200", "_Test Warehouse - _TC")
 
-		self.assertEqual(current_requested_qty_item1, existing_requested_qty_item1 - 27.0)
-		self.assertEqual(current_requested_qty_item2, existing_requested_qty_item2 - 1.5)
+		self.assertEqual(current_requested_qty_item1, existing_requested_qty_item1 + 27.0)
+		self.assertEqual(current_requested_qty_item2, existing_requested_qty_item2 + 1.5)
 
 		# check if per complete is as expected for Stock Entry cancelled
 		se.cancel()
@@ -344,8 +329,8 @@
 		current_requested_qty_item1 = self._get_requested_qty("_Test Item Home Desktop 100", "_Test Warehouse - _TC")
 		current_requested_qty_item2 = self._get_requested_qty("_Test Item Home Desktop 200", "_Test Warehouse - _TC")
 
-		self.assertEqual(current_requested_qty_item1, existing_requested_qty_item1 - 54.0)
-		self.assertEqual(current_requested_qty_item2, existing_requested_qty_item2 - 3.0)
+		self.assertEqual(current_requested_qty_item1, existing_requested_qty_item1 + 54.0)
+		self.assertEqual(current_requested_qty_item2, existing_requested_qty_item2 + 3.0)
 
 	def test_completed_qty_for_over_transfer(self):
 		existing_requested_qty_item1 = self._get_requested_qty("_Test Item Home Desktop 100", "_Test Warehouse - _TC")
@@ -357,14 +342,7 @@
 		mr.insert()
 		mr.submit()
 
-		# check if per complete is None
-		mr.load_from_db()
-		self.assertEqual(mr.per_ordered, 0)
-		self.assertEqual(mr.get("items")[0].ordered_qty, 0)
-		self.assertEqual(mr.get("items")[1].ordered_qty, 0)
-
 		# map a stock entry
-		from erpnext.stock.doctype.material_request.material_request import make_stock_entry
 
 		se_doc = make_stock_entry(mr.name)
 		se_doc.update({
@@ -425,8 +403,8 @@
 		current_requested_qty_item1 = self._get_requested_qty("_Test Item Home Desktop 100", "_Test Warehouse - _TC")
 		current_requested_qty_item2 = self._get_requested_qty("_Test Item Home Desktop 200", "_Test Warehouse - _TC")
 
-		self.assertEqual(current_requested_qty_item1, existing_requested_qty_item1 - 54.0)
-		self.assertEqual(current_requested_qty_item2, existing_requested_qty_item2 - 3.0)
+		self.assertEqual(current_requested_qty_item1, existing_requested_qty_item1 + 54.0)
+		self.assertEqual(current_requested_qty_item2, existing_requested_qty_item2 + 3.0)
 
 	def test_incorrect_mapping_of_stock_entry(self):
 		# submit material request of type Transfer
@@ -435,9 +413,6 @@
 		mr.insert()
 		mr.submit()
 
-		# map a stock entry
-		from erpnext.stock.doctype.material_request.material_request import make_stock_entry
-
 		se_doc = make_stock_entry(mr.name)
 		se_doc.update({
 			"posting_date": "2013-03-01",
@@ -468,8 +443,6 @@
 		mr.insert()
 		mr.submit()
 
-		# map a stock entry
-		from erpnext.stock.doctype.material_request.material_request import make_stock_entry
 		se_doc = make_stock_entry(mr.name)
 		self.assertEqual(se_doc.get("items")[0].s_warehouse, "_Test Warehouse - _TC")
 
@@ -483,8 +456,6 @@
 		return flt(frappe.db.get_value("Bin", {"item_code": item_code, "warehouse": warehouse}, "indented_qty"))
 
 	def test_make_stock_entry_for_material_issue(self):
-		from erpnext.stock.doctype.material_request.material_request import make_stock_entry
-
 		mr = frappe.copy_doc(test_records[0]).insert()
 
 		self.assertRaises(frappe.ValidationError, make_stock_entry,
@@ -503,8 +474,6 @@
 			return flt(frappe.db.get_value("Bin", {"item_code": "_Test Item Home Desktop 100",
 				"warehouse": "_Test Warehouse - _TC"}, "indented_qty"))
 
-		from erpnext.stock.doctype.material_request.material_request import make_stock_entry
-
 		existing_requested_qty = _get_requested_qty()
 
 		mr = frappe.copy_doc(test_records[0])
@@ -563,9 +532,37 @@
 			item_code= %s and warehouse= %s """, (mr.items[0].item_code, mr.items[0].warehouse))[0][0]
 		self.assertEqual(requested_qty, new_requested_qty)
 
-	def test_multi_uom_for_purchase(self):
-		from erpnext.stock.doctype.material_request.material_request import make_purchase_order
+	def test_requested_qty_multi_uom(self):
+		existing_requested_qty = self._get_requested_qty('_Test FG Item', '_Test Warehouse - _TC')
 
+		mr = make_material_request(item_code='_Test FG Item', material_request_type='Manufacture',
+			uom="_Test UOM 1", conversion_factor=12)
+		
+		requested_qty = self._get_requested_qty('_Test FG Item', '_Test Warehouse - _TC')
+
+		self.assertEqual(requested_qty, existing_requested_qty + 120)
+
+		work_order = raise_work_orders(mr.name)
+		wo = frappe.get_doc("Work Order", work_order[0])
+		wo.qty = 50
+		wo.wip_warehouse = "_Test Warehouse 1 - _TC"
+		wo.submit()
+
+		requested_qty = self._get_requested_qty('_Test FG Item', '_Test Warehouse - _TC')
+		self.assertEqual(requested_qty, existing_requested_qty + 70)
+
+		wo.cancel()
+
+		requested_qty = self._get_requested_qty('_Test FG Item', '_Test Warehouse - _TC')
+		self.assertEqual(requested_qty, existing_requested_qty + 120)
+
+		mr.reload()
+		mr.cancel()
+		requested_qty = self._get_requested_qty('_Test FG Item', '_Test Warehouse - _TC')
+		self.assertEqual(requested_qty, existing_requested_qty)
+
+
+	def test_multi_uom_for_purchase(self):
 		mr = frappe.copy_doc(test_records[0])
 		mr.material_request_type = 'Purchase'
 		item = mr.items[0]
@@ -607,7 +604,6 @@
 		self.assertEqual(mr.per_ordered, 100)
 
 	def test_customer_provided_parts_mr(self):
-		from erpnext.stock.doctype.material_request.material_request import make_stock_entry
 		create_item('CUST-0987', is_customer_provided_item = 1, customer = '_Test Customer', is_purchase_item = 0)
 		existing_requested_qty = self._get_requested_qty("_Test Customer", "_Test Warehouse - _TC")
 
@@ -633,6 +629,8 @@
 	mr.append("items", {
 		"item_code": args.item_code or "_Test Item",
 		"qty": args.qty or 10,
+		"uom": args.uom or "_Test UOM",
+		"conversion_factor": args.conversion_factor or 1,
 		"schedule_date": args.schedule_date or today(),
 		"warehouse": args.warehouse or "_Test Warehouse - _TC",
 		"cost_center": args.cost_center or "_Test Cost Center - _TC"
diff --git a/erpnext/stock/doctype/material_request_item/material_request_item.json b/erpnext/stock/doctype/material_request_item/material_request_item.json
index 9d1dafb..5604913 100644
--- a/erpnext/stock/doctype/material_request_item/material_request_item.json
+++ b/erpnext/stock/doctype/material_request_item/material_request_item.json
@@ -1,5 +1,4 @@
 {
- "actions": [],
  "autoname": "hash",
  "creation": "2013-02-22 01:28:02",
  "doctype": "DocType",
@@ -374,7 +373,10 @@
   {
    "fieldname": "received_qty",
    "fieldtype": "Float",
-   "label": "Received Quantity"
+   "label": "Received Quantity",
+   "no_copy": 1,
+   "print_hide": 1,
+   "read_only": 1
   },
   {
    "collapsible": 1,
@@ -404,14 +406,13 @@
   {
    "fieldname": "manufacturer_part_no",
    "fieldtype": "Data",
-   "label": "Manufacturer Part Number",
-   "read_only": 1
+   "label": "Manufacturer Part Number"
   }
  ],
  "idx": 1,
  "istable": 1,
  "links": [],
- "modified": "2020-02-25 03:09:10.698967",
+ "modified": "2020-04-16 09:00:00.992835",
  "modified_by": "Administrator",
  "module": "Stock",
  "name": "Material Request Item",
diff --git a/erpnext/stock/doctype/purchase_receipt/test_purchase_receipt.py b/erpnext/stock/doctype/purchase_receipt/test_purchase_receipt.py
index 113da9f..40d7cc2 100644
--- a/erpnext/stock/doctype/purchase_receipt/test_purchase_receipt.py
+++ b/erpnext/stock/doctype/purchase_receipt/test_purchase_receipt.py
@@ -356,8 +356,8 @@
 					'accounts': [{
 						'company_name': '_Test Company',
 						'fixed_asset_account': '_Test Fixed Asset - _TC',
-						'accumulated_depreciation_account': 'Depreciation - _TC',
-						'depreciation_expense_account': 'Depreciation - _TC'
+						'accumulated_depreciation_account': '_Test Accumulated Depreciations - _TC',
+						'depreciation_expense_account': '_Test Depreciation - _TC'
 					}]
 				}).insert()
 
diff --git a/erpnext/stock/doctype/purchase_receipt_item/purchase_receipt_item.json b/erpnext/stock/doctype/purchase_receipt_item/purchase_receipt_item.json
index a8b9c81..b15f23c 100644
--- a/erpnext/stock/doctype/purchase_receipt_item/purchase_receipt_item.json
+++ b/erpnext/stock/doctype/purchase_receipt_item/purchase_receipt_item.json
@@ -801,8 +801,7 @@
   {
    "fieldname": "manufacturer_part_no",
    "fieldtype": "Data",
-   "label": "Manufacturer Part Number",
-   "read_only": 1
+   "label": "Manufacturer Part Number"
   },
   {
    "depends_on": "is_fixed_asset",
@@ -832,7 +831,7 @@
  "idx": 1,
  "istable": 1,
  "links": [],
- "modified": "2020-03-11 14:19:48.799370",
+ "modified": "2020-04-07 18:38:21.141558",
  "modified_by": "Administrator",
  "module": "Stock",
  "name": "Purchase Receipt Item",
diff --git a/erpnext/stock/doctype/stock_entry/stock_entry.js b/erpnext/stock/doctype/stock_entry/stock_entry.js
index 3bb9415..d1048fc 100644
--- a/erpnext/stock/doctype/stock_entry/stock_entry.js
+++ b/erpnext/stock/doctype/stock_entry/stock_entry.js
@@ -220,8 +220,8 @@
 					},
 					get_query_filters: {
 						docstatus: 1,
-						material_request_type: "Material Transfer",
-						status: ['!=', 'Transferred']
+						material_request_type: ["in", ["Material Transfer", "Material Issue"]],
+						status: ["not in", ["Transferred", "Issued"]]
 					}
 				})
 			}, __("Get items from"));
diff --git a/erpnext/stock/get_item_details.py b/erpnext/stock/get_item_details.py
index b1bfc90..61429cc 100644
--- a/erpnext/stock/get_item_details.py
+++ b/erpnext/stock/get_item_details.py
@@ -341,6 +341,9 @@
 		else:
 			out["manufacturer_part_no"] = None
 			out["manufacturer"] = None
+	else:
+		out["manufacturer"], out["manufacturer_part_no"] = frappe.get_value("Item", item.name,
+			["default_item_manufacturer", "default_manufacturer_part_no"] )
 
 	child_doctype = args.doctype + ' Item'
 	meta = frappe.get_meta(child_doctype)
diff --git a/erpnext/stock/stock_balance.py b/erpnext/stock/stock_balance.py
index 2bdb04e..5697315 100644
--- a/erpnext/stock/stock_balance.py
+++ b/erpnext/stock/stock_balance.py
@@ -113,24 +113,30 @@
 	return flt(reserved_qty[0][0]) if reserved_qty else 0
 
 def get_indented_qty(item_code, warehouse):
-	inward_qty = frappe.db.sql("""select sum((mr_item.qty - mr_item.ordered_qty) * mr_item.conversion_factor)
-			from `tabMaterial Request Item` mr_item, `tabMaterial Request` mr
-			where mr_item.item_code=%s and mr_item.warehouse=%s
-			and mr.material_request_type in ('Purchase', 'Manufacture')
-			and mr_item.qty > mr_item.ordered_qty and mr_item.parent=mr.name
-			and mr.status!='Stopped' and mr.docstatus=1""", (item_code, warehouse))
-
-	outward_qty = frappe.db.sql("""select sum((mr_item.qty - mr_item.ordered_qty) * mr_item.conversion_factor)
+	# Ordered Qty is always maintained in stock UOM
+	inward_qty = frappe.db.sql("""
+		select sum(mr_item.stock_qty - mr_item.ordered_qty)
 		from `tabMaterial Request Item` mr_item, `tabMaterial Request` mr
 		where mr_item.item_code=%s and mr_item.warehouse=%s
-		and mr.material_request_type in ('Material Issue', 'Material Transfer')
-		and mr_item.qty > mr_item.ordered_qty and mr_item.parent=mr.name
-		and mr.status!='Stopped' and mr.docstatus=1""", (item_code, warehouse))
+			and mr.material_request_type in ('Purchase', 'Manufacture', 'Customer Provided', 'Material Transfer')
+			and mr_item.stock_qty > mr_item.ordered_qty and mr_item.parent=mr.name
+			and mr.status!='Stopped' and mr.docstatus=1
+	""", (item_code, warehouse))
+	inward_qty = flt(inward_qty[0][0]) if inward_qty else 0
 
-	inward_qty, outward_qty = flt(inward_qty[0][0]) if inward_qty else 0, flt(outward_qty[0][0]) if outward_qty else 0
-	indented_qty = inward_qty - outward_qty
+	outward_qty = frappe.db.sql("""
+		select sum(mr_item.stock_qty - mr_item.ordered_qty)
+		from `tabMaterial Request Item` mr_item, `tabMaterial Request` mr
+		where mr_item.item_code=%s and mr_item.warehouse=%s
+			and mr.material_request_type = 'Material Issue'
+			and mr_item.stock_qty > mr_item.ordered_qty and mr_item.parent=mr.name
+			and mr.status!='Stopped' and mr.docstatus=1
+	""", (item_code, warehouse))
+	outward_qty = flt(outward_qty[0][0]) if outward_qty else 0
 
-	return indented_qty
+	requested_qty = inward_qty - outward_qty
+
+	return requested_qty
 
 def get_ordered_qty(item_code, warehouse):
 	ordered_qty = frappe.db.sql("""