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.
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.
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()
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
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
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()