Adding customization for Sales Invoice Doctype

Hello;

Please I need help to resolve this problem that is related to the customization:

I am trying to add customization on the sales invoice doctype and I am using the below way, but I need help to add whitelist method to the custom python file so I can call it from the custom javascript file, appreciate if someone can help me and guide me.

I create jewelry as custom application with the following files:

apps/jewelry/jewelry/custom/sales_invoice/sales_invoice.py
apps/jewelry/jewelry/custom/sales_invoice/sales_invoice.js
apps/jewelry/jewelry/custom/sales_invoice/__ init__.py

The hooks.py of the custom_app is containing the following:
doctype_js = {"Sales Invoice" : "custom/sales_invoice/sales_invoice.js"}

The sales_invoice.py is containing the following:

from __ future__ import unicode_literals
import frappe
from frappe.model.document import Document
from erpnext.accounts.general_ledger import make_gl_entries
from erpnext.accounts.general_ledger import delete_gl_entries
from erpnext.controllers.accounts_controller import AccountsController
from frappe import utils

@frappe.whitelist()
def get_jewelry_price(jewelry_type):
gold_price = frappe.db.get_single_value(‘Jewelry Settings’, ‘gold_price’)
return gold_price

I need to call this whitelist method from the sales_invoice.js, so what is the correct path for the frappe.call method? I tried a lot of paths but it always give me: The resource you are looking for is not available

Do I need to do anything in the hooks.py?
Or I am calling the method wrongly using wrong path because I am using the following path:

if (item.item_code) {
frappe.call({
method: “jewelry.custom.sales_invoice.sales_invoice.get_jewelry_price”,
args: {jewelry_type: item.jewelry_type},
callback: function(r) {
if (r.message) {
item.gold_price = r.message;
}
else {
item.gold_price = 0;
}
refresh_field(‘items’);
}
});

As a troubleshoting, I tried the below:
bench execute jewelry.custom.sales_invoice.sales_invoice.get_jewelry_price

And I got the following error:

ImportError: No module named custom.sales_invoice.sales_invoice

As following:

frappe@Bilal:~/frappe-bench$ bench execute jewelry.custom.sales_invoice.sales_invoice.get_jewelry_price
Traceback (most recent call last):
File “/usr/lib/python2.7/runpy.py”, line 174, in _run_module_as_main
“main”, fname, loader, pkg_name)
File “/usr/lib/python2.7/runpy.py”, line 72, in _run_code
exec code in run_globals
File “/home/frappe/frappe-bench/apps/frappe/frappe/utils/bench_helper.py”, line 94, in
main()
File “/home/frappe/frappe-bench/apps/frappe/frappe/utils/bench_helper.py”, line 18, in main
click.Group(commands=commands)(prog_name=‘bench’)
File “/home/frappe/frappe-bench/env/local/lib/python2.7/site-packages/click/core.py”, line 764, in call
return self.main(*args, **kwargs)
File “/home/frappe/frappe-bench/env/local/lib/python2.7/site-packages/click/core.py”, line 717, in main
rv = self.invoke(ctx)
File “/home/frappe/frappe-bench/env/local/lib/python2.7/site-packages/click/core.py”, line 1137, in invoke
return _process_result(sub_ctx.command.invoke(sub_ctx))
File “/home/frappe/frappe-bench/env/local/lib/python2.7/site-packages/click/core.py”, line 1137, in invoke
return _process_result(sub_ctx.command.invoke(sub_ctx))
File “/home/frappe/frappe-bench/env/local/lib/python2.7/site-packages/click/core.py”, line 956, in invoke
return ctx.invoke(self.callback, **ctx.params)
File “/home/frappe/frappe-bench/env/local/lib/python2.7/site-packages/click/core.py”, line 555, in invoke
return callback(*args, **kwargs)
File “/home/frappe/frappe-bench/env/local/lib/python2.7/site-packages/click/decorators.py”, line 17, in new_func
return f(get_current_context(), *args, **kwargs)
File “/home/frappe/frappe-bench/apps/frappe/frappe/commands/init.py”, line 24, in _func
ret = f(frappe._dict(ctx.obj), *args, **kwargs)
File “/home/frappe/frappe-bench/apps/frappe/frappe/commands/utils.py”, line 117, in execute
ret = frappe.get_attr(method)(*args, **kwargs)
File “/home/frappe/frappe-bench/apps/frappe/frappe/init.py”, line 919, in get_attr
return getattr(get_module(modulename), methodname)
File “/home/frappe/frappe-bench/apps/frappe/frappe/init.py”, line 704, 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 custom.sales_invoice.sales_invoice

Regards
Bilal

Hey @bghayad, based on the error message, it seems like your Python interpreter can’t find the sales_invoice directory. The way it recognises modules/folders (atleast in Python 2.7) is by looking for __init__.py files inside them.

Do you have a __init__.py inside the custom folder?

1 Like

Hello @RohanB
Exactly, this was the solution.
It was required to add the init.py under the custom directory.
Regards
Bilal

1 Like