Files
enterprise-addons/l10n_be_hr_payroll/tests/test_payroll_sickness_relapse.py
T

521 lines
22 KiB
Python

from datetime import date
from dateutil.relativedelta import relativedelta
from odoo.tests import tagged
from .common import TestPayrollCommon
@tagged("post_install_l10n", "post_install", "-at_install", "payroll_sickness_relapse")
class TestPayrollSicknessRelapse(TestPayrollCommon):
@classmethod
def setUpClass(cls):
super().setUpClass()
cls.sick_time_off_type = cls.env.ref("hr_holidays.leave_type_sick_time_off")
def test_sickness_relapse_visibility(self):
"""
Test Case:
Employee Test is sick for a week. The following week the employee becomes
sick again and submits another time off request. For the second
time off request the employee has the option to select if this sickness
is a relapse of the sickness from the week before or a new sickness.
"""
first_leave = self.env["hr.leave"].create(
{
"holiday_status_id": self.sick_time_off_type.id,
"employee_id": self.employee_test.id,
"request_date_from": date(2024, 7, 1),
"request_date_to": date(2024, 7, 5),
}
)
second_leave = self.env["hr.leave"].create(
{
"holiday_status_id": self.sick_time_off_type.id,
"employee_id": self.employee_test.id,
"request_date_from": date(2024, 7, 10),
"request_date_to": date(2024, 7, 12),
}
)
(first_leave + second_leave).action_approve()
self.assertFalse(first_leave.l10n_be_sickness_can_relapse)
self.assertTrue(second_leave.l10n_be_sickness_can_relapse)
def test_sickness_relapse_no_relapse(self):
"""
Test Case:
Employee Test is sick for 3 weeks. A week after the employee becomes
sick again and submits another time off request for another 3 weeks.
For the second time off request Employee test has indicated that this
is a new sickness and not a relapse of the previous sickness.
This results in a work entry with the code LEAVE110, Sick Time Off,
30 Calendar days after the first sick day, indicating that
the first sick leave has no effect on the second one.
"""
first_leave = self.env["hr.leave"].create(
{
"holiday_status_id": self.sick_time_off_type.id,
"employee_id": self.employee_test.id,
"request_date_from": date(2024, 7, 1),
"request_date_to": date(2024, 7, 20),
}
)
second_leave = self.env["hr.leave"].create(
{
"holiday_status_id": self.sick_time_off_type.id,
"employee_id": self.employee_test.id,
"request_date_from": date(2024, 7, 29),
"request_date_to": date(2024, 8, 16),
"l10n_be_sickness_relapse": False,
}
)
(first_leave + second_leave).action_approve()
work_entries = self.employee_test.version_ids.generate_work_entries(
date(2024, 8, 8), date(2024, 8, 8)
)
work_entries.action_validate()
work_entry_names = set(work_entries.mapped("code"))
self.assertSetEqual(work_entry_names, {"LEAVE110"})
def test_sickness_relapse_with_relapse(self):
"""
Test Case:
Employee Test is sick for 3 weeks. A week after the employee becomes
sick again and submits another time off request for another 3 weeks.
For the second time off request Employee test has indicated that this
a relapse of the previous sickness. This results in a work entry
with the code LEAVE214, Sick Time Off(Without Guaranteed Salary),
31 sick days after the first sick day, indicating that the second
sick leave is a continuation of the first one.
"""
first_leave = self.env["hr.leave"].create(
{
"holiday_status_id": self.sick_time_off_type.id,
"employee_id": self.employee_test.id,
"request_date_from": date(2024, 7, 1),
"request_date_to": date(2024, 7, 20),
}
)
second_leave = self.env["hr.leave"].create(
{
"holiday_status_id": self.sick_time_off_type.id,
"employee_id": self.employee_test.id,
"request_date_from": date(2024, 7, 29),
"request_date_to": date(2024, 8, 16),
"l10n_be_sickness_relapse": True,
}
)
(first_leave + second_leave).action_approve()
work_entry_paid = self.employee_test.version_ids.generate_work_entries(
date(2024, 8, 7), date(2024, 8, 7)
)
work_entry_unpaid = self.employee_test.version_ids.generate_work_entries(
date(2024, 8, 8), date(2024, 8, 8)
)
work_entry_paid.action_validate()
work_entry_unpaid.action_validate()
work_entry_paid_code = set(work_entry_paid.mapped("code"))
work_entry_unpaid_code = set(work_entry_unpaid.mapped("code"))
self.assertSetEqual(work_entry_paid_code, {"LEAVE110"})
self.assertSetEqual(work_entry_unpaid_code, {"LEAVE214"})
def test_sickness_multiple_sicknesses_partial_relapse(self):
"""
Test Case:
Employee Test is sick for 5 days every week for 4 weeks. The next week
Employee Test is sick again, but this is a new sickness. This sickness
relapses again every week for 2 more week. Even though Employee Test has
taken 35 days of sick leave he should still be paid fully as the
two sick leaves are not for the same illness. Thus all work entries
starting from the first day in the 7th week should still have
a work entry code of LEAVE110.
"""
first_leave = self.env["hr.leave"].create(
{
"holiday_status_id": self.sick_time_off_type.id,
"employee_id": self.employee_test.id,
"request_date_from": date(2024, 7, 1),
"request_date_to": date(2024, 7, 5),
}
)
second_leave = self.env["hr.leave"].create(
{
"holiday_status_id": self.sick_time_off_type.id,
"employee_id": self.employee_test.id,
"request_date_from": date(2024, 7, 8),
"request_date_to": date(2024, 7, 12),
"l10n_be_sickness_relapse": True,
}
)
third_leave = self.env["hr.leave"].create(
{
"holiday_status_id": self.sick_time_off_type.id,
"employee_id": self.employee_test.id,
"request_date_from": date(2024, 7, 15),
"request_date_to": date(2024, 7, 19),
"l10n_be_sickness_relapse": True,
}
)
fourth_leave = self.env["hr.leave"].create(
{
"holiday_status_id": self.sick_time_off_type.id,
"employee_id": self.employee_test.id,
"request_date_from": date(2024, 7, 22),
"request_date_to": date(2024, 7, 26),
"l10n_be_sickness_relapse": True,
}
)
fifth_leave = self.env["hr.leave"].create(
{
"holiday_status_id": self.sick_time_off_type.id,
"employee_id": self.employee_test.id,
"request_date_from": date(2024, 7, 29),
"request_date_to": date(2024, 8, 2),
"l10n_be_sickness_relapse": False,
}
)
sixth_leave = self.env["hr.leave"].create(
{
"holiday_status_id": self.sick_time_off_type.id,
"employee_id": self.employee_test.id,
"request_date_from": date(2024, 8, 5),
"request_date_to": date(2024, 8, 9),
"l10n_be_sickness_relapse": True,
}
)
seventh_leave = self.env["hr.leave"].create(
{
"holiday_status_id": self.sick_time_off_type.id,
"employee_id": self.employee_test.id,
"request_date_from": date(2024, 8, 12),
"request_date_to": date(2024, 8, 16),
"l10n_be_sickness_relapse": True,
}
)
(
first_leave
+ second_leave
+ third_leave
+ fourth_leave
+ fifth_leave
+ sixth_leave
+ seventh_leave
).action_approve()
work_entries = self.employee_test.version_ids.generate_work_entries(
date(2024, 8, 12), date(2024, 8, 12)
)
work_entries.action_validate()
work_entries_code = set(work_entries.mapped("code"))
self.assertSetEqual(work_entries_code, {"LEAVE110"})
self.assertFalse(first_leave.l10n_be_sickness_can_relapse)
self.assertTrue(second_leave.l10n_be_sickness_can_relapse)
self.assertTrue(third_leave.l10n_be_sickness_can_relapse)
self.assertTrue(fourth_leave.l10n_be_sickness_can_relapse)
self.assertTrue(fifth_leave.l10n_be_sickness_can_relapse)
self.assertTrue(sixth_leave.l10n_be_sickness_can_relapse)
self.assertTrue(seventh_leave.l10n_be_sickness_can_relapse)
def test_sickness_multiple_sicknesses_only_relapse(self):
"""
Test Case:
Employee Test is sick for 5 days every week for 7 weeks, with every sick
leave being a relapse of the previous one. All work entries starting
from the first day in the 7th week should have a work entry code of LEAVE214.
"""
first_leave = self.env["hr.leave"].create(
{
"holiday_status_id": self.sick_time_off_type.id,
"employee_id": self.employee_test.id,
"request_date_from": date(2024, 7, 1),
"request_date_to": date(2024, 7, 5),
}
)
second_leave = self.env["hr.leave"].create(
{
"holiday_status_id": self.sick_time_off_type.id,
"employee_id": self.employee_test.id,
"request_date_from": date(2024, 7, 8),
"request_date_to": date(2024, 7, 12),
"l10n_be_sickness_relapse": True,
}
)
third_leave = self.env["hr.leave"].create(
{
"holiday_status_id": self.sick_time_off_type.id,
"employee_id": self.employee_test.id,
"request_date_from": date(2024, 7, 15),
"request_date_to": date(2024, 7, 19),
"l10n_be_sickness_relapse": True,
}
)
fourth_leave = self.env["hr.leave"].create(
{
"holiday_status_id": self.sick_time_off_type.id,
"employee_id": self.employee_test.id,
"request_date_from": date(2024, 7, 22),
"request_date_to": date(2024, 7, 26),
"l10n_be_sickness_relapse": True,
}
)
fifth_leave = self.env["hr.leave"].create(
{
"holiday_status_id": self.sick_time_off_type.id,
"employee_id": self.employee_test.id,
"request_date_from": date(2024, 7, 29),
"request_date_to": date(2024, 8, 2),
"l10n_be_sickness_relapse": True,
}
)
sixth_leave = self.env["hr.leave"].create(
{
"holiday_status_id": self.sick_time_off_type.id,
"employee_id": self.employee_test.id,
"request_date_from": date(2024, 8, 5),
"request_date_to": date(2024, 8, 9),
"l10n_be_sickness_relapse": True,
}
)
seventh_leave = self.env["hr.leave"].create(
{
"holiday_status_id": self.sick_time_off_type.id,
"employee_id": self.employee_test.id,
"request_date_from": date(2024, 8, 12),
"request_date_to": date(2024, 8, 16),
"l10n_be_sickness_relapse": True,
}
)
(
first_leave
+ second_leave
+ third_leave
+ fourth_leave
+ fifth_leave
+ sixth_leave
+ seventh_leave
).action_approve()
work_entries = self.employee_test.version_ids.generate_work_entries(
date(2024, 8, 12), date(2024, 8, 12)
)
work_entries.action_validate()
work_entries_code = set(work_entries.mapped("code"))
self.assertSetEqual(work_entries_code, {"LEAVE214"})
self.assertFalse(first_leave.l10n_be_sickness_can_relapse)
self.assertTrue(second_leave.l10n_be_sickness_can_relapse)
self.assertTrue(third_leave.l10n_be_sickness_can_relapse)
self.assertTrue(fourth_leave.l10n_be_sickness_can_relapse)
self.assertTrue(fifth_leave.l10n_be_sickness_can_relapse)
self.assertTrue(sixth_leave.l10n_be_sickness_can_relapse)
self.assertTrue(seventh_leave.l10n_be_sickness_can_relapse)
def test_sickness_biweekly_relapse(self):
"""
Test Case:
A person is sick for 2 days every 14 days for almost 8 months.
Eventually the sick leave days should culminate in over 30 days
of leave causing the person to no longer have work entries with the
code LEAVE110.
"""
for i in range(16):
start_date = date(2024, 1, 1) + relativedelta(days=(14 * i))
end_date = start_date + relativedelta(days=1)
short_leave = self.env["hr.leave"].create(
{
"holiday_status_id": self.sick_time_off_type.id,
"employee_id": self.employee_test.id,
"request_date_from": start_date,
"request_date_to": end_date,
"l10n_be_sickness_relapse": True,
}
)
short_leave.action_approve()
work_entries = self.employee_test.version_ids.generate_work_entries(
date(2024, 7, 15), date(2024, 7, 29)
)
work_entries.action_validate()
paid_date = work_entries.filtered(lambda entry: entry.date.day == 15)
unpaid_date = work_entries.filtered(lambda entry: entry.date.day == 29)
work_entry_paid_code = set(paid_date.mapped("code"))
work_entry_unpaid_code = set(unpaid_date.mapped("code"))
self.assertSetEqual(work_entry_paid_code, {"LEAVE110"})
self.assertSetEqual(work_entry_unpaid_code, {"LEAVE214"})
def test_from_comment(self):
"""
Example (all dates are inclusive):
| Name | Date from | Date to | Relapse | Calendar Days | Work Days |
| ---- | ----------- | ----------- | ------- | ------------- | ---------- |
| 1st | 10/Jun/2024 | 12/Jun/2024 | False | 03 (c)days | 03 (w)days |
| 2nd | 01/Jul/2024 | 08/Jul/2024 | False | 08 (c)days | 06 (w)days |
| 3rd | 15/Jul/2024 | 30/Jul/2024 | True | 16 (c)days | 12 (w)days |
| 4th | 05/Aug/2024 | 15/Aug/2024 | True | 11 (c)days | 09 (w)days |
Note: 1st and 2nd leave will have a relapse value of True in practice because
that is the default value for the field. In this example, the value is set to
False to hopefully make the example clearer.
The first leave is shorter than 30 (calendar) days.
All (work) days within this leave have a guaranteed salary.
The second leave is shorter than 30 (c) days.
The gap between it and the first leave is greater than 14 days.
All (w) days within this leave have a guaranteed salary.
The third leave is shorter than 30 (c) days.
The gap between it and the second leave is less than 14 days.
It is a relapse, sum the duration of this and previous related leaves.
The sum is 8 + 16 = 24 (c) days, which is less than 30 days.
All (w) days within this leave have a guaranteed salary.
The fourth leave is shorter than 30 (c) days.
The gap between it and the third leave is less than 14 days.
It is a relapse, sum the duration of this and previous related leaves.
That sum is 8 + 16 + 11 = 35 (c) days, which is greater than 30 days.
The first 6 (c) days have a guaranteed salary.
(w) days 12/08 - 15/08 do not have a guaranteed salary.
"""
first_leave = self.env["hr.leave"].create(
{
"holiday_status_id": self.sick_time_off_type.id,
"employee_id": self.employee_test.id,
"request_date_from": date(2024, 6, 10),
"request_date_to": date(2024, 6, 12),
}
)
second_leave = self.env["hr.leave"].create(
{
"holiday_status_id": self.sick_time_off_type.id,
"employee_id": self.employee_test.id,
"request_date_from": date(2024, 7, 1),
"request_date_to": date(2024, 7, 8),
}
)
third_leave = self.env["hr.leave"].create(
{
"holiday_status_id": self.sick_time_off_type.id,
"employee_id": self.employee_test.id,
"request_date_from": date(2024, 7, 15),
"request_date_to": date(2024, 7, 30),
}
)
fourth_leave = self.env["hr.leave"].create(
{
"holiday_status_id": self.sick_time_off_type.id,
"employee_id": self.employee_test.id,
"request_date_from": date(2024, 8, 5),
"request_date_to": date(2024, 8, 15),
}
)
(first_leave + second_leave + third_leave + fourth_leave).action_approve()
work_entries = self.employee_test.version_ids.generate_work_entries(
date(2024, 8, 9), date(2024, 8, 12)
)
work_entries.action_validate()
paid_date = work_entries.filtered(lambda entry: entry.date.day == 9)
unpaid_date = work_entries.filtered(lambda entry: entry.date.day == 12)
work_entry_paid_code = set(paid_date.mapped("code"))
work_entry_unpaid_code = set(unpaid_date.mapped("code"))
self.assertSetEqual(work_entry_paid_code, {"LEAVE110"})
self.assertSetEqual(work_entry_unpaid_code, {"LEAVE214"})
self.assertFalse(first_leave.l10n_be_sickness_can_relapse)
self.assertFalse(second_leave.l10n_be_sickness_can_relapse)
self.assertTrue(third_leave.l10n_be_sickness_can_relapse)
self.assertTrue(fourth_leave.l10n_be_sickness_can_relapse)
def test_sickness_relapse_starting_from_2026(self):
"""
Example (all dates are inclusive):
| Leave | Date from | Date to | Relapse | Calendar Days | Work Days |
| ----- | ----------- | ----------- | ------- | ------------- | ---------- |
| 1st | 10/Jan/26 | 30/Jan/26 | False | 21 (c)days | 15 (w)days |
| 2nd | 01/Apr/26 | 15/Apr/26 | False | 15 (c)days | 11 (w)days |
| 3rd | 11/May/26 | 30/May/26 | True | 20 (c)days | 15 (w)days |
| 4th | 10/Aug/26 | 20/Aug/26 | False | 11 (c)days | 8 (w)days |
The first leave is shorter than 30 (calendar) days.
All (work) days within this leave have a guaranteed salary.
The second leave is shorter than 30 (c) days.
The gap between it and the first leave is greater than 56 days.
It is not considered as a relapse.
All (w) days within this leave have a guaranteed salary.
The third leave is shorter than 30 (c) days.
The gap between it and the second leave is less than 56 days.
It is a relapse, sum the duration of this and previous related leaves.
The sum is 15 + 20 = 35 (c) days, which is greater than 30 days.
The first 30 (c) days have a guaranteed salary.
(w) days 26/05 - 30/05 do not have a guaranteed salary.
The fourth leave is shorter than 30 (c) days.
The gap between it and the third leave is greater than 56 days.
It is not considered as a relapse.
"""
first_leave = self.env["hr.leave"].create({
"holiday_status_id": self.sick_time_off_type.id,
"employee_id": self.employee_test.id,
"request_date_from": date(2026, 1, 10),
"request_date_to": date(2026, 1, 30),
})
second_leave = self.env["hr.leave"].create({
"holiday_status_id": self.sick_time_off_type.id,
"employee_id": self.employee_test.id,
"request_date_from": date(2026, 4, 1),
"request_date_to": date(2026, 4, 15),
})
third_leave = self.env["hr.leave"].create({
"holiday_status_id": self.sick_time_off_type.id,
"employee_id": self.employee_test.id,
"request_date_from": date(2026, 5, 11),
"request_date_to": date(2026, 5, 30),
})
fourth_leave = self.env["hr.leave"].create({
"holiday_status_id": self.sick_time_off_type.id,
"employee_id": self.employee_test.id,
"request_date_from": date(2026, 8, 10),
"request_date_to": date(2026, 8, 20),
})
(first_leave + second_leave + third_leave + fourth_leave).action_approve()
work_entries = self.employee_test.version_ids.generate_work_entries(
date(2026, 5, 21), date(2026, 5, 30)
)
work_entries.action_validate()
paid_date = work_entries.filtered(lambda entry: entry.date.day == 22)
unpaid_date = work_entries.filtered(lambda entry: entry.date.day == 29)
work_entry_paid_code = set(paid_date.mapped("code"))
work_entry_unpaid_code = set(unpaid_date.mapped("code"))
self.assertSetEqual(work_entry_paid_code, {"LEAVE110"})
self.assertSetEqual(work_entry_unpaid_code, {"LEAVE214"})
self.assertFalse(first_leave.l10n_be_sickness_can_relapse)
self.assertFalse(second_leave.l10n_be_sickness_can_relapse)
self.assertTrue(third_leave.l10n_be_sickness_can_relapse)
self.assertFalse(fourth_leave.l10n_be_sickness_can_relapse)