Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[14.0][ADD] hr_holidays_security: New module #143

Open
wants to merge 1 commit into
base: 14.0
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
98 changes: 98 additions & 0 deletions hr_holidays_security/README.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
====================
HR Holidays Security
====================

..
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! This file is generated by oca-gen-addon-readme !!
!! changes will be overwritten. !!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! source digest: sha256:1c52c1427940b2c6755bb73a4807a92cf62c513359e1f21dfd3d0b46495ea1c0
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

.. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png
:target: https://odoo-community.org/page/development-status
:alt: Beta
.. |badge2| image:: https://img.shields.io/badge/licence-AGPL--3-blue.png
:target: http://www.gnu.org/licenses/agpl-3.0-standalone.html
:alt: License: AGPL-3
.. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fhr--holidays-lightgray.png?logo=github
:target: https://github.com/OCA/hr-holidays/tree/14.0/hr_holidays_security
:alt: OCA/hr-holidays
.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png
:target: https://translation.odoo-community.org/projects/hr-holidays-14-0/hr-holidays-14-0-hr_holidays_security
:alt: Translate me on Weblate
.. |badge5| image:: https://img.shields.io/badge/runboat-Try%20me-875A7B.png
:target: https://runboat.odoo-community.org/builds?repo=OCA/hr-holidays&target_branch=14.0
:alt: Try me on Runboat

|badge1| |badge2| |badge3| |badge4| |badge5|

This module extends the permissions of Time Off responsibles and
approvers to flex their team assignments.

**Table of contents**

.. contents::
:local:

Use Cases / Context
===================

In a large organization Time Off Responsible users powers can be so
rigid, as they aren't allowed to fully approve their team's requests.
Time Off All Approvers have a too much approval scope while Time Off
Manager would be too powerful.

This module aims to adjust those powers for each group, respecting the
core workflow.

Usage
=====

Now a Time Off Responsible and All Approvals users can view, creat,
edit, reject, set as draft leaves and allocation from their team
employees.

Bug Tracker
===========

Bugs are tracked on `GitHub Issues <https://github.com/OCA/hr-holidays/issues>`_.
In case of trouble, please check there if your issue has already been reported.
If you spotted it first, help us to smash it by providing a detailed and welcomed
`feedback <https://github.com/OCA/hr-holidays/issues/new?body=module:%20hr_holidays_security%0Aversion:%2014.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**>`_.

Do not contact contributors directly about support or help with technical issues.

Credits
=======

Authors
-------

* Tecnativa
*

Contributors
------------

- `Tecnativa <https://tecnativa.com>`__

- David Vidal

Maintainers
-----------

This module is maintained by the OCA.

.. image:: https://odoo-community.org/logo.png
:alt: Odoo Community Association
:target: https://odoo-community.org

OCA, or the Odoo Community Association, is a nonprofit organization whose
mission is to support the collaborative development of Odoo features and
promote its widespread use.

This module is part of the `OCA/hr-holidays <https://github.com/OCA/hr-holidays/tree/14.0/hr_holidays_security>`_ project on GitHub.

You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.
1 change: 1 addition & 0 deletions hr_holidays_security/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
from . import models
18 changes: 18 additions & 0 deletions hr_holidays_security/__manifest__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# Copyright 2024 Tecnativa - David Vidal
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
{
"name": "HR Holidays Security",
"summary": "Allow time-off responsibles to fully manage their team requests",
"version": "14.0.1.0.0",
"license": "AGPL-3",
"category": "Human Resources",
"author": "Tecnativa, Odoo Community Association (OCA),",
"website": "https://github.com/OCA/hr-holidays",
"depends": ["hr_holidays"],
"data": [
"security/security.xml",
"views/hr_leave_views.xml",
"views/hr_leave_allocation_views.xml",
],
"installable": True,
}
3 changes: 3 additions & 0 deletions hr_holidays_security/models/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
from . import hr_leave
from . import hr_leave_allocation
from . import ir_actions_act_window
71 changes: 71 additions & 0 deletions hr_holidays_security/models/hr_leave.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
# Copyright 2024 Tecnativa - David Vidal
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
from odoo import _, models
from odoo.exceptions import UserError


class HrLeave(models.Model):
_inherit = "hr.leave"

