odoo/addons/stock_calendar/models/resource.py

124 lines
5.6 KiB
Python

# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from odoo import api, fields, models
class ResourceCalendarAttendance(models.Model):
_inherit = "resource.calendar.attendance"
group_id = fields.Many2one('procurement.group', 'Procurement Group')
class ResourceCalendarLeaves(models.Model):
_inherit = "resource.calendar.leaves"
group_id = fields.Many2one('procurement.group', string="Procurement Group")
class ResourceCalendar(models.Model):
_inherit = "resource.calendar"
# Keep as it takes into account times
@api.multi
def get_leave_intervals(self, resource_id=None,
start_datetime=None, end_datetime=None):
"""Get the leaves of the calendar. Leaves can be filtered on the resource,
the start datetime or the end datetime.
:param int resource_id: the id of the resource to take into account when
computing the leaves. If not set, only general
leaves are computed. If set, generic and
specific leaves are computed.
:param datetime start_datetime: if provided, do not take into account leaves
ending before this date.
:param datetime end_datetime: if provided, do not take into account leaves
beginning after this date.
:return list leaves: list of tuples (start_datetime, end_datetime) of
leave intervals
"""
# TDE FIXME: waw, overriding completely a method + changing its result
# and its behavior, very nice. Please FIXME.
self.ensure_one()
leaves = []
for leave in self.leave_ids:
if leave.resource_id and not resource_id == leave.resource_id.id:
continue
date_from = fields.Datetime.from_string(leave.date_from)
if end_datetime and date_from > end_datetime:
continue
date_to = fields.Datetime.from_string(leave.date_to)
if start_datetime and date_to < start_datetime:
continue
leaves.append((date_from, date_to, leave.group_id.id))
return leaves
# --------------------------------------------------
# Utility methods
# --------------------------------------------------
@api.model
def interval_remove_leaves(self, interval, leave_intervals):
""" Utility method that remove leave intervals from a base interval:
- clean the leave intervals, to have an ordered list of not-overlapping
intervals
- initiate the current interval to be the base interval
- for each leave interval:
- finishing before the current interval: skip, go to next
- beginning after the current interval: skip and get out of the loop
because we are outside range (leaves are ordered)
- beginning within the current interval: close the current interval
and begin a new current interval that begins at the end of the leave
interval
- ending within the current interval: update the current interval begin
to match the leave interval ending
- take into account the procurement group when needed
:param tuple interval: a tuple (beginning datetime, ending datetime) that
is the base interval from which the leave intervals
will be removed
:param list leave_intervals: a list of tuples (beginning datetime, ending datetime)
that are intervals to remove from the base interval
:return list intervals: a list of tuples (begin datetime, end datetime)
that are the remaining valid intervals """
# TDE FIXME: waw, overriding completely a method + changing its result
# and its behavior, very nice. Please FIXME.
if not interval:
return interval
if leave_intervals is None:
leave_intervals = []
intervals = []
#leave_intervals = self.interval_clean(leave_intervals) NOT NECESSARY TO CLEAN HERE AS IT WOULD REMOVE GROUP INFO
current_interval = list(interval)
for leave in leave_intervals:
if len(leave) > 2:
current_group = False
Att = self.env["resource.calendar.attendance"]
if leave[2]:
if len(current_interval) > 2:
current_group = current_interval[2] and Att.browse(current_interval[2]).group_id.id or False
if leave[2] != current_group:
continue
if leave[1] <= current_interval[0]:
continue
if leave[0] >= current_interval[1]:
break
if current_interval[0] < leave[0] < current_interval[1]:
current_interval[1] = leave[0]
intervals.append((current_interval[0], current_interval[1]))
current_interval = [leave[1], interval[1]]
# if current_interval[0] <= leave[1] <= current_interval[1]:
if current_interval[0] <= leave[1]:
current_interval[0] = leave[1]
if current_interval and current_interval[0] < interval[1]: # remove intervals moved outside base interval due to leaves
if len(interval) > 2:
intervals.append((current_interval[0], current_interval[1], interval[2]))
else:
intervals.append((current_interval[0], current_interval[1],))
return intervals