Skip to content

Commit

Permalink
feat: new validator list module
Browse files Browse the repository at this point in the history
  • Loading branch information
victorvermot authored and sarsurgithub committed Oct 4, 2023
1 parent e0c301c commit d5920e7
Show file tree
Hide file tree
Showing 10 changed files with 349 additions and 0 deletions.
1 change: 1 addition & 0 deletions hr_holidays_validator_list/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
from . import models
17 changes: 17 additions & 0 deletions hr_holidays_validator_list/__manifest__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# Copyright 2023 Camptocamp SA
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html)

{
"name": "HR Holidays validator list",
"summary": "Allow to add several leave validators",
"author": "Victor Vermot, Odoo Community Association (OCA)",
"website": "https://github.com/OCA/hr-holidays",
"category": "Human Resources",
"version": "14.0.1.0.0",
"license": "AGPL-3",
"depends": ["hr_holidays"],
"data": [
"views/hr_views.xml"
],
"installable": True,
}
1 change: 1 addition & 0 deletions hr_holidays_validator_list/models/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
from . import hr_employee
27 changes: 27 additions & 0 deletions hr_holidays_validator_list/models/hr_employee.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# Copyright 2023 Camptocamp SA
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html)

from odoo import fields, models


class HrEmployeeBase(models.AbstractModel):
_inherit = "hr.employee.base"

leave_manager_ids = fields.Many2many(
'res.users',
string='Time Off',
compute='_compute_leave_manager',
store=True,
readonly=False,
help='Select the users responsible for approving "Time Off" of this employee.\n'
'If empty, the approval is done by an Administrator or Approver (determined in settings/users).',
)

def create(self, values):
res = super().create(values)
return res

def write(self, values):
re = super().write(values)
return re

18 changes: 18 additions & 0 deletions hr_holidays_validator_list/models/hr_leave_allocation.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.

# Copyright (c) 2005-2006 Axelor SARL. (http://www.axelor.com)


from odoo import models


class HolidaysAllocation(models.Model):
""" Allocation Requests Access specifications: similar to leave requests """
_inherit = "hr.leave.allocation"

def _get_responsible_for_approval(self):
print("Need to override it")

def _check_approval_update(self, state):
print("Need to override it")
1 change: 1 addition & 0 deletions hr_holidays_validator_list/readme/CONTRIBUTORS.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
* Victor Vermot-Petit-Outhenin <[email protected]>
1 change: 1 addition & 0 deletions hr_holidays_validator_list/readme/DESCRIPTION.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
This module allows for an employee to have several leave validators.
Empty file.
266 changes: 266 additions & 0 deletions hr_holidays_validator_list/tests/test_hr_holidays_validator_list.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,266 @@
# Copyright 2016-2019 Onestein (<https://www.onestein.eu>)
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).

from datetime import datetime, timedelta

from odoo.exceptions import UserError, ValidationError
from odoo.tests import common


class TestHolidaysLeaveRepeated(common.TransactionCase):
def setUp(self):
super().setUp()

self.date_start = datetime(2016, 12, 5, 8, 0, 0, 0)
self.date_end = datetime(2016, 12, 5, 18, 0, 0, 0)

self.calendar = self.env["resource.calendar"].create({"name": "Calendar 1"})

for i in range(0, 7):
self.env["resource.calendar.attendance"].create(
{
"name": "Day " + str(i),
"dayofweek": str(i),
"hour_from": 8.0,
"hour_to": 16.0,
"calendar_id": self.calendar.id,
}
)

self.employee_1 = self.env["hr.employee"].create(
{"name": "Employee 1", "resource_calendar_id": self.calendar.id}
)
self.employee_2 = self.env["hr.employee"].create(
{"name": "Employee 2", "resource_calendar_id": self.calendar.id}
)
self.employee_3 = self.env["hr.employee"].create(
{"name": "Employee 3", "resource_calendar_id": self.calendar.id}
)
self.employee_4 = self.env["hr.employee"].create(
{"name": "Employee 4", "resource_calendar_id": self.calendar.id}
)
self.employee_5 = self.env["hr.employee"].create(
{"name": "Failing Employee", "resource_calendar_id": self.calendar.id}
)

