Auto Calculate Total, Grand Total in sales order based on Sales order Item Amount

Hello All,

I have added length and width column in Sales Order Item table and want to calculate Sales order item Amount = (length * width * qty * rate) / 1000000 and then want to update every related fields in sales invoice with the amount return by Sales Invoice Item Table.

I have done some of this using Hook Events of on_submit and then call python method in one of python file. But i think it’s too long way to achieve this. Is there any method written in erpnext code which auto calculate total, grand total, net total, base grand total etc of sales invoice based on amount written in sales invoice item table ?

I want to be done this same in Sales Order, Sales Invoice, Quotation, Delivery Note.

Regards,
Hardik Gadesha

1 Like

Any Help on this ?

There is a function in both Js and Py. doc_obj.calculate_taxes_and_totals()

can you explain or show some code to understand how it works ?

How about you share your function and I’ll tell you what you can do

@saifi0102

def si_length_width(doc,method):
from frappe.utils import flt
total = 0.0
for d in doc.items:
d.amount = (flt(d.length) * flt(d.width) * flt(d.qty) * flt(d.rate)) / 1000000
total += d.amount
doc.total = total

i run this code on hook event of validate and on_submit and it works. But is it possible to simplify code with above given method and can achieve all calculation in one go.

Run doc.calculate_taxes_and_totals() and it’ll calculate all the taxes and totals from the item table and taxes table

i tried it but can not work.

from future import unicode_literals
import frappe
from frappe import msgprint
from frappe.model.document import Document
from erpnext.controllers.taxes_and_totals import calculate_taxes_and_totals

def si_length_width(doc,method):
from frappe.utils import flt
for d in doc.items:
d.amount = (flt(d.length) * flt(d.width) * flt(d.qty) * flt(d.rate)) / 1000000
doc.calculate_taxes_and_totals()

Not Working :disappointed:

Try setting doc.price_list_rate or doc.rate as length * width / 1000000 since that function calculates amount from the rate

Actually best option to do it in custom script, one reason is your user wants to see the update live.

Go to custom script and on change of each field calculate the amount and call refresh function for sales order item child table. Do this for all SO, SI, and DN

@munim yes, i have tried this but it auto calculate qty * rate = amount on save event.

can you please explain with example ?

Do i need to pass any argument in doc.calculate_taxes_and_totals() ?

def si_length_width(doc,method):
    from frappe.utils import flt
    for d in doc.items:
        d.rate = flt(flt(d.length) * flt(d.width) / 1000000, doc.precision("rate", "items"))
    doc.calculate_taxes_and_totals()

I guess this should work. And if you want to, you can also write the same logic in JavaScript to show the calculated amount whenever length and width is changed

1 Like

@saifi0102 Not Working :disappointed:

Which hook are you using?

Custom App Hook for validate and on_submit.

Just wondering why arent your using UOM conversion ?

Your function should be called on validate and I think it should have worked… You should try debugging to see if you function is actually being called or not. Try putting frappe.msgprint(“debug messages”) in your code and see what is happening: is the function being called? and what is happening after calling doc.calculate_taxes_and_totals()? If the problem still confuses you, read the code of calculate_taxes_and_totals()

I can confirm that

> .calculate_taxes_and_totals()

works