feat: Dialog to select alternative item before creating Sales order
- Users can leave the row blank in the dialog if original item is to be used - Else users can select an alternative item against an original item - In the document, users must check `Is Alternative Item` if needed and also specify which item it is an altenrative to since there are no documented mappings
This commit is contained in:
parent
f19eadab9a
commit
cef7dfd0b4
@ -32,7 +32,7 @@ class calculate_taxes_and_totals(object):
|
||||
|
||||
def filter_rows(self):
|
||||
"""Exclude rows, that do not fulfill the filter criteria, from totals computation."""
|
||||
items = list(filter(lambda item: not item.get("is_alternative_item"), self.doc.get("items")))
|
||||
items = list(filter(lambda item: not item.get("is_alternative"), self.doc.get("items")))
|
||||
return items
|
||||
|
||||
def calculate(self):
|
||||
|
@ -889,6 +889,6 @@ erpnext.taxes_and_totals = class TaxesAndTotals extends erpnext.payments {
|
||||
}
|
||||
|
||||
filtered_items() {
|
||||
return this.frm.doc.items.filter(item => !item["is_alternative_item"]);
|
||||
return this.frm.doc.items.filter(item => !item["is_alternative"]);
|
||||
}
|
||||
};
|
||||
|
@ -87,7 +87,7 @@ erpnext.selling.QuotationController = class QuotationController extends erpnext.
|
||||
if (doc.docstatus == 1 && !["Lost", "Ordered"].includes(doc.status)) {
|
||||
this.frm.add_custom_button(
|
||||
__("Sales Order"),
|
||||
this.frm.cscript["Make Sales Order"],
|
||||
() => this.make_sales_order(),
|
||||
__("Create")
|
||||
);
|
||||
|
||||
@ -141,6 +141,20 @@ erpnext.selling.QuotationController = class QuotationController extends erpnext.
|
||||
|
||||
}
|
||||
|
||||
make_sales_order() {
|
||||
var me = this;
|
||||
|
||||
let has_alternative_item = this.frm.doc.items.some((item) => item.is_alternative);
|
||||
if (has_alternative_item) {
|
||||
this.show_alternative_item_dialog();
|
||||
} else {
|
||||
frappe.model.open_mapped_doc({
|
||||
method: "erpnext.selling.doctype.quotation.quotation.make_sales_order",
|
||||
frm: me.frm
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
set_dynamic_field_label(){
|
||||
if (this.frm.doc.quotation_to == "Customer")
|
||||
{
|
||||
@ -216,6 +230,69 @@ erpnext.selling.QuotationController = class QuotationController extends erpnext.
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
show_alternative_item_dialog() {
|
||||
// Create a `{original item: [alternate items]}` map
|
||||
const item_alt_map = {};
|
||||
this.frm.doc.items.filter(
|
||||
(item) => item.is_alternative
|
||||
).forEach((item) =>
|
||||
(item_alt_map[item.alternative_to] ??= []).push(item.item_code)
|
||||
)
|
||||
|
||||
const fields = [{
|
||||
fieldtype:"Link",
|
||||
fieldname:"original_item",
|
||||
options: "Item",
|
||||
label: __("Original Item"),
|
||||
read_only: 1,
|
||||
in_list_view: 1,
|
||||
},
|
||||
{
|
||||
fieldtype:"Link",
|
||||
fieldname:"alternative_item",
|
||||
options: "Item",
|
||||
label: __("Alternative Item"),
|
||||
in_list_view: 1,
|
||||
get_query: (row, cdt, cdn) => {
|
||||
return {
|
||||
filters: {
|
||||
"item_code": ["in", item_alt_map[row.original_item]]
|
||||
}
|
||||
}
|
||||
},
|
||||
}];
|
||||
|
||||
this.data = Object.keys(item_alt_map).map((item) => {
|
||||
return {"original_item": item}
|
||||
});
|
||||
|
||||
const dialog = new frappe.ui.Dialog({
|
||||
title: __("Select Alternatives for Sales Order"),
|
||||
fields: [
|
||||
{
|
||||
fieldname: "alternative_items",
|
||||
fieldtype: "Table",
|
||||
label: "Items with Alternatives",
|
||||
cannot_add_rows: true,
|
||||
in_place_edit: true,
|
||||
reqd: 1,
|
||||
data: this.data,
|
||||
description: __("Select an alternative to be used in the Sales Order or leave it blank to use the original item."),
|
||||
get_data: () => {
|
||||
return this.data;
|
||||
},
|
||||
fields: fields
|
||||
},
|
||||
],
|
||||
primary_action: function() {
|
||||
this.hide();
|
||||
},
|
||||
primary_action_label: __('Continue')
|
||||
});
|
||||
|
||||
dialog.show();
|
||||
}
|
||||
};
|
||||
|
||||
cur_frm.script_manager.make(erpnext.selling.QuotationController);
|
||||
|
@ -49,7 +49,8 @@
|
||||
"pricing_rules",
|
||||
"stock_uom_rate",
|
||||
"is_free_item",
|
||||
"is_alternative_item",
|
||||
"is_alternative",
|
||||
"alternative_to",
|
||||
"section_break_43",
|
||||
"valuation_rate",
|
||||
"column_break_45",
|
||||
@ -647,16 +648,25 @@
|
||||
},
|
||||
{
|
||||
"default": "0",
|
||||
"fieldname": "is_alternative_item",
|
||||
"fieldname": "is_alternative",
|
||||
"fieldtype": "Check",
|
||||
"label": "Is Alternative Item",
|
||||
"label": "Is Alternative",
|
||||
"print_hide": 1
|
||||
},
|
||||
{
|
||||
"depends_on": "is_alternative",
|
||||
"fieldname": "alternative_to",
|
||||
"fieldtype": "Link",
|
||||
"label": "Alternative To",
|
||||
"mandatory_depends_on": "is_alternative",
|
||||
"options": "Item",
|
||||
"print_hide": 1
|
||||
}
|
||||
],
|
||||
"idx": 1,
|
||||
"istable": 1,
|
||||
"links": [],
|
||||
"modified": "2023-01-24 08:48:06.290335",
|
||||
"modified": "2023-01-26 07:32:02.768197",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Selling",
|
||||
"name": "Quotation Item",
|
||||
|
Loading…
Reference in New Issue
Block a user