[IMP] resource : some docstrings cleaning + void calendar
taken into account in days scheduling + finished yesys bzr revid: tde@openerp.com-20140122132918-4c1ag6y5gqasi32d
This commit is contained in:
parent
ec2c2d4e86
commit
9fbbba1ee0
|
@ -254,7 +254,7 @@ class resource_calendar(osv.osv):
|
|||
|
||||
def get_working_intervals_of_day(self, cr, uid, id, start_dt=None, end_dt=None,
|
||||
leaves=None, compute_leaves=False, resource_id=None,
|
||||
context=None):
|
||||
context=None, default_interval=None):
|
||||
"""Get the working intervals of the day based on calendar. This method
|
||||
handle leaves that come directly from the leaves parameter or can be computed.
|
||||
|
||||
|
@ -279,12 +279,16 @@ class resource_calendar(osv.osv):
|
|||
computing the leaves. If not set, only general
|
||||
leaves are computed. If set, generic and
|
||||
specific leaves are computed.
|
||||
:param tuple default_interval: if no id, try to return a default working
|
||||
day using default_interval[0] as beginning
|
||||
hour, and default_interval[1] as ending hour.
|
||||
Example: default_interval = (8, 16).
|
||||
Otherwise, a void list of working intervals
|
||||
is returned when id is None.
|
||||
|
||||
:return list intervals: a list of tuples (start_datetime, end_datetime)
|
||||
of work intervals
|
||||
"""
|
||||
if id is None:
|
||||
return []
|
||||
if isinstance(id, (list, tuple)):
|
||||
id = id[0]
|
||||
|
||||
|
@ -305,6 +309,12 @@ class resource_calendar(osv.osv):
|
|||
intervals = []
|
||||
work_dt = start_dt.replace(hour=0, minute=0, second=0)
|
||||
|
||||
# no calendar: try to use the default_interval, then return directly
|
||||
if id is None:
|
||||
if default_interval:
|
||||
intervals.append((start_dt.replace(hour=default_interval[0]), start_dt.replace(hour=default_interval[1])))
|
||||
return intervals
|
||||
|
||||
working_intervals = []
|
||||
for calendar_working_day in self.get_attendances_for_weekdays(cr, uid, id, [start_dt.weekday()], context):
|
||||
working_interval = (
|
||||
|
@ -336,6 +346,10 @@ class resource_calendar(osv.osv):
|
|||
res += interval[1] - interval[0]
|
||||
return (res.total_seconds() / 3600.0)
|
||||
|
||||
# --------------------------------------------------
|
||||
# Hours scheduling
|
||||
# --------------------------------------------------
|
||||
|
||||
def _schedule_hours(self, cr, uid, id, hours, day_dt=None,
|
||||
compute_leaves=False, resource_id=None,
|
||||
context=None):
|
||||
|
@ -343,7 +357,7 @@ class resource_calendar(osv.osv):
|
|||
compute working and leave days. This method can be used backwards, i.e.
|
||||
scheduling days before a deadline.
|
||||
|
||||
:param timedelta hours: number of hours to schedule
|
||||
:param int hours: number of hours to schedule
|
||||
:param datetime day_dt: reference date to compute working days. If days is
|
||||
> 0 date is the starting date. If days is < 0
|
||||
date is the ending date.
|
||||
|
@ -381,7 +395,7 @@ class resource_calendar(osv.osv):
|
|||
|
||||
working_intervals = self.get_working_intervals_of_day(cr, uid, id, **call_args)
|
||||
|
||||
if id is None: # no calendar -> consider 8 working hours
|
||||
if id is None: # no calendar -> consider working 8 hours
|
||||
remaining_hours -= 8.0
|
||||
elif working_intervals:
|
||||
if backwards:
|
||||
|
@ -419,7 +433,8 @@ class resource_calendar(osv.osv):
|
|||
scheduling. """
|
||||
return self._schedule_hours(cr, uid, id, hours, day_dt, compute_leaves, resource_id, context)
|
||||
|
||||
def get_working_hours(self, cr, uid, id, start_dt, end_dt, compute_leaves=False, resource_id=None, context=None):
|
||||
def get_working_hours(self, cr, uid, id, start_dt, end_dt, compute_leaves=False,
|
||||
resource_id=None, context=None):
|
||||
hours = 0.0
|
||||
for day in rrule.rrule(rrule.DAILY, dtstart=start_dt,
|
||||
until=end_dt + datetime.timedelta(days=1),
|
||||
|
@ -427,11 +442,18 @@ class resource_calendar(osv.osv):
|
|||
hours += self.get_working_hours_of_date(cr, uid, id, start_dt=day, compute_leaves=compute_leaves, resource_id=resource_id)
|
||||
return hours
|
||||
|
||||
def _schedule_days(self, cr, uid, id, days, day_date=None, compute_leaves=False, resource_id=None, context=None):
|
||||
# --------------------------------------------------
|
||||
# Days scheduling
|
||||
# --------------------------------------------------
|
||||
|
||||
def _schedule_days(self, cr, uid, id, days, day_date=None, compute_leaves=False,
|
||||
resource_id=None, default_interval=None, context=None):
|
||||
"""Schedule days of work, using a calendar and an optional resource to
|
||||
compute working and leave days. This method can be used backwards, i.e.
|
||||
scheduling days before a deadline.
|
||||
|
||||
:param int days: number of days to schedule. Use a negative number to compute
|
||||
a backwards scheduling.
|
||||
:param date day_date: reference date to compute working days. If days is > 0
|
||||
date is the starting date. If days is < 0 date is the
|
||||
ending date.
|
||||
|
@ -442,13 +464,19 @@ class resource_calendar(osv.osv):
|
|||
computing the leaves. If not set, only general
|
||||
leaves are computed. If set, generic and
|
||||
specific leaves are computed.
|
||||
:param tuple default_interval: if no id, try to return a default working
|
||||
day using default_interval[0] as beginning
|
||||
hour, and default_interval[1] as ending hour.
|
||||
Example: default_interval = (8, 16).
|
||||
Otherwise, a void list of working intervals
|
||||
is returned when id is None.
|
||||
|
||||
:return tuple (datetime, intervals): datetime is the beginning/ending date
|
||||
of the schedulign; intervals are the
|
||||
working intervals of the scheduling.
|
||||
|
||||
TDE NOTE: Why not using rrule.rrule ? Because rrule does not seem to
|
||||
allow getting back in time.
|
||||
Implementation note: rrule.rrule is not used because rrule it des not seem
|
||||
to allow getting back in time.
|
||||
"""
|
||||
if day_date is None:
|
||||
day_date = datetime.datetime.now()
|
||||
|
@ -463,7 +491,11 @@ class resource_calendar(osv.osv):
|
|||
current_datetime = day_date.replace(hour=0, minute=0, second=0)
|
||||
|
||||
while planned_days < days and iterations < 1000:
|
||||
working_intervals = self.get_working_intervals_of_day(cr, uid, id, current_datetime, compute_leaves=compute_leaves, resource_id=resource_id, context=context)
|
||||
working_intervals = self.get_working_intervals_of_day(
|
||||
cr, uid, id, current_datetime,
|
||||
compute_leaves=compute_leaves, resource_id=resource_id,
|
||||
context=context,
|
||||
default_interval=default_interval)
|
||||
if id is None or working_intervals: # no calendar -> no working hours, but day is considered as worked
|
||||
planned_days += 1
|
||||
intervals += working_intervals
|
||||
|
@ -477,33 +509,37 @@ class resource_calendar(osv.osv):
|
|||
|
||||
return intervals
|
||||
|
||||
def schedule_days_get_date(self, cr, uid, id, days, day_date=None, compute_leaves=False, resource_id=None, context=None):
|
||||
"""Wrapper on _schedule_days: return the beginning/ending datetime of
|
||||
def schedule_days_get_date(self, cr, uid, id, days, day_date=None, compute_leaves=False,
|
||||
resource_id=None, default_interval=None, context=None):
|
||||
""" Wrapper on _schedule_days: return the beginning/ending datetime of
|
||||
a days scheduling. """
|
||||
res = self._schedule_days(cr, uid, id, days, day_date, compute_leaves, resource_id, context)
|
||||
return res[-1][1]
|
||||
res = self._schedule_days(cr, uid, id, days, day_date, compute_leaves, resource_id, default_interval, context)
|
||||
return res and res[-1][1] or []
|
||||
|
||||
def schedule_days(self, cr, uid, id, days, day_date=None, compute_leaves=False, resource_id=None, context=None):
|
||||
"""Wrapper on _schedule_days: return the working intervals of a days
|
||||
def schedule_days(self, cr, uid, id, days, day_date=None, compute_leaves=False,
|
||||
resource_id=None, default_interval=None, context=None):
|
||||
""" Wrapper on _schedule_days: return the working intervals of a days
|
||||
scheduling. """
|
||||
return self._schedule_days(cr, uid, id, days, day_date, compute_leaves, resource_id, context)
|
||||
return self._schedule_days(cr, uid, id, days, day_date, compute_leaves, resource_id, default_interval, context)
|
||||
|
||||
# --------------------------------------------------
|
||||
# Compatibility / to clean / to remove
|
||||
# --------------------------------------------------
|
||||
|
||||
def working_hours_on_day(self, cr, uid, resource_calendar_id, day, context=None):
|
||||
""" Compatibility method - will be removed for OpenERP v8.
|
||||
Computation was done for the whole day, ignoring hour/minutes.
|
||||
Used in hr_payroll/hr_payroll.py """
|
||||
""" Used in hr_payroll/hr_payroll.py
|
||||
|
||||
:deprecated: OpenERP saas-3. Use get_working_hours_of_date instead. Note:
|
||||
since saas-3, take hour/minutes into account, not just the whole day."""
|
||||
if isinstance(day, datetime.datetime):
|
||||
day = day.replace(hour=0, minute=0)
|
||||
return self.get_working_hours_of_date(cr, uid, resource_calendar_id.id, start_dt=day, context=None)
|
||||
|
||||
def interval_min_get(self, cr, uid, id, dt_from, hours, resource=False):
|
||||
""" Compatibility method - will be removed for OpenERP v8.
|
||||
Schedule hours backwards. Note: now count leave hours instead of all-day leaves.
|
||||
Used in mrp_operations/mrp_operations.py. """
|
||||
""" Schedule hours backwards. Used in mrp_operations/mrp_operations.py.
|
||||
|
||||
:deprecated: OpenERP saas-3. Use schedule_hours instead. Note: since
|
||||
saas-3, counts leave hours instead of all-day leaves."""
|
||||
return self.schedule_hours(
|
||||
cr, uid, id, hours * -1.0,
|
||||
day_dt=dt_from.replace(minute=0, second=0),
|
||||
|
@ -511,9 +547,11 @@ class resource_calendar(osv.osv):
|
|||
)
|
||||
|
||||
def interval_get_multi(self, cr, uid, date_and_hours_by_cal, resource=False, byday=True):
|
||||
""" Compatibility method - will be removed for OpenERP v8.
|
||||
Note: used in mrp_operations/mrp_operations.py (default parameters) and in interval_get()
|
||||
Byday was not used. Now counts Leave hours instead of all-day leaves. """
|
||||
""" Used in mrp_operations/mrp_operations.py (default parameters) and in
|
||||
interval_get()
|
||||
|
||||
:deprecated: OpenERP saas-3. Use get_working_hours_of_date instead. Note:
|
||||
Byday was not used. Since saas-3, counts Leave hours instead of all-day leaves."""
|
||||
res = {}
|
||||
for dt_str, hours, calendar_id in date_and_hours_by_cal:
|
||||
result = self.schedule_hours(
|
||||
|
@ -525,20 +563,25 @@ class resource_calendar(osv.osv):
|
|||
return res
|
||||
|
||||
def interval_get(self, cr, uid, id, dt_from, hours, resource=False, byday=True):
|
||||
""" Compatibility method - will be removed for OpenERP v8. Unifier of interval_get_multi.
|
||||
Used in: mrp_operations/mrp_operations.py, crm/crm_lead.py (res given) """
|
||||
""" Unifier of interval_get_multi. Used in: mrp_operations/mrp_operations.py,
|
||||
crm/crm_lead.py (res given).
|
||||
|
||||
:deprecated: OpenERP saas-3. Use get_working_hours instead."""
|
||||
res = self.interval_get_multi(cr, uid, [(dt_from.strftime('%Y-%m-%d %H:%M:%S'), hours, id)], resource, byday)[(dt_from.strftime('%Y-%m-%d %H:%M:%S'), hours, id)]
|
||||
return res
|
||||
|
||||
def interval_hours_get(self, cr, uid, id, dt_from, dt_to, resource=False):
|
||||
""" Compatibility method - will be removed for OpenERP v8. Unused wrapper """
|
||||
""" Unused wrapper.
|
||||
|
||||
:deprecated: OpenERP saas-3. Use get_working_hours instead."""
|
||||
return self._interval_hours_get(cr, uid, id, dt_from, dt_to, resource_id=resource)
|
||||
|
||||
def _interval_hours_get(self, cr, uid, id, dt_from, dt_to, resource_id=False, timezone_from_uid=None, exclude_leaves=True, context=None):
|
||||
""" Compatibility method - will be removed for OpenERP v8.
|
||||
Computes working hours between two dates, taking always same hour/minuts.
|
||||
Note: now resets hour/minuts. Now counts leave hours instead of all-day leaves. """
|
||||
return self.get_working_hours(cr, uid, id, dt_from, dt_to, compute_leaves=exclude_leaves, resource_id=resource_id, context=context)
|
||||
""" Computes working hours between two dates, taking always same hour/minuts.
|
||||
|
||||
:deprecated: OpenERP saas-3. Use get_working_hours instead. Note: since saas-3,
|
||||
now resets hour/minuts. Now counts leave hours instead of all-day leaves."""
|
||||
return self.get_working_hours(cr, uid, id, dt_from, dt_to, compute_leaves=(not exclude_leaves), resource_id=resource_id, context=context)
|
||||
|
||||
|
||||
class resource_calendar_attendance(osv.osv):
|
||||
|
|
|
@ -52,7 +52,7 @@ class TestResourceCommon(common.TransactionCase):
|
|||
self.leave3_end = datetime.strptime('2013-03-01 11:30:00', '%Y-%m-%d %H:%M:%S')
|
||||
|
||||
# Resource data
|
||||
# Calendar working days: 1 (8-16), 4 (8-13, 21-22)
|
||||
# Calendar working days: 1 (8-16 -> 8hours), 4 (8-13, 16-23 -> 12hours)
|
||||
self.calendar_id = self.resource_calendar.create(
|
||||
cr, uid, {
|
||||
'name': 'TestCalendar',
|
||||
|
|
|
@ -293,7 +293,7 @@ class TestResource(TestResourceCommon):
|
|||
self.assertEqual(td.total_seconds() / 3600.0, 40.0, 'resource_calendar: wrong hours scheduling')
|
||||
|
||||
# --------------------------------------------------
|
||||
# Test1: schedule hours forward (old interval_get)
|
||||
# Test2: schedule hours forward (old interval_get)
|
||||
# --------------------------------------------------
|
||||
|
||||
# res = self.resource_calendar.interval_get(cr, uid, self.calendar_id, self.date1, 40, resource=False, byday=True)
|
||||
|
@ -366,23 +366,55 @@ class TestResource(TestResourceCommon):
|
|||
td += item[1] - item[0]
|
||||
self.assertEqual(td.total_seconds() / 3600.0, 40.0, 'resource_calendar: wrong hours scheduling')
|
||||
|
||||
res = self.resource_calendar._interval_hours_get(cr, uid, self.calendar_id, self.date1.replace(hour=6, minute=0), self.date2.replace(hour=23, minute=0) + relativedelta(days=7), resource_id=self.resource1_id, exclude_leaves=False)
|
||||
# print res
|
||||
# --------------------------------------------------
|
||||
# Test3: working hours (old _interval_hours_get)
|
||||
# --------------------------------------------------
|
||||
|
||||
res = self.resource_calendar.get_working_hours(cr, uid, self.calendar_id, self.date1.replace(hour=6, minute=0), self.date2.replace(hour=23, minute=0) + relativedelta(days=7), compute_leaves=False, resource_id=self.resource1_id)
|
||||
# print res
|
||||
# old API: resource without leaves
|
||||
# res: 2 weeks -> 40 hours
|
||||
res = self.resource_calendar._interval_hours_get(
|
||||
cr, uid, self.calendar_id,
|
||||
self.date1.replace(hour=6, minute=0),
|
||||
self.date2.replace(hour=23, minute=0) + relativedelta(days=7),
|
||||
resource_id=self.resource1_id, exclude_leaves=True)
|
||||
self.assertEqual(res, 40.0, 'resource_calendar: wrong _interval_hours_get compatibility computation')
|
||||
|
||||
res = self.resource_calendar._interval_hours_get(cr, uid, self.calendar_id, self.date1.replace(hour=6, minute=0), self.date2.replace(hour=23, minute=0) + relativedelta(days=7), resource_id=self.resource1_id, exclude_leaves=True)
|
||||
# print res
|
||||
# new API: resource without leaves
|
||||
# res: 2 weeks -> 40 hours
|
||||
res = self.resource_calendar.get_working_hours(
|
||||
cr, uid, self.calendar_id,
|
||||
self.date1.replace(hour=6, minute=0),
|
||||
self.date2.replace(hour=23, minute=0) + relativedelta(days=7),
|
||||
compute_leaves=False, resource_id=self.resource1_id)
|
||||
self.assertEqual(res, 40.0, 'resource_calendar: wrong get_working_hours computation')
|
||||
|
||||
res = self.resource_calendar.get_working_hours(cr, uid, self.calendar_id, self.date1.replace(hour=6, minute=0), self.date2.replace(hour=23, minute=0) + relativedelta(days=7), compute_leaves=True, resource_id=self.resource1_id)
|
||||
# print res
|
||||
# old API: resource and leaves
|
||||
# res: 2 weeks -> 40 hours - (3+4) leave hours
|
||||
res = self.resource_calendar._interval_hours_get(
|
||||
cr, uid, self.calendar_id,
|
||||
self.date1.replace(hour=6, minute=0),
|
||||
self.date2.replace(hour=23, minute=0) + relativedelta(days=7),
|
||||
resource_id=self.resource1_id, exclude_leaves=False)
|
||||
self.assertEqual(res, 33.0, 'resource_calendar: wrong _interval_hours_get compatibility computation')
|
||||
|
||||
# new API: resource and leaves
|
||||
# res: 2 weeks -> 40 hours - (3+4) leave hours
|
||||
res = self.resource_calendar.get_working_hours(
|
||||
cr, uid, self.calendar_id,
|
||||
self.date1.replace(hour=6, minute=0),
|
||||
self.date2.replace(hour=23, minute=0) + relativedelta(days=7),
|
||||
compute_leaves=True, resource_id=self.resource1_id)
|
||||
self.assertEqual(res, 33.0, 'resource_calendar: wrong get_working_hours computation')
|
||||
|
||||
def test_50_calendar_schedule_days(self):
|
||||
""" Testing calendar days scheduling """
|
||||
cr, uid = self.cr, self.uid
|
||||
_format = '%Y-%m-%d %H:%M:%S'
|
||||
|
||||
# --------------------------------------------------
|
||||
# Test1: with calendar
|
||||
# --------------------------------------------------
|
||||
|
||||
res = self.resource_calendar.schedule_days_get_date(cr, uid, self.calendar_id, 5, day_date=self.date1)
|
||||
self.assertEqual(res.date(), datetime.strptime('2013-02-26 00:0:00', _format).date(), 'resource_calendar: wrong days scheduling')
|
||||
|
||||
|
@ -392,10 +424,9 @@ class TestResource(TestResourceCommon):
|
|||
self.assertEqual(res.date(), datetime.strptime('2013-03-01 00:0:00', _format).date(), 'resource_calendar: wrong days scheduling')
|
||||
|
||||
# --------------------------------------------------
|
||||
# Misc
|
||||
# Test2: without calendar and default scheduling
|
||||
# --------------------------------------------------
|
||||
|
||||
# # Without calendar, should only count days
|
||||
# print '---------------'
|
||||
# res = self.resource_calendar.schedule_days_get_date(cr, uid, None, 5, day_date=self.date1)
|
||||
# print res
|
||||
# Without calendar, should only count days -> 12 -> 16, 5 days
|
||||
res = self.resource_calendar.schedule_days_get_date(cr, uid, None, 5, day_date=self.date1, default_interval=(8, 16))
|
||||
self.assertEqual(res, datetime.strptime('2013-02-16 16:00:00', _format), 'resource_calendar: wrong days scheduling')
|
||||
|
|
Loading…
Reference in New Issue