85 lines
4.1 KiB
Python
85 lines
4.1 KiB
Python
|
# -*- coding: utf-8 -*-
|
||
|
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||
|
|
||
|
from datetime import datetime
|
||
|
|
||
|
from odoo import api, fields, models, _
|
||
|
from odoo.exceptions import ValidationError
|
||
|
from odoo.osv import expression
|
||
|
|
||
|
|
||
|
class HolidaysAllocation(models.Model):
|
||
|
_inherit = 'hr.leave.allocation'
|
||
|
|
||
|
def default_get(self, fields):
|
||
|
res = super().default_get(fields)
|
||
|
if 'holiday_status_id' in fields and self.env.context.get('deduct_extra_hours'):
|
||
|
domain = [('overtime_deductible', '=', True), ('requires_allocation', '=', 'yes')]
|
||
|
if self.env.context.get('deduct_extra_hours_employee_request', False):
|
||
|
# Prevent loading manager allocated time off type in self request contexts
|
||
|
domain = expression.AND([domain, [('employee_requests', '=', 'yes')]])
|
||
|
leave_type = self.env['hr.leave.type'].search(domain, limit=1)
|
||
|
res['holiday_status_id'] = leave_type.id
|
||
|
return res
|
||
|
|
||
|
overtime_deductible = fields.Boolean(compute='_compute_overtime_deductible')
|
||
|
overtime_id = fields.Many2one('hr.attendance.overtime', string='Extra Hours', groups='hr_holidays.group_hr_holidays_user')
|
||
|
employee_overtime = fields.Float(related='employee_id.total_overtime')
|
||
|
hr_attendance_overtime = fields.Boolean(related='employee_company_id.hr_attendance_overtime')
|
||
|
|
||
|
@api.depends('holiday_status_id')
|
||
|
def _compute_overtime_deductible(self):
|
||
|
for allocation in self:
|
||
|
allocation.overtime_deductible = allocation.hr_attendance_overtime and allocation.holiday_status_id.overtime_deductible
|
||
|
|
||
|
@api.model_create_multi
|
||
|
def create(self, vals_list):
|
||
|
res = super().create(vals_list)
|
||
|
for allocation in res:
|
||
|
if allocation.overtime_deductible and allocation.holiday_type == 'employee':
|
||
|
duration = allocation.number_of_hours_display
|
||
|
if duration > allocation.employee_id.total_overtime:
|
||
|
raise ValidationError(_('The employee does not have enough overtime hours to request this leave.'))
|
||
|
if not allocation.overtime_id:
|
||
|
allocation.sudo().overtime_id = self.env['hr.attendance.overtime'].sudo().create({
|
||
|
'employee_id': allocation.employee_id.id,
|
||
|
'date': allocation.date_from,
|
||
|
'adjustment': True,
|
||
|
'duration': -1 * duration,
|
||
|
})
|
||
|
return res
|
||
|
|
||
|
def write(self, vals):
|
||
|
res = super().write(vals)
|
||
|
if 'number_of_days' not in vals:
|
||
|
return res
|
||
|
for allocation in self.filtered('overtime_id'):
|
||
|
employee = allocation.employee_id
|
||
|
duration = allocation.number_of_hours_display
|
||
|
overtime_duration = allocation.overtime_id.sudo().duration
|
||
|
if overtime_duration != duration:
|
||
|
if duration > employee.total_overtime - overtime_duration:
|
||
|
raise ValidationError(_('The employee does not have enough extra hours to extend this allocation.'))
|
||
|
allocation.overtime_id.sudo().duration = -1 * duration
|
||
|
return res
|
||
|
|
||
|
def action_refuse(self):
|
||
|
res = super().action_refuse()
|
||
|
self.overtime_id.sudo().unlink()
|
||
|
return res
|
||
|
|
||
|
def _get_accrual_plan_level_work_entry_prorata(self, level, start_period, start_date, end_period, end_date):
|
||
|
self.ensure_one()
|
||
|
if level.frequency != 'hourly' or level.frequency_hourly_source != 'attendance':
|
||
|
return super()._get_accrual_plan_level_work_entry_prorata(level, start_period, start_date, end_period, end_date)
|
||
|
datetime_min_time = datetime.min.time()
|
||
|
start_dt = datetime.combine(start_date, datetime_min_time)
|
||
|
end_dt = datetime.combine(end_date, datetime_min_time)
|
||
|
attendances = self.env['hr.attendance'].sudo().search([
|
||
|
('employee_id', '=', self.employee_id.id),
|
||
|
('check_in', '>=', start_dt),
|
||
|
('check_out', '<=', end_dt),
|
||
|
])
|
||
|
work_entry_prorata = sum(attendances.mapped('worked_hours'))
|
||
|
return work_entry_prorata
|