From 47030fd605d6b3b47be895d5ea5d78f6f014db2b Mon Sep 17 00:00:00 2001 From: "Thomas Lefebvre (thle)" Date: Fri, 5 Apr 2024 09:28:43 +0200 Subject: [PATCH] [FIX] hr_holidays: ensure consistency with cap accrued time Steps to reproduce: ------------------- - create a time off accrual plan with: - cap accrued time equals to `True` - maximum leave equals to `0 days` - create an allocation with this accrual plan - run the scheduled action "Accrual Time Off: Updates the number of time off" (make sure you have the right "lastcall" and "nextcall") Issue: ------ The number of days of the allocation is set to zero. This scenario makes no sense from a business point of view. In effect, we are blocking the accumulation of allocations at zero. The result is that there will never be any days allocated to these allocations. Solution: --------- Add a constraint to force a maximum leave number when cap accrued time is set. opw-3847408 closes odoo/odoo#160626 Signed-off-by: Bertrand Dossogne (bedo) --- addons/hr_holidays/i18n/hr_holidays.pot | 8 +++++++ .../models/hr_leave_accrual_plan_level.py | 7 ++++++ .../tests/test_accrual_allocations.py | 24 +++++++++++++++++++ 3 files changed, 39 insertions(+) diff --git a/addons/hr_holidays/i18n/hr_holidays.pot b/addons/hr_holidays/i18n/hr_holidays.pot index 172d42b9776..48dccb46b6c 100644 --- a/addons/hr_holidays/i18n/hr_holidays.pot +++ b/addons/hr_holidays/i18n/hr_holidays.pot @@ -4441,6 +4441,14 @@ msgid "" " manager" msgstr "" +#. module: hr_holidays +#. odoo-python +#: code:addons/hr_holidays/models/hr_leave_accrual_plan_level.py:0 +#, python-format +msgid "" +"You cannot have a cap on accrued time without setting a maximum amount." +msgstr "" + #. module: hr_holidays #. odoo-python #: code:addons/hr_holidays/models/hr_leave_allocation.py:0 diff --git a/addons/hr_holidays/models/hr_leave_accrual_plan_level.py b/addons/hr_holidays/models/hr_leave_accrual_plan_level.py index f10180e7e00..3960cb9536f 100644 --- a/addons/hr_holidays/models/hr_leave_accrual_plan_level.py +++ b/addons/hr_holidays/models/hr_leave_accrual_plan_level.py @@ -4,6 +4,7 @@ from dateutil.relativedelta import relativedelta from odoo import _, api, fields, models +from odoo.exceptions import UserError DAYS = ['sun', 'mon', 'tue', 'wed', 'thu', 'fri', 'sat'] @@ -134,6 +135,12 @@ class AccrualPlanLevel(models.Model): ('added_value_greater_than_zero', 'CHECK(added_value > 0)', 'You must give a rate greater than 0 in accrual plan levels.') ] + @api.constrains('maximum_leave') + def _check_maximum_leave(self): + for level in self: + if level.cap_accrued_time and level.maximum_leave < 1: + raise UserError(_("You cannot have a cap on accrued time without setting a maximum amount.")) + @api.depends('start_count', 'start_type') def _compute_sequence(self): # Not 100% accurate because of odd months/years, but good enough diff --git a/addons/hr_holidays/tests/test_accrual_allocations.py b/addons/hr_holidays/tests/test_accrual_allocations.py index 4affc862dac..6b89c5c4856 100644 --- a/addons/hr_holidays/tests/test_accrual_allocations.py +++ b/addons/hr_holidays/tests/test_accrual_allocations.py @@ -5,6 +5,7 @@ from freezegun import freeze_time from dateutil.relativedelta import relativedelta from odoo import Command +from odoo.exceptions import UserError from odoo.tests import tagged from odoo.addons.hr_holidays.tests.common import TestHrHolidaysCommon @@ -41,6 +42,29 @@ class TestAccrualAllocations(TestHrHolidaysCommon): WHERE id = %s """ % (date, allocation_id)) + def test_consistency_between_cap_accrued_time_and_maximum_leave(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': 'day', + 'frequency': 'hourly', + 'cap_accrued_time': True, + 'maximum_leave': 10000 + })], + }) + level = accrual_plan.level_ids + level.maximum_leave = 10 + self.assertEqual(accrual_plan.level_ids.maximum_leave, 10) + + with self.assertRaises(UserError): + level.maximum_leave = 0 + + level.cap_accrued_time = False + self.assertEqual(accrual_plan.level_ids.maximum_leave, 0) + def test_frequency_hourly_calendar(self): with freeze_time("2017-12-5"): accrual_plan = self.env['hr.leave.accrual.plan'].with_context(tracking_disable=True).create({