diff --git a/addons/sale_stock/models/stock.py b/addons/sale_stock/models/stock.py index 789c86e03ee..3fd60679493 100644 --- a/addons/sale_stock/models/stock.py +++ b/addons/sale_stock/models/stock.py @@ -46,20 +46,9 @@ class StockMove(models.Model): return self.sale_line_id.order_id or res def _get_sale_order_lines(self): - """ Return all possible sale order lines for one or multiple stock moves. """ - def _get_origin_moves(move): - origin_moves = move.move_orig_ids - if origin_moves: - origin_moves += _get_origin_moves(origin_moves) - return origin_moves - - def _get_destination_moves(move): - destination_moves = move.move_dest_ids - if destination_moves: - destination_moves += _get_destination_moves(destination_moves) - return destination_moves - - return (self + _get_origin_moves(self) + _get_destination_moves(self)).sale_line_id + """ Return all possible sale order lines for one stock move. """ + self.ensure_one() + return (self + self.browse(self._rollup_move_origs() | self._rollup_move_dests())).sale_line_id def _assign_picking_post_process(self, new=False): super(StockMove, self)._assign_picking_post_process(new=new) diff --git a/addons/sale_stock/tests/test_sale_stock.py b/addons/sale_stock/tests/test_sale_stock.py index 6b9bba16b29..e69a454b45d 100644 --- a/addons/sale_stock/tests/test_sale_stock.py +++ b/addons/sale_stock/tests/test_sale_stock.py @@ -1605,3 +1605,51 @@ class TestSaleStock(TestSaleCommon, ValuationReconciliationTestCommon): {'product_id': self.product_a.id, 'product_uom_qty': 0, 'quantity': 0, 'state': 'cancel'}, {'product_id': self.product_b.id, 'product_uom_qty': 1, 'quantity': 0, 'state': 'waiting'}, ]) + + def test_create_so_return_with_tracked_product(self): + """ + Creates a sale order with a tracked product, validates it and its delivery, then creates a + return validates it and finally creates a second return. + """ + self.product_a.tracking = 'serial' + self.product_a.type = 'product' + sn1 = self.env['stock.lot'].create({ + 'name': 'SN0001', + 'product_id': self.product_a.id, + 'company_id': self.env.company.id, + }) + self.env['stock.quant']._update_available_quantity(self.product_a, self.company_data['default_warehouse'].lot_stock_id, 1, lot_id=sn1) + # Creates a sale order for 1 tracked product. + sale_order = self._get_new_sale_order(amount=1, product=self.product_a) + # validates the sale order, then validates the delivery. + sale_order.action_confirm() + self.assertTrue(sale_order.picking_ids) + picking = sale_order.picking_ids + picking.button_validate() + + # Checks the delivery amount (must be 1). + self.assertEqual(sale_order.order_line.qty_delivered, 1) + # Creates a return from the delivery picking. + return_picking_form = Form(self.env['stock.return.picking'] + .with_context(active_ids=picking.ids, active_id=picking.id, + active_model='stock.picking')) + return_wizard = return_picking_form.save() + self.assertEqual(return_wizard.product_return_moves.quantity, 1) + + # validates the return picking. + res = return_wizard.create_returns() + return_picking = self.env['stock.picking'].browse(res['res_id']) + return_picking.button_validate() + # Checks the delivery amount (must be 0). + self.assertEqual(sale_order.order_line.qty_delivered, 0) + return_picking_form = Form(self.env['stock.return.picking'] + .with_context(active_ids=return_picking.ids, active_id=return_picking.id, + active_model='stock.picking')) + return_wizard = return_picking_form.save() + self.assertEqual(return_wizard.product_return_moves.quantity, 1) + + # validates the return picking. + res = return_wizard.create_returns() + return_picking_2 = self.env['stock.picking'].browse(res['res_id']) + return_picking_2.button_validate() + self.assertEqual(return_wizard.product_return_moves.quantity, 1) diff --git a/addons/stock/models/stock_move.py b/addons/stock/models/stock_move.py index c389a5be4eb..7a76f9329d1 100644 --- a/addons/stock/models/stock_move.py +++ b/addons/stock/models/stock_move.py @@ -2143,6 +2143,7 @@ Please change the quantity done or the rounding precision of your unit of measur moves_to_reserve._action_assign() def _rollup_move_dests(self, seen=False): + self.ensure_one() if not seen: seen = OrderedSet() if self.id in seen: @@ -2153,6 +2154,7 @@ Please change the quantity done or the rounding precision of your unit of measur return seen def _rollup_move_origs(self, seen=False): + self.ensure_one() if not seen: seen = OrderedSet() if self.id in seen: