-
Notifications
You must be signed in to change notification settings - Fork 17
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Signed-off-by huguesdk
- Loading branch information
Showing
19 changed files
with
1,023 additions
and
223 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1,2 @@ | ||
from . import models | ||
from .hooks import post_load_hook |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,101 @@ | ||
# SPDX-FileCopyrightText: 2024 Coop IT Easy SC | ||
# | ||
# SPDX-License-Identifier: AGPL-3.0-or-later | ||
|
||
from datetime import datetime | ||
|
||
from pytz import UTC, timezone | ||
|
||
from odoo import api | ||
|
||
from odoo.addons.hr_holidays.models.hr_leave import HolidaysRequest | ||
from odoo.addons.resource.models.resource import float_to_time | ||
|
||
|
||
def patch_hr_leave_onchange_request_parameters(): | ||
if not hasattr(HolidaysRequest, "_onchange_request_parameters_original"): | ||
HolidaysRequest._onchange_request_parameters_original = ( | ||
HolidaysRequest._onchange_request_parameters | ||
) | ||
# we need to remove the _onchange property of the method, otherwise it | ||
# will still be called. | ||
HolidaysRequest._onchange_request_parameters_original._onchange_original = ( | ||
HolidaysRequest._onchange_request_parameters_original._onchange | ||
) | ||
del HolidaysRequest._onchange_request_parameters_original._onchange | ||
|
||
# in hr_holidays, this method reads the resource.calendar.attendance | ||
# records directly from the employee's or company resource.calendar to | ||
# find the first one and the last one corresponding to the leave date | ||
# range. below is a copy of the method from hr_holidays, with that part | ||
# replaced by a call to _get_request_attendances() to allow to change that | ||
# behavior. | ||
@api.onchange( | ||
"request_date_from_period", | ||
"request_hour_from", | ||
"request_hour_to", | ||
"request_date_from", | ||
"request_date_to", | ||
"employee_id", | ||
) | ||
def __new_onchange_request_parameters(self): | ||
if not self.request_date_from: | ||
self.date_from = False | ||
return | ||
|
||
if self.request_unit_half or self.request_unit_hours: | ||
self.request_date_to = self.request_date_from | ||
|
||
if not self.request_date_to: | ||
self.date_to = False | ||
return | ||
|
||
# begin change | ||
attendance_from, attendance_to = self._get_request_attendances() | ||
# end change | ||
|
||
if self.request_unit_half: | ||
if self.request_date_from_period == "am": | ||
hour_from = float_to_time(attendance_from.hour_from) | ||
hour_to = float_to_time(attendance_from.hour_to) | ||
else: | ||
hour_from = float_to_time(attendance_to.hour_from) | ||
hour_to = float_to_time(attendance_to.hour_to) | ||
elif self.request_unit_hours: | ||
# This hack is related to the definition of the field, basically we convert | ||
# the negative integer into .5 floats | ||
hour_from = float_to_time( | ||
abs(self.request_hour_from) - 0.5 | ||
if self.request_hour_from < 0 | ||
else self.request_hour_from | ||
) | ||
hour_to = float_to_time( | ||
abs(self.request_hour_to) - 0.5 | ||
if self.request_hour_to < 0 | ||
else self.request_hour_to | ||
) | ||
elif self.request_unit_custom: | ||
hour_from = self.date_from.time() | ||
hour_to = self.date_to.time() | ||
else: | ||
hour_from = float_to_time(attendance_from.hour_from) | ||
hour_to = float_to_time(attendance_to.hour_to) | ||
self.date_from = ( | ||
timezone(self.tz) | ||
.localize(datetime.combine(self.request_date_from, hour_from)) | ||
.astimezone(UTC) | ||
.replace(tzinfo=None) | ||
) | ||
self.date_to = ( | ||
timezone(self.tz) | ||
.localize(datetime.combine(self.request_date_to, hour_to)) | ||
.astimezone(UTC) | ||
.replace(tzinfo=None) | ||
) | ||
self._onchange_leave_dates() | ||
|
||
HolidaysRequest._onchange_request_parameters = __new_onchange_request_parameters | ||
|
||
|
||
def post_load_hook(): | ||
patch_hr_leave_onchange_request_parameters() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,5 @@ | ||
from . import hr_leave | ||
from . import resource_calendar | ||
from . import resource_calendar_leaves | ||
from . import resource_mixin | ||
from . import resource_resource |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
# SPDX-FileCopyrightText: 2024 Coop IT Easy SC | ||
# | ||
# SPDX-License-Identifier: AGPL-3.0-or-later | ||
|
||
from odoo import models | ||
|
||
from odoo.addons.hr_holidays.models.hr_leave import DummyAttendance | ||
|
||
|
||
class HrLeave(models.Model): | ||
_inherit = "hr.leave" | ||
|
||
def _get_request_attendances(self): | ||
""" | ||
Get the first and last resource.calendar.attendance corresponding to | ||
the range defined by request_date_from and request_date_to. | ||
""" | ||
attendance_from, attendance_to = self.employee_id.get_attendances_of_date_range( | ||
self.request_date_from, self.request_date_to | ||
) | ||
default_value = DummyAttendance(0, 0, 0, "morning") | ||
if attendance_from is None: | ||
attendance_from = default_value | ||
if attendance_to is None: | ||
attendance_to = default_value | ||
return attendance_from, attendance_to |
63 changes: 63 additions & 0 deletions
63
resource_work_time_from_contracts/models/resource_calendar.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
# SPDX-FileCopyrightText: 2024 Coop IT Easy SC | ||
# | ||
# SPDX-License-Identifier: AGPL-3.0-or-later | ||
|
||
import datetime | ||
|
||
from odoo import models | ||
|
||
|
||
class ResourceCalendar(models.Model): | ||
_inherit = "resource.calendar" | ||
|
||
def _get_first_attendance(self, date_from): | ||
# we should get the first attendance from a list of all the | ||
# attendances that starts with the weekday of date_from then wraps | ||
# around and ends with the weekday before date_from. the list should | ||
# be no longer (in terms of weekdays) than date_to - date_from + 1. | ||
all_attendances = self.attendance_ids | ||
if not all_attendances: | ||
return None | ||
weekday_from = date_from.weekday() | ||
all_attendances = all_attendances.filtered( | ||
lambda r: int(r.dayofweek) >= weekday_from | ||
) + all_attendances.filtered(lambda r: int(r.dayofweek) < weekday_from) | ||
first_attendance = all_attendances[0] | ||
weekday_diff = int(first_attendance.dayofweek) - weekday_from | ||
if weekday_diff < 0: | ||
weekday_diff += 7 | ||
first_attendance_date = date_from + datetime.timedelta(days=weekday_diff) | ||
return (first_attendance_date, first_attendance) | ||
|
||
def _get_last_attendance(self, date_to): | ||
# do the same as _get_first_attendance(), but in the other direction. | ||
all_attendances = self.attendance_ids | ||
if not all_attendances: | ||
return None | ||
weekday_to = date_to.weekday() | ||
all_attendances = all_attendances.filtered( | ||
lambda r: int(r.dayofweek) > weekday_to | ||
) + all_attendances.filtered(lambda r: int(r.dayofweek) <= weekday_to) | ||
last_attendance = all_attendances[-1] | ||
weekday_diff = int(last_attendance.dayofweek) - weekday_to | ||
if weekday_diff > 0: | ||
weekday_diff -= 7 | ||
last_attendance_date = date_to + datetime.timedelta(days=weekday_diff) | ||
return (last_attendance_date, last_attendance) | ||
|
||
def get_first_last_attendance(self, date_from, date_to): | ||
""" | ||
Get the first and last attendances between (and including) date_from | ||
and date_to. | ||
Return 2 tuples of the form (date, attendance). Each of the tuples can | ||
be None if there is no match. | ||
""" | ||
first_attendance_tuple = self._get_first_attendance(date_from) | ||
last_attendance_tuple = self._get_last_attendance(date_to) | ||
# some small checks. | ||
if first_attendance_tuple and first_attendance_tuple[0] > date_to: | ||
first_attendance_tuple = None | ||
if last_attendance_tuple and last_attendance_tuple[0] < date_from: | ||
last_attendance_tuple = None | ||
return (first_attendance_tuple, last_attendance_tuple) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.