feat: Multi UOM support in Request for Quotation
diff --git a/erpnext/buying/doctype/request_for_quotation/request_for_quotation.py b/erpnext/buying/doctype/request_for_quotation/request_for_quotation.py
index 95db33b..dfdb487 100644
--- a/erpnext/buying/doctype/request_for_quotation/request_for_quotation.py
+++ b/erpnext/buying/doctype/request_for_quotation/request_for_quotation.py
@@ -25,6 +25,7 @@
 		self.validate_duplicate_supplier()
 		self.validate_supplier_list()
 		validate_for_items(self)
+		super(RequestforQuotation, self).set_qty_as_per_stock_uom()
 		self.update_email_id()
 
 	def validate_duplicate_supplier(self):
@@ -278,6 +279,7 @@
 		"description": data.description,
 		"qty": data.qty,
 		"rate": data.rate,
+		"conversion_factor": data.conversion_factor if data.conversion_factor else None,
 		"supplier_part_no": frappe.db.get_value("Item Supplier", {'parent': data.item_code, 'supplier': supplier}, "supplier_part_no"),
 		"warehouse": data.warehouse or '',
 		"request_for_quotation_item": data.name,
diff --git a/erpnext/buying/doctype/request_for_quotation/test_request_for_quotation.py b/erpnext/buying/doctype/request_for_quotation/test_request_for_quotation.py
index dbd9f02..3de9526 100644
--- a/erpnext/buying/doctype/request_for_quotation/test_request_for_quotation.py
+++ b/erpnext/buying/doctype/request_for_quotation/test_request_for_quotation.py
@@ -6,12 +6,14 @@
 import unittest
 
 import frappe
-from erpnext.templates.pages.rfq import check_supplier_has_docname_access
 from frappe.utils import nowdate
+from erpnext.stock.doctype.item.test_item import make_item
+from erpnext.templates.pages.rfq import check_supplier_has_docname_access
+from erpnext.buying.doctype.request_for_quotation.request_for_quotation import make_supplier_quotation
+from erpnext.buying.doctype.request_for_quotation.request_for_quotation import create_supplier_quotation
 
 class TestRequestforQuotation(unittest.TestCase):
 	def test_quote_status(self):
-		from erpnext.buying.doctype.request_for_quotation.request_for_quotation import make_supplier_quotation
 		rfq = make_request_for_quotation()
 
 		self.assertEqual(rfq.get('suppliers')[0].quote_status, 'Pending')
@@ -31,7 +33,6 @@
 		self.assertEqual(rfq.get('suppliers')[1].quote_status, 'No Quote')
 
 	def test_make_supplier_quotation(self):
-		from erpnext.buying.doctype.request_for_quotation.request_for_quotation import make_supplier_quotation
 		rfq = make_request_for_quotation()
 
 		sq = make_supplier_quotation(rfq.name, rfq.get('suppliers')[0].supplier)
@@ -51,15 +52,13 @@
 		self.assertEqual(sq1.get('items')[0].qty, 5)
 
 	def test_make_supplier_quotation_with_special_characters(self):
-		from erpnext.buying.doctype.request_for_quotation.request_for_quotation import make_supplier_quotation
-
 		frappe.delete_doc_if_exists("Supplier", "_Test Supplier '1", force=1)
 		supplier = frappe.new_doc("Supplier")
 		supplier.supplier_name = "_Test Supplier '1"
 		supplier.supplier_group = "_Test Supplier Group"
 		supplier.insert()
 
-		rfq = make_request_for_quotation(supplier_wt_appos)
+		rfq = make_request_for_quotation(supplier_data=supplier_wt_appos)
 
 		sq = make_supplier_quotation(rfq.name, supplier_wt_appos[0].get("supplier"))
 		sq.submit()
@@ -76,7 +75,6 @@
 		frappe.form_dict.name = None
 
 	def test_make_supplier_quotation_from_portal(self):
-		from erpnext.buying.doctype.request_for_quotation.request_for_quotation import create_supplier_quotation
 		rfq = make_request_for_quotation()
 		rfq.get('items')[0].rate = 100
 		rfq.supplier = rfq.suppliers[0].supplier
