diff --git a/addons/hr_holidays/i18n/hr_holidays.pot b/addons/hr_holidays/i18n/hr_holidays.pot index 5a3882217ea..559700fe4a7 100644 --- a/addons/hr_holidays/i18n/hr_holidays.pot +++ b/addons/hr_holidays/i18n/hr_holidays.pot @@ -4058,6 +4058,14 @@ msgid "" "You don't have the rights to apply second approval on a time off request" msgstr "" +#. module: hr_holidays +#: code:addons/hr_holidays/models/hr_leave.py:0 +#, python-format +msgid "" +"You have several allocations for those type and period.\n" +"Please split your request to fit in their number of days." +msgstr "" + #. module: hr_holidays #: code:addons/hr_holidays/models/hr_leave.py:0 #, python-format diff --git a/addons/hr_holidays/models/hr_leave.py b/addons/hr_holidays/models/hr_leave.py index c717b068ba8..0908160982d 100644 --- a/addons/hr_holidays/models/hr_leave.py +++ b/addons/hr_holidays/models/hr_leave.py @@ -302,6 +302,12 @@ class HolidaysRequest(models.Model): for leave in self: leave.all_employee_ids = leave.employee_id | leave.employee_ids + @api.constrains('holiday_status_id', 'number_of_days') + def _check_allocation_duration(self): + for holiday in self: + if holiday.holiday_status_id.requires_allocation == 'yes' and holiday.number_of_days > holiday.holiday_allocation_id.number_of_days: + raise ValidationError(_("You have several allocations for those type and period.\nPlease split your request to fit in their number of days.")) + @api.depends_context('uid') def _compute_description(self): self.check_access_rights('read') @@ -355,7 +361,7 @@ class HolidaysRequest(models.Model): '&', ('date_to', '=', False), ('date_from', '<=', max(self.mapped('date_from'))), - ], ['id', 'date_from', 'date_to', 'holiday_status_id', 'employee_id'], order="date_to, id" + ], ['id', 'date_from', 'date_to', 'holiday_status_id', 'employee_id', 'number_of_days'], order="number_of_days desc, date_to, id" ) allocations_dict = defaultdict(lambda: []) for allocation in allocations: diff --git a/addons/hr_holidays/tests/test_leave_requests.py b/addons/hr_holidays/tests/test_leave_requests.py index 53a9267c235..a77859e19c0 100644 --- a/addons/hr_holidays/tests/test_leave_requests.py +++ b/addons/hr_holidays/tests/test_leave_requests.py @@ -583,3 +583,49 @@ class TestLeaveRequests(TestHrHolidaysCommon): 'date_to': datetime(2022, 3, 11, 23, 59, 59), }) self.assertEqual(leave.number_of_days, 1) + + def test_several_allocations(self): + allocation_vals = { + 'name': 'Allocation', + 'employee_id': self.employee_emp_id, + 'holiday_status_id': self.holidays_type_2.id, + 'number_of_days': 5, + 'state': 'confirm', + 'date_from': '2022-01-01', + 'date_to': '2022-12-31', + } + allocation1 = self.env['hr.leave.allocation'].create(allocation_vals) + allocation2 = self.env['hr.leave.allocation'].create(allocation_vals) + + allocation1.action_validate() + allocation2.action_validate() + + # Neither allocation has enough days + with self.assertRaises(ValidationError): + self.env['hr.leave'].with_user(self.user_employee_id).create({ + 'name': 'Holiday Request', + 'employee_id': self.employee_emp_id, + 'holiday_status_id': self.holidays_type_2.id, + 'date_from': '2022-01-01', + 'date_to': '2022-01-15', + 'number_of_days': 10, + }) + + allocation_vals.update({'number_of_days': 10}) + allocation3 = self.env['hr.leave.allocation'].create(allocation_vals) + allocation3.action_validate() + + # The 3rd allocation has enough days, so it should be picked + holiday = self.env['hr.leave'].with_user(self.user_employee_id).create({ + 'name': 'Holiday Request', + 'employee_id': self.employee_emp_id, + 'holiday_status_id': self.holidays_type_2.id, + 'date_from': '2022-01-01', + 'date_to': '2022-01-15', + 'number_of_days': 10, + }) + holiday.sudo().action_validate() + + self.assertEqual(allocation1.leaves_taken, 0.0, 'As this allocation does not have enough days, it should not be affected') + self.assertEqual(allocation2.leaves_taken, 0.0, 'As this allocation does not have enough days, it should not be affected') + self.assertEqual(allocation3.leaves_taken, 10.0, 'As this allocation has enough days, the leave days should be taken')