# Part of Odoo. See LICENSE file for full copyright and licensing details. from collections import defaultdict from datetime import timedelta from odoo import api, fields, models, _ from odoo.exceptions import ValidationError from odoo.tools import float_round class HrLeave(models.Model): _inherit = 'hr.leave' employee_overtime = fields.Float(compute='_compute_employee_overtime', groups='base.group_user') overtime_deductible = fields.Boolean(compute='_compute_overtime_deductible') @api.depends('holiday_status_id') def _compute_overtime_deductible(self): for leave in self: leave.overtime_deductible = leave.holiday_status_id.overtime_deductible and not leave.holiday_status_id.requires_allocation @api.model_create_multi def create(self, vals_list): res = super().create(vals_list) self._check_overtime_deductible(res) return res def write(self, vals): res = super().write(vals) fields_to_check = {'number_of_days', 'request_date_from', 'request_date_to', 'state', 'employee_id', 'holiday_status_id'} if not any(field for field in fields_to_check if field in vals): return res self._check_overtime_deductible(self) return res @api.model def _get_deductible_employee_overtime(self, employees): # Uses the calculation logic now located in the hr.employee model. return employees._get_deductible_employee_overtime() @api.depends('number_of_hours', 'employee_id', 'holiday_status_id') def _compute_employee_overtime(self): diff_by_employee = self.employee_id._get_deductible_employee_overtime() for leave in self: leave.employee_overtime = diff_by_employee[leave.employee_id] def _check_overtime_deductible(self, leaves): # If the type of leave is overtime deductible, we have to check that the employee has enough extra hours hours = leaves.employee_id._get_deductible_employee_overtime() for leave in leaves.filtered('overtime_deductible'): if hours[leave.employee_id] < 0: if leave.employee_id.user_id == self.env.user: raise ValidationError(_('You do not have enough extra hours to request this leave')) raise ValidationError(_('The employee does not have enough extra hours to request this leave.')) def action_reset_confirm(self): self._check_overtime_deductible(self) res = super().action_reset_confirm() return res def action_approve(self, check_state=True): res = super().action_approve(check_state) self._check_overtime_deductible(self) return res def _update_leaves_overtime(self): # TODO: Remove in master, since its no longer used. date_from, date_to = self.mapped('date_from'), self.mapped('date_to') if date_from and date_to: self.env['hr.attendance'].sudo().search([ ('check_in', '<=', max(date_to)), ('check_out', '>=', min(date_from)), ('employee_id', 'in', self.employee_id.ids), ])._update_overtime() def _force_cancel(self, *args, **kwargs): super()._force_cancel(*args, **kwargs)