def _check_approval_update(self, state):
"""Check if target state is achievable"""
if (
not self.env.user.has_group("hr_holidays.group_hr_holidays_responsible")
or self.env.user.has_group("hr_holidays.group_hr_holidays_manager")
or self.env.is_superuser()
):
return super()._check_approval_update(state)
# Do nothing
if state == "confirm":
return

Check warning on line 20 in hr_holidays_security/models/hr_leave.py

View check run for this annotation

Codecov / codecov/patch

hr_holidays_security/models/hr_leave.py#L20

Added line #L20 was not covered by tests
current_employee = self.env.user.employee_id
is_officer = self.env.user.has_group("hr_holidays.group_hr_holidays_user")
is_responsible = self.env.user.has_group(
"hr_holidays.group_hr_holidays_responsible"
)

for holiday in self:
val_type = holiday.validation_type
if state != "draft":
if (
val_type == "no_validation"
and current_employee == holiday.employee_id
):
continue

Check warning on line 34 in hr_holidays_security/models/hr_leave.py

View check run for this annotation

Codecov / codecov/patch

hr_holidays_security/models/hr_leave.py#L34

Added line #L34 was not covered by tests
# use ir.rule based first access check: department, members, ...
# (see security.xml)
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 (
(state == "validate1" and val_type == "both")
or (state == "validate" and val_type == "manager")
and holiday.holiday_type == "employee"
):
if (
not is_officer
and self.env.user != holiday.employee_id.leave_manager_id
):
raise UserError(

Check warning on line 54 in hr_holidays_security/models/hr_leave.py

View check run for this annotation

Codecov / codecov/patch

hr_holidays_security/models/hr_leave.py#L54

Added line #L54 was not covered by tests
_(
"You must be either %s's manager or Time off Manager "
"to approve this leave"
)
% (holiday.employee_id.name)
)
if (
not is_responsible
and (state == "validate" and val_type == "hr")
and holiday.holiday_type == "employee"
):
raise UserError(

Check warning on line 66 in hr_holidays_security/models/hr_leave.py

View check run for this annotation

Codecov / codecov/patch

hr_holidays_security/models/hr_leave.py#L66

Added line #L66 was not covered by tests
_(
"You must either be a Time off Officer or Time off Manager "
"to approve this leave"
)
)
82 changes: 82 additions & 0 deletions hr_holidays_security/models/hr_leave_allocation.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
# Copyright 2024 Tecnativa - David Vidal
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
from odoo import api, fields, models


class HrLeaveAllocation(models.Model):
_inherit = "hr.leave.allocation"

private_name = fields.Char(groups="hr_holidays.group_hr_holidays_responsible")
allowed_holyday_status_ids = fields.Many2many(
comodel_name="hr.leave.type", compute="_compute_allowed_holyday_status_ids"
)

def _get_allowed_holyday_status_domain(self):
if self.user_has_groups("hr_holidays.group_hr_holidays_user") or (
self._user_is_bare_responsible()
and self.employee_id.user_id != self.env.user
):
return [("valid", "=", True), ("allocation_type", "!=", "no")]

Check warning on line 19 in hr_holidays_security/models/hr_leave_allocation.py

View check run for this annotation

Codecov / codecov/patch

hr_holidays_security/models/hr_leave_allocation.py#L19

Added line #L19 was not covered by tests
else:
return [("valid", "=", True), ("allocation_type", "=", "fixed_allocation")]

Check warning on line 21 in hr_holidays_security/models/hr_leave_allocation.py

View check run for this annotation

Codecov / codecov/patch

hr_holidays_security/models/hr_leave_allocation.py#L21

Added line #L21 was not covered by tests

@api.depends("employee_id")
def _compute_allowed_holyday_status_ids(self):
"""Responsibles can only do allocations on their team members but on
themselves"""
for allocation in self:
allocation.allowed_holyday_status_ids = self.env["hr.leave.type"].search(

Check warning on line 28 in hr_holidays_security/models/hr_leave_allocation.py

View check run for this annotation

Codecov / codecov/patch

hr_holidays_security/models/hr_leave_allocation.py#L28

Added line #L28 was not covered by tests
allocation._get_allowed_holyday_status_domain()
)

