[REF] purchase, stock_calendar: pre migration cleaning

* All methods are converted into an api.multi style (using ids instead of
  a browse record or an id)
* Removed api.v7 methods for two methods defined in purchase and overriden
  in stock_calendar, now used only in a true multi-style (old and new API)
* Moved methods having orderpoint as primary object on the orderpoint model
* Removed unused next_day field on resource.calendar model; it was
  introduced with hacks of resource.calendar, and never used.

The whole override of resource models should be cleaned but will be done
after migration of resource and stock.calendar.
This commit is contained in:
Thibault Delavallée
2016-07-12 17:53:10 +02:00
parent 61039df4b9
commit 3f7a950ccb
4 changed files with 125 additions and 190 deletions
+4 -29
View File
@@ -806,45 +806,20 @@ class ProcurementOrder(models.Model):
return all(move.state == 'done' for move in self.move_ids)
return super(ProcurementOrder, self)._check()
@api.v8
def _get_purchase_schedule_date(self):
"""Return the datetime value to use as Schedule Date (``date_planned``) for the
Purchase Order Lines created to satisfy the given procurement. """
procurement_date_planned = datetime.strptime(self.date_planned, DEFAULT_SERVER_DATETIME_FORMAT)
schedule_date = (procurement_date_planned - relativedelta(days=self.company_id.po_lead))
return schedule_date
@api.v7
def _get_purchase_schedule_date(self, procurement):
"""Return the datetime value to use as Schedule Date (``date_planned``) for the
Purchase Order Lines created to satisfy the given procurement.
:param browse_record procurement: the procurement for which a PO will be created.
:rtype: datetime
:return: the desired Schedule Date for the PO lines
"""
procurement_date_planned = datetime.strptime(procurement.date_planned, DEFAULT_SERVER_DATETIME_FORMAT)
schedule_date = (procurement_date_planned - relativedelta(days=procurement.company_id.po_lead))
return schedule_date
@api.v8
def _get_purchase_order_date(self, schedule_date):
"""Return the datetime value to use as Order Date (``date_order``) for the
Purchase Order created to satisfy the given procurement. """
self.ensure_one()
seller_delay = int(self.product_id._select_seller(self.product_id).delay)
return schedule_date - relativedelta(days=seller_delay)
@api.v7
def _get_purchase_order_date(self, cr, uid, procurement, company, schedule_date, context=None):
"""Return the datetime value to use as Order Date (``date_order``) for the
Purchase Order created to satisfy the given procurement.
:param browse_record procurement: the procurement for which a PO will be created.
:param browse_report company: the company to which the new PO will belong to.
:param datetime schedule_date: desired Scheduled Date for the Purchase Order lines.
:rtype: datetime
:return: the desired Order Date for the PO
"""
seller_delay = int(procurement.product_id._select_seller(procurement.product_id).delay)
return schedule_date - relativedelta(days=seller_delay)
@api.multi
def _prepare_purchase_order_line(self, po, supplier):
self.ensure_one()
+3 -146
View File
@@ -28,51 +28,21 @@ class procurement_order(osv.osv):
if ops and ops[0]:
orderpoint = orderpoint_obj.browse(cr, uid, ops[0], context=context)
date_planned = datetime.strptime(procurement.date_planned, DEFAULT_SERVER_DATETIME_FORMAT)
purchase_date, delivery_date = self._get_previous_dates(cr, uid, orderpoint, date_planned, context=context)
purchase_date, delivery_date = self.pool['stock.orderpoint']._get_previous_dates(cr, uid, [orderpoint.id], date_planned, context=context)
if purchase_date and delivery_date:
self.write(cr, uid, [procurement.id], {'next_delivery_date': delivery_date.strftime(DEFAULT_SERVER_DATETIME_FORMAT),
'next_purchase_date': purchase_date.strftime(DEFAULT_SERVER_DATETIME_FORMAT),}, context=context)
@api.v8
def _get_purchase_order_date(self, schedule_date):
if self.next_purchase_date:
return datetime.strptime(self.next_purchase_date, DEFAULT_SERVER_DATETIME_FORMAT)
return super(procurement_order, self)._get_purchase_order_date(schedule_date)
@api.v7
def _get_purchase_order_date(self, cr, uid, procurement, company, schedule_date, context=None):
"""Return the datetime value to use as Order Date (``date_order``) for the
Purchase Order created to satisfy the given procurement.
:param browse_record procurement: the procurement for which a PO will be created.
:param browse_report company: the company to which the new PO will belong to.
:param datetime schedule_date: desired Scheduled Date for the Purchase Order lines.
:rtype: datetime
:return: the desired Order Date for the PO
"""
if procurement.next_purchase_date:
return datetime.strptime(procurement.next_purchase_date, DEFAULT_SERVER_DATETIME_FORMAT)
return super(procurement_order, self)._get_purchase_order_date(cr, uid, procurement, company, schedule_date, context=context)
@api.v8
def _get_purchase_schedule_date(self):
if self.next_delivery_date:
return datetime.strptime(self.next_delivery_date, DEFAULT_SERVER_DATETIME_FORMAT)
return super(procurement_order, self)._get_purchase_schedule_date()
@api.v7
def _get_purchase_schedule_date(self, cr, uid, procurement, context=None):
"""Return the datetime value to use as Schedule Date (``date_planned``) for the
Purchase Order Lines created to satisfy the given procurement.
:param browse_record procurement: the procurement for which a PO will be created.
:rtype: datetime
:return: the desired Schedule Date for the PO lines
"""
if procurement.next_delivery_date:
return datetime.strptime(procurement.next_delivery_date, DEFAULT_SERVER_DATETIME_FORMAT)
return super(procurement_order, self)._get_purchase_schedule_date(cr, uid, procurement, context=context)
def _prepare_purchase_order_line(self, cr, uid, ids, po, supplier, context=None):
res = super(procurement_order, self)._prepare_purchase_order_line(cr, uid, ids, po, supplier, context=context)
procurement = self.browse(cr, uid, ids, context=context)
@@ -80,119 +50,6 @@ class procurement_order(osv.osv):
res.update({'date_planned': procurement.next_delivery_date})
return res
def _get_previous_dates(self, cr, uid, orderpoint, start_date = False, context=None):
"""
Date should be given in utc
"""
calendar_obj = self.pool.get('resource.calendar')
att_obj = self.pool.get('resource.calendar.attendance')
context = context or {}
context['no_round_hours'] = True
# First check if the orderpoint has a Calendar as it should be delivered at this calendar date
purchase_date = False
delivery_date = start_date
if orderpoint.calendar_id and orderpoint.calendar_id.attendance_ids:
res = calendar_obj._schedule_days(cr, uid, orderpoint.calendar_id.id, -1, start_date, compute_leaves=True, context=context)
if res and res[0][0] < start_date:
group_to_find = res[0][2] and att_obj.browse(cr, uid, res[0][2], context=context).group_id.id or False
delivery_date = res[0][0]
found_date = delivery_date
if orderpoint.purchase_calendar_id and orderpoint.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 = calendar_obj._schedule_days(cr, uid, orderpoint.purchase_calendar_id.id, -1, found_date, compute_leaves=True, context=context)
for re in res:
group = re[2] and att_obj.browse(cr, uid, re[2], context=context).group_id.id or False
found_date = re[0]
if not purchase_date and (group_to_find and group_to_find == group or (not group_to_find)):
purchase_date = re[0]
else:
delivery_date = start_date or datetime.utcnow()
return purchase_date, delivery_date
def _get_next_dates(self, cr, uid, orderpoint, new_date=False, group=False, context=None):
calendar_obj = self.pool.get('resource.calendar')
att_obj = self.pool.get('resource.calendar.attendance')
context = context or {}
context['no_round_hours'] = True
if not new_date:
new_date = datetime.utcnow()
now_date = datetime.utcnow()
# Search first calendar day (without group)
res = calendar_obj._schedule_days(cr, uid, orderpoint.calendar_id.id, 1, new_date, compute_leaves=True, context=context)
att_group = res and res[0][2] and att_obj.browse(cr, uid, res[0][2], context=context).group_id.id or False
#If hours are smaller than the current date, search a day further
if res and res[0][0] < now_date:
new_date = res[0][1] + relativedelta(days=1)
res = calendar_obj._schedule_days(cr, uid, orderpoint.calendar_id.id, 1, new_date, compute_leaves=True, context=context)
for re in res:
att_group = False
if re[2]:
att_group = att_obj.browse(cr, uid, re[2], context=context).group_id.id
if att_group == group:
break
# If you can find an entry and you have a group to match, but it does not, search further until you find one that corresponds
number = 0
while res and group and att_group != group and number < 100:
number += 1
new_date = res[0][1] + relativedelta(days=1)
res = calendar_obj._schedule_days(cr, uid, orderpoint.calendar_id.id, 1, new_date, compute_leaves=True, context=context)
att_group = False
for re in res:
if re[2]:
att_group = att_obj.browse(cr, uid, re[2], context=context).group_id.id
if att_group == group:
break
#number as safety pall for endless loops
if number >= 100:
res = False
# If you found a solution(first date), you need the second date until the next delivery because you need to deliver
# everything needed until the second date on the first date
if res:
date1 = res[0][1]
new_date = res[0][1] + relativedelta(days=1)
res = calendar_obj._schedule_days(cr, uid, orderpoint.calendar_id.id, 1, new_date, compute_leaves=True, context=context)
if res:
return (date1, res[0][1])
return (False, False)
def _get_group(self, cr, uid, orderpoint, context=None):
"""
Will return the groups and the end dates of the intervals of the purchase calendar
that need to be executed now.
If a purchase calendar is defined, it should give the
:return [(date, group)]
"""
#Check if orderpoint has last execution date and calculate if we need to calculate again already
calendar_obj = self.pool.get("resource.calendar")
att_obj = self.pool.get("resource.calendar.attendance")
group = False
context = context or {}
context['no_round_hours'] = True
date = False
now_date = datetime.utcnow()
res_intervals = []
if orderpoint.purchase_calendar_id and orderpoint.purchase_calendar_id.attendance_ids:
if orderpoint.last_execution_date:
new_date = datetime.strptime(orderpoint.last_execution_date, DEFAULT_SERVER_DATETIME_FORMAT)
else:
new_date = datetime.utcnow()
# TDE note: I bet accessing interval[2] will crash, no ? this code seems very louche
intervals = calendar_obj._schedule_days(cr, uid, orderpoint.purchase_calendar_id.id, 1, new_date, compute_leaves=True, context=context)
for interval in intervals:
# If last execution date, interval should start after it in order not to execute the same orderpoint twice
# TODO: Make the interval a little bigger
if (orderpoint.last_execution_date and (interval[0] > new_date and interval[0] < now_date)) or (not orderpoint.last_execution_date and interval[0] < now_date and interval[1] > now_date):
group = att_obj.browse(cr, uid, interval[2], context=context).group_id.id
date = interval[1]
res_intervals += [(date, group), ]
else:
return [(now_date, None)]
return res_intervals
def _procurement_from_orderpoint_get_order(self, cr, uid, context=None):
return 'location_id, purchase_calendar_id, calendar_id'
@@ -203,10 +60,10 @@ class procurement_order(osv.osv):
def _procurement_from_orderpoint_get_groups(self, cr, uid, orderpoint_ids, context=None):
orderpoint = self.pool['stock.warehouse.orderpoint'].browse(cr, uid, orderpoint_ids[0], context=context)
res_groups = []
date_groups = self._get_group(cr, uid, orderpoint, context=context)
date_groups = self._get_group(cr, uid, [orderpoint.id], context=context)
for date, group in date_groups:
if orderpoint.calendar_id and orderpoint.calendar_id.attendance_ids:
date1, date2 = self._get_next_dates(cr, uid, orderpoint, date, group, context=context)
date1, date2 = self._get_next_dates(cr, uid, [orderpoint.id], date, group, context=context)
res_groups += [{'to_date': date2, 'procurement_values': {'group': group, 'date': date1, 'purchase_date': date}}] # date1/date2 as deliveries and date as purchase confirmation date
else:
res_groups += [{'to_date': False, 'procurement_values': {'group': group, 'date': date, 'purchase_date': date}}]
-15
View File
@@ -13,21 +13,6 @@ class resource_calendar_leaves(osv.osv):
class resource_calendar(osv.osv):
_inherit = "resource.calendar"
#Could remove this as it does not help a lot
def _calculate_next_day(self, cr, uid, ids, fields, names, context=None):
res = {}
for calend in self.browse(cr, uid, ids, context=context):
# date1 = self.get_next_day(cr, uid, calend.id, datetime.utcnow() + relativedelta(days = 1))
_format = '%Y-%m-%d %H:%M:%S'
sched_date = self.schedule_days_get_date(
cr, uid, calend.id, 1, day_date=datetime.datetime.utcnow(), compute_leaves=True)
res[calend.id] = sched_date and sched_date.strftime(_format) or False
return res
_columns = {
'next_day': fields.function(_calculate_next_day, string='Next day it should trigger', type='datetime'),
}
# Keep as it takes into account times
def get_leave_intervals(self, cr, uid, id, resource_id=None,
start_datetime=None, end_datetime=None,
+118
View File
@@ -1,4 +1,9 @@
from datetime import datetime
from dateutil.relativedelta import relativedelta
from openerp.osv import fields, osv
from openerp.tools import DEFAULT_SERVER_DATETIME_FORMAT, DEFAULT_SERVER_DATE_FORMAT
class stock_warehouse_orderpoint(osv.osv):
_inherit = "stock.warehouse.orderpoint"
@@ -16,3 +21,116 @@ class stock_warehouse_orderpoint(osv.osv):
'next_delivery_date': date,
'next_purchase_date': purchase_date})
return res
def _get_group(self, cr, uid, ids, context=None):
"""
Will return the groups and the end dates of the intervals of the purchase calendar
that need to be executed now.
If a purchase calendar is defined, it should give the
:return [(date, group)]
"""
# TDE FIXME: unused context key 'no_round_hours' removed
orderpoint = self.browse(cr, uid, ids, context=context)[0]
# Check if orderpoint has last execution date and calculate if we need to calculate again already
calendar_obj = self.pool.get("resource.calendar")
att_obj = self.pool.get("resource.calendar.attendance")
group = False
date = False
now_date = datetime.utcnow()
res_intervals = []
if orderpoint.purchase_calendar_id and orderpoint.purchase_calendar_id.attendance_ids:
if orderpoint.last_execution_date:
new_date = datetime.strptime(orderpoint.last_execution_date, DEFAULT_SERVER_DATETIME_FORMAT)
else:
new_date = datetime.utcnow()
# TDE note: I bet accessing interval[2] will crash, no ? this code seems very louche
intervals = calendar_obj._schedule_days(cr, uid, orderpoint.purchase_calendar_id.id, 1, new_date, compute_leaves=True, context=context)
for interval in intervals:
# If last execution date, interval should start after it in order not to execute the same orderpoint twice
# TODO: Make the interval a little bigger
if (orderpoint.last_execution_date and (interval[0] > new_date and interval[0] < now_date)) or (not orderpoint.last_execution_date and interval[0] < now_date and interval[1] > now_date):
group = att_obj.browse(cr, uid, interval[2], context=context).group_id.id
date = interval[1]
res_intervals += [(date, group), ]
else:
return [(now_date, None)]
return res_intervals
def _get_previous_dates(self, cr, uid, ids, start_date=False, context=None):
"""
Date should be given in utc
"""
# TDE FIXME: unused context key 'no_round_hours' removed
orderpoint = self.browse(cr, uid, ids, context=context)[0]
calendar_obj = self.pool.get('resource.calendar')
att_obj = self.pool.get('resource.calendar.attendance')
# First check if the orderpoint has a Calendar as it should be delivered at this calendar date
purchase_date = False
delivery_date = start_date
if orderpoint.calendar_id and orderpoint.calendar_id.attendance_ids:
res = calendar_obj._schedule_days(cr, uid, orderpoint.calendar_id.id, -1, start_date, compute_leaves=True, context=context)
if res and res[0][0] < start_date:
group_to_find = res[0][2] and att_obj.browse(cr, uid, res[0][2], context=context).group_id.id or False
delivery_date = res[0][0]
found_date = delivery_date
if orderpoint.purchase_calendar_id and orderpoint.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 = calendar_obj._schedule_days(cr, uid, orderpoint.purchase_calendar_id.id, -1, found_date, compute_leaves=True, context=context)
for re in res:
group = re[2] and att_obj.browse(cr, uid, re[2], context=context).group_id.id or False
found_date = re[0]
if not purchase_date and (group_to_find and group_to_find == group or (not group_to_find)):
purchase_date = re[0]
else:
delivery_date = start_date or datetime.utcnow()
return purchase_date, delivery_date
def _get_next_dates(self, cr, uid, ids, new_date=False, group=False, context=None):
# TDE FIXME: unused context key 'no_round_hours' removed
orderpoint = self.browse(cr, uid, ids, context=context)[0]
calendar_obj = self.pool.get('resource.calendar')
att_obj = self.pool.get('resource.calendar.attendance')
if not new_date:
new_date = datetime.utcnow()
now_date = datetime.utcnow()
# Search first calendar day (without group)
res = calendar_obj._schedule_days(cr, uid, orderpoint.calendar_id.id, 1, new_date, compute_leaves=True, context=context)
att_group = res and res[0][2] and att_obj.browse(cr, uid, res[0][2], context=context).group_id.id or False
#If hours are smaller than the current date, search a day further
if res and res[0][0] < now_date:
new_date = res[0][1] + relativedelta(days=1)
res = calendar_obj._schedule_days(cr, uid, orderpoint.calendar_id.id, 1, new_date, compute_leaves=True, context=context)
for re in res:
att_group = False
if re[2]:
att_group = att_obj.browse(cr, uid, re[2], context=context).group_id.id
if att_group == group:
break
# If you can find an entry and you have a group to match, but it does not, search further until you find one that corresponds
number = 0
while res and group and att_group != group and number < 100:
number += 1
new_date = res[0][1] + relativedelta(days=1)
res = calendar_obj._schedule_days(cr, uid, orderpoint.calendar_id.id, 1, new_date, compute_leaves=True, context=context)
att_group = False
for re in res:
if re[2]:
att_group = att_obj.browse(cr, uid, re[2], context=context).group_id.id
if att_group == group:
break
#number as safety pall for endless loops
if number >= 100:
res = False
# If you found a solution(first date), you need the second date until the next delivery because you need to deliver
# everything needed until the second date on the first date
if res:
date1 = res[0][1]
new_date = res[0][1] + relativedelta(days=1)
res = calendar_obj._schedule_days(cr, uid, orderpoint.calendar_id.id, 1, new_date, compute_leaves=True, context=context)
if res:
return (date1, res[0][1])
return (False, False)