[REF] hr_holidays: clean leave and allocation access rights

Purpose

 - clean access rights;
 - solve some access and security issues;

Access specifications

 - an user
  - can see all leaves;
  - cannot see name field of leaves belonging to other user as it may contain
    private information that we don't want to share to other people than
    HR people;
  - can modify only its own not validated leaves (except writing on state to
    avoid bypassing validation);
  - can discuss on its leave requests;
 - an Officer
  - can see all leaves;
  - can validate "HR" single validation leaves from people if
   - he is the employee manager;
   - he is the department manager;
   - he is member of the same department;
   - target employee has no manager and no department manager;
  - can validate "Manager" single validation leaves from people if
   - he is the employee manager;
   - he is the department manager;
   - target employee has no manager and no department manager;
  - can first validate "Both" double validation leaves from people like "HR"
    single validation, moving the leaves to validate1 state;
  - cannot validate its own leaves;
 - a Manager
  - can do everything he wants

In top of that, multi company rule are correctly added.

In reporting model using in "summary" name field should also be stripped
if you are not an HR officer and if it is not your own request.

Concerning allocation requests: implement same rules except constraint on
name field as it is less private and therefore can be seen.

This commit is linked to task ID 1876795 and PR #26656.
This commit is contained in:
Thibault Delavallée
2018-08-31 14:19:23 +02:00
parent 0113d989a8
commit 0f3281e3b1
8 changed files with 650 additions and 192 deletions
+110 -58
View File
@@ -8,7 +8,7 @@ import math
from datetime import timedelta
from odoo import api, fields, models
from odoo.exceptions import UserError, ValidationError
from odoo.exceptions import AccessError, UserError, ValidationError
from odoo.tools import float_compare
from odoo.tools.translate import _
@@ -16,27 +16,47 @@ from odoo.addons.resource.models.resource import HOURS_PER_DAY
_logger = logging.getLogger(__name__)
class HolidaysRequest(models.Model):
"""
Here are the rights associated with the flow of leave requests
State Groups Restriction
============================================================================================================
Draft Anybody Own Request only and state in [confirm, refuse]
Holiday Manager State in [confirm, refuse]
Confirm All State = draft
Validate1 Holiday Officer Not his own Request and state = confirm
Holiday Manager Not his own Request or has no manager and State = confirm
Validate Holiday Officer Not his own Request and state = confirm
Holiday Manager Not his own Request or has no manager and State in [validate1, confirm]
Refuse Holiday Officer State in [confirm, validate, validate1]
Holiday Manager State in [confirm, validate, validate1]
============================================================================================================
class HolidaysRequest(models.Model):
""" Leave Requests Access specifications
- a regular employee / user
- can see all leaves;
- cannot see name field of leaves belonging to other user as it may contain
private information that we don't want to share to other people than
HR people;
- can modify only its own not validated leaves (except writing on state to
bypass approval);
- can discuss on its leave requests;
- can reset only its own leaves;
- cannot validate any leaves;
- an Officer
- can see all leaves;
- can validate "HR" single validation leaves from people if
- he is the employee manager;
- he is the department manager;
- he is member of the same department;
- target employee has no manager and no department manager;
- can validate "Manager" single validation leaves from people if
- he is the employee manager;
- he is the department manager;
- target employee has no manager and no department manager;
- can first validate "Both" double validation leaves from people like "HR"
single validation, moving the leaves to validate1 state;
- cannot validate its own leaves;
- can reset only its own leaves;
- can refuse all leaves;
- a Manager
- can do everything he wants
On top of that multicompany rules apply based on company defined on the
leave request leave type.
"""
_name = "hr.leave"
_description = "Leave"
_order = "date_from desc"
_inherit = ['mail.thread', 'mail.activity.mixin']
_mail_post_access = 'read'
def _default_domain_holiday_status(self):
if self.user_has_groups('hr_holidays.group_hr_holidays_manager'):
@@ -56,7 +76,6 @@ class HolidaysRequest(models.Model):
def _default_employee(self):
return self.env.context.get('default_employee_id') or self.env['hr.employee'].search([('user_id', '=', self.env.uid)], limit=1)
name = fields.Char('Description')
state = fields.Selection([
('draft', 'To Submit'),
@@ -126,25 +145,28 @@ class HolidaysRequest(models.Model):
holiday.number_of_days = -holiday.number_of_days_temp
@api.multi
@api.depends('state', 'employee_id', 'department_id')
def _compute_can_reset(self):
""" User can reset a leave request if it is its own leave request
or if he is an Hr Manager.
"""
user = self.env.user
group_hr_manager = self.env.ref('hr_holidays.group_hr_holidays_manager')
for holiday in self:
if group_hr_manager in user.groups_id or holiday.employee_id and holiday.employee_id.user_id == user:
try:
holiday._check_approval_update('draft')
except (AccessError, UserError):
holiday.can_reset = False
else:
holiday.can_reset = True
@api.depends('employee_id', 'department_id')
@api.depends('state', 'employee_id', 'department_id')
def _compute_can_approve(self):
""" User can only approve a leave request if it is not his own
Exception : User is holiday manager and has no manager
"""
for holiday in self:
# User is holiday manager and has no manager
manager = self.user_has_groups('hr_holidays.group_hr_holidays_manager')
holiday.can_approve = (holiday.employee_id.user_id.id != self.env.uid) or manager
try:
if holiday.state == 'confirm' and holiday.holiday_status_id.validation_type == 'both':
holiday._check_approval_update('validate1')
else:
holiday._check_approval_update('validate')
except (AccessError, UserError):
holiday.can_approve = False
else:
holiday.can_approve = True
@api.onchange('holiday_type')
def _onchange_type(self):
@@ -264,8 +286,9 @@ class HolidaysRequest(models.Model):
dto = fields.Datetime.from_string(leave.date_to)
if dfrom and dto and (dfrom < vstart or dto > vstop):
raise UserError(_('You can take %s only between %s and %s') % (leave.holiday_status_id.display_name, \
leave.holiday_status_id.validity_start, leave.holiday_status_id.validity_stop))
raise UserError(
_('You can take %s only between %s and %s') % (
leave.holiday_status_id.display_name, leave.holiday_status_id.validity_start, leave.holiday_status_id.validity_stop))
@api.model
def create(self, values):
@@ -280,9 +303,29 @@ class HolidaysRequest(models.Model):
holiday.activity_update()
return holiday
def _read_from_database(self, field_names, inherited_field_names=[]):
if 'name' in field_names and 'employee_id' not in field_names:
field_names.append('employee_id')
super(HolidaysRequest, self)._read_from_database(field_names, inherited_field_names)
if 'name' in field_names:
if self.user_has_groups('hr_holidays.group_hr_holidays_user'):
return
current_employee = self.env['hr.employee'].sudo().search([('user_id', '=', self.env.uid)], limit=1)
for record in self:
emp_id = record._cache.get('employee_id', [False])[0]
if emp_id != current_employee.id:
try:
record._cache['name']
record._cache['name'] = '*****'
except Exception:
# skip SpecialValue (e.g. for missing record or access right)
pass
@api.multi
def write(self, values):
employee_id = values.get('employee_id', False)
if values.get('state'):
self._check_approval_update(values['state'])
result = super(HolidaysRequest, self).write(values)
self.add_follower(employee_id)
if 'employee_id' in values:
@@ -373,8 +416,6 @@ class HolidaysRequest(models.Model):
@api.multi
def action_draft(self):
for holiday in self:
if not holiday.can_reset:
raise UserError(_('Only an HR Manager or the concerned employee can reset to draft.'))
if holiday.state not in ['confirm', 'refuse']:
raise UserError(_('Leave request state must be "Refused" or "To Approve" in order to reset to Draft.'))
holiday.write({
@@ -401,22 +442,10 @@ class HolidaysRequest(models.Model):
def action_approve(self):
# if validation_type == 'both': this method is the first approval approval
# if validation_type != 'both': this method calls action_validate() below
if not self.env.user.has_group('hr_holidays.group_hr_holidays_user'):
raise UserError(_('Only an HR Officer or Manager can approve leave requests.'))
current_employee = self.env['hr.employee'].search([('user_id', '=', self.env.uid)], limit=1)
if any(holiday.state != 'confirm' for holiday in self):
raise UserError(_('Leave request must be confirmed ("To Approve") in order to approve it.'))
for holiday in self:
validation_type = holiday.holiday_status_id.validation_type
manager = holiday.employee_id.parent_id or holiday.employee_id.department_id.manager_id
if (validation_type in ['hr', 'both']) and (manager and manager != current_employee)\
and not self.env.user.has_group('hr_holidays.group_hr_holidays_manager'):
raise UserError(_('You must be %s manager to approve this leave') % (holiday.employee_id.name))
elif validation_type == 'manager' and not self.env.user.has_group('hr_holidays.group_hr_holidays_manager'):
raise UserError(_('You must be a Human Resource Manager to approve this Leave'))
current_employee = self.env['hr.employee'].search([('user_id', '=', self.env.uid)], limit=1)
self.filtered(lambda hol: hol.validation_type == 'both').write({'state': 'validate1', 'first_approver_id': current_employee.id})
self.filtered(lambda hol: not hol.validation_type == 'both').action_validate()
self.activity_update()
@@ -424,18 +453,10 @@ class HolidaysRequest(models.Model):
@api.multi
def action_validate(self):
if not self.env.user.has_group('hr_holidays.group_hr_holidays_user'):
raise UserError(_('Only an HR Officer or Manager can approve leave requests.'))
if any(not holiday.can_approve for holiday in self):
raise UserError(_('Only your manager can approve your leave requests'))
current_employee = self.env['hr.employee'].search([('user_id', '=', self.env.uid)], limit=1)
for holiday in self:
if holiday.state not in ['confirm', 'validate1']:
raise UserError(_('Leave request must be confirmed in order to approve it.'))
if holiday.state == 'validate1' and not holiday.env.user.has_group('hr_holidays.group_hr_holidays_manager'):
raise UserError(_('Only an HR Manager can apply the second approval on leave requests.'))
holiday.write({'state': 'validate'})
if holiday.validation_type == 'both':
@@ -459,9 +480,6 @@ class HolidaysRequest(models.Model):
@api.multi
def action_refuse(self):
if not self.env.user.has_group('hr_holidays.group_hr_holidays_user'):
raise UserError(_('Only an HR Officer or Manager can refuse leave requests.'))
current_employee = self.env['hr.employee'].search([('user_id', '=', self.env.uid)], limit=1)
for holiday in self:
if holiday.state not in ['confirm', 'validate', 'validate1']:
@@ -480,6 +498,40 @@ class HolidaysRequest(models.Model):
self.activity_update()
return True
def _check_approval_update(self, state):
""" Check if target state is achievable. """
current_employee = self.env['hr.employee'].search([('user_id', '=', self.env.uid)], limit=1)
is_officer = self.env.user.has_group('hr_holidays.group_hr_holidays_user')
is_manager = self.env.user.has_group('hr_holidays.group_hr_holidays_manager')
for holiday in self:
val_type = holiday.holiday_status_id.validation_type
if state == 'confirm':
continue
if state == 'draft':
if holiday.employee_id != current_employee and not is_manager:
raise UserError(_('Only a Leave Manager can reset other people leaves.'))
continue
if not is_officer:
raise UserError(_('Only a Leave Officer or Manager can approve or refuse leave requests.'))
if is_officer:
# use ir.rule based first access check: department, members, ... (see security.xml)
holiday.check_access_rule('write')
if holiday.employee_id == current_employee and not is_manager:
raise UserError(_('Only a Leave Manager can approve its own requests.'))
if (state == 'validate1' and val_type == 'both') or (state == 'validate' and val_type == 'manager'):
manager = holiday.employee_id.parent_id or holiday.employee_id.department_id.manager_id
if (manager and manager != current_employee) and not self.env.user.has_group('hr_holidays.group_hr_holidays_manager'):
raise UserError(_('You must be either %s\'s manager or Leave manager to approve this leave') % (holiday.employee_id.name))
if state == 'validate' and val_type == 'both':
if not self.env.user.has_group('hr_holidays.group_hr_holidays_manager'):
raise UserError(_('Only an Leave Manager can apply the second approval on leave requests.'))
# ------------------------------------------------------------
# Activity methods
# ------------------------------------------------------------
@@ -6,32 +6,18 @@
import logging
from odoo import api, fields, models
from odoo.exceptions import UserError
from odoo.exceptions import AccessError, UserError
from odoo.tools.translate import _
_logger = logging.getLogger(__name__)
class HolidaysAllocation(models.Model):
"""
Here are the rights associated with the flow of allocation requests
State Groups Restriction
============================================================================================================
Draft Anybody Own Allocation only and state in [confirm, refuse]
Holiday Manager State in [confirm, refuse]
Confirm All State = draft
Validate1 Holiday Officer Not his own Allocation and state = confirm
Holiday Manager Not his own Allocation or has no manager and State = confirm
Validate Holiday Officer Not his own Allocation and state = confirm
Holiday Manager Not his own Allocation or has no manager and State in [validate1, confirm]
Refuse Holiday Officer State in [confirm, validate, validate1]
Holiday Manager State in [confirm, validate, validate1]
============================================================================================================
"""
""" Allocation Requests Access specifications: similar to leave requests """
_name = "hr.leave.allocation"
_description = "Leaves Allocation"
_inherit = ['mail.thread', 'mail.activity.mixin']
_mail_post_access = 'read'
def _default_domain_holiday_status_id(self):
if self.user_has_groups('hr_holidays.group_hr_holidays_manager'):
@@ -103,25 +89,28 @@ class HolidaysAllocation(models.Model):
holiday.number_of_days = holiday.number_of_days_temp
@api.multi
@api.depends('state', 'employee_id', 'department_id')
def _compute_can_reset(self):
""" User can reset a leave request if it is its own leave request
or if he is an Hr Manager.
"""
user = self.env.user
group_hr_manager = self.env.ref('hr_holidays.group_hr_holidays_manager')
for holiday in self:
if group_hr_manager in user.groups_id or holiday.employee_id and holiday.employee_id.user_id == user:
holiday.can_reset = True
for allocation in self:
try:
allocation._check_approval_update('draft')
except (AccessError, UserError):
allocation.can_reset = False
else:
allocation.can_reset = True
@api.depends('employee_id', 'department_id')
@api.depends('state', 'employee_id', 'department_id')
def _compute_can_approve(self):
""" User can only approve a leave request if it is not his own
Exception : User is holiday manager and has no manager
"""
for holiday in self:
# User is holiday manager and has no manager
manager = self.user_has_groups('hr_holidays.group_hr_holidays_manager')
holiday.can_approve = (holiday.employee_id.user_id.id != self.env.uid) or manager
for allocation in self:
try:
if allocation.state == 'confirm' and allocation.holiday_status_id.validation_type == 'both':
allocation._check_approval_update('validate1')
else:
allocation._check_approval_update('validate')
except (AccessError, UserError):
allocation.can_approve = False
else:
allocation.can_approve = True
@api.onchange('holiday_type')
def _onchange_type(self):
@@ -185,6 +174,8 @@ class HolidaysAllocation(models.Model):
@api.multi
def write(self, values):
employee_id = values.get('employee_id', False)
if values.get('state'):
self._check_approval_update(values['state'])
result = super(HolidaysAllocation, self).write(values)
self.add_follower(employee_id)
return result
@@ -220,8 +211,6 @@ class HolidaysAllocation(models.Model):
@api.multi
def action_draft(self):
for holiday in self:
if not holiday.can_reset:
raise UserError(_('Only an HR Manager or the concerned employee can reset to draft.'))
if holiday.state not in ['confirm', 'refuse']:
raise UserError(_('Leave request state must be "Refused" or "To Approve" in order to reset to Draft.'))
holiday.write({
@@ -248,21 +237,10 @@ class HolidaysAllocation(models.Model):
def action_approve(self):
# if validation_type == 'both': this method is the first approval approval
# if validation_type != 'both': this method calls action_validate() below
if not self.env.user.has_group('hr_holidays.group_hr_holidays_user'):
raise UserError(_('Only an HR Officer or Manager can approve leave requests.'))
current_employee = self.env['hr.employee'].search([('user_id', '=', self.env.uid)], limit=1)
if any(holiday.state != 'confirm' for holiday in self):
raise UserError(_('Leave request must be confirmed ("To Approve") in order to approve it.'))
for holiday in self:
validation_type = holiday.holiday_status_id.validation_type
manager = holiday.employee_id.parent_id or holiday.employee_id.department_id.manager_id
if (validation_type in ['hr', 'both']) and (manager and manager != current_employee)\
and not self.env.user.has_group('hr_holidays.group_hr_holidays_manager'):
raise UserError(_('You must be %s manager to approve this leave') % (holiday.employee_id.name))
elif validation_type == 'manager' and not self.env.user.has_group('hr_holidays.group_hr_holidays_manager'):
raise UserError(_('You must be a Human Resource Manager to approve this Leave'))
current_employee = self.env['hr.employee'].search([('user_id', '=', self.env.uid)], limit=1)
self.filtered(lambda hol: hol.validation_type == 'both').write({'state': 'validate1', 'first_approver_id': current_employee.id})
self.filtered(lambda hol: not hol.validation_type == 'both').action_validate()
@@ -271,18 +249,10 @@ class HolidaysAllocation(models.Model):
@api.multi
def action_validate(self):
if not self.env.user.has_group('hr_holidays.group_hr_holidays_user'):
raise UserError(_('Only an HR Officer or Manager can approve leave requests.'))
if any(not holiday.can_approve for holiday in self):
raise UserError(_('Only your manager can approve your allocations'))
current_employee = self.env['hr.employee'].search([('user_id', '=', self.env.uid)], limit=1)
for holiday in self:
if holiday.state not in ['confirm', 'validate1']:
raise UserError(_('Leave request must be confirmed in order to approve it.'))
if holiday.state == 'validate1' and not holiday.env.user.has_group('hr_holidays.group_hr_holidays_manager'):
raise UserError(_('Only an HR Manager can apply the second approval on leave requests.'))
holiday.write({'state': 'validate'})
if holiday.validation_type == 'both':
@@ -304,9 +274,6 @@ class HolidaysAllocation(models.Model):
@api.multi
def action_refuse(self):
if not self.env.user.has_group('hr_holidays.group_hr_holidays_user'):
raise UserError(_('Only an HR Officer or Manager can refuse leave requests.'))
current_employee = self.env['hr.employee'].search([('user_id', '=', self.env.uid)], limit=1)
for holiday in self:
if holiday.state not in ['confirm', 'validate', 'validate1']:
@@ -321,6 +288,40 @@ class HolidaysAllocation(models.Model):
self.activity_update()
return True
def _check_approval_update(self, state):
""" Check if target state is achievable. """
current_employee = self.env['hr.employee'].search([('user_id', '=', self.env.uid)], limit=1)
is_officer = self.env.user.has_group('hr_holidays.group_hr_holidays_user')
is_manager = self.env.user.has_group('hr_holidays.group_hr_holidays_manager')
for holiday in self:
val_type = holiday.holiday_status_id.validation_type
if state == 'confirm':
continue
if state == 'draft':
if holiday.employee_id != current_employee and not is_manager:
raise UserError(_('Only a Leave Manager can reset other people leaves.'))
continue
if not is_officer:
raise UserError(_('Only a Leave Officer or Manager can approve or refuse leave requests.'))
if is_officer:
# use ir.rule based first access check: department, members, ... (see security.xml)
holiday.check_access_rule('write')
if holiday.employee_id == current_employee and not is_manager:
raise UserError(_('Only a Leave Manager can approve its own requests.'))
if (state == 'validate1' and val_type == 'both') or (state == 'validate' and val_type == 'manager'):
manager = holiday.employee_id.parent_id or holiday.employee_id.department_id.manager_id
if (manager and manager != current_employee) and not self.env.user.has_group('hr_holidays.group_hr_holidays_manager'):
raise UserError(_('You must be either %s\'s manager or Leave manager to approve this leave') % (holiday.employee_id.name))
if state == 'validate' and val_type == 'both':
if not self.env.user.has_group('hr_holidays.group_hr_holidays_manager'):
raise UserError(_('Only an Leave Manager can apply the second approval on leave requests.'))
# ------------------------------------------------------------
# Activity methods
# ------------------------------------------------------------
+19 -1
View File
@@ -1,7 +1,7 @@
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from odoo import fields, models, tools
from odoo import api, fields, models, tools
class LeaveReport(models.Model):
@@ -78,3 +78,21 @@ class LeaveReport(models.Model):
from hr_leave as request) leaves
);
""")
def _read_from_database(self, field_names, inherited_field_names=[]):
if 'name' in field_names and 'employee_id' not in field_names:
field_names.append('employee_id')
super(LeaveReport, self)._read_from_database(field_names, inherited_field_names)
if 'name' in field_names:
if self.user_has_groups('hr_holidays.group_hr_holidays_user'):
return
current_employee = self.env['hr.employee'].sudo().search([('user_id', '=', self.env.uid)], limit=1)
for record in self:
emp_id = record._cache.get('employee_id', [False])[0]
if emp_id != current_employee.id:
try:
record._cache['name']
record._cache['name'] = '*****'
except Exception:
# skip SpecialValue (e.g. for missing record or access right)
pass
@@ -18,64 +18,96 @@
</record>
<record id="hr_leave_rule_employee" model="ir.rule">
<field name="name">Employee Leaves</field>
<field name="name">Leaves: employee: read all</field>
<field name="model_id" ref="model_hr_leave"/>
<field name="domain_force">[('employee_id.user_id','=',user.id)]</field>
<field name="domain_force">[(1, '=', 1)]</field>
<field name="perm_create" eval="False"/>
<field name="perm_write" eval="False"/>
<field name="perm_unlink" eval="False"/>
<field name="groups" eval="[(4,ref('base.group_user'))]"/>
</record>
<record id="hr_leave_rule_employee_write" model="ir.rule">
<field name="name">Employee Leaves Create, Write, Unlink</field>
<record id="hr_leave_rule_employee_update" model="ir.rule">
<field name="name">Leaves: employee: create/write/unlink not validated own</field>
<field name="model_id" ref="model_hr_leave"/>
<field name="domain_force">[('employee_id.user_id','=',user.id), ('state', 'in', ['draft', 'confirm', 'cancel', 'refuse'])]</field>
<field name="perm_read" eval="False"/>
<field name="groups" eval="[(4,ref('base.group_user'))]"/>
</record>
<record id="hr_leave_rule_officer" model="ir.rule">
<field name="name">Leaves Officer</field>
<record id="hr_leave_rule_officer_read" model="ir.rule">
<field name="name">Leaves: officer: read all</field>
<field name="model_id" ref="model_hr_leave"/>
<field name="domain_force">['|','|','|', ('employee_id.user_id', '=', user.id), ('department_id', '=', False), ('department_id.manager_id', '=', False), ('department_id.manager_id.user_id', '=', user.id)]</field>
<field name="groups" eval="[(4,ref('hr_holidays.group_hr_holidays_user'))]"/>
<field name="domain_force">[(1, '=', 1)]</field>
<field name="perm_create" eval="False"/>
<field name="perm_write" eval="False"/>
<field name="perm_unlink" eval="False"/>
<field name="groups" eval="[(4, ref('hr_holidays.group_hr_holidays_user'))]"/>
</record>
<record id="hr_leave_rule_officer_update" model="ir.rule">
<field name="name">Leaves: officer: create/write/unlink own + managed employee + without department + same or managed department</field>
<field name="model_id" ref="model_hr_leave"/>
<field name="domain_force">['|',
'|', ('employee_id.user_id', '=', user.id), ('employee_id.parent_id.user_id', '=', user.id),
'|', '|', ('department_id', '=', False), ('department_id.member_ids.user_id', 'in', [user.id]), ('department_id.manager_id.user_id', '=', user.id)]</field>
<field name="perm_read" eval="False"/>
<field name="groups" eval="[(4, ref('hr_holidays.group_hr_holidays_user'))]"/>
</record>
<record id="hr_leave_rule_manager" model="ir.rule">
<field name="name">Manager Leaves</field>
<field name="name">Leaves: manager: no limit</field>
<field name="model_id" ref="model_hr_leave"/>
<field name="domain_force">[(1, '=', 1)]</field>
<field name="groups" eval="[(4, ref('group_hr_holidays_manager'))]"/>
</record>
<record id="hr_leave_rule_multicompany" model="ir.rule">
<field name="name">Leaves: multi company global rule</field>
<field name="model_id" ref="model_hr_leave"/>
<field name="global" eval="True"/>
<field name="domain_force">['|', ('holiday_status_id.company_id', '=', False), ('holiday_status_id.company_id', 'in', [user.company_id.id])]</field>
</record>
<record id="hr_leave_allocation_rule_employee" model="ir.rule">
<field name="name">Employee Allocations</field>
<field name="name">Allocations: employee: read own</field>
<field name="model_id" ref="model_hr_leave_allocation"/>
<field name="domain_force">[('employee_id.user_id','=',user.id)]</field>
<field name="domain_force">[('employee_id.user_id', '=', user.id)]</field>
<field name="perm_create" eval="False"/>
<field name="perm_write" eval="False"/>
<field name="perm_unlink" eval="False"/>
<field name="groups" eval="[(4,ref('base.group_user'))]"/>
</record>
<record id="hr_leave_allocation_rule_employee_write" model="ir.rule">
<field name="name">Employee Allocations Create, Write, Unlink</field>
<record id="hr_leave_allocation_rule_employee_update" model="ir.rule">
<field name="name">Allocations: employee: create/write/unlink not validated own</field>
<field name="model_id" ref="model_hr_leave_allocation"/>
<field name="domain_force">[('employee_id.user_id','=',user.id), ('state', 'in', ['draft', 'confirm', 'cancel', 'refuse'])]</field>
<field name="perm_read" eval="False"/>
<field name="groups" eval="[(4,ref('base.group_user'))]"/>
</record>
<record id="hr_leave_allocation_rule_officer" model="ir.rule">
<field name="name">Leaves Officer</field>
<record id="hr_leave_allocation_rule_officer_read" model="ir.rule">
<field name="name">Allocations: officer: read all</field>
<field name="model_id" ref="model_hr_leave_allocation"/>
<field name="domain_force">['|','|','|', ('employee_id.user_id', '=', user.id), ('department_id', '=', False), ('department_id.manager_id', '=', False), ('department_id.manager_id.user_id', '=', user.id)]</field>
<field name="domain_force">[(1, '=', 1)]</field>
<field name="perm_create" eval="False"/>
<field name="perm_write" eval="False"/>
<field name="perm_unlink" eval="False"/>
<field name="groups" eval="[(4, ref('hr_holidays.group_hr_holidays_user'))]"/>
</record>
<record id="hr_leave_allocation_rule_officer_update" model="ir.rule">
<field name="name">Allocations: officer: create/write/unlink own + managed employee + without department + same or managed department</field>
<field name="model_id" ref="model_hr_leave_allocation"/>
<field name="domain_force">['|',
'|', ('employee_id.user_id', '=', user.id), ('employee_id.parent_id.user_id', '=', user.id),
'|', '|', ('department_id', '=', False), ('department_id.member_ids.user_id', 'in', [user.id]), ('department_id.manager_id.user_id', '=', user.id)]</field>
<field name="groups" eval="[(4,ref('hr_holidays.group_hr_holidays_user'))]"/>
</record>
<record id="hr_leave_allocation_rule_manager" model="ir.rule">
<field name="name">Manager Allocations</field>
<field name="name">Allocations: manager: no limit</field>
<field name="model_id" ref="model_hr_leave_allocation"/>
<field name="domain_force">[(1, '=', 1)]</field>
<field name="groups" eval="[(4, ref('group_hr_holidays_manager'))]"/>
+1
View File
@@ -1,5 +1,6 @@
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from . import test_access_rights
from . import test_holidays_flow
from . import test_hr_leave_type
+19 -11
View File
@@ -15,24 +15,27 @@ class TestHrHolidaysBase(common.TransactionCase):
group_employee_id = self.ref('base.group_user')
# Test users to use through the various tests
self.user_hruser_id = Users.create({
self.user_hruser = Users.create({
'name': 'Armande HrUser',
'login': 'Armande',
'email': 'armande.hruser@example.com',
'groups_id': [(6, 0, [group_employee_id, self.ref('hr_holidays.group_hr_holidays_user')])]
}).id
self.user_hrmanager_id = Users.create({
})
self.user_hruser_id = self.user_hruser.id
self.user_hrmanager = Users.create({
'name': 'Bastien HrManager',
'login': 'bastien',
'email': 'bastien.hrmanager@example.com',
'groups_id': [(6, 0, [group_employee_id, self.ref('hr_holidays.group_hr_holidays_manager')])]
}).id
self.user_employee_id = Users.create({
self.user_hrmanager_id = self.user_hrmanager
self.user_employee = Users.create({
'name': 'David Employee',
'login': 'david',
'email': 'david.employee@example.com',
'groups_id': [(6, 0, [group_employee_id])]
}).id
})
self.user_employee_id = self.user_employee.id
self.user_hrmanager_2_id = Users.create({
'name': 'Florence HrManager',
'login': 'florence',
@@ -50,21 +53,26 @@ class TestHrHolidaysBase(common.TransactionCase):
'name': 'Research and devlopment',
})
self.employee_emp_id = self.env['hr.employee'].create({
self.employee_emp = self.env['hr.employee'].create({
'name': 'David Employee',
'user_id': self.user_employee_id,
'department_id': self.rd_dept.id,
}).id
self.employee_hruser_id = self.env['hr.employee'].create({
})
self.employee_emp_id = self.employee_emp.id
self.employee_hruser = self.env['hr.employee'].create({
'name': 'Armande HrUser',
'user_id': self.user_hruser_id,
'department_id': self.rd_dept.id,
}).id
self.employee_hrmanager_id = self.env['hr.employee'].create({
})
self.employee_hruser_id = self.employee_hruser.id
self.employee_hrmanager = self.env['hr.employee'].create({
'name': 'Bastien HrManager',
'user_id': self.user_hrmanager_id,
'department_id': self.hr_dept.id,
}).id
})
self.employee_hrmanager_id = self.employee_hrmanager.id
self.employee_hrmanager_2_id = self.env['hr.employee'].create({
'name': 'Florence HrManager',
@@ -0,0 +1,392 @@
# -*- 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 tests
from odoo.addons.hr_holidays.tests.common import TestHrHolidaysBase
from odoo.exceptions import AccessError, UserError
from odoo.tools import mute_logger
@tests.tagged('access_rights')
class TestLeavesRights(TestHrHolidaysBase):
def setUp(self):
super(TestLeavesRights, self).setUp()
self.leave_type = self.env['hr.leave.type'].create({
'name': 'Unlimited',
'limit': True,
'validation_type': 'hr',
})
self.rd_dept.manager_id = False
self.hr_dept.manager_id = False
self.employee_emp.parent_id = False
self.employee_leave = self.env['hr.leave'].sudo(self.user_employee_id).create({
'name': 'Test',
'holiday_status_id': self.leave_type.id,
'department_id': self.employee_emp.department_id.id,
'employee_id': self.employee_emp.id,
'date_from': datetime.now(),
'date_to': datetime.now() + relativedelta(days=1),
'number_of_days_temp': 1,
})
@mute_logger('odoo.models.unlink', 'odoo.addons.mail.models.mail_mail')
def test_leave_messaging_by_user(self):
""" User may communicate on its own leaves, even if validated """
self.employee_leave.sudo(self.user_employee_id).message_post(
body='I haz messaging',
subtype='mail.mt_comment',
message_type='comment'
)
self.employee_leave.sudo(self.user_hrmanager_id).action_approve()
self.employee_leave.sudo(self.user_employee_id).message_post(
body='I still haz messaging',
subtype='mail.mt_comment',
message_type='comment'
)
@mute_logger('odoo.models.unlink', 'odoo.addons.mail.models.mail_mail')
def test_leave_read_by_user_other(self):
""" Users should be able to read other people requests except name field """
other_leave = self.env['hr.leave'].sudo(self.user_hruser).create({
'name': 'Test',
'holiday_status_id': self.leave_type.id,
'department_id': self.employee_hruser.department_id.id,
'employee_id': self.employee_hruser.id,
'date_from': datetime.now(),
'date_to': datetime.now() + relativedelta(days=1),
'number_of_days_temp': 1,
})
res = other_leave.sudo(self.user_employee_id).read(['number_of_days_temp', 'state', 'name'])
self.assertEqual(
res[0]['name'], '*****',
'Private information should have been stripped, received %s instead' % res[0]['name']
)
@mute_logger('odoo.models.unlink', 'odoo.addons.mail.models.mail_mail')
def test_leave_read_by_user_other_browse(self):
""" Users should be able to browse other people requests except name field """
other_leave = self.env['hr.leave'].sudo(self.user_hruser).create({
'name': 'Test',
'holiday_status_id': self.leave_type.id,
'department_id': self.employee_hruser.department_id.id,
'employee_id': self.employee_hruser.id,
'date_from': datetime.now(),
'date_to': datetime.now() + relativedelta(days=1),
'number_of_days_temp': 1,
})
self.assertEqual(
other_leave.sudo(self.user_employee_id).name, '*****',
'Private information should have been stripped, received %s instead' % other_leave.sudo(self.user_employee_id).name
)
@mute_logger('odoo.models.unlink', 'odoo.addons.mail.models.mail_mail')
def test_leave_read_by_user_own(self):
""" Users should be able to read name field of own requests """
res = self.employee_leave.read(['name', 'number_of_days_temp', 'state'])
self.assertEqual(res[0]['name'], 'Test')
@mute_logger('odoo.models.unlink', 'odoo.addons.mail.models.mail_mail')
def test_leave_read_by_user_own_browse(self):
""" Users should be able to browse name field of own requests """
self.assertEqual(self.employee_leave.state, 'confirm')
self.assertEqual(self.employee_leave.name, 'Test')
@mute_logger('odoo.models.unlink', 'odoo.addons.mail.models.mail_mail')
def test_leave_update_hr_by_user(self):
""" User may update its leave """
self.employee_leave.sudo(self.user_employee_id).write({'name': 'Crocodile Dundee is my man'})
@mute_logger('odoo.models.unlink', 'odoo.addons.mail.models.mail_mail')
def test_leave_update_hr_by_user_other(self):
""" User cannot update other people leaves """
other_leave = self.env['hr.leave'].sudo(self.user_hruser).create({
'name': 'Test',
'holiday_status_id': self.leave_type.id,
'department_id': self.employee_hruser.department_id.id,
'employee_id': self.employee_hruser.id,
'date_from': datetime.now(),
'date_to': datetime.now() + relativedelta(days=1),
'number_of_days_temp': 1,
})
with self.assertRaises(AccessError):
other_leave.sudo(self.user_employee_id).write({'name': 'Crocodile Dundee is my man'})
# ----------------------------------------
# Reset
# ----------------------------------------
@mute_logger('odoo.models.unlink', 'odoo.addons.mail.models.mail_mail')
def test_leave_reset_by_manager(self):
""" Manager resets its own leaves """
manager_leave = self.env['hr.leave'].sudo(self.user_hrmanager).create({
'name': 'Test',
'holiday_status_id': self.leave_type.id,
'department_id': self.employee_hrmanager.department_id.id,
'employee_id': self.employee_hrmanager.id,
'date_from': datetime.now(),
'date_to': datetime.now() + relativedelta(days=1),
'number_of_days_temp': 1,
})
manager_leave.sudo(self.user_hrmanager).action_draft()
@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 """
self.employee_leave.sudo(self.user_hrmanager).action_draft()
@mute_logger('odoo.models.unlink', 'odoo.addons.mail.models.mail_mail')
def test_leave_reset_by_officer(self):
""" Officer resets its own leaves """
officer_leave = self.env['hr.leave'].sudo(self.user_hruser).create({
'name': 'Test',
'holiday_status_id': self.leave_type.id,
'department_id': self.employee_hruser.department_id.id,
'employee_id': self.employee_hruser.id,
'date_from': datetime.now(),
'date_to': datetime.now() + relativedelta(days=1),
'number_of_days_temp': 1,
})
officer_leave.sudo(self.user_hruser).action_draft()
@mute_logger('odoo.models.unlink', 'odoo.addons.mail.models.mail_mail')
def test_leave_reset_by_officer_other(self):
""" Officer may not reset other leaves """
with self.assertRaises(UserError):
self.employee_leave.sudo(self.user_hruser).action_draft()
@mute_logger('odoo.models.unlink', 'odoo.addons.mail.models.mail_mail')
def test_leave_reset_by_user(self):
""" User resets its own leaves """
self.employee_leave.sudo(self.user_employee_id).action_draft()
@mute_logger('odoo.models.unlink', 'odoo.addons.mail.models.mail_mail')
def test_leave_reset_by_user_other(self):
""" User may not reset other leaves """
other_leave = self.env['hr.leave'].sudo(self.user_hruser).create({
'name': 'Test',
'holiday_status_id': self.leave_type.id,
'department_id': self.employee_hruser.department_id.id,
'employee_id': self.employee_hruser.id,
'date_from': datetime.now(),
'date_to': datetime.now() + relativedelta(days=1),
'number_of_days_temp': 1,
})
with self.assertRaises(UserError):
other_leave.sudo(self.user_employee_id).action_draft()
# ----------------------------------------
# Validation: one validation, HR
# ----------------------------------------
@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.employee_leave.sudo(self.user_hrmanager_id).action_approve()
@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.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_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()
@mute_logger('odoo.models.unlink', 'odoo.addons.mail.models.mail_mail')
def test_leave_validation_hr_by_officer_other_department_with_manager(self):
""" Officer may not validate hr-only leaves for workers from another department that has a manager """
self.employee_hruser.write({'department_id': self.hr_dept.id})
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_wo_manager(self):
""" Officer may not validate hr-only leaves for workers from another department that has no manager """
self.employee_hruser.write({'department_id': self.hr_dept.id})
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_manager(self):
""" Officer validates hr-only leaves for workers from another department that he manages """
self.employee_hruser.write({'department_id': self.hr_dept.id})
self.employee_leave.sudo().department_id.write({'manager_id': self.employee_hruser.id})
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_user(self):
""" User may not validate any leaves """
with self.assertRaises(UserError):
self.employee_leave.sudo(self.user_employee_id).action_approve()
with self.assertRaises(UserError):
self.employee_leave.sudo(self.user_employee_id).write({'state': 'validate'})
# ----------------------------------------
# Validation: one validation, manager
# ----------------------------------------
@mute_logger('odoo.models.unlink', 'odoo.addons.mail.models.mail_mail')
def test_leave_validation_manager_by_manager(self):
""" Manager validates manager-only leaves """
self.leave_type.write({'validation_type': 'manager'})
self.employee_leave.sudo(self.user_hrmanager_id).action_approve()
@mute_logger('odoo.models.unlink', 'odoo.addons.mail.models.mail_mail')
def test_leave_validation_manager_by_officer_department_manager(self):
""" Officer validates manager-only leaves for co-workers from department he manages"""
self.leave_type.write({'validation_type': 'manager'})
self.employee_hruser.write({'department_id': self.hr_dept.id})
self.employee_leave.sudo().department_id.write({'manager_id': self.employee_hruser.id})
self.employee_leave.sudo(self.user_hruser).action_approve()
@mute_logger('odoo.models.unlink', 'odoo.addons.mail.models.mail_mail')
def test_leave_validation_manager_by_officer_department_manager_other(self):
""" Officer may not validates manager-only leaves for co-workers from department he does not"""
self.leave_type.write({'validation_type': 'manager'})
self.employee_hruser.write({'department_id': self.hr_dept.id})
self.employee_leave.sudo().department_id.write({'manager_id': self.employee_hrmanager.id})
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_manager_by_officer_manager(self):
""" Officer validates manager-only leaves for co-workers that he manages"""
self.leave_type.write({'validation_type': 'manager'})
self.employee_emp.write({'parent_id': self.employee_hruser.id})
self.employee_leave.sudo(self.user_hruser).action_approve()
@mute_logger('odoo.models.unlink', 'odoo.addons.mail.models.mail_mail')
def test_leave_validation_manager_by_officer_manager_other(self):
""" Officer may not validate manager-only leaves for co-workers he does not manage"""
self.leave_type.write({'validation_type': 'manager'})
self.employee_emp.write({'parent_id': self.employee_hrmanager.id})
with self.assertRaises(UserError):
self.employee_leave.sudo(self.user_hruser).action_approve()
with self.assertRaises(UserError):
self.employee_leave.sudo(self.user_hruser).write({'state': 'validate'})
# ----------------------------------------
# Validation: double
# ----------------------------------------
@mute_logger('odoo.models.unlink', 'odoo.addons.mail.models.mail_mail')
def test_leave_validation_both_by_manager(self):
""" Manager validates double validation leaves """
self.leave_type.write({'validation_type': 'both'})
self.employee_leave.sudo(self.user_hrmanager_id).action_approve()
self.employee_leave.sudo(self.user_hrmanager_id).action_validate()
@mute_logger('odoo.models.unlink', 'odoo.addons.mail.models.mail_mail')
def test_leave_validation_both_by_officer(self):
""" Officer may not validate double validation leaves """
self.leave_type.write({'validation_type': 'both'})
self.employee_leave.sudo(self.user_hruser).action_approve()
with self.assertRaises(UserError):
self.employee_leave.sudo(self.user_hruser).action_validate()
with self.assertRaises(UserError):
self.employee_leave.sudo(self.user_hruser).write({'state': 'validate'})
@mute_logger('odoo.models.unlink', 'odoo.addons.mail.models.mail_mail')
def test_leave_validation_both_by_officer_and_manager(self):
""" Officer + Manager complete double validation leaves """
self.leave_type.write({'validation_type': 'both'})
self.employee_leave.sudo(self.user_hruser).action_approve()
self.employee_leave.sudo(self.user_hrmanager_id).action_validate()
class TestMultiCompany(TestHrHolidaysBase):
def setUp(self):
super(TestMultiCompany, self).setUp()
self.new_company = self.env['res.company'].create({
'name': 'Crocodile Dundee Company',
})
self.leave_type = self.env['hr.leave.type'].create({
'name': 'Unlimited - Company New',
'limit': True,
'company_id': self.new_company.id,
'validation_type': 'hr',
})
self.rd_dept.manager_id = False
self.hr_dept.manager_id = False
self.employee_leave = self.env['hr.leave'].create({
'name': 'Test',
'holiday_status_id': self.leave_type.id,
'department_id': self.employee_emp.department_id.id,
'employee_id': self.employee_emp.id,
'date_from': datetime.now(),
'date_to': datetime.now() + relativedelta(days=1),
'number_of_days_temp': 1,
})
@mute_logger('odoo.models.unlink', 'odoo.addons.mail.models.mail_mail')
def test_leave_access_other_company_user(self):
employee_leave = self.employee_leave.sudo(self.user_employee)
with self.assertRaises(AccessError):
name = employee_leave.name
with self.assertRaises(AccessError):
employee_leave.action_approve()
@mute_logger('odoo.models.unlink', 'odoo.addons.mail.models.mail_mail')
def test_leave_access_other_company_officer(self):
employee_leave_hruser = self.employee_leave.sudo(self.user_hruser)
with self.assertRaises(AccessError):
name = employee_leave_hruser.name
with self.assertRaises(AccessError):
employee_leave_hruser.action_approve()
@mute_logger('odoo.models.unlink', 'odoo.addons.mail.models.mail_mail')
def test_leave_access_other_company_manager(self):
employee_leave_hrmanager = self.employee_leave.sudo(self.user_hrmanager)
with self.assertRaises(AccessError):
name = employee_leave_hrmanager.name
with self.assertRaises(AccessError):
employee_leave_hrmanager.action_approve()
@mute_logger('odoo.models.unlink', 'odoo.addons.mail.models.mail_mail')
def test_leave_access_no_company_user(self):
self.leave_type.write({'company_id': False})
employee_leave = self.employee_leave.sudo(self.user_employee)
name = employee_leave.name
with self.assertRaises(UserError):
employee_leave.action_approve()
self.assertEqual(employee_leave.state, 'confirm')
@mute_logger('odoo.models.unlink', 'odoo.addons.mail.models.mail_mail')
def test_leave_access_no_company_officer(self):
self.leave_type.write({'company_id': False})
employee_leave_hruser = self.employee_leave.sudo(self.user_hruser)
name = employee_leave_hruser.name
employee_leave_hruser.action_approve()
self.assertEqual(employee_leave_hruser.state, 'validate')
@mute_logger('odoo.models.unlink', 'odoo.addons.mail.models.mail_mail')
def test_leave_access_no_company_manager(self):
self.leave_type.write({'company_id': False})
employee_leave_hrmanager = self.employee_leave.sudo(self.user_hrmanager)
name = employee_leave_hrmanager.name
employee_leave_hrmanager.action_approve()
self.assertEqual(employee_leave_hrmanager.state, 'validate')
+1 -47
View File
@@ -72,15 +72,6 @@ class TestHolidaysFlow(TestHrHolidaysBase):
# Employee creates a leave request for another employee -> should crash
HolidaysEmployeeGroup = Requests.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,
})
Requests.search([('name', '=', 'Hol10')]).unlink()
# Employee creates a leave request in a no-limit category hr manager only
@@ -97,8 +88,6 @@ class TestHolidaysFlow(TestHrHolidaysBase):
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_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
@@ -119,14 +108,8 @@ class TestHolidaysFlow(TestHrHolidaysBase):
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
with self.assertRaises(UserError):
hol12_employee_group.action_approve()
self.assertEqual(hol12_user_group.state, 'confirm', 'hr_holidays: employee should not be able to validate its own leave request')
# HrUser validates the employee leave request -> should not work
with self.assertRaises(UserError):
hol12_user_group.action_approve()
# 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')
@@ -169,9 +152,7 @@ class TestHolidaysFlow(TestHrHolidaysBase):
})
# HrUser validates the first step
aloc1_user_group.action_approve()
# HrUser validates the second step -> should crash
with self.assertRaises(UserError):
aloc1_user_group.action_validate()
# HrManager validates the second step
aloc1_user_group.sudo(self.user_hrmanager_id).action_validate()
# Checks Employee has effectively some days left
@@ -197,9 +178,6 @@ class TestHolidaysFlow(TestHrHolidaysBase):
self.assertEqual(hol2.state, 'validate1',
'hr_holidays: first validation should lead to validate1 state')
# HrUser validates the second step -> should crash
with self.assertRaises(UserError):
hol2_user_group.action_validate()
# HrManager validates the second step
hol2_user_group.sudo(self.user_hrmanager_id).action_validate()
self.assertEqual(hol2.state, 'validate',
@@ -214,9 +192,6 @@ class TestHolidaysFlow(TestHrHolidaysBase):
# 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')
@@ -302,31 +277,10 @@ class TestHolidaysFlow(TestHrHolidaysBase):
'number_of_days_temp': 1,
})
# But not someone else's leave
with self.assertRaises(AccessError):
hol42.sudo(self.user_employee_id).action_draft()
# An officer should not be able to reset someone else's leave
with self.assertRaises(UserError):
hol42.sudo(self.user_hruser_id).action_draft()
# A manager should be able to reset someone else's leave
hol42.action_draft()
hol42.unlink()
# Officer should not be able to approve it's own leave
hol50 = HolidaysEmployeeGroup.sudo(self.user_hruser_id).create({
'name': 'Hol50',
'employee_id': self.employee_hruser_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_temp': 1,
})
with self.assertRaises(UserError):
hol50.action_approve()
# Manager should be able to approve it's own leave
hol51 = HolidaysEmployeeGroup.sudo(self.user_hrmanager_2_id).create({
'name': 'Hol51',