mirror of
https://gitlab.com/hibou-io/hibou-odoo/suite.git
synced 2025-01-20 12:37:31 +02:00
99 lines
4.6 KiB
Python
99 lines
4.6 KiB
Python
from datetime import datetime, time
|
|
from dateutil.relativedelta import relativedelta
|
|
|
|
from odoo import api, fields, models
|
|
from odoo.addons.resource.models.resource import HOURS_PER_DAY
|
|
|
|
|
|
class HRLeaveAllocation(models.Model):
|
|
_inherit = 'hr.leave.allocation'
|
|
|
|
interval_unit = fields.Selection(selection_add=[('payslip', 'Payslip')])
|
|
|
|
@api.model
|
|
def payslip_update_accrual(self, payslips):
|
|
employees = payslips.mapped('employee_id')
|
|
holidays = self.env['hr.leave.allocation'].search([
|
|
('employee_id', 'in', employees.ids),
|
|
('accrual', '=', True),
|
|
('state', '=', 'validate'),
|
|
('holiday_type', '=', 'employee'),
|
|
'|', ('date_to', '=', False),
|
|
('date_to', '>', fields.Datetime.now()),
|
|
])
|
|
for holiday in holidays:
|
|
days_to_give = holiday.number_per_interval
|
|
if holiday.unit_per_interval == 'hours':
|
|
# As we encode everything in days in the database we need to convert
|
|
# the number of hours into days for this we use the
|
|
# mean number of hours set on the employee's calendar
|
|
days_to_give = days_to_give / (holiday.employee_id.resource_calendar_id.hours_per_day or HOURS_PER_DAY)
|
|
|
|
new_number_of_days = holiday.number_of_days + days_to_give
|
|
if holiday.accrual_limit > 0:
|
|
new_number_of_days = min(new_number_of_days, holiday.accrual_limit)
|
|
holiday.number_of_days = new_number_of_days
|
|
|
|
|
|
|
|
|
|
# This is a 'patch' because I cannot influence the domain/search here to filter out the ones by payslip.
|
|
@api.model
|
|
def _update_accrual(self):
|
|
"""
|
|
Method called by the cron task in order to increment the number_of_days when
|
|
necessary.
|
|
"""
|
|
today = fields.Date.from_string(fields.Date.today())
|
|
|
|
holidays = self.search([('interval_unit', '!=', 'payslip'), # new domain filter
|
|
('accrual', '=', True), ('state', '=', 'validate'), ('holiday_type', '=', 'employee'),
|
|
'|', ('date_to', '=', False), ('date_to', '>', fields.Datetime.now()),
|
|
'|', ('nextcall', '=', False), ('nextcall', '<=', today)])
|
|
|
|
for holiday in holidays:
|
|
values = {}
|
|
|
|
delta = relativedelta(days=0)
|
|
|
|
if holiday.interval_unit == 'weeks':
|
|
delta = relativedelta(weeks=holiday.interval_number)
|
|
if holiday.interval_unit == 'months':
|
|
delta = relativedelta(months=holiday.interval_number)
|
|
if holiday.interval_unit == 'years':
|
|
delta = relativedelta(years=holiday.interval_number)
|
|
|
|
values['nextcall'] = (holiday.nextcall if holiday.nextcall else today) + delta
|
|
|
|
period_start = datetime.combine(today, time(0, 0, 0)) - delta
|
|
period_end = datetime.combine(today, time(0, 0, 0))
|
|
|
|
# We have to check when the employee has been created
|
|
# in order to not allocate him/her too much leaves
|
|
start_date = holiday.employee_id._get_date_start_work()
|
|
# If employee is created after the period, we cancel the computation
|
|
if period_end <= start_date:
|
|
holiday.write(values)
|
|
continue
|
|
|
|
# If employee created during the period, taking the date at which he has been created
|
|
if period_start <= start_date:
|
|
period_start = start_date
|
|
|
|
worked = holiday.employee_id.get_work_days_data(period_start, period_end, domain=[('holiday_id.holiday_status_id.unpaid', '=', True), ('time_type', '=', 'leave')])['days']
|
|
left = holiday.employee_id.get_leave_days_data(period_start, period_end, domain=[('holiday_id.holiday_status_id.unpaid', '=', True), ('time_type', '=', 'leave')])['days']
|
|
prorata = worked / (left + worked) if worked else 0
|
|
|
|
days_to_give = holiday.number_per_interval
|
|
if holiday.unit_per_interval == 'hours':
|
|
# As we encode everything in days in the database we need to convert
|
|
# the number of hours into days for this we use the
|
|
# mean number of hours set on the employee's calendar
|
|
days_to_give = days_to_give / (holiday.employee_id.resource_calendar_id.hours_per_day or HOURS_PER_DAY)
|
|
|
|
values['number_of_days'] = holiday.number_of_days + days_to_give * prorata
|
|
if holiday.accrual_limit > 0:
|
|
values['number_of_days'] = min(values['number_of_days'], holiday.accrual_limit)
|
|
|
|
holiday.write(values)
|