mirror of
https://github.com/frappe/erpnext.git
synced 2026-09-17 10:36:31 +00:00
feat: phantom bom (#50351)
* feat: add phantom bom settings in bom doctype * feat: new explosion logic for production plan, subcontracting and work order/manufacturing * feat: modify explosion logic in reports and bom creator * fix: failing test * feat: add convert to phantom item support in bom creator * test: added test cases * fix: always fetch rm rate if phantom bom * refactor: PP phantom explosion logic * fix: report test cases * feat: add phantom item in description of item if phantom item in bom tree * fix: hide create button if bom is phantom * fix: bugs found by coderabbit
This commit is contained in:
@@ -140,6 +140,17 @@ class BOMConfigurator {
|
||||
},
|
||||
btnClass: "hidden-xs",
|
||||
},
|
||||
{
|
||||
label: __(frappe.utils.icon("add", "sm") + " Phantom Item"),
|
||||
click: function (node) {
|
||||
let view = frappe.views.trees["BOM Configurator"];
|
||||
view.events.add_sub_assembly(node, view, true);
|
||||
},
|
||||
condition: function (node) {
|
||||
return node.expandable;
|
||||
},
|
||||
btnClass: "hidden-xs",
|
||||
},
|
||||
{
|
||||
label: __("Collapse All"),
|
||||
click: function (node) {
|
||||
@@ -170,6 +181,17 @@ class BOMConfigurator {
|
||||
},
|
||||
btnClass: "hidden-xs",
|
||||
},
|
||||
{
|
||||
label: __(frappe.utils.icon("move", "sm") + " Phantom Item"),
|
||||
click: function (node) {
|
||||
let view = frappe.views.trees["BOM Configurator"];
|
||||
view.events.convert_to_sub_assembly(node, view, true);
|
||||
},
|
||||
condition: function (node) {
|
||||
return !node.expandable;
|
||||
},
|
||||
btnClass: "hidden-xs",
|
||||
},
|
||||
{
|
||||
label: __(frappe.utils.icon("delete", "sm") + " Item"),
|
||||
click: function (node) {
|
||||
@@ -253,10 +275,10 @@ class BOMConfigurator {
|
||||
}
|
||||
}
|
||||
|
||||
add_sub_assembly(node, view) {
|
||||
add_sub_assembly(node, view, phantom = false) {
|
||||
let dialog = new frappe.ui.Dialog({
|
||||
fields: view.events.get_sub_assembly_modal_fields(view, node.is_root),
|
||||
title: __("Add Sub Assembly"),
|
||||
fields: view.events.get_sub_assembly_modal_fields(view, node.is_root, false, phantom),
|
||||
title: phantom ? __("Add Phantom Item") : __("Add Sub Assembly"),
|
||||
});
|
||||
view.events.set_query_for_workstation(dialog);
|
||||
|
||||
@@ -282,6 +304,7 @@ class BOMConfigurator {
|
||||
operation: node.data.operation,
|
||||
workstation_type: node.data.workstation_type,
|
||||
operation_time: node.data.operation_time,
|
||||
phantom: phantom,
|
||||
},
|
||||
callback: (r) => {
|
||||
view.events.load_tree(r, node);
|
||||
@@ -292,15 +315,18 @@ class BOMConfigurator {
|
||||
});
|
||||
}
|
||||
|
||||
get_sub_assembly_modal_fields(view, is_root = false, read_only = false) {
|
||||
get_sub_assembly_modal_fields(view, is_root = false, read_only = false, phantom = false) {
|
||||
let fields = [
|
||||
{
|
||||
label: __("Sub Assembly Item"),
|
||||
label: phantom ? __("Phantom Item") : __("Sub Assembly Item"),
|
||||
fieldname: "item_code",
|
||||
fieldtype: "Link",
|
||||
options: "Item",
|
||||
reqd: 1,
|
||||
read_only: read_only,
|
||||
filters: {
|
||||
is_stock_item: !phantom,
|
||||
},
|
||||
},
|
||||
{ fieldtype: "Column Break" },
|
||||
{
|
||||
@@ -320,7 +346,7 @@ class BOMConfigurator {
|
||||
},
|
||||
];
|
||||
|
||||
if (is_root) {
|
||||
if (is_root && !phantom) {
|
||||
fields.push(
|
||||
...[
|
||||
{ fieldtype: "Section Break" },
|
||||
@@ -384,10 +410,10 @@ class BOMConfigurator {
|
||||
return fields;
|
||||
}
|
||||
|
||||
convert_to_sub_assembly(node, view) {
|
||||
convert_to_sub_assembly(node, view, phantom = false) {
|
||||
let dialog = new frappe.ui.Dialog({
|
||||
fields: view.events.get_sub_assembly_modal_fields(view, node.is_root, true),
|
||||
title: __("Add Sub Assembly"),
|
||||
fields: view.events.get_sub_assembly_modal_fields(view, node.is_root, true, phantom),
|
||||
title: phantom ? __("Add Phantom Item") : __("Add Sub Assembly"),
|
||||
});
|
||||
|
||||
dialog.set_values({
|
||||
@@ -400,7 +426,9 @@ class BOMConfigurator {
|
||||
let bom_item = dialog.get_values();
|
||||
|
||||
if (!bom_item.item_code) {
|
||||
frappe.throw(__("Sub Assembly Item is mandatory"));
|
||||
frappe.throw(
|
||||
phantom ? __("Phantom Item is mandatory") : __("Sub Assembly Item is mandatory")
|
||||
);
|
||||
}
|
||||
|
||||
bom_item.items.forEach((d) => {
|
||||
@@ -425,6 +453,7 @@ class BOMConfigurator {
|
||||
workstation_type: node.data.workstation_type,
|
||||
operation_time: node.data.operation_time,
|
||||
workstation: node.data.workstation,
|
||||
phantom: phantom,
|
||||
},
|
||||
callback: (r) => {
|
||||
node.expandable = true;
|
||||
|
||||
Reference in New Issue
Block a user