From 43db7267c5051c9ad4877c27ce1220d446d7552d Mon Sep 17 00:00:00 2001 From: Mohammad Alhashash Date: Tue, 21 Oct 2014 21:12:58 +0200 Subject: [PATCH] [FIX] stock: UoS quantity in stock.picking Implements the UoS TODO items on stock.picking.do_partial() to fix #1432. Add a new method _compute_uos_qty() on product.product to computes product's invoicing quantity in UoS from quantity in UoM. The created invoice will use the product_uos of the stock.move, meaning keeping the quantity specified on the partial picking and the unit of measure of the original stock.move (e.g. recieving 1 dozen from a 12 unit picking should either get uos=dozen, uos_qty=1 or uos=unit, uos_qty=12, not a mix of both) Fixes #1432, opw 611479 --- addons/product/product.py | 28 ++++++++++++++++++++++++++++ addons/stock/stock.py | 9 +++++---- 2 files changed, 33 insertions(+), 4 deletions(-) diff --git a/addons/product/product.py b/addons/product/product.py index ff0a6a770d7..ac0de1d2fec 100644 --- a/addons/product/product.py +++ b/addons/product/product.py @@ -770,6 +770,34 @@ class product_product(osv.osv): args.append((('categ_id', 'child_of', context['search_default_categ_id']))) return super(product_product, self).search(cr, uid, args, offset=offset, limit=limit, order=order, context=context, count=count) + def _compute_uos_qty(self, cr, uid, ids, uom, qty, uos, context=None): + ''' + Computes product's invoicing quantity in UoS from quantity in UoM. + Takes into account the + :param uom: Source unit + :param qty: Source quantity + :param uos: Target UoS unit. + ''' + if not uom or not qty or not uos: + return qty + uom_obj = self.pool['product.uom'] + product_id = ids[0] if isinstance(ids, (list, tuple)) else ids + product = self.browse(cr, uid, product_id, context=context) + if isinstance(uos, (int, long)): + uos = uom_obj.browse(cr, uid, uos, context=context) + if isinstance(uom, (int, long)): + uom = uom_obj.browse(cr, uid, uom, context=context) + if product.uos_id: # Product has UoS defined + # We cannot convert directly between units even if the units are of the same category + # as we need to apply the conversion coefficient which is valid only between quantities + # in product's default UoM/UoS + qty_default_uom = uom_obj._compute_qty_obj(cr, uid, uom, qty, product.uom_id) # qty in product's default UoM + qty_default_uos = qty_default_uom * product.uos_coeff + return uom_obj._compute_qty_obj(cr, uid, product.uos_id, qty_default_uos, uos) + else: + return uom_obj._compute_qty_obj(cr, uid, uom, qty, uos) + + product_product() class product_packaging(osv.osv): diff --git a/addons/stock/stock.py b/addons/stock/stock.py index f117bdbc27d..644dae4ddf9 100644 --- a/addons/stock/stock.py +++ b/addons/stock/stock.py @@ -1241,7 +1241,7 @@ class stock_picking(osv.osv): for pick in self.browse(cr, uid, ids, context=context): new_picking = None complete, too_many, too_few = [], [], [] - move_product_qty, prodlot_ids, product_avail, partial_qty, product_uoms = {}, {}, {}, {}, {} + move_product_qty, prodlot_ids, product_avail, partial_qty, uos_qty, product_uoms = {}, {}, {}, {}, {}, {} for move in pick.move_lines: if move.state in ('done', 'cancel'): continue @@ -1255,6 +1255,7 @@ class stock_picking(osv.osv): prodlot_ids[move.id] = prodlot_id product_uoms[move.id] = product_uom partial_qty[move.id] = uom_obj._compute_qty(cr, uid, product_uoms[move.id], product_qty, move.product_uom.id) + uos_qty[move.id] = move.product_id._compute_uos_qty(product_uom, product_qty, move.product_uos) if product_qty else 0.0 if move.product_qty == partial_qty[move.id]: complete.append(move) elif move.product_qty > partial_qty[move.id]: @@ -1318,7 +1319,7 @@ class stock_picking(osv.osv): if product_qty != 0: defaults = { 'product_qty' : product_qty, - 'product_uos_qty': product_qty, #TODO: put correct uos_qty + 'product_uos_qty': uos_qty[move.id], 'picking_id' : new_picking, 'state': 'assigned', 'move_dest_id': False, @@ -1332,7 +1333,7 @@ class stock_picking(osv.osv): move_obj.write(cr, uid, [move.id], { 'product_qty': move.product_qty - partial_qty[move.id], - 'product_uos_qty': move.product_qty - partial_qty[move.id], #TODO: put correct uos_qty + 'product_uos_qty': move.product_uos_qty - uos_qty[move.id], 'prodlot_id': False, 'tracking_id': False, }) @@ -1348,7 +1349,7 @@ class stock_picking(osv.osv): product_qty = move_product_qty[move.id] defaults = { 'product_qty' : product_qty, - 'product_uos_qty': product_qty, #TODO: put correct uos_qty + 'product_uos_qty': uos_qty[move.id], 'product_uom': product_uoms[move.id] } prodlot_id = prodlot_ids.get(move.id)