[FIX] project_timesheet_holidays: reset timesheets when global holiday has calendar edited

Steps to reproduce:
- Install Time off and timesheet modules
- Create a public holiday with no "working hours"
- Then edit it and add it with working hours used by some employees

Expected behavior:
Adding the working hours makes that the global time off meets the
requirements to create timesheets. Then the employee related to the
new "working hours" is going to have timesheets created for this
holiday.

Current behavior:
No timesheet is created.

Explanation:
The write function of the global time off only updated timesheets
when the dates where modified. We add the update in the calendar_id
modification case and with it the new conditions to create the
timesheets. (working hours = calendar_id)

opw-2879882

closes odoo/odoo#96226

X-original-commit: a255a743b5296570aab166a5e275a323a1792b60
Signed-off-by: Laurent Stukkens (ltu) <ltu@odoo.com>
This commit is contained in:
mafo-odoo
2022-07-18 19:55:56 +02:00
committed by Xavier BOL (xbo)
parent d4b62debf9
commit 1ed41ee161
2 changed files with 47 additions and 10 deletions
@@ -151,15 +151,16 @@ class ResourceCalendarLeaves(models.Model):
return results
def write(self, vals):
start_dates = self.mapped('date_from')
end_dates = self.mapped('date_to')
date_from, date_to, calendar_id = vals.get('date_from'), vals.get('date_to'), vals.get('calendar_id')
global_time_off_updated = self.env['resource.calendar.leaves']
if date_from or date_to or 'calendar_id' in vals:
global_time_off_updated = self.filtered(lambda r: (date_from is not None and r.date_from != date_from) or (date_to is not None and r.date_to != date_to) or (calendar_id is not None and r.calendar_id.id != calendar_id))
timesheets = global_time_off_updated.sudo().timesheet_ids
if timesheets:
timesheets.write({'global_leave_id': False})
timesheets.unlink()
result = super(ResourceCalendarLeaves, self).write(vals)
date_from, date_to = vals.get('date_from'), vals.get('date_to')
if date_from or date_to:
if any(start_date != date_from or end_date != date_to for start_date, end_date in zip(start_dates, end_dates)):
timesheets = self.mapped('timesheet_ids')
if timesheets:
timesheets.write({'global_leave_id': False})
timesheets.unlink()
self._timesheet_create_lines()
if global_time_off_updated:
global_time_offs_with_leave_timesheet = global_time_off_updated.filtered(lambda r: not r.resource_id and r.calendar_id.company_id.internal_project_id and r.calendar_id.company_id.leave_timesheet_task_id)
global_time_offs_with_leave_timesheet._timesheet_create_lines()
return result
@@ -139,3 +139,39 @@ class TestTimesheetGlobalTimeOff(common.TransactionCase):
# No timesheet should have been created on the day off
timesheet = self.env['account.analytic.line'].search([('date', '=', day_off), ('task_id', '=', leave_task.id)])
self.assertFalse(timesheet.id)
# This tests that timesheets are created/deleted for every employee with the same calendar
# when a global time off has a calendar_id set/remove
def test_timesheet_creation_and_deletion_for_calendar_set_and_remove(self):
leave_start_datetime = datetime(2021, 1, 4, 7, 0, 0, 0) # This is a monday
leave_end_datetime = datetime(2021, 1, 8, 18, 0, 0, 0) # This is a friday
global_time_off = 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 and full_time_employee_2
# but none for part_time_employee
leave_task = self.test_company.leave_timesheet_task_id
# Now we delete the calendar_id. The timesheets should be deleted too.
global_time_off.calendar_id = False
self.assertFalse(leave_task.timesheet_ids.ids)
# Now we reset the calendar_id. The timesheets should be created and have the right value.
global_time_off.calendar_id = self.test_company.resource_calendar_id.id
timesheets_by_employee = defaultdict(lambda: self.env['account.analytic.line'])
for timesheet in leave_task.timesheet_ids:
timesheets_by_employee[timesheet.employee_id] |= timesheet
self.assertFalse(timesheets_by_employee.get(self.part_time_employee, False))
self.assertEqual(len(timesheets_by_employee.get(self.full_time_employee)), 5)
self.assertEqual(len(timesheets_by_employee.get(self.full_time_employee_2)), 5)
# The standard calendar is for 8 hours/day from 8 to 12 and from 13 to 17.
# So we need to check that the timesheets don't have more than 8 hours per day.
self.assertEqual(leave_task.effective_hours, 80)