From a4b7338a95856965d9638cab4e37349f053622c4 Mon Sep 17 00:00:00 2001 From: Florian Damhaut Date: Wed, 2 Mar 2022 16:17:41 +0000 Subject: [PATCH] [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 --- .../hr_holidays/models/hr_leave_allocation.py | 21 +++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/addons/hr_holidays/models/hr_leave_allocation.py b/addons/hr_holidays/models/hr_leave_allocation.py index 4f568334646..df027a44d7c 100644 --- a/addons/hr_holidays/models/hr_leave_allocation.py +++ b/addons/hr_holidays/models/hr_leave_allocation.py @@ -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()),