This question has been flagged
7 Replies
19180 Views

Hi all,

I would like to override a function called _cart_update which is in the website_sale module. But I want to change the middle of the function (I want to do something in the middle of the function code). So I tried to rewrite the function in my custom module and add the website_sale module as a dependency module (I rewrite the function without adding any super() calls). My function gets the function call. No problem with that. But there are other modules that override the same function with super() calls. Sadly, those functions will not be executed. But I want them to be executed.

Is there any issue with my work? or is there any other way to do this?

Thank you.

Avatar
Discard
Author

@Jake Robinson

Thank you. Your way worked!!!. Can you provide more details on the first approach (Changing where the hook is) ? I couldn't understand what you were saying. Could you please provide an example of that??

(Sorry I don't have enough Karma to comment on your answer. :( )

Hello @Janath Manthila

Hope you are well.

I have the same concern. Can you please help me? If you got any solution.

Thanks

Best Answer

Hi Janath

This kind of customisation is one of the trickiest parts of developing with Odoo, and poor approaches to this are one of the most common reasons I've seen apps break (especially app store apps, they love to override base code and not call super).

There are two main approaches:

Changing where the hook is: It's much better not to rewrite Odoo code, so trying another approach is always preferable. Is the code you're trying to edit actually being run in the _cart_update function, or is this function calling another function with some values that you'd like to change, or something else? If another function is being called, you can add a flag to the context before calling _cart_update, then make the change the other function that is being called if that flag exists. 

Overriding the original function: Rather than inheriting it, you can override the definition. You can do this with the following code:

from odoo.addons.website_sale.models.sale_order import SaleOrder as OriginalSaleOrder


def _cart_update(self, product_id=None, line_id=None, add_qty=0, set_qty=0, **kwargs):
# Insert the original code with your changes here

OriginalSaleOrder._cart_update = _cart_update

This just replaces the website_sale level of _cart_update, so all other modules will still function as normal, no need to call any super.

Avatar
Discard

Thank you

the problem with this is, when you uninstall the module the

´´´ OriginalSaleOrder._cart_update = _cart_update ´´´

part stays and blocks the basic function....

So when you install or uninstall the module with the _cart_update = _cart_update override you need to restart odoo to see the real changes. Otherwise it uses the same code.

Is there any elegant way to override the middle of a basic method? This seems a little bit tricky, what if you just use the same methodname in the same class from the custom module? This will override the basic methods too.

Best Answer

Hi Janatha,

Try this

def _cart_update(self):
    //copy the code from the function
    //add the code on the middle
    //the rest of the method you want to replace
    return super(className,self)._cart_update(self)
Avatar
Discard

Please avoid this empty space.

@Ermin Trevisan Broh, I couldn't find any unnecessary white space in the answer, If you can find any, kindly edit and remove it, if not rollback your vote.

Now empty space is gone LoL

Best Answer

Is there any issue with my work? 
   No there is no issue as long as your module dependency tree is intact/clear.  ​
is there any other way to do this?
   No there no way to override something which is in the middle of the method           

Avatar
Discard
Author Best Answer

Hi Muhammed 

Thank you for the reply.

But will it be a double code execution because we rewrite the code and call the parent function by adding super()?

Hi Ravi,

Thank you for the reply. Do you have any thoughts on why it doesn't execute the other functions which are written in other modules (using super())?

Avatar
Discard

that's true brother, let me check if there is any way to walk around it.

it's because you do not call super in your method so it will not execute other functions. in this case you may change the module dependency it's will change MRO (Method Resolution Order) so it will call first other methods then your method.