diff --git a/addons/hr_holidays/models/hr_leave_type.py b/addons/hr_holidays/models/hr_leave_type.py index b6f5a441316..3d26c56244b 100644 --- a/addons/hr_holidays/models/hr_leave_type.py +++ b/addons/hr_holidays/models/hr_leave_type.py @@ -313,7 +313,8 @@ class HolidaysType(models.Model): leave_unit = 'hours' if holiday_status_id.requires_allocation != 'no': for available_allocation in sorted_available_allocations: - if available_allocation.date_to and available_allocation.date_to < leave.date_from.date(): + if (available_allocation.date_to and available_allocation.date_to < leave.date_from.date()) \ + or (available_allocation.date_from > leave.date_to.date()): continue virtual_remaining_leaves = (available_allocation.number_of_days if leave_unit == 'days' else available_allocation.number_of_hours_display) - allocations_days_consumed[employee_id][holiday_status_id][available_allocation]['virtual_leaves_taken'] max_leaves = min(virtual_remaining_leaves, leave_duration) @@ -352,7 +353,7 @@ class HolidaysType(models.Model): if future_allocation_interval[0].date() > search_date: continue for allocation in future_allocation_interval[2]: - if not allocation.active: + if not allocation.active or allocation.date_from > search_date: continue days_consumed = allocations_days_consumed[employee_id][holiday_status_id][allocation] if future_allocation_interval[1] != fields.datetime.combine(date, time.max) + timedelta(days=5*365): diff --git a/addons/hr_holidays/tests/test_leave_requests.py b/addons/hr_holidays/tests/test_leave_requests.py index f24ada0e486..e738e607d02 100644 --- a/addons/hr_holidays/tests/test_leave_requests.py +++ b/addons/hr_holidays/tests/test_leave_requests.py @@ -1012,3 +1012,49 @@ class TestLeaveRequests(TestHrHolidaysCommon): 'number_of_days': 1, 'supported_attachment_ids': [(6, 0, [])], # Sent by webclient }) + + def test_prevent_misplacement_of_allocations_without_end_date(self): + """ + The objective is to check that it is not possible to place leaves + for which the interval does not correspond to the interval of allocations. + """ + holiday_type_A = self.env['hr.leave.type'].with_user(self.user_hrmanager_id).with_context(tracking_disable=True).create({ + 'name': 'Type A', + 'requires_allocation': 'yes', + 'employee_requests': 'yes', + 'leave_validation_type': 'hr', + }) + + # Create allocations with no end date + allocations = self.env['hr.leave.allocation'].create([ + { + 'name': 'Type A march 1 day without date to', + 'employee_id': self.employee_emp_id, + 'holiday_status_id': holiday_type_A.id, + 'number_of_days': 1, + 'state': 'confirm', + 'date_from': '2023-01-03', + }, + { + 'name': 'Type A april 5 day without date to', + 'employee_id': self.employee_emp_id, + 'holiday_status_id': holiday_type_A.id, + 'number_of_days': 5, + 'state': 'confirm', + 'date_from': '2023-04-01', + }, + ]) + + allocations.action_validate() + + trigger_error_leave = { + 'name': 'Holiday Request', + 'employee_id': self.employee_emp_id, + 'holiday_status_id': holiday_type_A.id, + 'date_from': '2023-03-14', + 'date_to': '2023-03-16', + 'number_of_days': 3, + } + + with self.assertRaises(ValidationError): + self.env['hr.leave'].with_user(self.user_employee_id).create(trigger_error_leave)