[FIX] project_timesheet_holidays: create/remove global time off timesheets

Before this commit, when the employee is generated with the salary
configurator, the employee is archived since the employee will not
directly start in the company. Even if the employee is archived and the
timesheets are generated for this employee based on the global time offs
found in the future. The problem is the timesheets cannot be created
for archived employees and so a user error is raised.
This problem could also happen if the user creates an archived employee.

This commit fixes the issue by preventing the timesheets generation when
the employee created is archived. When this employee will be updated and
active field will be set to True, the timesheets generation will be
applied. In the inverse use case, when the user will archive an employee
and timesheets generated for the future global time offs will be removed.

opw-2887727
opw-2870739

closes odoo/odoo#95644

X-original-commit: 160afba28d88ddd9d84856cc90639586bc2ea7b6
Related: odoo/enterprise#29273
Signed-off-by: Laurent Stukkens (ltu) <ltu@odoo.com>
Signed-off-by: Fockedey Martin (mafo) <mafo@odoo.com>
This commit is contained in:
mafo-odoo
2022-07-08 14:34:27 +02:00
committed by Xavier BOL (xbo)
parent c0cbcb330e
commit 4659736fc4
2 changed files with 50 additions and 7 deletions
@@ -16,13 +16,30 @@ class Employee(models.Model):
# We need to create timesheet entries for the global time off that are already created
# and are planned for after this employee creation date
# First we look for the global time off that are already planned after today
today = fields.Datetime.today()
self._create_future_public_holidays_timesheets(employees)
return employees
def write(self, vals):
result = super(Employee, self).write(vals)
if 'active' in vals:
if vals.get('active'):
# Create future holiday timesheets
self._create_future_public_holidays_timesheets(self)
else:
# Delete future holiday timesheets
future_timesheets = self.env['account.analytic.line'].sudo().search([('global_leave_id', '!=', False), ('date', '>=', fields.date.today()), ('employee_id', 'in', self.ids)])
future_timesheets.write({'global_leave_id': False})
future_timesheets.unlink()
return result
def _create_future_public_holidays_timesheets(self, employees):
lines_vals = []
for employee in employees:
global_leaves = employee.resource_calendar_id.global_leave_ids.filtered(lambda l: l.date_from >= today)
if not employee.active:
continue
# First we look for the global time off that are already planned after today
global_leaves = employee.resource_calendar_id.global_leave_ids.filtered(lambda l: l.date_from >= fields.Datetime.today())
work_hours_data = global_leaves._work_time_per_day()
for global_time_off in global_leaves:
for index, (day_date, work_hours_count) in enumerate(work_hours_data[global_time_off.id]):
lines_vals.append(
@@ -34,5 +51,4 @@ class Employee(models.Model):
work_hours_count
)
)
self.env['account.analytic.line'].sudo().create(lines_vals)
return employees
return self.env['account.analytic.line'].sudo().create(lines_vals)
@@ -2,7 +2,7 @@
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from collections import defaultdict
from datetime import datetime
from datetime import datetime, timedelta
from odoo import Command
from odoo.tests import common
@@ -89,6 +89,33 @@ class TestTimesheetGlobalTimeOff(common.TransactionCase):
self.assertFalse(leave_task.timesheet_ids.ids)
def test_timesheet_creation_and_deletion_on_employee_archive(self):
""" Test the timesheets linked to the global time off in the future when the employee is archived """
today = datetime.today()
leave_start_datetime = today + timedelta(days=-today.weekday(), weeks=1) # Next monday
leave_end_datetime = leave_start_datetime + timedelta(days=5) # Next friday
self.env['resource.calendar.leaves'].create({
'name': 'Test',
'calendar_id': self.test_company.resource_calendar_id.id,
'date_from': leave_start_datetime,
'date_to': leave_end_datetime,
})
# 5 Timesheets should have been created for full_time_employee
timesheets_full_time_employee = self.env['account.analytic.line'].search([('employee_id', '=', self.full_time_employee.id)])
self.assertEqual(len(timesheets_full_time_employee), 5)
# All timesheets should have been deleted for full_time_employee when he is archived
self.full_time_employee.active = False
timesheets_full_time_employee = self.env['account.analytic.line'].search([('employee_id', '=', self.full_time_employee.id)])
self.assertEqual(len(timesheets_full_time_employee), 0)
# 5 Timesheets should have been created for full_time_employee when he is unarchived
self.full_time_employee.active = True
timesheets_full_time_employee = self.env['account.analytic.line'].search([('employee_id', '=', self.full_time_employee.id)])
self.assertEqual(len(timesheets_full_time_employee), 5)
# This tests that no timesheet are created for days when the employee is not supposed to work
def test_no_timesheet_on_off_days(self):
leave_start_datetime = datetime(2021, 1, 4, 7, 0, 0, 0) # This is a monday