diff --git a/hr_holidays_team_manager/README.rst b/hr_holidays_team_manager/README.rst new file mode 100644 index 00000000000..8e894d6dc16 --- /dev/null +++ b/hr_holidays_team_manager/README.rst @@ -0,0 +1,84 @@ +======================== +HR Holidays Team Manager +======================== + +.. + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! This file is generated by oca-gen-addon-readme !! + !! changes will be overwritten. !! + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! source digest: sha256:ccedfc57a9859a7443298383150ade28cdd0ad1c30437f7a23ed63e2754ed2ae + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +.. |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-lightgray.png?logo=github + :target: https://github.com/OCA/hr/tree/16.0/hr_holidays_team_manager + :alt: OCA/hr +.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png + :target: https://translation.odoo-community.org/projects/hr-16-0/hr-16-0-hr_holidays_team_manager + :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&target_branch=16.0 + :alt: Try me on Runboat + +|badge1| |badge2| |badge3| |badge4| |badge5| + +Add a new group Time off/Team manager that can only view, write, and create time off +requests and time off assignment requests for employees who belong to the same department + +**Table of contents** + +.. contents:: + :local: + +Usage +===== + +Add a new group Time off/Team manager that can only view, write, and create time off +requests and time off assignment requests for employees who belong to the same department + +Bug Tracker +=========== + +Bugs are tracked on `GitHub 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 `_. + +Do not contact contributors directly about support or help with technical issues. + +Credits +======= + +Authors +~~~~~~~ + +* Open Source Integrators + +Contributors +~~~~~~~~~~~~ + +* Murtaza Mithaiwala + + +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 `_ project on GitHub. + +You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute. diff --git a/hr_holidays_team_manager/__init__.py b/hr_holidays_team_manager/__init__.py new file mode 100644 index 00000000000..0650744f6bc --- /dev/null +++ b/hr_holidays_team_manager/__init__.py @@ -0,0 +1 @@ +from . import models diff --git a/hr_holidays_team_manager/__manifest__.py b/hr_holidays_team_manager/__manifest__.py new file mode 100644 index 00000000000..13a18747d2a --- /dev/null +++ b/hr_holidays_team_manager/__manifest__.py @@ -0,0 +1,19 @@ +# Copyright (C) 2024 - TODAY, Open Source Integrators +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +{ + "name": "HR Holidays Team Manager", + "version": "16.0.1.0.0", + "license": "AGPL-3", + "author": "Open Source Integrators, " "Odoo Community Association (OCA)", + "maintainer": "Open Source Integrators", + "website": "https://github.com/OCA/hr", + "category": "HR", + "depends": ["hr_holidays"], + "data": [ + "data/hr_holidays_rules.xml", + "data/hr_holidays_security.xml", + "views/hr_leave_allocation_views.xml", + ], + "installable": True, +} diff --git a/hr_holidays_team_manager/data/hr_holidays_rules.xml b/hr_holidays_team_manager/data/hr_holidays_rules.xml new file mode 100644 index 00000000000..c6e84ddaf03 --- /dev/null +++ b/hr_holidays_team_manager/data/hr_holidays_rules.xml @@ -0,0 +1,10 @@ + + + + + + + diff --git a/hr_holidays_team_manager/data/hr_holidays_security.xml b/hr_holidays_team_manager/data/hr_holidays_security.xml new file mode 100644 index 00000000000..2a16e36144f --- /dev/null +++ b/hr_holidays_team_manager/data/hr_holidays_security.xml @@ -0,0 +1,60 @@ + + + + Time off/Team manager + + + + + Time off/Holiday Officer + + + + + + + + + + + Time off: Team manager time off same department + + ['|', + ('employee_id.department_id', 'in',[user.employee_ids.department_id.id]), + ('employee_ids.department_id', 'in', [user.employee_ids.department_id.id])] + + + + + + + + + + + Time off: Team manager time off allocation same department + + ['|', + ('employee_id.department_id', 'in', [user.employee_ids.department_id.id]), + ('employee_ids.department_id', 'in',[user.employee_ids.department_id.id])] + + + + + + + diff --git a/hr_holidays_team_manager/models/__init__.py b/hr_holidays_team_manager/models/__init__.py new file mode 100644 index 00000000000..7b1d737526f --- /dev/null +++ b/hr_holidays_team_manager/models/__init__.py @@ -0,0 +1,2 @@ +from . import hr_employee_base +from . import hr_leave_allocation diff --git a/hr_holidays_team_manager/models/hr_employee_base.py b/hr_holidays_team_manager/models/hr_employee_base.py new file mode 100644 index 00000000000..2a48dacb5a7 --- /dev/null +++ b/hr_holidays_team_manager/models/hr_employee_base.py @@ -0,0 +1,53 @@ +# Part of Odoo. See LICENSE file for full copyright and licensing details. + +from odoo import api, models + + +class HrEmployeeBase(models.AbstractModel): + _inherit = "hr.employee.base" + + def search(self, args, offset=0, limit=None, order=None, count=False): + params = self.env.context.get("params") + if params: + model = params.get("model") + if not self.env.context.get("by_pass"): + if ( + model in ["hr.leave", "hr.leave.allocation"] + and self.env.user.has_group("hr_holidays.group_hr_holidays_user") + and not self.env.user.has_group( + "hr_holidays_team_manager.group_hr_holidays_officer" + ) + ): + if args is None: + args = [] + employee_id = self.env.user.with_context(by_pass=True).employee_ids + if employee_id: + args += [ + ("department_id", "=", employee_id[0].department_id.id) + ] + + return super().search( + args, offset=offset, limit=limit, order=order, count=count + ) + + @api.model + def name_search(self, name="", args=None, operator="ilike", limit=100): + context = self.env.context + if context: + if not self.env.context.get("by_pass"): + if ( + [context.get("hr_leave_allocation") or context.get("hr_leave")] + and self.env.user.has_group("hr_holidays.group_hr_holidays_user") + and not self.env.user.has_group( + "hr_holidays_team_manager.group_hr_holidays_officer" + ) + ): + if args is None: + args = [] + employee_id = self.env.user.with_context(by_pass=True).employee_ids + if employee_id: + args += [ + ("department_id", "=", employee_id[0].department_id.id) + ] + + return super().name_search(name=name, args=args, operator=operator, limit=limit) diff --git a/hr_holidays_team_manager/models/hr_leave_allocation.py b/hr_holidays_team_manager/models/hr_leave_allocation.py new file mode 100644 index 00000000000..06044c21ffd --- /dev/null +++ b/hr_holidays_team_manager/models/hr_leave_allocation.py @@ -0,0 +1,17 @@ +# Part of Odoo. See LICENSE file for full copyright and licensing details. + +from odoo import _, models +from odoo.exceptions import ValidationError + + +class HolidaysAllocation(models.Model): + _inherit = "hr.leave.allocation" + + def action_validate(self): + if self.env.user.has_group( + "hr_holidays.group_hr_holidays_user" + ) and not self.env.user.has_group( + "hr_holidays_team_manager.group_hr_holidays_officer" + ): + raise ValidationError(_("Team managers can't approve time off allocations")) + return super().action_validate() diff --git a/hr_holidays_team_manager/readme/CONTRIBUTORS.rst b/hr_holidays_team_manager/readme/CONTRIBUTORS.rst new file mode 100644 index 00000000000..7ff670466b1 --- /dev/null +++ b/hr_holidays_team_manager/readme/CONTRIBUTORS.rst @@ -0,0 +1,2 @@ +* Murtaza Mithaiwala + diff --git a/hr_holidays_team_manager/readme/DESCRIPTION.rst b/hr_holidays_team_manager/readme/DESCRIPTION.rst new file mode 100644 index 00000000000..addc3cd5589 --- /dev/null +++ b/hr_holidays_team_manager/readme/DESCRIPTION.rst @@ -0,0 +1,2 @@ +Add a new group Time off/Team manager that can only view, write, and create time off +requests and time off assignment requests for employees who belong to the same department \ No newline at end of file diff --git a/hr_holidays_team_manager/readme/USAGE.rst b/hr_holidays_team_manager/readme/USAGE.rst new file mode 100644 index 00000000000..addc3cd5589 --- /dev/null +++ b/hr_holidays_team_manager/readme/USAGE.rst @@ -0,0 +1,2 @@ +Add a new group Time off/Team manager that can only view, write, and create time off +requests and time off assignment requests for employees who belong to the same department \ No newline at end of file diff --git a/hr_holidays_team_manager/static/description/index.html b/hr_holidays_team_manager/static/description/index.html new file mode 100644 index 00000000000..82089a799e7 --- /dev/null +++ b/hr_holidays_team_manager/static/description/index.html @@ -0,0 +1,427 @@ + + + + + +HR Holidays Team Manager + + + +
+

