[FIX] hr_work_entry_holidays: prevent not being able to cancel time off

Prior to this commit if work entries/payroll was installed you could not
cancel a time off in the future if the work entries were generated for
that period, however you should still be able to cancel a time off as
long as the work entries have not been validated yet.

TaskId-2791386

closes odoo/odoo#94165

X-original-commit: 975ac8d2a1809bf7725d577b0fa9143a5b255e0d
Related: odoo/enterprise#28673
Signed-off-by: Yannick Tivisse (yti) <yti@odoo.com>
This commit is contained in:
William Braeckman
2022-06-21 16:52:02 +02:00
parent c5fa2e7e29
commit f38ff9754d
2 changed files with 49 additions and 2 deletions
@@ -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:
@@ -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")