Commit 5c245836 authored by Łukasz Nowak's avatar Łukasz Nowak

- move _isRelatedWithMovement from SimulationMovement to BusinessPath as...

 - move _isRelatedWithMovement from SimulationMovement to BusinessPath as isMovementRelatedWithMovement, define in interface and use in SimulationMovement
 - implement proper fetching of all related simulation movements to business path and delivery
 - implement isBuildable for BusinessPath in a way, that partially completion is enough


git-svn-id: https://svn.erp5.org/repos/public/erp5/trunk@28100 20353a03-c40f-0410-a6d1-a30d3c3de9de
parent 60ebf59c
...@@ -193,7 +193,7 @@ class BusinessPath(Path): ...@@ -193,7 +193,7 @@ class BusinessPath(Path):
predecessor = self.getPredecessorValue() predecessor = self.getPredecessorValue()
if predecessor is None: if predecessor is None:
return result return result
if predecessor.isCompleted(explanation): if predecessor.isPartiallyCompleted(explanation):
return result return result
return False return False
...@@ -267,26 +267,103 @@ class BusinessPath(Path): ...@@ -267,26 +267,103 @@ class BusinessPath(Path):
return False return False
return True return True
def _recurseGetValueList(self, document, portal_type):
"""Helper method to recurse documents as deep as possible and returns
list of document values matching portal_type"""
return_list = []
for subdocument in document.contentValues():
if subdocument.getPortalType() == portal_type:
return_list.append(subdocument)
return_list.extend(self._recurseGetValueList(subdocument, portal_type))
return return_list
def isMovementRelatedWithMovement(self, movement_value_a, movement_value_b):
"""Documentation in IBusinessPath"""
movement_a_path_list = movement_value_a.getRelativeUrl().split('/')
movement_b_path_list = movement_value_b.getRelativeUrl().split('/')
if len(movement_a_path_list) == len(movement_b_path_list):
if movement_value_a == movement_value_b:
# same is related
return True
# same level, cannot be related
return False
index = 0
for movement_a_part in movement_a_path_list:
try:
movement_b_part = movement_b_path_list[index]
except IndexError:
# so far was good, they are related
return True
if movement_a_part != movement_b_part:
return False
index += 1
# movement_a_path_list was shorter than movement_b_path_list and matched
# so they are related
return True
def _isDeliverySimulationMovementRelated(self, delivery, simulation_movement):
"""Helper method, which checks if simulation_movement is BPM like related
with delivery"""
for delivery_simulation_movement in self \
._getDeliverySimulationMovementList(delivery):
if self.isMovementRelatedWithMovement(delivery_simulation_movement,
simulation_movement):
return True
return False
def _getDeliverySimulationMovementList(self, delivery):
"""Returns list of simulation movements related to delivery by applied rule
or delivery's movements"""
movement_list = []
for applied_rule in delivery.getCausalityRelatedValueList(
portal_type='Applied Rule'):
movement_list.extend(applied_rule.contentValues(
portal_type='Simulation Movement'))
for movement in delivery.getMovementList():
movement_list.extend(movement.getDeliveryRelatedValueList(
portal_type='Simulation Movement'))
return movement_list
# IBusinessPath implementation # IBusinessPath implementation
security.declareProtected(Permissions.AccessContentsInformation, security.declareProtected(Permissions.AccessContentsInformation,
'getRelatedSimulationMovementValueList') 'getRelatedSimulationMovementValueList')
def getRelatedSimulationMovementValueList(self, explanation): def getRelatedSimulationMovementValueList(self, explanation):
""" """
Returns all Simulation Movements related to explanation Returns recursively all Simulation Movements indirectly related to explanation and self
As business sequence is not related to simulation tree need to built
full simulation trees per applied rule
""" """
# FIXME: Needed better implementation, maybe use catalog?
simulation_movement_value_list = [] simulation_movement_value_list = []
# first simulation movements related to explanation itself by its applied rule # first tree from root Applied Rules related to delivery itself
for applied_rule in explanation.getCausalityRelatedValueList( for applied_rule in explanation.getCausalityRelatedValueList(
portal_type='Applied Rule'): portal_type='Applied Rule'):
simulation_movement_value_list.extend([x.getObject() for x in simulation_movement_value_list.extend(self._recurseGetValueList(
applied_rule.contentValues() if x.getCausalityValue() == self]) applied_rule, 'Simulation Movement'))
# now simulation movements which were used to build this delivery # now tree from root Applied Rules related to movements used to build delivery
root_applied_rule_list = []
for movement in explanation.getMovementList(): for movement in explanation.getMovementList():
simulation_movement_value_list.extend([x.getObject() for x in for simulation_movement in movement.getDeliveryRelatedValueList(
movement.getDeliveryRelatedValueList( portal_type='Simulation Movement'):
portal_type='Simulation Movement') if x \ applied_rule = simulation_movement.getRootAppliedRule()
.getCausalityValue() == self]) if applied_rule not in root_applied_rule_list:
return simulation_movement_value_list root_applied_rule_list.append(
simulation_movement.getRootAppliedRule())
for applied_rule in root_applied_rule_list:
simulation_movement_value_list.extend(self._recurseGetValueList(
applied_rule, 'Simulation Movement'))
return [simulation_movement.getObject() for simulation_movement
in simulation_movement_value_list
# this business path
if simulation_movement.getCausalityValue() == self
# related with explanation
and self._isDeliverySimulationMovementRelated(
explanation, simulation_movement)]
def getExpectedStartDate(self, explanation, predecessor_date=None, *args, **kwargs): def getExpectedStartDate(self, explanation, predecessor_date=None, *args, **kwargs):
""" """
......
...@@ -542,29 +542,6 @@ class SimulationMovement(Movement): ...@@ -542,29 +542,6 @@ class SimulationMovement(Movement):
else: else:
return getTreeDelivered(self, ignore_first=ignore_first) 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, security.declareProtected(Permissions.AccessContentsInformation,
'isBuildable') 'isBuildable')
def isBuildable(self): def isBuildable(self):
...@@ -584,7 +561,7 @@ class SimulationMovement(Movement): ...@@ -584,7 +561,7 @@ class SimulationMovement(Movement):
for successor_related in predecessor.getSuccessorRelatedValueList(): for successor_related in predecessor.getSuccessorRelatedValueList():
for business_path_movement in successor_related \ for business_path_movement in successor_related \
.getRelatedSimulationMovementValueList(explanation_value): .getRelatedSimulationMovementValueList(explanation_value):
if self._isRelatedWithMovement(business_path_movement): if successor_related.isMovementRelatedWithMovement(self, business_path_movement):
business_path_movement_delivery = business_path_movement \ business_path_movement_delivery = business_path_movement \
.getDeliveryValue() .getDeliveryValue()
if business_path_movement_delivery is None: if business_path_movement_delivery is None:
......
...@@ -63,3 +63,12 @@ class IBusinessPath(IBusinessCompletable, IBusinessBuildable): ...@@ -63,3 +63,12 @@ class IBusinessPath(IBusinessCompletable, IBusinessBuildable):
explanation - any document related to business path - which bootstraped explanation - any document related to business path - which bootstraped
process or is related to build of one paths process or is related to build of one paths
""" """
def isMovementRelatedWithMovement(movement_value_a, movement_value_b)
"""Checks if self is parent or children to movement_value
This logic is Business Process specific for Simulation Movements, as
sequence of Business Process is not related appearance of Simulation Tree
movement_value_a, movement_value_b - movements to check relation between
"""
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment