Childtable Triggering Custom Calculation

I wrote a custom script in the Purchase Order Item childtable, and it currently updates total volume when the field “qty” changes. I want this to be the case, but I, also, want it to do the calculation even if it’s just the default value (1) is there.

See the following screenshots. When I change Quantity from 1 to 5, then it triggers the calculation. Here is my script:

frappe.ui.form.on("Purchase Order Item", "qty", function(frm, cdt, cdn){
      var d = locals[cdt][cdn];
      frappe.model.set_value(d.doctype, d.name, "total_volume", d.qty * d.volume_per_unit);

      var total = 0;
      frm.doc.items.forEach(function(d) { total += d.total_volume;});
      frm.set_value('total_net_volume', total);

    });

add an extra trigger with row creation/addition/item code modification
any one of those will suffice

@neerajvkn I’m new to custom scripts so this might be a basic question, but how do I add another trigger? Can you point me to the right documentation if possible?

Thanks

qty in line 1 is the current trigger,
create a function for ur calculation, call that inside like below,

replicate the first 3 lines, change the trigger to whatever fieldname u want to.

 frappe.ui.form.on("Purchase Order Item", "qty", function(frm, cdt, cdn){
volume_calc(frm,cdt,cdn);
});

function volume_calc(frm,cdt,cdn){
    var d = locals[cdt][cdn];
    frappe.model.set_value(d.doctype, d.name, "total_volume", d.qty * d.volume_per_unit);
    var total = 0;
    frm.doc.items.forEach(function(d) { total += d.total_volume;});
    frm.set_value('total_net_volume', total);
}

if u add this to ur custom script, it’ll do the calculation when item code field is modified, if there exists one in ur table

 frappe.ui.form.on("Purchase Order Item", "item_code", function(frm, cdt, cdn){
volume_calc(frm,cdt,cdn);
});

@neerajvkn Thank you. I’m having issues with the trigger. Even when I just change the qty, it’s not triggering the change, in this function format:

frappe.ui.form.on("Purchase Order Item", "qty", function(frm, cdt, cdn){
    volume_calc(frm);
});

function volume_calc(frm){
    var d = locals[cdt][cdn];
    frappe.model.set_value(d.doctype, d.name, "total_volume", d.qty * d.volume_per_unit);
    var total = 0;
    frm.doc.items.forEach(function(d) { total += d.total_volume;});
    frm.set_value('total_net_volume', total);
}

When I use my original function (from original post), it works fine.

@neerajvkn updated to add childtable trigger, but it’s still not calculating

frappe.ui.form.on("Purchase Order Item", {
    // On qty update
    qty:function(frm, cdt, cdn){
        volume_calc(frm,cdt,cdn);
    },
    
    // On item_code update
    item_code:function(frm,cdt,cdn){
        volume_calc(frm,cdt,cdn);
    },
    
    // On adding a row to child table
    items_add:function(frm,cdt,cdn){
        volume_calc(frm,cdt,cdn);
    }
});

function volume_calc(frm, cdt, cdn){
    var d = locals[cdt][cdn];
    frappe.model.set_value(d.doctype, d.name, "total_volume", d.qty * d.volume_per_unit);
    var total = 0;
    frm.doc.items.forEach(function(d) { total += d.total_volume;});
    frm.set_value('total_net_volume', total);
    // console.log(d.qty)
}

add this line below the above quoted
refresh_field('total_net_volume')

@szufisher @neerajvkn

Not quite working. Here is what I’ve found. When I print my “d” variable, the field “qty” has a value of 1; however when I print d.qty the value is 0 thus the calculation for
total_value in the table is 0 until another volume_calc trigger. See my screenshot below, please.

Also, here is my function:

function volume_calc(frm, cdt, cdn){
    var d = locals[cdt][cdn];
    console.log("First Checkpoint");
    console.log(d);
    console.log(d.qty);
    frappe.model.set_value(cdt, cdn, "total_volume", d.qty * d.volume_per_unit);
    refresh_field('total_volume');
    var total = 0;
    frm.doc.items.forEach(function(d) { total += d.total_volume;});
    frm.set_value('total_net_volume', total);
}

Thanks

Latest Update. Works in most circumstances, however, it still fails when you add a new row to the table and enter the Item Code. Once you change quantity in this circumstance, it works.

frappe.ui.form.on("Purchase Order Item", {
    qty:function(frm, cdt, cdn){
        volume_calc(frm,cdt,cdn);
    },
    
    item_code:function(frm,cdt,cdn){
        volume_calc(frm,cdt,cdn);
    },
    
});

function volume_calc(frm, cdt, cdn){
    var d = locals[cdt][cdn];
    if(d.qty<=1){
        frappe.model.set_value(cdt, cdn, "qty", 1);
    }
    cur_frm.refresh_field("qty");
    frappe.model.set_value(cdt, cdn, "total_volume", d.qty * d.volume_per_unit);
    refresh_field('total_volume');
    var total = 0;
    frm.doc.items.forEach(function(d) { total += d.total_volume;});
    frm.set_value('total_net_volume', total);
}

Thank you @neerajvkn

@salar

where you able to further improve you solution?
I have a similar situation, the first initial add does not trigger the right calculation/values…

Hi,
I want to add formular for this field: amount =% * total amount after tax. And here is my script. But it doesn’t work. Can u pls help me with it


frappe.ui.form.on(“Output Payment Schedule”, {
total_amt_a_:function(frm, cdt, cdn){
var d = locals[cdt][cdn];
frappe.model.set_value(cdt,cdn ,“amount”, cur_frm.doc.total_amt_a_tax * d.percentage_of_amount);
refresh_field(“amount”)
},
percentage_of_amount:function(frm, cdt, cdn){
var d = locals[cdt][cdn];
frappe.model.set_value(cdt,cdn ,“amount”, cur_frm.doc.total_amt_a_tax * d.percentage_of_amount);
refresh_field(“amount”)

}
});