HR Holidays Team Manager

+ + +

Beta License: AGPL-3 OCA/hr Translate me on Weblate Try me on Runboat

+

Add a new group Time off/Team manager that can only view, write, and create time off +requests and time off assignment requests for employees who belong to the same department

+

Table of contents

+ +
+

Usage

+

Add a new group Time off/Team manager that can only view, write, and create time off +requests and time off assignment requests for employees who belong to the same department

+
+
+

Bug Tracker

+

Bugs are tracked on GitHub 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.

+

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

+
+
+

Credits

+
+

Authors

+
    +
  • Open Source Integrators
  • +
+
+ +
+

Maintainers

+

This module is maintained by the OCA.

+Odoo Community Association +

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 project on GitHub.

+

You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.

+
+
+
+ + diff --git a/hr_holidays_team_manager/tests/__init__.py b/hr_holidays_team_manager/tests/__init__.py new file mode 100644 index 00000000000..ee92587bf35 --- /dev/null +++ b/hr_holidays_team_manager/tests/__init__.py @@ -0,0 +1 @@ +from . import test_hr_holidays_team_manager diff --git a/hr_holidays_team_manager/tests/test_hr_holidays_team_manager.py b/hr_holidays_team_manager/tests/test_hr_holidays_team_manager.py new file mode 100644 index 00000000000..dbf3b8212ae --- /dev/null +++ b/hr_holidays_team_manager/tests/test_hr_holidays_team_manager.py @@ -0,0 +1,117 @@ +from odoo import fields +from odoo.exceptions import ValidationError +from odoo.tools import relativedelta + +from odoo.addons.base.tests.common import BaseCommon + + +class TestHRHolidaysTeamManager(BaseCommon): + @classmethod + def setUpClass(cls): + super().setUpClass() + cls.emp_obj = cls.env["hr.employee"] + cls.user = cls.env["res.users"].create( + { + "name": "Test User 1", + "login": "test", + "groups_id": [ + (4, cls.env.ref("hr_holidays.group_hr_holidays_user").id) + ], + } + ) + cls.department = cls.env["hr.department"].create( + { + "name": "Test Department", + } + ) + cls.department_1 = cls.env["hr.department"].create( + { + "name": "Test Department 2", + } + ) + cls.employee_1 = cls.emp_obj.create( + { + "name": "Test employee 1", + "department_id": cls.department.id, + "user_id": cls.user.id, + "work_email": "test@test.com", + } + ) + cls.employee_2 = cls.emp_obj.create( + {"name": "Test employee 2", "department_id": cls.department_1.id} + ) + + cls.employee_3 = cls.emp_obj.create( + { + "name": "Test employee 3", + "department_id": cls.department.id, + "work_email": "test@demo.com", + } + ) + cls.leave_type = cls.env["hr.leave.type"].create( + { + "requires_allocation": "no", + "name": "Legal Leaves", + "time_type": "leave", + } + ) + cls.leave_type = cls.env.ref("hr_holidays.holiday_status_unpaid") + cls.paid_type = cls.env.ref("hr_holidays.holiday_status_cl") + + def test_hr_leave(self): + employee_ids = ( + self.emp_obj.with_context(hr_leave=True).with_user(self.user).name_search() + ) + self.assertEqual(len(employee_ids), 2) + self.assertEqual(employee_ids[0][0], self.employee_1.id) + self.assertEqual(employee_ids[1][0], self.employee_3.id) + self.leaves = self.env["hr.leave"].create( + { + "date_from": fields.date.today() + relativedelta(days=-2), + "date_to": fields.date.today() + relativedelta(days=2), + "holiday_status_id": self.leave_type.id, + "employee_id": self.employee_3.id, + } + ) + self.leaves.with_user(self.user).action_approve() + + self.assertEqual(self.leaves.state, "validate1") + self.leaves.with_user(self.user).action_validate() + self.assertEqual(self.leaves.state, "validate") + + leave_ids = ( + self.env["hr.leave"] + .with_user(self.user) + .with_context(**{"params": {"model": "hr.leave"}}) + .search([]) + ) + self.assertEqual(len(leave_ids), 1) + + def test_hr_leave_allocation(self): + employee_ids = ( + self.emp_obj.with_context(hr_leave_allocation=True) + .with_user(self.user) + .name_search() + ) + self.assertEqual(len(employee_ids), 2) + self.assertEqual(employee_ids[0][0], self.employee_1.id) + self.assertEqual(employee_ids[1][0], self.employee_3.id) + + self.leaves = self.env["hr.leave.allocation"].create( + { + "date_from": fields.date.today() + relativedelta(days=-2), + "date_to": fields.date.today() + relativedelta(days=2), + "holiday_status_id": self.paid_type.id, + "employee_id": self.employee_3.id, + } + ) + with self.assertRaises(ValidationError): + self.leaves.with_user(self.user).action_confirm() + + leave_ids = ( + self.env["hr.leave.allocation"] + .with_user(self.user) + .with_context(**{"params": {"model": "hr.leave.allocation"}}) + .search([]) + ) + self.assertEqual(len(leave_ids), 1) diff --git a/hr_holidays_team_manager/views/hr_leave_allocation_views.xml b/hr_holidays_team_manager/views/hr_leave_allocation_views.xml new file mode 100644 index 00000000000..8392f04f043 --- /dev/null +++ b/hr_holidays_team_manager/views/hr_leave_allocation_views.xml @@ -0,0 +1,29 @@ + + + + hr.leave.allocation.view.form.manager + hr.leave.allocation + + + + {'hr_leave_allocation': True} + + + + + hr.leave.view.form.manager + hr.leave + + + + {'hr_leave': True} + + + + diff --git a/setup/hr_holidays_team_manager/odoo/addons/hr_holidays_team_manager b/setup/hr_holidays_team_manager/odoo/addons/hr_holidays_team_manager new file mode 120000 index 00000000000..1a92a687ffd --- /dev/null +++ b/setup/hr_holidays_team_manager/odoo/addons/hr_holidays_team_manager @@ -0,0 +1 @@ +../../../../hr_holidays_team_manager \ No newline at end of file diff --git a/setup/hr_holidays_team_manager/setup.py b/setup/hr_holidays_team_manager/setup.py new file mode 100644 index 00000000000..28c57bb6403 --- /dev/null +++ b/setup/hr_holidays_team_manager/setup.py @@ -0,0 +1,6 @@ +import setuptools + +setuptools.setup( + setup_requires=['setuptools-odoo'], + odoo_addon=True, +)