How to override method in frappe?

Yes, It worked

i need to change frappe.utils.format_date function but none of hooks.py method and monkey_patching method worked for me!!!
in second method when i use function just after load_monkey_patches(), value has been returned from my new function but in other places such as site, value returned from frappe.
any idea?

@johnwick
Hii
Have you you found any solution for this ? I am facing same problem.

can you explain with some examples for build_my_thing works?

could you please explain more what the problem you did?

Write these in your custom app

Override class method:

from erpnext.selling.doctype.sales_order.sales_order import SalesOrder

SalesOrder.validate = yourmethod

Override standard method:

from frappe import utils

utils.cstr = yourmethod

Where in the init.py file ?

Can someone please confirm frappe.core doctype classes are also part of this? I am trying to override “UserPermission” class (from frappe.core.doctype) and it is not working. However docTypes in ERPNext I am able to.

There is a hook for that.

Let’s continue this discussion :slight_smile:

Monkey patch is ok. Using hooks.py is ok.

Now let’s get into more details.

There is a non-Class method that I override successfully.

File to be overridden: frappe.desk.reportview.py

Method to be overridden: get_form_params(), the original code is shown below:

def get_form_params():
“”“Stringify GET request parameters.”“”
data = frappe._dict(frappe.local.form_dict)
clean_params(data)
validate_args(data)
return data

The clean_params(data) and validate_args(data) will call other functions within reportview.py.

Now I want to add a custom function just before

return data

The problem is that I need to copy the whole of reportview.py to my new override.py because some function doesn’t do a “return”; “data” will be lost during the chain of calls.

The new block looks like:

def get_form_params():
“”“Stringify GET request parameters.”“”
data = frappe._dict(frappe.local.form_dict)
frappe.desk.reportview.clean_params(data) ← added frappe.desk.reportview. so it will reference the original reportview.py
frappe.desk.reportview.validate_args(data) ← added frappe.desk.reportview. so it will reference the original reportview.py
new_function(data) ← the new function I need to process “data”
return data

I don’t want to copy N functions from reportview.py to override.py because it will be a nightmare to maintain.

I’m kinda stuck.

Any advice?

hey @Mohammed_Redha did you find the solution to this

I rise a problem…
This solution works only if your sites have the same app installed, because monkeypatch is applied on the same ERP instance and affects multiple sites.

The side effect of this solution result in calling a module that could be not installed in other sites and produce an error.
For example, suppose app1 override a method of erpnext, and suppose to have the following configuration:

  • site1: erpnext, app1
  • site2: erpnext, app2
    Monkeypatch will affect both the sites not only site1, and produce an error in site2 because frappe couldn’t not find app1 because the instance is the same…

Frappe’s team should take in charge this request, fix should be applied in Frappe core and we don’t have to think to complex and futile workaroud because, solution should came from Frappe.