New table of items, how to create a Total field

I’ve created a second Items table in the Quotation doctype called optional_items for putting optional or suggested items that I DON’T want the prices to total up with the main quoted items. I want these items however to show an “amount total” and to be totalled up below it’s table in a new separate field called optional_total which I created.

Can anyone help me with this customization? I spent a few hours trying to figure out accessing the already built total functions but I’m not getting anywhere. Not even sure if this needs just a Client side script or if it needs a Server-side one. Either is fine.

Hi @Dbone,

Try with the below code on validate method using hooks

for data in self.optional_items:
	self.optional_total += data.fiedname # here fieldname is the amount field in the optional_items

Thanks

Thank you rohit_w!

So the “optional_items” table I made inherits from Quotation Item, same as the “items” table that is standard in that doctype. It is another instance of the Quotation Item doctype. So the amount field is named the same, but it doesn’t work, won’t calculate. So your script won’t work until the amount field does.

Can I use a second instance of the Quotation Item table, or do I need to create a new doctype to use as a table? If I can use a second instance, how do I get the amount field to calculate?

Can you share me your code

Thanks

Haha, I don’t have any code to share. :slight_smile:

All I have done so far is in the Quotation doctype create:

  • new custom field “optional_items”, set to Table, “Quotation Item” as options
  • new custom field “optional_total”, set to Currency, “currency” as options, read-only

Without ANY custom code, the table shows up no problem and I can select items and add or edit the quantities and rate, but the amount field will not add the quantities and rate together like it does in the “items” table.

Do I need code for that too? I assumed the table would still just work. Would the code I need be similar to this:

for data in self.optional_items:
	data.amount = data.qty * data.rate

Yes and calculate operational_total within same

for data in self.optional_items:
	data.amount = data.qty * data.rate
        self.optional_total += data.amount

Thanks

Ok, here is what i’ve done, still not working unfortunately.

Created quotation_optional.py:

from __future__ import unicode_literals
import frappe
def second_totals():
       for data in self.optional_items:
          data.amount = data.qty * data.rate
          self.optional_total += data.amount

Put this in hooks.py of my custom app “nautcustom”:

doc_events = {"Quotation": {"validate": "nautcustom.quotation_optional.second_totals"}}

saved files, and reloaded ERPNext. No errors, but not working.

Hi @Dbone

Your code should be like as below

from __future__ import unicode_literals
import frappe

def second_totals(doc, method):
       for data in doc.optional_items:
          data.amount = data.qty * data.rate
          doc.optional_total += data.amount

run command bench clear-cache and check

Thanks

Still nothing with hooks.py:

doc_events = {"Quotation": {"validate": "nautcustom.quotation_optional.second_totals"}}

quotation_optional.py:

from __future__ import unicode_literals
import frappe
def second_totals():
       for data in self.optional_items:
          data.amount = data.qty * data.rate
          self.optional_total += data.amount

ran bench clear-cache, reloaded ERPNext, and also ran bench update

Any other ideas? I really appreciate your help.

Just tried to save a quotation and got this error:

Traceback (most recent call last):
  File "/home/frappe/frappe-bench/apps/frappe/frappe/desk/form/save.py", line 22, in savedocs
    doc.save()
  File "/home/frappe/frappe-bench/apps/frappe/frappe/model/document.py", line 242, in save
    return self._save(*args, **kwargs)
  File "/home/frappe/frappe-bench/apps/frappe/frappe/model/document.py", line 259, in _save
    self.insert()
  File "/home/frappe/frappe-bench/apps/frappe/frappe/model/document.py", line 212, in insert
    self.run_before_save_methods()
  File "/home/frappe/frappe-bench/apps/frappe/frappe/model/document.py", line 710, in run_before_save_methods
    self.run_method("validate")
  File "/home/frappe/frappe-bench/apps/frappe/frappe/model/document.py", line 661, in run_method
    return Document.hook(fn)(self, *args, **kwargs)
  File "/home/frappe/frappe-bench/apps/frappe/frappe/model/document.py", line 836, in composer
    hooks.append(frappe.get_attr(handler))
  File "/home/frappe/frappe-bench/apps/frappe/frappe/__init__.py", line 864, in get_attr
    return getattr(get_module(modulename), methodname)
  File "/home/frappe/frappe-bench/apps/frappe/frappe/__init__.py", line 648, in get_module
    return importlib.import_module(modulename)
  File "/usr/lib/python2.7/importlib/__init__.py", line 37, in import_module
    __import__(name)
ImportError: No module named quotation_optional

Does this mean the hooks.py file is incorrect?

Hi @Dbone

Yes you have defined incorrect path in the hooks.py file, kindly correct it

Thanks

i have the same Problem, but i dont quite understand where to put the code and where i should eventuall import it so it gets run.
Is there any good documentation how to start with this. i already did some apps in pyhton so syntax and basic programming knowledge is there, but i dont understand where to “inject it” into the framework