@api.model
def _user_is_bare_responsible(self):
return self.env.user.has_group(

Check warning on line 34 in hr_holidays_security/models/hr_leave_allocation.py

View check run for this annotation

Codecov / codecov/patch

hr_holidays_security/models/hr_leave_allocation.py#L34

Added line #L34 was not covered by tests
"hr_holidays.group_hr_holidays_responsible"
) and not self.env.user.has_group("hr_holidays.group_hr_holidays_user")

def _compute_description(self):
self.check_access_rights("read")
self.check_access_rule("read")

Check warning on line 40 in hr_holidays_security/models/hr_leave_allocation.py

View check run for this annotation

Codecov / codecov/patch

hr_holidays_security/models/hr_leave_allocation.py#L39-L40

Added lines #L39 - L40 were not covered by tests
if not self._user_is_bare_responsible():
return super()._compute_description()

Check warning on line 42 in hr_holidays_security/models/hr_leave_allocation.py

View check run for this annotation

Codecov / codecov/patch

hr_holidays_security/models/hr_leave_allocation.py#L42

Added line #L42 was not covered by tests
for allocation in self:
if (
allocation.employee_id.user_id == self.env.user
or allocation.manager_id == self.env.user
):
allocation.name = allocation.sudo().private_name

Check warning on line 48 in hr_holidays_security/models/hr_leave_allocation.py

View check run for this annotation

Codecov / codecov/patch

hr_holidays_security/models/hr_leave_allocation.py#L48

Added line #L48 was not covered by tests
else:
allocation.name = "*****"

Check warning on line 50 in hr_holidays_security/models/hr_leave_allocation.py

View check run for this annotation

Codecov / codecov/patch

hr_holidays_security/models/hr_leave_allocation.py#L50

Added line #L50 was not covered by tests

def _inverse_description(self):
if not self._user_is_bare_responsible():
return super()._inverse_description()

Check warning on line 54 in hr_holidays_security/models/hr_leave_allocation.py

View check run for this annotation

Codecov / codecov/patch

hr_holidays_security/models/hr_leave_allocation.py#L54

Added line #L54 was not covered by tests
for allocation in self:
if (
allocation.employee_id.user_id == self.env.user
or allocation.manager_id == self.env.user
):
allocation.sudo().private_name = allocation.name

Check warning on line 60 in hr_holidays_security/models/hr_leave_allocation.py

View check run for this annotation

Codecov / codecov/patch

hr_holidays_security/models/hr_leave_allocation.py#L60

Added line #L60 was not covered by tests

def _search_description(self, operator, value):
if not self._user_is_bare_responsible():
return super()._search_description(operator, value)
domain = [("private_name", operator, value)]
allocations = self.sudo().search(domain)
return [("id", "in", allocations.ids)]

Check warning on line 67 in hr_holidays_security/models/hr_leave_allocation.py

View check run for this annotation

Codecov / codecov/patch

hr_holidays_security/models/hr_leave_allocation.py#L64-L67

Added lines #L64 - L67 were not covered by tests

def _check_approval_update(self, state):
# Lift restrictions
if not self.env.user.has_group("hr_holidays.group_hr_holidays_responsible"):
return super()._check_approval_update(state)
current_employee = self.env.user.employee_id

Check warning on line 73 in hr_holidays_security/models/hr_leave_allocation.py

View check run for this annotation

Codecov / codecov/patch

hr_holidays_security/models/hr_leave_allocation.py#L72-L73

Added lines #L72 - L73 were not covered by tests
if not current_employee:
return

Check warning on line 75 in hr_holidays_security/models/hr_leave_allocation.py

View check run for this annotation

Codecov / codecov/patch

hr_holidays_security/models/hr_leave_allocation.py#L75

Added line #L75 was not covered by tests
for holiday in self:
if state == "confirm":
continue

Check warning on line 78 in hr_holidays_security/models/hr_leave_allocation.py

View check run for this annotation

Codecov / codecov/patch

hr_holidays_security/models/hr_leave_allocation.py#L78

Added line #L78 was not covered by tests
if self.env.user == holiday.employee_id.leave_manager_id:
# use ir.rule based first access check: department, members, ...
# (see security.xml)
holiday.check_access_rule("write")

Check warning on line 82 in hr_holidays_security/models/hr_leave_allocation.py

