pythonodoo-16

Odoo 16: Change the original write method


In odoo source code I have (hr.leave module)

    def write(self, values):
    if 'active' in values and not self.env.context.get('from_cancel_wizard'):
        raise UserError(_("You can't manually archive/unarchive a time off."))

    is_officer = self.env.user.has_group('hr_holidays.group_hr_holidays_user') or self.env.is_superuser()
    if not is_officer and values.keys() - {'attachment_ids', 'supported_attachment_ids', 'message_main_attachment_id'}:
        if any(hol.date_from.date() < fields.Date.today() and hol.employee_id.leave_manager_id != self.env.user for hol in self):
            raise UserError(_('You must have manager rights to modify/validate a time off that already begun'))

    # Unlink existing resource.calendar.leaves for validated time off
    if 'state' in values and values['state'] != 'validate':
        validated_leaves = self.filtered(lambda l: l.state == 'validate')
        validated_leaves._remove_resource_leave()

    employee_id = values.get('employee_id', False)
    if not self.env.context.get('leave_fast_create'):
        if values.get('state'):
            self._check_approval_update(values['state'])
            if any(holiday.validation_type == 'both' for holiday in self):
                if values.get('employee_id'):
                    employees = self.env['hr.employee'].browse(values.get('employee_id'))
                else:
                    employees = self.mapped('employee_id')
                self._check_double_validation_rules(employees, values['state'])
        if 'date_from' in values:
            values['request_date_from'] = values['date_from']
        if 'date_to' in values:
            values['request_date_to'] = values['date_to']
    result = super(HolidaysRequest, self).write(values)
    if not self.env.context.get('leave_fast_create'):
        for holiday in self:
            if employee_id:
                holiday.add_follower(employee_id)

    return result

in my custom module I have already an override of the write method of hr.leave

    def write(self, vals):
    result = super(HrLeavePermissionRequest, self).write(vals)

    # Recompute approve states switch holiday_status_id configuration if the type is changed or another employee is added.
    if 'holiday_status_id' in vals or 'employee_ids' in vals:
        self.action_draft()

    # Fix number_of_days in DB if duration_display is present in the vals
    if 'duration_display' in vals and 'number_of_days' not in vals and 'number_of_hours_display' not in vals:
        duration_display = vals.get('duration_display', self.duration_display)
        if duration_display:
            # Extract numeric parts from the duration_display string
            numeric_part = re.findall(r'\d+\.\d+|\d+', duration_display)
            if numeric_part:
                float_duration = float(numeric_part[0])
                vals['number_of_days'] = float_duration / 8
                vals['number_of_hours_display'] = float_duration
                super(HrLeavePermissionRequest, self).write({'number_of_days': vals['number_of_days'],
                                                             'number_of_hours_display': vals[
                                                                 'number_of_hours_display']})

    self._check_permission_hours()

    return result

what I want to do is skip (comment) this part in odoo source code in my inheritance.

is_officer = self.env.user.has_group('hr_holidays.group_hr_holidays_user') or self.env.is_superuser()
if not is_officer and values.keys() - {'attachment_ids', 'supported_attachment_ids', 'message_main_attachment_id'}:
    if any(hol.date_from.date() < fields.Date.today() and hol.employee_id.leave_manager_id != self.env.user for hol in self):
        raise UserError(_('You must have manager rights to modify/validate a time off that already begun'))

Please not that the custom code I have in my override should be executed in all cases.


Solution

  • Before applying the solution that i give here to answer your question technically, you'd rather granting the required rights: group_hr_holidays_user to the involved users.

    In a new module_a, re-write competely the original def write and change it the way you want, but without calling super() in its scope ( i have commented your unwished lines here):

    def write(self, values):
        if 'active' in values and not self.env.context.get('from_cancel_wizard'):
            raise UserError(_("You can't manually archive/unarchive a time off."))
    
        #is_officer = self.env.user.has_group('hr_holidays.group_hr_holidays_user') or self.env.is_superuser()
        #if not is_officer and values.keys() - {'attachment_ids', 'supported_attachment_ids', 'message_main_attachment_id'}:
            #if any(hol.date_from.date() < fields.Date.today() and hol.employee_id.leave_manager_id != self.env.user for hol in self):
                #raise UserError(_('You must have manager rights to modify/validate a time off that already begun'))
    
        # Unlink existing resource.calendar.leaves for validated time off
        if 'state' in values and values['state'] != 'validate':
            validated_leaves = self.filtered(lambda l: l.state == 'validate')
            validated_leaves._remove_resource_leave()
    
        employee_id = values.get('employee_id', False)
        if not self.env.context.get('leave_fast_create'):
            if values.get('state'):
                self._check_approval_update(values['state'])
                if any(holiday.validation_type == 'both' for holiday in self):
                    if values.get('employee_id'):
                        employees = self.env['hr.employee'].browse(values.get('employee_id'))
                    else:
                        employees = self.mapped('employee_id')
                    self._check_double_validation_rules(employees, values['state'])
            if 'date_from' in values:
                values['request_date_from'] = values['date_from']
            if 'date_to' in values:
                values['request_date_to'] = values['date_to']
        result = models.Model.write(self, values)
        if not self.env.context.get('leave_fast_create'):
            for holiday in self:
                if employee_id:
                    holiday.add_follower(employee_id)
    
        return result
    

    In your existing custom module_b, add module_a in the depends of its manifest.py.

    # -*- coding: utf-8 -*-
    {
        'name': "your_existing_custom_module_b",
        'version': '16.0.1.0.1',
        'depends': ['module_a'],
    }