diff --git a/rma/models/rma.py b/rma/models/rma.py index 5921848e9..1bf2d3999 100644 --- a/rma/models/rma.py +++ b/rma/models/rma.py @@ -1193,10 +1193,11 @@ def create_return(self, scheduled_date, qty=None, uom=None): rmas_to_return.write({"state": "waiting_return"}) def _prepare_replace_procurement_vals(self, warehouse=None, scheduled_date=None): - """This method is used only for Replace (not Delivery). We do not use any - specific route here.""" + """This method is used only for Replace (not Delivery).""" vals = self._prepare_common_procurement_vals(warehouse, scheduled_date) vals["rma_id"] = self.id + if self.warehouse_id.rma_out_replace_route_id: + vals["route_ids"] = self.warehouse_id.rma_out_replace_route_id return vals def _prepare_replace_procurements( diff --git a/rma/models/stock_warehouse.py b/rma/models/stock_warehouse.py index 79ad9dbfa..85f708194 100644 --- a/rma/models/stock_warehouse.py +++ b/rma/models/stock_warehouse.py @@ -30,6 +30,7 @@ class StockWarehouse(models.Model): ) rma_in_route_id = fields.Many2one("stock.route", "RMA in Route") rma_out_route_id = fields.Many2one("stock.route", "RMA out Route") + rma_out_replace_route_id = fields.Many2one("stock.route", "RMA out Replace Route") def _get_rma_location_values(self, vals, code=False): """this method is intended to be used by 'create' method diff --git a/rma/tests/test_rma.py b/rma/tests/test_rma.py index 7b798fcb8..2ff4243c0 100644 --- a/rma/tests/test_rma.py +++ b/rma/tests/test_rma.py @@ -2,6 +2,7 @@ # Copyright 2023 Michael Tietz (MT Software) # License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). +from odoo import Command from odoo.exceptions import UserError, ValidationError from odoo.tests import Form, TransactionCase, new_test_user, users from odoo.tools import mute_logger @@ -108,6 +109,20 @@ def _create_confirm_receive( rma.reception_move_id.picking_id._action_done() return rma + def _receive_and_replace(self, partner, product, qty, location): + rma = self._create_confirm_receive(partner, product, qty, location) + delivery_form = Form( + self.env["rma.delivery.wizard"].with_context( + active_ids=rma.ids, + rma_delivery_type="replace", + ) + ) + delivery_form.product_id = rma.product_id + delivery_form.product_uom_qty = qty + delivery_wizard = delivery_form.save() + delivery_wizard.action_deliver() + return rma + def _create_delivery(self): picking_type = self.env["stock.picking.type"].search( [ @@ -848,3 +863,53 @@ def test_autoconfirm_email(self): ) self.assertTrue(rma.name in mail_receipt.subject) self.assertTrue("products received" in mail_receipt.subject) + + def test_replace_picking_type(self): + """ + Test that by default, the replace operation uses the default delivery route, + meaning the warehouse's default delivery picking type is applied. + + RMA replacement orders are not separated from regular deliveries, and both use + the same picking type. + """ + rma = self._receive_and_replace(self.partner, self.product, 2, self.rma_loc) + rma_in_type = self.warehouse.rma_in_type_id + out_type = self.warehouse.out_type_id + self.assertEqual(rma.reception_move_id.picking_type_id, rma_in_type) + self.assertEqual(rma.delivery_move_ids.picking_type_id, out_type) + + def test_replace_picking_type_custom_picking_type(self): + """ + Test that when configured to use a custom route, the replace operation uses a + custom picking type, separating RMA replacement orders from regular deliveries. + + The custom picking type is applied specifically for RMA replacements, instead + of the default delivery picking type. + """ + rma_in_type = self.warehouse.rma_in_type_id + rma_out_type = self.warehouse.rma_out_type_id + route = self.env["stock.route"].create( + { + "name": "RMA OUT replace", + "active": True, + "sequence": 100, + "product_selectable": True, + "rule_ids": [ + Command.create( + { + "name": "RMA OUT", + "action": "pull", + "picking_type_id": rma_out_type.id, + "location_src_id": self.warehouse.lot_stock_id.id, + "location_dest_id": self.env.ref( + "stock.stock_location_customers" + ).id, + }, + ) + ], + } + ) + self.warehouse.rma_out_replace_route_id = route + rma = self._receive_and_replace(self.partner, self.product, 2, self.rma_loc) + self.assertEqual(rma.reception_move_id.picking_type_id, rma_in_type) + self.assertEqual(rma.delivery_move_ids.picking_type_id, rma_out_type) diff --git a/rma/views/stock_warehouse_views.xml b/rma/views/stock_warehouse_views.xml index 238f61981..f94dbb915 100644 --- a/rma/views/stock_warehouse_views.xml +++ b/rma/views/stock_warehouse_views.xml @@ -11,6 +11,10 @@ +