@@ -90,12 +88,34 @@
 		self.assertEqual(supplier_quotation_doc.get('items')[0].qty, 5)
 		self.assertEqual(supplier_quotation_doc.get('items')[0].amount, 500)
 
+	def test_make_multi_uom_supplier_quotation(self):
+		item_code = "_Test Multi UOM RFQ Item"
+		if not frappe.db.exists('Item', item_code):
+			item = make_item(item_code, {'stock_uom': '_Test UOM'})
+			row = item.append('uoms', {
+				'uom': 'Kg',
+				'conversion_factor': 2
+			})
+			row.db_update()
 
-def make_request_for_quotation(supplier_data=None):
+		rfq = make_request_for_quotation(item_code="_Test Multi UOM RFQ Item", uom="Kg", conversion_factor=2)
+		rfq.get('items')[0].rate = 100
+		rfq.supplier = rfq.suppliers[0].supplier
+
+		self.assertEqual(rfq.items[0].stock_qty, 10)
+
+		supplier_quotation_name = create_supplier_quotation(rfq)
+		supplier_quotation = frappe.get_doc('Supplier Quotation', supplier_quotation_name)
+
+		self.assertEqual(supplier_quotation.items[0].qty, 5)
+		self.assertEqual(supplier_quotation.items[0].stock_qty, 10)
+
+def make_request_for_quotation(**args):
 	"""
 	:param supplier_data: List containing supplier data
 	"""
-	supplier_data = supplier_data if supplier_data else get_supplier_data()
+	args = frappe._dict(args)
+	supplier_data = args.get("supplier_data") if args.get("supplier_data") else get_supplier_data()
 	rfq = frappe.new_doc('Request for Quotation')
 	rfq.transaction_date = nowdate()
 	rfq.status = 'Draft'
@@ -106,11 +126,13 @@
 		rfq.append('suppliers', data)
 
 	rfq.append("items", {
-		"item_code": "_Test Item",
+		"item_code": args.item_code or "_Test Item",
 		"description": "_Test Item",
-		"uom": "_Test UOM",
-		"qty": 5,
-		"warehouse": "_Test Warehouse - _TC",
+		"uom": args.uom or "_Test UOM",
+		"stock_uom": args.stock_uom or "_Test UOM",
+		"qty": args.qty or 5,
+		"conversion_factor": args.conversion_factor or 1.0,
+		"warehouse": args.warehouse or "_Test Warehouse - _TC",
 		"schedule_date": nowdate()
 	})
 
