[FIX] hr_holidays: multi-period accrual reset at year start

Step to reproduce:
- Create an accrual plan with the option "at the end of the year,
 unused accruals will be lost" and that can be allocated every year
(in this example, 3 days)
- Create an allocation for Marc Demo based on that accrual plan
 and starting in 2020.
- Run scheduled action
 "Accrual Time Off: updates the number of time off"
- Connect as Marc Demo

Current behaviour:
- Marc Demo has receive a 6 day allocation
- While loop over the elapsed period doesn't take lost time into account

Behaviour after PR:
- Marc Demo receive 3 day allocation

opw-2769066

closes odoo/odoo#86369

X-original-commit: fc18355158b6724aeb3f900cae50cdab3e6d707b
Signed-off-by: Kevin Baptiste <kba@odoo.com>
This commit is contained in:
Florian Damhaut
2022-03-14 17:28:40 +00:00
parent 3e1ba365a0
commit a4b7338a95
@@ -424,6 +424,15 @@ class HolidaysAllocation(models.Model):
# this is used to prorate the first number of days given to the employee
period_start = current_level._get_previous_date(allocation.lastcall)
period_end = current_level._get_next_date(allocation.lastcall)
# If accruals are lost at the beginning of year, skip accrual until beginning of this year
if current_level.action_with_unused_accruals == 'lost':
this_year_first_day = (today + relativedelta(day=1, month=1)).date()
if period_end < this_year_first_day or period_start < period_end:
allocation.lastcall = allocation.nextcall
allocation.nextcall = nextcall
continue
else:
period_start = max(period_start, this_year_first_day)
# Also prorate this accrual in the event that we are passing from one level to another
if current_level_idx < (len(level_ids) - 1) and allocation.accrual_plan_id.transition_mode == 'immediately':
next_level = level_ids[current_level_idx + 1]
@@ -449,12 +458,12 @@ class HolidaysAllocation(models.Model):
"""
# Get the current date to determine the start and end of the accrual period
today = datetime.combine(fields.Date.today(), time(0, 0, 0))
if today.day == 1 and today.month == 1:
end_of_year_allocations = self.search(
[('allocation_type', '=', 'accrual'), ('state', '=', 'validate'), ('accrual_plan_id', '!=', False), ('employee_id', '!=', False),
'|', ('date_to', '=', False), ('date_to', '>', fields.Datetime.now())])
end_of_year_allocations._end_of_year_accrual()
end_of_year_allocations.flush()
this_year_first_day = (today + relativedelta(day=1, month=1)).date()
end_of_year_allocations = self.search(
[('allocation_type', '=', 'accrual'), ('state', '=', 'validate'), ('accrual_plan_id', '!=', False), ('employee_id', '!=', False),
'|', ('date_to', '=', False), ('date_to', '>', fields.Datetime.now()), ('lastcall', '<', this_year_first_day)])
end_of_year_allocations._end_of_year_accrual()
end_of_year_allocations.flush()
allocations = self.search(
[('allocation_type', '=', 'accrual'), ('state', '=', 'validate'), ('accrual_plan_id', '!=', False), ('employee_id', '!=', False),
'|', ('date_to', '=', False), ('date_to', '>', fields.Datetime.now()),