Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: BOM for variant items (backport #44580) #44584

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
56 changes: 35 additions & 21 deletions erpnext/manufacturing/doctype/bom/bom.js
Original file line number Diff line number Diff line change
Expand Up @@ -182,25 +182,30 @@ frappe.ui.form.on("BOM", {
},

make_work_order(frm) {
frm.events.setup_variant_prompt(frm, "Work Order", (frm, item, data, variant_items) => {
frappe.call({
method: "erpnext.manufacturing.doctype.work_order.work_order.make_work_order",
args: {
bom_no: frm.doc.name,
item: item,
qty: data.qty || 0.0,
project: frm.doc.project,
variant_items: variant_items,
},
freeze: true,
callback(r) {
if (r.message) {
let doc = frappe.model.sync(r.message)[0];
frappe.set_route("Form", doc.doctype, doc.name);
}
},
});
});
frm.events.setup_variant_prompt(
frm,
"Work Order",
(frm, item, data, variant_items, use_multi_level_bom) => {
frappe.call({
method: "erpnext.manufacturing.doctype.work_order.work_order.make_work_order",
args: {
bom_no: frm.doc.name,
item: item,
qty: data.qty || 0.0,
project: frm.doc.project,
variant_items: variant_items,
use_multi_level_bom: use_multi_level_bom,
},
freeze: true,
callback(r) {
if (r.message) {
let doc = frappe.model.sync(r.message)[0];
frappe.set_route("Form", doc.doctype, doc.name);
}
},
});
}
);
},

make_variant_bom(frm) {
Expand Down Expand Up @@ -248,6 +253,13 @@ frappe.ui.form.on("BOM", {
};
},
});

fields.push({
fieldtype: "Check",
label: __("Use Multi-Level BOM"),
fieldname: "use_multi_level_bom",
default: 1,
});
}

if (!skip_qty_field) {
Expand Down Expand Up @@ -285,6 +297,7 @@ frappe.ui.form.on("BOM", {
fieldname: "items",
fieldtype: "Table",
label: __("Raw Materials"),
depends_on: "eval:!doc.use_multi_level_bom",
fields: [
{
fieldname: "item_code",
Expand Down Expand Up @@ -347,14 +360,15 @@ frappe.ui.form.on("BOM", {
(data) => {
let item = data.item || frm.doc.item;
let variant_items = data.items || [];
let use_multi_level_bom = data.use_multi_level_bom || 0;

variant_items.forEach((d) => {
if (!d.variant_item_code) {
if (!d.variant_item_code && !use_multi_level_bom) {
frappe.throw(__("Select variant item code for the template item {0}", [d.item_code]));
}
});

callback(frm, item, data, variant_items);
callback(frm, item, data, variant_items, use_multi_level_bom);
},
__(title),
__("Create")
Expand Down
18 changes: 15 additions & 3 deletions erpnext/manufacturing/doctype/work_order/work_order.py
Original file line number Diff line number Diff line change
Expand Up @@ -1299,7 +1299,7 @@ def get_item_details(item, project=None, skip_bom_info=False, throw=True):


@frappe.whitelist()
def make_work_order(bom_no, item, qty=0, project=None, variant_items=None):
def make_work_order(bom_no, item, qty=0, project=None, variant_items=None, use_multi_level_bom=None):
if not frappe.has_permission("Work Order", "write"):
frappe.throw(_("Not permitted"), frappe.PermissionError)

Expand All @@ -1309,12 +1309,13 @@ def make_work_order(bom_no, item, qty=0, project=None, variant_items=None):
wo_doc.production_item = item
wo_doc.update(item_details)
wo_doc.bom_no = bom_no
wo_doc.use_multi_level_bom = cint(use_multi_level_bom)

if flt(qty) > 0:
wo_doc.qty = flt(qty)
wo_doc.get_items_and_operations_from_bom()

if variant_items:
if variant_items and not wo_doc.use_multi_level_bom:
add_variant_item(variant_items, wo_doc, bom_no, "required_items")

return wo_doc
Expand Down Expand Up @@ -1358,7 +1359,18 @@ def add_variant_item(variant_items, wo_doc, bom_no, table_name="items"):

args["amount"] = flt(args.get("required_qty")) * flt(args.get("rate"))
args["uom"] = item_data.stock_uom
wo_doc.append(table_name, args)

existing_row = get_template_rm_item(wo_doc, item.get("item_code"))
if existing_row:
existing_row.update(args)
else:
wo_doc.append(table_name, args)


def get_template_rm_item(wo_doc, item_code):
for row in wo_doc.required_items:
if row.item_code == item_code:
return row


@frappe.whitelist()
Expand Down
Loading