diff --git a/addons/hr_holidays/models/hr_holidays.py b/addons/hr_holidays/models/hr_holidays.py
index 72cbd3e24c1..d2aa657de4e 100644
--- a/addons/hr_holidays/models/hr_holidays.py
+++ b/addons/hr_holidays/models/hr_holidays.py
@@ -163,10 +163,10 @@ class Holidays(models.Model):
('validate1', 'Second Approval'),
('validate', 'Approved')
], string='Status', readonly=True, track_visibility='onchange', copy=False, default='confirm',
- help="The status is set to 'To Submit', when a holiday request is created.\
- \nThe status is 'To Approve', when holiday request is confirmed by user.\
- \nThe status is 'Refused', when holiday request is refused by manager.\
- \nThe status is 'Approved', when holiday request is approved by manager.")
+ help="The status is set to 'To Submit', when a holiday request is created." +
+ "\nThe status is 'To Approve', when holiday request is confirmed by user." +
+ "\nThe status is 'Refused', when holiday request is refused by manager." +
+ "\nThe status is 'Approved', when holiday request is approved by manager.")
payslip_status = fields.Boolean('Reported in last payslips',
help='Green this button when the leave has been taken into account in the payslip.')
report_note = fields.Text('HR Comments')
@@ -284,7 +284,7 @@ class Holidays(models.Model):
uom_hour = resource.calendar_id.uom_id
uom_day = self.env.ref('product.product_uom_day')
if uom_hour and uom_day:
- return self.env['product.uom']._compute_qty_obj(uom_hour, hours[0], uom_day)
+ return self.env['product.uom']._compute_qty_obj(uom_hour, hours, uom_day)
time_delta = to_dt - from_dt
return math.ceil(time_delta.days + float(time_delta.seconds) / 86400)
diff --git a/addons/hr_payroll/models/hr_payroll.py b/addons/hr_payroll/models/hr_payroll.py
index beb5aa0caff..fd8646f96c8 100644
--- a/addons/hr_payroll/models/hr_payroll.py
+++ b/addons/hr_payroll/models/hr_payroll.py
@@ -330,7 +330,7 @@ class HrPayslip(models.Model):
day_to = fields.Datetime.from_string(date_to)
nb_of_days = (day_to - day_from).days + 1
for day in range(0, nb_of_days):
- working_hours_on_day = self.env['resource.calendar'].working_hours_on_day(contract.working_hours, day_from + timedelta(days=day))
+ working_hours_on_day = contract.working_hours.working_hours_on_day(day_from + timedelta(days=day))
if working_hours_on_day:
#the employee had to work
leave_type = was_on_leave(contract.employee_id.id, day_from + timedelta(days=day))
diff --git a/addons/project_issue/models/project_issue.py b/addons/project_issue/models/project_issue.py
index 8d4dacd0caf..7c0598ea54e 100644
--- a/addons/project_issue/models/project_issue.py
+++ b/addons/project_issue/models/project_issue.py
@@ -94,35 +94,21 @@ class ProjectIssue(models.Model):
@api.depends('create_date', 'date_closed', 'date_open')
def _compute_day(self):
for issue in self:
- # if the working hours on the project are not defined, use default ones (8 -> 12 and 13 -> 17 * 5), represented by None
- calendar_id = None
- if issue.project_id and issue.project_id.resource_calendar_id:
- calendar_id = issue.project_id.resource_calendar_id.id
+ # if the working hours on the project are not defined, use default ones (8 -> 12 and 13 -> 17 * 5)
+ calendar = issue.project_id.resource_calendar_id
dt_create_date = fields.Datetime.from_string(issue.create_date)
if issue.date_open:
dt_date_open = fields.Datetime.from_string(issue.date_open)
issue.day_open = (dt_date_open - dt_create_date).total_seconds() / (24.0 * 3600)
- # FIXME when resource.calendar is migrated to new api
- # Old api call because get_working_hours uses get_weekdays
- # which has a different behavior if the given id is None.
- issue.working_hours_open = self.pool['resource.calendar'].get_working_hours(
- self.env.cr, self.env.uid, calendar_id, dt_create_date, dt_date_open,
- compute_leaves=True, resource_id=False, default_interval=(8, 16),
- context=self.env.context
- )
+ issue.working_hours_open = calendar.get_working_hours(dt_create_date, dt_date_open,
+ compute_leaves=True, resource_id=False, default_interval=(8, 16))
if issue.date_closed:
dt_date_closed = fields.Datetime.from_string(issue.date_closed)
issue.day_close = (dt_date_closed - dt_create_date).total_seconds() / (24.0 * 3600)
- # FIXME when resource.calendar is migrated to new api
- # Old api call because get_working_hours uses get_weekdays
- # which has a different behavior if the given id is None.
- issue.working_hours_close = self.pool['resource.calendar'].get_working_hours(
- self.env.cr, self.env.uid, calendar_id, dt_create_date, dt_date_closed,
- compute_leaves=True, resource_id=False, default_interval=(8, 16),
- context=self.env.context
- )
+ issue.working_hours_close = calendar.get_working_hours(dt_create_date, dt_date_closed,
+ compute_leaves=True, resource_id=False, default_interval=(8, 16))
@api.multi
@api.depends('create_date', 'date_action_last', 'date_last_stage_update')
diff --git a/addons/resource/__init__.py b/addons/resource/__init__.py
index 4ca401409b4..81fc81d29c9 100644
--- a/addons/resource/__init__.py
+++ b/addons/resource/__init__.py
@@ -1,4 +1,4 @@
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
-import resource
+import models
diff --git a/addons/resource/__openerp__.py b/addons/resource/__openerp__.py
index 9ca5c246d5f..1c79b94ace0 100644
--- a/addons/resource/__openerp__.py
+++ b/addons/resource/__openerp__.py
@@ -2,10 +2,9 @@
# Part of Odoo. See LICENSE file for full copyright and licensing details.
{
- 'name' : 'Resource',
- 'version' : '1.1',
- 'category' : 'Hidden',
- 'website' : 'http://www.openerp.com',
+ 'name': 'Resource',
+ 'version': '1.1',
+ 'category': 'Hidden',
'description': """
Module for resource management.
===============================
@@ -18,13 +17,7 @@ associated to every resource. It also manages the leaves of every resource.
'data': [
'security/ir.model.access.csv',
'security/resource_security.xml',
- 'resource_view.xml',
+ 'views/resource_views.xml',
],
- 'demo': ['resource_demo.xml'],
- 'test': [
- 'test/resource.yml',
- 'test/duplicate_resource.yml',
- ],
- 'installable': True,
- 'auto_install': False,
+ 'demo': ['data/resource_demo.xml'],
}
diff --git a/addons/resource/resource_demo.xml b/addons/resource/data/resource_demo.xml
similarity index 99%
rename from addons/resource/resource_demo.xml
rename to addons/resource/data/resource_demo.xml
index 509e57ca262..7869468483c 100644
--- a/addons/resource/resource_demo.xml
+++ b/addons/resource/data/resource_demo.xml
@@ -1,6 +1,5 @@
-
-
+
@@ -121,5 +120,4 @@
-
-
+
diff --git a/addons/resource/models/__init__.py b/addons/resource/models/__init__.py
new file mode 100644
index 00000000000..4ca401409b4
--- /dev/null
+++ b/addons/resource/models/__init__.py
@@ -0,0 +1,4 @@
+# -*- coding: utf-8 -*-
+# Part of Odoo. See LICENSE file for full copyright and licensing details.
+
+import resource
diff --git a/addons/resource/resource.py b/addons/resource/models/resource.py
similarity index 68%
rename from addons/resource/resource.py
rename to addons/resource/models/resource.py
index 3f41e2c1552..b10637cdbaa 100644
--- a/addons/resource/resource.py
+++ b/addons/resource/models/resource.py
@@ -2,21 +2,19 @@
# Part of Odoo. See LICENSE file for full copyright and licensing details.
import datetime
-import functools
+import pytz
+
from datetime import timedelta
from dateutil import rrule
from dateutil.relativedelta import relativedelta
-from openerp.tools import DEFAULT_SERVER_DATE_FORMAT
from operator import itemgetter
-from openerp import tools
-from openerp.osv import fields, osv
-from openerp.tools.float_utils import float_compare
-from openerp.tools.translate import _
-from openerp.exceptions import UserError
-import pytz
+from odoo import api, fields, models, _
+from odoo.exceptions import ValidationError
+from odoo.tools.float_utils import float_compare
-class resource_calendar(osv.osv):
+
+class ResourceCalendar(models.Model):
""" Calendar model for a resource. It has
- attendance_ids: list of resource.calendar.attendance that are a working
@@ -30,19 +28,15 @@ class resource_calendar(osv.osv):
_name = "resource.calendar"
_description = "Resource Calendar"
- _columns = {
- 'name': fields.char("Name", required=True),
- 'company_id': fields.many2one('res.company', 'Company', required=False),
- 'attendance_ids': fields.one2many('resource.calendar.attendance', 'calendar_id', 'Working Time', copy=True),
- 'manager': fields.many2one('res.users', 'Workgroup Manager'),
- 'leave_ids': fields.one2many(
- 'resource.calendar.leaves', 'calendar_id', 'Leaves',
- help=''
- ),
- }
- _defaults = {
- 'company_id': lambda self, cr, uid, context: self.pool.get('res.company')._company_default_get(cr, uid, 'resource.calendar', context=context)
- }
+ name = fields.Char(required=True)
+ company_id = fields.Many2one('res.company', string='Company',
+ default=lambda self: self.env['res.company']._company_default_get())
+ attendance_ids = fields.One2many(
+ 'resource.calendar.attendance', 'calendar_id', string='Working Time',
+ copy=True)
+ manager = fields.Many2one('res.users', string='Workgroup Manager')
+ leave_ids = fields.One2many(
+ 'resource.calendar.leaves', 'calendar_id', string='Leaves')
# --------------------------------------------------
# Utility methods
@@ -72,7 +66,8 @@ class resource_calendar(osv.osv):
cleaned.append(tuple(working_interval))
return cleaned
- def interval_remove_leaves(self, cr, uid, interval, leave_intervals, context=None):
+ @api.model
+ def interval_remove_leaves(self, interval, leave_intervals):
""" Utility method that remove leave intervals from a base interval:
- clean the leave intervals, to have an ordered list of not-overlapping
@@ -112,7 +107,6 @@ class resource_calendar(osv.osv):
current_interval[1] = leave[0]
intervals.append((current_interval[0], current_interval[1]))
current_interval = [leave[1], interval[1]]
- # if current_interval[0] <= leave[1] <= current_interval[1]:
if current_interval[0] <= leave[1]:
current_interval[0] = leave[1]
if current_interval and current_interval[0] < interval[1]: # remove intervals moved outside base interval due to leaves
@@ -139,14 +133,14 @@ class resource_calendar(osv.osv):
is greater than the possible scheduling in the intervals, no extra-scheduling
is done, and results == intervals. """
results = []
- res = datetime.timedelta()
- limit = datetime.timedelta(hours=hour)
+ res = timedelta()
+ limit = timedelta(hours=hour)
for interval in intervals:
res += interval[1] - interval[0]
if res > limit and remove_at_end:
- interval = (interval[0], interval[1] + relativedelta(seconds=seconds(limit-res)))
+ interval = (interval[0], interval[1] + relativedelta(seconds=seconds(limit - res)))
elif res > limit:
- interval = (interval[0] + relativedelta(seconds=seconds(res-limit)), interval[1])
+ interval = (interval[0] + relativedelta(seconds=seconds(res - limit)), interval[1])
results.append(interval)
if res > limit:
break
@@ -156,41 +150,40 @@ class resource_calendar(osv.osv):
# Date and hours computation
# --------------------------------------------------
- def get_attendances_for_weekday(self, cr, uid, id, date, context=None):
+ @api.multi
+ def get_attendances_for_weekday(self, date):
""" Given a list of weekdays, return matching resource.calendar.attendance"""
- calendar = self.browse(cr, uid, id, context=None)
+ self.ensure_one()
weekday = date.weekday()
- date = date.strftime(DEFAULT_SERVER_DATE_FORMAT)
- res = []
- for att in calendar.attendance_ids:
- if int(att.dayofweek) == weekday:
- if not ((att.date_from and date < att.date_from) or (att.date_to and date > att.date_to)):
- res.append(att)
- return res
+ date = fields.Date.today()
+ attendances = self.env['resource.calendar.attendance']
+ for attendance in self.attendance_ids.filtered(lambda att: int(att.dayofweek) == weekday and
+ not ((att.date_from and date < att.date_from) or (att.date_to and date > att.date_to))):
+ attendances |= attendance
+ return attendances
- def get_weekdays(self, cr, uid, id, default_weekdays=None, context=None):
+ @api.multi
+ def get_weekdays(self, default_weekdays=None):
""" Return the list of weekdays that contain at least one working interval.
If no id is given (no calendar), return default weekdays. """
- if id is None:
+ if not self:
return default_weekdays if default_weekdays is not None else [0, 1, 2, 3, 4]
- calendar = self.browse(cr, uid, id, context=None)
- weekdays = set()
- for attendance in calendar.attendance_ids:
- weekdays.add(int(attendance.dayofweek))
+ self.ensure_one()
+ weekdays = set(map(int, (self.attendance_ids.mapped('dayofweek'))))
return list(weekdays)
- def get_next_day(self, cr, uid, id, day_date, context=None):
+ @api.multi
+ def get_next_day(self, day_date):
""" Get following date of day_date, based on resource.calendar. If no
calendar is provided, just return the next day.
- :param int id: id of a resource.calendar. If not given, simply add one day
- to the submitted date.
:param date day_date: current day as a date
:return date: next day of calendar, or just next day """
- if not id:
+ if not self:
return day_date + relativedelta(days=1)
- weekdays = self.get_weekdays(cr, uid, id, context)
+ self.ensure_one()
+ weekdays = self.get_weekdays()
base_index = -1
for weekday in weekdays:
@@ -205,18 +198,18 @@ class resource_calendar(osv.osv):
return day_date + relativedelta(days=days)
- def get_previous_day(self, cr, uid, id, day_date, context=None):
+ @api.multi
+ def get_previous_day(self, day_date):
""" Get previous date of day_date, based on resource.calendar. If no
calendar is provided, just return the previous day.
- :param int id: id of a resource.calendar. If not given, simply remove
- one day from the submitted date.
:param date day_date: current day as a date
:return date: previous day of calendar, or just previous day """
- if not id:
+ if not self:
return day_date + relativedelta(days=-1)
- weekdays = self.get_weekdays(cr, uid, id, context)
+ self.ensure_one()
+ weekdays = self.get_weekdays()
weekdays.reverse()
base_index = -1
@@ -232,9 +225,9 @@ class resource_calendar(osv.osv):
return day_date + relativedelta(days=days)
- def get_leave_intervals(self, cr, uid, id, resource_id=None,
- start_datetime=None, end_datetime=None,
- context=None):
+ @api.multi
+ def get_leave_intervals(self, resource_id=None,
+ start_datetime=None, end_datetime=None):
"""Get the leaves of the calendar. Leaves can be filtered on the resource,
the start datetime or the end datetime.
@@ -250,27 +243,27 @@ class resource_calendar(osv.osv):
:return list leaves: list of tuples (start_datetime, end_datetime) of
leave intervals
"""
- resource_calendar = self.browse(cr, uid, id, context=context)
+ self.ensure_one()
leaves = []
- for leave in resource_calendar.leave_ids:
+ for leave in self.leave_ids:
if leave.resource_id and not resource_id == leave.resource_id.id:
continue
- date_from = datetime.datetime.strptime(leave.date_from, tools.DEFAULT_SERVER_DATETIME_FORMAT)
+ date_from = fields.Datetime.from_string(leave.date_from)
if end_datetime and date_from > end_datetime:
continue
- date_to = datetime.datetime.strptime(leave.date_to, tools.DEFAULT_SERVER_DATETIME_FORMAT)
+ date_to = fields.Datetime.from_string(leave.date_to)
if start_datetime and date_to < start_datetime:
continue
leaves.append((date_from, date_to))
return leaves
- def get_working_intervals_of_day(self, cr, uid, id, start_dt=None, end_dt=None,
+ @api.multi
+ def get_working_intervals_of_day(self, start_dt=None, end_dt=None,
leaves=None, compute_leaves=False, resource_id=None,
- default_interval=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.
- :param int id: resource.calendar id; take the first one if is a list
:param datetime start_dt: datetime object that is the beginning hours
for the working intervals computation; any
working interval beginning before start_dt
@@ -300,8 +293,6 @@ class resource_calendar(osv.osv):
:return list intervals: a list of tuples (start_datetime, end_datetime)
of work intervals """
- if isinstance(id, (list, tuple)):
- id = id[0]
# Computes start_dt, end_dt (with default values if not set) + off-interval work limits
work_limits = []
@@ -321,17 +312,17 @@ class resource_calendar(osv.osv):
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 not self:
working_interval = []
if default_interval:
working_interval = (start_dt.replace(hour=default_interval[0], minute=0, second=0),
start_dt.replace(hour=default_interval[1], minute=0, second=0))
- intervals = self.interval_remove_leaves(cr, uid, working_interval, work_limits, context=context)
+ intervals = self.interval_remove_leaves(working_interval, work_limits)
return intervals
working_intervals = []
- tz_info = fields.datetime.context_timestamp(cr, uid, work_dt, context=context).tzinfo
- for calendar_working_day in self.get_attendances_for_weekday(cr, uid, id, start_dt, context=context):
+ tz_info = fields.Datetime.context_timestamp(self, work_dt).tzinfo
+ for calendar_working_day in self.get_attendances_for_weekday(start_dt):
dt_f = work_dt.replace(hour=0, minute=0, second=0) + timedelta(seconds=(calendar_working_day.hour_from * 3600))
dt_t = work_dt.replace(hour=0, minute=0, second=0) + timedelta(seconds=(calendar_working_day.hour_to * 3600))
@@ -341,41 +332,42 @@ class resource_calendar(osv.osv):
dt_t.replace(tzinfo=tz_info).astimezone(pytz.UTC).replace(tzinfo=None),
calendar_working_day.id
)
- working_intervals += self.interval_remove_leaves(cr, uid, working_interval, work_limits, context=context)
+ working_intervals += self.interval_remove_leaves(working_interval, work_limits)
# find leave intervals
if leaves is None and compute_leaves:
- leaves = self.get_leave_intervals(cr, uid, id, resource_id=resource_id, context=context)
+ leaves = self.get_leave_intervals(resource_id=resource_id)
# filter according to leaves
for interval in working_intervals:
- work_intervals = self.interval_remove_leaves(cr, uid, interval, leaves, context=context)
+ work_intervals = self.interval_remove_leaves(interval, leaves)
intervals += work_intervals
return intervals
- def get_working_hours_of_date(self, cr, uid, id, start_dt=None, end_dt=None,
+ @api.multi
+ def get_working_hours_of_date(self, start_dt=None, end_dt=None,
leaves=None, compute_leaves=False, resource_id=None,
- default_interval=None, context=None):
+ default_interval=None):
""" Get the working hours of the day based on calendar. This method uses
get_working_intervals_of_day to have the work intervals of the day. It
then calculates the number of hours contained in those intervals. """
- res = datetime.timedelta()
+ res = timedelta()
intervals = self.get_working_intervals_of_day(
- cr, uid, id,
start_dt, end_dt, leaves,
compute_leaves, resource_id,
- default_interval, context)
+ default_interval)
for interval in intervals:
res += interval[1] - interval[0]
return seconds(res) / 3600.0
- def get_working_hours(self, cr, uid, id, start_dt, end_dt, compute_leaves=False,
- resource_id=None, default_interval=None, context=None):
+ @api.multi
+ def get_working_hours(self, start_dt, end_dt, compute_leaves=False,
+ resource_id=None, default_interval=None):
hours = 0.0
for day in rrule.rrule(rrule.DAILY, dtstart=start_dt,
- until=(end_dt + datetime.timedelta(days=1)).replace(hour=0, minute=0, second=0),
- byweekday=self.get_weekdays(cr, uid, id, context=context)):
+ until=(end_dt + timedelta(days=1)).replace(hour=0, minute=0, second=0),
+ byweekday=self.get_weekdays()):
day_start_dt = day.replace(hour=0, minute=0, second=0)
if start_dt and day.date() == start_dt.date():
day_start_dt = start_dt
@@ -383,20 +375,19 @@ class resource_calendar(osv.osv):
if end_dt and day.date() == end_dt.date():
day_end_dt = end_dt
hours += self.get_working_hours_of_date(
- cr, uid, id, start_dt=day_start_dt, end_dt=day_end_dt,
+ start_dt=day_start_dt, end_dt=day_end_dt,
compute_leaves=compute_leaves, resource_id=resource_id,
- default_interval=default_interval,
- context=context)
+ default_interval=default_interval)
return hours
# --------------------------------------------------
# Hours scheduling
# --------------------------------------------------
-
- def _schedule_hours(self, cr, uid, id, hours, day_dt=None,
+ @api.multi
+ def _schedule_hours(self, hours, day_dt=None,
compute_leaves=False, resource_id=None,
- default_interval=None, context=None):
+ default_interval=None):
""" Schedule hours 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.
@@ -436,7 +427,7 @@ class resource_calendar(osv.osv):
iterations = 0
current_datetime = day_dt
- call_args = dict(compute_leaves=compute_leaves, resource_id=resource_id, default_interval=default_interval, context=context)
+ call_args = dict(compute_leaves=compute_leaves, resource_id=resource_id, default_interval=default_interval)
while float_compare(remaining_hours, 0.0, precision_digits=2) in (1, 0) and iterations < 1000:
if backwards:
@@ -444,9 +435,9 @@ class resource_calendar(osv.osv):
else:
call_args['start_dt'] = current_datetime
- working_intervals = self.get_working_intervals_of_day(cr, uid, id, **call_args)
+ working_intervals = self.get_working_intervals_of_day(**call_args)
- if id is None and not working_intervals: # no calendar -> consider working 8 hours
+ if not self and not working_intervals: # no calendar -> consider working 8 hours
remaining_hours -= 8.0
elif working_intervals:
if backwards:
@@ -455,7 +446,7 @@ class resource_calendar(osv.osv):
if backwards:
new_working_intervals.reverse()
- res = datetime.timedelta()
+ res = timedelta()
for interval in working_intervals:
res += interval[1] - interval[0]
remaining_hours -= (seconds(res) / 3600.0)
@@ -465,36 +456,38 @@ class resource_calendar(osv.osv):
intervals = intervals + new_working_intervals
# get next day
if backwards:
- current_datetime = datetime.datetime.combine(self.get_previous_day(cr, uid, id, current_datetime, context), datetime.time(23, 59, 59))
+ current_datetime = datetime.datetime.combine(self.get_previous_day(current_datetime), datetime.time(23, 59, 59))
else:
- current_datetime = datetime.datetime.combine(self.get_next_day(cr, uid, id, current_datetime, context), datetime.time())
+ current_datetime = datetime.datetime.combine(self.get_next_day(current_datetime), datetime.time())
# avoid infinite loops
iterations += 1
return intervals
- def schedule_hours_get_date(self, cr, uid, id, hours, day_dt=None,
+ @api.multi
+ def schedule_hours_get_date(self, hours, day_dt=None,
compute_leaves=False, resource_id=None,
- default_interval=None, context=None):
+ default_interval=None):
""" Wrapper on _schedule_hours: return the beginning/ending datetime of
an hours scheduling. """
- res = self._schedule_hours(cr, uid, id, hours, day_dt, compute_leaves, resource_id, default_interval, context)
+ res = self._schedule_hours(hours, day_dt, compute_leaves, resource_id, default_interval)
return res and res[0][0] or False
- def schedule_hours(self, cr, uid, id, hours, day_dt=None,
+ @api.multi
+ def schedule_hours(self, hours, day_dt=None,
compute_leaves=False, resource_id=None,
- default_interval=None, context=None):
+ default_interval=None):
""" Wrapper on _schedule_hours: return the working intervals of an hours
scheduling. """
- return self._schedule_hours(cr, uid, id, hours, day_dt, compute_leaves, resource_id, default_interval, context)
-
+ return self._schedule_hours(hours, day_dt, compute_leaves, resource_id, default_interval)
# --------------------------------------------------
# Days scheduling
# --------------------------------------------------
- def _schedule_days(self, cr, uid, id, days, day_date=None, compute_leaves=False,
- resource_id=None, default_interval=None, context=None):
+ @api.multi
+ def _schedule_days(self, days, day_date=None, compute_leaves=False,
+ resource_id=None, default_interval=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.
@@ -536,157 +529,165 @@ class resource_calendar(osv.osv):
while planned_days < days and iterations < 100:
working_intervals = self.get_working_intervals_of_day(
- cr, uid, id, current_datetime,
+ current_datetime,
compute_leaves=compute_leaves, resource_id=resource_id,
- default_interval=default_interval,
- context=context)
- if id is None or working_intervals: # no calendar -> no working hours, but day is considered as worked
+ default_interval=default_interval)
+ if not self or working_intervals: # no calendar -> no working hours, but day is considered as worked
planned_days += 1
intervals += working_intervals
# get next day
if backwards:
- current_datetime = self.get_previous_day(cr, uid, id, current_datetime, context)
+ current_datetime = self.get_previous_day(current_datetime)
else:
- current_datetime = self.get_next_day(cr, uid, id, current_datetime, context)
+ current_datetime = self.get_next_day(current_datetime)
# avoid infinite loops
iterations += 1
return intervals
- def schedule_days_get_date(self, cr, uid, id, days, day_date=None, compute_leaves=False,
- resource_id=None, default_interval=None, context=None):
+ @api.multi
+ def schedule_days_get_date(self, days, day_date=None, compute_leaves=False,
+ resource_id=None, default_interval=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, default_interval, context)
+ res = self._schedule_days(days, day_date, compute_leaves, resource_id, default_interval)
return res and res[-1][1] or False
- def schedule_days(self, cr, uid, id, days, day_date=None, compute_leaves=False,
- resource_id=None, default_interval=None, context=None):
+ @api.multi
+ def schedule_days(self, days, day_date=None, compute_leaves=False,
+ resource_id=None, default_interval=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, default_interval, context)
+ return self._schedule_days(days, day_date, compute_leaves, resource_id, default_interval)
# --------------------------------------------------
# Compatibility / to clean / to remove
# --------------------------------------------------
- def working_hours_on_day(self, cr, uid, resource_calendar_id, day, context=None):
+ @api.multi
+ def working_hours_on_day(self, day):
""" Used in hr_payroll/hr_payroll.py
- :deprecated: OpenERP saas-3. Use get_working_hours_of_date instead. Note:
+ :deprecated: Odoo 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)
+ return self.get_working_hours_of_date(start_dt=day)
- def interval_min_get(self, cr, uid, id, dt_from, hours, resource=False):
+ @api.multi
+ def interval_min_get(self, dt_from, hours, resource=False):
""" Schedule hours backwards. Used in mrp_operations/mrp_operations.py.
- :deprecated: OpenERP saas-3. Use schedule_hours instead. Note: since
+ :deprecated: Odoo 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,
+ hours * -1.0,
day_dt=dt_from.replace(minute=0, second=0),
compute_leaves=True, resource_id=resource,
default_interval=(8, 16)
)
- def interval_get_multi(self, cr, uid, date_and_hours_by_cal, resource=False, byday=True):
+ @api.model
+ def interval_get_multi(self, date_and_hours_by_cal, resource=False, byday=True):
""" Used in mrp_operations/mrp_operations.py (default parameters) and in
interval_get()
- :deprecated: OpenERP saas-3. Use schedule_hours instead. Note:
+ :deprecated: Odoo saas-3. Use schedule_hours 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(
- cr, uid, calendar_id, hours,
- day_dt=datetime.datetime.strptime(dt_str, '%Y-%m-%d %H:%M:%S').replace(second=0),
+ result = self.browse(calendar_id).schedule_hours(
+ hours,
+ day_dt=fields.Datetime.from_string(dt_str).replace(second=0),
compute_leaves=True, resource_id=resource,
default_interval=(8, 16)
)
res[(dt_str, hours, calendar_id)] = result
return res
- def interval_get(self, cr, uid, id, dt_from, hours, resource=False, byday=True):
+ @api.multi
+ def interval_get(self, dt_from, hours, resource=False, byday=True):
""" 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."""
+ :deprecated: Odoo saas-3. Use get_working_hours instead."""
+ self.ensure_one()
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)]
+ [(fields.Datetime.to_string(dt_from), hours, self.id)], resource, byday)[(fields.Datetime.to_string(dt_from), hours, self.id)]
return res
- def interval_hours_get(self, cr, uid, id, dt_from, dt_to, resource=False):
+ @api.multi
+ def interval_hours_get(self, dt_from, dt_to, resource=False):
""" 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)
+ :deprecated: Odoo saas-3. Use get_working_hours instead."""
+ return self._interval_hours_get(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):
- """ Computes working hours between two dates, taking always same hour/minutes.
-
- :deprecated: OpenERP saas-3. Use get_working_hours instead. Note: since saas-3,
+ @api.multi
+ def _interval_hours_get(self, dt_from, dt_to, resource_id=False, timezone_from_uid=None, exclude_leaves=True):
+ """ Computes working hours between two dates, taking always same hour/minuts.
+ :deprecated: Odoo 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,
+ dt_from, dt_to,
compute_leaves=(not exclude_leaves), resource_id=resource_id,
- default_interval=(8, 16), context=context)
+ default_interval=(8, 16))
-class resource_calendar_attendance(osv.osv):
+class ResourceCalendarAttendance(models.Model):
_name = "resource.calendar.attendance"
_description = "Work Detail"
-
- _columns = {
- 'name' : fields.char("Name", required=True),
- 'dayofweek': fields.selection([('0','Monday'),('1','Tuesday'),('2','Wednesday'),('3','Thursday'),('4','Friday'),('5','Saturday'),('6','Sunday')], 'Day of Week', required=True, select=True),
- 'date_from' : fields.date('Starting Date'),
- 'date_to': fields.date('End Date'),
- 'hour_from' : fields.float('Work from', required=True, help="Start and End time of working.", select=True),
- 'hour_to' : fields.float("Work to", required=True),
- 'calendar_id' : fields.many2one("resource.calendar", "Resource's Calendar", required=True),
- }
-
_order = 'dayofweek, hour_from'
- _defaults = {
- 'dayofweek' : '0'
- }
+ name = fields.Char(required=True)
+ dayofweek = fields.Selection([
+ ('0', 'Monday'),
+ ('1', 'Tuesday'),
+ ('2', 'Wednesday'),
+ ('3', 'Thursday'),
+ ('4', 'Friday'),
+ ('5', 'Saturday'),
+ ('6', 'Sunday')
+ ], 'Day of Week', required=True, index=True, default='0')
+ date_from = fields.Date(string='Starting Date')
+ date_to = fields.Date(string='End Date')
+ hour_from = fields.Float(string='Work from', required=True, index=True, help="Start and End time of working.")
+ hour_to = fields.Float(string='Work to', required=True)
+ calendar_id = fields.Many2one("resource.calendar", string="Resource's Calendar", required=True)
+
def hours_time_string(hours):
""" convert a number of hours (float) into a string with format '%H:%M' """
minutes = int(round(hours * 60))
return "%02d:%02d" % divmod(minutes, 60)
-class resource_resource(osv.osv):
+
+class ResourceResource(models.Model):
_name = "resource.resource"
_description = "Resource Detail"
- _columns = {
- 'name': fields.char("Name", required=True),
- 'code': fields.char('Code', size=16, copy=False),
- 'active' : fields.boolean('Active', track_visibility='onchange',
- help="If the active field is set to False, it will allow you to hide the resource record without removing it."),
- 'company_id' : fields.many2one('res.company', 'Company'),
- 'resource_type': fields.selection([('user','Human'),('material','Material')], 'Resource Type', required=True),
- 'user_id' : fields.many2one('res.users', 'User', help='Related user name for the resource to manage its access.'),
- 'time_efficiency' : fields.float('Efficiency Factor', size=8, required=True, help="An efficiency of 50% means the resource is two times smaller than his usual speed."),
- 'calendar_id' : fields.many2one("resource.calendar", "Working Time", help="Define the schedule of resource"),
- }
- _defaults = {
- 'resource_type' : 'user',
- 'time_efficiency' : 100,
- 'active' : True,
- 'company_id': lambda self, cr, uid, context: self.pool.get('res.company')._company_default_get(cr, uid, 'resource.resource', context=context)
- }
+ name = fields.Char(required=True)
+ code = fields.Char(copy=False)
+ active = fields.Boolean(track_visibility='onchange', default=True,
+ help="If the active field is set to False, it will allow you to hide the resource record without removing it.")
+ company_id = fields.Many2one('res.company', string='Company', default=lambda self: self.env['res.company']._company_default_get())
+ resource_type = fields.Selection([
+ ('user', 'Human'),
+ ('material', 'Material')
+ ], string='Resource Type', required=True, default='user')
+ user_id = fields.Many2one('res.users', string='User', help='Related user name for the resource to manage its access.')
+ time_efficiency = fields.Float(string='Efficiency Factor', required=True, default=100,
+ help="This field depict the efficiency of the resource to complete tasks. e.g resource put alone on a phase of 5 days with 5 tasks assigned to him, will show a load of 100% for this phase by default, but if we put a efficiency of 200%, then his load will only be 50%.")
+ calendar_id = fields.Many2one("resource.calendar", string='Working Time', help="Define the schedule of resource")
- def copy(self, cr, uid, id, default=None, context=None):
+ @api.multi
+ def copy(self, default=None):
+ self.ensure_one()
if default is None:
default = {}
- if not default.get('name', False):
- default.update(name=_('%s (copy)') % (self.browse(cr, uid, id, context=context).name))
- return super(resource_resource, self).copy(cr, uid, id, default, context)
+ if not default.get('name'):
+ default.update(name=_('%s (copy)') % (self.name))
+ return super(ResourceResource, self).copy(default)
def _is_work_day(self, date):
""" Whether the provided date is a work day for the subject resource.
@@ -719,37 +720,28 @@ class resource_resource(osv.osv):
if intervals and intervals[0]:
yield dt.date()
-class resource_calendar_leaves(osv.osv):
+class ResourceCalendarLeaves(models.Model):
_name = "resource.calendar.leaves"
_description = "Leave Detail"
- _columns = {
- 'name' : fields.char("Name"),
- 'company_id' : fields.related('calendar_id','company_id',type='many2one',relation='res.company',string="Company", store=True, readonly=True),
- 'calendar_id' : fields.many2one("resource.calendar", "Working Time"),
- 'date_from' : fields.datetime('Start Date', required=True),
- 'date_to' : fields.datetime('End Date', required=True),
- 'resource_id' : fields.many2one("resource.resource", "Resource", help="If empty, this is a generic holiday for the company. If a resource is set, the holiday/leave is only for this resource"),
- }
- def check_dates(self, cr, uid, ids, context=None):
- for leave in self.browse(cr, uid, ids, context=context):
- if leave.date_from and leave.date_to and leave.date_from > leave.date_to:
- return False
- return True
+ name = fields.Char()
+ company_id = fields.Many2one('res.company', related='calendar_id.company_id', string="Company", store=True, readonly=True)
+ calendar_id = fields.Many2one('resource.calendar', string='Working Time')
+ date_from = fields.Datetime(string='Start Date', required=True)
+ date_to = fields.Datetime(string='End Date', required=True)
+ resource_id = fields.Many2one("resource.resource", string='Resource',
+ help="If empty, this is a generic holiday for the company. If a resource is set, the holiday/leave is only for this resource")
- _constraints = [
- (check_dates, 'Error! leave start-date must be lower then leave end-date.', ['date_from', 'date_to'])
- ]
+ @api.constrains('date_from', 'date_to')
+ def check_dates(self):
+ if self.filtered(lambda leave: leave.date_from > leave.date_to):
+ raise ValidationError(_('Error! leave start-date must be lower then leave end-date.'))
- def onchange_resource(self, cr, uid, ids, resource, context=None):
- result = {}
- if resource:
- resource_pool = self.pool.get('resource.resource')
- result['calendar_id'] = resource_pool.browse(cr, uid, resource, context=context).calendar_id.id
- return {'value': result}
- return {'value': {'calendar_id': []}}
+ @api.onchange('resource_id')
+ def onchange_resource(self):
+ self.calendar_id = self.resource_id.calendar_id
def seconds(td):
- assert isinstance(td, datetime.timedelta)
+ assert isinstance(td, timedelta)
return (td.microseconds + (td.seconds + td.days * 24 * 3600) * 10**6) / 10.**6
diff --git a/addons/resource/security/resource_security.xml b/addons/resource/security/resource_security.xml
index 43bfa6c3a4b..d33fdebc296 100644
--- a/addons/resource/security/resource_security.xml
+++ b/addons/resource/security/resource_security.xml
@@ -1,5 +1,5 @@
-
+
@@ -13,4 +13,4 @@
-
+
diff --git a/addons/resource/test/duplicate_resource.yml b/addons/resource/test/duplicate_resource.yml
deleted file mode 100644
index 5869530e2f4..00000000000
--- a/addons/resource/test/duplicate_resource.yml
+++ /dev/null
@@ -1,6 +0,0 @@
--
- I duplicate the resource "Analyst"
--
- !python {model: resource.resource}: |
- copied_id = self.copy(cr, uid, ref("resource_analyst"))
- assert copied_id, "Unable to Duplicate Resource"
diff --git a/addons/resource/test/resource.yml b/addons/resource/test/resource.yml
deleted file mode 100644
index 40fa0cab7c4..00000000000
--- a/addons/resource/test/resource.yml
+++ /dev/null
@@ -1,53 +0,0 @@
--
- In order to test resource.
--
- I assign working calendar '45 Hours/Week' to human resource.
--
- !python {model: resource.resource}: |
- self.write(cr, uid, [ref('resource_analyst'), ref('resource_designer'), ref('resource_developer')], {'calendar_id' : ref('timesheet_group1'), 'resource_type': 'user'})
-
--
- I had Project of OpenERP Integration of 50 Hours with three human resource assigned on it. I have started project from this week start.
--
- I check per day work hour availability of the Resource based on Working Calendar Assigned to each resource, for first day of the week.
--
- !python {model: resource.resource}: |
- from openerp.tools import float_compare
- calendar_pool = self.pool.get('resource.calendar')
- resources = self.browse(cr, uid, [ref('resource_analyst'), ref('resource_designer'), ref('resource_developer')], context)
- from datetime import datetime, timedelta
- now = datetime.now()
- dt = now - timedelta(days=now.weekday())
- for resource in resources:
- result = calendar_pool.working_hours_on_day(cr, uid, resource.calendar_id, dt, context)
- assert float_compare(result, 8.0, precision_digits=2) == 0, 'Wrong calculation of day work hour availability of the Resource (found %d).' % result
--
- Now, resource "Developer" drafted leave on Thursday in this week.
--
- !python {model: resource.calendar.leaves}: |
- from datetime import datetime,timedelta
- now = datetime.now()
- dt = (now - timedelta(days=now.weekday()) ) + timedelta(days=3)
- self.write(cr, uid, [ref('resource_dummyleave')], {'resource_id': ref('resource_developer'), 'calendar_id': ref('timesheet_group1'), 'date_from': dt.strftime("%Y-%m-%d 09:00:00"), 'date_to': dt.strftime("%Y-%m-%d 18:00:00")})
-
--
- I check Actual working hours on resource 'Developer' from this week
--
- !python {model: resource.calendar}: |
- from datetime import datetime
- from dateutil.relativedelta import relativedelta
- now = datetime.now()
- dt_from = now - relativedelta(days=now.weekday(), hour=8, minute=30)
- dt_to = dt_from + relativedelta(days=6, hour=17)
- hours = self.interval_hours_get(cr, uid, ref('timesheet_group1'), dt_from, dt_to, resource=ref('resource_developer'))
- assert hours > 27 , 'Invalid Total Week working hour calculated, got %r, expected > 27' % hours
--
- Project Analysis work is of 20 hours which will start from Week start so i will calculate working schedule for resource Analyst for the same.
--
- !python {model: resource.calendar}: |
-
- from datetime import datetime, timedelta
- now = datetime.now()
- work_intreval = self.interval_min_get(cr, uid, ref('timesheet_group1'), now, 20.0, resource=ref('resource_designer'))
- assert len(work_intreval) >= 5, 'Wrong Schedule Calculated'
-
diff --git a/addons/resource/tests/common.py b/addons/resource/tests/common.py
index adb813be3d3..686070dd27f 100644
--- a/addons/resource/tests/common.py
+++ b/addons/resource/tests/common.py
@@ -1,106 +1,102 @@
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
-from datetime import datetime
-
-from openerp.tests import common
+from odoo.fields import Datetime
+from odoo.tests.common import TransactionCase
-class TestResourceCommon(common.TransactionCase):
+class TestResourceCommon(TransactionCase):
def setUp(self):
super(TestResourceCommon, self).setUp()
- cr, uid = self.cr, self.uid
self.context = context = dict(tz='UTC')
- self.registry('res.users').write(cr, uid, uid, {'tz': 'UTC'}, context=context)
+ self.env['res.users'].browse(self.env.uid).with_context(context).write({'tz': 'UTC'})
# Usefull models
- self.resource_resource = self.registry('resource.resource')
- self.resource_calendar = self.registry('resource.calendar')
- self.resource_attendance = self.registry('resource.calendar.attendance')
- self.resource_leaves = self.registry('resource.calendar.leaves')
+ self.Resource = self.env['resource.resource']
+ self.ResourceCalendar = self.env['resource.calendar']
+ self.ResourceAttendance = self.env['resource.calendar.attendance']
+ self.ResourceLeaves = self.env['resource.calendar.leaves']
# Some demo data
- self.date1 = datetime.strptime('2013-02-12 09:08:07', '%Y-%m-%d %H:%M:%S') # weekday() returns 1, isoweekday() returns 2
- self.date2 = datetime.strptime('2013-02-15 10:11:12', '%Y-%m-%d %H:%M:%S') # weekday() returns 4, isoweekday() returns 5
+ self.date1 = Datetime.from_string('2013-02-12 09:08:07') # weekday() returns 1, isoweekday() returns 2
+ self.date2 = Datetime.from_string('2013-02-15 10:11:12') # weekday() returns 4, isoweekday() returns 5
# Leave1: 19/02/2013, from 9 to 12, is a day 1
- self.leave1_start = datetime.strptime('2013-02-19 09:00:00', '%Y-%m-%d %H:%M:%S')
- self.leave1_end = datetime.strptime('2013-02-19 12:00:00', '%Y-%m-%d %H:%M:%S')
+ self.leave1_start = Datetime.from_string('2013-02-19 09:00:00')
+ self.leave1_end = Datetime.from_string('2013-02-19 12:00:00')
# Leave2: 22/02/2013, from 9 to 15, is a day 4
- self.leave2_start = datetime.strptime('2013-02-22 09:00:00', '%Y-%m-%d %H:%M:%S')
- self.leave2_end = datetime.strptime('2013-02-22 15:00:00', '%Y-%m-%d %H:%M:%S')
+ self.leave2_start = Datetime.from_string('2013-02-22 09:00:00')
+ self.leave2_end = Datetime.from_string('2013-02-22 15:00:00')
# Leave3: 25/02/2013 (day0) -> 01/03/2013 (day4)
- self.leave3_start = datetime.strptime('2013-02-25 13:00:00', '%Y-%m-%d %H:%M:%S')
- self.leave3_end = datetime.strptime('2013-03-01 11:30:00', '%Y-%m-%d %H:%M:%S')
+ self.leave3_start = Datetime.from_string('2013-02-25 13:00:00')
+ self.leave3_end = Datetime.from_string('2013-03-01 11:30:00')
# Resource data
# Calendar working days: 1 (8-16 -> 8hours), 4 (8-13, 16-23 -> 12hours)
- self.calendar_id = self.resource_calendar.create(
- cr, uid, {
+ self.calendar = self.ResourceCalendar.with_context(context).create(
+ {
'name': 'TestCalendar',
- }, context=context
+ }
)
- self.att1_id = self.resource_attendance.create(
- cr, uid, {
+ self.att1_id = self.ResourceAttendance.with_context(context).create(
+ {
'name': 'Att1',
'dayofweek': '1',
'hour_from': 8,
'hour_to': 16,
- 'calendar_id': self.calendar_id,
- }, context=context
- )
- self.att2_id = self.resource_attendance.create(
- cr, uid, {
+ 'calendar_id': self.calendar.id,
+ }
+ ).id
+ self.att2_id = self.ResourceAttendance.with_context(context).create(
+ {
'name': 'Att2',
'dayofweek': '4',
'hour_from': 8,
'hour_to': 13,
- 'calendar_id': self.calendar_id,
- }, context=context
- )
- self.att3_id = self.resource_attendance.create(
- cr, uid, {
+ 'calendar_id': self.calendar.id,
+ }
+ ).id
+ self.att3_id = self.ResourceAttendance.with_context(context).create(
+ {
'name': 'Att3',
'dayofweek': '4',
'hour_from': 16,
'hour_to': 23,
- 'calendar_id': self.calendar_id,
- }, context=context
- )
- self.resource1_id = self.resource_resource.create(
- cr, uid, {
+ 'calendar_id': self.calendar.id,
+ }
+ ).id
+ self.resource1_id = self.Resource.with_context(context).create(
+ {
'name': 'TestResource1',
'resource_type': 'user',
'time_efficiency': 150.0,
- 'calendar_id': self.calendar_id,
- }, context=context
- )
- self.leave1_id = self.resource_leaves.create(
- cr, uid, {
+ 'calendar_id': self.calendar.id,
+ }
+ ).id
+ self.leave1_id = self.ResourceLeaves.with_context(context).create(
+ {
'name': 'GenericLeave',
- 'calendar_id': self.calendar_id,
+ 'calendar_id': self.calendar.id,
'date_from': self.leave1_start,
'date_to': self.leave1_end,
- }, context=context
- )
- self.leave2_id = self.resource_leaves.create(
- cr, uid, {
+ }
+ ).id
+ self.leave2_id = self.ResourceLeaves.with_context(context).create(
+ {
'name': 'ResourceLeave',
- 'calendar_id': self.calendar_id,
+ 'calendar_id': self.calendar.id,
'resource_id': self.resource1_id,
'date_from': self.leave2_start,
'date_to': self.leave2_end,
- }, context=context
- )
- self.leave3_id = self.resource_leaves.create(
- cr, uid, {
+ }
+ ).id
+ self.leave3_id = self.ResourceLeaves.with_context(context).create(
+ {
'name': 'ResourceLeave2',
- 'calendar_id': self.calendar_id,
+ 'calendar_id': self.calendar.id,
'resource_id': self.resource1_id,
'date_from': self.leave3_start,
'date_to': self.leave3_end,
- }, context=context
- )
- # Some browse data
- self.calendar = self.resource_calendar.browse(cr, uid, self.calendar_id, context=context)
+ }
+ ).id
diff --git a/addons/resource/tests/test_resource.py b/addons/resource/tests/test_resource.py
index 208166a2108..3f2caa1d71e 100644
--- a/addons/resource/tests/test_resource.py
+++ b/addons/resource/tests/test_resource.py
@@ -6,7 +6,9 @@ from datetime import datetime, timedelta, date
import babel.dates
from dateutil.relativedelta import relativedelta
-from openerp.addons.resource.tests.common import TestResourceCommon
+from odoo.fields import Datetime
+from odoo.tools import float_compare
+from odoo.addons.resource.tests.common import TestResourceCommon
from openerp.tests import TransactionCase
@@ -14,93 +16,91 @@ from openerp.tests import TransactionCase
class TestResource(TestResourceCommon):
def test_00_intervals(self):
- cr, uid = self.cr, self.uid
intervals = [
(
- datetime.strptime('2013-02-04 09:00:00', '%Y-%m-%d %H:%M:%S'),
- datetime.strptime('2013-02-04 11:00:00', '%Y-%m-%d %H:%M:%S')
+ Datetime.from_string('2013-02-04 09:00:00'),
+ Datetime.from_string('2013-02-04 11:00:00')
), (
- datetime.strptime('2013-02-04 08:00:00', '%Y-%m-%d %H:%M:%S'),
- datetime.strptime('2013-02-04 12:00:00', '%Y-%m-%d %H:%M:%S')
+ Datetime.from_string('2013-02-04 08:00:00'),
+ Datetime.from_string('2013-02-04 12:00:00')
), (
- datetime.strptime('2013-02-04 11:00:00', '%Y-%m-%d %H:%M:%S'),
- datetime.strptime('2013-02-04 14:00:00', '%Y-%m-%d %H:%M:%S')
+ Datetime.from_string('2013-02-04 11:00:00'),
+ Datetime.from_string('2013-02-04 14:00:00')
), (
- datetime.strptime('2013-02-04 17:00:00', '%Y-%m-%d %H:%M:%S'),
- datetime.strptime('2013-02-04 21:00:00', '%Y-%m-%d %H:%M:%S')
+ Datetime.from_string('2013-02-04 17:00:00'),
+ Datetime.from_string('2013-02-04 21:00:00')
), (
- datetime.strptime('2013-02-03 08:00:00', '%Y-%m-%d %H:%M:%S'),
- datetime.strptime('2013-02-03 10:00:00', '%Y-%m-%d %H:%M:%S')
+ Datetime.from_string('2013-02-03 08:00:00'),
+ Datetime.from_string('2013-02-03 10:00:00')
), (
- datetime.strptime('2013-02-04 18:00:00', '%Y-%m-%d %H:%M:%S'),
- datetime.strptime('2013-02-04 19:00:00', '%Y-%m-%d %H:%M:%S')
+ Datetime.from_string('2013-02-04 18:00:00'),
+ Datetime.from_string('2013-02-04 19:00:00')
)
]
# Test: interval cleaning
- cleaned_intervals = self.resource_calendar.interval_clean(intervals)
+ cleaned_intervals = self.ResourceCalendar.interval_clean(intervals)
self.assertEqual(len(cleaned_intervals), 3, 'resource_calendar: wrong interval cleaning')
# First interval: 03, unchanged
- self.assertEqual(cleaned_intervals[0][0], datetime.strptime('2013-02-03 08:00:00', '%Y-%m-%d %H:%M:%S'), 'resource_calendar: wrong interval cleaning')
- self.assertEqual(cleaned_intervals[0][1], datetime.strptime('2013-02-03 10:00:00', '%Y-%m-%d %H:%M:%S'), 'resource_calendar: wrong interval cleaning')
+ self.assertEqual(cleaned_intervals[0][0], Datetime.from_string('2013-02-03 08:00:00'), 'resource_calendar: wrong interval cleaning')
+ self.assertEqual(cleaned_intervals[0][1], Datetime.from_string('2013-02-03 10:00:00'), 'resource_calendar: wrong interval cleaning')
# Second intreval: 04, 08-14, combining 08-12 and 11-14, 09-11 being inside 08-12
- self.assertEqual(cleaned_intervals[1][0], datetime.strptime('2013-02-04 08:00:00', '%Y-%m-%d %H:%M:%S'), 'resource_calendar: wrong interval cleaning')
- self.assertEqual(cleaned_intervals[1][1], datetime.strptime('2013-02-04 14:00:00', '%Y-%m-%d %H:%M:%S'), 'resource_calendar: wrong interval cleaning')
+ self.assertEqual(cleaned_intervals[1][0], Datetime.from_string('2013-02-04 08:00:00'), 'resource_calendar: wrong interval cleaning')
+ self.assertEqual(cleaned_intervals[1][1], Datetime.from_string('2013-02-04 14:00:00'), 'resource_calendar: wrong interval cleaning')
# Third interval: 04, 17-21, 18-19 being inside 17-21
- self.assertEqual(cleaned_intervals[2][0], datetime.strptime('2013-02-04 17:00:00', '%Y-%m-%d %H:%M:%S'), 'resource_calendar: wrong interval cleaning')
- self.assertEqual(cleaned_intervals[2][1], datetime.strptime('2013-02-04 21:00:00', '%Y-%m-%d %H:%M:%S'), 'resource_calendar: wrong interval cleaning')
+ self.assertEqual(cleaned_intervals[2][0], Datetime.from_string('2013-02-04 17:00:00'), 'resource_calendar: wrong interval cleaning')
+ self.assertEqual(cleaned_intervals[2][1], Datetime.from_string('2013-02-04 21:00:00'), 'resource_calendar: wrong interval cleaning')
# Test: disjoint removal
- working_interval = (datetime.strptime('2013-02-04 08:00:00', '%Y-%m-%d %H:%M:%S'), datetime.strptime('2013-02-04 18:00:00', '%Y-%m-%d %H:%M:%S'))
- result = self.resource_calendar.interval_remove_leaves(cr, uid, working_interval, intervals)
+ working_interval = (Datetime.from_string('2013-02-04 08:00:00'), Datetime.from_string('2013-02-04 18:00:00'))
+ result = self.ResourceCalendar.interval_remove_leaves(working_interval, intervals)
self.assertEqual(len(result), 1, 'resource_calendar: wrong leave removal from interval')
# First interval: 04, 14-17
- self.assertEqual(result[0][0], datetime.strptime('2013-02-04 14:00:00', '%Y-%m-%d %H:%M:%S'), 'resource_calendar: wrong leave removal from interval')
- self.assertEqual(result[0][1], datetime.strptime('2013-02-04 17:00:00', '%Y-%m-%d %H:%M:%S'), 'resource_calendar: wrong leave removal from interval')
+ self.assertEqual(result[0][0], Datetime.from_string('2013-02-04 14:00:00'), 'resource_calendar: wrong leave removal from interval')
+ self.assertEqual(result[0][1], Datetime.from_string('2013-02-04 17:00:00'), 'resource_calendar: wrong leave removal from interval')
# Test: schedule hours on intervals
- result = self.resource_calendar.interval_schedule_hours(cleaned_intervals, 5.5)
+ result = self.ResourceCalendar.interval_schedule_hours(cleaned_intervals, 5.5)
self.assertEqual(len(result), 2, 'resource_calendar: wrong hours scheduling in interval')
# First interval: 03, 8-10 untouches
- self.assertEqual(result[0][0], datetime.strptime('2013-02-03 08:00:00', '%Y-%m-%d %H:%M:%S'), 'resource_calendar: wrong leave removal from interval')
- self.assertEqual(result[0][1], datetime.strptime('2013-02-03 10:00:00', '%Y-%m-%d %H:%M:%S'), 'resource_calendar: wrong leave removal from interval')
+ self.assertEqual(result[0][0], Datetime.from_string('2013-02-03 08:00:00'), 'resource_calendar: wrong leave removal from interval')
+ self.assertEqual(result[0][1], Datetime.from_string('2013-02-03 10:00:00'), 'resource_calendar: wrong leave removal from interval')
# First interval: 04, 08-11:30
- self.assertEqual(result[1][0], datetime.strptime('2013-02-04 08:00:00', '%Y-%m-%d %H:%M:%S'), 'resource_calendar: wrong leave removal from interval')
- self.assertEqual(result[1][1], datetime.strptime('2013-02-04 11:30:00', '%Y-%m-%d %H:%M:%S'), 'resource_calendar: wrong leave removal from interval')
+ self.assertEqual(result[1][0], Datetime.from_string('2013-02-04 08:00:00'), 'resource_calendar: wrong leave removal from interval')
+ self.assertEqual(result[1][1], Datetime.from_string('2013-02-04 11:30:00'), 'resource_calendar: wrong leave removal from interval')
# Test: schedule hours on intervals, backwards
cleaned_intervals.reverse()
- result = self.resource_calendar.interval_schedule_hours(cleaned_intervals, 5.5, remove_at_end=False)
+ result = self.ResourceCalendar._model.interval_schedule_hours(cleaned_intervals, 5.5, remove_at_end=False)
self.assertEqual(len(result), 2, 'resource_calendar: wrong hours scheduling in interval')
# First interval: 03, 8-10 untouches
- self.assertEqual(result[0][0], datetime.strptime('2013-02-04 17:00:00', '%Y-%m-%d %H:%M:%S'), 'resource_calendar: wrong leave removal from interval')
- self.assertEqual(result[0][1], datetime.strptime('2013-02-04 21:00:00', '%Y-%m-%d %H:%M:%S'), 'resource_calendar: wrong leave removal from interval')
+ self.assertEqual(result[0][0], Datetime.from_string('2013-02-04 17:00:00'), 'resource_calendar: wrong leave removal from interval')
+ self.assertEqual(result[0][1], Datetime.from_string('2013-02-04 21:00:00'), 'resource_calendar: wrong leave removal from interval')
# First interval: 04, 08-11:30
- self.assertEqual(result[1][0], datetime.strptime('2013-02-04 12:30:00', '%Y-%m-%d %H:%M:%S'), 'resource_calendar: wrong leave removal from interval')
- self.assertEqual(result[1][1], datetime.strptime('2013-02-04 14:00:00', '%Y-%m-%d %H:%M:%S'), 'resource_calendar: wrong leave removal from interval')
+ self.assertEqual(result[1][0], Datetime.from_string('2013-02-04 12:30:00'), 'resource_calendar: wrong leave removal from interval')
+ self.assertEqual(result[1][1], Datetime.from_string('2013-02-04 14:00:00'), 'resource_calendar: wrong leave removal from interval')
def test_10_calendar_basics(self):
""" Testing basic method of resource.calendar """
- cr, uid = self.cr, self.uid
# --------------------------------------------------
# Test1: get_next_day
# --------------------------------------------------
# Test: next day: next day after day1 is day4
- date = self.resource_calendar.get_next_day(cr, uid, self.calendar_id, day_date=self.date1.date())
+ date = self.calendar.get_next_day(day_date=self.date1.date())
self.assertEqual(date, self.date2.date(), 'resource_calendar: wrong next day computing')
# Test: next day: next day after day4 is (day1+7)
- date = self.resource_calendar.get_next_day(cr, uid, self.calendar_id, day_date=self.date2.date())
+ date = self.calendar.get_next_day(day_date=self.date2.date())
self.assertEqual(date, self.date1.date() + relativedelta(days=7), 'resource_calendar: wrong next day computing')
# Test: next day: next day after day4+1 is (day1+7)
- date = self.resource_calendar.get_next_day(cr, uid, self.calendar_id, day_date=self.date2.date() + relativedelta(days=1))
+ date = self.calendar.get_next_day(day_date=self.date2.date() + relativedelta(days=1))
self.assertEqual(date, self.date1.date() + relativedelta(days=7), 'resource_calendar: wrong next day computing')
# Test: next day: next day after day1-1 is day1
- date = self.resource_calendar.get_next_day(cr, uid, self.calendar_id, day_date=self.date1.date() + relativedelta(days=-1))
+ date = self.calendar.get_next_day(day_date=self.date1.date() + relativedelta(days=-1))
self.assertEqual(date, self.date1.date(), 'resource_calendar: wrong next day computing')
# --------------------------------------------------
@@ -108,174 +108,134 @@ class TestResource(TestResourceCommon):
# --------------------------------------------------
# Test: previous day: previous day before day1 is (day4-7)
- date = self.resource_calendar.get_previous_day(cr, uid, self.calendar_id, day_date=self.date1.date())
+ date = self.calendar.get_previous_day(day_date=self.date1.date())
self.assertEqual(date, self.date2.date() + relativedelta(days=-7), 'resource_calendar: wrong previous day computing')
# Test: previous day: previous day before day4 is day1
- date = self.resource_calendar.get_previous_day(cr, uid, self.calendar_id, day_date=self.date2.date())
+ date = self.calendar.get_previous_day(day_date=self.date2.date())
self.assertEqual(date, self.date1.date(), 'resource_calendar: wrong previous day computing')
# Test: previous day: previous day before day4+1 is day4
- date = self.resource_calendar.get_previous_day(cr, uid, self.calendar_id, day_date=self.date2.date() + relativedelta(days=1))
+ date = self.calendar.get_previous_day(day_date=self.date2.date() + relativedelta(days=1))
self.assertEqual(date, self.date2.date(), 'resource_calendar: wrong previous day computing')
# Test: previous day: previous day before day1-1 is (day4-7)
- date = self.resource_calendar.get_previous_day(cr, uid, self.calendar_id, day_date=self.date1.date() + relativedelta(days=-1))
+ date = self.calendar.get_previous_day(day_date=self.date1.date() + relativedelta(days=-1))
self.assertEqual(date, self.date2.date() + relativedelta(days=-7), 'resource_calendar: wrong previous day computing')
# --------------------------------------------------
# Test3: misc
# --------------------------------------------------
- weekdays = self.resource_calendar.get_weekdays(cr, uid, self.calendar_id)
+ weekdays = self.calendar.get_weekdays()
self.assertEqual(weekdays, [1, 4], 'resource_calendar: wrong weekdays computing')
-# attendances = self.resource_calendar.get_attendances_for_weekdays(cr, uid, self.calendar_id, [2, 3, 4, 5])
-# self.assertEqual(set([att.id for att in attendances]), set([self.att2_id, self.att3_id]),
-# 'resource_calendar: wrong attendances filtering by weekdays computing')
-
def test_20_calendar_working_intervals(self):
""" Testing working intervals computing method of resource.calendar """
- cr, uid = self.cr, self.uid
- context = self.context
- _format = '%Y-%m-%d %H:%M:%S'
# Test: day0 without leaves: 1 interval
- intervals = self.resource_calendar.get_working_intervals_of_day(cr, uid, self.calendar_id, start_dt=self.date1, context=context)
+ intervals = self.calendar.get_working_intervals_of_day(start_dt=self.date1)
self.assertEqual(len(intervals), 1, 'resource_calendar: wrong working intervals')
- self.assertEqual(intervals[0][0], datetime.strptime('2013-02-12 09:08:07', _format), 'resource_calendar: wrong working intervals')
- self.assertEqual(intervals[0][1], datetime.strptime('2013-02-12 16:00:00', _format), 'resource_calendar: wrong working intervals')
+ self.assertEqual(intervals[0][0], Datetime.from_string('2013-02-12 09:08:07'), 'resource_calendar: wrong working intervals')
+ self.assertEqual(intervals[0][1], Datetime.from_string('2013-02-12 16:00:00'), 'resource_calendar: wrong working intervals')
# Test: day3 without leaves: 2 interval
- intervals = self.resource_calendar.get_working_intervals_of_day(cr, uid, self.calendar_id, start_dt=self.date2, context=context)
+ intervals = self.calendar.get_working_intervals_of_day(start_dt=self.date2)
self.assertEqual(len(intervals), 2, 'resource_calendar: wrong working intervals')
- self.assertEqual(intervals[0][0], datetime.strptime('2013-02-15 10:11:12', _format), 'resource_calendar: wrong working intervals')
- self.assertEqual(intervals[0][1], datetime.strptime('2013-02-15 13:00:00', _format), 'resource_calendar: wrong working intervals')
- self.assertEqual(intervals[1][0], datetime.strptime('2013-02-15 16:00:00', _format), 'resource_calendar: wrong working intervals')
- self.assertEqual(intervals[1][1], datetime.strptime('2013-02-15 23:00:00', _format), 'resource_calendar: wrong working intervals')
+ self.assertEqual(intervals[0][0], Datetime.from_string('2013-02-15 10:11:12'), 'resource_calendar: wrong working intervals')
+ self.assertEqual(intervals[0][1], Datetime.from_string('2013-02-15 13:00:00'), 'resource_calendar: wrong working intervals')
+ self.assertEqual(intervals[1][0], Datetime.from_string('2013-02-15 16:00:00'), 'resource_calendar: wrong working intervals')
+ self.assertEqual(intervals[1][1], Datetime.from_string('2013-02-15 23:00:00'), 'resource_calendar: wrong working intervals')
# Test: day0 with leaves outside range: 1 interval
- intervals = self.resource_calendar.get_working_intervals_of_day(cr, uid, self.calendar_id, start_dt=self.date1.replace(hour=0), compute_leaves=True, context=context)
+ intervals = self.calendar.get_working_intervals_of_day(start_dt=self.date1.replace(hour=0), compute_leaves=True)
self.assertEqual(len(intervals), 1, 'resource_calendar: wrong working intervals')
- self.assertEqual(intervals[0][0], datetime.strptime('2013-02-12 08:00:00', _format), 'resource_calendar: wrong working intervals')
- self.assertEqual(intervals[0][1], datetime.strptime('2013-02-12 16:00:00', _format), 'resource_calendar: wrong working intervals')
+ self.assertEqual(intervals[0][0], Datetime.from_string('2013-02-12 08:00:00'), 'resource_calendar: wrong working intervals')
+ self.assertEqual(intervals[0][1], Datetime.from_string('2013-02-12 16:00:00'), 'resource_calendar: wrong working intervals')
# Test: day0 with leaves: 2 intervals because of leave between 9 ans 12, ending at 15:45:30
- intervals = self.resource_calendar.get_working_intervals_of_day(cr, uid, self.calendar_id,
- start_dt=self.date1.replace(hour=8) + relativedelta(days=7),
- end_dt=self.date1.replace(hour=15, minute=45, second=30) + relativedelta(days=7),
- compute_leaves=True, context=context)
+ intervals = self.calendar.get_working_intervals_of_day(start_dt=self.date1.replace(hour=8) + relativedelta(days=7),
+ end_dt=self.date1.replace(hour=15, minute=45, second=30) + relativedelta(days=7),
+ compute_leaves=True)
self.assertEqual(len(intervals), 2, 'resource_calendar: wrong working intervals')
- self.assertEqual(intervals[0][0], datetime.strptime('2013-02-19 08:08:07', _format), 'resource_calendar: wrong working intervals')
- self.assertEqual(intervals[0][1], datetime.strptime('2013-02-19 09:00:00', _format), 'resource_calendar: wrong working intervals')
- self.assertEqual(intervals[1][0], datetime.strptime('2013-02-19 12:00:00', _format), 'resource_calendar: wrong working intervals')
- self.assertEqual(intervals[1][1], datetime.strptime('2013-02-19 15:45:30', _format), 'resource_calendar: wrong working intervals')
+ self.assertEqual(intervals[0][0], Datetime.from_string('2013-02-19 08:08:07'), 'resource_calendar: wrong working intervals')
+ self.assertEqual(intervals[0][1], Datetime.from_string('2013-02-19 09:00:00'), 'resource_calendar: wrong working intervals')
+ self.assertEqual(intervals[1][0], Datetime.from_string('2013-02-19 12:00:00'), 'resource_calendar: wrong working intervals')
+ self.assertEqual(intervals[1][1], Datetime.from_string('2013-02-19 15:45:30'), 'resource_calendar: wrong working intervals')
def test_30_calendar_working_days(self):
""" Testing calendar hours computation on a working day """
- cr, uid = self.cr, self.uid
- context = self.context
- _format = '%Y-%m-%d %H:%M:%S'
# Test: day1, beginning at 10:30 -> work from 10:30 (arrival) until 16:00
- intervals = self.resource_calendar.get_working_intervals_of_day(cr, uid, self.calendar_id, start_dt=self.date1.replace(hour=10, minute=30, second=0), context=context)
+ intervals = self.calendar.get_working_intervals_of_day(start_dt=self.date1.replace(hour=10, minute=30, second=0))
self.assertEqual(len(intervals), 1, 'resource_calendar: wrong working interval / day computing')
- self.assertEqual(intervals[0][0], datetime.strptime('2013-02-12 10:30:00', _format), 'resource_calendar: wrong working interval / day computing')
- self.assertEqual(intervals[0][1], datetime.strptime('2013-02-12 16:00:00', _format), 'resource_calendar: wrong working interval / day computing')
+ self.assertEqual(intervals[0][0], Datetime.from_string('2013-02-12 10:30:00'), 'resource_calendar: wrong working interval / day computing')
+ self.assertEqual(intervals[0][1], Datetime.from_string('2013-02-12 16:00:00'), 'resource_calendar: wrong working interval / day computing')
# Test: hour computation for same interval, should give 5.5
- wh = self.resource_calendar.get_working_hours_of_date(cr, uid, self.calendar_id, start_dt=self.date1.replace(hour=10, minute=30, second=0), context=context)
+ wh = self.calendar.get_working_hours_of_date(start_dt=self.date1.replace(hour=10, minute=30, second=0))
self.assertEqual(wh, 5.5, 'resource_calendar: wrong working interval / day time computing')
# Test: day1+7 on leave, without leave computation
- intervals = self.resource_calendar.get_working_intervals_of_day(
- cr, uid, self.calendar_id,
- start_dt=self.date1.replace(hour=7, minute=0, second=0) + relativedelta(days=7), context=context
+ intervals = self.calendar.get_working_intervals_of_day(
+ start_dt=self.date1.replace(hour=7, minute=0, second=0) + relativedelta(days=7)
)
# Result: day1 (08->16)
self.assertEqual(len(intervals), 1, 'resource_calendar: wrong working interval/day computing')
- self.assertEqual(intervals[0][0], datetime.strptime('2013-02-19 08:00:00', _format), 'resource_calendar: wrong working interval / day computing')
- self.assertEqual(intervals[0][1], datetime.strptime('2013-02-19 16:00:00', _format), 'resource_calendar: wrong working interval / day computing')
+ self.assertEqual(intervals[0][0], Datetime.from_string('2013-02-19 08:00:00'), 'resource_calendar: wrong working interval / day computing')
+ self.assertEqual(intervals[0][1], Datetime.from_string('2013-02-19 16:00:00'), 'resource_calendar: wrong working interval / day computing')
# Test: day1+7 on leave, with generic leave computation
- intervals = self.resource_calendar.get_working_intervals_of_day(
- cr, uid, self.calendar_id,
+ intervals = self.calendar.get_working_intervals_of_day(
start_dt=self.date1.replace(hour=7, minute=0, second=0) + relativedelta(days=7),
- compute_leaves=True, context=context
+ compute_leaves=True
)
# Result: day1 (08->09 + 12->16)
self.assertEqual(len(intervals), 2, 'resource_calendar: wrong working interval/day computing')
- self.assertEqual(intervals[0][0], datetime.strptime('2013-02-19 08:00:00', _format), 'resource_calendar: wrong working interval / day computing')
- self.assertEqual(intervals[0][1], datetime.strptime('2013-02-19 09:00:00', _format), 'resource_calendar: wrong working interval / day computing')
- self.assertEqual(intervals[1][0], datetime.strptime('2013-02-19 12:00:00', _format), 'resource_calendar: wrong working interval / day computing')
- self.assertEqual(intervals[1][1], datetime.strptime('2013-02-19 16:00:00', _format), 'resource_calendar: wrong working interval / day computing')
+ self.assertEqual(intervals[0][0], Datetime.from_string('2013-02-19 08:00:00'), 'resource_calendar: wrong working interval / day computing')
+ self.assertEqual(intervals[0][1], Datetime.from_string('2013-02-19 09:00:00'), 'resource_calendar: wrong working interval / day computing')
+ self.assertEqual(intervals[1][0], Datetime.from_string('2013-02-19 12:00:00'), 'resource_calendar: wrong working interval / day computing')
+ self.assertEqual(intervals[1][1], Datetime.from_string('2013-02-19 16:00:00'), 'resource_calendar: wrong working interval / day computing')
# Test: day1+14 on leave, with generic leave computation
- intervals = self.resource_calendar.get_working_intervals_of_day(
- cr, uid, self.calendar_id,
+ intervals = self.calendar.get_working_intervals_of_day(
start_dt=self.date1.replace(hour=7, minute=0, second=0) + relativedelta(days=14),
- compute_leaves=True, context=context
+ compute_leaves=True
)
# Result: day1 (08->16)
self.assertEqual(len(intervals), 1, 'resource_calendar: wrong working interval/day computing')
- self.assertEqual(intervals[0][0], datetime.strptime('2013-02-26 08:00:00', _format), 'resource_calendar: wrong working interval / day computing')
- self.assertEqual(intervals[0][1], datetime.strptime('2013-02-26 16:00:00', _format), 'resource_calendar: wrong working interval / day computing')
+ self.assertEqual(intervals[0][0], Datetime.from_string('2013-02-26 08:00:00'), 'resource_calendar: wrong working interval / day computing')
+ self.assertEqual(intervals[0][1], Datetime.from_string('2013-02-26 16:00:00'), 'resource_calendar: wrong working interval / day computing')
# Test: day1+14 on leave, with resource leave computation
- intervals = self.resource_calendar.get_working_intervals_of_day(
- cr, uid, self.calendar_id,
+ intervals = self.calendar.get_working_intervals_of_day(
start_dt=self.date1.replace(hour=7, minute=0, second=0) + relativedelta(days=14),
compute_leaves=True,
- resource_id=self.resource1_id, context=context
+ resource_id=self.resource1_id
)
# Result: nothing, because on leave
self.assertEqual(len(intervals), 0, 'resource_calendar: wrong working interval/day computing')
def test_40_calendar_hours_scheduling(self):
""" Testing calendar hours scheduling """
- cr, uid = self.cr, self.uid
- context = self.context
- _format = '%Y-%m-%d %H:%M:%S'
- # --------------------------------------------------
- # Test0: schedule hours backwards (old interval_min_get)
- # Done without calendar
- # --------------------------------------------------
-
- # Done without calendar
- # res = self.resource_calendar.interval_min_get(cr, uid, None, self.date1, 40, resource=False)
- # res: (datetime.datetime(2013, 2, 7, 9, 8, 7), datetime.datetime(2013, 2, 12, 9, 8, 7))
-
- # --------------------------------------------------
- # Test1: schedule hours backwards (old interval_min_get)
- # --------------------------------------------------
-
- # res = self.resource_calendar.interval_min_get(cr, uid, self.calendar_id, self.date1, 40, resource=False)
- # (datetime.datetime(2013, 1, 29, 9, 0), datetime.datetime(2013, 1, 29, 16, 0))
- # (datetime.datetime(2013, 2, 1, 8, 0), datetime.datetime(2013, 2, 1, 13, 0))
- # (datetime.datetime(2013, 2, 1, 16, 0), datetime.datetime(2013, 2, 1, 23, 0))
- # (datetime.datetime(2013, 2, 5, 8, 0), datetime.datetime(2013, 2, 5, 16, 0))
- # (datetime.datetime(2013, 2, 8, 8, 0), datetime.datetime(2013, 2, 8, 13, 0))
- # (datetime.datetime(2013, 2, 8, 16, 0), datetime.datetime(2013, 2, 8, 23, 0))
- # (datetime.datetime(2013, 2, 12, 8, 0), datetime.datetime(2013, 2, 12, 9, 0))
-
- res = self.resource_calendar.schedule_hours(cr, uid, self.calendar_id, -40, day_dt=self.date1.replace(minute=0, second=0), context=context)
+ res = self.calendar.schedule_hours(-40, day_dt=self.date1.replace(minute=0, second=0))
# current day, limited at 09:00 because of day_dt specified -> 1 hour
- self.assertEqual(res[-1][0], datetime.strptime('2013-02-12 08:00:00', _format), 'resource_calendar: wrong hours scheduling')
- self.assertEqual(res[-1][1], datetime.strptime('2013-02-12 09:00:00', _format), 'resource_calendar: wrong hours scheduling')
+ self.assertEqual(res[-1][0], Datetime.from_string('2013-02-12 08:00:00'), 'resource_calendar: wrong hours scheduling')
+ self.assertEqual(res[-1][1], Datetime.from_string('2013-02-12 09:00:00'), 'resource_calendar: wrong hours scheduling')
# previous days: 5+7 hours / 8 hours / 5+7 hours -> 32 hours
- self.assertEqual(res[-2][0], datetime.strptime('2013-02-08 16:00:00', _format), 'resource_calendar: wrong hours scheduling')
- self.assertEqual(res[-2][1], datetime.strptime('2013-02-08 23:00:00', _format), 'resource_calendar: wrong hours scheduling')
- self.assertEqual(res[-3][0], datetime.strptime('2013-02-08 08:00:00', _format), 'resource_calendar: wrong hours scheduling')
- self.assertEqual(res[-3][1], datetime.strptime('2013-02-08 13:00:00', _format), 'resource_calendar: wrong hours scheduling')
- self.assertEqual(res[-4][0], datetime.strptime('2013-02-05 08:00:00', _format), 'resource_calendar: wrong hours scheduling')
- self.assertEqual(res[-4][1], datetime.strptime('2013-02-05 16:00:00', _format), 'resource_calendar: wrong hours scheduling')
- self.assertEqual(res[-5][0], datetime.strptime('2013-02-01 16:00:00', _format), 'resource_calendar: wrong hours scheduling')
- self.assertEqual(res[-5][1], datetime.strptime('2013-02-01 23:00:00', _format), 'resource_calendar: wrong hours scheduling')
- self.assertEqual(res[-6][0], datetime.strptime('2013-02-01 08:00:00', _format), 'resource_calendar: wrong hours scheduling')
- self.assertEqual(res[-6][1], datetime.strptime('2013-02-01 13:00:00', _format), 'resource_calendar: wrong hours scheduling')
+ self.assertEqual(res[-2][0], Datetime.from_string('2013-02-08 16:00:00'), 'resource_calendar: wrong hours scheduling')
+ self.assertEqual(res[-2][1], Datetime.from_string('2013-02-08 23:00:00'), 'resource_calendar: wrong hours scheduling')
+ self.assertEqual(res[-3][0], Datetime.from_string('2013-02-08 08:00:00'), 'resource_calendar: wrong hours scheduling')
+ self.assertEqual(res[-3][1], Datetime.from_string('2013-02-08 13:00:00'), 'resource_calendar: wrong hours scheduling')
+ self.assertEqual(res[-4][0], Datetime.from_string('2013-02-05 08:00:00'), 'resource_calendar: wrong hours scheduling')
+ self.assertEqual(res[-4][1], Datetime.from_string('2013-02-05 16:00:00'), 'resource_calendar: wrong hours scheduling')
+ self.assertEqual(res[-5][0], Datetime.from_string('2013-02-01 16:00:00'), 'resource_calendar: wrong hours scheduling')
+ self.assertEqual(res[-5][1], Datetime.from_string('2013-02-01 23:00:00'), 'resource_calendar: wrong hours scheduling')
+ self.assertEqual(res[-6][0], Datetime.from_string('2013-02-01 08:00:00'), 'resource_calendar: wrong hours scheduling')
+ self.assertEqual(res[-6][1], Datetime.from_string('2013-02-01 13:00:00'), 'resource_calendar: wrong hours scheduling')
# 7 hours remaining
- self.assertEqual(res[-7][0], datetime.strptime('2013-01-29 09:00:00', _format), 'resource_calendar: wrong hours scheduling')
- self.assertEqual(res[-7][1], datetime.strptime('2013-01-29 16:00:00', _format), 'resource_calendar: wrong hours scheduling')
+ self.assertEqual(res[-7][0], Datetime.from_string('2013-01-29 09:00:00'), 'resource_calendar: wrong hours scheduling')
+ self.assertEqual(res[-7][1], Datetime.from_string('2013-01-29 16:00:00'), 'resource_calendar: wrong hours scheduling')
# Compute scheduled hours
td = timedelta()
for item in res:
@@ -283,74 +243,53 @@ class TestResource(TestResourceCommon):
self.assertEqual(seconds(td) / 3600.0, 40.0, 'resource_calendar: wrong hours scheduling')
# --------------------------------------------------
- # Test2: schedule hours forward (old interval_get)
+ # Test2: schedule hours forward
# --------------------------------------------------
- # res = self.resource_calendar.interval_get(cr, uid, self.calendar_id, self.date1, 40, resource=False, byday=True)
- # (datetime.datetime(2013, 2, 12, 9, 0), datetime.datetime(2013, 2, 12, 16, 0))
- # (datetime.datetime(2013, 2, 15, 8, 0), datetime.datetime(2013, 2, 15, 13, 0))
- # (datetime.datetime(2013, 2, 15, 16, 0), datetime.datetime(2013, 2, 15, 23, 0))
- # (datetime.datetime(2013, 2, 22, 8, 0), datetime.datetime(2013, 2, 22, 13, 0))
- # (datetime.datetime(2013, 2, 22, 16, 0), datetime.datetime(2013, 2, 22, 23, 0))
- # (datetime.datetime(2013, 2, 26, 8, 0), datetime.datetime(2013, 2, 26, 16, 0))
- # (datetime.datetime(2013, 3, 1, 8, 0), datetime.datetime(2013, 3, 1, 9, 0))
-
- res = self.resource_calendar.schedule_hours(
- cr, uid, self.calendar_id, 40,
- day_dt=self.date1.replace(minute=0, second=0), context=context
+ res = self.calendar.schedule_hours(
+ 40, day_dt=self.date1.replace(minute=0, second=0)
)
- self.assertEqual(res[0][0], datetime.strptime('2013-02-12 09:00:00', _format), 'resource_calendar: wrong hours scheduling')
- self.assertEqual(res[0][1], datetime.strptime('2013-02-12 16:00:00', _format), 'resource_calendar: wrong hours scheduling')
- self.assertEqual(res[1][0], datetime.strptime('2013-02-15 08:00:00', _format), 'resource_calendar: wrong hours scheduling')
- self.assertEqual(res[1][1], datetime.strptime('2013-02-15 13:00:00', _format), 'resource_calendar: wrong hours scheduling')
- self.assertEqual(res[2][0], datetime.strptime('2013-02-15 16:00:00', _format), 'resource_calendar: wrong hours scheduling')
- self.assertEqual(res[2][1], datetime.strptime('2013-02-15 23:00:00', _format), 'resource_calendar: wrong hours scheduling')
- self.assertEqual(res[3][0], datetime.strptime('2013-02-19 08:00:00', _format), 'resource_calendar: wrong hours scheduling')
- self.assertEqual(res[3][1], datetime.strptime('2013-02-19 16:00:00', _format), 'resource_calendar: wrong hours scheduling')
- self.assertEqual(res[4][0], datetime.strptime('2013-02-22 08:00:00', _format), 'resource_calendar: wrong hours scheduling')
- self.assertEqual(res[4][1], datetime.strptime('2013-02-22 13:00:00', _format), 'resource_calendar: wrong hours scheduling')
- self.assertEqual(res[5][0], datetime.strptime('2013-02-22 16:00:00', _format), 'resource_calendar: wrong hours scheduling')
- self.assertEqual(res[5][1], datetime.strptime('2013-02-22 23:00:00', _format), 'resource_calendar: wrong hours scheduling')
- self.assertEqual(res[6][0], datetime.strptime('2013-02-26 08:00:00', _format), 'resource_calendar: wrong hours scheduling')
- self.assertEqual(res[6][1], datetime.strptime('2013-02-26 09:00:00', _format), 'resource_calendar: wrong hours scheduling')
+ self.assertEqual(res[0][0], Datetime.from_string('2013-02-12 09:00:00'), 'resource_calendar: wrong hours scheduling')
+ self.assertEqual(res[0][1], Datetime.from_string('2013-02-12 16:00:00'), 'resource_calendar: wrong hours scheduling')
+ self.assertEqual(res[1][0], Datetime.from_string('2013-02-15 08:00:00'), 'resource_calendar: wrong hours scheduling')
+ self.assertEqual(res[1][1], Datetime.from_string('2013-02-15 13:00:00'), 'resource_calendar: wrong hours scheduling')
+ self.assertEqual(res[2][0], Datetime.from_string('2013-02-15 16:00:00'), 'resource_calendar: wrong hours scheduling')
+ self.assertEqual(res[2][1], Datetime.from_string('2013-02-15 23:00:00'), 'resource_calendar: wrong hours scheduling')
+ self.assertEqual(res[3][0], Datetime.from_string('2013-02-19 08:00:00'), 'resource_calendar: wrong hours scheduling')
+ self.assertEqual(res[3][1], Datetime.from_string('2013-02-19 16:00:00'), 'resource_calendar: wrong hours scheduling')
+ self.assertEqual(res[4][0], Datetime.from_string('2013-02-22 08:00:00'), 'resource_calendar: wrong hours scheduling')
+ self.assertEqual(res[4][1], Datetime.from_string('2013-02-22 13:00:00'), 'resource_calendar: wrong hours scheduling')
+ self.assertEqual(res[5][0], Datetime.from_string('2013-02-22 16:00:00'), 'resource_calendar: wrong hours scheduling')
+ self.assertEqual(res[5][1], Datetime.from_string('2013-02-22 23:00:00'), 'resource_calendar: wrong hours scheduling')
+ self.assertEqual(res[6][0], Datetime.from_string('2013-02-26 08:00:00'), 'resource_calendar: wrong hours scheduling')
+ self.assertEqual(res[6][1], Datetime.from_string('2013-02-26 09:00:00'), 'resource_calendar: wrong hours scheduling')
td = timedelta()
for item in res:
td += item[1] - item[0]
self.assertEqual(seconds(td) / 3600.0, 40.0, 'resource_calendar: wrong hours scheduling')
- # res = self.resource_calendar.interval_get(cr, uid, self.calendar_id, self.date1, 40, resource=self.resource1_id, byday=True)
- # (datetime.datetime(2013, 2, 12, 9, 0), datetime.datetime(2013, 2, 12, 16, 0))
- # (datetime.datetime(2013, 2, 15, 8, 0), datetime.datetime(2013, 2, 15, 13, 0))
- # (datetime.datetime(2013, 2, 15, 16, 0), datetime.datetime(2013, 2, 15, 23, 0))
- # (datetime.datetime(2013, 3, 1, 8, 0), datetime.datetime(2013, 3, 1, 13, 0))
- # (datetime.datetime(2013, 3, 1, 16, 0), datetime.datetime(2013, 3, 1, 23, 0))
- # (datetime.datetime(2013, 3, 5, 8, 0), datetime.datetime(2013, 3, 5, 16, 0))
- # (datetime.datetime(2013, 3, 8, 8, 0), datetime.datetime(2013, 3, 8, 9, 0))
-
- res = self.resource_calendar.schedule_hours(
- cr, uid, self.calendar_id, 40,
- day_dt=self.date1.replace(minute=0, second=0),
- compute_leaves=True,
- resource_id=self.resource1_id, context=context
+ res = self.calendar.schedule_hours(
+ 40, day_dt=self.date1.replace(minute=0, second=0),
+ compute_leaves=True, resource_id=self.resource1_id
)
- self.assertEqual(res[0][0], datetime.strptime('2013-02-12 09:00:00', _format), 'resource_calendar: wrong hours scheduling')
- self.assertEqual(res[0][1], datetime.strptime('2013-02-12 16:00:00', _format), 'resource_calendar: wrong hours scheduling')
- self.assertEqual(res[1][0], datetime.strptime('2013-02-15 08:00:00', _format), 'resource_calendar: wrong hours scheduling')
- self.assertEqual(res[1][1], datetime.strptime('2013-02-15 13:00:00', _format), 'resource_calendar: wrong hours scheduling')
- self.assertEqual(res[2][0], datetime.strptime('2013-02-15 16:00:00', _format), 'resource_calendar: wrong hours scheduling')
- self.assertEqual(res[2][1], datetime.strptime('2013-02-15 23:00:00', _format), 'resource_calendar: wrong hours scheduling')
- self.assertEqual(res[3][0], datetime.strptime('2013-02-19 08:00:00', _format), 'resource_calendar: wrong hours scheduling')
- self.assertEqual(res[3][1], datetime.strptime('2013-02-19 09:00:00', _format), 'resource_calendar: wrong hours scheduling')
- self.assertEqual(res[4][0], datetime.strptime('2013-02-19 12:00:00', _format), 'resource_calendar: wrong hours scheduling')
- self.assertEqual(res[4][1], datetime.strptime('2013-02-19 16:00:00', _format), 'resource_calendar: wrong hours scheduling')
- self.assertEqual(res[5][0], datetime.strptime('2013-02-22 08:00:00', _format), 'resource_calendar: wrong hours scheduling')
- self.assertEqual(res[5][1], datetime.strptime('2013-02-22 09:00:00', _format), 'resource_calendar: wrong hours scheduling')
- self.assertEqual(res[6][0], datetime.strptime('2013-02-22 16:00:00', _format), 'resource_calendar: wrong hours scheduling')
- self.assertEqual(res[6][1], datetime.strptime('2013-02-22 23:00:00', _format), 'resource_calendar: wrong hours scheduling')
- self.assertEqual(res[7][0], datetime.strptime('2013-03-01 11:30:00', _format), 'resource_calendar: wrong hours scheduling')
- self.assertEqual(res[7][1], datetime.strptime('2013-03-01 13:00:00', _format), 'resource_calendar: wrong hours scheduling')
- self.assertEqual(res[8][0], datetime.strptime('2013-03-01 16:00:00', _format), 'resource_calendar: wrong hours scheduling')
- self.assertEqual(res[8][1], datetime.strptime('2013-03-01 22:30:00', _format), 'resource_calendar: wrong hours scheduling')
+ self.assertEqual(res[0][0], Datetime.from_string('2013-02-12 09:00:00'), 'resource_calendar: wrong hours scheduling')
+ self.assertEqual(res[0][1], Datetime.from_string('2013-02-12 16:00:00'), 'resource_calendar: wrong hours scheduling')
+ self.assertEqual(res[1][0], Datetime.from_string('2013-02-15 08:00:00'), 'resource_calendar: wrong hours scheduling')
+ self.assertEqual(res[1][1], Datetime.from_string('2013-02-15 13:00:00'), 'resource_calendar: wrong hours scheduling')
+ self.assertEqual(res[2][0], Datetime.from_string('2013-02-15 16:00:00'), 'resource_calendar: wrong hours scheduling')
+ self.assertEqual(res[2][1], Datetime.from_string('2013-02-15 23:00:00'), 'resource_calendar: wrong hours scheduling')
+ self.assertEqual(res[3][0], Datetime.from_string('2013-02-19 08:00:00'), 'resource_calendar: wrong hours scheduling')
+ self.assertEqual(res[3][1], Datetime.from_string('2013-02-19 09:00:00'), 'resource_calendar: wrong hours scheduling')
+ self.assertEqual(res[4][0], Datetime.from_string('2013-02-19 12:00:00'), 'resource_calendar: wrong hours scheduling')
+ self.assertEqual(res[4][1], Datetime.from_string('2013-02-19 16:00:00'), 'resource_calendar: wrong hours scheduling')
+ self.assertEqual(res[5][0], Datetime.from_string('2013-02-22 08:00:00'), 'resource_calendar: wrong hours scheduling')
+ self.assertEqual(res[5][1], Datetime.from_string('2013-02-22 09:00:00'), 'resource_calendar: wrong hours scheduling')
+ self.assertEqual(res[6][0], Datetime.from_string('2013-02-22 16:00:00'), 'resource_calendar: wrong hours scheduling')
+ self.assertEqual(res[6][1], Datetime.from_string('2013-02-22 23:00:00'), 'resource_calendar: wrong hours scheduling')
+ self.assertEqual(res[7][0], Datetime.from_string('2013-03-01 11:30:00'), 'resource_calendar: wrong hours scheduling')
+ self.assertEqual(res[7][1], Datetime.from_string('2013-03-01 13:00:00'), 'resource_calendar: wrong hours scheduling')
+ self.assertEqual(res[8][0], Datetime.from_string('2013-03-01 16:00:00'), 'resource_calendar: wrong hours scheduling')
+ self.assertEqual(res[8][1], Datetime.from_string('2013-03-01 22:30:00'), 'resource_calendar: wrong hours scheduling')
td = timedelta()
for item in res:
td += item[1] - item[0]
@@ -362,38 +301,34 @@ class TestResource(TestResourceCommon):
# old API: resource without leaves
# res: 2 weeks -> 40 hours
- res = self.resource_calendar._interval_hours_get(
- cr, uid, self.calendar_id,
+ res = self.calendar._interval_hours_get(
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, context=context)
+ resource_id=self.resource1_id, exclude_leaves=True)
self.assertEqual(res, 40.0, 'resource_calendar: wrong _interval_hours_get compatibility computation')
# new API: resource without leaves
# res: 2 weeks -> 40 hours
- res = self.resource_calendar.get_working_hours(
- cr, uid, self.calendar_id,
+ res = self.calendar.get_working_hours(
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, context=context)
+ compute_leaves=False, resource_id=self.resource1_id)
self.assertEqual(res, 40.0, 'resource_calendar: wrong get_working_hours computation')
# 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,
+ res = self.calendar._interval_hours_get(
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, context=context)
+ 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,
+ res = self.calendar.get_working_hours(
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, context=context)
+ compute_leaves=True, resource_id=self.resource1_id)
self.assertEqual(res, 33.0, 'resource_calendar: wrong get_working_hours computation')
# --------------------------------------------------
@@ -401,69 +336,105 @@ class TestResource(TestResourceCommon):
# --------------------------------------------------
# Test without calendar and default_interval
- res = self.resource_calendar.get_working_hours(
- cr, uid, None,
+ res = self.ResourceCalendar.with_context(self.context).get_working_hours(
self.date1.replace(hour=6, minute=0),
self.date2.replace(hour=23, minute=0),
compute_leaves=True, resource_id=self.resource1_id,
- default_interval=(8, 16), context=context)
+ default_interval=(8, 16))
self.assertEqual(res, 32.0, 'resource_calendar: wrong get_working_hours computation')
- self.att0_0_id = self.resource_attendance.create(
- cr, uid, {
+ self.att0_0_id = self.ResourceAttendance.with_context(self.context).create(
+ {
'name': 'Att0',
'dayofweek': '0',
'hour_from': 7.5,
'hour_to': 12.5,
- 'calendar_id': self.calendar_id,
- }, context=context
+ 'calendar_id': self.calendar.id,
+ }
)
- self.att0_1_id = self.resource_attendance.create(
- cr, uid, {
+ self.att0_1_id = self.ResourceAttendance.with_context(self.context).create(
+ {
'name': 'Att0',
'dayofweek': '0',
'hour_from': 13,
'hour_to': 14,
- 'calendar_id': self.calendar_id,
- }, context=context
+ 'calendar_id': self.calendar.id,
+ }
)
- date1 = datetime.strptime('2013-02-11 07:30:00', '%Y-%m-%d %H:%M:%S')
- date2 = datetime.strptime('2013-02-11 14:00:00', '%Y-%m-%d %H:%M:%S')
- res = self.resource_calendar.get_working_hours(
- cr, uid, self.calendar_id,
+ date1 = Datetime.from_string('2013-02-11 07:30:00')
+ date2 = Datetime.from_string('2013-02-11 14:00:00')
+ res = self.calendar.get_working_hours(
date1,
date2,
- compute_leaves=False, resource_id=self.resource1_id, context=context)
+ compute_leaves=False, resource_id=self.resource1_id)
# 7h30 -> 12h30 = 5 / 13h -> 14h = 1 / -> 6h
self.assertEqual(res, 6, '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, context={'tz': 'UTC'})
- self.assertEqual(res.date(), datetime.strptime('2013-02-26 00:0:00', _format).date(), 'resource_calendar: wrong days scheduling')
- res = self.resource_calendar.schedule_days_get_date(cr, uid, self.calendar_id, -2, day_date=self.date1, context={'tz': 'UTC'})
- self.assertEqual(res.date(), datetime.strptime('2013-02-08 00:00:00', _format).date(), 'resource_calendar: wrong days scheduling')
+ res = self.calendar.schedule_days_get_date(5, day_date=self.date1)
+ self.assertEqual(res.date(), Datetime.from_string('2013-02-26 00:00:00').date(), 'resource_calendar: wrong days scheduling')
+ res = self.calendar.schedule_days_get_date(-2, day_date=self.date1)
+ self.assertEqual(res.date(), Datetime.from_string('2013-02-08 00:00:00').date(), 'resource_calendar: wrong days scheduling')
- res = self.resource_calendar.schedule_days_get_date(
- cr, uid, self.calendar_id, 5, day_date=self.date1,
- compute_leaves=True, resource_id=self.resource1_id, context={'tz': 'UTC'})
- self.assertEqual(res.date(), datetime.strptime('2013-03-01 00:0:00', _format).date(), 'resource_calendar: wrong days scheduling')
+ res = self.calendar.schedule_days_get_date(
+ 5, day_date=self.date1,
+ compute_leaves=True, resource_id=self.resource1_id)
+ self.assertEqual(res.date(), Datetime.from_string('2013-03-01 00:00:00').date(), 'resource_calendar: wrong days scheduling')
# --------------------------------------------------
# Test2: misc
# --------------------------------------------------
# Without calendar, should only count days -> 12 -> 16, 5 days with default intervals
- res = self.resource_calendar.schedule_days_get_date(cr, uid, None, 5, day_date=self.date1, default_interval=(8, 16), context={'tz': 'UTC'})
- self.assertEqual(res, datetime.strptime('2013-02-16 16:00:00', _format), 'resource_calendar: wrong days scheduling')
+ res = self.ResourceCalendar.with_context(self.context).schedule_days_get_date(5, day_date=self.date1, default_interval=(8, 16))
+ self.assertEqual(res, Datetime.from_string('2013-02-16 16:00:00'), 'resource_calendar: wrong days scheduling')
+
+ def test_60_project(self):
+ # I assign working calendar '45 Hours/Week' to human resource.
+ resources = self.env.ref('resource.resource_analyst') + self.env.ref('resource.resource_designer') + self.env.ref('resource.resource_developer')
+ resources.write({'calendar_id': self.ref('resource.timesheet_group1'), 'resource_type': 'user'})
+
+ # I had Project of Odoo Integration of 50 Hours with three human resource assigned on it. I have started project from this week start.
+ # I check per day work hour availability of the Resource based on Working Calendar Assigned to each resource, for first day of the week.
+ now = datetime.now()
+ dt = now - timedelta(days=now.weekday())
+ for resource in resources:
+ result = resource.calendar_id.working_hours_on_day(dt)
+ self.assertEqual(float_compare(result, 8.0, precision_digits=2), 0, 'Wrong calculation of day work hour availability of the Resource (found %d).' % result)
+
+ # Now, resource "Developer" drafted leave on Thursday in this week.
+ now = datetime.now()
+ dt = (now - timedelta(days=now.weekday())) + timedelta(days=3)
+ vals = {
+ 'resource_id': self.ref('resource.resource_developer'),
+ 'calendar_id': self.ref('resource.timesheet_group1'),
+ 'date_from': dt.strftime("%Y-%m-%d 09:00:00"),
+ 'date_to': dt.strftime("%Y-%m-%d 18:00:00")
+ }
+ self.env.ref('resource.resource_dummyleave').write(vals)
+
+ # I check Actual working hours on resource 'Developer' from this week
+ now = datetime.now()
+ dt_from = now - relativedelta(days=now.weekday(), hour=8, minute=30)
+ dt_to = dt_from + relativedelta(days=6, hour=17)
+ hours = self.env.ref('resource.timesheet_group1').interval_hours_get(dt_from, dt_to, resource=self.ref('resource.resource_developer'))
+ self.assertGreater(hours, 27, 'Invalid Total Week working hour calculated, got %r, expected > 27' % hours)
+
+ # Project Analysis work is of 20 hours which will start from Week start so i will calculate working schedule for resource Analyst for the same.
+ now = datetime.now()
+ work_intreval = self.env.ref('resource.timesheet_group1').interval_min_get(now, 20.0, resource=self.ref('resource.resource_designer'))
+ self.assertGreaterEqual(len(work_intreval), 5, 'Wrong Schedule Calculated')
+
+ def test_70_duplicate_resource(self):
+ resource_id = self.env.ref('resource.resource_analyst').copy()
+ self.assertTrue(resource_id, 'Unable to Duplicate Resource')
+
WAR_START = date(1932, 11, 2)
WAR_END = date(1932, 12, 10)
@@ -569,10 +540,8 @@ class TestWorkDays(TransactionCase):
weekdays = [d for d in self._days if d.weekday() not in (5, 6)]
self.assertEqual(weekdays, list(r1._iter_work_days(WAR_START, WAR_END)))
- self.assertEqual(
- [d for d in weekdays
- if d < date(1932, 11, 9) or d > date(1932, 11, 12)
- ],
+ self.assertEqual([
+ d for d in weekdays if d < date(1932, 11, 9) or d > date(1932, 11, 12)],
list(r2._iter_work_days(WAR_START, WAR_END))
)
@@ -593,12 +562,11 @@ class TestWorkDays(TransactionCase):
'resource_id': r.id
})
- self.assertEqual(
- [d for d in self._days
- if d.weekday() not in (5, 6)
- if d < date(1932, 11, 9) or d > date(1932, 11, 12)
- if d < date(1932, 12, 2)
- ],
+ self.assertEqual([
+ d for d in self._days
+ if d.weekday() not in (5, 6)
+ if d < date(1932, 11, 9) or d > date(1932, 11, 12)
+ if d < date(1932, 12, 2)],
list(r._iter_work_days(WAR_START, WAR_END))
)
@@ -608,11 +576,11 @@ class TestWorkDays(TransactionCase):
self.assertTrue(r._is_work_day(date(1932, 11, 14)))
self.assertTrue(r._is_work_day(date(1932, 12, 1)))
- self.assertFalse(r._is_work_day(date(1932, 11, 11))) # global leave
- self.assertFalse(r._is_work_day(date(1932, 11, 13))) # sun
- self.assertFalse(r._is_work_day(date(1932, 11, 19))) # sat
- self.assertFalse(r._is_work_day(date(1932, 11, 20))) # sun
- self.assertFalse(r._is_work_day(date(1932, 12, 6))) # personal leave
+ self.assertFalse(r._is_work_day(date(1932, 11, 11))) # global leave
+ self.assertFalse(r._is_work_day(date(1932, 11, 13))) # sun
+ self.assertFalse(r._is_work_day(date(1932, 11, 19))) # sat
+ self.assertFalse(r._is_work_day(date(1932, 11, 20))) # sun
+ self.assertFalse(r._is_work_day(date(1932, 12, 6))) # personal leave
def seconds(td):
assert isinstance(td, timedelta)
diff --git a/addons/resource/resource_view.xml b/addons/resource/views/resource_views.xml
similarity index 98%
rename from addons/resource/resource_view.xml
rename to addons/resource/views/resource_views.xml
index 5eeec8aaf05..6dbb2c29a91 100644
--- a/addons/resource/resource_view.xml
+++ b/addons/resource/views/resource_views.xml
@@ -1,6 +1,5 @@
-
-
+
@@ -212,7 +211,7 @@
-
+
diff --git a/addons/stock_calendar/models/resource.py b/addons/stock_calendar/models/resource.py
index e0e2c22dc07..0ddec1b0cd5 100644
--- a/addons/stock_calendar/models/resource.py
+++ b/addons/stock_calendar/models/resource.py
@@ -1,10 +1,8 @@
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
-import datetime
from odoo import api, fields, models
-from odoo.tools import DEFAULT_SERVER_DATETIME_FORMAT, DEFAULT_SERVER_DATE_FORMAT
class ResourceCalendarAttendance(models.Model):
@@ -16,16 +14,16 @@ class ResourceCalendarAttendance(models.Model):
class ResourceCalendarLeaves(models.Model):
_inherit = "resource.calendar.leaves"
- group_id = fields.Many2one('procurement.group', 'Procurement Group')
+ group_id = fields.Many2one('procurement.group', string="Procurement Group")
class ResourceCalendar(models.Model):
_inherit = "resource.calendar"
# Keep as it takes into account times
- def get_leave_intervals(self, cr, uid, id, resource_id=None,
- start_datetime=None, end_datetime=None,
- context=None):
+ @api.multi
+ def get_leave_intervals(self, resource_id=None,
+ start_datetime=None, end_datetime=None):
"""Get the leaves of the calendar. Leaves can be filtered on the resource,
the start datetime or the end datetime.
@@ -43,15 +41,15 @@ class ResourceCalendar(models.Model):
"""
# TDE FIXME: waw, overriding completely a method + changing its result
# and its behavior, very nice. Please FIXME.
- resource_calendar = self.browse(cr, uid, id, context=context)
+ self.ensure_one()
leaves = []
- for leave in resource_calendar.leave_ids:
+ for leave in self.leave_ids:
if leave.resource_id and not resource_id == leave.resource_id.id:
continue
- date_from = datetime.datetime.strptime(leave.date_from, DEFAULT_SERVER_DATETIME_FORMAT)
+ date_from = fields.Datetime.from_string(leave.date_from)
if end_datetime and date_from > end_datetime:
continue
- date_to = datetime.datetime.strptime(leave.date_to, DEFAULT_SERVER_DATETIME_FORMAT)
+ date_to = fields.Datetime.from_string(leave.date_to)
if start_datetime and date_to < start_datetime:
continue
leaves.append((date_from, date_to, leave.group_id.id))
@@ -61,7 +59,8 @@ class ResourceCalendar(models.Model):
# Utility methods
# --------------------------------------------------
- def interval_remove_leaves(self, cr, uid, interval, leave_intervals, context=None):
+ @api.model
+ def interval_remove_leaves(self, interval, leave_intervals):
""" Utility method that remove leave intervals from a base interval:
- clean the leave intervals, to have an ordered list of not-overlapping
@@ -101,7 +100,7 @@ class ResourceCalendar(models.Model):
att_obj = self.pool.get("resource.calendar.attendance")
if leave[2]:
if len(current_interval) > 2:
- current_group = current_interval[2] and att_obj.browse(cr, uid, current_interval[2], context=context).group_id.id or False
+ current_group = current_interval[2] and att_obj.browse(current_interval[2]).group_id.id or False
if leave[2] != current_group:
continue
if leave[1] <= current_interval[0]:
diff --git a/addons/stock_calendar/models/stock.py b/addons/stock_calendar/models/stock.py
index 660bd42bc05..01768f43d0d 100644
--- a/addons/stock_calendar/models/stock.py
+++ b/addons/stock_calendar/models/stock.py
@@ -68,7 +68,7 @@ class StockWarehouseOrderpoint(models.Model):
purchase_date = False
delivery_date = start_date
if self.calendar_id and self.calendar_id.attendance_ids:
- res = self.calendar_id._schedule_days(-1, start_date, compute_leaves=True)[0] # CLEANME
+ res = self.calendar_id._schedule_days(-1, start_date, compute_leaves=True)
if res and res[0][0] < start_date:
group_to_find = res[0][2] and Attendance.browse(res[0][2]).group_id.id
delivery_date = res[0][0]
@@ -76,7 +76,7 @@ class StockWarehouseOrderpoint(models.Model):
if self.purchase_calendar_id and self.purchase_calendar_id.attendance_ids:
while not purchase_date:
found_date = found_date + relativedelta(days=-1) # won't allow to deliver within the day
- res = self.purchase_calendar_id._schedule_days(-1, found_date, compute_leaves=True)[0] # CLEANME
+ res = self.purchase_calendar_id._schedule_days(-1, found_date, compute_leaves=True)
for re in res:
group = re[2] and Attendance.browse(re[2]).group_id.id
found_date = re[0]
@@ -94,7 +94,7 @@ class StockWarehouseOrderpoint(models.Model):
now_date = datetime.utcnow()
# Search first calendar day (without group)
- res = self.calendar_id._schedule_days(1, new_date, compute_leaves=True)[0] # CLEANME
+ res = self.calendar_id._schedule_days(1, new_date, compute_leaves=True)
att_group = res and res[0][2] and Attendance.browse(res[0][2]).group_id.id
# If hours are smaller than the current date, search a day further
if res and res[0][0] < now_date:
@@ -112,7 +112,7 @@ class StockWarehouseOrderpoint(models.Model):
while res and group and att_group != group and number < 100:
number += 1
new_date = res[0][1] + relativedelta(days=1)
- res = self.calendar_id._schedule_days(1, new_date, compute_leaves=True)[0]
+ res = self.calendar_id._schedule_days(1, new_date, compute_leaves=True)
att_group = False
for re in res:
if re[2]:
@@ -128,7 +128,7 @@ class StockWarehouseOrderpoint(models.Model):
if res:
date1 = res[0][1]
new_date = res[0][1] + relativedelta(days=1)
- res = self.calendar_id._schedule_days(1, new_date, compute_leaves=True)[0]
+ res = self.calendar_id._schedule_days(1, new_date, compute_leaves=True)
if res:
return (date1, res[0][1])
return (False, False)