[MOV] hr, resource: unavailability methods

Move and adapt gantt unavailability related methods (
_get_work_interval() and _get_unavailable_intervals() ) from
hr.employee to resource.resource. This move allows the unavailability
to be generated for users without related employees (like in FSM in
enterprise).

Task-2069861

closes odoo/odoo#36785

Signed-off-by: Jérome Maes (jem) <jem@openerp.com>
This commit is contained in:
Geoffroy Larue
2019-09-30 07:59:10 +00:00
parent 5350c6576a
commit 9a39194813
2 changed files with 45 additions and 45 deletions
-45
View File
@@ -327,51 +327,6 @@ 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
# ---------------------------------------------------------
+45
View File
@@ -17,6 +17,7 @@ from odoo.osv import expression
from odoo.tools.float_utils import float_round
from odoo.tools import date_utils, float_utils
from .resource_mixin import timezone_datetime
# Default hour per day value. The one should
# only be used when the one from the calendar
@@ -702,6 +703,50 @@ class ResourceResource(models.Model):
if self.user_id:
self.tz = self.user_id.tz
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)
resource_mapping = {}
for resource in self:
work_intervals = sorted(
resource.calendar_id._work_intervals(start_datetime, end_datetime, resource),
key=lambda x: x[0]
)
if work_intervals:
resource_mapping[resource.id] = (work_intervals[0][0].astimezone(utc), work_intervals[-1][1].astimezone(utc))
else:
resource_mapping[resource.id] = (None, None)
return resource_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)
resource_mapping = {}
for resource in self:
calendar = resource.calendar_id
resource_work_intervals = calendar._work_intervals(start_datetime, end_datetime, resource)
resource_work_intervals = [(start, stop) for start, stop, meta in resource_work_intervals]
# start + flatten(intervals) + end
resource_work_intervals = [start_datetime] + list(chain.from_iterable(resource_work_intervals)) + [end_datetime]
# put it back to UTC
resource_work_intervals = list(map(lambda dt: dt.astimezone(utc), resource_work_intervals))
# pick groups of two
resource_work_intervals = list(zip(resource_work_intervals[0::2], resource_work_intervals[1::2]))
resource_mapping[resource.id] = resource_work_intervals
return resource_mapping
class ResourceCalendarLeaves(models.Model):
_name = "resource.calendar.leaves"