From 0b90ef9bba30f9e60f34f986ff2b31d2647f55b2 Mon Sep 17 00:00:00 2001 From: Kevin Baptiste Date: Mon, 25 Apr 2022 08:48:53 +0000 Subject: [PATCH] [FIX] hr_holidays: correctly compute accrual days when no cap Having a value of 0 for `maximum_leave` means 'no limit', but it was considered as a limit of 0 - thus no days were accrued. closes odoo/odoo#90173 Taskid: 2832160 X-original-commit: 59a319a90a4232f869811ffca62cb356a50a3acf Signed-off-by: Kevin Baptiste --- .../hr_holidays/models/hr_leave_allocation.py | 4 +- .../tests/test_accrual_allocations.py | 101 ++++++++++++++++++ 2 files changed, 103 insertions(+), 2 deletions(-) diff --git a/addons/hr_holidays/models/hr_leave_allocation.py b/addons/hr_holidays/models/hr_leave_allocation.py index 53b62f2acea..51404fdb5d3 100644 --- a/addons/hr_holidays/models/hr_leave_allocation.py +++ b/addons/hr_holidays/models/hr_leave_allocation.py @@ -475,9 +475,9 @@ class HolidaysAllocation(models.Model): force_period = False if days_added_per_level: - number_of_days_to_add = sum(days_added_per_level.values()) + number_of_days_to_add = allocation.number_of_days + sum(days_added_per_level.values()) # Let's assume the limit of the last level is the correct one - allocation.write({'number_of_days': min(allocation.number_of_days + number_of_days_to_add, current_level.maximum_leave)}) + allocation.number_of_days = min(number_of_days_to_add, current_level.maximum_leave + allocation.leaves_taken) if current_level.maximum_leave > 0 else number_of_days_to_add @api.model def _update_accrual(self): diff --git a/addons/hr_holidays/tests/test_accrual_allocations.py b/addons/hr_holidays/tests/test_accrual_allocations.py index 3ae7acb7a03..479a503a604 100644 --- a/addons/hr_holidays/tests/test_accrual_allocations.py +++ b/addons/hr_holidays/tests/test_accrual_allocations.py @@ -635,3 +635,104 @@ class TestAccrualAllocations(TestHrHolidaysCommon): with freeze_time('2022-1-10'): allocation._update_accrual() self.assertAlmostEqual(allocation.number_of_days, 30.79, 2, "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', + 'level_ids': [(0, 0, { + 'start_count': 1, + 'start_type': 'day', + 'added_value': 1, + 'added_value_type': 'days', + 'frequency': 'daily', + 'maximum_leave': 5, + })], + }) + allocation = self.env['hr.leave.allocation'].with_user(self.user_hrmanager_id).with_context(tracking_disable=True).create({ + 'name': 'Accrual allocation for employee', + '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': '2021-09-03', + }) + + with freeze_time(datetime.date(2021, 10, 3)): + allocation.action_confirm() + allocation.action_validate() + allocation._update_accrual() + + self.assertEqual(allocation.number_of_days, 5, "Should accrue maximum 5 days") + + def test_accrual_maximum_leaves_no_limit(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': 1, + 'start_type': 'day', + 'added_value': 1, + 'added_value_type': 'days', + 'frequency': 'daily', + 'maximum_leave': 0, + })], + }) + allocation = self.env['hr.leave.allocation'].with_user(self.user_hrmanager_id).with_context(tracking_disable=True).create({ + 'name': 'Accrual allocation for employee', + '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': '2021-09-03', + }) + + with freeze_time(datetime.date(2021, 10, 3)): + allocation.action_confirm() + allocation.action_validate() + allocation._update_accrual() + + self.assertEqual(allocation.number_of_days, 29, "No limits for accrued days") + + def test_accrual_leaves_taken_maximum(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': 0, + 'start_type': 'day', + 'added_value': 1, + 'added_value_type': 'days', + 'frequency': 'weekly', + 'week_day': 'mon', + 'maximum_leave': 5, + })], + }) + allocation = self.env['hr.leave.allocation'].with_user(self.user_hrmanager_id).with_context(tracking_disable=True).create({ + 'name': 'Accrual allocation for employee', + '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': '2022-01-01', + }) + allocation.action_confirm() + allocation.action_validate() + + with freeze_time(datetime.date(2022, 3, 2)): + allocation._update_accrual() + + self.assertEqual(allocation.number_of_days, 5, "Maximum of 5 days accrued") + + leave = self.env['hr.leave'].create({ + 'name': 'leave', + 'employee_id': self.employee_emp.id, + 'holiday_status_id': self.leave_type.id, + 'date_from': '2022-03-07 00:00:00', + 'date_to': '2022-03-11 23:59:59', + }) + leave.action_validate() + + with freeze_time(datetime.date(2022, 6, 1)): + allocation._update_accrual() + self.assertEqual(allocation.number_of_days, 10, "Should accrue 5 additional days")