From e3353b0ad82c273ab118a9b581c8066c75383476 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=C5=81ukasz=20Nowak?= <luke@nexedi.com>
Date: Mon, 13 Jul 2009 12:50:19 +0000
Subject: [PATCH]  - implement BPMised isBuildable on Simulation Movement with
 helper method to know if movements are related each with another

git-svn-id: https://svn.erp5.org/repos/public/erp5/trunk@28065 20353a03-c40f-0410-a6d1-a30d3c3de9de
---
 product/ERP5/Document/SimulationMovement.py | 56 +++++++++++++++++++++
 1 file changed, 56 insertions(+)

diff --git a/product/ERP5/Document/SimulationMovement.py b/product/ERP5/Document/SimulationMovement.py
index 88e15449b4..c6663dc52a 100644
--- a/product/ERP5/Document/SimulationMovement.py
+++ b/product/ERP5/Document/SimulationMovement.py
@@ -542,3 +542,59 @@ class SimulationMovement(Movement):
     else:
       return getTreeDelivered(self, ignore_first=ignore_first)
 
+  def _isRelatedWithMovement(self, movement_value):
+    """Checks if self is parent or children to movement_value, so those are related somehow
+
+    As simulation tree is not related to business process, relation can be bidirectional
+    """
+    self_path_list = self.getRelativeUrl().split('/')
+    movement_path_list = movement_value.getRelativeUrl().split('/')
+    
+    if len(self_path_list) == len(movement_path_list):
+      # same level, cannot be related
+      return False
+    
+    index = 0
+    for self_part in self_path_list:
+      try:
+        movement_part = movement_path_list[index]
+      except IndexError:
+        # so far was good, they are related
+        return True
+      if self_part != movement_part:
+        return False
+      index += 1
+
+  security.declareProtected(Permissions.AccessContentsInformation,
+                            'isBuildable')
+  def isBuildable(self):
+    """Simulation Movement buildable logic"""
+    if self.getDeliveryValue() is not None:
+      # already delivered
+      return False
+    # might be buildable - business path depended
+    business_path = self.getCausalityValue(portal_type='Business Path')
+    explanation_value = self.getExplanationValue()
+    if business_path is not None and explanation_value is not None:
+      predecessor = business_path.getPredecessorValue()
+      if predecessor is None:
+        # first one, can be built
+        return True
+      else:
+        for successor_related in predecessor.getSuccessorRelatedValueList():
+          for business_path_movement in successor_related \
+              .getRelatedSimulationMovementValueList(explanation_value):
+            if self._isRelatedWithMovement(business_path_movement):
+              business_path_movement_delivery = business_path_movement \
+                  .getDeliveryValue()
+              if business_path_movement_delivery is None:
+                return False # related movement is not delivered yet
+              business_path_movement_delivery_document = \
+                  business_path_movement_delivery.getParentValue()
+              # here we can optimise somehow, as
+              # business_path_movement_delivery_document would repeat
+              if not successor_related.isCompleted(
+                  business_path_movement_delivery_document):
+                # related movements delivery is not completed
+                return False
+    return True
-- 
2.30.9