diff --git a/addons/hr_work_entry_holidays/models/hr_leave.py b/addons/hr_work_entry_holidays/models/hr_leave.py index d07485d9d10..94c9cd77f4d 100644 --- a/addons/hr_work_entry_holidays/models/hr_leave.py +++ b/addons/hr_work_entry_holidays/models/hr_leave.py @@ -179,6 +179,18 @@ class HrLeave(models.Model): where the refused leave was. """ res = super(HrLeave, self).action_refuse() + self._regen_work_entries() + return res + + def _action_user_cancel(self, reason): + res = super()._action_user_cancel(reason) + self.sudo()._regen_work_entries() + return res + + def _regen_work_entries(self): + """ + Called when the leave is refused or cancelled to regenerate the work entries properly for that period. + """ work_entries = self.env['hr.work.entry'].sudo().search([('leave_id', 'in', self.ids)]) work_entries.write({'active': False}) @@ -187,7 +199,6 @@ class HrLeave(models.Model): for work_entry in work_entries: vals_list += work_entry.contract_id._get_work_entries_values(work_entry.date_start, work_entry.date_stop) self.env['hr.work.entry'].create(vals_list) - return res def _get_number_of_days(self, date_from, date_to, employee_id): """ If an employee is currently working full time but asks for time off next month @@ -225,7 +236,7 @@ class HrLeave(models.Model): super()._compute_can_cancel() cancellable_leaves = self.filtered('can_cancel') - work_entries = self.env['hr.work.entry'].sudo().search([('leave_id', 'in', cancellable_leaves.ids)]) + work_entries = self.env['hr.work.entry'].sudo().search([('state', '=', 'validated'), ('leave_id', 'in', cancellable_leaves.ids)]) leave_ids = work_entries.mapped('leave_id').ids for leave in cancellable_leaves: diff --git a/addons/hr_work_entry_holidays/tests/test_leave.py b/addons/hr_work_entry_holidays/tests/test_leave.py index 6ff4e227f24..1985e6faae2 100644 --- a/addons/hr_work_entry_holidays/tests/test_leave.py +++ b/addons/hr_work_entry_holidays/tests/test_leave.py @@ -4,6 +4,9 @@ from datetime import datetime from dateutil.relativedelta import relativedelta +from freezegun import freeze_time + +from odoo import SUPERUSER_ID from odoo.addons.hr_work_entry_holidays.tests.common import TestWorkEntryHolidaysBase @@ -136,3 +139,36 @@ class TestWorkEntryLeave(TestWorkEntryHolidaysBase): work_entry.toggle_active() self.assertEqual(work_entry.state, 'cancelled', "Attendance work entries should be cancelled and not conflict") self.assertFalse(work_entry.active) + + def test_work_entry_cancel_leave(self): + user = self.env['res.users'].create({ + 'name': 'User Employee', + 'login': 'jul', + 'password': 'julpassword', + }) + self.richard_emp.user_id = user + self.richard_emp.contract_ids.state = 'open' + with freeze_time(datetime(2022, 3, 21)): + # Tests that cancelling a leave archives the work entries. + leave = self.env['hr.leave'].with_user(user).create({ + 'name': 'Sick 1 week during christmas snif', + 'employee_id': self.richard_emp.id, + 'holiday_status_id': self.leave_type.id, + 'date_from': datetime(2022, 3, 22, 6), + 'date_to': datetime(2022, 3, 25, 20), + 'number_of_days': 4, + }) + can_cancel_field = leave._fields['can_cancel'] + leave.with_user(SUPERUSER_ID).action_validate() + # No work entries exist yet + self.assertTrue(leave.can_cancel, "The leave should still be cancellable") + # can not create in the future + self.richard_emp.contract_ids._generate_work_entries(datetime(2022, 3, 21, 6), datetime(2022, 3, 25, 20)) + work_entries = self.env['hr.work.entry'].search([('employee_id', '=', self.richard_emp.id)]) + self.env.cache.invalidate([(can_cancel_field, leave.ids)]) + # Work entries exist but are not locked yet + self.assertTrue(leave.can_cancel, "The leave should still be cancellable") + work_entries.action_validate() + self.env.cache.invalidate([(can_cancel_field, leave.ids)]) + # Work entries locked + self.assertFalse(leave.can_cancel, "The leave should not be cancellable")