FYI, you can also use monkey patching with Python. I needed to override erpnext.controllers.taxes_and_totals.calculate_taxes_and_totals
. Here is what I did:
- Create a new module called
my_app.my_module
and a file inside it calledoverride_calculate_taxes_and_totals.py
with a new class like this:
from erpnext.controllers import taxes_and_totals
class my_app_calculate_taxes_and_totals(
taxes_and_totals.calculate_taxes_and_totals
):
"""Override for calculating taxes and totals in MyApp."""
<your changes here>
taxes_and_totals.calculate_taxes_and_totals = my_app_calculate_taxes_and_totals
Note that I import the module, not the class, and reference the class as taxes_and_totals.calculate_taxes_and_totals
.
The last line changes the reference for taxes_and_totals.calculate_taxes_and_totals
to my_app_calculate_taxes_and_totals
so any other imports in standard ERPNext code get my class instead of the original class.
- Make sure your code runs before any other imports:
This only works if the code above runs before the standard code imports taxes_and_totals.calculate_taxes_and_totals
so you can add the following line to hooks.py
:
extend_bootinfo = [
"my_app.startup.boot.boot_session",
]
and create a module called my_app.startup
with a file called boot.py
as so:
# This is the important line
from my_app.my_module import override_calculate_taxes_and_totals
def boot_session(bootinfo):
"""boot session."""
We don’t need the boot_session
function to do anything. It is the import at the top that matters. Because this code runs every time a user logs in, the patch is set and the modified code will run. Of course, because I am inheriting from the original class, the original function is available as a super()
reference.