Is there a way to explode the product bundle into individual items on adding to sales order or sales invoice?
Use Case: Some times one or more items as part of the bundle may not be available, so a different items will be sent. If the bundle is automatically exploded, these unavailable items can be replaced with different items.
You have to write a custom client script for this.
You can call this function on a button click in refresh function.
var get_items_from_product_bundle = function(frm) {
var me = this;
var dialog = new frappe.ui.Dialog({
title: __("Get Items from Product Bundle"),
fields:[
{ fieldtype: 'Link', options: 'Product Bundle', label: 'Product Bundle', fieldname: "product_bundle", reqd: true,
description:'All items in the product bundle selected will be added to the Sales Invoice items.'
}
]
});
dialog.set_primary_action(__('Add'), function() {
var bundle_price_list_rate = 0;
var selected_bundle = {};
var product_bundle = dialog.fields_dict.product_bundle.input.value;
if (product_bundle) {
frm.set_value("items", []);
frappe.call({
method: "frappe.client.get",
args: {
doctype: "Product Bundle",
name: product_bundle,
},
callback(r) {
if(r.message) {
selected_bundle = r.message;
for(let i=0; i<selected_bundle.items.length; i++){
var si_item = frappe.model.add_child(frm.doc, 'Sales Invoice Item', 'items');
frappe.model.set_value(si_item.doctype, si_item.name, 'item_code', selected_bundle.items[i].item_code);
frappe.model.set_value(si_item.doctype, si_item.name, 'qty', selected_bundle.items[i].qty);
if(selected_bundle.items[i].qty > 1){
frappe.model.set_value(si_item.doctype, si_item.name, 'qty', parseFloat(selected_bundle.items[i].qty));
}
}
frm.refresh_fields();
dialog.hide();
}
}
});
} else {
frappe.msgprint(__("Please select Product Bundle"));
}
});
dialog.show();
};
1 Like
As alternative, it is also possible to do something similar whenever a new item is added. If it is a PB, the childs are added to the item list.
frappe.ui.form.on("Sales Order Item", "item_code", function(frm, cdt, cdn) {
var d = locals[cdt][cdn];
if (d.item_code) {
frappe.db.get_list("Product Bundle Item", {
filters: {
parent: d.item_code
},
fields: ['item_code', 'qty', 'description']
}).then((data) => {
frappe.run_serially([
() => {
if (data.length > 0) {
$.each(data, function(i, f) {
var row = frappe.model.add_child(cur_frm.doc, "Sales Order Item", "items");
row.item_code = f.item_code;
row.delivery_date = cur_frm.doc.delivery_date;
row.item_name = f.item_code;
row.description = f.description;
row.qty = f.qty;
})
refresh_field("items");
}
}
]);
});
}
});
2 Likes
Thank You. Should be the right approach. Let me validate this.
Hello Dear ,
Could you guide me For Creating Purchase order from sales order of Bundle Product
I am using version 14.13 ,
But there is one Issue here
- As Bundle Product Which suppose be Be NON Stock and NON Purchase item ,
- When Clicking Create purchase order in List Loading Bundle Product where it suppose to Load Bundled Items , so that after selecting Supplied for each item Supplier PO could be created ,
Hi,
I’m trying to use this client script, but when I’m creating a sales order with a bundle Item, I get the error: Insufficient Permission for Product Bundle Item. I’m using an admin account, but why could this be happening?.
Thanks