Skip to content

Commit c52f12d

Browse files
committed
[FIX] stock: Fix neg_moves with location_dest taken from rule
Steps to reproduce: - Install Sales and Stock - Activate the multi-step routes setting - Go to a Delivery route in the warehouse - Change the `location_dest_id` of the operation type set on the rule - Enable the "Location Dest. Taken from Rule" checkbox - Ensure `rule.location_dest_id` and `operation_type.location_dest_id` are different - Create a Sales Order (SO) for a product with quantity = 5 and confirm - Change the SO line quantity to 3 and save Issue: A second picking is created with a move taking the product from `rule.operation_type.location_dest_id -> rule.operation_type. location_src_id` with quantity = -2. This happens because the decrease in the SO quantity triggers a negative move, and this move is not merged with the existing positive move. Instead, a new move is created in the opposite direction. In `_merge_moves`: https://github.com/odoo/odoo/blob/3c4275fb00255e519f01bf5547eff1db3a59d4b5/addons/stock/models/stock_move.py#L1191-L1193 It checks if the negative move has similar characteristics to the existing positive moves. However, the `neg_key(neg_move)` differs in `location_dest_id`, so the merge fails. This happens because the negative move does **not** read the `location_dest_id` from the rule — unlike the procurement, which **does** use the rule and therefore creates positive moves with the correct destination. When the negative move is created with the procurement, it initially has the correct `location_dest_id`. But then: https://github.com/odoo/odoo/blob/b984c72df398c4fe942d8894442e4e893ca0660e/addons/stock/models/stock_move.py#L1191 triggers `_compute_location_dest_id`, which doesn't consider the `rule.location_dest_id` and defaults to `operation_type. location_dest_id`, causing the merge to fail due to mismatched destination_locations. The positive move has read the correct value, because when it was assigned to a picking, the picking has the correct destination from the procurement. But for the neg_move it has picking None so it maps to the operation_type without consdiering the location from rule checkbox. opw-4793171 closes odoo#212355 Signed-off-by: Tiffany Chang (tic) <[email protected]>
1 parent 157f981 commit c52f12d

File tree

2 files changed

+36
-0
lines changed

2 files changed

+36
-0
lines changed

addons/stock/models/stock_move.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -224,6 +224,8 @@ def _compute_location_dest_id(self):
224224
location_dest = False
225225
if move.picking_id:
226226
location_dest = move.picking_id.location_dest_id
227+
elif move.rule_id.location_dest_from_rule:
228+
location_dest = move.rule_id.location_dest_id
227229
elif move.picking_type_id:
228230
location_dest = move.picking_type_id.default_location_dest_id
229231
is_move_to_interco_transit = False

addons/stock/tests/test_old_rules.py

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -641,3 +641,37 @@ def test_propagate_cancel_in_pull_setup(self):
641641
pick_move = move_chain.filtered(lambda m: m.picking_type_id == self.warehouse_3_steps.pick_type_id)
642642
pick_move.picking_id.action_cancel()
643643
self.assertEqual(move_chain.mapped('state'), ['cancel', 'cancel', 'cancel'])
644+
645+
def test_negative_move_with_take_loc_from_rule(self):
646+
"""
647+
This test checks if t a negative move will be merged correctly when the loc_dest_id
648+
is taken from the rule instead of the picking type.
649+
"""
650+
rule = self.warehouse_1.reception_route_id.rule_ids.filtered(lambda r: r.action == 'pull')
651+
new_loc = self.env['stock.location'].create({
652+
'name': 'Shelf',
653+
'usage': 'transit',
654+
'location_id': rule.location_dest_id.id,
655+
})
656+
rule.write({
657+
'location_dest_id': new_loc.id,
658+
})
659+
rule.location_dest_from_rule = True
660+
picking = self.env['stock.picking'].create({
661+
'picking_type_id': rule.picking_type_id.id,
662+
'location_dest_id': rule.location_dest_id.id,
663+
})
664+
pos_move = self.env['stock.move'].create({
665+
'name': 'Positive move',
666+
'product_id': self.product_1.id,
667+
'product_uom_qty': 5.0,
668+
'picking_id': picking.id,
669+
'rule_id': rule.id,
670+
})
671+
pos_move._action_confirm()
672+
neg_move = pos_move.copy({
673+
'name': 'Negative move',
674+
'product_uom_qty': -2.0,
675+
})
676+
neg_move._action_confirm()
677+
self.assertEqual(picking.move_ids.product_uom_qty, 3.0)

0 commit comments

Comments
 (0)