diff --git a/rma_sale/models/sale.py b/rma_sale/models/sale.py index f79c6516a..c410d0d1c 100644 --- a/rma_sale/models/sale.py +++ b/rma_sale/models/sale.py @@ -128,19 +128,20 @@ def prepare_sale_rma_data(self): def _get_chained_moves(_moves, done_moves=None): moves = _moves.browse() done_moves = done_moves or _moves.browse() + moves_to_parse = moves for move in _moves: - if move.location_dest_id.usage == "customer": - moves |= move.returned_move_ids - else: - moves |= move.move_dest_ids + if move._is_outgoing() or move._is_incoming(): + moves |= move + # Parse next moves + moves_to_parse |= move.move_dest_ids | move.returned_move_ids done_moves |= _moves moves = moves.filtered( lambda r: r.state in ["partially_available", "assigned", "done"] ) - if not moves: + if not moves_to_parse: return moves - moves -= done_moves - moves |= _get_chained_moves(moves, done_moves) + moves_to_parse -= done_moves + moves |= _get_chained_moves(moves_to_parse, done_moves) return moves product = self.product_id @@ -153,10 +154,10 @@ def _get_chained_moves(_moves, done_moves=None): # Look for chained moves to check how many items we can allow # to return. When a product is re-delivered it should be # allowed to open an RMA again on it. - qty = move.product_uom_qty + qty = 0 for _move in _get_chained_moves(move): factor = 1 - if _move.location_dest_id.usage != "customer": + if _move._is_incoming(): factor = -1 qty += factor * _move.product_uom_qty # If by chance we get a negative qty we should ignore it diff --git a/rma_sale/tests/test_rma_sale_allowed_qty.py b/rma_sale/tests/test_rma_sale_allowed_qty.py index 5ee09e486..0659be09b 100644 --- a/rma_sale/tests/test_rma_sale_allowed_qty.py +++ b/rma_sale/tests/test_rma_sale_allowed_qty.py @@ -52,6 +52,69 @@ def _deliver(self, qty): self.assertEqual(self.picking.state, "done") self.assertEqual(self.so.order_line.qty_delivered, qty) + def _create_rma_route_in_2_steps(self): + """ + 2 steps return route: Customer -> RMA Entrance -> RMA QC OK. + """ + rma_entrance = self.env["stock.location"].create( + { + "name": "RMA: entrance before quality check", + "usage": "internal", + } + ) + rma_reception = self.env["stock.picking.type"].create( + { + "name": "RMA Receptions", + "code": "incoming", + "sequence_code": "RMA-IN-REC", + "default_location_src_id": self.env.ref( + "stock.stock_location_customers" + ).id, + "default_location_dest_id": rma_entrance.id, + } + ) + rma_qc = self.env["stock.picking.type"].create( + { + "name": "RMA QC", + "code": "internal", + "sequence_code": "RMA-QC", + "default_location_src_id": rma_entrance.id, + "default_location_dest_id": self.env.ref( + "stock.stock_location_stock" + ).id, + } + ) + self.env["stock.route"].create( + { + "name": "RMA: In in 2 steps", + "warehouse_selectable": "True", + "warehouse_ids": [Command.link(self.warehouse.id)], + "rule_ids": [ + Command.create( + { + "name": "RMA Reception", + "action": "pull", + "picking_type_id": rma_reception.id, + "procure_method": "make_to_stock", + "location_src_id": rma_reception.default_location_src_id.id, + "location_dest_id": rma_entrance.id, + }, + ), + Command.create( + { + "name": "RMA QC", + "action": "push", + "picking_type_id": rma_qc.id, + "auto": "manual", + "location_src_id": rma_entrance.id, + "location_dest_id": rma_qc.default_location_dest_id.id, + }, + ), + ], + } + ) + self.warehouse.rma_loc_id = rma_entrance + def test_1(self): """ Test rma wizard: @@ -109,3 +172,34 @@ def test_3(self): ): wizard.line_ids.quantity = 5 wizard.line_ids.quantity = 1 + + def test_4(self): + """ + Test rma wizard: + + - deliver the so + - return 1 unit with a return route generating 2 moves + - open rma wizard + expected: + - qty proposed: 4 + - allowed qty 4 + - qty 0 if is_return_all = False + """ + self._create_rma_route_in_2_steps() + self._deliver(5) + wizard = self._get_rma_wizard() + wizard.line_ids[0].quantity = 1 + wizard.operation_id = self.env.ref("rma.rma_operation_refund").id + rma = wizard.create_rma() + rma.action_confirm() + rma.reception_move_id.picking_id.button_validate() + self.assertTrue( + rma.reception_move_id.move_dest_ids, + "Second step move for return should have been created", + ) + rma.reception_move_id.move_dest_ids.picking_id.button_validate() + # Returned product was received, QC ok. Both steps performed + wizard = self._get_rma_wizard() + self.assertEqual(len(wizard.line_ids), 1) + self.assertEqual(wizard.line_ids.quantity, 4) + self.assertEqual(wizard.line_ids.allowed_quantity, 4)