[ADD] copy paste module hr_holidays_timeoff_analysis from version 16.0 (from repo elabore-addons)

This commit is contained in:
2025-10-09 11:11:31 +02:00
parent f4d9cd008c
commit 37a8bda090
14 changed files with 1440 additions and 0 deletions

View File

@@ -0,0 +1 @@
from . import hr_leave_timeoff_day

View File

@@ -0,0 +1,100 @@
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from odoo import fields, models, api
from datetime import timedelta
class TimeOffDay(models.Model):
_name = 'hr.leave.timeoff.day'
_description = 'Timeoff Day'
_order = 'date desc'
date = fields.Date()
employee_id = fields.Many2one('hr.employee')
hr_leave_id = fields.Many2one('hr.leave')
hr_leave_type = fields.Many2one(related='hr_leave_id.holiday_status_id', store=True)
leave_duration_by_day = fields.Float()
def employee_is_scheduled_to_work_this_day(self, date, employee):
""" Check if the employee is scheduled to work on this day according to his calendar """
calendar = employee.resource_calendar_id
if not calendar or not calendar.attendance_ids:
return False
day_of_week = str(date.weekday())
attendances = calendar.attendance_ids.filtered(
lambda att: att.dayofweek == day_of_week
)
return bool(attendances)
def is_a_public_holiday(self, date, employee):
""" Check if the day is a public holiday """
# public holidays start the day before in database (ex: date_from : 7mai 22:00 and date_to : 8mai 23:59 for 8mai public holiday) )
public_holidays = self.env['resource.calendar.leaves'].search([
('date_from', '<=', date-timedelta(days=1)),
('date_to', '>=', date),
('resource_id', '=', False) # resource_id is null for public holiday
])
if public_holidays:
return True
return False
def compute_leave_duration_by_day(self, leave):
""" Compute the leave duration by day based on the leave type """
leave_duration_by_day = 0.0
# Full day case
if leave.request_unit_half:
leave_duration_by_day = 0.5
elif leave.request_unit_hours:
leave_duration_by_day = leave.number_of_days_display
else:
leave_duration_by_day = 1.0
return leave_duration_by_day
@api.model
def cron_manage_timeoff_days(self):
self.cron_create_timeoff_days()
self.cron_delete_timeoff_days()
def cron_create_timeoff_days(self):
# Browse all validated leaves
leaves = self.env['hr.leave'].search([
('state', '=', 'validate'),
('request_date_from', '!=', False),
('request_date_to', '!=', False),
('employee_id', '!=', False),
])
for leave in leaves:
current_date = leave.request_date_from
employee = leave.employee_id
while current_date <= leave.request_date_to:
if self.employee_is_scheduled_to_work_this_day(current_date, employee) and not self.is_a_public_holiday(current_date, employee):
# The employee is scheluded to work this day according his calendar and it's not a public holiday,
# so create a timeoff day record if it does not already exist
if not self.search([
('date', '=', current_date),
('employee_id', '=', employee.id),
('hr_leave_id', '=', leave.id),
], limit=1):
self.create({
'date': current_date,
'employee_id': employee.id,
'hr_leave_id': leave.id,
'leave_duration_by_day': self.compute_leave_duration_by_day(leave),
})
current_date += timedelta(days=1)
def cron_delete_timeoff_days(self):
# Browse all unvalidated leaves
leaves = self.env['hr.leave'].search([
('state', '!=', 'validate'),
('request_date_from', '!=', False),
('request_date_to', '!=', False),
('employee_id', '!=', False),
])
# Delete timeoff days for leaves that are no longer validated
for leave in leaves:
self.search([
('hr_leave_id', '=', leave.id),
]).unlink()
# Delete timeoff days that are not linked to any leave
self.search([
('hr_leave_id', '=', False),
]).unlink()