I have a Invoice for a Service
each service Contain 3 child Items
all t child item have own prices all child item price calculated total will be price of parent item,
i bring the child services in invoice using following script
its appearing but not coe in print format
in print format disply nun
frappe.ui.form.on('Sales Invoice Item', {
item_code: function (frm, cdt, cdn) {
let row = frappe.get_doc(cdt, cdn);
if (row.item_code) {
// Fetch data from the Item Doctype
frappe.call({
method: "frappe.client.get",
args: {
doctype: "Item",
name: row.item_code
},
callback: function (r) {
if (r.message) {
const item = r.message;
// Set main item fields
frappe.model.set_value(cdt, cdn, "custom_is_main_item", 1);
frappe.model.set_value(cdt, cdn, "custom_terms", item.custom_terms || "");
frappe.model.set_value(cdt, cdn, "custom_operational_hours", item.custom_operation_hours || "");
frappe.model.set_value(cdt, cdn, "custom_status", item.custom_status || "");
frappe.model.set_value(cdt, cdn, "item_group", item.item_group || "");
// Generate child items
generate_child_items(frm, row, item);
}
}
});
}
}
});
function generate_child_items(frm, main_row, item) {
// Get the selected company for the Sales Invoice
const company = frm.doc.company || "Default Company"; // Fallback to "Default Company" if no company selected
// Default Sales Account based on the selected company
let income_account = "4110 - Sales - PW"; // Default income account for the sales
if (company) {
// Optionally, you can fetch company-specific income account if needed
// Example: Fetch from company settings if it's dynamic per company
// income_account = fetch_income_account_from_company(company);
}
// Default UOM for all child items
let uom = "Nos"; // UOM for all child items
// Check if child items already exist for this main item
const existing_child_items = frm.doc.items.filter(
(row) => row.parent_item_code === main_row.item_code && row.custom_is_main_item === 0
);
if (existing_child_items.length > 0) {
// Child items already exist, no need to re-add
return;
}
const status = item.custom_status || "Unknown Status"; // Handle missing status gracefully
const child_items = [
{
label: `${status} Terms Bonus `,
rate: item.custom_terms_price || 0,
qty: item.custom_terms || 0,
},
{
label: `${status} Operational Hours Bonus `,
rate: item.custom_hours_price || 0,
qty: item.custom_operation_hours || 0,
},
{
label: `${status} Brand Price Bonus ${item.item_group}`, // Updated label with status
rate: item.custom_item_group_price || 0,
qty: 1
}
];
// Add child items
child_items.forEach((data) => {
let child_row = frm.add_child("items");
frappe.model.set_value(child_row.doctype, child_row.name, "item_name", data.label);
frappe.model.set_value(child_row.doctype, child_row.name, "custom_rate", data.rate);
frappe.model.set_value(child_row.doctype, child_row.name, "qty", data.qty);
frappe.model.set_value(child_row.doctype, child_row.name, "amount", data.qty * data.rate);
frappe.model.set_value(child_row.doctype, child_row.name, "parent_item_code", main_row.item_code);
frappe.model.set_value(child_row.doctype, child_row.name, "custom_is_main_item", 0);
// Set dynamic Income Account and UOM for all child items
frappe.model.set_value(child_row.doctype, child_row.name, "income_account", income_account);
frappe.model.set_value(child_row.doctype, child_row.name, "uom", uom);
});
frm.refresh_field("items");
}
frappe.ui.form.on("Sales Invoice", {
validate: function (frm) {
// Ensure no empty rows exist in items
frm.doc.items = frm.doc.items.filter((row) => row.item_code || row.item_name);
frm.refresh_field("items");
},
item_remove: function (frm, cdt, cdn) {
let row = frappe.get_doc(cdt, cdn);
// If a main item is removed, delete all associated child items
if (row.custom_is_main_item === 1) {
frm.doc.items = frm.doc.items.filter((r) => r.parent_item_code !== row.item_code);
frm.refresh_field("items");
}
},
on_submit: function (frm) {
// Ensure child items are properly updated when saving
frm.doc.items.forEach((row) => {
if (!row.item_code && row.item_name) {
frappe.model.set_value(row.doctype, row.name, "item_code", row.item_name);
}
});
frm.refresh_field("items");
}
});