diff --git a/product/ERP5/Document/SimulationMovement.py b/product/ERP5/Document/SimulationMovement.py
index af9bc11907b90ebab5513f65d16ca42410e285cf..d5bd6c6d40be25bd9e625a3f7136291f5e5f5ac0 100644
--- a/product/ERP5/Document/SimulationMovement.py
+++ b/product/ERP5/Document/SimulationMovement.py
@@ -567,26 +567,53 @@ class SimulationMovement(Movement, PropertyRecordableMixin):
       # first one, can be built
       return True
 
-    simulation_movement_list = business_path.getBusinessPathClosure([self])
-
     # store a causality -> causality_related_movement_list mapping
     causality_dict = dict()
-    for mov in simulation_movement_list:
-      causality_dict.setdefault(mov.getCausality(), []).append(mov)
 
+    # for now only explore ancestors
+    current = self.getParentValue()
+    while True:
+      portal_type = current.getPortalType()
+      if portal_type == "Simulation Movement":
+        causality_dict[current.getCausality()] = current
+      elif portal_type != "Applied Rule":
+        break
+      # XXX or maybe directly go up by two levels?
+      current = current.getParentValue()
+
+    parent_path_list = predecessor.getSuccessorRelatedValueList()
+    remaining_path_list = []
+    for path in parent_path_list:
+      related_simulation = causality_dict.get(path.getRelativeUrl())
+      if related_simulation is None:
+        remaining_path_list.append(path)
+        continue
+      if related_simulation.getDeliveryValue() is None:
+        return False # related movement is not delivered yet
+      if related_simulation.getSimulationState() not in \
+          path.getCompletedStateList():
+        return False
+
+    # in 90% of cases, Business Path goes downward and this is enough
+    if not remaining_path_list:
+      return True
+
+    # But sometimes we have to dig deeper
 
-    for parent_path in predecessor.getSuccessorRelatedValueList():
-      causality = parent_path.getRelativeUrl()
-      related_simulation_list = causality_dict.get(causality, [])
+    # reset dict
+    causality_dict = dict()
 
-      completed_state_list = parent_path.getCompletedStateList()
-      for business_path_movement in related_simulation_list:
-        business_path_movement_delivery = business_path_movement \
-            .getDeliveryValue()
-        if business_path_movement_delivery is None:
-          return False # related movement is not delivered yet
-        if business_path_movement.getSimulationState() not in completed_state_list:
+    # and explore descendants
+    for descendant in business_path._recurseGetValueList(self, 'Simulation Movement'):
+      causality_dict.setdefault(descendant.getCausality(), []).append(descendant)
+    for path in remaining_path_list:
+      completed_state_list = path.getCompletedStateList()
+      for simulation in causality_dict.get(path.getRelativeUrl(), []):
+        if simulation.getDeliveryValue() is None:
+          return False
+        if simulation.getSimulationState() not in completed_state_list:
           return False
+
     return True
 
   def getSolverProcessValueList(self, movement=None, validation_state=None):