diff --git a/erpnext/buying/doctype/request_for_quotation_item/request_for_quotation_item.json b/erpnext/buying/doctype/request_for_quotation_item/request_for_quotation_item.json
index 0159df9..408f49f 100644
--- a/erpnext/buying/doctype/request_for_quotation_item/request_for_quotation_item.json
+++ b/erpnext/buying/doctype/request_for_quotation_item/request_for_quotation_item.json
@@ -1,4 +1,5 @@
 {
+ "actions": [],
  "autoname": "hash",
  "creation": "2016-02-25 08:04:02.452958",
  "doctype": "DocType",
@@ -9,6 +10,7 @@
   "supplier_part_no",
   "column_break_3",
   "item_name",
+  "schedule_date",
   "section_break_5",
   "description",
   "item_group",
@@ -18,9 +20,11 @@
   "image_view",
   "quantity",
   "qty",
+  "stock_uom",
   "col_break2",
-  "schedule_date",
   "uom",
+  "conversion_factor",
+  "stock_qty",
   "warehouse_and_reference",
   "warehouse",
   "project_name",
@@ -33,7 +37,7 @@
  "fields": [
   {
    "bold": 1,
-   "columns": 3,
+   "columns": 2,
    "fieldname": "item_code",
    "fieldtype": "Link",
    "in_list_view": 1,
@@ -98,7 +102,7 @@
   {
    "fieldname": "quantity",
    "fieldtype": "Section Break",
-   "label": "Quantity"
+   "label": "Quantity & Stock"
   },
   {
    "bold": 1,
@@ -129,12 +133,12 @@
   {
    "fieldname": "uom",
    "fieldtype": "Link",
+   "in_list_view": 1,
    "label": "UOM",
    "oldfieldname": "uom",
    "oldfieldtype": "Link",
    "options": "UOM",
    "print_width": "100px",
-   "read_only": 1,
    "reqd": 1,
    "width": "100px"
   },
@@ -144,7 +148,7 @@
    "label": "Warehouse and Reference"
   },
   {
-   "columns": 3,
+   "columns": 2,
    "fieldname": "warehouse",
    "fieldtype": "Link",
    "in_list_view": 1,
@@ -202,6 +206,7 @@
   },
   {
    "allow_on_submit": 1,
+   "default": "0",
    "fieldname": "page_break",
    "fieldtype": "Check",
    "label": "Page Break",
@@ -219,10 +224,36 @@
   {
    "fieldname": "section_break_23",
    "fieldtype": "Section Break"
+  },
+  {
+   "fieldname": "stock_uom",
+   "fieldtype": "Link",
+   "label": "Stock UOM",
+   "options": "UOM",
+   "print_hide": 1,
+   "read_only": 1,
+   "reqd": 1
+  },
+  {
+   "fieldname": "conversion_factor",
+   "fieldtype": "Float",
+   "label": "UOM Conversion Factor",
+   "print_hide": 1,
+   "read_only": 1,
+   "reqd": 1
+  },
+  {
+   "fieldname": "stock_qty",
+   "fieldtype": "Float",
+   "label": "Qty as per Stock UOM",
+   "no_copy": 1,
+   "print_hide": 1,
+   "read_only": 1
   }
  ],
  "istable": 1,
- "modified": "2019-05-01 17:50:23.703801",
+ "links": [],
+ "modified": "2020-06-12 19:10:36.333441",
  "modified_by": "Administrator",
  "module": "Buying",
  "name": "Request for Quotation Item",
diff --git a/erpnext/patches.txt b/erpnext/patches.txt
index 1f5d4d5..e999cfe 100644
--- a/erpnext/patches.txt
+++ b/erpnext/patches.txt
@@ -696,3 +696,4 @@
 erpnext.patches.v12_0.update_uom_conversion_factor
 erpnext.patches.v13_0.delete_old_purchase_reports
 erpnext.patches.v12_0.set_italian_import_supplier_invoice_permissions
+erpnext.patches.v12_0.set_multi_uom_in_rfq
diff --git a/erpnext/patches/v12_0/set_multi_uom_in_rfq.py b/erpnext/patches/v12_0/set_multi_uom_in_rfq.py
new file mode 100644
index 0000000..50725bb
--- /dev/null
+++ b/erpnext/patches/v12_0/set_multi_uom_in_rfq.py
@@ -0,0 +1,29 @@
+# Copyright (c) 2017, Frappe and Contributors
+# License: GNU General Public License v3. See license.txt
+
+from __future__ import unicode_literals
+import frappe
+from frappe.utils import flt
+from erpnext.stock.get_item_details import get_conversion_factor
+
+def execute():
+	frappe.reload_doc('buying', 'doctype', 'request_for_quotation_item')
+
+	for rfq_item in frappe.db.sql("""SELECT name, item_code, uom, qty FROM `tabRequest for Quotation Item` WHERE docstatus<2""", as_dict=1):
+		item_code, uom, qty = rfq_item.get("item_code"), rfq_item.get("uom"), rfq_item.get("qty")
+		conversion_factor = get_conversion_factor(item_code, uom).get("conversion_factor") or 1.0
+
+		filters = {
+			"name" : rfq_item.get("name"),
+			"stock_uom" : frappe.db.get_value("Item", item_code, "stock_uom"),
+			"conversion_factor" : conversion_factor,
+			"stock_qty" : flt(qty) * flt(conversion_factor)
+		}
+
+		frappe.db.sql("""UPDATE `tabRequest for Quotation Item`
+			SET
+				stock_uom= %(stock_uom)s,
+				conversion_factor = %(conversion_factor)s,
+				stock_qty = %(stock_qty)s
+			WHERE
+				name = %(name)s""", filters)
\ No newline at end of file