[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
This commit is contained in:
parent
f4870f8418
commit
43db7267c5
|
@ -770,6 +770,34 @@ class product_product(osv.osv):
|
||||||
args.append((('categ_id', 'child_of', context['search_default_categ_id'])))
|
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)
|
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()
|
product_product()
|
||||||
|
|
||||||
class product_packaging(osv.osv):
|
class product_packaging(osv.osv):
|
||||||
|
|
|
@ -1241,7 +1241,7 @@ class stock_picking(osv.osv):
|
||||||
for pick in self.browse(cr, uid, ids, context=context):
|
for pick in self.browse(cr, uid, ids, context=context):
|
||||||
new_picking = None
|
new_picking = None
|
||||||
complete, too_many, too_few = [], [], []
|
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:
|
for move in pick.move_lines:
|
||||||
if move.state in ('done', 'cancel'):
|
if move.state in ('done', 'cancel'):
|
||||||
continue
|
continue
|
||||||
|
@ -1255,6 +1255,7 @@ class stock_picking(osv.osv):
|
||||||
prodlot_ids[move.id] = prodlot_id
|
prodlot_ids[move.id] = prodlot_id
|
||||||
product_uoms[move.id] = product_uom
|
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)
|
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]:
|
if move.product_qty == partial_qty[move.id]:
|
||||||
complete.append(move)
|
complete.append(move)
|
||||||
elif move.product_qty > partial_qty[move.id]:
|
elif move.product_qty > partial_qty[move.id]:
|
||||||
|
@ -1318,7 +1319,7 @@ class stock_picking(osv.osv):
|
||||||
if product_qty != 0:
|
if product_qty != 0:
|
||||||
defaults = {
|
defaults = {
|
||||||
'product_qty' : product_qty,
|
'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,
|
'picking_id' : new_picking,
|
||||||
'state': 'assigned',
|
'state': 'assigned',
|
||||||
'move_dest_id': False,
|
'move_dest_id': False,
|
||||||
|
@ -1332,7 +1333,7 @@ class stock_picking(osv.osv):
|
||||||
move_obj.write(cr, uid, [move.id],
|
move_obj.write(cr, uid, [move.id],
|
||||||
{
|
{
|
||||||
'product_qty': move.product_qty - partial_qty[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,
|
'prodlot_id': False,
|
||||||
'tracking_id': False,
|
'tracking_id': False,
|
||||||
})
|
})
|
||||||
|
@ -1348,7 +1349,7 @@ class stock_picking(osv.osv):
|
||||||
product_qty = move_product_qty[move.id]
|
product_qty = move_product_qty[move.id]
|
||||||
defaults = {
|
defaults = {
|
||||||
'product_qty' : product_qty,
|
'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]
|
'product_uom': product_uoms[move.id]
|
||||||
}
|
}
|
||||||
prodlot_id = prodlot_ids.get(move.id)
|
prodlot_id = prodlot_ids.get(move.id)
|
||||||
|
|
Loading…
Reference in New Issue