[FIX] stock: immediate transfer
Create an immediate transfer for a receipt, add a move, set a quantity
done and due to rev[0], an initial demand is set, then
_autoconfirm_picking is called and action_confirm of picking calls
_action_assign if the location source bypasses the reservation. Set
again an inferior qty_done, the initial demand is also updated due to
rev[0] and somehow the system tries to write on a now unlinked move
line.
fixes
- never reserve an immediate transfer
- never update the initial demand if the move is reserved to fix the
existing databases.
- adapt _compute_state so that immediate transfer moves considered
reserved so that they're always "ready"
- adapt the test that was working on an immediate transfer picking and
setting the initial demand while it's not possible through the
interface, the user can only set the done quantity.
[0] 8303b1a
closes odoo/odoo#45317
X-original-commit: 357e0a862744f1bc23a9643a1822d2ee4a2eb7a2
Signed-off-by: Simon Lejeune (sle) <sle@openerp.com>
This commit is contained in:
@@ -347,7 +347,8 @@ class StockMoveLine(models.Model):
|
||||
# done stock move should have its `quantity_done` equals to its `product_uom_qty`, and
|
||||
# this is what move's `action_done` will do. So, we replicate the behavior here.
|
||||
if updates or 'qty_done' in vals:
|
||||
moves = self.filtered(lambda ml: ml.move_id.state == 'done' or ml.move_id.picking_id and ml.move_id.picking_id.immediate_transfer).mapped('move_id')
|
||||
moves = self.filtered(lambda ml: ml.move_id.state == 'done').mapped('move_id')
|
||||
moves |= self.filtered(lambda ml: ml.move_id.state not in ('done', 'cancel') and ml.move_id.picking_id.immediate_transfer and not ml.product_uom_qty).mapped('move_id')
|
||||
for move in moves:
|
||||
move.product_uom_qty = move.quantity_done
|
||||
next_moves._do_unreserve()
|
||||
|
||||
@@ -427,7 +427,7 @@ class Picking(models.Model):
|
||||
]
|
||||
})
|
||||
|
||||
@api.depends('move_type', 'move_lines.state', 'move_lines.picking_id')
|
||||
@api.depends('move_type', 'immediate_transfer', 'move_lines.state', 'move_lines.picking_id')
|
||||
def _compute_state(self):
|
||||
''' State of a picking depends on the state of its related stock.move
|
||||
- Draft: only used for "planned pickings"
|
||||
@@ -452,7 +452,9 @@ class Picking(models.Model):
|
||||
picking.state = 'done'
|
||||
else:
|
||||
relevant_move_state = picking.move_lines._get_relevant_state_among_moves()
|
||||
if relevant_move_state == 'partially_available':
|
||||
if picking.immediate_transfer and relevant_move_state not in ('draft', 'cancel', 'done'):
|
||||
picking.state = 'assigned'
|
||||
elif relevant_move_state == 'partially_available':
|
||||
picking.state = 'assigned'
|
||||
else:
|
||||
picking.state = relevant_move_state
|
||||
@@ -656,7 +658,7 @@ class Picking(models.Model):
|
||||
.filtered(lambda move: move.state == 'draft')\
|
||||
._action_confirm()
|
||||
# call `_action_assign` on every confirmed move which location_id bypasses the reservation
|
||||
self.filtered(lambda picking: picking.location_id.usage in ('supplier', 'inventory', 'production') and picking.state == 'confirmed')\
|
||||
self.filtered(lambda picking: not picking.immediate_transfer and picking.location_id.usage in ('supplier', 'inventory', 'production') and picking.state == 'confirmed')\
|
||||
.mapped('move_lines')._action_assign()
|
||||
return True
|
||||
|
||||
|
||||
@@ -88,8 +88,8 @@ SELECT
|
||||
ELSE date::date - interval '1 day'
|
||||
END, '1 day'::interval)::date date,
|
||||
CASE
|
||||
WHEN (whs.id IS NOT NULL AND whd.id IS NULL) OR ls.usage = 'transit' AND m.state = 'done' THEN product_qty
|
||||
WHEN (whs.id IS NULL AND whd.id IS NOT NULL) OR ld.usage = 'transit' AND m.state = 'done' THEN -product_qty
|
||||
WHEN ((whs.id IS NOT NULL AND whd.id IS NULL) OR ls.usage = 'transit') AND m.state = 'done' THEN product_qty
|
||||
WHEN ((whs.id IS NULL AND whd.id IS NOT NULL) OR ld.usage = 'transit') AND m.state = 'done' THEN -product_qty
|
||||
WHEN (whs.id IS NOT NULL AND whd.id IS NULL) OR ls.usage = 'transit' THEN -product_qty
|
||||
WHEN (whs.id IS NULL AND whd.id IS NOT NULL) OR ld.usage = 'transit' THEN product_qty
|
||||
END AS product_qty,
|
||||
|
||||
@@ -4277,12 +4277,12 @@ class StockMove(SavepointCase):
|
||||
'location_dest_id': self.stock_location.id,
|
||||
'product_id': self.product.id,
|
||||
'product_uom': self.uom_unit.id,
|
||||
'product_uom_qty': 10.0,
|
||||
'quantity_done': 10.0,
|
||||
'picking_id': picking.id,
|
||||
})
|
||||
picking._autoconfirm_picking()
|
||||
self.assertEqual(picking.state, 'assigned')
|
||||
move1.product_uom_qty = 12
|
||||
move1.quantity_done = 12
|
||||
self.assertEqual(picking.state, 'assigned')
|
||||
|
||||
def test_initial_demand_4(self):
|
||||
|
||||
Reference in New Issue
Block a user