Trigger control question and/or enhancement proposal

Just this week I was working on a customization where I was heavily depending on triggers to run some calculations upon the user entering data in a form. In my particular example, Sales Invoice and Sales Invoice Item had a custom trigger added that would recalculate some taxes upon changing the purchase of unit of measure. The calculation depends on the erpnext field stock_qty and a pair of custom fields: custom_field_excise_tax and custom_field_excise_tax_amt_this_line

The formula is simple: (stock_qty * custom_field_excise_tax)

The results are then assigned to custom_field_excise_tax_amt_this_line like this:

frm.doc.items[index].custom_field_excise_tax_amt_this_line = (stock_qty * custom_field_excise_tax)

(Note: index here is a parameter from a forEach function that selects the correct row (the current one) in a child table)

Thus, when updating the purchase uom field on Sales Invoice Item Frappe automatically recalculates the stock_qty, but my function, which runs correctly and calculates correctly otherwise, will run before frappe recalculates. This creates an error for my calculation function because it takes the values of stock_qty that were previously available.

Thanks to some outside help, I was able to use the workaround trigger to run this: before_save, and the calculation now picks the frappe-calculated values and yields the expected results. This workaround will have frappe running its code to update the stock_qty field upon changing the uom, and my function calculating improperly the first time, but when the view refreshes after save, the results now show correctly.

My function now runs from a separate trigger, like this:

frappe.ui.form.on("Sales Invoice", "before_save", function(frm) {
	frm.doc.items.forEach((item) => {
		my_calculation_function(frm, "Sales Invoice Item",;

So, although the problem is currently resolved, the user has to be forced to Save the Sales Invoice, and I would really prefer to give the user the ability to see the results of his changes immediately as he or she is entering data in a form. This helps speed up multiple entries and makes data calculations on the fly.

So, I would like to know if there exists, or if we need to code it into the core, a program control feature that allows prioritization of calculations to be declared on the trigger directly, so that one can fine tune when your custom script is run. How can I tell frappe client-side the run order for functions? Or is this inexistent in the code?

If this already exists, it would be great to know how to use it. I will continue investigating the code.
If it doesn’t, I propose (and will eventually code and send a Pull request) some parameter passed into the trigger as a parameter with a hierarchical integer, which would allow for complex computations. Here’s an example of what I have in mind:

uom: function(frm, cdt, cdn, run_order=3) {
   frm.doc.items.forEach((item) => {
		my_calculation_function(frm, "Sales Invoice Item",;

In this case: run_order= and its integer would tell which order to run this. For example, frappe has a run order of 1. erpnext has a run order of 2. Your custom script then can be run as #3 (after frappe and erpnext) or if you want to run it before, run it as run order 1