[WIP] Alternative items (#13705)
* Alternative Items in BOM
* Alternative Items in Work Order
diff --git a/erpnext/manufacturing/doctype/bom/bom.js b/erpnext/manufacturing/doctype/bom/bom.js
index 531da8a..c706be9 100644
--- a/erpnext/manufacturing/doctype/bom/bom.js
+++ b/erpnext/manufacturing/doctype/bom/bom.js
@@ -68,6 +68,15 @@
frm.toggle_enable("item", frm.doc.__islocal);
toggle_operations(frm);
+ frm.set_indicator_formatter('item_code',
+ function(doc) {
+ if (doc.original_item){
+ return (doc.item_code != doc.original_item) ? "orange" : ""
+ }
+ return ""
+ }
+ )
+
if (!frm.doc.__islocal && frm.doc.docstatus<2) {
frm.add_custom_button(__("Update Cost"), function() {
frm.events.update_cost(frm);
@@ -85,6 +94,24 @@
frm.copy_doc();
});
}
+
+ if(frm.doc.items && frm.doc.allow_alternative_item) {
+ const has_alternative = frm.doc.items.find(i => i.allow_alternative_item === 1);
+ if (frm.doc.docstatus == 0 && has_alternative) {
+ frm.add_custom_button(__('Alternate Item'), () => {
+ erpnext.utils.select_alternate_items({
+ frm: frm,
+ child_docname: "items",
+ warehouse_field: "source_warehouse",
+ child_doctype: "BOM Item",
+ original_item_field: "original_item",
+ condition: (d) => {
+ if (d.allow_alternative_item) {return true;}
+ }
+ })
+ });
+ }
+ }
},
update_cost: function(frm) {
@@ -338,6 +365,14 @@
refresh_field("stock_qty", d.name, d.parentfield);
});
+frappe.ui.form.on("BOM Item", "item_code", function(frm, cdt, cdn) {
+ var d = locals[cdt][cdn];
+ frappe.db.get_value('Item', {name: d.item_code}, 'allow_alternative_item', (r) => {
+ d.allow_alternative_item = r.allow_alternative_item
+ })
+ refresh_field("allow_alternative_item", d.name, d.parentfield);
+});
+
frappe.ui.form.on("BOM Operation", "operations_remove", function(frm) {
erpnext.bom.calculate_op_cost(frm.doc);
erpnext.bom.calculate_total(frm.doc);
diff --git a/erpnext/manufacturing/doctype/bom_item/bom_item.json b/erpnext/manufacturing/doctype/bom_item/bom_item.json
index 5147bd0..3f1fef0 100644
--- a/erpnext/manufacturing/doctype/bom_item/bom_item.json
+++ b/erpnext/manufacturing/doctype/bom_item/bom_item.json
@@ -41,6 +41,7 @@
"reqd": 1,
"search_index": 1,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
@@ -71,6 +72,7 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
@@ -100,6 +102,7 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
@@ -133,6 +136,7 @@
"reqd": 0,
"search_index": 1,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0,
"width": "150px"
},
@@ -165,6 +169,7 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
@@ -195,6 +200,7 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
@@ -227,6 +233,7 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0,
"width": "250px"
},
@@ -256,6 +263,7 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
@@ -286,6 +294,7 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
@@ -317,6 +326,7 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
@@ -346,6 +356,7 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
@@ -377,6 +388,7 @@
"reqd": 1,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
@@ -408,6 +420,7 @@
"reqd": 1,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
@@ -436,6 +449,7 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
@@ -468,6 +482,7 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
@@ -500,6 +515,7 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
@@ -530,6 +546,7 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
@@ -560,6 +577,7 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
@@ -591,6 +609,7 @@
"reqd": 1,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
@@ -622,6 +641,7 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
@@ -651,6 +671,7 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
@@ -684,6 +705,7 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0,
"width": "150px"
},
@@ -716,6 +738,7 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
@@ -745,6 +768,7 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
@@ -776,6 +800,7 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
@@ -807,6 +832,100 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "section_break_27",
+ "fieldtype": "Section Break",
+ "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,
+ "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,
+ "translatable": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "allow_alternative_item",
+ "fieldtype": "Check",
+ "hidden": 1,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Allow Alternative Item",
+ "length": 0,
+ "no_copy": 0,
+ "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,
+ "translatable": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "original_item",
+ "fieldtype": "Link",
+ "hidden": 1,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Original Item",
+ "length": 0,
+ "no_copy": 0,
+ "options": "Item",
+ "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,
+ "translatable": 0,
"unique": 0
}
],
@@ -820,7 +939,7 @@
"issingle": 0,
"istable": 1,
"max_attachments": 0,
- "modified": "2017-08-18 16:22:46.078661",
+ "modified": "2018-04-17 11:01:32.458783",
"modified_by": "Administrator",
"module": "Manufacturing",
"name": "BOM Item",
diff --git a/erpnext/manufacturing/doctype/work_order/work_order.js b/erpnext/manufacturing/doctype/work_order/work_order.js
index fc8eaa1..a9c1491 100644
--- a/erpnext/manufacturing/doctype/work_order/work_order.js
+++ b/erpnext/manufacturing/doctype/work_order/work_order.js
@@ -121,6 +121,24 @@
})
})
}
+
+ if(frm.doc.required_items && frm.doc.allow_alternative_item) {
+ const has_alternative = frm.doc.required_items.find(i => i.allow_alternative_item === 1);
+ if (frm.doc.docstatus == 0 && has_alternative) {
+ frm.add_custom_button(__('Alternate Item'), () => {
+ erpnext.utils.select_alternate_items({
+ frm: frm,
+ child_docname: "required_items",
+ warehouse_field: "source_warehouse",
+ child_doctype: "Work Order Item",
+ original_item_field: "original_item",
+ condition: (d) => {
+ if (d.allow_alternative_item) {return true;}
+ }
+ })
+ });
+ }
+ }
},
show_progress: function(frm) {
diff --git a/erpnext/public/js/utils.js b/erpnext/public/js/utils.js
index a9ac8c4..ed4b4d2 100644
--- a/erpnext/public/js/utils.js
+++ b/erpnext/public/js/utils.js
@@ -287,9 +287,13 @@
alternative_items.forEach(d => {
let row = frappe.get_doc(opts.child_doctype, d.docname);
- let qty = row.qty;
+ let qty = null;
+ if (row.doctype === 'Work Order Item') {
+ qty = row.required_qty;
+ } else {
+ qty = row.qty;
+ }
row[item_field] = d.alternate_item;
-
frm.script_manager.trigger(item_field, row.doctype, row.name)
.then(() => {
frappe.model.set_value(row.doctype, row.name, 'qty', qty);