From f7e42211b91a67d09c94346d58a48cd0c63b70f1 Mon Sep 17 00:00:00 2001 From: Ben Cornwell-Mott Date: Wed, 26 Jul 2017 23:09:01 -0700 Subject: [PATCH 1/8] Added Quote Status to RFQ Suppliers with No Quote --- .../request_for_quotation.js | 25 ++++++- .../request_for_quotation.py | 22 +++++++ .../request_for_quotation_supplier.json | 65 ++++++++++++++++++- .../supplier_quotation/supplier_quotation.py | 34 ++++++++++ .../manual/en/buying/request-for-quotation.md | 32 ++++----- 5 files changed, 160 insertions(+), 18 deletions(-) diff --git a/erpnext/buying/doctype/request_for_quotation/request_for_quotation.js b/erpnext/buying/doctype/request_for_quotation/request_for_quotation.js index 558e072cade..6b37edafc79 100644 --- a/erpnext/buying/doctype/request_for_quotation/request_for_quotation.js +++ b/erpnext/buying/doctype/request_for_quotation/request_for_quotation.js @@ -138,7 +138,6 @@ frappe.ui.form.on("Request for Quotation",{ dialog.show(); }, - make_suppplier_quotation: function(frm) { var doc = frm.doc; var dialog = new frappe.ui.Dialog({ @@ -207,6 +206,30 @@ frappe.ui.form.on("Request for Quotation Supplier",{ if(!w) { frappe.msgprint(__("Please enable pop-ups")); return; } + }, + no_quote: function(frm, cdt, cdn) { + var d = locals[cdt][cdn]; + if (d.no_quote) { + if (d.quote_status != __('Received')) { + frappe.model.set_value(cdt, cdn, 'quote_status', 'No Quote'); + } else { + frappe.msgprint(__("Cannot set a received RFQ to No Quote")); + frappe.model.set_value(cdt, cdn, 'no_quote', 0); + } + } else { + d.quote_status = __('Pending'); + frm.call({ + method:"update_rfq_supplier_status", + doc: frm.doc, + args: { + sup_name: d.supplier + }, + callback: function(r) { + frm.refresh_field("suppliers"); + } + }); + } + } }) 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 e9603fbcaeb..a8e897c2ddd 100644 --- a/erpnext/buying/doctype/request_for_quotation/request_for_quotation.py +++ b/erpnext/buying/doctype/request_for_quotation/request_for_quotation.py @@ -54,6 +54,7 @@ class RequestforQuotation(BuyingController): frappe.db.set(self, 'status', 'Submitted') for supplier in self.suppliers: supplier.email_sent = 0 + supplier.quote_status = 'Pending' def on_cancel(self): frappe.db.set(self, 'status', 'Cancelled') @@ -157,6 +158,27 @@ class RequestforQuotation(BuyingController): attachments.append(frappe.attach_print(self.doctype, self.name, doc=self)) return attachments + def update_rfq_supplier_status(self, sup_name=None): + for supplier in self.suppliers: + if sup_name != None and supplier.supplier == sup_name: + if supplier.quote_status != _('No Quote'): + quote_status = _('Received') + for item in self.items: + sqi_count = frappe.db.sql(""" + SELECT + COUNT(sqi.name) as count + FROM + `tabSupplier Quotation Item` as sqi, + `tabSupplier Quotation` as sq + WHERE sq.supplier = %(supplier)s + AND sqi.docstatus = 1 + AND sqi.request_for_quotation_item = %(rqi)s + AND sqi.parent = sq.name""", {"supplier": supplier.supplier, "rqi": item.name}, as_dict=1)[0] + if (sqi_count.count) == 0: + quote_status = _('Pending') + supplier.quote_status = quote_status + + @frappe.whitelist() def send_supplier_emails(rfq_name): check_portal_enabled('Request for Quotation') diff --git a/erpnext/buying/doctype/request_for_quotation_supplier/request_for_quotation_supplier.json b/erpnext/buying/doctype/request_for_quotation_supplier/request_for_quotation_supplier.json index a7c5a376838..4babbe92d50 100644 --- a/erpnext/buying/doctype/request_for_quotation_supplier/request_for_quotation_supplier.json +++ b/erpnext/buying/doctype/request_for_quotation_supplier/request_for_quotation_supplier.json @@ -137,6 +137,69 @@ "set_only_once": 0, "unique": 0 }, + { + "allow_bulk_edit": 0, + "allow_on_submit": 1, + "bold": 0, + "collapsible": 0, + "columns": 0, + "depends_on": "eval:doc.docstatus >= 1 && doc.quote_status != 'Received'", + "fieldname": "no_quote", + "fieldtype": "Check", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_global_search": 0, + "in_list_view": 0, + "in_standard_filter": 0, + "label": "No Quote", + "length": 0, + "no_copy": 0, + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 0, + "remember_last_selected_value": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, + "unique": 0 + }, + { + "allow_bulk_edit": 0, + "allow_on_submit": 1, + "bold": 0, + "collapsible": 0, + "columns": 0, + "depends_on": "eval:doc.docstatus >= 1 && !doc.no_quote", + "fieldname": "quote_status", + "fieldtype": "Select", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_global_search": 0, + "in_list_view": 0, + "in_standard_filter": 0, + "label": "Quote Status", + "length": 0, + "no_copy": 0, + "options": "Pending\nReceived\nNo Quote", + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 1, + "remember_last_selected_value": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, + "unique": 0 + }, { "allow_bulk_edit": 0, "allow_on_submit": 0, @@ -269,7 +332,7 @@ "issingle": 0, "istable": 1, "max_attachments": 0, - "modified": "2017-07-24 06:52:19.542717", + "modified": "2017-07-26 22:25:58.096584", "modified_by": "Administrator", "module": "Buying", "name": "Request for Quotation Supplier", diff --git a/erpnext/buying/doctype/supplier_quotation/supplier_quotation.py b/erpnext/buying/doctype/supplier_quotation/supplier_quotation.py index 1cb5a18662c..5e17dce6101 100644 --- a/erpnext/buying/doctype/supplier_quotation/supplier_quotation.py +++ b/erpnext/buying/doctype/supplier_quotation/supplier_quotation.py @@ -31,9 +31,11 @@ class SupplierQuotation(BuyingController): def on_submit(self): frappe.db.set(self, "status", "Submitted") + self.update_rfq_supplier_status(1) def on_cancel(self): frappe.db.set(self, "status", "Cancelled") + self.update_rfq_supplier_status(0) def on_trash(self): pass @@ -50,6 +52,38 @@ class SupplierQuotation(BuyingController): "is_child_table": True } }) + def update_rfq_supplier_status(self, include_me): + rfq_list = set([]) + for item in self.items: + if item.request_for_quotation: + rfq_list.add(item.request_for_quotation) + for rfq in rfq_list: + doc = frappe.get_doc('Request for Quotation', rfq) + doc_sup = frappe.get_all('Request for Quotation Supplier', filters= + {'parent': doc.name, 'supplier': self.supplier}, fields=['name', 'quote_status'])[0] + + quote_status = _('Received') + for item in doc.items: + sqi_count = frappe.db.sql(""" + SELECT + COUNT(sqi.name) as count + FROM + `tabSupplier Quotation Item` as sqi, + `tabSupplier Quotation` as sq + WHERE sq.supplier = %(supplier)s + AND sqi.docstatus = 1 + AND sq.name != %(me)s + AND sqi.request_for_quotation_item = %(rqi)s + AND sqi.parent = sq.name""", {"supplier": self.supplier, "rqi": item.name, 'me': self.name}, as_dict=1)[0] + self_count = sum(my_item.request_for_quotation_item == item.name for my_item in self.items) if include_me else 0 + if (sqi_count.count + self_count) == 0: + quote_status = _('Pending') + if quote_status == _('Received') and doc_sup.quote_status == _('No Quote'): + frappe.msgprint(_("{0} indicates that {1} will not provide a quotation, but all items have been quoted. Updating the RFQ quote status.").format(doc.name, self.supplier)) + frappe.db.set_value('Request for Quotation Supplier', doc_sup.name, 'quote_status', quote_status) + frappe.db.set_value('Request for Quotation Supplier', doc_sup.name, 'no_quote', 0) + elif doc_sup.quote_status != _('No Quote'): + frappe.db.set_value('Request for Quotation Supplier', doc_sup.name, 'quote_status', quote_status) def get_list_context(context=None): from erpnext.controllers.website_list_for_contact import get_list_context diff --git a/erpnext/docs/user/manual/en/buying/request-for-quotation.md b/erpnext/docs/user/manual/en/buying/request-for-quotation.md index 182c89d4e6f..a48c297a6fe 100644 --- a/erpnext/docs/user/manual/en/buying/request-for-quotation.md +++ b/erpnext/docs/user/manual/en/buying/request-for-quotation.md @@ -2,43 +2,40 @@ A Request for Quotation is a document that an organization submits to one or more suppliers eliciting quotation for items. -In ERPNext, You can create request for quotation directly by going to: +In ERPNext, You can create Request for Quotation directly by going to: > Buying > Documents > Request for Quotation > New Request for Quotation -![Request For Quotation](/docs/assets/img/buying/request-for-quotation.png) +After creation of Request for Quotation, there are two ways to generate Supplier Quotation from Request for Quotation. -After creation of request for quotation, there are two ways to generate supplier quotation from request for quotation. #### For User -__Step 1:__ Open request for quotation and click on make supplier quotation. +__Step 1:__ Open Request for Quotation and click on make Supplier Quotation. ![Request For Quotation](/docs/assets/img/buying/make-supplier-quotation-from-rfq.png) -__Step 2:__ Select supplier and click on make supplier quotation. +__Step 2:__ Select supplier and click on make Supplier Quotation. ![Request For Quotation](/docs/assets/img/buying/supplier-selection-from-rfq.png) -__Step 3:__ System will open the supplier quotation, user has to enter the rate and submit it. +__Step 3:__ System will open the Supplier Quotation, user has to enter the rate and submit it. ![Request For Quotation](/docs/assets/img/buying/supplier-quotation-from-rfq.png) #### For Supplier -__Step 1:__ User has to create contact or enter Email Address against the supplier on request for quotation. +__Step 1:__ User has to create contact or enter Email Address against the supplier on Request for Quotation. ![Request For Quotation](/docs/assets/img/buying/set-email-id.png) __Step 2:__ User has to click on send supplier emails button. -![Request For Quotation](/docs/assets/img/buying/send-supplier-emails.png) - -* If supplier's user not available: system will create supplier's user and send details to the supplier, supplier will need to click on the link(Password Update) present in the email. After password update supplier can access his portal with the request for quotation form. +* If supplier's user not available: system will create supplier's user and send details to the supplier, supplier will need to click on the link(Password Update) present in the email. After password update supplier can access his portal with the Request for Quotation form. ![Request For Quotation](/docs/assets/img/buying/supplier-password-update-link.png) -* If supplier's user available: system will send request for quotation link to supplier, supplier has to login using his credentials to view request for quotation form on portal. +* If supplier's user available: system will send Request for Quotation link to supplier, supplier has to login using his credentials to view Request for Quotation form on portal. ![Request For Quotation](/docs/assets/img/buying/send-rfq-link.png) @@ -46,9 +43,12 @@ __Step 3:__ Supplier has to enter amount and notes(payment terms) on the form an ![Request For Quotation](/docs/assets/img/buying/supplier-portal-rfq.png) -__Step 4:__ On submission, system will create supplier quotation(draft mode) against the supplier. User has to review the supplier quotation - and submit it. - -More details:- +__Step 4:__ On submission, system will create Supplier Quotation (draft mode) against the supplier. The user has to review the Supplier Quotation + and submit it. When all items from the Request for Quotation have been quoted by a supplier, the status is updated in the Supplier + table of the Request for Quotation. -![Request For Quotation](/docs/assets/img/buying/request-for-quotation.gif) \ No newline at end of file +#### More details + +If a supplier indicates that they will not provide a quotation for the item, this can be indicated in the RFQ document by checking the 'No Quote' box after the Request for Quotation has been submitted. + +![Request For Quotation](/docs/assets/img/buying/request-for-quotation.gif) From 48058a88e5a0416ae58b7bfd3e6a1da8197247a1 Mon Sep 17 00:00:00 2001 From: Ben Cornwell-Mott Date: Wed, 26 Jul 2017 23:14:15 -0700 Subject: [PATCH 2/8] Minor cleanup --- .../request_for_quotation/request_for_quotation.js | 1 - .../request_for_quotation/request_for_quotation.py | 3 ++- .../doctype/supplier_quotation/supplier_quotation.py | 9 ++++++--- 3 files changed, 8 insertions(+), 5 deletions(-) diff --git a/erpnext/buying/doctype/request_for_quotation/request_for_quotation.js b/erpnext/buying/doctype/request_for_quotation/request_for_quotation.js index 6b37edafc79..8509d77e207 100644 --- a/erpnext/buying/doctype/request_for_quotation/request_for_quotation.js +++ b/erpnext/buying/doctype/request_for_quotation/request_for_quotation.js @@ -229,7 +229,6 @@ frappe.ui.form.on("Request for Quotation Supplier",{ } }); } - } }) 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 a8e897c2ddd..4a88191edcb 100644 --- a/erpnext/buying/doctype/request_for_quotation/request_for_quotation.py +++ b/erpnext/buying/doctype/request_for_quotation/request_for_quotation.py @@ -173,7 +173,8 @@ class RequestforQuotation(BuyingController): WHERE sq.supplier = %(supplier)s AND sqi.docstatus = 1 AND sqi.request_for_quotation_item = %(rqi)s - AND sqi.parent = sq.name""", {"supplier": supplier.supplier, "rqi": item.name}, as_dict=1)[0] + AND sqi.parent = sq.name""", + {"supplier": supplier.supplier, "rqi": item.name}, as_dict=1)[0] if (sqi_count.count) == 0: quote_status = _('Pending') supplier.quote_status = quote_status diff --git a/erpnext/buying/doctype/supplier_quotation/supplier_quotation.py b/erpnext/buying/doctype/supplier_quotation/supplier_quotation.py index 5e17dce6101..4de2c00596a 100644 --- a/erpnext/buying/doctype/supplier_quotation/supplier_quotation.py +++ b/erpnext/buying/doctype/supplier_quotation/supplier_quotation.py @@ -74,12 +74,15 @@ class SupplierQuotation(BuyingController): AND sqi.docstatus = 1 AND sq.name != %(me)s AND sqi.request_for_quotation_item = %(rqi)s - AND sqi.parent = sq.name""", {"supplier": self.supplier, "rqi": item.name, 'me': self.name}, as_dict=1)[0] - self_count = sum(my_item.request_for_quotation_item == item.name for my_item in self.items) if include_me else 0 + AND sqi.parent = sq.name""", + {"supplier": self.supplier, "rqi": item.name, 'me': self.name}, as_dict=1)[0] + self_count = sum(my_item.request_for_quotation_item == item.name + for my_item in self.items) if include_me else 0 if (sqi_count.count + self_count) == 0: quote_status = _('Pending') if quote_status == _('Received') and doc_sup.quote_status == _('No Quote'): - frappe.msgprint(_("{0} indicates that {1} will not provide a quotation, but all items have been quoted. Updating the RFQ quote status.").format(doc.name, self.supplier)) + frappe.msgprint(_("{0} indicates that {1} will not provide a quotation, but all items \ + have been quoted. Updating the RFQ quote status.").format(doc.name, self.supplier)) frappe.db.set_value('Request for Quotation Supplier', doc_sup.name, 'quote_status', quote_status) frappe.db.set_value('Request for Quotation Supplier', doc_sup.name, 'no_quote', 0) elif doc_sup.quote_status != _('No Quote'): From 1b4351516099897d788903a8fd767496a5e98de3 Mon Sep 17 00:00:00 2001 From: Ben Cornwell-Mott Date: Thu, 27 Jul 2017 02:56:00 -0700 Subject: [PATCH 3/8] Codacy fixes --- .../doctype/request_for_quotation/request_for_quotation.py | 2 +- .../buying/doctype/supplier_quotation/supplier_quotation.py | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) 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 4a88191edcb..7a33034413b 100644 --- a/erpnext/buying/doctype/request_for_quotation/request_for_quotation.py +++ b/erpnext/buying/doctype/request_for_quotation/request_for_quotation.py @@ -173,7 +173,7 @@ class RequestforQuotation(BuyingController): WHERE sq.supplier = %(supplier)s AND sqi.docstatus = 1 AND sqi.request_for_quotation_item = %(rqi)s - AND sqi.parent = sq.name""", + AND sqi.parent = sq.name""", {"supplier": supplier.supplier, "rqi": item.name}, as_dict=1)[0] if (sqi_count.count) == 0: quote_status = _('Pending') diff --git a/erpnext/buying/doctype/supplier_quotation/supplier_quotation.py b/erpnext/buying/doctype/supplier_quotation/supplier_quotation.py index 4de2c00596a..b3d92be4b6b 100644 --- a/erpnext/buying/doctype/supplier_quotation/supplier_quotation.py +++ b/erpnext/buying/doctype/supplier_quotation/supplier_quotation.py @@ -74,9 +74,9 @@ class SupplierQuotation(BuyingController): AND sqi.docstatus = 1 AND sq.name != %(me)s AND sqi.request_for_quotation_item = %(rqi)s - AND sqi.parent = sq.name""", + AND sqi.parent = sq.name""", {"supplier": self.supplier, "rqi": item.name, 'me': self.name}, as_dict=1)[0] - self_count = sum(my_item.request_for_quotation_item == item.name + self_count = sum(my_item.request_for_quotation_item == item.name for my_item in self.items) if include_me else 0 if (sqi_count.count + self_count) == 0: quote_status = _('Pending') From bea7d9f91994dd5b51130ccad39457168d4f9341 Mon Sep 17 00:00:00 2001 From: Ben Cornwell-Mott Date: Wed, 2 Aug 2017 05:12:12 -0700 Subject: [PATCH 4/8] Added tests --- .../request_for_quotation.py | 2 +- .../test_request_for_quotation.py | 44 ++++-- .../{ => tests}/test_request_for_quotation.js | 0 .../test_request_for_quotation_for_status.js | 133 ++++++++++++++++++ 4 files changed, 166 insertions(+), 13 deletions(-) rename erpnext/buying/doctype/request_for_quotation/{ => tests}/test_request_for_quotation.js (100%) create mode 100644 erpnext/buying/doctype/request_for_quotation/tests/test_request_for_quotation_for_status.js 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 7a33034413b..2d8820d9922 100644 --- a/erpnext/buying/doctype/request_for_quotation/request_for_quotation.py +++ b/erpnext/buying/doctype/request_for_quotation/request_for_quotation.py @@ -160,7 +160,7 @@ class RequestforQuotation(BuyingController): def update_rfq_supplier_status(self, sup_name=None): for supplier in self.suppliers: - if sup_name != None and supplier.supplier == sup_name: + if sup_name == None or supplier.supplier == sup_name: if supplier.quote_status != _('No Quote'): quote_status = _('Received') for item in self.items: 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 2e8b946f9db..5c9fb132092 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 @@ -10,21 +10,41 @@ from erpnext.templates.pages.rfq import check_supplier_has_docname_access from frappe.utils import nowdate 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.assertEquals(rfq.get('suppliers')[0].quote_status, 'Pending') + self.assertEquals(rfq.get('suppliers')[1].quote_status, 'Pending') + + # Submit the first supplier quotation + sq = make_supplier_quotation(rfq.name, rfq.get('suppliers')[0].supplier) + sq.submit() + + # No Quote first supplier quotation + rfq.get('suppliers')[1].no_quote = 1 + rfq.get('suppliers')[1].quote_status = 'No Quote' + + rfq.update_rfq_supplier_status() #rfq.get('suppliers')[1].supplier) + + self.assertEquals(rfq.get('suppliers')[0].quote_status, 'Received') + self.assertEquals(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) sq.submit() - + sq1 = make_supplier_quotation(rfq.name, rfq.get('suppliers')[1].supplier) sq1.submit() - + self.assertEquals(sq.supplier, rfq.get('suppliers')[0].supplier) self.assertEquals(sq.get('items')[0].request_for_quotation, rfq.name) self.assertEquals(sq.get('items')[0].item_code, "_Test Item") self.assertEquals(sq.get('items')[0].qty, 5) - + self.assertEquals(sq1.supplier, rfq.get('suppliers')[1].supplier) self.assertEquals(sq1.get('items')[0].request_for_quotation, rfq.name) self.assertEquals(sq1.get('items')[0].item_code, "_Test Item") @@ -61,15 +81,15 @@ class TestRequestforQuotation(unittest.TestCase): rfq.get('items')[0].rate = 100 rfq.supplier = rfq.suppliers[0].supplier supplier_quotation_name = create_supplier_quotation(rfq) - + supplier_quotation_doc = frappe.get_doc('Supplier Quotation', supplier_quotation_name) - + self.assertEquals(supplier_quotation_doc.supplier, rfq.get('suppliers')[0].supplier) self.assertEquals(supplier_quotation_doc.get('items')[0].request_for_quotation, rfq.name) self.assertEquals(supplier_quotation_doc.get('items')[0].item_code, "_Test Item") self.assertEquals(supplier_quotation_doc.get('items')[0].qty, 5) self.assertEquals(supplier_quotation_doc.get('items')[0].amount, 500) - + def make_request_for_quotation(supplier_data=None): """ @@ -81,10 +101,10 @@ def make_request_for_quotation(supplier_data=None): rfq.status = 'Draft' rfq.company = '_Test Company' rfq.message_for_supplier = 'Please supply the specified items at the best possible rates.' - + for data in supplier_data: rfq.append('suppliers', data) - + rfq.append("items", { "item_code": "_Test Item", "description": "_Test Item", @@ -93,11 +113,11 @@ def make_request_for_quotation(supplier_data=None): "warehouse": "_Test Warehouse - _TC", "schedule_date": nowdate() }) - + rfq.submit() - + return rfq - + def get_supplier_data(): return [{ "supplier": "_Test Supplier", diff --git a/erpnext/buying/doctype/request_for_quotation/test_request_for_quotation.js b/erpnext/buying/doctype/request_for_quotation/tests/test_request_for_quotation.js similarity index 100% rename from erpnext/buying/doctype/request_for_quotation/test_request_for_quotation.js rename to erpnext/buying/doctype/request_for_quotation/tests/test_request_for_quotation.js diff --git a/erpnext/buying/doctype/request_for_quotation/tests/test_request_for_quotation_for_status.js b/erpnext/buying/doctype/request_for_quotation/tests/test_request_for_quotation_for_status.js new file mode 100644 index 00000000000..e971ef9030c --- /dev/null +++ b/erpnext/buying/doctype/request_for_quotation/tests/test_request_for_quotation_for_status.js @@ -0,0 +1,133 @@ +QUnit.module('buying'); + +QUnit.test("Test: Request for Quotation", function (assert) { + assert.expect(5); + let done = assert.async(); + let rfq_name = ""; + + frappe.run_serially([ + // Go to RFQ list + () => frappe.set_route("List", "Request for Quotation"), + // Create a new RFQ + () => frappe.new_doc("Request for Quotation"), + () => frappe.timeout(1), + () => cur_frm.set_value("transaction_date", "04-04-2017"), + () => cur_frm.set_value("company", "_Test Company"), + // Add Suppliers + () => { + cur_frm.fields_dict.suppliers.grid.grid_rows[0].toggle_view(); + }, + () => frappe.timeout(1), + () => { + cur_frm.fields_dict.suppliers.grid.grid_rows[0].doc.supplier = "_Test Supplier"; + frappe.click_check('Send Email'); + cur_frm.cur_grid.frm.script_manager.trigger('supplier'); + }, + () => frappe.timeout(1), + () => { + cur_frm.cur_grid.toggle_view(); + }, + () => frappe.timeout(1), + () => frappe.click_button('Add Row',0), + () => frappe.timeout(1), + () => { + cur_frm.fields_dict.suppliers.grid.grid_rows[1].toggle_view(); + }, + () => frappe.timeout(1), + () => { + cur_frm.fields_dict.suppliers.grid.grid_rows[1].doc.supplier = "_Test Supplier 1"; + frappe.click_check('Send Email'); + cur_frm.cur_grid.frm.script_manager.trigger('supplier'); + }, + () => frappe.timeout(1), + () => { + cur_frm.cur_grid.toggle_view(); + }, + () => frappe.timeout(1), + //Add Item + () => { + cur_frm.fields_dict.items.grid.grid_rows[0].toggle_view(); + }, + () => frappe.timeout(1), + () => { + cur_frm.fields_dict.items.grid.grid_rows[0].doc.item_code = "_Test Item"; + frappe.set_control('item_code',"_Test Item"); + frappe.set_control('qty',5); + frappe.set_control('schedule_date', "05-05-2017"); + cur_frm.cur_grid.frm.script_manager.trigger('supplier'); + }, + () => frappe.timeout(2), + () => { + cur_frm.cur_grid.toggle_view(); + }, + () => frappe.timeout(2), + () => { + cur_frm.fields_dict.items.grid.grid_rows[0].doc.warehouse = "_Test Warehouse - _TC"; + }, + () => frappe.click_button('Save'), + () => frappe.timeout(1), + () => frappe.click_button('Submit'), + () => frappe.timeout(1), + () => frappe.click_button('Yes'), + () => frappe.timeout(1), + () => frappe.click_button('Menu'), + () => frappe.timeout(1), + () => frappe.click_link('Reload'), + () => frappe.timeout(1), + () => { + assert.equal(cur_frm.doc.docstatus, 1); + rfq_name = cur_frm.doc.name; + assert.ok(cur_frm.fields_dict.suppliers.grid.grid_rows[0].doc.quote_status == "Pending"); + assert.ok(cur_frm.fields_dict.suppliers.grid.grid_rows[1].doc.quote_status == "Pending"); + }, + () => { + cur_frm.fields_dict.suppliers.grid.grid_rows[0].toggle_view(); + }, + () => frappe.timeout(1), + () => { + frappe.click_check('No Quote'); + }, + () => frappe.timeout(1), + () => { + cur_frm.cur_grid.toggle_view(); + }, + () => frappe.click_button('Update'), + () => frappe.timeout(1), + + () => frappe.click_button('Supplier Quotation'), + () => frappe.timeout(1), + () => frappe.click_link('Make'), + () => frappe.timeout(1), + () => { + frappe.set_control('supplier',"_Test Supplier 1"); + }, + () => frappe.timeout(1), + () => frappe.click_button('Make Supplier Quotation'), + () => frappe.timeout(1), + () => cur_frm.set_value("company", "_Test Company"), + () => cur_frm.fields_dict.items.grid.grid_rows[0].doc.rate = 4.99, + () => frappe.timeout(1), + () => frappe.click_button('Save'), + () => frappe.timeout(1), + () => frappe.click_button('Submit'), + () => frappe.timeout(1), + () => frappe.click_button('Yes'), + () => frappe.timeout(1), + () => frappe.set_route("List", "Request for Quotation"), + () => frappe.timeout(2), + () => frappe.set_route("List", "Request for Quotation"), + () => frappe.timeout(2), + () => frappe.click_link(rfq_name), + () => frappe.timeout(1), + () => frappe.click_button('Menu'), + () => frappe.timeout(1), + () => frappe.click_link('Reload'), + () => frappe.timeout(1), + () => { + assert.ok(cur_frm.fields_dict.suppliers.grid.grid_rows[1].doc.quote_status == "Received"); + assert.ok(cur_frm.fields_dict.suppliers.grid.grid_rows[0].doc.no_quote == 1); + console.log(cur_frm.fields_dict.suppliers.grid.grid_rows[1].doc); + }, + () => done() + ]); +}); \ No newline at end of file From 13218f7d76484af9a8c348a885ec6a6c997f33f1 Mon Sep 17 00:00:00 2001 From: Ben Cornwell-Mott Date: Wed, 2 Aug 2017 05:25:45 -0700 Subject: [PATCH 5/8] Fixed codacy issues --- .../test_request_for_quotation_for_status.js | 29 +++++++++---------- 1 file changed, 14 insertions(+), 15 deletions(-) diff --git a/erpnext/buying/doctype/request_for_quotation/tests/test_request_for_quotation_for_status.js b/erpnext/buying/doctype/request_for_quotation/tests/test_request_for_quotation_for_status.js index e971ef9030c..f0d797a4f53 100644 --- a/erpnext/buying/doctype/request_for_quotation/tests/test_request_for_quotation_for_status.js +++ b/erpnext/buying/doctype/request_for_quotation/tests/test_request_for_quotation_for_status.js @@ -14,15 +14,15 @@ QUnit.test("Test: Request for Quotation", function (assert) { () => cur_frm.set_value("transaction_date", "04-04-2017"), () => cur_frm.set_value("company", "_Test Company"), // Add Suppliers - () => { + () => { cur_frm.fields_dict.suppliers.grid.grid_rows[0].toggle_view(); }, () => frappe.timeout(1), () => { - cur_frm.fields_dict.suppliers.grid.grid_rows[0].doc.supplier = "_Test Supplier"; - frappe.click_check('Send Email'); - cur_frm.cur_grid.frm.script_manager.trigger('supplier'); - }, + cur_frm.fields_dict.suppliers.grid.grid_rows[0].doc.supplier = "_Test Supplier"; + frappe.click_check('Send Email'); + cur_frm.cur_grid.frm.script_manager.trigger('supplier'); + }, () => frappe.timeout(1), () => { cur_frm.cur_grid.toggle_view(); @@ -35,7 +35,7 @@ QUnit.test("Test: Request for Quotation", function (assert) { }, () => frappe.timeout(1), () => { - cur_frm.fields_dict.suppliers.grid.grid_rows[1].doc.supplier = "_Test Supplier 1"; + cur_frm.fields_dict.suppliers.grid.grid_rows[1].doc.supplier = "_Test Supplier 1"; frappe.click_check('Send Email'); cur_frm.cur_grid.frm.script_manager.trigger('supplier'); }, @@ -44,18 +44,18 @@ QUnit.test("Test: Request for Quotation", function (assert) { cur_frm.cur_grid.toggle_view(); }, () => frappe.timeout(1), - //Add Item + // Add Item () => { cur_frm.fields_dict.items.grid.grid_rows[0].toggle_view(); }, () => frappe.timeout(1), - () => { + () => { cur_frm.fields_dict.items.grid.grid_rows[0].doc.item_code = "_Test Item"; - frappe.set_control('item_code',"_Test Item"); - frappe.set_control('qty',5); - frappe.set_control('schedule_date', "05-05-2017"); + frappe.set_control('item_code',"_Test Item"); + frappe.set_control('qty',5); + frappe.set_control('schedule_date', "05-05-2017"); cur_frm.cur_grid.frm.script_manager.trigger('supplier'); - }, + }, () => frappe.timeout(2), () => { cur_frm.cur_grid.toggle_view(); @@ -85,7 +85,7 @@ QUnit.test("Test: Request for Quotation", function (assert) { }, () => frappe.timeout(1), () => { - frappe.click_check('No Quote'); + frappe.click_check('No Quote'); }, () => frappe.timeout(1), () => { @@ -94,7 +94,7 @@ QUnit.test("Test: Request for Quotation", function (assert) { () => frappe.click_button('Update'), () => frappe.timeout(1), - () => frappe.click_button('Supplier Quotation'), + () => frappe.click_button('Supplier Quotation'), () => frappe.timeout(1), () => frappe.click_link('Make'), () => frappe.timeout(1), @@ -126,7 +126,6 @@ QUnit.test("Test: Request for Quotation", function (assert) { () => { assert.ok(cur_frm.fields_dict.suppliers.grid.grid_rows[1].doc.quote_status == "Received"); assert.ok(cur_frm.fields_dict.suppliers.grid.grid_rows[0].doc.no_quote == 1); - console.log(cur_frm.fields_dict.suppliers.grid.grid_rows[1].doc); }, () => done() ]); From df83191ea02e80e50e04b3fe4ef1d0e47771acf9 Mon Sep 17 00:00:00 2001 From: Rohit Waghchaure Date: Wed, 2 Aug 2017 18:23:39 +0530 Subject: [PATCH 6/8] Set write permission to sales manger for permlevel 1 in Quotation doctype --- erpnext/patches.txt | 5 ++++- .../set_write_permission_for_quotation_for_sales_manager.py | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/erpnext/patches.txt b/erpnext/patches.txt index 60caf0fec1c..56af066c54a 100644 --- a/erpnext/patches.txt +++ b/erpnext/patches.txt @@ -431,4 +431,7 @@ erpnext.patches.v8_5.set_default_mode_of_payment erpnext.patches.v8_5.update_customer_group_in_POS_profile erpnext.patches.v8_6.update_timesheet_company_from_PO erpnext.patches.v8_6.set_write_permission_for_quotation_for_sales_manager -erpnext.patches.v8_5.remove_project_type_property_setter \ No newline at end of file +<<<<<<< HEAD +erpnext.patches.v8_5.remove_project_type_property_setter +======= +>>>>>>> Set write permission to sales manger for permlevel 1 in Quotation doctype diff --git a/erpnext/patches/v8_6/set_write_permission_for_quotation_for_sales_manager.py b/erpnext/patches/v8_6/set_write_permission_for_quotation_for_sales_manager.py index c2320ec04c8..db4f94748e1 100644 --- a/erpnext/patches/v8_6/set_write_permission_for_quotation_for_sales_manager.py +++ b/erpnext/patches/v8_6/set_write_permission_for_quotation_for_sales_manager.py @@ -8,4 +8,4 @@ def execute(): # Set write permission to permlevel 1 for sales manager role in Quotation doctype frappe.db.sql(""" update `tabCustom DocPerm` set `tabCustom DocPerm`.write = 1 where `tabCustom DocPerm`.parent = 'Quotation' and `tabCustom DocPerm`.role = 'Sales Manager' - and `tabCustom DocPerm`.permlevel = 1 """) + and `tabCustom DocPerm`.permlevel = 1 """) \ No newline at end of file From 9727a3fe5077aba36b3d7b249f06f6f24f68a623 Mon Sep 17 00:00:00 2001 From: Ben Cornwell-Mott Date: Wed, 2 Aug 2017 06:08:32 -0700 Subject: [PATCH 7/8] More codacy issues --- .../tests/test_request_for_quotation_for_status.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/erpnext/buying/doctype/request_for_quotation/tests/test_request_for_quotation_for_status.js b/erpnext/buying/doctype/request_for_quotation/tests/test_request_for_quotation_for_status.js index f0d797a4f53..c315f6b6efb 100644 --- a/erpnext/buying/doctype/request_for_quotation/tests/test_request_for_quotation_for_status.js +++ b/erpnext/buying/doctype/request_for_quotation/tests/test_request_for_quotation_for_status.js @@ -18,7 +18,7 @@ QUnit.test("Test: Request for Quotation", function (assert) { cur_frm.fields_dict.suppliers.grid.grid_rows[0].toggle_view(); }, () => frappe.timeout(1), - () => { + () => { cur_frm.fields_dict.suppliers.grid.grid_rows[0].doc.supplier = "_Test Supplier"; frappe.click_check('Send Email'); cur_frm.cur_grid.frm.script_manager.trigger('supplier'); @@ -36,9 +36,9 @@ QUnit.test("Test: Request for Quotation", function (assert) { () => frappe.timeout(1), () => { cur_frm.fields_dict.suppliers.grid.grid_rows[1].doc.supplier = "_Test Supplier 1"; - frappe.click_check('Send Email'); - cur_frm.cur_grid.frm.script_manager.trigger('supplier'); - }, + frappe.click_check('Send Email'); + cur_frm.cur_grid.frm.script_manager.trigger('supplier'); + }, () => frappe.timeout(1), () => { cur_frm.cur_grid.toggle_view(); @@ -94,7 +94,7 @@ QUnit.test("Test: Request for Quotation", function (assert) { () => frappe.click_button('Update'), () => frappe.timeout(1), - () => frappe.click_button('Supplier Quotation'), + () => frappe.click_button('Supplier Quotation'), () => frappe.timeout(1), () => frappe.click_link('Make'), () => frappe.timeout(1), From ee9f9863ff6695d2dd9e493932c9ffa10e47b35f Mon Sep 17 00:00:00 2001 From: Ben Cornwell-Mott Date: Wed, 2 Aug 2017 06:28:01 -0700 Subject: [PATCH 8/8] MORE CODACY --- .../tests/test_request_for_quotation_for_status.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/erpnext/buying/doctype/request_for_quotation/tests/test_request_for_quotation_for_status.js b/erpnext/buying/doctype/request_for_quotation/tests/test_request_for_quotation_for_status.js index c315f6b6efb..f831b4f42ff 100644 --- a/erpnext/buying/doctype/request_for_quotation/tests/test_request_for_quotation_for_status.js +++ b/erpnext/buying/doctype/request_for_quotation/tests/test_request_for_quotation_for_status.js @@ -34,7 +34,7 @@ QUnit.test("Test: Request for Quotation", function (assert) { cur_frm.fields_dict.suppliers.grid.grid_rows[1].toggle_view(); }, () => frappe.timeout(1), - () => { + () => { cur_frm.fields_dict.suppliers.grid.grid_rows[1].doc.supplier = "_Test Supplier 1"; frappe.click_check('Send Email'); cur_frm.cur_grid.frm.script_manager.trigger('supplier'); @@ -84,9 +84,9 @@ QUnit.test("Test: Request for Quotation", function (assert) { cur_frm.fields_dict.suppliers.grid.grid_rows[0].toggle_view(); }, () => frappe.timeout(1), - () => { + () => { frappe.click_check('No Quote'); - }, + }, () => frappe.timeout(1), () => { cur_frm.cur_grid.toggle_view();