flectra/addons/hr_holidays/tests/test_holidays_flow.py

241 lines
12 KiB
Python
Raw Permalink Normal View History

# -*- coding: utf-8 -*-
2018-01-16 11:34:37 +01:00
# Part of Odoo, Flectra. See LICENSE file for full copyright and licensing details.
from datetime import datetime
from dateutil.relativedelta import relativedelta
2018-01-16 11:34:37 +01:00
from flectra.exceptions import AccessError, ValidationError, UserError
from flectra.tools import mute_logger, test_reports
2018-01-16 11:34:37 +01:00
from flectra.addons.hr_holidays.tests.common import TestHrHolidaysBase
class TestHolidaysFlow(TestHrHolidaysBase):
2018-01-16 11:34:37 +01:00
@mute_logger('flectra.addons.base.ir.ir_model', 'flectra.models')
def test_00_leave_request_flow(self):
""" Testing leave request flow """
Holidays = self.env['hr.holidays']
HolidaysStatus = self.env['hr.holidays.status']
def _check_holidays_status(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')
# 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',
'limit': True,
})
# HrManager creates some holiday statuses
HolidayStatusManagerGroup = HolidaysStatus.sudo(self.user_hrmanager_id)
HolidayStatusManagerGroup.create({
'name': 'WithMeetingType',
'limit': True,
'categ_id': self.env['calendar.event.type'].sudo(self.user_hrmanager_id).create({'name': 'NotLimitedMeetingType'}).id
})
self.holidays_status_1 = HolidayStatusManagerGroup.create({
'name': 'NotLimited',
'limit': True,
})
self.holidays_status_2 = HolidayStatusManagerGroup.create({
'name': 'Limited',
'limit': False,
'double_validation': True,
})
# --------------------------------------------------
# Case1: unlimited type of leave request
# --------------------------------------------------
# Employee creates a leave request for another employee -> should crash
HolidaysEmployeeGroup = Holidays.sudo(self.user_employee_id)
with self.assertRaises(ValidationError):
HolidaysEmployeeGroup.create({
'name': 'Hol10',
'employee_id': self.employee_hruser_id,
'holiday_status_id': self.holidays_status_1.id,
'date_from': (datetime.today() - relativedelta(days=1)),
'date_to': datetime.today(),
'number_of_days_temp': 1,
})
Holidays.search([('name', '=', 'Hol10')]).unlink()
# Employee creates a leave request in a no-limit category
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_temp': 1,
})
hol1_user_group = hol1_employee_group.sudo(self.user_hruser_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
with self.assertRaises(UserError):
hol1_employee_group.action_approve()
self.assertEqual(hol1_user_group.state, 'confirm', 'hr_holidays: employee should not be able to validate its own leave request')
# HrUser validates the employee leave request
hol1_user_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_temp': 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=0)).strftime('%Y-%m-%d %H:%M'),
'date_to': (datetime.today() + relativedelta(days=1)),
'number_of_days_temp': 1,
})
# Clean transaction
Holidays.search([('name', 'in', ['Hol21', 'Hol22'])]).unlink()
# HrUser allocates some leaves to the employee
aloc1_user_group = Holidays.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,
'type': 'add',
'number_of_days_temp': 2,
})
# HrUser validates the first step
aloc1_user_group.action_approve()
# 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)
_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,
'date_from': (datetime.today() + relativedelta(days=2)).strftime('%Y-%m-%d %H:%M'),
'date_to': (datetime.today() + relativedelta(days=3)),
'number_of_days_temp': 1,
})
hol2_user_group = hol2.sudo(self.user_hruser_id)
# Check left days: - 1 virtual remaining day
_check_holidays_status(hol_status_2_employee_group, 2.0, 0.0, 2.0, 1.0)
# HrUser validates the first step
hol2_user_group.action_approve()
self.assertEqual(hol2.state, 'validate1',
'hr_holidays: first validation should lead to validate1 state')
# HrManager validates the second step
hol2_user_group.sudo(self.user_hrmanager_id).action_validate()
self.assertEqual(hol2.state, 'validate',
'hr_holidays: second validation should lead to validate state')
# Check left days: - 1 day taken
_check_holidays_status(hol_status_2_employee_group, 2.0, 1.0, 1.0, 1.0)
# HrManager finds an error: he refuses the leave request
hol2.sudo(self.user_hrmanager_id).action_refuse()
self.assertEqual(hol2.state, 'refuse',
'hr_holidays: refuse should lead to refuse state')
# Check left days: 2 days left again
_check_holidays_status(hol_status_2_employee_group, 2.0, 0.0, 2.0, 2.0)
# Annoyed, HrUser tries to fix its error and tries to reset the leave request -> does not work, only HrManager
with self.assertRaises(UserError):
hol2_user_group.action_draft()
self.assertEqual(hol2.state, 'refuse',
'hr_holidays: hr_user should not be able to reset a refused leave request')
# HrManager resets the request
hol2_manager_group = hol2.sudo(self.user_hrmanager_id)
hol2_manager_group.action_draft()
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_temp': 4,
})
with self.assertRaises(ValidationError):
hol2_manager_group.action_confirm()
employee_id = self.ref('hr.employee_root')
# cl can be of maximum 20 days for employee_root
hol3_status = self.env.ref('hr_holidays.holiday_status_cl').with_context(employee_id=employee_id)
# I assign the dates in the holiday request for 1 day
hol3 = Holidays.create({
'name': 'Sick Leave',
'holiday_status_id': hol3_status.id,
'date_from': datetime.today().strftime('%Y-%m-10 10:00:00'),
'date_to': datetime.today().strftime('%Y-%m-11 19:00:00'),
'employee_id': employee_id,
'type': 'remove',
'number_of_days_temp': 1
})
# I find a small mistake on my leave request to I click on "Refuse" button to correct a mistake.
hol3.action_refuse()
self.assertEqual(hol3.state, 'refuse', 'hr_holidays: refuse should lead to refuse state')
# I again set to draft and then confirm.
hol3.action_draft()
self.assertEqual(hol3.state, 'draft', 'hr_holidays: resetting should lead to draft state')
hol3.action_confirm()
self.assertEqual(hol3.state, 'confirm', 'hr_holidays: confirming should lead to confirm state')
# I validate the holiday request by clicking on "To Approve" button.
hol3.action_approve()
self.assertEqual(hol3.state, 'validate', 'hr_holidays: validation should lead to validate state')
# Check left days for casual leave: 19 days left
_check_holidays_status(hol3_status, 20.0, 1.0, 19.0, 19.0)
def test_10_leave_summary_reports(self):
# Print the HR Holidays(Summary Department) Report through the wizard
ctx = {
'model': 'hr.department',
'active_ids': [self.ref('hr.employee_root'), self.ref('hr.employee_qdp'), self.ref('hr.employee_al')]
}
data_dict = {
'date_from': datetime.today().strftime('%Y-%m-01'),
'depts': [(6, 0, [self.ref('hr.dep_sales')])],
'holiday_type': 'Approved'
}
test_reports.try_report_action(self.env.cr, self.env.uid, 'action_hr_holidays_summary_dept', wiz_data=data_dict, context=ctx, our_module='hr_holidays')
# Print the HR Holidays(Summary Employee) Report through the wizard
ctx = {
'model': 'hr.employee',
'active_ids': [self.ref('hr.employee_root'), self.ref('hr.employee_qdp'), self.ref('hr.employee_al')]
}
data_dict = {
'date_from': datetime.today().strftime('%Y-%m-01'),
'emp': [(6, 0, [self.ref('hr.employee_root'), self.ref('hr.employee_qdp'), self.ref('hr.employee_al')])],
'holiday_type': 'Approved'
}
test_reports.try_report_action(self.env.cr, self.env.uid, 'action_hr_holidays_summary_employee', wiz_data=data_dict, context=ctx, our_module='hr_holidays')