mirror of
https://github.com/bringout/oca-ocb-hr.git
synced 2026-04-26 00:32:00 +02:00
Initial commit: Hr packages
This commit is contained in:
commit
62531cd146
2820 changed files with 1432848 additions and 0 deletions
|
|
@ -0,0 +1,8 @@
|
|||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from . import test_auto_status
|
||||
from . import test_contract
|
||||
from . import test_calendar_sync
|
||||
from . import test_resource
|
||||
from . import test_employee
|
||||
from . import test_attendances
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from odoo.tests.common import TransactionCase
|
||||
|
||||
|
||||
class TestContractCommon(TransactionCase):
|
||||
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
super(TestContractCommon, cls).setUpClass()
|
||||
|
||||
cls.employee = cls.env['hr.employee'].create({
|
||||
'name': 'Richard',
|
||||
'gender': 'male',
|
||||
'country_id': cls.env.ref('base.be').id,
|
||||
})
|
||||
|
|
@ -0,0 +1,68 @@
|
|||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from pytz import timezone
|
||||
|
||||
from datetime import datetime, date
|
||||
|
||||
from odoo.addons.hr_contract.tests.common import TestContractCommon
|
||||
|
||||
|
||||
class TestAttendances(TestContractCommon):
|
||||
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
super().setUpClass()
|
||||
cls.env.company.resource_calendar_id.tz = "Europe/Brussels"
|
||||
|
||||
resource_calendar_half_time = cls.env['resource.calendar'].create([{
|
||||
'name': "Test Calendar: Half Time",
|
||||
'company_id': cls.env.company.id,
|
||||
'tz': "Europe/Brussels",
|
||||
'two_weeks_calendar': False,
|
||||
'attendance_ids': [(5, 0, 0)] + [(0, 0, {
|
||||
'name': "Attendance",
|
||||
'dayofweek': dayofweek,
|
||||
'hour_from': hour_from,
|
||||
'hour_to': hour_to,
|
||||
'day_period': day_period,
|
||||
}) for dayofweek, hour_from, hour_to, day_period in [
|
||||
("0", 8.0, 12.0, "morning"),
|
||||
("0", 13.0, 16.6, "afternoon"),
|
||||
("1", 8.0, 12.0, "morning"),
|
||||
("1", 13.0, 16.6, "afternoon"),
|
||||
("2", 8.0, 11.8, "morning"),
|
||||
]],
|
||||
}])
|
||||
|
||||
contract_now = cls.env['hr.contract'].create({
|
||||
'name': 'Current Contract',
|
||||
'employee_id': cls.employee.id,
|
||||
'state': "open",
|
||||
'wage': 1,
|
||||
'date_start': date(2024, 6, 1),
|
||||
'date_end': date(2024, 6, 30),
|
||||
})
|
||||
|
||||
cls.env['hr.contract'].create({
|
||||
'name': 'Next Contract',
|
||||
'employee_id': cls.employee.id,
|
||||
'resource_calendar_id': resource_calendar_half_time.id,
|
||||
'state': "open",
|
||||
'wage': 1,
|
||||
'date_start': date(2024, 7, 1),
|
||||
'date_end': False,
|
||||
})
|
||||
|
||||
cls.employee.resource_calendar_id = contract_now.resource_calendar_id
|
||||
|
||||
def test_incoming_overlapping_contract(self):
|
||||
tz = timezone("Europe/Brussels")
|
||||
check_in_tz = datetime.combine(datetime(2024, 6, 1), datetime.min.time()).astimezone(tz)
|
||||
check_out_tz = datetime.combine(datetime(2024, 6, 30), datetime.max.time()).astimezone(tz)
|
||||
intervals = self.employee._get_expected_attendances(check_in_tz, check_out_tz)
|
||||
self.assertEqual(len(intervals), 40)
|
||||
|
||||
check_in_tz = datetime.combine(datetime(2024, 7, 1), datetime.min.time()).astimezone(tz)
|
||||
check_out_tz = datetime.combine(datetime(2024, 7, 31), datetime.max.time()).astimezone(tz)
|
||||
intervals = self.employee._get_expected_attendances(check_in_tz, check_out_tz)
|
||||
self.assertEqual(len(intervals), 25)
|
||||
|
|
@ -0,0 +1,78 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from datetime import date, datetime
|
||||
from dateutil.relativedelta import relativedelta
|
||||
from odoo.addons.hr_contract.tests.common import TestContractCommon
|
||||
|
||||
|
||||
class TestHrContracts(TestContractCommon):
|
||||
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
super(TestHrContracts, cls).setUpClass()
|
||||
cls.contracts = cls.env['hr.contract'].with_context(tracking_disable=True)
|
||||
cls.test_contract = dict(name='Test', wage=1, employee_id=cls.employee.id, state='open')
|
||||
|
||||
def test_employee_contractwarning(self):
|
||||
self.assertEqual(self.employee.contract_warning, True)
|
||||
|
||||
def apply_cron(self):
|
||||
self.env.ref('hr_contract.ir_cron_data_contract_update_state').method_direct_trigger()
|
||||
|
||||
def test_contract_enddate(self):
|
||||
self.test_contract.update(dict(date_end=datetime.now() + relativedelta(days=100)))
|
||||
self.contract = self.contracts.create(self.test_contract)
|
||||
self.apply_cron()
|
||||
self.assertEqual(self.contract.state, 'open')
|
||||
self.assertEqual(self.contract.kanban_state, 'normal')
|
||||
self.assertEqual(self.employee.contract_warning, False)
|
||||
|
||||
self.test_contract.update(dict(date_end=datetime.now() + relativedelta(days=5)))
|
||||
self.contract.write(self.test_contract)
|
||||
self.apply_cron()
|
||||
self.assertEqual(self.contract.state, 'open')
|
||||
self.assertEqual(self.contract.kanban_state, 'blocked')
|
||||
|
||||
self.test_contract.update({
|
||||
'date_start': datetime.now() + relativedelta(days=-50),
|
||||
'date_end': datetime.now() + relativedelta(days=-1),
|
||||
'state': 'open',
|
||||
'kanban_state': 'blocked',
|
||||
})
|
||||
self.contract.write(self.test_contract)
|
||||
self.apply_cron()
|
||||
self.assertEqual(self.contract.state, 'close')
|
||||
|
||||
def test_contract_pending_visa_expire(self):
|
||||
self.employee.visa_expire = date.today() + relativedelta(days=30)
|
||||
self.test_contract.update(dict(date_end=False))
|
||||
self.contract = self.contracts.create(self.test_contract)
|
||||
self.apply_cron()
|
||||
self.assertEqual(self.contract.state, 'open')
|
||||
self.assertEqual(self.contract.kanban_state, 'blocked')
|
||||
|
||||
self.employee.visa_expire = date.today() + relativedelta(days=-5)
|
||||
self.test_contract.update({
|
||||
'date_start': datetime.now() + relativedelta(days=-50),
|
||||
'state': 'open',
|
||||
'kanban_state': 'blocked',
|
||||
})
|
||||
self.contract.write(self.test_contract)
|
||||
self.apply_cron()
|
||||
self.assertEqual(self.contract.state, 'close')
|
||||
|
||||
def test_contract_start_date(self):
|
||||
self.test_contract.update(dict(date_start=datetime.now(), state='draft', kanban_state='done'))
|
||||
self.contract = self.contracts.create(self.test_contract)
|
||||
self.apply_cron()
|
||||
self.assertEqual(self.contract.state, 'open')
|
||||
|
||||
def test_contract_auto_expire(self):
|
||||
self.test_contract.update(dict(date_start=date.today() - relativedelta(days=10), state='open'))
|
||||
self.contract = self.contracts.create(self.test_contract)
|
||||
self.apply_cron()
|
||||
self.assertEqual(self.contract.state, 'open')
|
||||
|
||||
self.contract.date_end = date.today() - relativedelta(days=3)
|
||||
self.assertEqual(self.contract.state, 'close')
|
||||
|
|
@ -0,0 +1,69 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from odoo.fields import Datetime, Date
|
||||
from odoo.addons.hr_contract.tests.common import TestContractCommon
|
||||
|
||||
|
||||
class TestContractCalendars(TestContractCommon):
|
||||
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
super(TestContractCalendars, cls).setUpClass()
|
||||
cls.calendar_richard = cls.env['resource.calendar'].create({'name': 'Calendar of Richard'})
|
||||
cls.employee.resource_calendar_id = cls.calendar_richard
|
||||
|
||||
cls.calendar_35h = cls.env['resource.calendar'].create({'name': '35h calendar'})
|
||||
cls.calendar_35h._onchange_hours_per_day() # update hours/day
|
||||
|
||||
cls.contract_cdd = cls.env['hr.contract'].create({
|
||||
'date_end': Date.to_date('2015-11-15'),
|
||||
'date_start': Date.to_date('2015-01-01'),
|
||||
'name': 'First CDD Contract for Richard',
|
||||
'resource_calendar_id': cls.calendar_35h.id,
|
||||
'wage': 5000.0,
|
||||
'employee_id': cls.employee.id,
|
||||
'state': 'close',
|
||||
})
|
||||
|
||||
def test_contract_state_incoming_to_open(self):
|
||||
# Employee's calendar should change
|
||||
self.assertEqual(self.employee.resource_calendar_id, self.calendar_richard)
|
||||
self.contract_cdd.state = 'open'
|
||||
self.assertEqual(self.employee.resource_calendar_id, self.contract_cdd.resource_calendar_id, "The employee should have the calendar of its contract.")
|
||||
|
||||
def test_contract_transfer_leaves(self):
|
||||
|
||||
def create_calendar_leave(start, end, resource=None):
|
||||
return self.env['resource.calendar.leaves'].create({
|
||||
'name': 'leave name',
|
||||
'date_from': start,
|
||||
'date_to': end,
|
||||
'resource_id': resource.id if resource else None,
|
||||
'calendar_id': self.employee.resource_calendar_id.id,
|
||||
'time_type': 'leave',
|
||||
})
|
||||
|
||||
start = Datetime.to_datetime('2015-11-17 07:00:00')
|
||||
end = Datetime.to_datetime('2015-11-20 18:00:00')
|
||||
leave1 = create_calendar_leave(start, end, resource=self.employee.resource_id)
|
||||
|
||||
start = Datetime.to_datetime('2015-11-25 07:00:00')
|
||||
end = Datetime.to_datetime('2015-11-28 18:00:00')
|
||||
leave2 = create_calendar_leave(start, end, resource=self.employee.resource_id)
|
||||
|
||||
# global leave
|
||||
start = Datetime.to_datetime('2015-11-25 07:00:00')
|
||||
end = Datetime.to_datetime('2015-11-28 18:00:00')
|
||||
leave3 = create_calendar_leave(start, end)
|
||||
|
||||
self.calendar_richard.transfer_leaves_to(self.calendar_35h, resources=self.employee.resource_id, from_date=Date.to_date('2015-11-21'))
|
||||
|
||||
self.assertEqual(leave1.calendar_id, self.calendar_richard, "It should stay in Richard's calendar")
|
||||
self.assertEqual(leave3.calendar_id, self.calendar_richard, "Global leave should stay in original calendar")
|
||||
self.assertEqual(leave2.calendar_id, self.calendar_35h, "It should be transfered to the other calendar")
|
||||
|
||||
# Transfer global leaves
|
||||
self.calendar_richard.transfer_leaves_to(self.calendar_35h, resources=None, from_date=Date.to_date('2015-11-21'))
|
||||
|
||||
self.assertEqual(leave3.calendar_id, self.calendar_35h, "Global leave should be transfered")
|
||||
|
|
@ -0,0 +1,199 @@
|
|||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from datetime import datetime, date
|
||||
from dateutil.relativedelta import relativedelta
|
||||
|
||||
from odoo.exceptions import ValidationError
|
||||
from odoo.addons.hr_contract.tests.common import TestContractCommon
|
||||
from odoo.tests import tagged
|
||||
from odoo.tests import Form
|
||||
|
||||
@tagged('test_contracts')
|
||||
class TestHrContracts(TestContractCommon):
|
||||
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
super(TestHrContracts, cls).setUpClass()
|
||||
cls.contracts = cls.env['hr.contract'].with_context(tracking_disable=True)
|
||||
|
||||
def create_contract(self, state, kanban_state, start, end=None):
|
||||
return self.env['hr.contract'].create({
|
||||
'name': 'Contract',
|
||||
'employee_id': self.employee.id,
|
||||
'state': state,
|
||||
'kanban_state': kanban_state,
|
||||
'wage': 1,
|
||||
'date_start': start,
|
||||
'date_end': end,
|
||||
})
|
||||
|
||||
def test_incoming_overlapping_contract(self):
|
||||
start = datetime.strptime('2015-11-01', '%Y-%m-%d').date()
|
||||
end = datetime.strptime('2015-11-30', '%Y-%m-%d').date()
|
||||
self.create_contract('open', 'normal', start, end)
|
||||
|
||||
# Incoming contract
|
||||
with self.assertRaises(ValidationError, msg="It should not create two contract in state open or incoming"):
|
||||
start = datetime.strptime('2015-11-15', '%Y-%m-%d').date()
|
||||
end = datetime.strptime('2015-12-30', '%Y-%m-%d').date()
|
||||
self.create_contract('draft', 'done', start, end)
|
||||
|
||||
def test_pending_overlapping_contract(self):
|
||||
start = datetime.strptime('2015-11-01', '%Y-%m-%d').date()
|
||||
end = datetime.strptime('2015-11-30', '%Y-%m-%d').date()
|
||||
self.create_contract('open', 'normal', start, end)
|
||||
|
||||
# Pending contract
|
||||
with self.assertRaises(ValidationError, msg="It should not create two contract in state open or pending"):
|
||||
start = datetime.strptime('2015-11-15', '%Y-%m-%d').date()
|
||||
end = datetime.strptime('2015-12-30', '%Y-%m-%d').date()
|
||||
self.create_contract('open', 'blocked', start, end)
|
||||
|
||||
# Draft contract -> should not raise
|
||||
start = datetime.strptime('2015-11-15', '%Y-%m-%d').date()
|
||||
end = datetime.strptime('2015-12-30', '%Y-%m-%d').date()
|
||||
self.create_contract('draft', 'normal', start, end)
|
||||
|
||||
def test_draft_overlapping_contract(self):
|
||||
start = datetime.strptime('2015-11-01', '%Y-%m-%d').date()
|
||||
end = datetime.strptime('2015-11-30', '%Y-%m-%d').date()
|
||||
self.create_contract('open', 'normal', start, end)
|
||||
|
||||
# Draft contract -> should not raise even if overlapping
|
||||
start = datetime.strptime('2015-11-15', '%Y-%m-%d').date()
|
||||
end = datetime.strptime('2015-12-30', '%Y-%m-%d').date()
|
||||
self.create_contract('draft', 'normal', start, end)
|
||||
|
||||
def test_overlapping_contract_no_end(self):
|
||||
|
||||
# No end date
|
||||
self.create_contract('open', 'normal', datetime.strptime('2015-11-01', '%Y-%m-%d').date())
|
||||
|
||||
with self.assertRaises(ValidationError):
|
||||
start = datetime.strptime('2015-11-15', '%Y-%m-%d').date()
|
||||
end = datetime.strptime('2015-12-30', '%Y-%m-%d').date()
|
||||
self.create_contract('draft', 'done', start, end)
|
||||
|
||||
def test_overlapping_contract_no_end2(self):
|
||||
|
||||
start = datetime.strptime('2015-11-01', '%Y-%m-%d').date()
|
||||
end = datetime.strptime('2015-12-30', '%Y-%m-%d').date()
|
||||
self.create_contract('open', 'normal', start, end)
|
||||
|
||||
with self.assertRaises(ValidationError):
|
||||
# No end
|
||||
self.create_contract('draft', 'done', datetime.strptime('2015-01-01', '%Y-%m-%d').date())
|
||||
|
||||
def test_set_employee_contract_create(self):
|
||||
contract = self.create_contract('open', 'normal', date(2018, 1, 1), date(2018, 1, 2))
|
||||
self.assertEqual(self.employee.contract_id, contract)
|
||||
|
||||
def test_set_employee_contract_write(self):
|
||||
contract = self.create_contract('draft', 'normal', date(2018, 1, 1), date(2018, 1, 2))
|
||||
contract.state = 'open'
|
||||
self.assertEqual(self.employee.contract_id, contract)
|
||||
|
||||
def test_first_contract_date(self):
|
||||
self.create_contract('open', 'normal', date(2018, 1, 1), date(2018, 1, 31))
|
||||
self.assertEqual(self.employee.first_contract_date, date(2018, 1, 1))
|
||||
|
||||
# New contract, no gap
|
||||
self.create_contract('open', 'normal', date(2017, 1, 1), date(2017, 12, 31))
|
||||
self.assertEqual(self.employee.first_contract_date, date(2017, 1, 1))
|
||||
|
||||
# New contract, with gap
|
||||
self.create_contract('open', 'normal', date(2016, 1, 1), date(2016, 1, 31))
|
||||
self.assertEqual(self.employee.first_contract_date, date(2017, 1, 1))
|
||||
|
||||
def test_current_contract_stage_change(self):
|
||||
today = date.today()
|
||||
contract = self.create_contract('open', 'normal', today + relativedelta(day=1), today + relativedelta(day=31))
|
||||
self.assertEqual(self.employee.contract_id, contract)
|
||||
|
||||
draft_contract = self.create_contract('draft', 'normal', today + relativedelta(months=1, day=1), today + relativedelta(months=1, day=31))
|
||||
draft_contract.state = 'open'
|
||||
self.assertEqual(self.employee.contract_id, draft_contract)
|
||||
|
||||
draft_contract.state = 'draft'
|
||||
self.assertEqual(self.employee.contract_id, contract)
|
||||
|
||||
def test_copy_employee_contract_create(self):
|
||||
contract = self.create_contract('open', 'normal', date(2018, 1, 1), date(2018, 1, 2))
|
||||
duplicate_employee = self.employee.copy()
|
||||
self.assertNotEqual(duplicate_employee.contract_id, contract)
|
||||
|
||||
def test_contract_calendar_update(self):
|
||||
"""
|
||||
Ensure the employee's working schedule updates after modifying them on
|
||||
their contract, as well as well as the working schedule linked to the
|
||||
employee's leaves iff they fall under the active contract duration.
|
||||
"""
|
||||
contract1 = self.create_contract('close', 'done', date(2024, 1, 1), date(2024, 5, 31))
|
||||
contract2 = self.create_contract('open', 'normal', date(2024, 6, 1))
|
||||
|
||||
calendar1 = contract1.resource_calendar_id
|
||||
calendar2 = self.env['resource.calendar'].create({'name': 'Test Schedule'})
|
||||
|
||||
leave1 = self.env['resource.calendar.leaves'].create({
|
||||
'name': 'Sick day',
|
||||
'resource_id': self.employee.resource_id.id,
|
||||
'calendar_id': calendar1.id,
|
||||
'date_from': datetime(2024, 5, 2, 8, 0),
|
||||
'date_to': datetime(2024, 5, 2, 17, 0),
|
||||
})
|
||||
leave2 = self.env['resource.calendar.leaves'].create({
|
||||
'name': 'Sick again',
|
||||
'resource_id': self.employee.resource_id.id,
|
||||
'calendar_id': calendar1.id,
|
||||
'date_from': datetime(2024, 7, 5, 8, 0),
|
||||
'date_to': datetime(2024, 7, 5, 17, 0),
|
||||
})
|
||||
|
||||
contract2.resource_calendar_id = calendar2
|
||||
|
||||
self.assertEqual(
|
||||
self.employee.resource_calendar_id,
|
||||
calendar2,
|
||||
"Employee calendar should update",
|
||||
)
|
||||
self.assertEqual(
|
||||
leave1.calendar_id,
|
||||
calendar1,
|
||||
"Leave under previous calendar should not update",
|
||||
)
|
||||
self.assertEqual(
|
||||
leave2.calendar_id,
|
||||
calendar2,
|
||||
"Leave under active contract should update",
|
||||
)
|
||||
|
||||
def test_running_contract_updates_employee_job_info(self):
|
||||
employee = self.env['hr.employee'].create({
|
||||
'name': 'John Doe'
|
||||
})
|
||||
job = self.env['hr.job'].create({
|
||||
'name': 'Software dev'
|
||||
})
|
||||
department = self.env['hr.department'].create({
|
||||
'name': 'R&D'
|
||||
})
|
||||
|
||||
contract_form = Form(self.env['hr.contract'].create({
|
||||
'name': 'Contract',
|
||||
'employee_id': employee.id,
|
||||
'hr_responsible_id': self.env.uid,
|
||||
'job_id': job.id,
|
||||
'department_id': department.id,
|
||||
'wage': 1,
|
||||
}))
|
||||
|
||||
contract_form.save()
|
||||
self.assertFalse(employee.job_id)
|
||||
self.assertFalse(employee.job_title)
|
||||
self.assertFalse(employee.department_id)
|
||||
|
||||
contract_form.state = 'open'
|
||||
contract_form.save()
|
||||
self.assertEqual(contract_form.job_id, employee.job_id)
|
||||
self.assertEqual(contract_form.job_id.name, employee.job_title)
|
||||
self.assertEqual(contract_form.department_id, employee.department_id)
|
||||
|
|
@ -0,0 +1,68 @@
|
|||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from datetime import datetime
|
||||
|
||||
from .common import TestContractCommon
|
||||
|
||||
|
||||
class TestHrEmployee(TestContractCommon):
|
||||
|
||||
def create_contract(self, state, kanban_state, start, end=None):
|
||||
return self.env['hr.contract'].create({
|
||||
'name': 'Contract',
|
||||
'employee_id': self.employee.id,
|
||||
'state': state,
|
||||
'kanban_state': kanban_state,
|
||||
'wage': 1,
|
||||
'date_start': start,
|
||||
'date_end': end,
|
||||
})
|
||||
|
||||
def test_employee_first_contract_date_base_case(self):
|
||||
'''
|
||||
Test if when a contract is attached to an employee, the
|
||||
first_contract_date is updated accordingly.
|
||||
'''
|
||||
start = datetime.strptime('2015-11-01', '%Y-%m-%d').date()
|
||||
self.create_contract('open', 'normal', start)
|
||||
self.assertEqual(
|
||||
self.employee.first_contract_date, start,
|
||||
'The first_contract_date should be the start date of the contract.'
|
||||
)
|
||||
|
||||
def test_employee_first_contract_date_archived_contract(self):
|
||||
'''
|
||||
Test if when a contract is attached to an employee, the
|
||||
first_contract_date is updated accordingly when archived.
|
||||
'''
|
||||
start = datetime.strptime('2015-11-01', '%Y-%m-%d').date()
|
||||
contract = self.create_contract('open', 'normal', start)
|
||||
self.assertEqual(
|
||||
self.employee.first_contract_date, start,
|
||||
'The first_contract_date should be the start date of the contract.',
|
||||
)
|
||||
contract.action_archive()
|
||||
self.assertEqual(
|
||||
self.employee.first_contract_date, False,
|
||||
'The first_contract_date should be False when the contract is archived. '
|
||||
'Because no active contract is attached to the employee.',
|
||||
)
|
||||
|
||||
def test_employee_first_contract_date_multiple_contracts(self):
|
||||
'''
|
||||
Test if when multiple contracts are attached to an employee, the
|
||||
first_contract_date is updated accordingly.
|
||||
'''
|
||||
start1 = datetime.strptime('2015-11-01', '%Y-%m-%d').date()
|
||||
start2 = datetime.strptime('2016-11-01', '%Y-%m-%d').date()
|
||||
contract1 = self.create_contract('open', 'normal', start1)
|
||||
self.create_contract('draft', 'normal', start2)
|
||||
self.assertEqual(
|
||||
self.employee.first_contract_date, start1,
|
||||
'The first_contract_date should be the start date of the first contract.',
|
||||
)
|
||||
contract1.action_archive()
|
||||
self.assertEqual(
|
||||
self.employee.first_contract_date, start2,
|
||||
'The first_contract_date should be the start date of the second contract.',
|
||||
)
|
||||
|
|
@ -0,0 +1,109 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
from datetime import date, datetime
|
||||
from pytz import utc, timezone
|
||||
|
||||
from odoo.addons.resource.models.resource import Intervals, sum_intervals
|
||||
from odoo.fields import Date
|
||||
|
||||
from .common import TestContractCommon
|
||||
|
||||
class TestResource(TestContractCommon):
|
||||
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
super(TestResource, cls).setUpClass()
|
||||
cls.calendar_richard = cls.env['resource.calendar'].create({'name': 'Calendar of Richard'})
|
||||
cls.employee.resource_calendar_id = cls.calendar_richard
|
||||
|
||||
cls.calendar_35h = cls.env['resource.calendar'].create({
|
||||
'name': '35h calendar',
|
||||
'attendance_ids': [
|
||||
(0, 0, {'name': 'Monday Morning', 'dayofweek': '0', 'hour_from': 8, 'hour_to': 12, 'day_period': 'morning'}),
|
||||
(0, 0, {'name': 'Monday Evening', 'dayofweek': '0', 'hour_from': 13, 'hour_to': 16, 'day_period': 'afternoon'}),
|
||||
(0, 0, {'name': 'Tuesday Morning', 'dayofweek': '1', 'hour_from': 8, 'hour_to': 12, 'day_period': 'morning'}),
|
||||
(0, 0, {'name': 'Tuesday Evening', 'dayofweek': '1', 'hour_from': 13, 'hour_to': 16, 'day_period': 'afternoon'}),
|
||||
(0, 0, {'name': 'Wednesday Morning', 'dayofweek': '2', 'hour_from': 8, 'hour_to': 12, 'day_period': 'morning'}),
|
||||
(0, 0, {'name': 'Wednesday Evening', 'dayofweek': '2', 'hour_from': 13, 'hour_to': 16, 'day_period': 'afternoon'}),
|
||||
(0, 0, {'name': 'Thursday Morning', 'dayofweek': '3', 'hour_from': 8, 'hour_to': 12, 'day_period': 'morning'}),
|
||||
(0, 0, {'name': 'Thursday Evening', 'dayofweek': '3', 'hour_from': 13, 'hour_to': 16, 'day_period': 'afternoon'}),
|
||||
(0, 0, {'name': 'Friday Morning', 'dayofweek': '4', 'hour_from': 8, 'hour_to': 12, 'day_period': 'morning'}),
|
||||
(0, 0, {'name': 'Friday Evening', 'dayofweek': '4', 'hour_from': 13, 'hour_to': 16, 'day_period': 'afternoon'})
|
||||
],
|
||||
})
|
||||
cls.calendar_35h._onchange_hours_per_day() # update hours/day
|
||||
|
||||
cls.contract_cdd = cls.env['hr.contract'].create({
|
||||
'date_start': Date.to_date('2021-09-01'),
|
||||
'date_end': Date.to_date('2021-10-31'),
|
||||
'name': 'First CDD Contract for Richard',
|
||||
'resource_calendar_id': cls.calendar_35h.id,
|
||||
'wage': 5000.0,
|
||||
'employee_id': cls.employee.id,
|
||||
'state': 'open',
|
||||
})
|
||||
cls.contract_cdi = cls.env['hr.contract'].create({
|
||||
'date_start': Date.to_date('2021-11-01'),
|
||||
'name': 'CDI Contract for Richard',
|
||||
'resource_calendar_id': cls.calendar_richard.id,
|
||||
'wage': 5000.0,
|
||||
'employee_id': cls.employee.id,
|
||||
'state': 'draft',
|
||||
'kanban_state': 'done',
|
||||
})
|
||||
|
||||
def test_calendars_validity_within_period(self):
|
||||
tz = timezone(self.employee.tz)
|
||||
calendars = self.employee.resource_id._get_calendars_validity_within_period(
|
||||
tz.localize(datetime(2021, 10, 1, 0, 0, 0)),
|
||||
tz.localize(datetime(2021, 12, 1, 0, 0, 0)),
|
||||
)
|
||||
interval_35h = Intervals([(
|
||||
tz.localize(datetime(2021, 10, 1, 0, 0, 0)),
|
||||
tz.localize(datetime.combine(date(2021, 10, 31), datetime.max.time())),
|
||||
self.env['resource.calendar.attendance']
|
||||
)])
|
||||
interval_40h = Intervals([(
|
||||
tz.localize(datetime(2021, 11, 1, 0, 0, 0)),
|
||||
tz.localize(datetime(2021, 12, 1, 0, 0, 0)),
|
||||
self.env['resource.calendar.attendance']
|
||||
)])
|
||||
|
||||
self.assertEqual(1, len(calendars), "The dict returned by calendars validity should only have 1 entry")
|
||||
self.assertEqual(2, len(calendars[self.employee.resource_id.id]), "Jean should only have one calendar")
|
||||
richard_entries = calendars[self.employee.resource_id.id]
|
||||
for calendar in richard_entries:
|
||||
self.assertTrue(calendar in (self.calendar_35h | self.calendar_richard), "Each calendar should be listed")
|
||||
if calendar == self.calendar_35h:
|
||||
self.assertFalse(richard_entries[calendar] - interval_35h, "Interval 35h should cover all calendar 35h validity")
|
||||
self.assertFalse(interval_35h - richard_entries[calendar], "Calendar 35h validity should cover all interval 35h")
|
||||
elif calendar == self.calendar_richard:
|
||||
self.assertFalse(richard_entries[calendar] - interval_40h, "Interval 40h should cover all calendar 40h validity")
|
||||
self.assertFalse(interval_40h - richard_entries[calendar], "Calendar 40h validity should cover all interval 40h")
|
||||
|
||||
def test_queries(self):
|
||||
employees_test = self.env['hr.employee'].create([{
|
||||
'name': 'Employee ' + str(i),
|
||||
} for i in range(0, 50)])
|
||||
for emp in employees_test:
|
||||
new_contract = self.contract_cdd.copy()
|
||||
new_contract.employee_id = emp
|
||||
new_contract.state = 'open'
|
||||
new_contract = self.contract_cdi.copy()
|
||||
new_contract.employee_id = emp
|
||||
new_contract.state = 'draft'
|
||||
new_contract.kanban_state = 'done'
|
||||
|
||||
start = utc.localize(datetime(2021, 9, 1, 0, 0, 0))
|
||||
end = utc.localize(datetime(2021, 11, 30, 23, 59, 59))
|
||||
with self.assertQueryCount(15):
|
||||
work_intervals, _ = (employees_test | self.employee).resource_id._get_valid_work_intervals(start, end)
|
||||
|
||||
self.assertEqual(len(work_intervals), 51)
|
||||
|
||||
def test_get_valid_work_intervals(self):
|
||||
start = timezone(self.employee.tz).localize(datetime(2021, 10, 24, 2, 0, 0))
|
||||
end = timezone(self.employee.tz).localize(datetime(2021, 11, 6, 23, 59, 59))
|
||||
work_intervals, _ = self.employee.resource_id._get_valid_work_intervals(start, end)
|
||||
sum_work_intervals = sum_intervals(work_intervals[self.employee.resource_id.id])
|
||||
self.assertEqual(75, sum_work_intervals, "Sum of the work intervals for the employee should be 35h+40h = 75h")
|
||||
Loading…
Add table
Add a link
Reference in a new issue