diff --git a/stock_available_to_promise_release/models/stock_move.py b/stock_available_to_promise_release/models/stock_move.py index 5b7b3f0e4e..0d303811b6 100644 --- a/stock_available_to_promise_release/models/stock_move.py +++ b/stock_available_to_promise_release/models/stock_move.py @@ -396,6 +396,15 @@ def _action_cancel(self): # Unrelease moves that can be, before canceling them. moves_to_unrelease = self.filtered(lambda m: m.unrelease_allowed) moves_to_unrelease.unrelease() + # if we manually cancel one of picking chain we set the dest moves + # to need_release so they can be released again + if not self.env.context.get("cancel_due_to_unrelease"): + for dest_moves in self._get_chained_moves_iterator("move_dest_ids"): + need_release_moves = dest_moves.filtered( + lambda m: m.state not in ("draft", "cancel", "done") + and not m.need_release + ) + need_release_moves.need_release = True super()._action_cancel() self.write({"need_release": False}) return True @@ -592,7 +601,7 @@ def unrelease(self, safe_unrelease=False): origin_moves.write({"propagate_cancel": False}) # origin_moves._action_cancel() moves_to_cancel |= origin_moves - moves_to_cancel._action_cancel() + moves_to_cancel.with_context(cancel_due_to_unrelease=True)._action_cancel() # restore the procure_method overwritten by _action_cancel() move.procure_method = procure_method moves_to_unrelease.write({"need_release": True}) diff --git a/stock_available_to_promise_release/tests/test_unrelease_2steps.py b/stock_available_to_promise_release/tests/test_unrelease_2steps.py index 6712523e93..b33389422e 100644 --- a/stock_available_to_promise_release/tests/test_unrelease_2steps.py +++ b/stock_available_to_promise_release/tests/test_unrelease_2steps.py @@ -77,3 +77,12 @@ def test_simulate_cancel_so(self): self.assertTrue( all(m.procure_method == "make_to_order" for m in self.shipping2.move_ids) ) + + def test_cancel_pick(self): + """ + if we manually cancel one of picking chain we set the dest moves + to need_release so they can be released again + """ + self.assertFalse(self.shipping1.need_release) + self.picking1.action_cancel() + self.assertTrue(self.shipping1.need_release) diff --git a/stock_available_to_promise_release/tests/test_unrelease_3steps.py b/stock_available_to_promise_release/tests/test_unrelease_3steps.py index 555d3f1d51..6a6d377dbe 100644 --- a/stock_available_to_promise_release/tests/test_unrelease_3steps.py +++ b/stock_available_to_promise_release/tests/test_unrelease_3steps.py @@ -68,3 +68,22 @@ def test_unrelease_delivery_no_picking_done(self): # self.assertFalse(move_cancel.move_dest_ids) self.assertFalse(move_cancel.move_orig_ids) self.assertEqual(self.ship2.move_ids.move_orig_ids, self.pack2.move_ids) + + def test_cancel_pick(self): + """ + if we manually cancel one of picking chain we set the dest moves + to need_release so they can be released again + """ + self.assertFalse(self.ship1.move_ids.need_release) + self.pick1.action_cancel() + self.assertTrue(self.pack1.move_ids.need_release) + self.assertTrue(self.ship1.move_ids.need_release) + + def test_cancel_pack(self): + """ + if we manually cancel one of picking chain we set the dest moves + to need_release so they can be released again + """ + self.assertFalse(self.ship1.move_ids.need_release) + self.pack1.action_cancel() + self.assertTrue(self.ship1.move_ids.need_release)