self.status_1 = self.env["hr.leave.type"].create(
{"name": "Repeating Status", "repeat": True, "validity_start": False}
)

self.leave_1 = self.env["hr.leave"].create(
{
"holiday_status_id": self.status_1.id,
"holiday_type": "employee",
"repeat_every": "workday",
"repeat_mode": "times",
"repeat_limit": 5,
"date_from": self.date_start,
"date_to": self.date_end,
"employee_id": self.employee_1.id,
}
)
self.leave_2 = self.env["hr.leave"].create(
{
"holiday_status_id": self.status_1.id,
"holiday_type": "employee",
"repeat_every": "week",
"repeat_mode": "times",
"repeat_limit": 4,
"date_from": self.date_start,
"date_to": self.date_end,
"employee_id": self.employee_2.id,
}
)
self.leave_3 = self.env["hr.leave"].create(
{
"holiday_status_id": self.status_1.id,
"holiday_type": "employee",
"repeat_every": "biweek",
"repeat_mode": "times",
"repeat_limit": 3,
"date_from": self.date_start,
"date_to": self.date_end,
"employee_id": self.employee_3.id,
}
)
self.leave_4 = self.env["hr.leave"].create(
{
"holiday_status_id": self.status_1.id,
"holiday_type": "employee",
"repeat_every": "month",
"repeat_mode": "times",
"repeat_limit": 2,
"date_from": self.date_start,
"date_to": self.date_end,
"employee_id": self.employee_4.id,
}
)

def test_01_count_repetitions(self):

leave_1_list = self.env["hr.leave"].search(
[
("holiday_status_id", "=", self.status_1.id),
("employee_id", "=", self.employee_1.id),
]
)
leave_2_list = self.env["hr.leave"].search(
[
("holiday_status_id", "=", self.status_1.id),
("employee_id", "=", self.employee_2.id),
]
)
leave_3_list = self.env["hr.leave"].search(
[
("holiday_status_id", "=", self.status_1.id),
("employee_id", "=", self.employee_3.id),
]
)
leave_4_list = self.env["hr.leave"].search(
[
("holiday_status_id", "=", self.status_1.id),
("employee_id", "=", self.employee_4.id),
]
)

self.assertEqual(len(leave_1_list), 5)
self.assertEqual(len(leave_2_list), 4)
self.assertEqual(len(leave_3_list), 3)
self.assertEqual(len(leave_4_list), 2)

def test_02_workdays(self):
for i in range(0, 5):
check_from = self.date_start + timedelta(days=i)
check_to = self.date_end + timedelta(days=i)
leaves = self.env["hr.leave"].search(
[
("holiday_status_id", "=", self.status_1.id),
("employee_id", "=", self.employee_1.id),
("date_from", "=", check_from),
("date_to", "=", check_to),
]
)
self.assertEqual(len(leaves), 1)

def test_03_weeks(self):

for i in range(0, 4):
check_from = self.date_start + timedelta(days=i * 7)
check_to = self.date_end + timedelta(days=i * 7)
leaves = self.env["hr.leave"].search(
[
("holiday_status_id", "=", self.status_1.id),
("employee_id", "=", self.employee_2.id),
("date_from", "=", check_from),
("date_to", "=", check_to),
]
)
self.assertEqual(len(leaves), 1)

def test_04_biweeks(self):
for i in range(0, 3):
check_from = self.date_start + timedelta(days=i * 14)
check_to = self.date_end + timedelta(days=i * 14)
leaves = self.env["hr.leave"].search(
[
("holiday_status_id", "=", self.status_1.id),
("employee_id", "=", self.employee_3.id),
("date_from", "=", check_from),
("date_to", "=", check_to),
]
)
self.assertEqual(len(leaves), 1)

