[IMP] hr_holidays: adjust access rights for time off manager

In time off, someone can be set as a time off manager for another employee
without needing any rights on the time off app. In order to
make it so they only have access to what's needed, this commit
applies the following changes:
- addition of a new default filter "Waiting for me" in the time off
management menu, which only displays the time offs that the user needs
to approve.
- removal of the menuitem "allocations" for those managers without time off
rights since they're not allowed to modify or create any.
- addition of the employee(s) choice for the time off if that user decides to
create a new time off from the management view.

task-3329715

closes odoo/odoo#122517

Signed-off-by: Sofie Gvaladze (sgv) <sgv@odoo.com>
This commit is contained in:
Dossogne Bertrand
2023-10-24 12:38:02 +00:00
parent 88e75fd5cd
commit ca0440b476
3 changed files with 61 additions and 14 deletions
+28 -4
View File
@@ -132,6 +132,7 @@ class HolidaysRequest(models.Model):
report_note = fields.Text('HR Comments', copy=False, groups="hr_holidays.group_hr_holidays_manager")
user_id = fields.Many2one('res.users', string='User', related='employee_id.user_id', related_sudo=True, compute_sudo=True, store=True, readonly=True, index=True)
manager_id = fields.Many2one('hr.employee', compute='_compute_from_employee_id', store=True, readonly=False)
is_user_only_responsible = fields.Boolean(compute="_compute_is_user_only_responsible")
# leave type configuration
holiday_status_id = fields.Many2one(
"hr.leave.type", compute='_compute_from_employee_id',
@@ -194,7 +195,8 @@ class HolidaysRequest(models.Model):
string='Allocation Mode', readonly=False, required=True, default='employee',
help='By Employee: Allocation/Request for individual Employee, By Employee Tag: Allocation/Request for group of employees in category')
employee_ids = fields.Many2many(
'hr.employee', compute='_compute_from_holiday_type', store=True, string='Employees', readonly=False, groups="hr_holidays.group_hr_holidays_user")
'hr.employee', compute='_compute_from_holiday_type', store=True, string='Employees', readonly=True, groups="hr_holidays.group_hr_holidays_responsible")
allowed_employee_ids = fields.Many2many('hr.employee', compute='_compute_allowed_employee_ids')
multi_employee = fields.Boolean(
compute='_compute_from_employee_ids', store=True, compute_sudo=False,
help='Holds whether this allocation concerns more than 1 employee')
@@ -418,6 +420,17 @@ class HolidaysRequest(models.Model):
holiday.employee_id = False
holiday.multi_employee = (len(holiday.employee_ids) > 1)
@api.depends_context('uid')
def _compute_allowed_employee_ids(self):
allowed_employees = self.env['hr.employee'].search([
('active', '=', True),
('company_id', 'in', self.env.companies.ids)])
if not self.env.user.has_group('hr_holidays.group_hr_holidays_user'):
user = self.env.user
self.allowed_employee_ids = allowed_employees.filtered(lambda emp: emp.user_id == user or emp.leave_manager_id == user)
else:
self.allowed_employee_ids = allowed_employees
@api.depends('holiday_type')
def _compute_from_holiday_type(self):
allocation_from_domain = self.env['hr.leave.allocation']
@@ -463,6 +476,13 @@ class HolidaysRequest(models.Model):
if holiday.employee_id and not holiday.holiday_status_id.with_context(employee_id=holiday.employee_id.id).has_valid_allocation:
holiday.holiday_status_id = False
@api.depends_context('uid')
@api.depends('employee_id')
def _compute_is_user_only_responsible(self):
user = self.env.user
self.is_user_only_responsible = user.has_group('hr_holidays.group_hr_holidays_responsible')\
and not user.has_group('hr_holidays.group_hr_holidays_user')
@api.depends('employee_id', 'holiday_type')
def _compute_department_id(self):
for holiday in self:
@@ -1408,14 +1428,18 @@ class HolidaysRequest(models.Model):
holiday.check_access_rule('write')
# This handles states validate1 validate and refuse
if holiday.employee_id == current_employee:
raise UserError(_('Only a Time Off Manager can approve/refuse its own requests.'))
if holiday.employee_id == current_employee\
and self.env.user != holiday.employee_id.leave_manager_id\
and not is_officer:
raise UserError(_('Only a Time Off Officer or Manager can approve/refuse its own requests.'))
if (state == 'validate1' and val_type == 'both') and holiday.holiday_type == 'employee':
if not is_officer and self.env.user != holiday.employee_id.leave_manager_id:
raise UserError(_('You must be either %s\'s manager or Time off Manager to approve this leave') % (holiday.employee_id.name))
if (state == 'validate' and val_type == 'manager') and self.env.user != (holiday.employee_id | holiday.sudo().employee_ids).leave_manager_id:
if (state == 'validate' and val_type == 'manager')\
and self.env.user != (holiday.employee_id | holiday.sudo().employee_ids).leave_manager_id\
and not is_officer:
if holiday.employee_id:
employees = holiday.employee_id
else:
@@ -59,7 +59,8 @@
name="Allocations"
parent="menu_hr_holidays_management"
action="hr_leave_allocation_action_approve_department"
sequence="2"/>
sequence="2"
groups="hr_holidays.group_hr_holidays_user"/>
<menuitem
id="menu_hr_holidays_report"
+31 -9
View File
@@ -43,6 +43,29 @@
<field name="employee_id"/>
<field name="holiday_status_id"/>
<field name="name"/>
<filter domain="[
('state','in',['confirm']),
'|',
('employee_id.user_id', '!=', uid),
'&amp;',
('employee_id.user_id', '=', uid),
('employee_id.leave_manager_id', '=', uid)]"
string="Waiting For Me"
name="waiting_for_me"
groups="hr_holidays.group_hr_holidays_responsible,!hr_holidays.group_hr_holidays_user"/>
<filter domain="[
('state','in',['confirm','validate1']),
'|',
('employee_id.user_id', '!=', uid),
'|',
'&amp;',
('state','=','confirm'),
('holiday_status_id.leave_validation_type','=','hr'),
('state','=','validate1')]"
string="Waiting For Me"
name="waiting_for_me_manager"
groups="hr_holidays.group_hr_holidays_user"/>
<separator/>
<filter domain="[('state','in',('confirm','validate1'))]" string="First Approval" name="approve"/>
<filter domain="[('state', '=', 'validate1')]" string="Second Approval" name="second_approval"/>
<filter string="Approved" domain="[('state', '=', 'validate')]" name="validated"/>
@@ -426,14 +449,15 @@
<attribute name="invisible">0</attribute>
</xpath>
<xpath expr="//field[@name='holiday_status_id']" position="before">
<field name="holiday_type" string="Mode"
groups="hr_holidays.group_hr_holidays_user" readonly="state not in ['confirm', 'draft']"/>
<field name="is_user_only_responsible" invisible="1"/>
<field name="holiday_type" string="Mode" groups="hr_holidays.group_hr_holidays_user" readonly="state not in ['confirm', 'draft']"/>
<field name="mode_company_id" string="Company" groups="hr_holidays.group_hr_holidays_user" invisible="holiday_type != 'company'" readonly="state not in ['confirm', 'draft']" required="holiday_type == 'company'"/>
<field name="category_id" groups="hr_holidays.group_hr_holidays_user" invisible="holiday_type != 'category'" readonly="state not in ['confirm', 'draft']" required="holiday_type == 'category'"/>
<field name="department_id" groups="hr_holidays.group_hr_holidays_user" invisible="holiday_type != 'department'" readonly="state in ['cancel', 'refuse', 'validate', 'validate1']" required="holiday_type == 'department'"/>
<field name="multi_employee" invisible="1" force_save="1"/>
<field name="employee_id" groups="hr_holidays.group_hr_holidays_user" invisible="holiday_type != 'employee' or state != 'validate' or not employee_id" readonly="state in ['cancel', 'refuse', 'validate', 'validate1']" widget="many2one_avatar_user"/>
<field name="employee_ids" groups="hr_holidays.group_hr_holidays_user" invisible="holiday_type != 'employee' or (state == 'validate' and employee_id)" readonly="state in ['cancel', 'refuse', 'validate', 'validate1']" required="holiday_type == 'employee' and state in ('draft', 'cancel', 'refuse')" widget="many2many_tags_avatar"/>
<field name="multi_employee" invisible="1" force_save="1"/>
<field name="allowed_employee_ids" invisible="1"/>
<field name="employee_id" groups="hr_holidays.group_hr_holidays_user" domain="[('id', 'in', allowed_employee_ids)]" invisible="holiday_type != 'employee' or state != 'validate' or not employee_id" readonly="state in ['cancel', 'refuse', 'validate', 'validate1']" widget="many2one_avatar_user"/>
<field name="employee_ids" groups="hr_holidays.group_hr_holidays_user" domain="[('id', 'in', allowed_employee_ids)]" invisible="holiday_type != 'employee' or (state == 'validate' and employee_id)" readonly="state in ['cancel', 'refuse', 'validate', 'validate1']" required="holiday_type == 'employee' and state in ('draft', 'cancel', 'refuse')" widget="many2many_tags_avatar"/>
</xpath>
<field name="name" position="replace"/>
<field name="user_id" position="before">
@@ -678,10 +702,8 @@
<field name="view_mode">tree,kanban,form,calendar,activity</field>
<field name="search_view_id" ref="hr_holidays.hr_leave_view_search_manager"/>
<field name="context">{
'search_default_approve': 1,
'search_default_my_team': 2,
'search_default_active_employee': 3,
'search_default_active_time_off': 4,
'search_default_waiting_for_me': 1,
'search_default_waiting_for_me_manager': 2,
'hide_employee_name': 1,
'holiday_status_display_name': False}
</field>