diff --git a/addons/sale_stock/tests/test_sale_stock.py b/addons/sale_stock/tests/test_sale_stock.py index 389c06cfce7..7e750993692 100644 --- a/addons/sale_stock/tests/test_sale_stock.py +++ b/addons/sale_stock/tests/test_sale_stock.py @@ -1680,6 +1680,34 @@ class TestSaleStock(TestSaleCommon, ValuationReconciliationTestCommon): return_picking_2.button_validate() self.assertEqual(return_wizard.product_return_moves.quantity, 1) + def test_2_steps_decrease_sol_qty_to_zero(self): + """ + 2 steps delivery, 'cancel next move' enabled + SO with one product + On the SO, cancel the qty of the product + On each picking, the SM should be canceled + """ + warehouse = self.env['stock.warehouse'].search([('company_id', '=', self.env.company.id)], limit=1) + + warehouse.delivery_steps = 'pick_ship' + warehouse.delivery_route_id.rule_ids.propagate_cancel = True + + so = self.env['sale.order'].create({ + 'partner_id': self.partner_a.id, + 'order_line': [(0, 0, { + 'name': self.product_a.name, + 'product_id': self.product_a.id, + 'product_uom_qty': 1, + 'product_uom': self.product_a.uom_id.id, + 'price_unit': self.product_a.list_price, + })], + }) + so.action_confirm() + + so.order_line.product_uom_qty = 0 + + self.assertEqual(so.picking_ids.move_ids.mapped('state'), ['cancel', 'cancel']) + def test_2_steps_fixed_procurement_propagation_with_backorder(self): """ When validating a picking (partially coming from a backorder) linked to 2 destinations moves in a 2-steps delivery, diff --git a/addons/stock/models/stock_move.py b/addons/stock/models/stock_move.py index 63455f1fcb7..d362ae254d1 100644 --- a/addons/stock/models/stock_move.py +++ b/addons/stock/models/stock_move.py @@ -1053,9 +1053,10 @@ Please change the quantity done or the rounding precision of your unit of measur pos_move.product_uom_qty = 0 moves_to_cancel |= pos_move + # We are using propagate to False in order to not cancel destination moves merged in moves[0] + (moves_to_unlink | moves_to_cancel)._clean_merged() + if moves_to_unlink: - # We are using propagate to False in order to not cancel destination moves merged in moves[0] - moves_to_unlink._clean_merged() moves_to_unlink._action_cancel() moves_to_unlink.sudo().unlink()