Is Method overriding in Frappe possible?

We know, we can hook to various CRUD events of any doctype.

At that time, Our custom method gets executed after execution of default method.
Is there any way to skip execution of default method.

For example,
I want to execute custom validate method in project, instead of standard validate method.
We want to add some custom field on Task, which gets auto filled when we create Task from project.

Maybe add a before_validate hook?

What is your use case?

1 Like

We want to add mandatory custom field on Task.
This custom field should get automatically filled when creating new task on Project.

Issue is, We need to override following method to add custom field

Some time we come across such requirement when we need to override existing functionality.
We don’t want to change core code. So, Any advice on this will be helpful.

@kolate_sambhaji use after_insert or a before_update hook

You need use frappe.db.set_value, but you can defined all titles in your tasks title.

a example:

def re_title_tasks(doc, method=None):
    for task in doc.tasks:
        t_title = 'TSK - {0} - {1} - {2}'.format(task.idx, task.start_date, task.end_date)
        frappe.db.set_value('Task', task.name, 'title', t_title)

It will redefined the title of all tasks as something like TSK - 1 - 2016-01-01 - 2016-02-10

3 Likes

@max_morais_dmm thanks, let me check this.

@max_morais_dmm @kolate_sambhaji This may not work in all use cases. For eg, in our case - we want to allow users to apply for 2 half day leaves on the same day. This becomes necessity, when a user has only 0.5 day balance in Casual Leave. To take a leave, the user applies half a day CL, and then applies Privilege leave for remaining 0.5 days. The default system validation methjod doesnt allow this to happen. We want to write a method that will override the default validation. I can write a hook to do this validation, but it will still execute the default method as well and throw an error. How do I prevent the default method from executing?

1 Like

Am trying this re_title_tasks on after_insert. However, it does not enter the server side code of re_title_tasks at all.
Tested it with a simple frappe.msgprint and realised hook on after_insert does not work in this situation.

Is there any alternate to renaming tasks after creation?
Thank you.

@asneha1 I used validate do you need check if

doc.get('__islocal'):
    doc.name = "My new Name"

@max_morais_dmm If I use validate, once i enter the server side code re_title_tasks, the doc.tasks is empty. So it does not enter the loop to rename. It exits.

@asneha1 what makes a full sense! If the Project dont have tasks dont have nothing to rename!

@max_morais_dmm No, project does have tasks.
But when i write a hook on validate, when it enters the server side code, doc.tasks is empty.

@asneha1 I’m felling that you are using the wrong approach to solve your issue! Can you describe step-by-step what are you trying?

@max_morais_dmm
Sure.
I am trying the above example of renaming all the titles of task after saving.

  1. In my custom python code :
    @frappe.whitelist()
    def re_title_tasks(doc, method=None):
    for task in doc.tasks:
    t_title = ‘TSK - {0} - {1} - {2}’.format(task.idx, task.start_date, task.end_date)
    frappe.db.set_value(‘Task’, task.name, ‘title’, t_title)

2.In the hooks :
doc_events = {
“Project”: {
“validate”: “projects_custom.projects_custom.doctype.project.project.re_title_tasks”
}
}

And when i try the above scenario after adding rows of tasks in the Project, when it enters the re_title_tasks, doc.tasks is empty.

@asneha1 your code is right, the approach is right, but

It only will works for projects that is already saved:

try this:

def re_title_tasks(doc, method=None):
    for task in doc.tasks:
        title = 'TSK - {0} - {1} - {2}'.format(task.idx, task.start_date, task.end_date)
        if title != task.title:
            task.title = title

1 Like

@asneha1, dont forget of bench restart

@max_morais_dmm, Thank you for your help.
Tried the above.
But even for already saved tasks, when it enters re_title_tasks, the for loop is not being done as doc.tasks is empty. Kindly let me know if that works for you. You are able to get a non-empty doc.tasks?

@asneha1, can you explain how are you expecting to rename the task if it is not related to Project?

If the doc.tasks is empty has nothing to rename!

@max_morais_dmm

I do have a list of tasks under Projects :

However, with the hook on validate,
doc_events = {
“Project”: {
“validate”: “projects_custom.projects_custom.doctype.project.project.re_title_tasks”
}
}

at the server side function, I only get a empty doc.tasks at the server side re_title_tasks function.

:frowning: