[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:
jem-odoo
2019-07-05 13:06:05 +00:00
parent 3ca2842cc1
commit 31a8616a03
+57 -1
View File
@@ -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)