View check run for this annotation

Codecov / codecov/patch

hr_holidays_security/models/hr_leave_allocation.py#L82

Added line #L82 was not covered by tests
46 changes: 46 additions & 0 deletions hr_holidays_security/models/ir_actions_act_window.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
# Copyright 2024 Tecnativa - David Vidal
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
from odoo import models


class IrActionsActWindow(models.Model):
_inherit = "ir.actions.act_window"

def _compute_views(self):
# HACK: Not a very nice override but negative groups don't work right in this
# case as they don't trigger the necessary compute changes in the views. So we
# want to use a different view for this
res = super()._compute_views()

Check warning on line 13 in hr_holidays_security/models/ir_actions_act_window.py

View check run for this annotation

Codecov / codecov/patch

hr_holidays_security/models/ir_actions_act_window.py#L13

Added line #L13 was not covered by tests
leave_action = self.filtered(
lambda x: x
== self.env.ref("hr_holidays.hr_leave_action_action_approve_department")
)
allocation_action = self.filtered(
lambda x: x
== self.env.ref("hr_holidays.hr_leave_allocation_action_approve_department")
)
if leave_action or allocation_action:
bare_responsible = self.env.user.has_group(

Check warning on line 23 in hr_holidays_security/models/ir_actions_act_window.py

View check run for this annotation

Codecov / codecov/patch

hr_holidays_security/models/ir_actions_act_window.py#L23

Added line #L23 was not covered by tests
"hr_holidays.group_hr_holidays_responsible"
) and not self.env.user.has_group("hr_holidays.group_hr_holidays_user")
if bare_responsible and leave_action:
bare_responsible_form = self.env.ref(

Check warning on line 27 in hr_holidays_security/models/ir_actions_act_window.py

View check run for this annotation

Codecov / codecov/patch

hr_holidays_security/models/ir_actions_act_window.py#L27

Added line #L27 was not covered by tests
"hr_holidays_security.hr_leave_view_form_responsible"
)
leave_action.views = [
(view, view_type)
if view_type != "form"
else (bare_responsible_form.id, view_type)
for view, view_type in leave_action.views
]
if bare_responsible and allocation_action:
bare_responsible_form = self.env.ref(

Check warning on line 37 in hr_holidays_security/models/ir_actions_act_window.py

View check run for this annotation

Codecov / codecov/patch

hr_holidays_security/models/ir_actions_act_window.py#L37

Added line #L37 was not covered by tests
"hr_holidays_security.hr_leave_allocation_view_form_manager"
)
allocation_action.views = [
(view, view_type)
if view_type != "form"
else (bare_responsible_form.id, view_type)
for view, view_type in allocation_action.views
]
return res

Check warning on line 46 in hr_holidays_security/models/ir_actions_act_window.py

View check run for this annotation

Codecov / codecov/patch

hr_holidays_security/models/ir_actions_act_window.py#L46

Added line #L46 was not covered by tests
5 changes: 5 additions & 0 deletions hr_holidays_security/readme/CONTEXT.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
In a large organization Time Off Responsible users powers can be so rigid, as they
aren't allowed to fully approve their team's requests. Time Off All Approvers have a
too much approval scope while Time Off Manager would be too powerful.

This module aims to adjust those powers for each group, respecting the core workflow.
2 changes: 2 additions & 0 deletions hr_holidays_security/readme/CONTRIBUTORS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
- [Tecnativa](https://tecnativa.com)
- David Vidal
2 changes: 2 additions & 0 deletions hr_holidays_security/readme/DESCRIPTION.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
This module extends the permissions of Time Off responsibles and approvers to flex
their team assignments.
2 changes: 2 additions & 0 deletions hr_holidays_security/readme/USAGE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Now a Time Off Responsible and All Approvals users can view, creat, edit, reject, set as
draft leaves and allocation from their team employees.
9 changes: 9 additions & 0 deletions hr_holidays_security/security/security.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<?xml version='1.0' encoding='UTF-8' ?>
<odoo>
<record id="hr_holidays.hr_leave_allocation_rule_officer_update" model="ir.rule">
<field
name="groups"
eval="[(4, ref('hr_holidays.group_hr_holidays_responsible'))]"
/>
</record>
</odoo>
Loading
Loading