From 3a19fa4b7adb9d34ea7f427159790b41b7c28f58 Mon Sep 17 00:00:00 2001 From: Jordi Ballester Alomar Date: Mon, 26 Feb 2024 16:01:54 +0100 Subject: [PATCH] [IMP] introduce fields in_force_same_lot and out_force_same_lot Those fields in the rma.operation allows us to control if we want to ensure that the same lot as the one indicated in the RMA should be used in deliveries to customers and receipts from suppliers --- rma/data/rma_operation.xml | 4 ++ rma/models/rma_operation.py | 10 +++ rma/models/stock_move.py | 2 + rma/views/rma_operation_view.xml | 8 +++ rma/wizards/rma_make_picking.py | 84 ++++++++++++------------- rma_put_away/tests/test_rma_put_away.py | 4 ++ 6 files changed, 70 insertions(+), 42 deletions(-) diff --git a/rma/data/rma_operation.xml b/rma/data/rma_operation.xml index 92e3fec00..fb642255a 100644 --- a/rma/data/rma_operation.xml +++ b/rma/data/rma_operation.xml @@ -8,6 +8,8 @@ customer + True + False @@ -18,6 +20,8 @@ supplier + False + True diff --git a/rma/models/rma_operation.py b/rma/models/rma_operation.py index bd3d0f167..3de155f05 100644 --- a/rma/models/rma_operation.py +++ b/rma/models/rma_operation.py @@ -94,3 +94,13 @@ def _default_routes(self): required=True, default=lambda self: self.env.user.company_id, ) + in_force_same_lot = fields.Boolean( + string="Force same lot in incoming shipments", + help="Forces the same lot to be used " + "in outgoing pickings as the one indicated in the RMA", + ) + out_force_same_lot = fields.Boolean( + string="Force same lot in outgoing shipments", + help="Forces the same lot to be used " + "in incoming pickings as the one indicated in the RMA", + ) diff --git a/rma/models/stock_move.py b/rma/models/stock_move.py index 9a839f180..52cbf72fe 100644 --- a/rma/models/stock_move.py +++ b/rma/models/stock_move.py @@ -62,6 +62,7 @@ def _get_available_quantity( not lot_id and self.rma_line_id.lot_id and self.location_id.usage == "internal" + and self.rma_line_id.operation_id.out_force_same_lot ): # In supplier RMA deliveries we can only send the RMA lot/serial. lot_id = self.rma_line_id.lot_id @@ -88,6 +89,7 @@ def _update_reserved_quantity( not lot_id and self.rma_line_id.lot_id and self.location_id.usage == "internal" + and self.rma_line_id.operation_id.out_force_same_lot ): # In supplier RMA deliveries we can only send the RMA lot/serial. lot_id = self.rma_line_id.lot_id diff --git a/rma/views/rma_operation_view.xml b/rma/views/rma_operation_view.xml index c2bb1b59e..08a00f286 100644 --- a/rma/views/rma_operation_view.xml +++ b/rma/views/rma_operation_view.xml @@ -53,6 +53,10 @@ name="customer_to_supplier" attrs="{'invisible':[('type', '=', 'supplier')]}" /> + @@ -61,6 +65,10 @@ name="supplier_to_customer" attrs="{'invisible':[('type', '=', 'customer')]}" /> + diff --git a/rma/wizards/rma_make_picking.py b/rma/wizards/rma_make_picking.py index 0b92b1d85..2982b75f0 100644 --- a/rma/wizards/rma_make_picking.py +++ b/rma/wizards/rma_make_picking.py @@ -210,48 +210,48 @@ def action_create_picking(self): else: pickings = self.mapped("item_ids.line_id")._get_in_pickings() action = self.item_ids.line_id.action_view_in_shipments() - if picking_type == "incoming": - # Force the reservation of the RMA specific lot for incoming shipments. - # FIXME: still needs fixing, not reserving appropriate serials. - for move in pickings.move_ids.filtered( - lambda x: x.state not in ("draft", "cancel", "done", "waiting") - and x.rma_line_id - and x.product_id.tracking in ("lot", "serial") - and x.rma_line_id.lot_id - ): - # Force the reservation of the RMA specific lot for incoming shipments. - move.move_line_ids.unlink() - if move.product_id.tracking == "serial": - move.write( - { - "lot_ids": [(6, 0, move.rma_line_id.lot_id.ids)], - } - ) - move.move_line_ids.write( - { - "reserved_uom_qty": 1, - "qty_done": 0, - } - ) - elif move.product_id.tracking == "lot": - if picking_type == "incoming": - qty = self.item_ids.filtered( - lambda x: x.line_id.id == move.rma_line_id.id - ).qty_to_receive - else: - qty = self.item_ids.filtered( - lambda x: x.line_id.id == move.rma_line_id.id - ).qty_to_deliver - move_line_data = move._prepare_move_line_vals() - move_line_data.update( - { - "lot_id": move.rma_line_id.lot_id.id, - "product_uom_id": move.product_id.uom_id.id, - "qty_done": 0, - "reserved_uom_qty": qty, - } - ) - move_line_model.create(move_line_data) + + for move in pickings.move_ids.filtered( + lambda x: x.state not in ("draft", "cancel", "done", "waiting") + and x.rma_line_id + and x.product_id.tracking in ("lot", "serial") + and x.rma_line_id.lot_id + and x.rma_line_id.operation_id.in_force_same_lot + and x.location_dest_id.usage == "internal" + ): + # Force the reservation of the RMA specific lot for incoming shipments if required. + move.move_line_ids.unlink() + if move.product_id.tracking == "serial": + move.write( + { + "lot_ids": [(6, 0, move.rma_line_id.lot_id.ids)], + } + ) + move.move_line_ids.write( + { + "reserved_uom_qty": 1, + "qty_done": 0, + } + ) + elif move.product_id.tracking == "lot": + if picking_type == "incoming": + qty = self.item_ids.filtered( + lambda x: x.line_id.id == move.rma_line_id.id + ).qty_to_receive + else: + qty = self.item_ids.filtered( + lambda x: x.line_id.id == move.rma_line_id.id + ).qty_to_deliver + move_line_data = move._prepare_move_line_vals() + move_line_data.update( + { + "lot_id": move.rma_line_id.lot_id.id, + "product_uom_id": move.product_id.uom_id.id, + "qty_done": 0, + "reserved_uom_qty": qty, + } + ) + move_line_model.create(move_line_data) pickings.with_context(force_no_bypass_reservation=True).action_assign() return action diff --git a/rma_put_away/tests/test_rma_put_away.py b/rma_put_away/tests/test_rma_put_away.py index b3bec91e2..16d3514e1 100644 --- a/rma_put_away/tests/test_rma_put_away.py +++ b/rma_put_away/tests/test_rma_put_away.py @@ -84,6 +84,8 @@ def setUpClass(cls): "put_away_location_id": cls.put_away_loc.id, "in_route_id": cls.rma_route_cust.id, "out_route_id": cls.rma_route_cust.id, + "out_force_same_lot": True, + "in_force_same_lot": True, } ) cls.operation_2 = cls.rma_op_obj.create( @@ -97,6 +99,8 @@ def setUpClass(cls): "put_away_location_id": cls.put_away_loc.id, "in_route_id": cls.rma_route_cust.id, "out_route_id": cls.rma_route_cust.id, + "out_force_same_lot": True, + "in_force_same_lot": True, } )