Skip to content

Commit

Permalink
[MIG] hr_holidays_leave_repeated: Migration to 17.0
Browse files Browse the repository at this point in the history
  • Loading branch information
remi-filament committed Dec 26, 2024
1 parent 4946c99 commit da842f4
Show file tree
Hide file tree
Showing 11 changed files with 261 additions and 198 deletions.
7 changes: 7 additions & 0 deletions hr_holidays_leave_repeated/README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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
===========

Expand All @@ -69,13 +73,16 @@ Authors
-------

* Onestein
* Le Filament

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\\> <https://le-filament.com\>>`__

Maintainers
-----------
Expand Down
4 changes: 2 additions & 2 deletions hr_holidays_leave_repeated/__manifest__.py
Original file line number Diff line number Diff line change
Expand Up @@ -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"],
Expand Down
14 changes: 4 additions & 10 deletions hr_holidays_leave_repeated/i18n/fr.po
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand Down Expand Up @@ -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"
10 changes: 2 additions & 8 deletions hr_holidays_leave_repeated/i18n/nl.po
Original file line number Diff line number Diff line change
Expand Up @@ -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"
104 changes: 61 additions & 43 deletions hr_holidays_leave_repeated/models/hr_leave.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
# Copyright 2016-2019 Onestein (<https://www.onestein.eu>)
# 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
Expand All @@ -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):
Expand Down Expand Up @@ -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

Check warning on line 113 in hr_holidays_leave_repeated/models/hr_leave.py

View check run for this annotation

Codecov / codecov/patch

hr_holidays_leave_repeated/models/hr_leave.py#L113

Added line #L113 was not covered by tests
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:
Expand Down
1 change: 1 addition & 0 deletions hr_holidays_leave_repeated/readme/CONTRIBUTORS.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
- 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\>
5 changes: 5 additions & 0 deletions hr_holidays_leave_repeated/readme/USAGE.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.
6 changes: 6 additions & 0 deletions hr_holidays_leave_repeated/static/description/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -403,6 +403,9 @@ <h1><a class="toc-backref" href="#toc-entry-2">Usage</a></h1>
<li>Create (save) the leave request. All the periodical leave requests
are automatically created.</li>
</ol>
<p>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.</p>
</div>
<div class="section" id="bug-tracker">
<h1><a class="toc-backref" href="#toc-entry-3">Bug Tracker</a></h1>
Expand All @@ -418,6 +421,7 @@ <h1><a class="toc-backref" href="#toc-entry-4">Credits</a></h1>
<h2><a class="toc-backref" href="#toc-entry-5">Authors</a></h2>
<ul class="simple">
<li>Onestein</li>
<li>Le Filament</li>
</ul>
</div>
<div class="section" id="contributors">
Expand All @@ -426,6 +430,8 @@ <h2><a class="toc-backref" href="#toc-entry-6">Contributors</a></h2>
<li>Andrea Stirpe &lt;<a class="reference external" href="mailto:a.stirpe&#64;onestein.nl">a.stirpe&#64;onestein.nl</a>&gt;</li>
<li>Hieu, Vo Minh Bao &lt;<a class="reference external" href="mailto:hieu.vmb&#64;komit-consulting.com">hieu.vmb&#64;komit-consulting.com</a>&gt;</li>
<li>Italo LOPES &lt;<a class="reference external" href="mailto:italo.lopes&#64;camptocamp.com">italo.lopes&#64;camptocamp.com</a>&gt;</li>
<li>Rémi - Le Filament
&lt;<a class="reference external" href="https://le-filament.com&gt;">https://le-filament.com\&gt;</a></li>
</ul>
</div>
<div class="section" id="maintainers">
Expand Down
Loading

0 comments on commit da842f4

Please sign in to comment.