[FIX] hr_{,holidays}_attendance, resource: overtime is wrong for multi companies

Steps to Reproduce:

Create 2 companies > Create employee in 1st company > Enable both companies > Create public holidays company-wise> In company 1 create a public holiday for (13/11/2023) > In company 2 create public holidays (13/11/2023) and (29/11/2023).

Then switch to the one company (where the public holiday was created only for (13/11/2023))> Go to attendance > Configuration > Enable the count extra hours feature > Create attendance date (29/11/2023) for ex. 9 hours > Go to employee form > You may see the extra hour of "1 hour" > Because there is no public holiday on 29/11/2023.

Then enable both companies > Create attendance date (29/11/2023) for ex. 9 hours > Go to employee form > You may see the extra hours of "9 hours" > Because there is a public holiday in another company on 29/11/2023.

Bug Source:
commit 1407052 fixed the fact that public holidays are not taken into account when computing the overtime, but it doesn't cover the multi companies case.

Solution:
Verify that the public holiday company and the employee company are the same before applying the compute.
An optimization was also added to avoid searching for public holidays in db by filtering with the
employee company.

opw-3597287

closes odoo/odoo#146987

X-original-commit: 62494f5c7c80f2fafa56e397f2cd918e1a9e2648
Signed-off-by: Xavier Bol (xbo) <xbo@odoo.com>
This commit is contained in:
Abderraouf Ghrissi (abgh)
2023-12-21 21:53:44 +00:00
parent 11c77e3b32
commit 9ac153c7aa
3 changed files with 22 additions and 6 deletions
+4 -1
View File
@@ -264,7 +264,10 @@ class HrAttendance(models.Model):
)[emp.resource_id.id]
# Substract Global Leaves and Employee's Leaves
leave_intervals = calendar._leave_intervals_batch(
start, stop, emp.resource_id, domain=self._get_overtime_leave_domain()
start, stop, emp.resource_id, domain=AND([
self._get_overtime_leave_domain(),
[('company_id', 'in', [False, emp.company_id.id])],
])
)
expected_attendances -= leave_intervals[False] | leave_intervals[emp.resource_id.id]
@@ -246,12 +246,25 @@ class TestHolidaysOvertime(TransactionCase):
self.assertFalse(leave.overtime_id.exists())
def test_public_leave_overtime(self):
self.env['resource.calendar.leaves'].create([{
leave = self.env['resource.calendar.leaves'].create([{
'name': 'Public Holiday',
'date_from': datetime(2022, 5, 5, 6),
'date_to': datetime(2022, 5, 5, 18),
'time_type': 'leave',
}])
self.new_attendance(check_in=datetime(2022, 5, 5, 8), check_out=datetime(2022, 5, 5, 16))
self.assertEqual(self.employee.total_overtime, 7, 'Should have 7 hours of overtime (there is one hour of lunch)')
leave.company_id.write({
'hr_attendance_overtime': True,
'overtime_start_date': datetime(2021, 1, 1),
})
self.assertNotEqual(leave.company_id, self.employee.company_id)
self.manager.company_id = leave.company_id.id
for emp in [self.employee, self.manager]:
self.env['hr.attendance'].create({
'employee_id': emp.id,
'check_in': datetime(2022, 5, 5, 8),
'check_out': datetime(2022, 5, 5, 17),
})
self.assertEqual(self.employee.total_overtime, 0, "Should have 0 hours of overtime as the public holiday doesn't impact his company")
self.assertEqual(self.manager.total_overtime, 8, 'Should have 8 hours of overtime (there is one hour of lunch)')
+1 -1
View File
@@ -401,7 +401,7 @@ class ResourceCalendar(models.Model):
tz_dates = {}
for leave in self.env['resource.calendar.leaves'].search(domain):
for resource in resources_list:
if leave.resource_id.id not in [False, resource.id]:
if leave.resource_id.id not in [False, resource.id] or (not leave.resource_id and resource and resource.company_id != leave.company_id):
continue
tz = tz if tz else timezone((resource or self).tz)
if (tz, start_dt) in tz_dates: