[FIX] procurement: refactor scheduler so it continues even if a procurement failed

If the mrp scheduler fails during the treatment of a procurement (due to a postgresql error, like an update lock), we let it try the other procurements, instead of stopping at the first procurement which fails.
Besides, we retry to treat the procurements which failed, until the list of the remaining procurements is always the same (meaning something is wrong and block the procurements treatment).
This commit is contained in:
Denis Ledoux 2014-08-12 11:02:15 +02:00
parent 3632949cff
commit 3609ba10f2
1 changed files with 86 additions and 82 deletions

View File

@ -28,6 +28,7 @@ from openerp.osv import fields
from openerp.tools.translate import _ from openerp.tools.translate import _
from openerp.tools import DEFAULT_SERVER_DATE_FORMAT, DEFAULT_SERVER_DATETIME_FORMAT from openerp.tools import DEFAULT_SERVER_DATE_FORMAT, DEFAULT_SERVER_DATETIME_FORMAT
from openerp import tools from openerp import tools
from psycopg2 import OperationalError
class procurement_order(osv.osv): class procurement_order(osv.osv):
_inherit = 'procurement.order' _inherit = 'procurement.order'
@ -70,56 +71,45 @@ class procurement_order(osv.osv):
cr.commit() cr.commit()
company = self.pool.get('res.users').browse(cr, uid, uid, context=context).company_id company = self.pool.get('res.users').browse(cr, uid, uid, context=context).company_id
maxdate = (datetime.today() + relativedelta(days=company.schedule_range)).strftime(tools.DEFAULT_SERVER_DATE_FORMAT) maxdate = (datetime.today() + relativedelta(days=company.schedule_range)).strftime(tools.DEFAULT_SERVER_DATE_FORMAT)
start_date = fields.datetime.now() prev_ids = []
offset = 0
report = []
report_total = 0
report_except = 0
report_later = 0
while True: while True:
ids = procurement_obj.search(cr, uid, [('state', '=', 'confirmed'), ('procure_method', '=', 'make_to_order')], offset=offset, limit=500, order='priority, date_planned', context=context) ids = procurement_obj.search(cr, uid, [('state', '=', 'confirmed'), ('procure_method', '=', 'make_to_order'), ('date_planned', '<', maxdate)], limit=500, order='priority, date_planned', context=context)
for proc in procurement_obj.browse(cr, uid, ids, context=context): for proc in procurement_obj.browse(cr, uid, ids, context=context):
if maxdate >= proc.date_planned: try:
wf_service.trg_validate(uid, 'procurement.order', proc.id, 'button_check', cr) wf_service.trg_validate(uid, 'procurement.order', proc.id, 'button_check', cr)
else:
offset += 1
report_later += 1
if proc.state == 'exception':
report.append(_('PROC %d: on order - %3.2f %-5s - %s') % \
(proc.id, proc.product_qty, proc.product_uom.name,
proc.product_id.name))
report_except += 1
report_total += 1
if use_new_cursor: if use_new_cursor:
cr.commit() cr.commit()
if not ids: except OperationalError:
if use_new_cursor:
cr.rollback()
continue
else:
raise
if not ids or prev_ids == ids:
break break
offset = 0
ids = []
while True:
report_ids = []
ids = procurement_obj.search(cr, uid, [('state', '=', 'confirmed'), ('procure_method', '=', 'make_to_stock')], offset=offset)
for proc in procurement_obj.browse(cr, uid, ids):
if maxdate >= proc.date_planned:
wf_service.trg_validate(uid, 'procurement.order', proc.id, 'button_check', cr)
report_ids.append(proc.id)
else: else:
report_later += 1 prev_ids = ids
report_total += 1 ids = []
prev_ids = []
if proc.state == 'exception': while True:
report.append(_('PROC %d: from stock - %3.2f %-5s - %s') % \ ids = procurement_obj.search(cr, uid, [('state', '=', 'confirmed'), ('procure_method', '=', 'make_to_stock'), ('date_planned', '<', maxdate)], limit=500)
(proc.id, proc.product_qty, proc.product_uom.name, for proc in procurement_obj.browse(cr, uid, ids):
proc.product_id.name,)) try:
report_except += 1 wf_service.trg_validate(uid, 'procurement.order', proc.id, 'button_check', cr)
if use_new_cursor: if use_new_cursor:
cr.commit() cr.commit()
offset += len(ids) except OperationalError:
if not ids: break if use_new_cursor:
end_date = fields.datetime.now() cr.rollback()
continue
else:
raise
if not ids or prev_ids == ids:
break
else:
prev_ids = ids
if use_new_cursor: if use_new_cursor:
cr.commit() cr.commit()
@ -228,13 +218,16 @@ class procurement_order(osv.osv):
procurement_obj = self.pool.get('procurement.order') procurement_obj = self.pool.get('procurement.order')
wf_service = netsvc.LocalService("workflow") wf_service = netsvc.LocalService("workflow")
offset = 0
ids = [1] ids = [1]
prev_ids = []
if automatic: if automatic:
self.create_automatic_op(cr, uid, context=context) self.create_automatic_op(cr, uid, context=context)
while ids: orderpoint_ids = orderpoint_obj.search(cr, uid, [])
ids = orderpoint_obj.search(cr, uid, [], offset=offset, limit=100) while orderpoint_ids:
ids = orderpoint_ids[:100]
del orderpoint_ids[:100]
for op in orderpoint_obj.browse(cr, uid, ids, context=context): for op in orderpoint_obj.browse(cr, uid, ids, context=context):
try:
prods = self._product_virtual_get(cr, uid, op) prods = self._product_virtual_get(cr, uid, op)
if prods is None: if prods is None:
continue continue
@ -273,9 +266,20 @@ class procurement_order(osv.osv):
'button_check', cr) 'button_check', cr)
orderpoint_obj.write(cr, uid, [op.id], orderpoint_obj.write(cr, uid, [op.id],
{'procurement_id': proc_id}, context=context) {'procurement_id': proc_id}, context=context)
offset += len(ids)
if use_new_cursor: if use_new_cursor:
cr.commit() cr.commit()
except OperationalError:
if use_new_cursor:
orderpoint_ids.append(op.id)
cr.rollback()
continue
else:
raise
if prev_ids == ids:
break
else:
prev_ids = ids
if use_new_cursor: if use_new_cursor:
cr.commit() cr.commit()
cr.close() cr.close()