diff --git a/hr_holidays_leave_self_approve/README.rst b/hr_holidays_leave_self_approve/README.rst new file mode 100644 index 00000000..f24a174a --- /dev/null +++ b/hr_holidays_leave_self_approve/README.rst @@ -0,0 +1 @@ +autogenerated diff --git a/hr_holidays_leave_self_approve/__init__.py b/hr_holidays_leave_self_approve/__init__.py new file mode 100644 index 00000000..83e553ac --- /dev/null +++ b/hr_holidays_leave_self_approve/__init__.py @@ -0,0 +1,3 @@ +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). + +from . import models diff --git a/hr_holidays_leave_self_approve/__manifest__.py b/hr_holidays_leave_self_approve/__manifest__.py new file mode 100644 index 00000000..7ecd68f5 --- /dev/null +++ b/hr_holidays_leave_self_approve/__manifest__.py @@ -0,0 +1,15 @@ +# Copyright 2023 Camptocamp SA +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). + +{ + "name": "Self Approve Leaves", + "version": "15.0.1.0.0", + "license": "AGPL-3", + "summary": "Allow employees to approve their own leaves when allowed", + "author": "Camptocamp, Odoo Community Association (OCA)", + "website": "https://github.com/OCA/hr-holidays", + "category": "Human Resources", + "depends": ["hr_holidays"], + "data": [], + "installable": True, +} diff --git a/hr_holidays_leave_self_approve/models/__init__.py b/hr_holidays_leave_self_approve/models/__init__.py new file mode 100644 index 00000000..b1c9b691 --- /dev/null +++ b/hr_holidays_leave_self_approve/models/__init__.py @@ -0,0 +1,3 @@ +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). + +from . import hr_leave diff --git a/hr_holidays_leave_self_approve/models/hr_leave.py b/hr_holidays_leave_self_approve/models/hr_leave.py new file mode 100644 index 00000000..d4112809 --- /dev/null +++ b/hr_holidays_leave_self_approve/models/hr_leave.py @@ -0,0 +1,20 @@ +# Copyright 2023 Camptocamp SA +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). + +from odoo import models + + +class HrLeave(models.Model): + _inherit = "hr.leave" + + def _check_approval_update(self, state): + if self.env.is_admin(): + return + if state in ("validate", "refuse"): + current_employee = self.env.user.employee_id + if current_employee.user_id == current_employee.leave_manager_id: + # Filter out self-approved leaves + self = self.filtered_domain( + [("employee_id", "!=", current_employee.id)] + ) + super()._check_approval_update(state) diff --git a/hr_holidays_leave_self_approve/readme/CONFIGURE.rst b/hr_holidays_leave_self_approve/readme/CONFIGURE.rst new file mode 100644 index 00000000..886a7ed1 --- /dev/null +++ b/hr_holidays_leave_self_approve/readme/CONFIGURE.rst @@ -0,0 +1 @@ +Nothing to configure. When employee "Time Off" approver is set to himself, it will work as expected. diff --git a/hr_holidays_leave_self_approve/readme/CONTRIBUTORS.rst b/hr_holidays_leave_self_approve/readme/CONTRIBUTORS.rst new file mode 100644 index 00000000..9fa85e03 --- /dev/null +++ b/hr_holidays_leave_self_approve/readme/CONTRIBUTORS.rst @@ -0,0 +1 @@ +* Florent Xicluna diff --git a/hr_holidays_leave_self_approve/readme/DESCRIPTION.rst b/hr_holidays_leave_self_approve/readme/DESCRIPTION.rst new file mode 100644 index 00000000..83b0fbe8 --- /dev/null +++ b/hr_holidays_leave_self_approve/readme/DESCRIPTION.rst @@ -0,0 +1 @@ +This module allows employee to approve/refuse their own leave requests, when their "Time Off" approver is themself. diff --git a/hr_holidays_leave_self_approve/tests/__init__.py b/hr_holidays_leave_self_approve/tests/__init__.py new file mode 100644 index 00000000..10ab23c9 --- /dev/null +++ b/hr_holidays_leave_self_approve/tests/__init__.py @@ -0,0 +1,3 @@ +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). + +from . import test_hr_holidays_leave_self_approve diff --git a/hr_holidays_leave_self_approve/tests/test_hr_holidays_leave_self_approve.py b/hr_holidays_leave_self_approve/tests/test_hr_holidays_leave_self_approve.py new file mode 100644 index 00000000..ce2dee33 --- /dev/null +++ b/hr_holidays_leave_self_approve/tests/test_hr_holidays_leave_self_approve.py @@ -0,0 +1,82 @@ +# Copyright 2023 Camptocamp SA +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). + +from datetime import datetime, timedelta + +from odoo.tests.common import TransactionCase + + +class TestHolidaysAutoValidate(TransactionCase): + @classmethod + def setUpClass(cls): + super().setUpClass() + cls.env = cls.env(context=dict(cls.env.context, tracking_disable=True)) + + cls.employee_model = cls.env["hr.employee"] + cls.user_model = cls.env["res.users"] + cls.leave_request_model = cls.env["hr.leave"] + cls.leave_allocation_model = cls.env["hr.leave.allocation"] + + # Create an employee user to make leave requests + cls.test_user_id = cls.user_model.create( + {"name": "Test User", "login": "test_user", "email": "mymail@test.com"} + ) + + # Create an employee related to the user to make leave requests + # Assign user as self-approver + cls.test_employee_id = cls.employee_model.create( + { + "name": "Test Employee", + "user_id": cls.test_user_id.id, + "leave_manager_id": cls.test_user_id.id, + } + ) + + # "Paid Leave" type + leave_type = cls.env.ref("hr_holidays.holiday_status_cl") + + # Create leave allocation request + cls.leave_allocation = cls.leave_allocation_model.create( + { + "name": "Test Allocation Request", + "holiday_status_id": leave_type.id, + "holiday_type": "employee", + "employee_id": cls.test_employee_id.id, + "number_of_days": 10, + } + ) + + def test_allocation_request_state(self): + # Check for leave_allocation state + self.assertEqual(self.leave_allocation.state, "draft") + + # Validate the leave_allocation + self.leave_allocation.action_confirm() + self.leave_allocation.action_validate() + + # Check for leave_allocation state + self.assertEqual(self.leave_allocation.state, "validate") + + def test_leave_request_state(self): + today = datetime.today() + + # Create leave request + leave = self.leave_request_model.create( + { + "name": "Test Leave Request", + "holiday_status_id": self.leave_allocation.holiday_status_id.id, + "date_from": today, + "date_to": today + timedelta(days=2), + "holiday_type": "employee", + "employee_id": self.test_employee_id.id, + } + ) + + # Check for leave "To approve" + self.assertEqual(leave.state, "confirm") + + # Self approve + leave.with_user(self.test_user_id).action_approve() + + # Check for leave state "Approved" + self.assertEqual(leave.state, "validate1") diff --git a/setup/hr_holidays_leave_self_approve/odoo/addons/hr_holidays_leave_self_approve b/setup/hr_holidays_leave_self_approve/odoo/addons/hr_holidays_leave_self_approve new file mode 120000 index 00000000..f655a8a6 --- /dev/null +++ b/setup/hr_holidays_leave_self_approve/odoo/addons/hr_holidays_leave_self_approve @@ -0,0 +1 @@ +../../../../hr_holidays_leave_self_approve \ No newline at end of file diff --git a/setup/hr_holidays_leave_self_approve/setup.py b/setup/hr_holidays_leave_self_approve/setup.py new file mode 100644 index 00000000..28c57bb6 --- /dev/null +++ b/setup/hr_holidays_leave_self_approve/setup.py @@ -0,0 +1,6 @@ +import setuptools + +setuptools.setup( + setup_requires=['setuptools-odoo'], + odoo_addon=True, +)