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