From 69a32bff14b38caca41f819da4a1918cbe54ede2 Mon Sep 17 00:00:00 2001
From: Sebastien Robin <seb@nexedi.com>
Date: Wed, 14 Sep 2022 15:18:15 +0200
Subject: [PATCH] ERP5Type/Workflow: add getFutureStateSet to workflows

We add getFutureStateSet on DCWorkflow, also add this function
to ERP5 Workflows
---
 product/ERP5Type/Core/Workflow.py | 23 +++++++++++++++++++++++
 1 file changed, 23 insertions(+)

diff --git a/product/ERP5Type/Core/Workflow.py b/product/ERP5Type/Core/Workflow.py
index 3dbd1e0060..6ea55e6bff 100644
--- a/product/ERP5Type/Core/Workflow.py
+++ b/product/ERP5Type/Core/Workflow.py
@@ -662,6 +662,29 @@ class Workflow(XMLObject):
     return [state.getReference()
             for state in self.objectValues(portal_type="Workflow State")]
 
+  security.declareProtected(Permissions.AccessContentsInformation,
+                            'getFutureStateSet')
+  def getFutureStateSet(self, state, ignore=(),
+                        _future_state_set=None):
+    """Return the states that can be reached from a given state, directly or not.
+
+    This method returns a set of ids of all states that can be reached in any
+    number of transitions, starting from the state specified by the 'state'
+    parameter. 'ignore' parameter is a list of states to ignore, as if there was
+    no transition to them.
+    """
+    if _future_state_set is None:
+      _future_state_set = set()
+    _future_state_set.add(state)
+    state_object = self.getStateValueByReference(state)
+    for transition in state_object.getDestinationValueList():
+      state_value = transition.getDestinationValue()
+      if state_value is not None:
+        state = state_value.getReference()
+        if state and state not in _future_state_set and state not in ignore:
+          self.getFutureStateSet(state, ignore, _future_state_set)
+    return _future_state_set
+
   security.declareProtected(Permissions.AccessContentsInformation,
                             'getWorklistValueList')
   def getWorklistValueList(self):
-- 
2.30.9