0

I have created a custom applications (module) on Odoo v9, that inherits hr.holidays(leaves module) in models of my module, and overrides create() method and also _check_state_access_right() method as I want to modify _check_state_access_right() in my module.

Existing leaves module base class - (hr_holidays.py)

class hr_holidays(osv.osv):
    _name = "hr.holidays"
    _description = "Leave"
    _order = "type desc, date_from desc"
    _inherit = ['mail.thread', 'ir.needaction_mixin']


    def _check_state_access_right(self, cr, uid, vals, context=None):
        if vals.get('state') and vals['state'] not in ['draft', 'confirm', 'cancel'] and not self.pool['res.users'].has_group(cr, uid, 'base.group_hr_user'):
            return False
        return True

    def create(self, cr, uid, values, context=None):
        """ Override to avoid automatic logging of creation """
        if context is None:
            context = {}
        employee_id = values.get('employee_id', False)
        context = dict(context, mail_create_nolog=True, mail_create_nosubscribe=True)
        if not self._check_state_access_right(cr, uid, values, context):
            raise AccessError(_('You cannot set a leave request as \'%s\'. Contact a human resource manager.') % values.get('state'))
        if not values.get('name'):
            employee_name = self.pool['hr.employee'].browse(cr, uid, employee_id, context=context).name
            holiday_type = self.pool['hr.holidays.status'].browse(cr, uid, values.get('holiday_status_id'), context=context).name
            values['name'] = _("%s on %s") % (employee_name, holiday_type)
        hr_holiday_id = super(hr_holidays, self).create(cr, uid, values, context=context)
        self.add_follower(cr, uid, [hr_holiday_id], employee_id, context=context)
        return hr_holiday_id

When I override create method it calls super(hr_holidays,self).create(cr,uid, values,context=context) that calls the create method of the base class of leaves module and then again goes to _check_state_access_right() method of base class and my functionality fails. Please have a look to the code and suggest me whether I can create records without calling super(hr_holidays, self).

class HrHolidaysCustom(osv.osv):
    _name = 'hr.holidays'
    _inherit= 'hr.holidays' 

    def _check_state_access_right_new(self, vals):
        if vals.get('state') and vals['state'] not in ['draft', 'doa', 'reroute', 'confirm', 'cancel'] and not self.pool['res.users'].has_group(request.cr, request.uid, 'base.group_hr_user') : #
            return False
        return True 

    @api.model
    def create(self, values):
        """ Override to add states in method _check_state_access_rights() """
        cr, uid, context = request.cr, request.uid, request.context
        if context is None:
            context = {}
        employee_id = values.get('employee_id', False)
        context = dict(context, mail_create_nolog=True, mail_create_nosubscribe=True)
        if not self._check_state_access_right_new(values):
            print self._check_state_access_right_new(values)
            raise AccessError(_('You cannot set a leave request as \'%s\'. Contact a human resource manager.') % values.get('state'))
        if not values.get('name'):
            employee_name = self.pool['hr.employee'].browse(cr, uid, employee_id, context=context).name
            holiday_type = self.pool['hr.holidays.status'].browse(cr, uid, values.get('holiday_status_id'), context=context).name            
            values['name'] = ("%s on %s") % (employee_name, holiday_type)
        hr_holiday_id = super(HrHolidaysCustom, self).create(values)
        return hr_holiday_id

Ultimately I want to add two more states in the _check_state_access_rights method by making changes in the custom module I made rather than making any changes in the code of existing leave module.

Ashish Ranjan
  • 5,523
  • 2
  • 18
  • 39
Shikhar S
  • 319
  • 1
  • 8

1 Answers1

0

get rid of _name = 'hr.holidays', if you just want to override or add properties to a model using _inhereit='hr.holidays' is fine

to properly override the new method in your class the methods name have to be the same, so in your HrHolidaysCustom class change your method definition to

 def _check_state_access_right(self, vals):
        if vals.get('state') and vals['state'] not in ['draft', 'doa', 'reroute', 'confirm', 'cancel'] and not self.pool['res.users'].has_group(request.cr, request.uid, 'base.group_hr_user') : #
            return False
        return True

from now on the new method will be called in place of the old one you're extending

danidee
  • 9,298
  • 2
  • 35
  • 55
  • Yes but then also it is not creating records without calling the base class of hr.holidays. I want the inherited class to create records locally. Because whenever it's base class is called it goes to _check_state_access_rights method and then my overriding becomes worthless. – Shikhar S Jul 15 '16 at 10:22
  • Thanks. for your response. but as _check_state_access_rights is a private method, it won't be called from the create method of the base class. The create method of the base class will call it's own _check_state_access_rights method instead of calling the one we created and customized. Waiting for your valuable response. Thanks – Shikhar S Jul 16 '16 at 08:41
  • No that's not right, python doesn't have access modifiers like java and most `c-based` languages the `underscore(_)` is just a guidance telling other python developers and those reading and/or intending to use the code that this variable shouldn't be accessed from outside the class (it's meant to be private)...it doesn't stop you from actually overriding it. see this SO question and answer(s) http://stackoverflow.com/questions/70528/why-are-pythons-private-methods-not-actually-private – danidee Jul 16 '16 at 09:22
  • so glad to hear that...if my answer worked for you consider accepting and or upvoting it, that's the way we say thank you on stack overflow :)....there's a Grey arrow beside the answer. – danidee Jul 16 '16 at 11:01