[IMP] hr_holidays: Correctly compute number_of_hours_display

Purpose
=======

Impacted versions: 13.0

Steps to reproduce:
- Add employee
- allocate paid leave
- set leave in hours
- Employee working hours is
  Mo: 8:30-12:30
  Tu-Fr: 8:30-12:30 and 13:00-17:30 (total of 38h per week).
- Employee requests on week of leave
- Total hours in request is 38. Manager approves.

Current behavior:
Before approval the total hours in the request is 38. The manager
approves and the total hours change to 40. Total remaining hours is
also -40.

Expected behavior:
After approval the requested hours should not change and remain 38.
The total remaining hours should also be -38.

Taskid: 2166964
Closes: #41848
X-original-commit: b89565b93d8e6905d4cc3fe9d3de8ddecb43acd4
This commit is contained in:
Yannick Tivisse
2020-01-08 17:09:07 +00:00
parent 3c5194a00b
commit 416a1cc089
2 changed files with 79 additions and 2 deletions
+17 -2
View File
@@ -473,8 +473,23 @@ class HolidaysRequest(models.Model):
for holiday in self:
calendar = holiday._get_calendar()
if holiday.date_from and holiday.date_to:
number_of_hours = holiday._get_number_of_days(holiday.date_from, holiday.date_to, holiday.employee_id.id)['hours']
holiday.number_of_hours_display = number_of_hours or (holiday.number_of_days * HOURS_PER_DAY)
# Take attendances into account, in case the leave validated
# Otherwise, this will result into number_of_hours = 0
# and number_of_hours_display = 0 or (#day * calendar.hours_per_day),
# which could be wrong if the employee doesn't work the same number
# hours each day
if holiday.state == 'validate':
start_dt = holiday.date_from
end_dt = holiday.date_to
if not start_dt.tzinfo:
start_dt = start_dt.replace(tzinfo=UTC)
if not end_dt.tzinfo:
end_dt = end_dt.replace(tzinfo=UTC)
intervals = calendar._attendance_intervals(start_dt, end_dt, holiday.employee_id)
number_of_hours = sum((stop - start).total_seconds() / 3600 for start, stop, dummy in intervals)
else:
number_of_hours = holiday._get_number_of_days(holiday.date_from, holiday.date_to, holiday.employee_id.id)['hours']
holiday.number_of_hours_display = number_of_hours or (holiday.number_of_days * (calendar.hours_per_day or HOURS_PER_DAY))
else:
holiday.number_of_hours_display = 0
@@ -250,3 +250,65 @@ class TestLeaveRequests(TestHrHolidaysCommon):
leave._onchange_request_parameters()
self.assertEqual(leave.date_from, datetime(2019, 5, 5, 20, 0, 0), "It should have been localized before saving in UTC")
self.assertEqual(leave.date_to, datetime(2019, 5, 6, 5, 0, 0), "It should have been localized before saving in UTC")
def test_number_of_hours_display(self):
calendar = self.env['resource.calendar'].create({
'name': 'Monday Morning Else Full Time 38h/week',
'hours_per_day': 7.6,
'attendance_ids': [
(0, 0, {'name': 'Monday Morning', 'dayofweek': '0', 'hour_from': 8.5, 'hour_to': 12.5, 'day_period': 'morning'}),
(0, 0, {'name': 'Tuesday Morning', 'dayofweek': '1', 'hour_from': 8.5, 'hour_to': 12.5, 'day_period': 'morning'}),
(0, 0, {'name': 'Tuesday Afternoon', 'dayofweek': '1', 'hour_from': 13, 'hour_to': 17.5, 'day_period': 'afternoon'}),
(0, 0, {'name': 'Wednesday Morning', 'dayofweek': '2', 'hour_from': 8.5, 'hour_to': 12.5, 'day_period': 'morning'}),
(0, 0, {'name': 'Wednesday Afternoon', 'dayofweek': '2', 'hour_from': 13, 'hour_to': 17.5, 'day_period': 'afternoon'}),
(0, 0, {'name': 'Thursday Morning', 'dayofweek': '3', 'hour_from': 8.5, 'hour_to': 12.5, 'day_period': 'morning'}),
(0, 0, {'name': 'Thursday Afternoon', 'dayofweek': '3', 'hour_from': 13, 'hour_to': 17.5, 'day_period': 'afternoon'}),
(0, 0, {'name': 'Friday Morning', 'dayofweek': '4', 'hour_from': 8.5, 'hour_to': 12.5, 'day_period': 'morning'}),
(0, 0, {'name': 'Friday Afternoon', 'dayofweek': '4', 'hour_from': 13, 'hour_to': 17.5, 'day_period': 'afternoon'})
],
})
employee = self.employee_emp
employee.resource_calendar_id = calendar
self.env.user.company_id.resource_calendar_id = calendar
leave_type = self.env['hr.leave.type'].create({
'name': 'Paid Time Off',
'request_unit': 'hour',
'leave_validation_type': 'both',
})
allocation = self.env['hr.leave.allocation'].create({
'name': '20 days allocation',
'holiday_status_id': leave_type.id,
'number_of_days': 20,
'employee_id': employee.id,
})
allocation.action_approve()
leave1 = self.env['hr.leave'].create({
'name': 'Holiday 1 week',
'employee_id': employee.id,
'holiday_status_id': leave_type.id,
'date_from': fields.Datetime.from_string('2019-12-23 06:00:00'),
'date_to': fields.Datetime.from_string('2019-12-27 20:00:00'),
'number_of_days': 5,
})
self.assertEqual(leave1.number_of_hours_display, 38)
leave1.action_approve()
self.assertEqual(leave1.number_of_hours_display, 38)
leave1.action_validate()
self.assertEqual(leave1.number_of_hours_display, 38)
leave2 = self.env['hr.leave'].create({
'name': 'Holiday 1 Day',
'employee_id': employee.id,
'holiday_status_id': leave_type.id,
'date_from': fields.Datetime.from_string('2019-12-30 06:00:00'),
'date_to': fields.Datetime.from_string('2019-12-30 13:00:00'),
'number_of_days': 1,
})
self.assertEqual(leave2.number_of_hours_display, 4)
leave2.action_approve()
self.assertEqual(leave2.number_of_hours_display, 4)
leave2.action_validate()
self.assertEqual(leave2.number_of_hours_display, 4)