mirror of
https://github.com/bringout/oca-technical.git
synced 2026-04-26 16:12:00 +02:00
87 lines
3.6 KiB
Python
87 lines
3.6 KiB
Python
# Copyright 2024 Moduon Team S.L.
|
|
# License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl-3.0)
|
|
|
|
from collections import defaultdict
|
|
|
|
from odoo import fields, models
|
|
|
|
from odoo.addons.resource.models.resource import Intervals
|
|
|
|
|
|
class ResourceCalendar(models.Model):
|
|
_inherit = "resource.calendar"
|
|
|
|
def _get_general_time_off_intervals_by_state(self, domain=None, any_calendar=False):
|
|
"""Get a map of State to Intervals of leaves for the given domain."""
|
|
domain = domain or []
|
|
# Respect the any_calendar option
|
|
if not any_calendar:
|
|
domain = [("calendar_id", "in", self.ids + [False])] + domain
|
|
# Ensure that the leaves are not related to a specific resource
|
|
domain = [("resource_id", "=", False)] + domain
|
|
# Iterate all matching leaves
|
|
state_interval_map = defaultdict(Intervals)
|
|
for res_cal_leave in self.env["resource.calendar.leaves"].search(domain):
|
|
# Convert to aware datetime with user timezone
|
|
dttf = fields.Datetime.context_timestamp(
|
|
res_cal_leave, res_cal_leave.date_from
|
|
)
|
|
dttt = fields.Datetime.context_timestamp(
|
|
res_cal_leave, res_cal_leave.date_to
|
|
)
|
|
# Add the interval to the corresponding State or False if no state
|
|
if res_cal_leave.state_ids:
|
|
for state in res_cal_leave.state_ids:
|
|
state_interval_map[state.id] |= Intervals(
|
|
[(dttf, dttt, res_cal_leave)]
|
|
)
|
|
else:
|
|
state_interval_map[False] |= Intervals([(dttf, dttt, res_cal_leave)])
|
|
return state_interval_map
|
|
|
|
def _leave_intervals_batch(
|
|
self, start_dt, end_dt, resources=None, domain=None, tz=None, any_calendar=False
|
|
):
|
|
# All interval batches (with/out State)
|
|
res = super()._leave_intervals_batch(
|
|
start_dt,
|
|
end_dt,
|
|
resources=resources,
|
|
domain=domain,
|
|
tz=tz,
|
|
any_calendar=any_calendar,
|
|
)
|
|
# Overwrite the result if resources are specified, but only with
|
|
# the global leaves (skipping the local leaves) using the domain
|
|
for resource in resources or []:
|
|
res.update(
|
|
super()._leave_intervals_batch(
|
|
start_dt,
|
|
end_dt,
|
|
resources=resource,
|
|
domain=[("state_ids", "=", False)], # Force global leaves
|
|
tz=tz,
|
|
any_calendar=any_calendar,
|
|
)
|
|
)
|
|
# Get Local interval batches by State
|
|
state_interval_map = self._get_general_time_off_intervals_by_state(
|
|
domain=domain, any_calendar=any_calendar
|
|
)
|
|
# Post-process generated intervals
|
|
for resource_id in res.keys():
|
|
if not resource_id:
|
|
# If no resource is specified, only consider Global leaves
|
|
res[resource_id] = state_interval_map[False]
|
|
else:
|
|
# If resource is specified, add Local Leaves to the result if
|
|
# the State of its Work Address has Local leaves
|
|
resource_state_id = (
|
|
self.env["hr.employee"]
|
|
.sudo()
|
|
.search([("resource_id", "=", resource_id)], limit=1)
|
|
.address_id.state_id.id
|
|
)
|
|
if resource_state_id in state_interval_map:
|
|
res[resource_id] |= state_interval_map[resource_state_id]
|
|
return res
|