fix: requested qty calculation and some other small fixes (#21296)

* fix: Made received qty readonly and no-copy

* fix: Made release date mandatory

* fix: requested qty calculation fix for UOM
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/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..30c47c3 100644
--- a/erpnext/stock/doctype/material_request/test_material_request.py
+++ b/erpnext/stock/doctype/material_request/test_material_request.py
@@ -563,6 +563,36 @@
 			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_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):
 		from erpnext.stock.doctype.material_request.material_request import make_purchase_order
 
@@ -633,6 +663,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 30206b6..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,
@@ -410,7 +412,7 @@
  "idx": 1,
  "istable": 1,
  "links": [],
- "modified": "2020-04-07 18:37:54.495112",
+ "modified": "2020-04-16 09:00:00.992835",
  "modified_by": "Administrator",
  "module": "Stock",
  "name": "Material Request Item",
diff --git a/erpnext/stock/stock_balance.py b/erpnext/stock/stock_balance.py
index 2bdb04e..d9434e3 100644
--- a/erpnext/stock/stock_balance.py
+++ b/erpnext/stock/stock_balance.py
@@ -113,24 +113,32 @@
 	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 maintained in purchase UOM
+	requested_qty_for_purchase_and_manufacture = 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')
+			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))
+	requested_qty_for_purchase_and_manufacture = flt(requested_qty_for_purchase_and_manufacture[0][0]) \
+		if requested_qty_for_purchase_and_manufacture 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
+	requested_qty_for_issue_and_transfer = 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.stock_qty > mr_item.ordered_qty and mr_item.parent=mr.name
+			and mr.status!='Stopped' and mr.docstatus=1
+	""", (item_code, warehouse))
+	requested_qty_for_issue_and_transfer = flt(requested_qty_for_issue_and_transfer[0][0]) \
+		if requested_qty_for_issue_and_transfer else 0
 
-	return indented_qty
+	requested_qty = requested_qty_for_purchase_and_manufacture - requested_qty_for_issue_and_transfer
+
+	return requested_qty
 
 def get_ordered_qty(item_code, warehouse):
 	ordered_qty = frappe.db.sql("""