[FIX] stock: exclude not-picked mls at validation
Requires barcode to be installed to reproduce (or customization of view/direct shell manipulation) Steps to reproduce: - create a SN tracked product with 2 serial numbers - setup a delivery with a demand of 1 of the SN tracked product - open the delivery in barcode - scan the product then scan the not reserved SN - validate Expected result: Only the scanned SN is marked as done Actual result: Both SNs are marked as done and the move quantity = 2 Issue is due to the code expecting all mls of a "picked" move to be processed as done. Typically when this flow is done in the backend, the user can see that they need to set the not used SN quantity to 0, but this is not the case in barcode. Therefore since barcode will mark the scanned SN ml as "picked", but not the other (reserved, but not scanned) SN, we check at time of picking validation whether or not all of the mls are marked as "picked" and if now, only count the ones that are marked. Note that same issue can occur when multi-location quants and non-reserved loc quantities are scanned. closes odoo/odoo#141210 Related: odoo/enterprise#50274 Signed-off-by: William Henrotin (whe) <whe@odoo.com>
This commit is contained in:
@@ -1509,6 +1509,18 @@ Please change the quantity done or the rounding precision of your unit of measur
|
||||
location = forced_location or self.location_id
|
||||
return location.should_bypass_reservation() or self.product_id.type != 'product'
|
||||
|
||||
def _get_picked_quantity(self):
|
||||
self.ensure_one()
|
||||
if self.picked and any(not ml.picked for ml in self.move_line_ids):
|
||||
picked_qty = 0
|
||||
for ml in self.move_line_ids:
|
||||
if not ml.picked:
|
||||
continue
|
||||
picked_qty += ml.product_uom_id._compute_quantity(ml.quantity, self.product_uom, round=False)
|
||||
return picked_qty
|
||||
else:
|
||||
return self.quantity
|
||||
|
||||
# necessary hook to be able to override move reservation to a restrict lot, owner, pack, location...
|
||||
def _get_available_quantity(self, location_id, lot_id=None, package_id=None, owner_id=None, strict=False, allow_negative=False):
|
||||
self.ensure_one()
|
||||
@@ -1796,10 +1808,16 @@ Please change the quantity done or the rounding precision of your unit of measur
|
||||
|
||||
# Cancel moves where necessary ; we should do it before creating the extra moves because
|
||||
# this operation could trigger a merge of moves.
|
||||
ml_ids_to_unlink = OrderedSet()
|
||||
for move in moves:
|
||||
if move.picked:
|
||||
# in theory, we should only have a mix of picked and non-picked mls in the barcode use case
|
||||
# where non-scanned mls = not picked => we definitely don't want to validate them
|
||||
ml_ids_to_unlink |= move.move_line_ids.filtered(lambda ml: not ml.picked).ids
|
||||
if (move.quantity <= 0 or not move.picked) and not move.is_inventory:
|
||||
if float_compare(move.product_uom_qty, 0.0, precision_rounding=move.product_uom.rounding) == 0 or cancel_backorder:
|
||||
move._action_cancel()
|
||||
self.env['stock.move.line'].browse(ml_ids_to_unlink).unlink()
|
||||
|
||||
# Create extra moves where necessary
|
||||
for move in moves:
|
||||
|
||||
@@ -1220,8 +1220,8 @@ class Picking(models.Model):
|
||||
if picking.picking_type_id.create_backorder != 'ask':
|
||||
continue
|
||||
if any(
|
||||
float_compare(move.quantity, move.product_uom_qty, precision_digits=prec) < 0 or
|
||||
(move.product_uom_qty and not move.picked)
|
||||
(move.product_uom_qty and not move.picked) or
|
||||
float_compare(move._get_picked_quantity(), move.product_uom_qty, precision_digits=prec) < 0
|
||||
for move in picking.move_ids
|
||||
if move.state != 'cancel'
|
||||
):
|
||||
|
||||
@@ -41,10 +41,11 @@ class StockBackorderConfirmation(models.TransientModel):
|
||||
for pick_id in pickings:
|
||||
moves_to_log = {}
|
||||
for move in pick_id.move_ids:
|
||||
picked_qty = move._get_picked_quantity()
|
||||
if float_compare(move.product_uom_qty,
|
||||
move.quantity,
|
||||
picked_qty,
|
||||
precision_rounding=move.product_uom.rounding) > 0:
|
||||
moves_to_log[move] = (move.quantity, move.product_uom_qty)
|
||||
moves_to_log[move] = (picked_qty, move.product_uom_qty)
|
||||
if moves_to_log:
|
||||
pick_id._log_less_quantities_than_expected(moves_to_log)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user