From 662657f44bf494e6b7eb4248e025ef76c788bf9c Mon Sep 17 00:00:00 2001 From: jbm-odoo Date: Wed, 31 Oct 2018 14:11:54 +0000 Subject: [PATCH] [IMP] hr_holidays: Re-introduce complete tests suite The tests have been detroyed while merging a refactoring for 12.0. This commit reintroduces unit tests to checks each business cases from "The Flow" into python tests. closes odoo/odoo#28323 --- addons/hr_holidays/tests/__init__.py | 1 + .../hr_holidays/tests/test_access_rights.py | 64 ++++- .../hr_holidays/tests/test_holidays_flow.py | 252 +++++------------- .../hr_holidays/tests/test_hr_leave_type.py | 10 + .../hr_holidays/tests/test_leave_requests.py | 152 +++++++++++ 5 files changed, 291 insertions(+), 188 deletions(-) create mode 100644 addons/hr_holidays/tests/test_leave_requests.py diff --git a/addons/hr_holidays/tests/__init__.py b/addons/hr_holidays/tests/__init__.py index c8c2b4a438b..ba8bdaabb15 100644 --- a/addons/hr_holidays/tests/__init__.py +++ b/addons/hr_holidays/tests/__init__.py @@ -5,3 +5,4 @@ from . import test_access_rights from . import test_holidays_flow from . import test_hr_leave_type from . import test_accrual_allocations +from . import test_leave_requests diff --git a/addons/hr_holidays/tests/test_access_rights.py b/addons/hr_holidays/tests/test_access_rights.py index cf4e8f76ad8..ca651a69010 100644 --- a/addons/hr_holidays/tests/test_access_rights.py +++ b/addons/hr_holidays/tests/test_access_rights.py @@ -6,7 +6,7 @@ from dateutil.relativedelta import relativedelta from odoo import tests from odoo.addons.hr_holidays.tests.common import TestHrHolidaysBase -from odoo.exceptions import AccessError, UserError +from odoo.exceptions import AccessError, ValidationError, UserError from odoo.tools import mute_logger @@ -117,6 +117,24 @@ class TestLeavesRights(TestHrHolidaysBase): with self.assertRaises(AccessError): other_leave.sudo(self.user_employee_id).write({'name': 'Crocodile Dundee is my man'}) + # ---------------------------------------- + # Creation + # ---------------------------------------- + + @mute_logger('odoo.models.unlink', 'odoo.addons.mail.models.mail_mail') + def test_leave_creation_for_other_user(self): + """ Employee cannot creates a leave request for another employee """ + HolidaysEmployeeGroup = self.env['hr.leave'].sudo(self.user_employee_id) + with self.assertRaises(AccessError): + HolidaysEmployeeGroup.create({ + 'name': 'Hol10', + 'employee_id': self.employee_hruser_id, + 'holiday_status_id': self.leave_type.id, + 'date_from': (datetime.today() - relativedelta(days=1)), + 'date_to': datetime.today(), + 'number_of_days': 1, + }) + # ---------------------------------------- # Reset # ---------------------------------------- @@ -137,7 +155,7 @@ class TestLeavesRights(TestHrHolidaysBase): @mute_logger('odoo.models.unlink', 'odoo.addons.mail.models.mail_mail') def test_leave_reset_by_manager_other(self): - """ Manager may not reset other leaves """ + """ Manager may reset other leaves """ self.employee_leave.sudo(self.user_hrmanager).action_draft() @mute_logger('odoo.models.unlink', 'odoo.addons.mail.models.mail_mail') @@ -187,19 +205,23 @@ class TestLeavesRights(TestHrHolidaysBase): @mute_logger('odoo.models.unlink', 'odoo.addons.mail.models.mail_mail') def test_leave_validation_hr_by_manager(self): """ Manager validates hr-only leaves """ + self.assertEqual(self.employee_leave.state, 'confirm') self.employee_leave.sudo(self.user_hrmanager_id).action_approve() + self.assertEqual(self.employee_leave.state, 'validate') @mute_logger('odoo.models.unlink', 'odoo.addons.mail.models.mail_mail') def test_leave_validation_hr_by_officer_department(self): """ Officer validates hr-only leaves for co-workers """ + self.assertEqual(self.employee_leave.state, 'confirm') self.employee_leave.sudo(self.user_hruser).action_approve() + self.assertEqual(self.employee_leave.state, 'validate') @mute_logger('odoo.models.unlink', 'odoo.addons.mail.models.mail_mail') def test_leave_validation_hr_by_officer_no_department(self): """ Officer validates hr-only leaves for workers from no department and with no manager """ self.employee_hruser.write({'department_id': False}) - # TDE FIXME: not sure for this one - # self.employee_leave.sudo(self.user_hruser).action_approve() + with self.assertRaises(AccessError): + self.employee_leave.sudo(self.user_hruser).action_approve() @mute_logger('odoo.models.unlink', 'odoo.addons.mail.models.mail_mail') def test_leave_validation_hr_by_officer_other_department_with_manager(self): @@ -207,6 +229,7 @@ class TestLeavesRights(TestHrHolidaysBase): self.employee_hruser.write({'department_id': self.hr_dept.id}) with self.assertRaises(AccessError): self.employee_leave.sudo(self.user_hruser).action_approve() + self.assertEqual(self.employee_leave.state, 'confirm') @mute_logger('odoo.models.unlink', 'odoo.addons.mail.models.mail_mail') def test_leave_validation_hr_by_officer_other_department_wo_manager(self): @@ -214,6 +237,7 @@ class TestLeavesRights(TestHrHolidaysBase): self.employee_hruser.write({'department_id': self.hr_dept.id}) with self.assertRaises(AccessError): self.employee_leave.sudo(self.user_hruser).action_approve() + self.assertEqual(self.employee_leave.state, 'confirm') @mute_logger('odoo.models.unlink', 'odoo.addons.mail.models.mail_mail') def test_leave_validation_hr_by_officer_other_department_manager(self): @@ -221,7 +245,9 @@ class TestLeavesRights(TestHrHolidaysBase): self.employee_hruser.write({'department_id': self.hr_dept.id}) self.employee_leave.sudo().department_id.write({'manager_id': self.employee_hruser.id}) + self.assertEqual(self.employee_leave.state, 'confirm') self.employee_leave.sudo(self.user_hruser).action_approve() + self.assertEqual(self.employee_leave.state, 'validate') @mute_logger('odoo.models.unlink', 'odoo.addons.mail.models.mail_mail') def test_leave_validation_hr_by_user(self): @@ -232,6 +258,36 @@ class TestLeavesRights(TestHrHolidaysBase): with self.assertRaises(UserError): self.employee_leave.sudo(self.user_employee_id).write({'state': 'validate'}) + @mute_logger('odoo.models.unlink', 'odoo.addons.mail.models.mail_mail') + def test_leave_validate_by_manager(self): + """ Manager (who has no manager) validate its own leaves """ + manager_leave = self.env['hr.leave'].sudo(self.user_hrmanager_id).create({ + 'name': 'Hol manager', + 'holiday_status_id': self.leave_type.id, + 'employee_id': self.employee_hrmanager_id, + 'date_from': (datetime.today() + relativedelta(days=15)), + 'date_to': (datetime.today() + relativedelta(days=16)), + 'number_of_days': 1, + }) + self.assertEqual(manager_leave.state, 'confirm') + manager_leave.action_approve() + self.assertEqual(manager_leave.state, 'validate') + + @mute_logger('odoo.models.unlink', 'odoo.addons.mail.models.mail_mail') + def test_leave_validate_by_manager_2(self): + """ Manager (who has also a manager) validate its own leaves """ + manager_leave2 = self.env['hr.leave'].sudo(self.user_hrmanager_2_id).create({ + 'name': 'Hol manager2', + 'holiday_status_id': self.leave_type.id, + 'employee_id': self.employee_hrmanager_2_id, + 'date_from': (datetime.today() + relativedelta(days=15)), + 'date_to': (datetime.today() + relativedelta(days=16)), + 'number_of_days': 1, + }) + self.assertEqual(manager_leave2.state, 'confirm') + manager_leave2.action_approve() + self.assertEqual(manager_leave2.state, 'validate') + # ---------------------------------------- # Validation: one validation, manager # ---------------------------------------- diff --git a/addons/hr_holidays/tests/test_holidays_flow.py b/addons/hr_holidays/tests/test_holidays_flow.py index 51bcafe049c..08e1be1b20d 100644 --- a/addons/hr_holidays/tests/test_holidays_flow.py +++ b/addons/hr_holidays/tests/test_holidays_flow.py @@ -13,8 +13,69 @@ from odoo.addons.hr_holidays.tests.common import TestHrHolidaysBase class TestHolidaysFlow(TestHrHolidaysBase): @mute_logger('odoo.addons.base.models.ir_model', 'odoo.models') - def test_00_leave_request_flow(self): - """ Testing leave request flow """ + def test_00_leave_request_flow_unlimited(self): + """ Testing leave request flow: unlimited type of leave request """ + Requests = self.env['hr.leave'] + HolidaysStatus = self.env['hr.leave.type'] + + # HrManager creates some holiday statuses + HolidayStatusManagerGroup = HolidaysStatus.sudo(self.user_hrmanager_id) + HolidayStatusManagerGroup.create({ + 'name': 'WithMeetingType', + 'allocation_type': 'no', + 'categ_id': self.env['calendar.event.type'].sudo(self.user_hrmanager_id).create({'name': 'NotLimitedMeetingType'}).id + }) + self.holidays_status_hr = HolidayStatusManagerGroup.create({ + 'name': 'NotLimitedHR', + 'allocation_type': 'no', + 'validation_type': 'hr', + }) + self.holidays_status_manager = HolidayStatusManagerGroup.create({ + 'name': 'NotLimitedManager', + 'allocation_type': 'no', + 'validation_type': 'manager', + }) + + HolidaysEmployeeGroup = Requests.sudo(self.user_employee_id) + + # Employee creates a leave request in a no-limit category hr manager only + hol1_employee_group = HolidaysEmployeeGroup.create({ + 'name': 'Hol11', + 'employee_id': self.employee_emp_id, + 'holiday_status_id': self.holidays_status_hr.id, + 'date_from': (datetime.today() - relativedelta(days=1)), + 'date_to': datetime.today(), + 'number_of_days': 1, + }) + hol1_user_group = hol1_employee_group.sudo(self.user_hruser_id) + hol1_manager_group = hol1_employee_group.sudo(self.user_hrmanager_id) + self.assertEqual(hol1_user_group.state, 'confirm', 'hr_holidays: newly created leave request should be in confirm state') + + # HrUser validates the employee leave request -> should work + hol1_user_group.action_approve() + self.assertEqual(hol1_manager_group.state, 'validate', 'hr_holidays: validated leave request should be in validate state') + + # Employee creates a leave request in a no-limit category department manager only + hol12_employee_group = HolidaysEmployeeGroup.create({ + 'name': 'Hol12', + 'employee_id': self.employee_emp_id, + 'holiday_status_id': self.holidays_status_manager.id, + 'date_from': (datetime.today() + relativedelta(days=12)), + 'date_to': (datetime.today() + relativedelta(days=13)), + 'number_of_days': 1, + }) + hol12_user_group = hol12_employee_group.sudo(self.user_hruser_id) + hol12_manager_group = hol12_employee_group.sudo(self.user_hrmanager_id) + self.assertEqual(hol12_user_group.state, 'confirm', 'hr_holidays: newly created leave request should be in confirm state') + + # HrManager validate the employee leave request + hol12_manager_group.action_approve() + self.assertEqual(hol1_user_group.state, 'validate', 'hr_holidays: validates leave request should be in validate state') + + + @mute_logger('odoo.addons.base.models.ir_model', 'odoo.models') + def test_01_leave_request_flow_limited(self): + """ Testing leave request flow: limited type of leave request """ Requests = self.env['hr.leave'] Allocations = self.env['hr.leave.allocation'] HolidaysStatus = self.env['hr.leave.type'] @@ -29,13 +90,6 @@ class TestHolidaysFlow(TestHrHolidaysBase): self.assertEqual(holiday_status.virtual_remaining_leaves, vrl, 'hr_holidays: wrong type days computation') - # HrUser creates some holiday statuses -> crash because only HrManagers should do this - with self.assertRaises(AccessError): - HolidaysStatus.sudo(self.user_hruser_id).create({ - 'name': 'UserCheats', - 'allocation_type': 'no', - }) - # HrManager creates some holiday statuses HolidayStatusManagerGroup = HolidaysStatus.sudo(self.user_hrmanager_id) HolidayStatusManagerGroup.create({ @@ -43,111 +97,19 @@ class TestHolidaysFlow(TestHrHolidaysBase): 'allocation_type': 'no', 'categ_id': self.env['calendar.event.type'].sudo(self.user_hrmanager_id).create({'name': 'NotLimitedMeetingType'}).id }) - self.holidays_status_1 = HolidayStatusManagerGroup.create({ - 'name': 'NotLimitedHR', - 'allocation_type': 'no', - 'validation_type': 'hr', - }) - self.holidays_status_2 = HolidayStatusManagerGroup.create({ + + self.holidays_status_limited = HolidayStatusManagerGroup.create({ 'name': 'Limited', 'allocation_type': 'fixed', 'validation_type': 'both', }) - self.holidays_status_3 = HolidayStatusManagerGroup.create({ - 'name': 'NotLimitedManager', - 'allocation_type': 'no', - 'validation_type': 'manager', - }) - self.holiday_status_4 = HolidayStatusManagerGroup.create({ - 'name': 'TimeNotLimited', - 'allocation_type': 'no', - 'validation_type': 'manager', - 'validity_start': fields.Datetime.from_string('2017-01-01 00:00:00'), - 'validity_stop': fields.Datetime.from_string('2017-06-01 00:00:00'), - }) - - # -------------------------------------------------- - # Case1: unlimited type of leave request - # -------------------------------------------------- - - # Employee creates a leave request for another employee -> should crash HolidaysEmployeeGroup = Requests.sudo(self.user_employee_id) - Requests.search([('name', '=', 'Hol10')]).unlink() - - # Employee creates a leave request in a no-limit category hr manager only - hol1_employee_group = HolidaysEmployeeGroup.create({ - 'name': 'Hol11', - 'employee_id': self.employee_emp_id, - 'holiday_status_id': self.holidays_status_1.id, - 'date_from': (datetime.today() - relativedelta(days=1)), - 'date_to': datetime.today(), - 'number_of_days': 1, - }) - hol1_user_group = hol1_employee_group.sudo(self.user_hruser_id) - hol1_manager_group = hol1_employee_group.sudo(self.user_hrmanager_id) - self.assertEqual(hol1_user_group.state, 'confirm', 'hr_holidays: newly created leave request should be in confirm state') - - # Employee validates its leave request -> should not work - self.assertEqual(hol1_manager_group.state, 'confirm', 'hr_holidays: employee should not be able to validate its own leave request') - - # HrUser validates the employee leave request -> should work - hol1_user_group.action_approve() - self.assertEqual(hol1_manager_group.state, 'validate', 'hr_holidays: validated leave request should be in validate state') - - # Employee creates a leave request in a no-limit category department manager only - hol12_employee_group = HolidaysEmployeeGroup.create({ - 'name': 'Hol12', - 'employee_id': self.employee_emp_id, - 'holiday_status_id': self.holidays_status_3.id, - 'date_from': (datetime.today() + relativedelta(days=12)), - 'date_to': (datetime.today() + relativedelta(days=13)), - 'number_of_days': 1, - }) - hol12_user_group = hol12_employee_group.sudo(self.user_hruser_id) - hol12_manager_group = hol12_employee_group.sudo(self.user_hrmanager_id) - self.assertEqual(hol12_user_group.state, 'confirm', 'hr_holidays: newly created leave request should be in confirm state') - - # Employee validates its leave request -> should not work - self.assertEqual(hol12_user_group.state, 'confirm', 'hr_holidays: employee should not be able to validate its own leave request') - - # HrManager validate the employee leave request - hol12_manager_group.action_approve() - self.assertEqual(hol1_user_group.state, 'validate', 'hr_holidays: validates leave request should be in validate state') - - # -------------------------------------------------- - # Case2: limited type of leave request - # -------------------------------------------------- - - # Employee creates a new leave request at the same time -> crash, avoid interlapping - with self.assertRaises(ValidationError): - HolidaysEmployeeGroup.create({ - 'name': 'Hol21', - 'employee_id': self.employee_emp_id, - 'holiday_status_id': self.holidays_status_1.id, - 'date_from': (datetime.today() - relativedelta(days=1)).strftime('%Y-%m-%d %H:%M'), - 'date_to': datetime.today(), - 'number_of_days': 1, - }) - - # Employee creates a leave request in a limited category -> crash, not enough days left - with self.assertRaises(ValidationError): - HolidaysEmployeeGroup.create({ - 'name': 'Hol22', - 'employee_id': self.employee_emp_id, - 'holiday_status_id': self.holidays_status_2.id, - 'date_from': (datetime.today() + relativedelta(days=1)).strftime('%Y-%m-%d %H:%M'), - 'date_to': (datetime.today() + relativedelta(days=2)), - 'number_of_days': 1, - }) - - # Clean transaction - Requests.search([('name', 'in', ['Hol21', 'Hol22'])]).unlink() # HrUser allocates some leaves to the employee aloc1_user_group = Allocations.sudo(self.user_hruser_id).create({ 'name': 'Days for limited category', 'employee_id': self.employee_emp_id, - 'holiday_status_id': self.holidays_status_2.id, + 'holiday_status_id': self.holidays_status_limited.id, 'number_of_days': 2, }) # HrUser validates the first step @@ -156,14 +118,14 @@ class TestHolidaysFlow(TestHrHolidaysBase): # HrManager validates the second step aloc1_user_group.sudo(self.user_hrmanager_id).action_validate() # Checks Employee has effectively some days left - hol_status_2_employee_group = self.holidays_status_2.sudo(self.user_employee_id) + hol_status_2_employee_group = self.holidays_status_limited.sudo(self.user_employee_id) _check_holidays_status(hol_status_2_employee_group, 2.0, 0.0, 2.0, 2.0) # Employee creates a leave request in the limited category, now that he has some days left hol2 = HolidaysEmployeeGroup.create({ 'name': 'Hol22', 'employee_id': self.employee_emp_id, - 'holiday_status_id': self.holidays_status_2.id, + 'holiday_status_id': self.holidays_status_limited.id, 'date_from': (datetime.today() + relativedelta(days=2)).strftime('%Y-%m-%d %H:%M'), 'date_to': (datetime.today() + relativedelta(days=3)), 'number_of_days': 1, @@ -201,15 +163,6 @@ class TestHolidaysFlow(TestHrHolidaysBase): self.assertEqual(hol2.state, 'draft', 'hr_holidays: resetting should lead to draft state') - # HrManager changes the date and put too much days -> crash when confirming - hol2_manager_group.write({ - 'date_from': (datetime.today() + relativedelta(days=4)).strftime('%Y-%m-%d %H:%M'), - 'date_to': (datetime.today() + relativedelta(days=7)), - 'number_of_days': 4, - }) - with self.assertRaises(ValidationError): - hol2_manager_group.action_confirm() - employee_id = self.ref('hr.employee_admin') # cl can be of maximum 20 days for employee_admin hol3_status = self.env.ref('hr_holidays.holiday_status_cl').with_context(employee_id=employee_id) @@ -236,75 +189,6 @@ class TestHolidaysFlow(TestHrHolidaysBase): # Check left days for casual leave: 19 days left _check_holidays_status(hol3_status, 20.0, 1.0, 19.0, 19.0) - Requests.create({ - 'name': 'Sick Leave', - 'holiday_status_id': self.holiday_status_4.id, - 'date_from': fields.Datetime.from_string('2017-03-03 06:00:00'), - 'date_to': fields.Datetime.from_string('2017-03-11 19:00:00'), - 'employee_id': employee_id, - 'number_of_days': 1, - }).unlink() - - with self.assertRaises(ValidationError): - Requests.create({ - 'name': 'Sick Leave', - 'holiday_status_id': self.holiday_status_4.id, - 'date_from': fields.Datetime.from_string('2017-07-03 06:00:00'), - 'date_to': fields.Datetime.from_string('2017-07-11 19:00:00'), - 'employee_id': employee_id, - 'number_of_days': 1, - }) - - hol41 = HolidaysEmployeeGroup.create({ - 'name': 'Hol41', - 'employee_id': self.employee_emp_id, - 'holiday_status_id': self.holidays_status_1.id, - 'date_from': (datetime.today() + relativedelta(days=9)).strftime('%Y-%m-%d %H:%M'), - 'date_to': (datetime.today() + relativedelta(days=10)), - 'number_of_days': 1, - }) - - # A simple user should be able to reset it's own leave - hol41.action_draft() - hol41.unlink() - - hol42 = Requests.sudo(self.user_hrmanager_id).create({ - 'name': 'Hol41', - 'employee_id': self.employee_hrmanager_id, - 'holiday_status_id': self.holidays_status_1.id, - 'date_from': (datetime.today() + relativedelta(days=9)).strftime('%Y-%m-%d %H:%M'), - 'date_to': (datetime.today() + relativedelta(days=10)), - 'number_of_days': 1, - }) - - # A manager should be able to reset someone else's leave - hol42.action_draft() - hol42.unlink() - - # Manager should be able to approve it's own leave - hol51 = HolidaysEmployeeGroup.sudo(self.user_hrmanager_2_id).create({ - 'name': 'Hol51', - 'employee_id': self.employee_hrmanager_2_id, - 'holiday_status_id': self.holidays_status_1.id, - 'date_from': (datetime.today() + relativedelta(days=15)).strftime('%Y-%m-%d %H:%M'), - 'date_to': (datetime.today() + relativedelta(days=16)), - 'number_of_days': 1, - }) - - hol51.action_approve() - - # Unless there is not manager above - hol52 = HolidaysEmployeeGroup.sudo(self.user_hrmanager_id).create({ - 'name': 'Hol52', - 'employee_id': self.employee_hrmanager_id, - 'holiday_status_id': self.holidays_status_1.id, - 'date_from': (datetime.today() + relativedelta(days=15)).strftime('%Y-%m-%d %H:%M'), - 'date_to': (datetime.today() + relativedelta(days=16)), - 'number_of_days': 1, - }) - - hol52.action_approve() - def test_10_leave_summary_reports(self): # Print the HR Holidays(Summary Department) Report through the wizard ctx = { diff --git a/addons/hr_holidays/tests/test_hr_leave_type.py b/addons/hr_holidays/tests/test_hr_leave_type.py index 495d1aa2e4b..dfe1b77713d 100644 --- a/addons/hr_holidays/tests/test_hr_leave_type.py +++ b/addons/hr_holidays/tests/test_hr_leave_type.py @@ -4,6 +4,8 @@ from datetime import datetime from dateutil.relativedelta import relativedelta +from odoo.exceptions import AccessError + from odoo.addons.hr_holidays.tests.common import TestHrHolidaysBase @@ -30,3 +32,11 @@ class TestHrLeaveType(TestHrHolidaysBase): self.env['resource.calendar.leaves'].search([('holiday_id', '=', leave_1.id)]).time_type, 'leave' ) + + def test_type_creation_right(self): + # HrUser creates some holiday statuses -> crash because only HrManagers should do this + with self.assertRaises(AccessError): + self.env['hr.leave.type'].sudo(self.user_hruser_id).create({ + 'name': 'UserCheats', + 'allocation_type': 'no', + }) diff --git a/addons/hr_holidays/tests/test_leave_requests.py b/addons/hr_holidays/tests/test_leave_requests.py new file mode 100644 index 00000000000..8dad86eae39 --- /dev/null +++ b/addons/hr_holidays/tests/test_leave_requests.py @@ -0,0 +1,152 @@ +# -*- coding: utf-8 -*- +# Part of Odoo. See LICENSE file for full copyright and licensing details. +from datetime import datetime +from dateutil.relativedelta import relativedelta + +from odoo import fields +from odoo.exceptions import ValidationError +from odoo.tools import mute_logger + +from odoo.addons.hr_holidays.tests.common import TestHrHolidaysBase + +class TestLeaveRequests(TestHrHolidaysBase): + + def _check_holidays_status(self, holiday_status, ml, lt, rl, vrl): + self.assertEqual(holiday_status.max_leaves, ml, + 'hr_holidays: wrong type days computation') + self.assertEqual(holiday_status.leaves_taken, lt, + 'hr_holidays: wrong type days computation') + self.assertEqual(holiday_status.remaining_leaves, rl, + 'hr_holidays: wrong type days computation') + self.assertEqual(holiday_status.virtual_remaining_leaves, vrl, + 'hr_holidays: wrong type days computation') + + def setUp(self): + super(TestLeaveRequests, self).setUp() + + # Make sure we have the rights to create, validate and delete the leaves, leave types and allocations + LeaveType = self.env['hr.leave.type'].sudo(self.user_hrmanager_id).with_context(tracking_disable=True) + + self.holidays_type_1 = LeaveType.create({ + 'name': 'NotLimitedHR', + 'allocation_type': 'no', + 'validation_type': 'hr', + }) + self.holidays_type_2 = LeaveType.create({ + 'name': 'Limited', + 'allocation_type': 'fixed', + 'validation_type': 'hr', + }) + self.holidays_type_3 = LeaveType.create({ + 'name': 'TimeNotLimited', + 'allocation_type': 'no', + 'validation_type': 'manager', + 'validity_start': fields.Datetime.from_string('2017-01-01 00:00:00'), + 'validity_stop': fields.Datetime.from_string('2017-06-01 00:00:00'), + }) + + self.set_employee_create_date(self.employee_emp_id, '2010-02-03 00:00:00') + self.set_employee_create_date(self.employee_hruser_id, '2010-02-03 00:00:00') + + def set_employee_create_date(self, id, newdate): + """ This method is a hack in order to be able to define/redefine the create_date + of the employees. + This is done in SQL because ORM does not allow to write onto the create_date field. + """ + self.env.cr.execute(""" + UPDATE + hr_employee + SET create_date = '%s' + WHERE id = %s + """ % (newdate, id)) + + @mute_logger('odoo.models.unlink', 'odoo.addons.mail.models.mail_mail') + def test_overlapping_requests(self): + """ Employee cannot create a new leave request at the same time, avoid interlapping """ + self.env['hr.leave'].sudo(self.user_employee_id).create({ + 'name': 'Hol11', + 'employee_id': self.employee_emp_id, + 'holiday_status_id': self.holidays_type_1.id, + 'date_from': (datetime.today() - relativedelta(days=1)), + 'date_to': datetime.today(), + 'number_of_days': 1, + }) + + with self.assertRaises(ValidationError): + self.env['hr.leave'].sudo(self.user_employee_id).create({ + 'name': 'Hol21', + 'employee_id': self.employee_emp_id, + 'holiday_status_id': self.holidays_type_1.id, + 'date_from': (datetime.today() - relativedelta(days=1)), + 'date_to': datetime.today(), + 'number_of_days': 1, + }) + + @mute_logger('odoo.models.unlink', 'odoo.addons.mail.models.mail_mail') + def test_limited_type_no_days(self): + """ Employee creates a leave request in a limited category but has not enough days left """ + + with self.assertRaises(ValidationError): + self.env['hr.leave'].sudo(self.user_employee_id).create({ + 'name': 'Hol22', + 'employee_id': self.employee_emp_id, + 'holiday_status_id': self.holidays_type_2.id, + 'date_from': (datetime.today() + relativedelta(days=1)).strftime('%Y-%m-%d %H:%M'), + 'date_to': (datetime.today() + relativedelta(days=2)), + 'number_of_days': 1, + }) + + @mute_logger('odoo.models.unlink', 'odoo.addons.mail.models.mail_mail') + def test_limited_type_days_left(self): + """ Employee creates a leave request in a limited category and has enough days left """ + aloc1_user_group = self.env['hr.leave.allocation'].sudo(self.user_hruser_id).create({ + 'name': 'Days for limited category', + 'employee_id': self.employee_emp_id, + 'holiday_status_id': self.holidays_type_2.id, + 'number_of_days': 2, + }) + aloc1_user_group.action_approve() + + holiday_status = self.holidays_type_2.sudo(self.user_employee_id) + self._check_holidays_status(holiday_status, 2.0, 0.0, 2.0, 2.0) + + hol = self.env['hr.leave'].sudo(self.user_employee_id).create({ + 'name': 'Hol11', + 'employee_id': self.employee_emp_id, + 'holiday_status_id': self.holidays_type_2.id, + 'date_from': (datetime.today() - relativedelta(days=2)), + 'date_to': datetime.today(), + 'number_of_days': 2, + }) + + holiday_status.invalidate_cache() + self._check_holidays_status(holiday_status, 2.0, 0.0, 2.0, 0.0) + + hol.sudo(self.user_hrmanager_id).action_approve() + + self._check_holidays_status(holiday_status, 2.0, 2.0, 0.0, 0.0) + + @mute_logger('odoo.models.unlink', 'odoo.addons.mail.models.mail_mail') + def test_accrual_validity_time_valid(self): + """ Employee ask leave during a valid validity time """ + self.env['hr.leave'].sudo(self.user_employee_id).create({ + 'name': 'Valid time period', + 'employee_id': self.employee_emp_id, + 'holiday_status_id': self.holidays_type_3.id, + 'date_from': fields.Datetime.from_string('2017-03-03 06:00:00'), + 'date_to': fields.Datetime.from_string('2017-03-11 19:00:00'), + 'number_of_days': 1, + }) + + @mute_logger('odoo.models.unlink', 'odoo.addons.mail.models.mail_mail') + def test_accrual_validity_time_not_valid(self): + """ Employee ask leav during a not valid validity time """ + with self.assertRaises(ValidationError): + self.env['hr.leave'].sudo(self.user_employee_id).create({ + 'name': 'Sick Leave', + 'employee_id': self.employee_emp_id, + 'holiday_status_id': self.holidays_type_3.id, + 'date_from': fields.Datetime.from_string('2017-07-03 06:00:00'), + 'date_to': fields.Datetime.from_string('2017-07-11 19:00:00'), + 'number_of_days': 1, + })