fix: RFQ UX fixes (#23382)
* chore: RFQ UX fixes * fix: RFQ to SUpplier Quotation Dialog * fix: Remove 'No Quote' functionality - No Quote in Suppliers table is removed - It's use everywhere has been removed too (tests, server side files, DOM event) * chore: More Info section and Project field Co-authored-by: Nabin Hait <nabinhait@gmail.com>
This commit is contained in:
parent
c4be397954
commit
0bd576aa44
@ -29,14 +29,12 @@ frappe.ui.form.on("Request for Quotation",{
|
|||||||
|
|
||||||
refresh: function(frm, cdt, cdn) {
|
refresh: function(frm, cdt, cdn) {
|
||||||
if (frm.doc.docstatus === 1) {
|
if (frm.doc.docstatus === 1) {
|
||||||
frm.add_custom_button(__('Create'),
|
|
||||||
function(){ frm.trigger("make_suppplier_quotation") }, __("Supplier Quotation"));
|
|
||||||
|
|
||||||
frm.add_custom_button(__("View"),
|
frm.add_custom_button(__('Supplier Quotation'),
|
||||||
function(){ frappe.set_route('List', 'Supplier Quotation',
|
function(){ frm.trigger("make_suppplier_quotation") }, __("Create"));
|
||||||
{'request_for_quotation': frm.doc.name}) }, __("Supplier Quotation"));
|
|
||||||
|
|
||||||
frm.add_custom_button(__("Send Supplier Emails"), function() {
|
|
||||||
|
frm.add_custom_button(__("Send Emails to Suppliers"), function() {
|
||||||
frappe.call({
|
frappe.call({
|
||||||
method: 'erpnext.buying.doctype.request_for_quotation.request_for_quotation.send_supplier_emails',
|
method: 'erpnext.buying.doctype.request_for_quotation.request_for_quotation.send_supplier_emails',
|
||||||
freeze: true,
|
freeze: true,
|
||||||
@ -47,150 +45,82 @@ frappe.ui.form.on("Request for Quotation",{
|
|||||||
frm.reload_doc();
|
frm.reload_doc();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
}, __("Tools"));
|
||||||
|
|
||||||
|
frm.add_custom_button(__('Download PDF'), () => {
|
||||||
|
var suppliers = [];
|
||||||
|
const fields = [{
|
||||||
|
fieldtype: 'Link',
|
||||||
|
label: __('Select a Supplier'),
|
||||||
|
fieldname: 'supplier',
|
||||||
|
options: 'Supplier',
|
||||||
|
reqd: 1,
|
||||||
|
get_query: () => {
|
||||||
|
return {
|
||||||
|
filters: [
|
||||||
|
["Supplier", "name", "in", frm.doc.suppliers.map((row) => {return row.supplier;})]
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}];
|
||||||
|
|
||||||
|
frappe.prompt(fields, data => {
|
||||||
|
var child = locals[cdt][cdn]
|
||||||
|
|
||||||
|
var w = window.open(
|
||||||
|
frappe.urllib.get_full_url("/api/method/erpnext.buying.doctype.request_for_quotation.request_for_quotation.get_pdf?"
|
||||||
|
+"doctype="+encodeURIComponent(frm.doc.doctype)
|
||||||
|
+"&name="+encodeURIComponent(frm.doc.name)
|
||||||
|
+"&supplier="+encodeURIComponent(data.supplier)
|
||||||
|
+"&no_letterhead=0"));
|
||||||
|
if(!w) {
|
||||||
|
frappe.msgprint(__("Please enable pop-ups")); return;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
'Download PDF for Supplier',
|
||||||
|
'Download');
|
||||||
|
},
|
||||||
|
__("Tools"));
|
||||||
|
|
||||||
|
frm.page.set_inner_btn_group_as_primary(__('Create'));
|
||||||
}
|
}
|
||||||
|
|
||||||
},
|
},
|
||||||
|
|
||||||
get_suppliers_button: function (frm) {
|
|
||||||
var doc = frm.doc;
|
|
||||||
var dialog = new frappe.ui.Dialog({
|
|
||||||
title: __("Get Suppliers"),
|
|
||||||
fields: [
|
|
||||||
{
|
|
||||||
"fieldtype": "Select", "label": __("Get Suppliers By"),
|
|
||||||
"fieldname": "search_type",
|
|
||||||
"options": ["Tag","Supplier Group"],
|
|
||||||
"reqd": 1,
|
|
||||||
onchange() {
|
|
||||||
if(dialog.get_value('search_type') == 'Tag'){
|
|
||||||
frappe.call({
|
|
||||||
method: 'erpnext.buying.doctype.request_for_quotation.request_for_quotation.get_supplier_tag',
|
|
||||||
}).then(r => {
|
|
||||||
dialog.set_df_property("tag", "options", r.message)
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"fieldtype": "Link", "label": __("Supplier Group"),
|
|
||||||
"fieldname": "supplier_group",
|
|
||||||
"options": "Supplier Group",
|
|
||||||
"reqd": 0,
|
|
||||||
"depends_on": "eval:doc.search_type == 'Supplier Group'"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"fieldtype": "Select", "label": __("Tag"),
|
|
||||||
"fieldname": "tag",
|
|
||||||
"reqd": 0,
|
|
||||||
"depends_on": "eval:doc.search_type == 'Tag'",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"fieldtype": "Button", "label": __("Add All Suppliers"),
|
|
||||||
"fieldname": "add_suppliers"
|
|
||||||
},
|
|
||||||
]
|
|
||||||
});
|
|
||||||
|
|
||||||
dialog.fields_dict.add_suppliers.$input.click(function() {
|
|
||||||
var args = dialog.get_values();
|
|
||||||
if(!args) return;
|
|
||||||
dialog.hide();
|
|
||||||
|
|
||||||
//Remove blanks
|
|
||||||
for (var j = 0; j < frm.doc.suppliers.length; j++) {
|
|
||||||
if(!frm.doc.suppliers[j].hasOwnProperty("supplier")) {
|
|
||||||
frm.get_field("suppliers").grid.grid_rows[j].remove();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function load_suppliers(r) {
|
|
||||||
if(r.message) {
|
|
||||||
for (var i = 0; i < r.message.length; i++) {
|
|
||||||
var exists = false;
|
|
||||||
if (r.message[i].constructor === Array){
|
|
||||||
var supplier = r.message[i][0];
|
|
||||||
} else {
|
|
||||||
var supplier = r.message[i].name;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (var j = 0; j < doc.suppliers.length;j++) {
|
|
||||||
if (supplier === doc.suppliers[j].supplier) {
|
|
||||||
exists = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(!exists) {
|
|
||||||
var d = frm.add_child('suppliers');
|
|
||||||
d.supplier = supplier;
|
|
||||||
frm.script_manager.trigger("supplier", d.doctype, d.name);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
frm.refresh_field("suppliers");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (args.search_type === "Tag" && args.tag) {
|
|
||||||
return frappe.call({
|
|
||||||
type: "GET",
|
|
||||||
method: "frappe.desk.doctype.tag.tag.get_tagged_docs",
|
|
||||||
args: {
|
|
||||||
"doctype": "Supplier",
|
|
||||||
"tag": args.tag
|
|
||||||
},
|
|
||||||
callback: load_suppliers
|
|
||||||
});
|
|
||||||
} else if (args.supplier_group) {
|
|
||||||
return frappe.call({
|
|
||||||
method: "frappe.client.get_list",
|
|
||||||
args: {
|
|
||||||
doctype: "Supplier",
|
|
||||||
order_by: "name",
|
|
||||||
fields: ["name"],
|
|
||||||
filters: [["Supplier", "supplier_group", "=", args.supplier_group]]
|
|
||||||
|
|
||||||
},
|
|
||||||
callback: load_suppliers
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
dialog.show();
|
|
||||||
|
|
||||||
},
|
|
||||||
make_suppplier_quotation: function(frm) {
|
make_suppplier_quotation: function(frm) {
|
||||||
var doc = frm.doc;
|
var doc = frm.doc;
|
||||||
var dialog = new frappe.ui.Dialog({
|
var dialog = new frappe.ui.Dialog({
|
||||||
title: __("For Supplier"),
|
title: __("Create Supplier Quotation"),
|
||||||
fields: [
|
fields: [
|
||||||
{ "fieldtype": "Select", "label": __("Supplier"),
|
{ "fieldtype": "Select", "label": __("Supplier"),
|
||||||
"fieldname": "supplier",
|
"fieldname": "supplier",
|
||||||
"options": doc.suppliers.map(d => d.supplier),
|
"options": doc.suppliers.map(d => d.supplier),
|
||||||
"reqd": 1,
|
"reqd": 1,
|
||||||
"default": doc.suppliers.length === 1 ? doc.suppliers[0].supplier_name : "" },
|
"default": doc.suppliers.length === 1 ? doc.suppliers[0].supplier_name : "" },
|
||||||
{ "fieldtype": "Button", "label": __('Create Supplier Quotation'),
|
],
|
||||||
"fieldname": "make_supplier_quotation", "cssClass": "btn-primary" },
|
primary_action_label: __("Create"),
|
||||||
]
|
primary_action: (args) => {
|
||||||
|
if(!args) return;
|
||||||
|
dialog.hide();
|
||||||
|
|
||||||
|
return frappe.call({
|
||||||
|
type: "GET",
|
||||||
|
method: "erpnext.buying.doctype.request_for_quotation.request_for_quotation.make_supplier_quotation_from_rfq",
|
||||||
|
args: {
|
||||||
|
"source_name": doc.name,
|
||||||
|
"for_supplier": args.supplier
|
||||||
|
},
|
||||||
|
freeze: true,
|
||||||
|
callback: function(r) {
|
||||||
|
if(!r.exc) {
|
||||||
|
var doc = frappe.model.sync(r.message);
|
||||||
|
frappe.set_route("Form", r.message.doctype, r.message.name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
dialog.fields_dict.make_supplier_quotation.$input.click(function() {
|
|
||||||
var args = dialog.get_values();
|
|
||||||
if(!args) return;
|
|
||||||
dialog.hide();
|
|
||||||
return frappe.call({
|
|
||||||
type: "GET",
|
|
||||||
method: "erpnext.buying.doctype.request_for_quotation.request_for_quotation.make_supplier_quotation_from_rfq",
|
|
||||||
args: {
|
|
||||||
"source_name": doc.name,
|
|
||||||
"for_supplier": args.supplier
|
|
||||||
},
|
|
||||||
freeze: true,
|
|
||||||
callback: function(r) {
|
|
||||||
if(!r.exc) {
|
|
||||||
var doc = frappe.model.sync(r.message);
|
|
||||||
frappe.set_route("Form", r.message.doctype, r.message.name);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
dialog.show()
|
dialog.show()
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -273,42 +203,6 @@ frappe.ui.form.on("Request for Quotation Supplier",{
|
|||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
|
||||||
download_pdf: function(frm, cdt, cdn) {
|
|
||||||
var child = locals[cdt][cdn]
|
|
||||||
|
|
||||||
var w = window.open(
|
|
||||||
frappe.urllib.get_full_url("/api/method/erpnext.buying.doctype.request_for_quotation.request_for_quotation.get_pdf?"
|
|
||||||
+"doctype="+encodeURIComponent(frm.doc.doctype)
|
|
||||||
+"&name="+encodeURIComponent(frm.doc.name)
|
|
||||||
+"&supplier_idx="+encodeURIComponent(child.idx)
|
|
||||||
+"&no_letterhead=0"));
|
|
||||||
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");
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
|
|
||||||
erpnext.buying.RequestforQuotationController = erpnext.buying.BuyingController.extend({
|
erpnext.buying.RequestforQuotationController = erpnext.buying.BuyingController.extend({
|
||||||
@ -332,7 +226,8 @@ erpnext.buying.RequestforQuotationController = erpnext.buying.BuyingController.e
|
|||||||
per_ordered: ["<", 99.99]
|
per_ordered: ["<", 99.99]
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}, __("Get items from"));
|
}, __("Get Items From"));
|
||||||
|
|
||||||
// Get items from Opportunity
|
// Get items from Opportunity
|
||||||
this.frm.add_custom_button(__('Opportunity'),
|
this.frm.add_custom_button(__('Opportunity'),
|
||||||
function() {
|
function() {
|
||||||
@ -344,7 +239,8 @@ erpnext.buying.RequestforQuotationController = erpnext.buying.BuyingController.e
|
|||||||
company: me.frm.doc.company
|
company: me.frm.doc.company
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
}, __("Get items from"));
|
}, __("Get Items From"));
|
||||||
|
|
||||||
// Get items from open Material Requests based on supplier
|
// Get items from open Material Requests based on supplier
|
||||||
this.frm.add_custom_button(__('Possible Supplier'), function() {
|
this.frm.add_custom_button(__('Possible Supplier'), function() {
|
||||||
// Create a dialog window for the user to pick their supplier
|
// Create a dialog window for the user to pick their supplier
|
||||||
@ -382,8 +278,13 @@ erpnext.buying.RequestforQuotationController = erpnext.buying.BuyingController.e
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
d.show();
|
d.show();
|
||||||
}, __("Get items from"));
|
}, __("Get Items From"));
|
||||||
|
|
||||||
|
// Get Suppliers
|
||||||
|
this.frm.add_custom_button(__('Get Suppliers'),
|
||||||
|
function() {
|
||||||
|
me.get_suppliers_button(me.frm);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -393,9 +294,108 @@ erpnext.buying.RequestforQuotationController = erpnext.buying.BuyingController.e
|
|||||||
|
|
||||||
tc_name: function() {
|
tc_name: function() {
|
||||||
this.get_terms();
|
this.get_terms();
|
||||||
}
|
},
|
||||||
});
|
|
||||||
|
|
||||||
|
get_suppliers_button: function (frm) {
|
||||||
|
var doc = frm.doc;
|
||||||
|
var dialog = new frappe.ui.Dialog({
|
||||||
|
title: __("Get Suppliers"),
|
||||||
|
fields: [
|
||||||
|
{
|
||||||
|
"fieldtype": "Select", "label": __("Get Suppliers By"),
|
||||||
|
"fieldname": "search_type",
|
||||||
|
"options": ["Tag","Supplier Group"],
|
||||||
|
"reqd": 1,
|
||||||
|
onchange() {
|
||||||
|
if(dialog.get_value('search_type') == 'Tag'){
|
||||||
|
frappe.call({
|
||||||
|
method: 'erpnext.buying.doctype.request_for_quotation.request_for_quotation.get_supplier_tag',
|
||||||
|
}).then(r => {
|
||||||
|
dialog.set_df_property("tag", "options", r.message)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldtype": "Link", "label": __("Supplier Group"),
|
||||||
|
"fieldname": "supplier_group",
|
||||||
|
"options": "Supplier Group",
|
||||||
|
"reqd": 0,
|
||||||
|
"depends_on": "eval:doc.search_type == 'Supplier Group'"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldtype": "Select", "label": __("Tag"),
|
||||||
|
"fieldname": "tag",
|
||||||
|
"reqd": 0,
|
||||||
|
"depends_on": "eval:doc.search_type == 'Tag'",
|
||||||
|
}
|
||||||
|
],
|
||||||
|
primary_action_label: __("Add Suppliers"),
|
||||||
|
primary_action : (args) => {
|
||||||
|
if(!args) return;
|
||||||
|
dialog.hide();
|
||||||
|
|
||||||
|
//Remove blanks
|
||||||
|
for (var j = 0; j < frm.doc.suppliers.length; j++) {
|
||||||
|
if(!frm.doc.suppliers[j].hasOwnProperty("supplier")) {
|
||||||
|
frm.get_field("suppliers").grid.grid_rows[j].remove();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function load_suppliers(r) {
|
||||||
|
if(r.message) {
|
||||||
|
for (var i = 0; i < r.message.length; i++) {
|
||||||
|
var exists = false;
|
||||||
|
if (r.message[i].constructor === Array){
|
||||||
|
var supplier = r.message[i][0];
|
||||||
|
} else {
|
||||||
|
var supplier = r.message[i].name;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (var j = 0; j < doc.suppliers.length;j++) {
|
||||||
|
if (supplier === doc.suppliers[j].supplier) {
|
||||||
|
exists = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(!exists) {
|
||||||
|
var d = frm.add_child('suppliers');
|
||||||
|
d.supplier = supplier;
|
||||||
|
frm.script_manager.trigger("supplier", d.doctype, d.name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
frm.refresh_field("suppliers");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (args.search_type === "Tag" && args.tag) {
|
||||||
|
return frappe.call({
|
||||||
|
type: "GET",
|
||||||
|
method: "frappe.desk.doctype.tag.tag.get_tagged_docs",
|
||||||
|
args: {
|
||||||
|
"doctype": "Supplier",
|
||||||
|
"tag": args.tag
|
||||||
|
},
|
||||||
|
callback: load_suppliers
|
||||||
|
});
|
||||||
|
} else if (args.supplier_group) {
|
||||||
|
return frappe.call({
|
||||||
|
method: "frappe.client.get_list",
|
||||||
|
args: {
|
||||||
|
doctype: "Supplier",
|
||||||
|
order_by: "name",
|
||||||
|
fields: ["name"],
|
||||||
|
filters: [["Supplier", "supplier_group", "=", args.supplier_group]]
|
||||||
|
|
||||||
|
},
|
||||||
|
callback: load_suppliers
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
dialog.show();
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
// for backward compatibility: combine new and previous states
|
// for backward compatibility: combine new and previous states
|
||||||
$.extend(cur_frm.cscript, new erpnext.buying.RequestforQuotationController({frm: cur_frm}));
|
$.extend(cur_frm.cscript, new erpnext.buying.RequestforQuotationController({frm: cur_frm}));
|
||||||
|
@ -12,9 +12,10 @@
|
|||||||
"vendor",
|
"vendor",
|
||||||
"column_break1",
|
"column_break1",
|
||||||
"transaction_date",
|
"transaction_date",
|
||||||
|
"status",
|
||||||
|
"amended_from",
|
||||||
"suppliers_section",
|
"suppliers_section",
|
||||||
"suppliers",
|
"suppliers",
|
||||||
"get_suppliers_button",
|
|
||||||
"items_section",
|
"items_section",
|
||||||
"items",
|
"items",
|
||||||
"link_to_mrs",
|
"link_to_mrs",
|
||||||
@ -31,11 +32,7 @@
|
|||||||
"terms",
|
"terms",
|
||||||
"printing_settings",
|
"printing_settings",
|
||||||
"select_print_heading",
|
"select_print_heading",
|
||||||
"letter_head",
|
"letter_head"
|
||||||
"more_info",
|
|
||||||
"status",
|
|
||||||
"column_break3",
|
|
||||||
"amended_from"
|
|
||||||
],
|
],
|
||||||
"fields": [
|
"fields": [
|
||||||
{
|
{
|
||||||
@ -83,6 +80,7 @@
|
|||||||
"width": "50%"
|
"width": "50%"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
"default": "Today",
|
||||||
"fieldname": "transaction_date",
|
"fieldname": "transaction_date",
|
||||||
"fieldtype": "Date",
|
"fieldtype": "Date",
|
||||||
"in_list_view": 1,
|
"in_list_view": 1,
|
||||||
@ -99,16 +97,11 @@
|
|||||||
{
|
{
|
||||||
"fieldname": "suppliers",
|
"fieldname": "suppliers",
|
||||||
"fieldtype": "Table",
|
"fieldtype": "Table",
|
||||||
"label": "Supplier Detail",
|
"label": "Suppliers",
|
||||||
"options": "Request for Quotation Supplier",
|
"options": "Request for Quotation Supplier",
|
||||||
"print_hide": 1,
|
"print_hide": 1,
|
||||||
"reqd": 1
|
"reqd": 1
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"fieldname": "get_suppliers_button",
|
|
||||||
"fieldtype": "Button",
|
|
||||||
"label": "Get Suppliers"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"fieldname": "items_section",
|
"fieldname": "items_section",
|
||||||
"fieldtype": "Section Break",
|
"fieldtype": "Section Break",
|
||||||
@ -144,6 +137,7 @@
|
|||||||
"print_hide": 1
|
"print_hide": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
"allow_on_submit": 1,
|
||||||
"fetch_from": "email_template.response",
|
"fetch_from": "email_template.response",
|
||||||
"fetch_if_empty": 1,
|
"fetch_if_empty": 1,
|
||||||
"fieldname": "message_for_supplier",
|
"fieldname": "message_for_supplier",
|
||||||
@ -206,14 +200,6 @@
|
|||||||
"options": "Letter Head",
|
"options": "Letter Head",
|
||||||
"print_hide": 1
|
"print_hide": 1
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"collapsible": 1,
|
|
||||||
"fieldname": "more_info",
|
|
||||||
"fieldtype": "Section Break",
|
|
||||||
"label": "More Information",
|
|
||||||
"oldfieldtype": "Section Break",
|
|
||||||
"options": "fa fa-file-text"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"fieldname": "status",
|
"fieldname": "status",
|
||||||
"fieldtype": "Select",
|
"fieldtype": "Select",
|
||||||
@ -227,10 +213,6 @@
|
|||||||
"reqd": 1,
|
"reqd": 1,
|
||||||
"search_index": 1
|
"search_index": 1
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"fieldname": "column_break3",
|
|
||||||
"fieldtype": "Column Break"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"fieldname": "amended_from",
|
"fieldname": "amended_from",
|
||||||
"fieldtype": "Link",
|
"fieldtype": "Link",
|
||||||
@ -275,9 +257,10 @@
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
"icon": "fa fa-shopping-cart",
|
"icon": "fa fa-shopping-cart",
|
||||||
|
"index_web_pages_for_search": 1,
|
||||||
"is_submittable": 1,
|
"is_submittable": 1,
|
||||||
"links": [],
|
"links": [],
|
||||||
"modified": "2020-10-01 14:54:50.888729",
|
"modified": "2020-10-16 17:49:09.561929",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Buying",
|
"module": "Buying",
|
||||||
"name": "Request for Quotation",
|
"name": "Request for Quotation",
|
||||||
|
@ -28,6 +28,10 @@ class RequestforQuotation(BuyingController):
|
|||||||
super(RequestforQuotation, self).set_qty_as_per_stock_uom()
|
super(RequestforQuotation, self).set_qty_as_per_stock_uom()
|
||||||
self.update_email_id()
|
self.update_email_id()
|
||||||
|
|
||||||
|
if self.docstatus < 1:
|
||||||
|
# after amend and save, status still shows as cancelled, until submit
|
||||||
|
frappe.db.set(self, 'status', 'Draft')
|
||||||
|
|
||||||
def validate_duplicate_supplier(self):
|
def validate_duplicate_supplier(self):
|
||||||
supplier_list = [d.supplier for d in self.suppliers]
|
supplier_list = [d.supplier for d in self.suppliers]
|
||||||
if len(supplier_list) != len(set(supplier_list)):
|
if len(supplier_list) != len(set(supplier_list)):
|
||||||
@ -82,7 +86,7 @@ class RequestforQuotation(BuyingController):
|
|||||||
# make new user if required
|
# make new user if required
|
||||||
update_password_link, contact = self.update_supplier_contact(rfq_supplier, self.get_link())
|
update_password_link, contact = self.update_supplier_contact(rfq_supplier, self.get_link())
|
||||||
|
|
||||||
self.update_supplier_part_no(rfq_supplier)
|
self.update_supplier_part_no(rfq_supplier.supplier)
|
||||||
self.supplier_rfq_mail(rfq_supplier, update_password_link, self.get_link())
|
self.supplier_rfq_mail(rfq_supplier, update_password_link, self.get_link())
|
||||||
rfq_supplier.email_sent = 1
|
rfq_supplier.email_sent = 1
|
||||||
if not rfq_supplier.contact:
|
if not rfq_supplier.contact:
|
||||||
@ -93,11 +97,11 @@ class RequestforQuotation(BuyingController):
|
|||||||
# RFQ link for supplier portal
|
# RFQ link for supplier portal
|
||||||
return get_url("/rfq/" + self.name)
|
return get_url("/rfq/" + self.name)
|
||||||
|
|
||||||
def update_supplier_part_no(self, args):
|
def update_supplier_part_no(self, supplier):
|
||||||
self.vendor = args.supplier
|
self.vendor = supplier
|
||||||
for item in self.items:
|
for item in self.items:
|
||||||
item.supplier_part_no = frappe.db.get_value('Item Supplier',
|
item.supplier_part_no = frappe.db.get_value('Item Supplier',
|
||||||
{'parent': item.item_code, 'supplier': args.supplier}, 'supplier_part_no')
|
{'parent': item.item_code, 'supplier': supplier}, 'supplier_part_no')
|
||||||
|
|
||||||
def update_supplier_contact(self, rfq_supplier, link):
|
def update_supplier_contact(self, rfq_supplier, link):
|
||||||
'''Create a new user for the supplier if not set in contact'''
|
'''Create a new user for the supplier if not set in contact'''
|
||||||
@ -197,23 +201,22 @@ class RequestforQuotation(BuyingController):
|
|||||||
def update_rfq_supplier_status(self, sup_name=None):
|
def update_rfq_supplier_status(self, sup_name=None):
|
||||||
for supplier in self.suppliers:
|
for supplier in self.suppliers:
|
||||||
if sup_name == None or supplier.supplier == sup_name:
|
if sup_name == None or supplier.supplier == sup_name:
|
||||||
if supplier.quote_status != _('No Quote'):
|
quote_status = _('Received')
|
||||||
quote_status = _('Received')
|
for item in self.items:
|
||||||
for item in self.items:
|
sqi_count = frappe.db.sql("""
|
||||||
sqi_count = frappe.db.sql("""
|
SELECT
|
||||||
SELECT
|
COUNT(sqi.name) as count
|
||||||
COUNT(sqi.name) as count
|
FROM
|
||||||
FROM
|
`tabSupplier Quotation Item` as sqi,
|
||||||
`tabSupplier Quotation Item` as sqi,
|
`tabSupplier Quotation` as sq
|
||||||
`tabSupplier Quotation` as sq
|
WHERE sq.supplier = %(supplier)s
|
||||||
WHERE sq.supplier = %(supplier)s
|
AND sqi.docstatus = 1
|
||||||
AND sqi.docstatus = 1
|
AND sqi.request_for_quotation_item = %(rqi)s
|
||||||
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]
|
||||||
{"supplier": supplier.supplier, "rqi": item.name}, as_dict=1)[0]
|
if (sqi_count.count) == 0:
|
||||||
if (sqi_count.count) == 0:
|
quote_status = _('Pending')
|
||||||
quote_status = _('Pending')
|
supplier.quote_status = quote_status
|
||||||
supplier.quote_status = quote_status
|
|
||||||
|
|
||||||
|
|
||||||
@frappe.whitelist()
|
@frappe.whitelist()
|
||||||
@ -322,16 +325,15 @@ def create_rfq_items(sq_doc, supplier, data):
|
|||||||
})
|
})
|
||||||
|
|
||||||
@frappe.whitelist()
|
@frappe.whitelist()
|
||||||
def get_pdf(doctype, name, supplier_idx):
|
def get_pdf(doctype, name, supplier):
|
||||||
doc = get_rfq_doc(doctype, name, supplier_idx)
|
doc = get_rfq_doc(doctype, name, supplier)
|
||||||
if doc:
|
if doc:
|
||||||
download_pdf(doctype, name, doc=doc)
|
download_pdf(doctype, name, doc=doc)
|
||||||
|
|
||||||
def get_rfq_doc(doctype, name, supplier_idx):
|
def get_rfq_doc(doctype, name, supplier):
|
||||||
if cint(supplier_idx):
|
if supplier:
|
||||||
doc = frappe.get_doc(doctype, name)
|
doc = frappe.get_doc(doctype, name)
|
||||||
args = doc.get('suppliers')[cint(supplier_idx) - 1]
|
doc.update_supplier_part_no(supplier)
|
||||||
doc.update_supplier_part_no(args)
|
|
||||||
return doc
|
return doc
|
||||||
|
|
||||||
@frappe.whitelist()
|
@frappe.whitelist()
|
||||||
|
@ -25,14 +25,10 @@ class TestRequestforQuotation(unittest.TestCase):
|
|||||||
sq = make_supplier_quotation_from_rfq(rfq.name, for_supplier=rfq.get('suppliers')[0].supplier)
|
sq = make_supplier_quotation_from_rfq(rfq.name, for_supplier=rfq.get('suppliers')[0].supplier)
|
||||||
sq.submit()
|
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)
|
rfq.update_rfq_supplier_status() #rfq.get('suppliers')[1].supplier)
|
||||||
|
|
||||||
self.assertEqual(rfq.get('suppliers')[0].quote_status, 'Received')
|
self.assertEqual(rfq.get('suppliers')[0].quote_status, 'Received')
|
||||||
self.assertEqual(rfq.get('suppliers')[1].quote_status, 'No Quote')
|
self.assertEqual(rfq.get('suppliers')[1].quote_status, 'Pending')
|
||||||
|
|
||||||
def test_make_supplier_quotation(self):
|
def test_make_supplier_quotation(self):
|
||||||
rfq = make_request_for_quotation()
|
rfq = make_request_for_quotation()
|
||||||
|
@ -84,9 +84,6 @@ QUnit.test("Test: Request for Quotation", function (assert) {
|
|||||||
cur_frm.fields_dict.suppliers.grid.grid_rows[0].toggle_view();
|
cur_frm.fields_dict.suppliers.grid.grid_rows[0].toggle_view();
|
||||||
},
|
},
|
||||||
() => frappe.timeout(1),
|
() => frappe.timeout(1),
|
||||||
() => {
|
|
||||||
frappe.click_check('No Quote');
|
|
||||||
},
|
|
||||||
() => frappe.timeout(1),
|
() => frappe.timeout(1),
|
||||||
() => {
|
() => {
|
||||||
cur_frm.cur_grid.toggle_view();
|
cur_frm.cur_grid.toggle_view();
|
||||||
@ -125,7 +122,6 @@ QUnit.test("Test: Request for Quotation", function (assert) {
|
|||||||
() => frappe.timeout(1),
|
() => 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[1].doc.quote_status == "Received");
|
||||||
assert.ok(cur_frm.fields_dict.suppliers.grid.grid_rows[0].doc.no_quote == 1);
|
|
||||||
},
|
},
|
||||||
() => done()
|
() => done()
|
||||||
]);
|
]);
|
||||||
|
@ -27,10 +27,11 @@
|
|||||||
"stock_qty",
|
"stock_qty",
|
||||||
"warehouse_and_reference",
|
"warehouse_and_reference",
|
||||||
"warehouse",
|
"warehouse",
|
||||||
"project_name",
|
|
||||||
"col_break4",
|
"col_break4",
|
||||||
"material_request",
|
"material_request",
|
||||||
"material_request_item",
|
"material_request_item",
|
||||||
|
"section_break_24",
|
||||||
|
"project_name",
|
||||||
"section_break_23",
|
"section_break_23",
|
||||||
"page_break"
|
"page_break"
|
||||||
],
|
],
|
||||||
@ -161,7 +162,7 @@
|
|||||||
{
|
{
|
||||||
"fieldname": "project_name",
|
"fieldname": "project_name",
|
||||||
"fieldtype": "Link",
|
"fieldtype": "Link",
|
||||||
"label": "Project Name",
|
"label": "Project",
|
||||||
"options": "Project",
|
"options": "Project",
|
||||||
"print_hide": 1
|
"print_hide": 1
|
||||||
},
|
},
|
||||||
@ -249,11 +250,18 @@
|
|||||||
"no_copy": 1,
|
"no_copy": 1,
|
||||||
"print_hide": 1,
|
"print_hide": 1,
|
||||||
"read_only": 1
|
"read_only": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"collapsible": 1,
|
||||||
|
"fieldname": "section_break_24",
|
||||||
|
"fieldtype": "Section Break",
|
||||||
|
"label": "Accounting Dimensions"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
"index_web_pages_for_search": 1,
|
||||||
"istable": 1,
|
"istable": 1,
|
||||||
"links": [],
|
"links": [],
|
||||||
"modified": "2020-06-12 19:10:36.333441",
|
"modified": "2020-09-24 17:26:46.276934",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Buying",
|
"module": "Buying",
|
||||||
"name": "Request for Quotation Item",
|
"name": "Request for Quotation Item",
|
||||||
|
@ -9,19 +9,19 @@
|
|||||||
"email_sent",
|
"email_sent",
|
||||||
"supplier",
|
"supplier",
|
||||||
"contact",
|
"contact",
|
||||||
"no_quote",
|
|
||||||
"quote_status",
|
"quote_status",
|
||||||
"column_break_3",
|
"column_break_3",
|
||||||
"supplier_name",
|
"supplier_name",
|
||||||
"email_id",
|
"email_id"
|
||||||
"download_pdf"
|
|
||||||
],
|
],
|
||||||
"fields": [
|
"fields": [
|
||||||
{
|
{
|
||||||
"allow_on_submit": 1,
|
"allow_on_submit": 1,
|
||||||
|
"columns": 2,
|
||||||
"default": "1",
|
"default": "1",
|
||||||
"fieldname": "send_email",
|
"fieldname": "send_email",
|
||||||
"fieldtype": "Check",
|
"fieldtype": "Check",
|
||||||
|
"in_list_view": 1,
|
||||||
"label": "Send Email"
|
"label": "Send Email"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -35,7 +35,7 @@
|
|||||||
"read_only": 1
|
"read_only": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"columns": 4,
|
"columns": 2,
|
||||||
"fieldname": "supplier",
|
"fieldname": "supplier",
|
||||||
"fieldtype": "Link",
|
"fieldtype": "Link",
|
||||||
"in_list_view": 1,
|
"in_list_view": 1,
|
||||||
@ -45,7 +45,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"allow_on_submit": 1,
|
"allow_on_submit": 1,
|
||||||
"columns": 3,
|
"columns": 2,
|
||||||
"fieldname": "contact",
|
"fieldname": "contact",
|
||||||
"fieldtype": "Link",
|
"fieldtype": "Link",
|
||||||
"in_list_view": 1,
|
"in_list_view": 1,
|
||||||
@ -55,19 +55,11 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"allow_on_submit": 1,
|
"allow_on_submit": 1,
|
||||||
"default": "0",
|
"depends_on": "eval:doc.docstatus >= 1",
|
||||||
"depends_on": "eval:doc.docstatus >= 1 && doc.quote_status != 'Received'",
|
|
||||||
"fieldname": "no_quote",
|
|
||||||
"fieldtype": "Check",
|
|
||||||
"label": "No Quote"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"allow_on_submit": 1,
|
|
||||||
"depends_on": "eval:doc.docstatus >= 1 && !doc.no_quote",
|
|
||||||
"fieldname": "quote_status",
|
"fieldname": "quote_status",
|
||||||
"fieldtype": "Select",
|
"fieldtype": "Select",
|
||||||
"label": "Quote Status",
|
"label": "Quote Status",
|
||||||
"options": "Pending\nReceived\nNo Quote",
|
"options": "Pending\nReceived",
|
||||||
"read_only": 1
|
"read_only": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -90,17 +82,12 @@
|
|||||||
"in_list_view": 1,
|
"in_list_view": 1,
|
||||||
"label": "Email Id",
|
"label": "Email Id",
|
||||||
"no_copy": 1
|
"no_copy": 1
|
||||||
},
|
|
||||||
{
|
|
||||||
"allow_on_submit": 1,
|
|
||||||
"fieldname": "download_pdf",
|
|
||||||
"fieldtype": "Button",
|
|
||||||
"label": "Download PDF"
|
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
"index_web_pages_for_search": 1,
|
||||||
"istable": 1,
|
"istable": 1,
|
||||||
"links": [],
|
"links": [],
|
||||||
"modified": "2020-09-28 19:31:11.855588",
|
"modified": "2020-10-16 12:23:41.769820",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Buying",
|
"module": "Buying",
|
||||||
"name": "Request for Quotation Supplier",
|
"name": "Request for Quotation Supplier",
|
||||||
|
@ -91,12 +91,7 @@ class SupplierQuotation(BuyingController):
|
|||||||
for my_item in self.items) if include_me else 0
|
for my_item in self.items) if include_me else 0
|
||||||
if (sqi_count.count + self_count) == 0:
|
if (sqi_count.count + self_count) == 0:
|
||||||
quote_status = _('Pending')
|
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)
|
frappe.db.set_value('Request for Quotation Supplier', doc_sup.name, 'quote_status', quote_status)
|
||||||
|
|
||||||
def get_list_context(context=None):
|
def get_list_context(context=None):
|
||||||
|
Loading…
x
Reference in New Issue
Block a user