summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenis Ledoux <dle@odoo.com>2014-08-13 12:00:38 +0200
committerDenis Ledoux <dle@odoo.com>2014-08-13 12:00:38 +0200
commitca55a2437444cf3e5231ee8edff9e60049da38ba (patch)
tree86192981695f6db249d279abbf410c6bb95dd88f
parentfe83c11301b1d2449b45701869269837ad9ac0fc (diff)
[FIX] procurement, stock: forward port of bug fix 3609ba10f2d00a608d8f32334ae1b9a25b34f037
-rw-r--r--addons/procurement/procurement.py63
-rw-r--r--addons/stock/procurement.py70
2 files changed, 86 insertions, 47 deletions
diff --git a/addons/procurement/procurement.py b/addons/procurement/procurement.py
index 2ebc800ec04..5a73ef168ec 100644
--- a/addons/procurement/procurement.py
+++ b/addons/procurement/procurement.py
@@ -20,6 +20,7 @@
##############################################################################
import time
+from psycopg2 import OperationalError
from openerp import SUPERUSER_ID
from openerp.osv import fields, osv
@@ -193,31 +194,49 @@ class procurement_order(osv.osv):
def reset_to_confirmed(self, cr, uid, ids, context=None):
return self.write(cr, uid, ids, {'state': 'confirmed'}, context=context)
- def run(self, cr, uid, ids, context=None):
+ def run(self, cr, uid, ids, autocommit=False, context=None):
for procurement_id in ids:
#we intentionnaly do the browse under the for loop to avoid caching all ids which would be ressource greedy
#and useless as we'll make a refresh later that will invalidate all the cache (and thus the next iteration
#will fetch all the ids again)
procurement = self.browse(cr, uid, procurement_id, context=context)
if procurement.state not in ("running", "done"):
- if self._assign(cr, uid, procurement, context=context):
- procurement.refresh()
- res = self._run(cr, uid, procurement, context=context or {})
- if res:
- self.write(cr, uid, [procurement.id], {'state': 'running'}, context=context)
+ try:
+ if self._assign(cr, uid, procurement, context=context):
+ procurement.refresh()
+ res = self._run(cr, uid, procurement, context=context or {})
+ if res:
+ self.write(cr, uid, [procurement.id], {'state': 'running'}, context=context)
+ else:
+ self.write(cr, uid, [procurement.id], {'state': 'exception'}, context=context)
else:
+ self.message_post(cr, uid, [procurement.id], body=_('No rule matching this procurement'), context=context)
self.write(cr, uid, [procurement.id], {'state': 'exception'}, context=context)
- else:
- self.message_post(cr, uid, [procurement.id], body=_('No rule matching this procurement'), context=context)
- self.write(cr, uid, [procurement.id], {'state': 'exception'}, context=context)
+ if autocommit:
+ cr.commit()
+ except OperationalError:
+ if autocommit:
+ cr.rollback()
+ continue
+ else:
+ raise
return True
- def check(self, cr, uid, ids, context=None):
+ def check(self, cr, uid, ids, autocommit=False, context=None):
done_ids = []
for procurement in self.browse(cr, uid, ids, context=context):
- result = self._check(cr, uid, procurement, context=context)
- if result:
- done_ids.append(procurement.id)
+ try:
+ result = self._check(cr, uid, procurement, context=context)
+ if result:
+ done_ids.append(procurement.id)
+ if autocommit:
+ cr.commit()
+ except OperationalError:
+ if autocommit:
+ cr.rollback()
+ continue
+ else:
+ raise
if done_ids:
self.write(cr, uid, done_ids, {'state': 'done'}, context=context)
return done_ids
@@ -288,22 +307,26 @@ class procurement_order(osv.osv):
cr = openerp.registry(cr.dbname).cursor()
# Run confirmed procurements
+ prev_ids = []
while True:
ids = self.search(cr, SUPERUSER_ID, [('state', '=', 'confirmed')], context=context)
- if not ids:
+ if not ids or prev_ids == ids:
break
- self.run(cr, SUPERUSER_ID, ids, context=context)
+ else:
+ prev_ids = ids
+ self.run(cr, SUPERUSER_ID, ids, autocommit=use_new_cursor, context=context)
if use_new_cursor:
cr.commit()
# Check if running procurements are done
- offset = 0
+ prev_ids = []
while True:
- ids = self.search(cr, SUPERUSER_ID, [('state', '=', 'running')], offset=offset, context=context)
- if not ids:
+ ids = self.search(cr, SUPERUSER_ID, [('state', '=', 'running')], context=context)
+ if not ids or prev_ids == ids:
break
- done = self.check(cr, SUPERUSER_ID, ids, context=context)
- offset += len(ids) - len(done)
+ else:
+ prev_ids = ids
+ self.check(cr, SUPERUSER_ID, ids, autocommit=use_new_cursor, context=context)
if use_new_cursor:
cr.commit()
diff --git a/addons/stock/procurement.py b/addons/stock/procurement.py
index f53776d4b9a..d8be63e47e8 100644
--- a/addons/stock/procurement.py
+++ b/addons/stock/procurement.py
@@ -26,6 +26,7 @@ from openerp.tools import DEFAULT_SERVER_DATE_FORMAT, DEFAULT_SERVER_DATETIME_FO
from openerp import SUPERUSER_ID
from dateutil.relativedelta import relativedelta
from datetime import datetime
+from psycopg2 import OperationalError
import openerp
class procurement_group(osv.osv):
@@ -204,8 +205,8 @@ class procurement_order(osv.osv):
return True
return super(procurement_order, self)._run(cr, uid, procurement, context=context)
- def run(self, cr, uid, ids, context=None):
- res = super(procurement_order, self).run(cr, uid, ids, context=context)
+ def run(self, cr, uid, ids, autocommit=False, context=None):
+ res = super(procurement_order, self).run(cr, uid, ids, autocommit=autocommit, context=context)
#after all the procurements are run, check if some created a draft stock move that needs to be confirmed
#(we do that in batch because it fasts the picking assignation and the picking state computation)
move_to_confirm_ids = []
@@ -345,35 +346,50 @@ class procurement_order(osv.osv):
orderpoint_obj = self.pool.get('stock.warehouse.orderpoint')
procurement_obj = self.pool.get('procurement.order')
- offset = 0
- ids = [1]
- while ids:
- ids = orderpoint_obj.search(cr, uid, [('company_id', '=', company_id)], offset=offset, limit=100)
+ orderpoint_ids = orderpoint_obj.search(cr, uid, [('company_id', '=', company_id)])
+ prev_ids = []
+ while orderpoint_ids:
+ ids = orderpoint_ids[:100]
+ del orderpoint_ids[:100]
for op in orderpoint_obj.browse(cr, uid, ids, context=context):
- prods = self._product_virtual_get(cr, uid, op)
- if prods is None:
- continue
- if prods < op.product_min_qty:
- qty = max(op.product_min_qty, op.product_max_qty) - prods
-
- reste = qty % op.qty_multiple
- if reste > 0:
- qty += op.qty_multiple - reste
-
- if qty <= 0:
+ try:
+ prods = self._product_virtual_get(cr, uid, op)
+ if prods is None:
continue
-
- qty -= orderpoint_obj.subtract_procurements(cr, uid, op, context=context)
-
- if qty > 0:
- proc_id = procurement_obj.create(cr, uid,
- self._prepare_orderpoint_procurement(cr, uid, op, qty, context=context),
- context=context)
- self.check(cr, uid, [proc_id])
- self.run(cr, uid, [proc_id])
- offset += len(ids)
+ if prods < op.product_min_qty:
+ qty = max(op.product_min_qty, op.product_max_qty) - prods
+
+ reste = qty % op.qty_multiple
+ if reste > 0:
+ qty += op.qty_multiple - reste
+
+ if qty <= 0:
+ continue
+
+ qty -= orderpoint_obj.subtract_procurements(cr, uid, op, context=context)
+
+ if qty > 0:
+ proc_id = procurement_obj.create(cr, uid,
+ self._prepare_orderpoint_procurement(cr, uid, op, qty, context=context),
+ context=context)
+ self.check(cr, uid, [proc_id])
+ self.run(cr, uid, [proc_id])
+ if use_new_cursor:
+ cr.commit()
+ except OperationalError:
+ if use_new_cursor:
+ orderpoint_ids.append(op.id)
+ cr.rollback()
+ continue
+ else:
+ raise
if use_new_cursor:
cr.commit()
+ if prev_ids == ids:
+ break
+ else:
+ prev_ids = ids
+
if use_new_cursor:
cr.commit()
cr.close()