# -*- 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