[IMP] hr: add helpers to get employee unavaibilities
Those 2 methods are used in enterprise (for now) in order to get employee unavailabilities. This is used for planning and forecast gantt view. As we didn't want to create a bridge module for those 2 methods, we place them here as 'hr' is the only one common dependency between forecast and planning. Task-2024216 closes odoo/odoo#34638 Signed-off-by: Jérome Maes (jem) <jem@openerp.com>
This commit is contained in:
@@ -4,11 +4,14 @@
|
||||
import base64
|
||||
from random import choice
|
||||
from string import digits
|
||||
import itertools
|
||||
from werkzeug import url_encode
|
||||
import pytz
|
||||
|
||||
from odoo import api, fields, models, tools, _
|
||||
from odoo.exceptions import ValidationError, AccessError
|
||||
from odoo.modules.module import get_module_resource
|
||||
from odoo.addons.resource.models.resource_mixin import timezone_datetime
|
||||
|
||||
|
||||
class HrEmployeePrivate(models.Model):
|
||||
@@ -148,7 +151,7 @@ class HrEmployeePrivate(models.Model):
|
||||
search on an hr.employee returns a hr.employee recordset, even if you don't have access
|
||||
to this model, as the result of _search (the ids of the public employees) is to be
|
||||
browsed on the hr.employee model. This can be trusted as the ids of the public
|
||||
employees exactly match the ids of the related hr.employee.
|
||||
employees exactly match the ids of the related hr.employee.
|
||||
"""
|
||||
if self.check_access_rights('read', raise_exception=False):
|
||||
return super(HrEmployeePrivate, self)._search(args, offset=offset, limit=limit, order=order, count=count, access_rights_uid=access_rights_uid)
|
||||
@@ -306,6 +309,10 @@ class HrEmployeePrivate(models.Model):
|
||||
except AccessError:
|
||||
employee.is_address_home_a_company = False
|
||||
|
||||
# ---------------------------------------------------------
|
||||
# Business Methods
|
||||
# ---------------------------------------------------------
|
||||
|
||||
@api.model
|
||||
def get_import_templates(self):
|
||||
return [{
|
||||
@@ -326,6 +333,55 @@ class HrEmployeePrivate(models.Model):
|
||||
self = self.with_user(real_user)
|
||||
return self
|
||||
|
||||
def _get_work_interval(self, start, end):
|
||||
""" Return interval's start datetime for interval closest to start. And interval's end datetime for interval closest to end.
|
||||
If none is found return None
|
||||
Note: this method is used in enterprise (forecast and planning)
|
||||
|
||||
:start: datetime
|
||||
:end: datetime
|
||||
:return: (datetime|None, datetime|None)
|
||||
"""
|
||||
start_datetime = timezone_datetime(start)
|
||||
end_datetime = timezone_datetime(end)
|
||||
employee_mapping = {}
|
||||
for employee in self:
|
||||
work_intervals = sorted(
|
||||
employee.resource_calendar_id._work_intervals(start_datetime, end_datetime, employee.resource_id),
|
||||
key=lambda x: x[0]
|
||||
)
|
||||
if work_intervals:
|
||||
employee_mapping[employee.id] = (work_intervals[0][0].astimezone(pytz.utc), work_intervals[-1][1].astimezone(pytz.utc))
|
||||
else:
|
||||
employee_mapping[employee.id] = (None, None)
|
||||
return employee_mapping
|
||||
|
||||
def _get_unavailable_intervals(self, start, end):
|
||||
""" Compute the intervals during which employee is unavailable with hour granularity between start and end
|
||||
Note: this method is used in enterprise (forecast and planning)
|
||||
|
||||
"""
|
||||
start_datetime = timezone_datetime(start)
|
||||
end_datetime = timezone_datetime(end)
|
||||
employee_mapping = {}
|
||||
for employee in self:
|
||||
calendar = employee.resource_calendar_id
|
||||
resource = employee.resource_id
|
||||
employee_work_intervals = calendar._work_intervals(start_datetime, end_datetime, resource)
|
||||
employee_work_intervals = [(start, stop) for start, stop, meta in employee_work_intervals]
|
||||
# start + flatten(intervals) + end
|
||||
employee_work_intervals = [start_datetime] + list(itertools.chain.from_iterable(employee_work_intervals)) + [end_datetime]
|
||||
# put it back to UTC
|
||||
employee_work_intervals = list(map(lambda dt: dt.astimezone(pytz.utc), employee_work_intervals))
|
||||
# pick groups of two
|
||||
employee_work_intervals = list(zip(employee_work_intervals[0::2], employee_work_intervals[1::2]))
|
||||
employee_mapping[employee.id] = employee_work_intervals
|
||||
return employee_mapping
|
||||
|
||||
# ---------------------------------------------------------
|
||||
# Messaging
|
||||
# ---------------------------------------------------------
|
||||
|
||||
def _message_log(self, **kwargs):
|
||||
return super(HrEmployeePrivate, self._post_author())._message_log(**kwargs)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user