diff --git a/product_lot_sequence/models/__init__.py b/product_lot_sequence/models/__init__.py index ec4ec034fcb..9bfdbf927d8 100644 --- a/product_lot_sequence/models/__init__.py +++ b/product_lot_sequence/models/__init__.py @@ -1,2 +1,3 @@ from . import product from . import stock_production_lot +from . import stock_move diff --git a/product_lot_sequence/models/stock_move.py b/product_lot_sequence/models/stock_move.py new file mode 100644 index 00000000000..c95ef7e1dc6 --- /dev/null +++ b/product_lot_sequence/models/stock_move.py @@ -0,0 +1,23 @@ +# Copyright 2023 Camptocamp SA +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl) +from odoo import models + + +class StockMove(models.Model): + _inherit = "stock.move" + + def action_show_details(self): + """Avoid calling and incrementing the sequence if not needed or already done""" + seq_policy = self.env["stock.production.lot"]._get_sequence_policy() + if seq_policy in ("product", "global"): + # If move is not supposed to assign serial pass empty string for next serial + if not self.display_assign_serial: + return super( + StockMove, self.with_context(force_next_serial="") + ).action_show_details() + # If the sequence was already called once, avoid calling it another time + elif self.next_serial: + return super( + StockMove, self.with_context(force_next_serial=self.next_serial) + ).action_show_details() + return super().action_show_details() diff --git a/product_lot_sequence/models/stock_production_lot.py b/product_lot_sequence/models/stock_production_lot.py index 42cf12fd408..0b07712befa 100644 --- a/product_lot_sequence/models/stock_production_lot.py +++ b/product_lot_sequence/models/stock_production_lot.py @@ -56,6 +56,8 @@ def create(self, vals_list): @api.model def _get_next_serial(self, company, product): + if "force_next_serial" in self.env.context: + return self.env.context.get("force_next_serial") seq_policy = self._get_sequence_policy() if seq_policy == "product": seq = product.product_tmpl_id.lot_sequence_id diff --git a/product_lot_sequence/tests/test_product_lot_sequence.py b/product_lot_sequence/tests/test_product_lot_sequence.py index 9dfe55a969d..6c6d8a4de08 100644 --- a/product_lot_sequence/tests/test_product_lot_sequence.py +++ b/product_lot_sequence/tests/test_product_lot_sequence.py @@ -9,6 +9,22 @@ def setUp(self): super(TestProductLotSequence, self).setUp() self.product_product = self.env["product.product"] self.stock_production_lot = self.env["stock.production.lot"] + self.receipt_type = self.env.ref("stock.picking_type_in") + self.delivery_type = self.env.ref("stock.picking_type_out") + + def _create_picking(self, picking_type, move_vals_list): + picking_form = Form(self.env["stock.picking"]) + picking_form.picking_type_id = picking_type + for move_vals in move_vals_list: + with picking_form.move_ids_without_package.new() as move_form: + move_form.product_id = move_vals.get("product_id") + move_form.product_uom_qty = move_vals.get("product_uom_qty", 1.0) + move_form.product_uom = move_vals.get( + "product_uom", self.env.ref("uom.product_uom_unit") + ) + picking = picking_form.save() + picking.action_confirm() + return picking def test_product_sequence(self): self.assertEqual(self.stock_production_lot._get_sequence_policy(), "product") @@ -88,3 +104,36 @@ def test_lot_onchange_product_id_global(self): lot_form.product_id = product lot = lot_form.save() self.assertEqual(lot.name, next_sequence_number) + + def test_open_detailed_operations(self): + self.env["ir.config_parameter"].set_param( + "product_lot_sequence.policy", "global" + ) + seq = self.env["ir.sequence"].search([("code", "=", "stock.lot.serial")]) + first_next_sequence_number = seq.get_next_char(seq.number_next_actual) + product = self.product_product.create( + {"name": "Test global", "tracking": "serial"} + ) + delivery_picking = self._create_picking( + self.delivery_type, [{"product_id": product}] + ) + delivery_move = delivery_picking.move_lines + self.assertFalse(delivery_move.next_serial) + delivery_move.action_show_details() + self.assertFalse(delivery_move.next_serial) + self.assertEqual( + seq.get_next_char(seq.number_next_actual), first_next_sequence_number + ) + receipt_picking = self._create_picking( + self.receipt_type, [{"product_id": product}] + ) + receipt_move = receipt_picking.move_lines + self.assertFalse(receipt_move.next_serial) + receipt_move.action_show_details() + self.assertEqual(receipt_move.next_serial, first_next_sequence_number) + new_next_sequence_number = seq.get_next_char(seq.number_next_actual) + self.assertNotEqual(new_next_sequence_number, first_next_sequence_number) + receipt_move.action_show_details() + self.assertEqual( + new_next_sequence_number, seq.get_next_char(seq.number_next_actual) + )