3

I have a lot of models (around 30) that overrides the create method to check for a license state and all of them go like this:

class Model1(models.Model):
    _name='testing_model1'

    @api.model
    def create(self)
        check_license(self)
        return super(Model1, self).create(values)

Is there any way to add the "check_license" function in the main create so I don't have to write it in every model?

David Rios
  • 377
  • 4
  • 9

2 Answers2

4

You can do that by munkey patching but I really don't recommend to do this, and what you should do is create a small module that do this and make sure that all other modules depends on it, this way the call to check will be done only one time.

Peace of advice when you repeat a code in two module consider extracting it to a small module and make sure the two modules depends on it.

Like in your case you can create module check_license put all related code to this operation in it fix dependency on the others 30 modules this will make sure when you install one of those modules the new module will be installed first, and the main benefits is the call to check for license will happen only one time even if you install all 30 modules

Charif DZ
  • 14,415
  • 3
  • 21
  • 40
  • 1
    I agree with this alot. In particular it's already not recommended to mess with the core of Odoo. Any bug in the licence method will cause no object to be created. On top of that, it will make Odoo significantly slower (first-hand experience). As @charif described, just create a reusable module out of it. – JustLudo Oct 14 '20 at 08:44
  • 1
    Your answer makes some wrong assumptions. I think you mix "models" (in the question) with "modules" (which is not in the question). So the question is: how can i avoid to repeat the same logic for every model, if i already have a core function to change. So i see two better answers: 1. my first answer just extending `create` with Odoo's inheritance, which could lead to problems like @Ludo21South is mentioning. And as 2. answer (which i will write later) the use of mixins, which can also lead to such problems but not on every model in Odoo, but only on the ones using the mixin. – CZoellner Oct 14 '20 at 14:19
2

I see two easy possibilities:

1. Usage of Odoo's inheritance

Odoo's inheritance mechanism is also working on the base model. The following example is from Odoo V13 module base_import, but in Odoo V11 there are some examples, too (e.g. in web):

class Base(models.AbstractModel):
    _inherit = 'base'

    @api.model
    def get_import_templates(self):
        """
        Get the import templates label and path.

        :return: a list(dict) containing label and template path
                 like ``[{'label': 'foo', 'template': 'path'}]``
        """
        return []

Following is the code which you'll need (won't work in later versions because create has changed):

class Base(models.AbstractModel):
    _inherit = 'base'

    def create(self, values):
        """
        Extended core method to implement a license check,
        before creating a record.
        """
        check_license(self)
        return super().create(values)

2. Using a mixin (lot of examples in Odoo code)

It's possible to use a mixin class to restrict the license check to some models, which will inherit this mixin. The 1. concept isn't restricting it (but it is possible there too).

class LicenseCheckMixin(models.AbstractModel):
    _name = 'license.check.mixin'

    def create(self, values):
        """
        Extended create method to implement a license check,
        before creating a record.
        """
        check_license(self)
        return super().create(values)

You can then inherit this mixin in other Odoo models:

class SaleOrder(models.Model):
    _name = 'sale.order'
    _inherit = ['sale.order', 'license.check.mixin']
CZoellner
  • 13,553
  • 3
  • 25
  • 38
  • I like the second option us more elegant – Charif DZ Oct 14 '20 at 16:43
  • 1
    Whilst I agree on this answer (the second option is pretty elegant) I would still like to point to the real underlying issue of this question; the license check is tied in with the create option on 30 objects. In my humble opinion I would first check to see if you could separate the two. Maybe set the license options on login, or earlier in the process? I know that it is not what the TS asked and if he really wants to implement this behavior I would recommend @CZoellner's second option using mixins. – JustLudo Oct 15 '20 at 06:42
  • Yes the whole requirement or the concept of fulfilling it should be reconsidered. – CZoellner Oct 15 '20 at 09:11
  • Option #2 works great. Thank you all for the fast response. – David Rios Oct 15 '20 at 13:02