65 lines
3.3 KiB
Python
65 lines
3.3 KiB
Python
|
|
from odoo.tools.intervals import Intervals
|
|
from datetime import datetime, timedelta
|
|
from dateutil.rrule import rrule, DAILY
|
|
from odoo.tools.date_utils import sum_intervals
|
|
from pytz import timezone, utc
|
|
import copy
|
|
|
|
from odoo import models
|
|
from odoo.fields import Domain
|
|
|
|
|
|
class HrEmployee(models.Model):
|
|
_inherit = 'hr.employee'
|
|
|
|
def _get_schedules_by_employee_by_work_type(self, start, stop, version_periods_by_employee):
|
|
res = super()._get_schedules_by_employee_by_work_type(start, stop, version_periods_by_employee)
|
|
employee_schedule = copy.deepcopy(res['schedule'])
|
|
planning_periods = []
|
|
for employee, version_periods in version_periods_by_employee.items():
|
|
for (begin, end, version) in version_periods:
|
|
if version.work_entry_source == 'planning':
|
|
planning_periods.append([
|
|
('state', '=', 'published'),
|
|
('start_datetime', '<=', end.replace(tzinfo=None)),
|
|
('end_datetime', '>=', begin.replace(tzinfo=None)),
|
|
])
|
|
version_period = Intervals([(
|
|
begin.replace(tzinfo=None),
|
|
end.replace(tzinfo=None),
|
|
self.env['resource.calendar'])])
|
|
res['schedule'][employee]['work'] -= version_period
|
|
res['fully_flexible'][employee] -= version_period
|
|
|
|
planning_slots_by_employee = dict(self.env['planning.slot'].sudo()._read_group(
|
|
domain=Domain.AND([
|
|
Domain('state', '=', 'published'),
|
|
Domain('employee_id', 'in', self.ids),
|
|
Domain.OR(planning_periods)
|
|
]),
|
|
groupby=["employee_id"],
|
|
aggregates=["id:recordset"]
|
|
))
|
|
for employee, planning_slots in planning_slots_by_employee.items():
|
|
planning_slot_interval = Intervals([])
|
|
tz = timezone(employee.tz)
|
|
for planning_slot in planning_slots:
|
|
start = utc.localize(planning_slot.start_datetime).astimezone(tz).replace(tzinfo=None)
|
|
stop = utc.localize(planning_slot.end_datetime).astimezone(tz).replace(tzinfo=None)
|
|
allocated_percentage = planning_slot.allocated_percentage
|
|
schedule_interval = employee_schedule[employee]['work'] & Intervals([(start, stop, self.env['resource.calendar'])])
|
|
planning_intervals = Intervals([])
|
|
if allocated_percentage == 100:
|
|
planning_intervals = schedule_interval
|
|
else:
|
|
for day in rrule(DAILY, dtstart=start, until=stop):
|
|
day_start = max(datetime.combine(day, datetime.min.time()), start)
|
|
day_stop = min(datetime.combine(day, datetime.max.time()), stop)
|
|
full_duration = sum_intervals(schedule_interval & Intervals([(day_start, day_stop, self.env['resource.calendar'])]))
|
|
day_stop -= timedelta(hours=full_duration * (100 - allocated_percentage))
|
|
planning_intervals |= Intervals([(day_start, day_stop, self.env['resource.calendar'])])
|
|
planning_slot_interval |= planning_intervals
|
|
res['schedule'][employee]['work'] |= planning_slot_interval
|
|
return res
|