Odoo18-Base/addons/hr_holidays/tests/test_company_leave.py

470 lines
20 KiB
Python
Raw Permalink Normal View History

2025-03-10 11:12:23 +07:00
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from datetime import date, datetime
from odoo.tests import tagged
from odoo.tests.common import TransactionCase, warmup
@tagged('company_leave')
class TestCompanyLeave(TransactionCase):
""" Test leaves for a whole company, conflict resolutions """
@classmethod
def setUpClass(cls):
super(TestCompanyLeave, cls).setUpClass()
cls.company = cls.env['res.company'].create({'name': 'A company'})
cls.company.resource_calendar_id.tz = "Europe/Brussels"
cls.bank_holiday = cls.env['hr.leave.type'].create({
'name': 'Bank Holiday',
'responsible_id': cls.env.user.id,
'company_id': cls.company.id,
'requires_allocation': 'no',
})
cls.paid_time_off = cls.env['hr.leave.type'].create({
'name': 'Paid Time Off',
'request_unit': 'day',
'leave_validation_type': 'both',
'company_id': cls.company.id,
'requires_allocation': 'no',
})
cls.employee = cls.env['hr.employee'].create({
'name': 'My Employee',
'company_id': cls.company.id,
'tz': "Europe/Brussels",
})
def test_leave_whole_company_01(self):
# TEST CASE 1: Leaves taken in days. Take a 3 days leave
# Add a company leave on the second day.
# Check that leave is split into 2.
leave = self.env['hr.leave'].create({
'name': 'Hol11',
'employee_id': self.employee.id,
'holiday_status_id': self.paid_time_off.id,
'request_date_from': date(2020, 1, 7),
'date_from': date(2020, 1, 7),
'request_date_to': date(2020, 1, 9),
'date_to': date(2020, 1, 9),
'number_of_days': 3,
})
leave._compute_date_from_to()
company_leave = self.env['hr.leave'].create({
'name': 'Bank Holiday',
'holiday_type': 'company',
'mode_company_id': self.company.id,
'holiday_status_id': self.bank_holiday.id,
'date_from': date(2020, 1, 8),
'request_date_from': date(2020, 1, 8),
'date_to': date(2020, 1, 8),
'request_date_to': date(2020, 1, 8),
'number_of_days': 1,
})
company_leave._compute_date_from_to()
company_leave.action_validate()
all_leaves = self.env['hr.leave'].search([('employee_id', '=', self.employee.id)], order='id')
self.assertEqual(len(all_leaves), 4)
# Original Leave
self.assertEqual(leave.state, 'refuse')
# before leave
self.assertEqual(all_leaves[1].date_from, datetime(2020, 1, 7, 7, 0))
self.assertEqual(all_leaves[1].date_to, datetime(2020, 1, 7, 16, 0))
self.assertEqual(all_leaves[1].number_of_days, 1)
self.assertEqual(all_leaves[1].state, 'confirm')
# After leave
self.assertEqual(all_leaves[2].date_from, datetime(2020, 1, 9, 7, 0))
self.assertEqual(all_leaves[2].date_to, datetime(2020, 1, 9, 16, 0))
self.assertEqual(all_leaves[2].number_of_days, 1)
self.assertEqual(all_leaves[2].state, 'confirm')
# Company Leave
self.assertEqual(all_leaves[3].date_from, datetime(2020, 1, 8, 7, 0))
self.assertEqual(all_leaves[3].date_to, datetime(2020, 1, 8, 16, 0))
self.assertEqual(all_leaves[3].number_of_days, 1)
self.assertEqual(all_leaves[3].state, 'validate')
def test_leave_whole_company_02(self):
# TEST CASE 2: Leaves taken in half-days. Take a 3 days leave
# Add a company leave on the second day
# Check that leave is split into 2
self.paid_time_off.request_unit = 'half_day'
leave = self.env['hr.leave'].create({
'name': 'Hol11',
'employee_id': self.employee.id,
'holiday_status_id': self.paid_time_off.id,
'request_date_from': date(2020, 1, 7),
'date_from': date(2020, 1, 7),
'request_date_to': date(2020, 1, 9),
'date_to': date(2020, 1, 9),
'number_of_days': 3,
})
leave._compute_date_from_to()
company_leave = self.env['hr.leave'].create({
'name': 'Bank Holiday',
'holiday_type': 'company',
'mode_company_id': self.company.id,
'holiday_status_id': self.bank_holiday.id,
'date_from': date(2020, 1, 8),
'request_date_from': date(2020, 1, 8),
'date_to': date(2020, 1, 8),
'request_date_to': date(2020, 1, 8),
'number_of_days': 1,
})
company_leave._compute_date_from_to()
company_leave.action_validate()
all_leaves = self.env['hr.leave'].search([('employee_id', '=', self.employee.id)], order='id')
self.assertEqual(len(all_leaves), 4)
# Original Leave
self.assertEqual(leave.state, 'refuse')
# before leave
self.assertEqual(all_leaves[1].date_from, datetime(2020, 1, 7, 7, 0))
self.assertEqual(all_leaves[1].date_to, datetime(2020, 1, 7, 16, 0))
self.assertEqual(all_leaves[1].number_of_days, 1)
self.assertEqual(all_leaves[1].state, 'confirm')
# After leave
self.assertEqual(all_leaves[2].date_from, datetime(2020, 1, 9, 7, 0))
self.assertEqual(all_leaves[2].date_to, datetime(2020, 1, 9, 16, 0))
self.assertEqual(all_leaves[2].number_of_days, 1)
self.assertEqual(all_leaves[2].state, 'confirm')
# Company Leave
self.assertEqual(all_leaves[3].date_from, datetime(2020, 1, 8, 7, 0))
self.assertEqual(all_leaves[3].date_to, datetime(2020, 1, 8, 16, 0))
self.assertEqual(all_leaves[3].number_of_days, 1)
self.assertEqual(all_leaves[3].state, 'validate')
def test_leave_whole_company_03(self):
# TEST CASE 3: Leaves taken in half-days. Take a 0.5 days leave
# Add a company leave on the same day
# Check that leave refused
self.paid_time_off.request_unit = 'half_day'
leave = self.env['hr.leave'].create({
'name': 'Hol11',
'employee_id': self.employee.id,
'holiday_status_id': self.paid_time_off.id,
'date_from': date(2020, 1, 7),
'request_date_from': date(2020, 1, 7),
'date_to': date(2020, 1, 7),
'request_date_to': date(2020, 1, 7),
'number_of_days': 0.5,
'request_unit_half': True,
'request_date_from_period': 'am',
})
leave._compute_date_from_to()
company_leave = self.env['hr.leave'].create({
'name': 'Bank Holiday',
'holiday_type': 'company',
'mode_company_id': self.company.id,
'holiday_status_id': self.bank_holiday.id,
'date_from': date(2020, 1, 7),
'request_date_from': date(2020, 1, 7),
'date_to': date(2020, 1, 7),
'request_date_to': date(2020, 1, 7),
'number_of_days': 1,
})
company_leave._compute_date_from_to()
company_leave.action_validate()
all_leaves = self.env['hr.leave'].search([('employee_id', '=', self.employee.id)], order='id')
self.assertEqual(len(all_leaves), 2)
# Original Leave
self.assertEqual(leave.state, 'refuse')
# Company Leave
self.assertEqual(all_leaves[1].date_from, datetime(2020, 1, 7, 7, 0))
self.assertEqual(all_leaves[1].date_to, datetime(2020, 1, 7, 16, 0))
self.assertEqual(all_leaves[1].number_of_days, 1)
self.assertEqual(all_leaves[1].state, 'validate')
def test_leave_whole_company_04(self):
# TEST CASE 4: Leaves taken in days. Take a 1 days leave
# Add a company leave on the same day
# Check that leave is refused
self.paid_time_off.request_unit = 'day'
leave = self.env['hr.leave'].create({
'name': 'Hol11',
'employee_id': self.employee.id,
'holiday_status_id': self.paid_time_off.id,
'date_from': datetime.now(),
'request_date_from': date(2020, 1, 9),
'date_to': datetime.now(),
'request_date_to': date(2020, 1, 9),
'number_of_days': 1,
})
leave._compute_date_from_to()
company_leave = self.env['hr.leave'].create({
'name': 'Bank Holiday',
'holiday_type': 'company',
'mode_company_id': self.company.id,
'holiday_status_id': self.bank_holiday.id,
'date_from': date(2020, 1, 9),
'request_date_from': date(2020, 1, 9),
'date_to': date(2020, 1, 9),
'request_date_to': date(2020, 1, 9),
'number_of_days': 1,
})
company_leave._compute_date_from_to()
company_leave.action_validate()
all_leaves = self.env['hr.leave'].search([('employee_id', '=', self.employee.id)], order='id')
self.assertEqual(len(all_leaves), 2)
# Original Leave
self.assertEqual(leave.state, 'refuse')
# Company Leave
self.assertEqual(all_leaves[1].date_from, datetime(2020, 1, 9, 7, 0))
self.assertEqual(all_leaves[1].date_to, datetime(2020, 1, 9, 16, 0))
self.assertEqual(all_leaves[1].number_of_days, 1)
self.assertEqual(all_leaves[1].state, 'validate')
def test_leave_whole_company_06(self):
# Test case 6: Leaves taken in days. But the employee
# only works on Monday, Wednesday and Friday
# Takes a time off for all the week (3 days), should be split
self.employee.resource_calendar_id.write({'attendance_ids': [
(5, 0, 0),
(0, 0, {'name': 'Monday Morning', 'dayofweek': '0', 'hour_from': 8, 'hour_to': 12, 'day_period': 'morning'}),
(0, 0, {'name': 'Monday Afternoon', 'dayofweek': '0', 'hour_from': 13, 'hour_to': 17, 'day_period': 'afternoon'}),
(0, 0, {'name': 'Wednesday Morning', 'dayofweek': '2', 'hour_from': 8, 'hour_to': 12, 'day_period': 'morning'}),
(0, 0, {'name': 'Wednesday Afternoon', 'dayofweek': '2', 'hour_from': 13, 'hour_to': 17, 'day_period': 'afternoon'}),
(0, 0, {'name': 'Friday Morning', 'dayofweek': '4', 'hour_from': 8, 'hour_to': 12, 'day_period': 'morning'}),
(0, 0, {'name': 'Friday Afternoon', 'dayofweek': '4', 'hour_from': 13, 'hour_to': 17, 'day_period': 'afternoon'})
]})
leave = self.env['hr.leave'].create({
'name': 'Hol11',
'employee_id': self.employee.id,
'holiday_status_id': self.paid_time_off.id,
'date_from': date(2020, 1, 6),
'request_date_from': date(2020, 1, 6),
'date_to': date(2020, 1, 10),
'request_date_to': date(2020, 1, 10),
'number_of_days': 3,
})
leave._compute_date_from_to()
company_leave = self.env['hr.leave'].create({
'name': 'Bank Holiday',
'holiday_type': 'company',
'mode_company_id': self.company.id,
'holiday_status_id': self.bank_holiday.id,
'date_from': date(2020, 1, 10),
'request_date_from': date(2020, 1, 10),
'date_to': date(2020, 1, 10),
'request_date_to': date(2020, 1, 10),
'number_of_days': 1,
})
company_leave._compute_date_from_to()
company_leave.action_validate()
all_leaves = self.env['hr.leave'].search([('employee_id', '=', self.employee.id)], order='id')
self.assertEqual(len(all_leaves), 3)
# Original Leave
self.assertEqual(leave.state, 'refuse')
# before leave
self.assertEqual(all_leaves[1].date_from, datetime(2020, 1, 6, 7, 0))
self.assertEqual(all_leaves[1].date_to, datetime(2020, 1, 9, 16, 0))
self.assertEqual(all_leaves[1].number_of_days, 2)
self.assertEqual(all_leaves[1].state, 'confirm')
# Company Leave
self.assertEqual(all_leaves[2].date_from, datetime(2020, 1, 10, 7, 0))
self.assertEqual(all_leaves[2].date_to, datetime(2020, 1, 10, 16, 0))
self.assertEqual(all_leaves[2].number_of_days, 1)
self.assertEqual(all_leaves[2].state, 'validate')
@warmup
def test_leave_whole_company_07(self):
# Test Case 7: Try to create a bank holidays for a lot of
# employees, and check the performances
# 100 employees - 15 already on holidays that day
employees = self.env['hr.employee'].create([{
'name': 'Employee %s' % i,
'company_id': self.company.id
} for i in range(100)])
leaves = self.env['hr.leave'].create([{
'name': 'Holiday - %s' % employee.name,
'employee_id': employee.id,
'holiday_status_id': self.paid_time_off.id,
'request_date_from': date(2020, 3, 29),
'date_from': datetime(2020, 3, 29, 7, 0, 0),
'request_date_to': date(2020, 4, 1),
'date_to': datetime(2020, 4, 1, 19, 0, 0),
'number_of_days': 3,
} for employee in employees[0:15]])
leaves._compute_date_from_to()
company_leave = self.env['hr.leave'].create({
'name': 'Bank Holiday',
'holiday_type': 'company',
'mode_company_id': self.company.id,
'holiday_status_id': self.bank_holiday.id,
'date_from': date(2020, 4, 1),
'request_date_from': date(2020, 4, 1),
'date_to': date(2020, 4, 1),
'request_date_to': date(2020, 4, 1),
'number_of_days': 1,
})
company_leave._compute_date_from_to()
with self.assertQueryCount(__system__=830): # 770 community
# Original query count: 1987
# Without tracking/activity context keys: 5154
company_leave.action_validate()
leaves = self.env['hr.leave'].search([('holiday_status_id', '=', self.bank_holiday.id)])
self.assertEqual(len(leaves), 102)
def test_leave_whole_company_08(self):
"""
Give a company leave with employees on different schedules.
"""
# employee on different schedule
calendar = self.env['resource.calendar'].create({
'name': 'Different schedule',
'attendance_ids': [(5, 0, 0),
(0, 0, {
'name': 'monday morning, earlier start',
'hour_from': 7.5,
'hour_to': 9.75,
'day_period': 'morning',
'dayofweek': '0',
}),
(0, 0, {
'name': 'monday morning, second attendance',
'hour_from': 10,
'hour_to': 12,
'day_period': 'morning',
'dayofweek': '0',
}),
(0, 0, {
'name': 'monday afternoon',
'hour_from': 13,
'hour_to': 17,
'day_period': 'afternoon',
'dayofweek': '0',
}),
]
})
self.employee.resource_calendar_id = calendar
# employee on default schedule
employee2 = self.env['hr.employee'].create({
'name': 'Employee2',
'company_id': self.company.id,
'tz': "Europe/Brussels",
})
company_leave = self.env['hr.leave'].create({
'name': 'Bank Holiday',
'holiday_type': 'company',
'mode_company_id': self.company.id,
'holiday_status_id': self.bank_holiday.id,
'date_from': date(2020, 1, 6),
'request_date_from': date(2020, 1, 6),
'date_to': date(2020, 1, 6),
'request_date_to': date(2020, 1, 6),
'number_of_days': 1,
})
company_leave._compute_date_from_to()
company_leave.action_validate()
half_day_company_leave = self.env['hr.leave'].create({
'name': 'Bank Holiday',
'holiday_type': 'company',
'mode_company_id': self.company.id,
'holiday_status_id': self.bank_holiday.id,
'date_from': date(2020, 1, 13),
'request_date_from': date(2020, 1, 13),
'date_to': date(2020, 1, 13),
'request_date_to': date(2020, 1, 13),
'number_of_days': 0.5,
'request_unit_half': True,
'request_date_from_period': 'am',
})
half_day_company_leave._compute_date_from_to()
half_day_company_leave.action_validate()
employee_leaves = self.env['hr.leave'].search([('employee_id', '=', self.employee.id)], order='id')
self.assertEqual(employee_leaves[0].date_from, datetime(2020, 1, 6, 6, 30))
self.assertEqual(employee_leaves[0].date_to, datetime(2020, 1, 6, 16, 0))
self.assertEqual(employee_leaves[0].number_of_days, 1)
self.assertEqual(employee_leaves[0].number_of_hours_display, 8.25)
self.assertEqual(employee_leaves[1].date_from, datetime(2020, 1, 13, 6, 30))
self.assertEqual(employee_leaves[1].date_to, datetime(2020, 1, 13, 11, 0))
self.assertEqual(employee_leaves[1].number_of_days, 0.5)
self.assertEqual(employee_leaves[1].number_of_hours_display, 4.25)
employee2_leaves = self.env['hr.leave'].search([('employee_id', '=', employee2.id)], order='id')
self.assertEqual(employee2_leaves[0].date_from, datetime(2020, 1, 6, 7, 0))
self.assertEqual(employee2_leaves[0].number_of_days, 1)
self.assertEqual(employee2_leaves[1].date_from, datetime(2020, 1, 13, 7, 0))
self.assertEqual(employee2_leaves[1].date_to, datetime(2020, 1, 13, 11, 0))
self.assertEqual(employee2_leaves[1].number_of_days, 0.5)
def test_leave_whole_company_09(self):
"""
Check leaves given in half days and in hours for a company.
"""
half_day_leave = self.env['hr.leave'].create({
'name': 'Bank Holiday (full day)',
'holiday_type': 'company',
'mode_company_id': self.company.id,
'holiday_status_id': self.bank_holiday.id,
'date_from': date(2020, 1, 6),
'request_date_from': date(2020, 1, 6),
'date_to': date(2020, 1, 6),
'request_date_to': date(2020, 1, 6),
'number_of_days': 0.5,
'request_unit_half': True,
'request_date_from_period': 'am',
})
hours_leave = self.env['hr.leave'].create({
'name': 'Bank Holiday (half day)',
'holiday_type': 'company',
'mode_company_id': self.company.id,
'holiday_status_id': self.bank_holiday.id,
'date_from': date(2020, 1, 7),
'request_date_from': date(2020, 1, 7),
'date_to': date(2020, 1, 7),
'request_date_to': date(2020, 1, 7),
'request_unit_hours': True,
'request_hour_from': '5.5',
'request_hour_to': '9',
})
half_day_leave._compute_date_from_to()
half_day_leave.action_validate()
hours_leave._compute_date_from_to()
hours_leave.action_validate()
employee_leaves = self.env['hr.leave'].search([('employee_id', '=', self.employee.id)], order='id')
# half days leave
self.assertEqual(employee_leaves[0].date_from, datetime(2020, 1, 6, 7, 0))
self.assertEqual(employee_leaves[0].date_to, datetime(2020, 1, 6, 11, 0))
self.assertEqual(employee_leaves[0].number_of_days, 0.5)
# leave given in hours
self.assertEqual(employee_leaves[1].date_from, datetime(2020, 1, 7, 3, 30))
self.assertEqual(employee_leaves[1].date_to, datetime(2020, 1, 7, 7, 0))
self.assertEqual(employee_leaves[1].number_of_hours_display, 1.0)