diff --git a/addons/hr_holidays/models/hr_leave_allocation.py b/addons/hr_holidays/models/hr_leave_allocation.py index 3fa1237f99c..9467d68584f 100644 --- a/addons/hr_holidays/models/hr_leave_allocation.py +++ b/addons/hr_holidays/models/hr_leave_allocation.py @@ -357,7 +357,7 @@ class HolidaysAllocation(models.Model): current_level = False current_level_idx = -1 for idx, level in enumerate(level_ids): - if date >= self.date_from + get_timedelta(level.start_count, level.start_type): + if date > self.date_from + get_timedelta(level.start_count, level.start_type): current_level = level current_level_idx = idx # If transition_mode is set to `immediately` or we are currently on the first level @@ -421,7 +421,7 @@ class HolidaysAllocation(models.Model): allocation.nextcall = first_level._get_next_date(allocation.lastcall) if len(level_ids) > 1: second_level_start_date = allocation.date_from + get_timedelta(level_ids[1].start_count, level_ids[1].start_type) - allocation.nextcall = min(second_level_start_date - relativedelta(days=1), allocation.nextcall) + allocation.nextcall = min(second_level_start_date, allocation.nextcall) allocation._message_log(body=first_allocation) days_added_per_level = defaultdict(lambda: 0) while allocation.nextcall <= date_to: @@ -435,7 +435,7 @@ class HolidaysAllocation(models.Model): # 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] - current_level_last_date = allocation.date_from + get_timedelta(next_level.start_count, next_level.start_type) - relativedelta(days=1) + current_level_last_date = allocation.date_from + get_timedelta(next_level.start_count, next_level.start_type) if allocation.nextcall != current_level_last_date: nextcall = min(nextcall, current_level_last_date) diff --git a/addons/hr_holidays/tests/test_accrual_allocations.py b/addons/hr_holidays/tests/test_accrual_allocations.py index 9830ac2c85e..799270bf5ba 100644 --- a/addons/hr_holidays/tests/test_accrual_allocations.py +++ b/addons/hr_holidays/tests/test_accrual_allocations.py @@ -639,7 +639,54 @@ class TestAccrualAllocations(TestHrHolidaysCommon): allocation.action_validate() with freeze_time('2022-1-10'): allocation._update_accrual() - self.assertAlmostEqual(allocation.number_of_days, 30.79, 2, "Invalid number of days") + self.assertAlmostEqual(allocation.number_of_days, 30.82, 2, "Invalid number of days") + + def test_three_levels_accrual(self): + accrual_plan = self.env['hr.leave.accrual.plan'].with_context(tracking_disable=True).create({ + 'name': 'Accrual Plan For Test', + 'level_ids': [(0, 0, { + 'start_count': 2, + 'start_type': 'month', + 'added_value': 3, + 'added_value_type': 'days', + 'frequency': 'monthly', + 'maximum_leave': 3, + 'action_with_unused_accruals': 'postponed', + 'first_day': 31, + }), (0, 0, { + 'start_count': 3, + 'start_type': 'month', + 'added_value': 6, + 'added_value_type': 'days', + 'frequency': 'monthly', + 'maximum_leave': 6, + 'action_with_unused_accruals': 'postponed', + 'first_day': 31, + }), (0, 0, { + 'start_count': 4, + 'start_type': 'month', + 'added_value': 1, + 'added_value_type': 'days', + 'frequency': 'monthly', + 'maximum_leave': 100, + 'action_with_unused_accruals': 'postponed', + 'first_day': 31, + })], + }) + allocation = self.env['hr.leave.allocation'].with_user(self.user_hrmanager_id).with_context(tracking_disable=True).create({ + 'name': 'Accrual Allocation - Test', + 'accrual_plan_id': accrual_plan.id, + 'employee_id': self.employee_emp.id, + 'holiday_status_id': self.leave_type.id, + 'number_of_days': 0, + 'allocation_type': 'accrual', + 'date_from': datetime.date(2022, 1, 31), + }) + allocation.action_confirm() + allocation.action_validate() + with freeze_time('2022-7-20'): + allocation._update_accrual() + self.assertEqual(allocation.number_of_days, 10) def test_accrual_lost_previous_days(self): # Test that when an allocation with two levels is made and that the first level has it's action