From d1465d823aaa4c38e298841bd122dc7dfe7245a3 Mon Sep 17 00:00:00 2001 From: Michael Tietz Date: Tue, 30 Jul 2024 14:31:13 +0200 Subject: [PATCH] [IMP] stock_move_auto_assign_auto_release: Release release_ready moves together Release all release_ready moves of a transfers marked with release_policy=one together --- .../models/product_product.py | 13 ++++++-- .../readme/CONTRIBUTORS.rst | 1 + .../tests/test_assign_auto_release.py | 32 +++++++++++++++++++ 3 files changed, 44 insertions(+), 2 deletions(-) diff --git a/stock_move_auto_assign_auto_release/models/product_product.py b/stock_move_auto_assign_auto_release/models/product_product.py index d099250cdbbe..f81cee70eaff 100644 --- a/stock_move_auto_assign_auto_release/models/product_product.py +++ b/stock_move_auto_assign_auto_release/models/product_product.py @@ -1,4 +1,5 @@ # Copyright 2022 ACSONE SA/NV +# Copyright 2024 Michael Tietz (MT Software) # License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). from odoo import models @@ -17,8 +18,8 @@ def _moves_auto_release_domain(self): def moves_auto_release(self): """Job trying to auto release moves based on product - It searches all* the moves auto releasable and trigger the release - available to promise process. + It searches all* the moves auto releasable and there siblings + and trigger the release available to promise process. """ self.ensure_one() moves = self.env["stock.move"].search(self._moves_auto_release_domain()) @@ -26,4 +27,12 @@ def moves_auto_release(self): if not pickings: return self._lock_pickings_or_retry(pickings) + move_ids = moves.ids + for picking in pickings: + if picking.release_policy != "one": + continue + for move in picking.move_lines: + if move.id not in move_ids and move.is_auto_release_allowed: + move_ids.append(move.id) + moves = moves.browse(move_ids) moves.release_available_to_promise() diff --git a/stock_move_auto_assign_auto_release/readme/CONTRIBUTORS.rst b/stock_move_auto_assign_auto_release/readme/CONTRIBUTORS.rst index 172b2d223cef..fd6329eb2ea9 100644 --- a/stock_move_auto_assign_auto_release/readme/CONTRIBUTORS.rst +++ b/stock_move_auto_assign_auto_release/readme/CONTRIBUTORS.rst @@ -1 +1,2 @@ * Laurent Mignon +* Michael Tietz (MT Software) diff --git a/stock_move_auto_assign_auto_release/tests/test_assign_auto_release.py b/stock_move_auto_assign_auto_release/tests/test_assign_auto_release.py index 614af12ffd1a..710c9f8d82e7 100644 --- a/stock_move_auto_assign_auto_release/tests/test_assign_auto_release.py +++ b/stock_move_auto_assign_auto_release/tests/test_assign_auto_release.py @@ -1,4 +1,5 @@ # Copyright 2022 ACSONE SA/NV +# Copyright 2024 Michael Tietz (MT Software) # License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). from datetime import datetime @@ -166,3 +167,34 @@ def test_move_field_is_auto_release_allowed(self): for domain in NOT_RELEASABLE_DOMAINS: self.assertIn(move_released, self.env["stock.move"].search(domain)) self.assertNotIn(move_not_released, self.env["stock.move"].search(domain)) + + def test_picking_policy_one_async_receive(self): + shipping = self._out_picking( + self._create_picking_chain( + self.wh, + [(self.product1, 10), (self.product2, 10)], + date=datetime(2019, 9, 2, 16, 0), + ) + ) + shipping.release_policy = "one" + shipping.move_type = "one" + self.assertTrue( + all( + move.need_release and not move.release_ready + for move in shipping.move_lines + ) + ) + with trap_jobs() as trap: + self._receive_product(self.product1, 100) + trap.perform_enqueued_jobs() + with trap_jobs() as trap: + self._receive_product(self.product2, 100) + trap.perform_enqueued_jobs() + move_product1 = shipping.move_lines.filtered( + lambda m: m.product_id == self.product1 + ) + move_product2 = shipping.move_lines - move_product1 + self.assertFalse(move_product2.release_ready) + self.assertFalse(move_product2.need_release) + self.assertFalse(move_product1.need_release) + self.assertFalse(move_product1.release_ready)