Custom script for purchase order item

Hi !
I need some help about a custom script. It’s probably so evident for you Erpnext guys, but I don’t get it.
What I need is to display actual qty and projected qty on item grid in the same column (for space sake). it would display 10/12 for example.
So, I added a custom script on Purchase Order doctype, and tried this

frappe.ui.form.on("Purchase Order Item", {
    item_code: function(frm, cdt, cdn) {
        var row = locals[cdt][cdn];
console.log(row);
        cur_frm.cscript.recalculate();
        cur_frm.refresh_fields();
        var actual = row.actual_qty;
        var projected = row.projected_qty;
console.log(row.projected_qty);
        row.stock_summary = projected+" / "+actual;
        frm.refresh_field("items");
    },
});

but actual_qty and projected_qty returns 0, whatever the real qty is.

Can someone help me please ?

by the way, I trigger this script on item row insertion, but I’d like too to update the value on load, but didn’t manage…

Regards

Hi there !
can anybody help ? I’m sure it’s something ridiculously easy like I didn’t use the right trigger, or I missed some ajax stuff…
Thanks

You could try this:

frappe.ui.form.on("Purchase Order Item", {
item_code: function(frm, cdt, cdn) {
	var d = locals[cdt][cdn];
	frappe.model.set_value(d.doctype, d.name, 'stock_summary', (d.projected_qty + "/" + d.actual_qty));
}
});

Thank you @cpurbaugh, but still no chance… d.projected_qty and d.actual_qty are still undefined, or 0 if I use cur_frm.cscript.recalculate();
projected_qty and actual_qty are custom fields themselves, can it be the reason why I can fetch their value ?
Regards

Hi @MelBohard,

this might look more than a hack than a nice solution, but it seems to work :smile: instead of using the actual row, why not check all rows and update accordingly:

frappe.ui.form.on("Purchase Order Item", {
  item_code: function(frm, cdt, cdn) {
    var items = cur_frm.doc.items;
    items.forEach(function(entry) {
      if (entry.item_code != null) {
        var actual = entry.actual_qty;
        var projected = entry.projected_qty;
        var stock_summary = projected + " / " + actual;
        frappe.model.set_value(entry.doctype, entry.name, "stock_summary", stock_summary); 
      } 
    }
  }
});

This, still will only get updated on row addition. A workaround for this could be a mutation observer: this will check a field (e.g. total) for changes; assuming that a change in the table will affect the total, this could help. Otherwise, try the refresh trigger (on saving, F5, …).

 // mutation observer for item changes
 var totalObserver = new MutationObserver(function(mutations) {
     mutations.forEach(function(mutation) {
        // execute your function here
     });
 });
 var target=document.querySelector('div[data-fieldname="total"] .control-input-wrapper .control-value');
 var options = {
    attributes: true,
    characterData: true
 };
 totalObserver.observe(target, options);

Hope this helps.

Thank you so much @lasalesi !
I finally used the refresh trigger, at least for a quick solution. Maybe I’ll rework this later, but for now it will do.

frappe.ui.form.on("Purchase Order", {
    refresh: function(frm, cdt, cdn) {
        var items = cur_frm.doc.items;
        items.forEach(function(entry) {
            if (entry.item_code != null) {
                var actual = entry.actual_qty;
                var projected = entry.projected_qty;
                var stock_summary = actual + " / " + projected;
                frappe.model.set_value(entry.doctype, entry.name, "stock_summary", stock_summary);
            }
        });
    }
});

Thanks again !