From c5fbcf4fd21674b1a81b549c4ff55a1e34c97763 Mon Sep 17 00:00:00 2001 From: "Quentin (OpenERP)" Date: Fri, 11 Oct 2013 16:28:27 +0200 Subject: [PATCH] [IMP] stock: attempt to get rid of the server patch to order by an more complex expression than currently allowed by the server (which we would like to keep to restraint the developpers to stay on a clean and safe implementation) bzr revid: qdp-launchpad@openerp.com-20131011142827-vwv6q9luq4d441zh --- addons/stock/stock.py | 80 ++++++++++++++++++++++--------------------- 1 file changed, 41 insertions(+), 39 deletions(-) diff --git a/addons/stock/stock.py b/addons/stock/stock.py index 9888092f708..9b8ce6db5f9 100644 --- a/addons/stock/stock.py +++ b/addons/stock/stock.py @@ -24,7 +24,7 @@ from dateutil import relativedelta import time -from openerp.osv import fields, osv, orm +from openerp.osv import fields, osv from openerp.tools.translate import _ from openerp import tools from openerp.tools import DEFAULT_SERVER_DATETIME_FORMAT @@ -34,7 +34,6 @@ import logging _logger = logging.getLogger(__name__) - #---------------------------------------------------------- # Incoterms #---------------------------------------------------------- @@ -205,12 +204,6 @@ class stock_quant(osv.osv): 'company_id': lambda self, cr, uid, c: self.pool.get('res.company')._company_default_get(cr, uid, 'stock.quant', context=c), } - def _check_qorder(self, word): - """ - Needs to pass True to allow "expression order" in search - """ - return True - def quants_reserve(self, cr, uid, quants, move, context=None): toreserve = [] for quant,qty in quants: @@ -246,7 +239,25 @@ class stock_quant(osv.osv): quant.refresh() return quant - def quants_get(self, cr, uid, location, product, qty, domain=None, prefered_order=False, reservedcontext=None, restrict_lot_id=False, restrict_partner_id=False, context=None): + def quants_get_prefered_domain(self, cr, uid, location, product, qty, domain=None, prefered_domain=False, fallback_domain=False, restrict_lot_id=False, restrict_partner_id=False, context=None): + if prefered_domain and fallback_domain: + if domain is None: + domain = [] + quants = self.quants_get(cr, uid, location, product, qty, domain=domain + prefered_domain, context=context) + res_qty = qty + for quant in quants: + if quant[0]: + res_qty -= quant[1] + if res_qty > 0: + #try to replace the last tuple (None, res_qty) with something that wasn't chosen at first because of the prefered order + quants.pop() + unprefered_quants = self.quants_get(cr, uid, location, product, res_qty, domain=domain + fallback_domain, context=context) + for quant in unprefered_quants: + quants.append(quant) + return quants + return self.quants_get(cr, uid, location, product, qty, domain=domain, restrict_lot_id=restrict_lot_id, restrict_partner_id=restrict_partner_id, context=context) + + def quants_get(self, cr, uid, location, product, qty, domain=None, restrict_lot_id=False, restrict_partner_id=False, context=None): """ Use the removal strategies of product to search for the correct quants If you inherit, put the super at the end of your method. @@ -265,9 +276,9 @@ class stock_quant(osv.osv): if location: removal_strategy = self.pool.get('stock.location').get_removal_strategy(cr, uid, location, product, context=context) or 'fifo' if removal_strategy == 'fifo': - result += self._quants_get_fifo(cr, uid, location, product, qty, domain, prefered_order=prefered_order, context=context) + result += self._quants_get_fifo(cr, uid, location, product, qty, domain, context=context) elif removal_strategy == 'lifo': - result += self._quants_get_lifo(cr, uid, location, product, qty, domain, prefered_order=prefered_order, context=context) + result += self._quants_get_lifo(cr, uid, location, product, qty, domain, context=context) else: raise osv.except_osv(_('Error!'), _('Removal strategy %s not implemented.' % (removal_strategy,))) return result @@ -423,7 +434,7 @@ class stock_quant(osv.osv): # def _quants_get_order(self, cr, uid, location, product, quantity, domain=[], orderby='in_date', context=None): domain += location and [('location_id', 'child_of', location.id)] or [] - domain += [('product_id','=',product.id)] + domain + domain += [('product_id', '=', product.id)] + domain res = [] offset = 0 while quantity > 0: @@ -442,16 +453,12 @@ class stock_quant(osv.osv): offset += 10 return res - def _quants_get_fifo(self, cr, uid, location, product, quantity, domain=[], prefered_order=False,context=None): + def _quants_get_fifo(self, cr, uid, location, product, quantity, domain=[], context=None): order = 'in_date' - if prefered_order: - order = prefered_order + ', in_date' return self._quants_get_order(cr, uid, location, product, quantity, domain, order, context=context) - def _quants_get_lifo(self, cr, uid, location, product, quantity, domain=[], prefered_order=False, context=None): + def _quants_get_lifo(self, cr, uid, location, product, quantity, domain=[], context=None): order = 'in_date desc' - if prefered_order: - order = prefered_order + ', in_date desc' return self._quants_get_order(cr, uid, location, product, quantity, domain, order, context=context) # Return the company owning the location if any @@ -840,9 +847,9 @@ class stock_picking(osv.osv): for picking in self.browse(cr, uid, picking_ids, context=context): for move in picking.move_lines: ids_to_free += [quant.id for quant in move.reserved_quant_ids] - if ids_to_free: - quant_obj.write(cr, uid, ids_to_free, {'reservation_id' : False, 'reservation_op_id': False }, context = context) - + if ids_to_free: + quant_obj.write(cr, uid, ids_to_free, {'reservation_id': False, 'reservation_op_id': False}, context=context) + def _reserve_quants_ops_move(self, cr, uid, ops, move, qty, create=False, context=None): """ Will return the quantity that could not be reserved @@ -851,26 +858,25 @@ class stock_picking(osv.osv): op_obj = self.pool.get("stock.pack.operation") if create and move.location_id.usage != 'internal': # Create quants - quant = quant_obj._quant_create(cr, uid, qty, move, lot_id = ops.lot_id and ops.lot_id.id or False, owner_id = ops.owner_id and ops.owner_id.id or False, context=context) + quant = quant_obj._quant_create(cr, uid, qty, move, lot_id=ops.lot_id and ops.lot_id.id or False, owner_id=ops.owner_id and ops.owner_id.id or False, context=context) #TODO: location_id -> force location? quant.write({'reservation_op_id': ops.id, 'location_id': move.location_id.id}) quant_obj.quants_reserve(cr, uid, [(quant, qty)], move, context=context) return 0 else: #Quants get - prefered_order = "reservation_id IS NOT NULL" #TODO: reservation_id as such might work + #prefered_order = "reservation_id IS NOT NULL" #TODO: reservation_id as such might work dom = op_obj._get_domain(cr, uid, ops, context=context) dom = dom + [('reservation_id', 'not in', [x.id for x in move.picking_id.move_lines])] - quants = quant_obj.quants_get(cr, uid, move.location_id, move.product_id, qty, domain=dom, prefered_order=prefered_order, context=context) + quants = quant_obj.quants_get_prefered_domain(cr, uid, move.location_id, move.product_id, qty, domain=dom, prefered_domain=[('reservation_id', '=', False)], fallback_domain=[('reservation_id', '!=', False)], context=context) res_qty = qty for quant in quants: - if quant[0]: #If quant can be reserved + if quant[0]: # If quant can be reserved res_qty -= quant[1] quant_obj.quants_reserve(cr, uid, quants, move, context=context) quant_obj.write(cr, uid, [x[0].id for x in quants if x[0]], {'reservation_op_id': ops.id}, context=context) return res_qty - - + def rereserve(self, cr, uid, picking_ids, create=False, context=None): """ This will unreserve all products and reserve the quants from the operations again @@ -880,11 +886,8 @@ class stock_picking(osv.osv): resneg: the negative quants to be created: resneg[move][ops] gives negative quant to be created tuple of dictionary with quantities of quant operation and product that can not be matched between ops and moves and dictionary with remaining values on moves - """ quant_obj = self.pool.get("stock.quant") - move_obj = self.pool.get("stock.move") - op_obj = self.pool.get("stock.pack.operation") pack_obj = self.pool.get("stock.quant.package") res = {} # Qty still to do from ops res2 = {} #what is left from moves @@ -1608,7 +1611,9 @@ class stock_move(osv.osv): dp.append(str(q.id)) qty -= q.qty domain = ['|', ('reservation_id', '=', False), ('reservation_id', '=', move.id), ('qty', '>', 0)] - quants = quant_obj.quants_get(cr, uid, move.location_id, move.product_id, qty, domain=domain, prefered_order = dp and ('id not in ('+','.join(dp)+')') or False, restrict_lot_id=move.restrict_lot_id.id, restrict_partner_id=move.restrict_partner_id.id, context=context) + prefered_domain = dp and [('id', 'not in', dp)] or [] + fallback_domain = dp and [('id', 'in', dp)] or [] + quants = quant_obj.quants_get_prefered_domain(cr, uid, move.location_id, move.product_id, qty, domain=domain, prefered_domain=prefered_domain, fallback_domain=fallback_domain, restrict_lot_id=move.restrict_lot_id.id, restrict_partner_id=move.restrict_partner_id.id, context=context) #Will only reserve physical quants, no negative quant_obj.quants_reserve(cr, uid, quants, move, context=context) # the total quantity is provided by existing quants @@ -1679,14 +1684,11 @@ class stock_move(osv.osv): # quants = quant_obj.quants_get(cr, uid, move.location_id, move.product_id, qty, context=context) # quant_obj.quants_move(cr, uid, quants, move, location_dest_id, context=context) # should replace the above 2 lines - dom = ['|', ('reservation_id', '=', False), ('reservation_id', '=', move.id), ('qty', '>', 0)] - prefered_order = 'reservation_id' -# if lot_id: -# prefered_order = 'lot_id<>' + lot_id + ", " + prefered_order -# if pack_id: -# prefered_order = 'pack_id<>' + pack_id + ", " + prefered_order + dom = [('qty', '>', 0)] + prefered_domain = [('reservation_id', '=', move.id)] + fallback_domain = [('reservation_id', '=', False)] if move.picking_id and move.picking_id.pack_operation_ids: - quants = quant_obj.quants_get(cr, uid, move.location_id, move.product_id, qty - move.remaining_qty, domain=dom, prefered_order = prefered_order, context=context) + quants = quant_obj.quants_get_prefered_domain(cr, uid, move.location_id, move.product_id, qty - move.remaining_qty, domain=dom, prefered_domain=prefered_domain, fallback_domain=fallback_domain, context=context) quant_obj.quants_move(cr, uid, quants, move, context=context) for negative_op in negatives[move.id].keys(): ops = ops_obj.browse(cr, uid, negative_op, context=context) @@ -1702,7 +1704,7 @@ class stock_move(osv.osv): else: pack_obj.write(cr, uid, [ops.package_id.id], {'parent_id': ops.result_package_id and ops.result_package_id.id or False}, context=context) else: - quants = quant_obj.quants_get(cr, uid, move.location_id, move.product_id, qty, domain=dom, prefered_order=prefered_order, context=context) + quants = quant_obj.quants_get_prefered_domain(cr, uid, move.location_id, move.product_id, qty, domain=dom, prefered_domain=prefered_domain, fallback_domain=fallback_domain, context=context) #Will move all quants_get and as such create negative quants quant_obj.quants_move(cr, uid, quants, move, context=context) quant_obj.quants_unreserve(cr, uid, move, context=context)