From da842f46f16aea6f99197813ee5cac8acede4618 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9mi=20-=20Le=20Filament?= <30716308+remi-filament@users.noreply.github.com> Date: Thu, 26 Dec 2024 11:12:21 +0100 Subject: [PATCH] [MIG] hr_holidays_leave_repeated: Migration to 17.0 --- hr_holidays_leave_repeated/README.rst | 7 + hr_holidays_leave_repeated/__manifest__.py | 4 +- hr_holidays_leave_repeated/i18n/fr.po | 14 +- hr_holidays_leave_repeated/i18n/nl.po | 10 +- hr_holidays_leave_repeated/models/hr_leave.py | 104 +++++---- .../readme/CONTRIBUTORS.md | 1 + hr_holidays_leave_repeated/readme/USAGE.md | 5 + .../static/description/index.html | 6 + .../tests/test_holidays_leave_repeated.py | 217 ++++++++++++------ hr_holidays_leave_repeated/views/hr_leave.xml | 89 ++----- .../views/hr_leave_type.xml | 2 +- 11 files changed, 261 insertions(+), 198 deletions(-) diff --git a/hr_holidays_leave_repeated/README.rst b/hr_holidays_leave_repeated/README.rst index fe9df3e2..707c3b7e 100644 --- a/hr_holidays_leave_repeated/README.rst +++ b/hr_holidays_leave_repeated/README.rst @@ -52,6 +52,10 @@ Usage 4. Create (save) the leave request. All the periodical leave requests are automatically created. +Note for HR Time Off responsibles : creating repeated leaves can only be +used when selecting Mode = "By Employee" and that all selected employees +should share the same resource calendar, otherwise an error is raised. + Bug Tracker =========== @@ -69,6 +73,7 @@ Authors ------- * Onestein +* Le Filament Contributors ------------ @@ -76,6 +81,8 @@ Contributors - Andrea Stirpe - Hieu, Vo Minh Bao - Italo LOPES +- Rémi - Le Filament + <`https://le-filament.com\\> >`__ Maintainers ----------- diff --git a/hr_holidays_leave_repeated/__manifest__.py b/hr_holidays_leave_repeated/__manifest__.py index 55b06f2c..45b10a14 100644 --- a/hr_holidays_leave_repeated/__manifest__.py +++ b/hr_holidays_leave_repeated/__manifest__.py @@ -4,10 +4,10 @@ { "name": "HR Holidays leave repeated", "summary": "Define periodical leaves", - "author": "Onestein, Odoo Community Association (OCA)", + "author": "Onestein, Le Filament, Odoo Community Association (OCA)", "website": "https://github.com/OCA/hr-holidays", "category": "Human Resources", - "version": "14.0.1.1.0", + "version": "17.0.1.1.0", "license": "AGPL-3", "depends": ["hr_holidays"], "data": ["views/hr_leave_type.xml", "views/hr_leave.xml"], diff --git a/hr_holidays_leave_repeated/i18n/fr.po b/hr_holidays_leave_repeated/i18n/fr.po index 5c927b42..36b67f44 100644 --- a/hr_holidays_leave_repeated/i18n/fr.po +++ b/hr_holidays_leave_repeated/i18n/fr.po @@ -74,7 +74,7 @@ msgstr "Veuillez définir un nombre de répétitions positif." #: model:ir.model.fields,field_description:hr_holidays_leave_repeated.field_hr_leave__holiday_type_repeat #: model:ir.model.fields,field_description:hr_holidays_leave_repeated.field_hr_leave_type__repeat msgid "Repeat" -msgstr "Répeter" +msgstr "Répéter" #. module: hr_holidays_leave_repeated #: model:ir.model.fields,field_description:hr_holidays_leave_repeated.field_hr_leave__repeat_limit @@ -84,7 +84,7 @@ msgstr "Répéter # fois" #. module: hr_holidays_leave_repeated #: model:ir.model.fields,field_description:hr_holidays_leave_repeated.field_hr_leave__repeat_end_date msgid "Repeat End Date" -msgstr "Répéter la date de fin" +msgstr "Date de fin de répétition" #. module: hr_holidays_leave_repeated #: model:ir.model.fields,field_description:hr_holidays_leave_repeated.field_hr_leave__repeat_every @@ -145,15 +145,9 @@ msgstr "" #. module: hr_holidays_leave_repeated #: model:ir.model,name:hr_holidays_leave_repeated.model_hr_leave msgid "Time Off" -msgstr "" +msgstr "Congés" #. module: hr_holidays_leave_repeated #: model:ir.model,name:hr_holidays_leave_repeated.model_hr_leave_type msgid "Time Off Type" -msgstr "" - -#~ msgid "Leave" -#~ msgstr "Congé" - -#~ msgid "Leave Type" -#~ msgstr "Type de congé" +msgstr "Type de congés" diff --git a/hr_holidays_leave_repeated/i18n/nl.po b/hr_holidays_leave_repeated/i18n/nl.po index 313e204a..b95bf42c 100644 --- a/hr_holidays_leave_repeated/i18n/nl.po +++ b/hr_holidays_leave_repeated/i18n/nl.po @@ -146,15 +146,9 @@ msgstr "" #. module: hr_holidays_leave_repeated #: model:ir.model,name:hr_holidays_leave_repeated.model_hr_leave msgid "Time Off" -msgstr "" +msgstr "Verlof" #. module: hr_holidays_leave_repeated #: model:ir.model,name:hr_holidays_leave_repeated.model_hr_leave_type msgid "Time Off Type" -msgstr "" - -#~ msgid "Leave" -#~ msgstr "Verlof" - -#~ msgid "Leave Type" -#~ msgstr "Verlofsoort" +msgstr "Verlofsoort" diff --git a/hr_holidays_leave_repeated/models/hr_leave.py b/hr_holidays_leave_repeated/models/hr_leave.py index 4109c562..027e1399 100644 --- a/hr_holidays_leave_repeated/models/hr_leave.py +++ b/hr_holidays_leave_repeated/models/hr_leave.py @@ -1,7 +1,9 @@ # Copyright 2016-2019 Onestein () +# Copyright 2024- Le Filament (https://le-filament.com) # License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). from dateutil.relativedelta import relativedelta +from pytz import utc from odoo import _, api, fields, models from odoo.exceptions import UserError, ValidationError @@ -26,30 +28,26 @@ class HrLeave(models.Model): repeat_end_date = fields.Date(default=lambda self: fields.Date.today()) @api.model - def _update_repeated_workday_dates(self, employee, from_dt, to_dt, days): + def _update_repeated_workday_dates(self, resource_calendar, from_dt, to_dt, days): user = self.env.user - calendar = employee.resource_calendar_id - orig_from_dt = fields.Datetime.context_timestamp(user, from_dt) - orig_to_dt = fields.Datetime.context_timestamp(user, to_dt) - work_hours = calendar.get_work_hours_count(from_dt, to_dt, compute_leaves=False) + from_dt = fields.Datetime.context_timestamp(user, from_dt) + to_dt = fields.Datetime.context_timestamp(user, to_dt) + work_hours = resource_calendar.get_work_hours_count( + from_dt, to_dt, compute_leaves=False + ) while work_hours: from_dt = from_dt + relativedelta(days=days) to_dt = to_dt + relativedelta(days=days) - new_work_hours = calendar.get_work_hours_count( + new_work_hours = resource_calendar.get_work_hours_count( from_dt, to_dt, compute_leaves=True ) if new_work_hours and work_hours <= new_work_hours: break - user_from_dt = fields.Datetime.context_timestamp(user, from_dt) - user_to_dt = fields.Datetime.context_timestamp(user, to_dt) - from_dt = from_dt - user_from_dt.tzinfo._utcoffset - from_dt = from_dt + orig_from_dt.tzinfo._utcoffset - to_dt = to_dt - user_to_dt.tzinfo._utcoffset - to_dt = to_dt + orig_to_dt.tzinfo._utcoffset - - return from_dt, to_dt + return from_dt.astimezone(utc).replace(tzinfo=None), to_dt.astimezone( + utc + ).replace(tzinfo=None) @api.model def _get_repeated_vals_dict(self): @@ -85,55 +83,75 @@ def _get_repeated_vals_dict(self): } @api.model - def _update_repeated_leave_vals(self, vals, employee): + def _update_repeated_leave_vals(self, leave, resource_calendar): vals_dict = self._get_repeated_vals_dict() - param_dict = vals_dict[vals.get("repeat_every")] - from_dt = fields.Datetime.from_string(vals.get("date_from")) - to_dt = fields.Datetime.from_string(vals.get("date_to")) - end_date = fields.Datetime.from_string(vals.get("repeat_end_date")) + param_dict = vals_dict[leave.repeat_every] + from_dt = leave.date_from + to_dt = leave.date_to if (to_dt - from_dt).days > param_dict["days"]: raise UserError(param_dict["user_error_msg"]) from_dt, to_dt = self._update_repeated_workday_dates( - employee, from_dt, to_dt, param_dict["days"] + resource_calendar, from_dt, to_dt, param_dict["days"] ) - vals["request_date_from"] = vals["date_from"] = from_dt - vals["request_date_to"] = vals["date_to"] = to_dt - vals["repeat_end_date"] = end_date - return vals + return { + "employee_ids": [(6, 0, leave.employee_ids.ids)], + "request_date_from": from_dt.date(), + "request_date_to": to_dt.date(), + } @api.model - def create_repeated_handler(self, vals, employee): - def _check_repeating(count, vals): - repeat_mode = vals.get("repeat_mode", "times") - if repeat_mode == "times" and count < vals.get("repeat_limit", 0): + def create_repeated_handler(self, leave, resource_calendar): + def _check_repeating(count, leave): + repeat_mode = leave.repeat_mode + if repeat_mode == "times" and count < leave.repeat_limit: return True - repeat_end_date = vals.get("repeat_end_date", fields.Date.today()) - if repeat_mode == "date" and vals["date_to"] <= repeat_end_date: + repeat_end_date = leave.repeat_end_date + if repeat_mode == "date" and leave.request_date_to <= repeat_end_date: return True return False count = 1 - vals = self._update_repeated_leave_vals(vals, employee) - while _check_repeating(count, vals): - self.with_context(skip_create_handler=True).create(vals) + leave_vals = self._update_repeated_leave_vals(leave, resource_calendar) + while _check_repeating(count, leave): + leave = leave.with_context(skip_create_handler=True).copy(leave_vals) count += 1 - vals = self._update_repeated_leave_vals(vals, employee) + leave_vals = self._update_repeated_leave_vals(leave, resource_calendar) - @api.model - def create(self, vals): - res = super().create(vals) + @api.model_create_multi + def create(self, vals_list): + res = super().create(vals_list) skip_create_handler = self.env.context.get("skip_create_handler") - all_vals_set = vals.get("repeat_every") and vals.get("repeat_mode") - if not skip_create_handler and all_vals_set: - employee = self.env["hr.employee"].browse(vals.get("employee_id")) - if employee.resource_calendar_id: - self.create_repeated_handler(vals, employee) + if skip_create_handler: + return res + for leave in res.filtered( + lambda leave: leave.repeat_every + and leave.repeat_mode + and leave.holiday_type == "employee" + ): + employees = leave.employee_ids + resource_calendars = employees.mapped("resource_calendar_id") + if len(resource_calendars) == 1: + self.create_repeated_handler(leave, resource_calendars[0]) + elif len(resource_calendars) == 0: + raise ValidationError( + _( + "Please define resource calendar on employee(s) in order " + "to compute repeated leaves." + ) + ) + else: + raise ValidationError( + _( + "Creating leaves for multiple employees with different " + "resource calendar is not supported." + ) + ) return res - @api.constrains("repeat_limit", "repeat_end_date") + @api.constrains("repeat_mode", "repeat_limit", "repeat_end_date") def _check_repeat_limit(self): for record in self: if record.repeat_mode == "times" and record.repeat_limit < 0: diff --git a/hr_holidays_leave_repeated/readme/CONTRIBUTORS.md b/hr_holidays_leave_repeated/readme/CONTRIBUTORS.md index e843c8ba..fa2a0bea 100644 --- a/hr_holidays_leave_repeated/readme/CONTRIBUTORS.md +++ b/hr_holidays_leave_repeated/readme/CONTRIBUTORS.md @@ -1,3 +1,4 @@ - Andrea Stirpe \<\> - Hieu, Vo Minh Bao \<\> - Italo LOPES \<\> +- Rémi - Le Filament \ diff --git a/hr_holidays_leave_repeated/readme/USAGE.md b/hr_holidays_leave_repeated/readme/USAGE.md index 991f17eb..21ada995 100644 --- a/hr_holidays_leave_repeated/readme/USAGE.md +++ b/hr_holidays_leave_repeated/readme/USAGE.md @@ -6,3 +6,8 @@ 'Repeat Every' and 'Repeat End Date'. 4. Create (save) the leave request. All the periodical leave requests are automatically created. + +Note for HR Time Off responsibles : creating repeated leaves can only +be used when selecting Mode = "By Employee" and that all selected +employees should share the same resource calendar, otherwise an error +is raised. diff --git a/hr_holidays_leave_repeated/static/description/index.html b/hr_holidays_leave_repeated/static/description/index.html index 7ad67ecd..a3351a00 100644 --- a/hr_holidays_leave_repeated/static/description/index.html +++ b/hr_holidays_leave_repeated/static/description/index.html @@ -403,6 +403,9 @@

Usage

  • Create (save) the leave request. All the periodical leave requests are automatically created.
  • +

    Note for HR Time Off responsibles : creating repeated leaves can only be +used when selecting Mode = “By Employee” and that all selected employees +should share the same resource calendar, otherwise an error is raised.

    Bug Tracker

    @@ -418,6 +421,7 @@

    Credits

    Authors

    • Onestein
    • +
    • Le Filament
    @@ -426,6 +430,8 @@

    Contributors

  • Andrea Stirpe <a.stirpe@onestein.nl>
  • Hieu, Vo Minh Bao <hieu.vmb@komit-consulting.com>
  • Italo LOPES <italo.lopes@camptocamp.com>
  • +
  • Rémi - Le Filament +<https://le-filament.com\>
  • diff --git a/hr_holidays_leave_repeated/tests/test_holidays_leave_repeated.py b/hr_holidays_leave_repeated/tests/test_holidays_leave_repeated.py index 54f02b9a..e321f1de 100644 --- a/hr_holidays_leave_repeated/tests/test_holidays_leave_repeated.py +++ b/hr_holidays_leave_repeated/tests/test_holidays_leave_repeated.py @@ -1,98 +1,100 @@ # Copyright 2016-2019 Onestein () +# Copyright 2024- Le Filament (https://le-filament.com) # License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). -from datetime import datetime, timedelta +from datetime import date, timedelta +import odoo.tests.common as common from odoo.exceptions import UserError, ValidationError -from odoo.tests import common class TestHolidaysLeaveRepeated(common.TransactionCase): - def setUp(self): - super().setUp() + @classmethod + def setUpClass(cls): + super().setUpClass() - self.date_start = datetime(2016, 12, 5, 8, 0, 0, 0) - self.date_end = datetime(2016, 12, 5, 18, 0, 0, 0) + cls.date_start = date(2016, 12, 5) + cls.date_end = date(2016, 12, 5) - self.calendar = self.env["resource.calendar"].create({"name": "Calendar 1"}) + cls.calendar = cls.env["resource.calendar"].create({"name": "Calendar 1"}) for i in range(0, 7): - self.env["resource.calendar.attendance"].create( + cls.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, + "calendar_id": cls.calendar.id, } ) - self.employee_1 = self.env["hr.employee"].create( - {"name": "Employee 1", "resource_calendar_id": self.calendar.id} + cls.employee_1 = cls.env["hr.employee"].create( + {"name": "Employee 1", "resource_calendar_id": cls.calendar.id} ) - self.employee_2 = self.env["hr.employee"].create( - {"name": "Employee 2", "resource_calendar_id": self.calendar.id} + cls.employee_2 = cls.env["hr.employee"].create( + {"name": "Employee 2", "resource_calendar_id": cls.calendar.id} ) - self.employee_3 = self.env["hr.employee"].create( - {"name": "Employee 3", "resource_calendar_id": self.calendar.id} + cls.employee_3 = cls.env["hr.employee"].create( + {"name": "Employee 3", "resource_calendar_id": cls.calendar.id} ) - self.employee_4 = self.env["hr.employee"].create( - {"name": "Employee 4", "resource_calendar_id": self.calendar.id} + cls.employee_4 = cls.env["hr.employee"].create( + {"name": "Employee 4", "resource_calendar_id": cls.calendar.id} ) - self.employee_5 = self.env["hr.employee"].create( - {"name": "Failing Employee", "resource_calendar_id": self.calendar.id} + cls.employee_5 = cls.env["hr.employee"].create( + {"name": "Failing Employee", "resource_calendar_id": cls.calendar.id} ) - self.status_1 = self.env["hr.leave.type"].create( - {"name": "Repeating Status", "repeat": True, "validity_start": False} + cls.status_1 = cls.env["hr.leave.type"].create( + {"name": "Repeating Status", "repeat": True} ) - self.leave_1 = self.env["hr.leave"].create( + cls.leave_1 = cls.env["hr.leave"].create( { - "holiday_status_id": self.status_1.id, + "holiday_status_id": cls.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, + "request_date_from": cls.date_start, + "request_date_to": cls.date_end, + "employee_id": cls.employee_1.id, } ) - self.leave_2 = self.env["hr.leave"].create( + cls.leave_2 = cls.env["hr.leave"].create( { - "holiday_status_id": self.status_1.id, + "holiday_status_id": cls.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, + "request_date_from": cls.date_start, + "request_date_to": cls.date_end, + "employee_id": cls.employee_2.id, } ) - self.leave_3 = self.env["hr.leave"].create( + cls.leave_3 = cls.env["hr.leave"].create( { - "holiday_status_id": self.status_1.id, + "holiday_status_id": cls.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, + "request_date_from": cls.date_start, + "request_date_to": cls.date_end, + "employee_id": cls.employee_3.id, } ) - self.leave_4 = self.env["hr.leave"].create( + cls.leave_4 = cls.env["hr.leave"].create( { - "holiday_status_id": self.status_1.id, + "holiday_status_id": cls.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, + "request_date_from": cls.date_start, + "request_date_to": cls.date_end, + "employee_id": cls.employee_4.id, } ) @@ -135,8 +137,8 @@ def test_02_workdays(self): [ ("holiday_status_id", "=", self.status_1.id), ("employee_id", "=", self.employee_1.id), - ("date_from", "=", check_from), - ("date_to", "=", check_to), + ("request_date_from", "=", check_from), + ("request_date_to", "=", check_to), ] ) self.assertEqual(len(leaves), 1) @@ -149,8 +151,8 @@ def test_03_weeks(self): [ ("holiday_status_id", "=", self.status_1.id), ("employee_id", "=", self.employee_2.id), - ("date_from", "=", check_from), - ("date_to", "=", check_to), + ("request_date_from", "=", check_from), + ("request_date_to", "=", check_to), ] ) self.assertEqual(len(leaves), 1) @@ -163,8 +165,8 @@ def test_04_biweeks(self): [ ("holiday_status_id", "=", self.status_1.id), ("employee_id", "=", self.employee_3.id), - ("date_from", "=", check_from), - ("date_to", "=", check_to), + ("request_date_from", "=", check_from), + ("request_date_to", "=", check_to), ] ) self.assertEqual(len(leaves), 1) @@ -177,8 +179,8 @@ def test_05_months(self): [ ("holiday_status_id", "=", self.status_1.id), ("employee_id", "=", self.employee_4.id), - ("date_from", "=", check_from), - ("date_to", "=", check_to), + ("request_date_from", "=", check_from), + ("request_date_to", "=", check_to), ] ) self.assertEqual(len(leaves), 1) @@ -191,15 +193,15 @@ def test_06_check_dates(self): "holiday_type": "employee", "repeat_every": "workday", "repeat_limit": -1, - "date_from": self.date_start, - "date_to": self.date_end, + "request_date_from": self.date_start, + "request_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) + date_start = date(2019, 2, 18) + date_end = date(2019, 2, 20) with self.assertRaises(UserError): self.env["hr.leave"].create( { @@ -208,15 +210,15 @@ def test_07_check_dates(self): "repeat_every": "workday", "repeat_mode": "times", "repeat_limit": 5, - "date_from": date_start, - "date_to": date_end, + "request_date_from": date_start, + "request_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) + date_start = date(2019, 3, 1) + date_end = date(2019, 3, 1) self.env["hr.leave"].create( { "holiday_status_id": self.status_1.id, @@ -224,8 +226,8 @@ def test_08_workdays_with_weekend(self): "repeat_every": "workday", "repeat_mode": "times", "repeat_limit": 5, - "date_from": date_start, - "date_to": date_end, + "request_date_from": date_start, + "request_date_to": date_end, "employee_id": self.employee_1.id, } ) @@ -236,8 +238,8 @@ def test_08_workdays_with_weekend(self): [ ("holiday_status_id", "=", self.status_1.id), ("employee_id", "=", self.employee_1.id), - ("date_from", "=", datetime_from), - ("date_to", "=", datetime_to), + ("request_date_from", "=", datetime_from), + ("request_date_to", "=", datetime_to), ] ) if datetime_from.weekday() < 5: # is a weekday @@ -246,9 +248,9 @@ def test_08_workdays_with_weekend(self): 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) + old_date = date(2019, 3, 18) + date_start = date(2019, 2, 18) + date_end = date(2019, 2, 18) with self.assertRaises(ValidationError): self.env["hr.leave"].create( { @@ -257,8 +259,91 @@ def test_09_check_repeat_end_date(self): "repeat_every": "workday", "repeat_mode": "date", "repeat_end_date": old_date, - "date_from": date_start, - "date_to": date_end, + "request_date_from": date_start, + "request_date_to": date_end, "employee_id": self.employee_5.id, } ) + + def test_10_check_different_resource_calendar(self): + with self.assertRaises(ValidationError): + calendar2 = self.env["resource.calendar"].create({"name": "Calendar 2"}) + employee_a = self.env["hr.employee"].create( + {"name": "Employee 8", "resource_calendar_id": self.calendar.id} + ) + employee_b = self.env["hr.employee"].create( + { + "name": "Employee 9 - different calendar", + "resource_calendar_id": calendar2.id, + } + ) + self.env["hr.leave"].create( + { + "holiday_status_id": self.status_1.id, + "holiday_type": "employee", + "repeat_every": "workday", + "repeat_mode": "times", + "repeat_limit": 5, + "request_date_from": self.date_start, + "request_date_to": self.date_end, + "multi_employee": True, + "employee_ids": [(6, False, [employee_a.id, employee_b.id])], + } + ) + + def test_11_check_no_resource_calendar(self): + with self.assertRaises(ValidationError): + employee = self.env["hr.employee"].create( + { + "name": "Employee 10 - no calendar", + "resource_calendar_id": False, + } + ) + self.env["hr.leave"].create( + { + "holiday_status_id": self.status_1.id, + "holiday_type": "employee", + "repeat_every": "workday", + "repeat_mode": "times", + "repeat_limit": 5, + "request_date_from": self.date_start, + "request_date_to": self.date_end, + "multi_employee": True, + "employee_id": employee.id, + } + ) + + def test_12_count_repetitions_multi_employees(self): + employee_a = self.env["hr.employee"].create( + {"name": "Employee 6", "resource_calendar_id": self.calendar.id} + ) + employee_b = self.env["hr.employee"].create( + {"name": "Employee 7", "resource_calendar_id": self.calendar.id} + ) + status = self.env["hr.leave.type"].create( + { + "name": "Repeating Status - No Allocation", + "repeat": True, + "requires_allocation": "no", + } + ) + self.env["hr.leave"].create( + { + "holiday_status_id": status.id, + "holiday_type": "employee", + "repeat_every": "workday", + "repeat_mode": "times", + "repeat_limit": 5, + "request_date_from": self.date_start, + "request_date_to": self.date_end, + "employee_id": employee_a.id, + "employee_ids": [(6, False, [employee_a.id, employee_b.id])], + } + ) + leave_list = self.env["hr.leave"].search( + [ + ("holiday_status_id", "=", status.id), + ("employee_ids", "in", [employee_a.id, employee_b.id]), + ] + ) + self.assertEqual(len(leave_list), 5) diff --git a/hr_holidays_leave_repeated/views/hr_leave.xml b/hr_holidays_leave_repeated/views/hr_leave.xml index c6e3478f..5080a030 100644 --- a/hr_holidays_leave_repeated/views/hr_leave.xml +++ b/hr_holidays_leave_repeated/views/hr_leave.xml @@ -4,77 +4,30 @@ hr.leave - - -
    + + + -
    -
    -
    -
    + + -
    -
    + invisible="holiday_type != 'employee' or not holiday_type_repeat or not repeat_every or repeat_mode == 'date'" + readonly="id != False" + /> +
    - - hr.leave - - - - -
    -
    -
    -
    -
    -
    -
    -
    -
    diff --git a/hr_holidays_leave_repeated/views/hr_leave_type.xml b/hr_holidays_leave_repeated/views/hr_leave_type.xml index 7bc12d0f..e1b0bc53 100644 --- a/hr_holidays_leave_repeated/views/hr_leave_type.xml +++ b/hr_holidays_leave_repeated/views/hr_leave_type.xml @@ -4,7 +4,7 @@ hr.leave.type - +