def test_05_months(self):
for i in range(0, 2):
check_from = self.date_start + timedelta(days=i * 28)
check_to = self.date_end + timedelta(days=i * 28)
leaves = self.env["hr.leave"].search(
[
("holiday_status_id", "=", self.status_1.id),
("employee_id", "=", self.employee_4.id),
("date_from", "=", check_from),
("date_to", "=", check_to),
]
)
self.assertEqual(len(leaves), 1)

def test_06_check_dates(self):
with self.assertRaises(ValidationError):
self.env["hr.leave"].create(
{
"holiday_status_id": self.status_1.id,
"holiday_type": "employee",
"repeat_every": "workday",
"repeat_limit": -1,
"date_from": self.date_start,
"date_to": self.date_end,
"employee_id": self.employee_5.id,
}
)

def test_07_check_dates(self):
date_start = datetime(2019, 2, 18, 8, 0, 0, 0)
date_end = datetime(2019, 2, 20, 18, 0, 0, 0)
with self.assertRaises(UserError):
self.env["hr.leave"].create(
{
"holiday_status_id": self.status_1.id,
"holiday_type": "employee",
"repeat_every": "workday",
"repeat_mode": "times",
"repeat_limit": 5,
"date_from": date_start,
"date_to": date_end,
"employee_id": self.employee_5.id,
}
)

def test_08_workdays_with_weekend(self):
date_start = datetime(2019, 3, 1, 8, 0, 0, 0)
date_end = datetime(2019, 3, 1, 18, 0, 0, 0)
self.env["hr.leave"].create(
{
"holiday_status_id": self.status_1.id,
"holiday_type": "employee",
"repeat_every": "workday",
"repeat_mode": "times",
"repeat_limit": 5,
"date_from": date_start,
"date_to": date_end,
"employee_id": self.employee_1.id,
}
)
for i in range(0, 7):
datetime_from = date_start + timedelta(days=i)
datetime_to = date_end + timedelta(days=i)
leaves = self.env["hr.leave"].search(
[
("holiday_status_id", "=", self.status_1.id),
("employee_id", "=", self.employee_1.id),
("date_from", "=", datetime_from),
("date_to", "=", datetime_to),
]
)
if datetime_from.weekday() < 5: # is a weekday
self.assertEqual(len(leaves), 1)
else: # is weekend
self.assertEqual(len(leaves), 0)

def test_09_check_repeat_end_date(self):
old_date = datetime(2019, 3, 18, 8, 0, 0, 0)
date_start = datetime(2019, 2, 18, 8, 0, 0, 0)
date_end = datetime(2019, 2, 18, 18, 0, 0, 0)
with self.assertRaises(ValidationError):
self.env["hr.leave"].create(
{
"holiday_status_id": self.status_1.id,
"holiday_type": "employee",
"repeat_every": "workday",
"repeat_mode": "date",
"repeat_end_date": old_date,
"date_from": date_start,
"date_to": date_end,
"employee_id": self.employee_5.id,
}
)
17 changes: 17 additions & 0 deletions hr_holidays_validator_list/views/hr_views.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<?xml version='1.0' encoding='UTF-8'?>
<odoo>
<!-- Hr employee inherit Legal Leaves -->
<record id="view_employee_form_leave_inherit" model="ir.ui.view">
<field name="name">hr.employee.leave.form.inherit</field>
<field name="model">hr.employee</field>
<field name="inherit_id" ref="hr_holidays.view_employee_form_leave_inherit"/>
<field name="arch" type="xml">
<xpath expr="//field[@name='leave_manager_id']" position="attributes">
<attribute name="invisible">1</attribute>
</xpath>
<xpath expr="//group[@name='managers']" position="inside">
<field name="leave_manager_ids" />
</xpath>
</field>
</record>
</odoo>

0 comments on commit d5920e7

Please sign in to comment.