From 094ab73a2a2aa3d2231c6eaa487e5c310e6bbae4 Mon Sep 17 00:00:00 2001 From: Yannick Tivisse Date: Thu, 14 Mar 2024 11:48:02 +0100 Subject: [PATCH] [FIX] hr_work_entry_holidays: Prevent time off duration erasing Purpose ======= The time off duration is set to 0 when the related contract is set as expired, then we remove the end date and set the contract back to running. That's because the check was done before calling super, hence the contract is excluded from the candidates because it is still expired without end date, which would make no sense when trying to retrieve the related calendar. closes odoo/odoo#157681 Taskid: 3806342 Signed-off-by: Yannick Tivisse (yti) --- addons/hr_work_entry_holidays/models/hr_contract.py | 7 ++++--- addons/hr_work_entry_holidays/models/hr_leave.py | 4 +--- addons/hr_work_entry_holidays/tests/test_leave.py | 13 +++++++++++++ 3 files changed, 18 insertions(+), 6 deletions(-) diff --git a/addons/hr_work_entry_holidays/models/hr_contract.py b/addons/hr_work_entry_holidays/models/hr_contract.py index d3e2b6cd873..03dd9b1b6c6 100644 --- a/addons/hr_work_entry_holidays/models/hr_contract.py +++ b/addons/hr_work_entry_holidays/models/hr_contract.py @@ -105,13 +105,14 @@ class HrContract(models.Model): # Get all overlapping contracts but exclude draft contracts that are not included in this transaction. overlapping_contracts = leave._get_overlapping_contracts(contract_states=[ ('state', '!=', 'cancel'), + ('resource_calendar_id', '!=', False), '|', '|', ('id', 'in', self.ids), ('state', '!=', 'draft'), ('kanban_state', '=', 'done'), - ]) + ]).sorted(key=lambda c: {'open': 1, 'close': 2, 'draft': 3, 'cancel': 4}[c.state]) if len(overlapping_contracts.resource_calendar_id) <= 1: - if leave.resource_calendar_id != overlapping_contracts.resource_calendar_id: - leave.resource_calendar_id = overlapping_contracts.resource_calendar_id + if overlapping_contracts and leave.resource_calendar_id != overlapping_contracts[0].resource_calendar_id: + leave.resource_calendar_id = overlapping_contracts[0].resource_calendar_id continue if leave.id not in leaves_state: leaves_state[leave.id] = leave.state diff --git a/addons/hr_work_entry_holidays/models/hr_leave.py b/addons/hr_work_entry_holidays/models/hr_leave.py index c0276be6285..34af3d2bd5c 100644 --- a/addons/hr_work_entry_holidays/models/hr_leave.py +++ b/addons/hr_work_entry_holidays/models/hr_leave.py @@ -40,9 +40,7 @@ class HrLeave(models.Model): ('date_start', '<=', self.date_to), '|', ('date_end', '>=', self.date_from), - '&', - ('date_end', '=', False), - ('state', '!=', 'close') + ('date_end', '=', False), ]]) return self.env['hr.contract'].sudo().search(domain) diff --git a/addons/hr_work_entry_holidays/tests/test_leave.py b/addons/hr_work_entry_holidays/tests/test_leave.py index e688a9f5048..7a200f08417 100644 --- a/addons/hr_work_entry_holidays/tests/test_leave.py +++ b/addons/hr_work_entry_holidays/tests/test_leave.py @@ -186,3 +186,16 @@ class TestWorkEntryLeave(TestWorkEntryHolidaysBase): ('date_stop', '<=', end), ]) self.assertEqual(len(work_entries.work_entry_type_id), 2) + + def test_time_off_duration_contract_state_change(self): + # check that setting a contract without end state from + # expired to running won't erase the time off duration + + leave = self.create_leave(datetime(2019, 10, 10, 9, 0), datetime(2019, 10, 10, 18, 0)) + self.assertTrue(leave.number_of_days, 1) + contract = self.richard_emp.contract_ids + contract.state = "close" + contract.date_end = False + self.assertTrue(leave.number_of_days, 1) + contract.state = "open" + self.assertTrue(leave.number_of_days, 1)