diff --git a/addons/hr_holidays/models/hr_leave_allocation.py b/addons/hr_holidays/models/hr_leave_allocation.py index 7dcc0357801..cf43d0ac769 100644 --- a/addons/hr_holidays/models/hr_leave_allocation.py +++ b/addons/hr_holidays/models/hr_leave_allocation.py @@ -331,21 +331,22 @@ class HolidaysAllocation(models.Model): # to override in payroll today = fields.Date.today() last_day_last_year = today + relativedelta(years=-1, month=12, day=31) + first_day_this_year = today + relativedelta(month=1, day=1) for allocation in self: - current_level = allocation._get_current_accrual_plan_level_id(today)[0] + current_level = allocation._get_current_accrual_plan_level_id(first_day_this_year)[0] if not current_level: continue - nextcall = current_level._get_next_date(today) + nextcall = current_level._get_next_date(first_day_this_year) if current_level.action_with_unused_accruals == 'lost': # Allocations are lost but number_of_days should not be lower than leaves_taken - allocation.write({'number_of_days': allocation.leaves_taken, 'lastcall': today, 'nextcall': nextcall}) + allocation.write({'number_of_days': allocation.leaves_taken, 'lastcall': first_day_this_year, 'nextcall': nextcall}) elif current_level.action_with_unused_accruals == 'postponed' and current_level.postpone_max_days: # Make sure the period was ran until the last day of last year if allocation.nextcall: allocation.nextcall = last_day_last_year allocation._process_accrual_plans(last_day_last_year, True) number_of_days = min(allocation.number_of_days - allocation.leaves_taken, current_level.postpone_max_days) + allocation.leaves_taken - allocation.write({'number_of_days': number_of_days, 'lastcall': today, 'nextcall': nextcall}) + allocation.write({'number_of_days': number_of_days, 'lastcall': first_day_this_year, 'nextcall': nextcall}) def _get_current_accrual_plan_level_id(self, date, level_ids=False): """ diff --git a/addons/hr_holidays/tests/test_accrual_allocations.py b/addons/hr_holidays/tests/test_accrual_allocations.py index 42b5449d363..9830ac2c85e 100644 --- a/addons/hr_holidays/tests/test_accrual_allocations.py +++ b/addons/hr_holidays/tests/test_accrual_allocations.py @@ -641,6 +641,47 @@ class TestAccrualAllocations(TestHrHolidaysCommon): allocation._update_accrual() self.assertAlmostEqual(allocation.number_of_days, 30.79, 2, "Invalid number of days") + 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 + # with unused accruals set as lost that the days are effectively lost + 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': 0, + 'start_type': 'day', + 'added_value': 1, + 'added_value_type': 'days', + 'frequency': 'monthly', + 'maximum_leave': 12, + 'action_with_unused_accruals': 'lost', + }), + (0, 0, { + 'start_count': 1, + 'start_type': 'year', + 'added_value': 1, + 'added_value_type': 'days', + 'frequency': 'monthly', + 'maximum_leave': 12, + 'action_with_unused_accruals': 'lost', + }), + ], + }) + 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(2021, 1, 1), + }) + allocation.action_confirm() + allocation.action_validate() + with freeze_time('2022-4-4'): + allocation._update_accrual() + self.assertEqual(allocation.number_of_days, 3, "Invalid number of days") + def test_accrual_maximum_leaves(self): accrual_plan = self.env['hr.leave.accrual.plan'].with_context(tracking_disable=True).create({ 'name': 'Accrual Plan For Test',