Commit 9880c119 authored by Jean-Paul Smets's avatar Jean-Paul Smets

Some more ideas where BPM is heading to

git-svn-id: https://svn.erp5.org/repos/public/erp5/sandbox/amount_generator@35585 20353a03-c40f-0410-a6d1-a30d3c3de9de
parent e31f2aef
......@@ -34,42 +34,12 @@ from AccessControl import ClassSecurityInfo
from Products.ERP5Type import Permissions, PropertySheet, interfaces
from Products.ERP5.Document.Path import Path
from Products.ERP5.Document.Predicate import Predicate
from Products.ERP5.ExplanationCache import _getExplanationCache
import zope.interface
from zLOG import LOG
class ExplanationCache:
"""ExplanationCache provides a central access to
all parameters and values which are needed to process
an explanation. It is based on the idea that a value is calculated
once and once only, as a way to accelerate performance of algorithms
related to an explanation.
'explanation_uid': self._getExplanationUidList(explanation) # XXX-JPS why do we need explanation_uid ? and why a list
'simulation_path': simulation_path,
explanation_uid = self._getExplanationUidList(explanation) # A hint value to reduce the size of the tree
simulation_path = '/erp5/p.../%' # A list of path
"""
def __init__(self, explanation):
"""
"""
self.explanation = explanation
def getRootExplanationUidList(self):
"""
"""
def getSimulationPathPatternList(self):
"""
"""
def _getExplanationCache(explanation):
# XXX-JPS Cache this in a transaction variable or better
return ExplanationCache(explanation)
class BusinessPath(Path, Predicate):
"""
The BusinessPath class embeds all information related to
......@@ -175,6 +145,12 @@ class BusinessPath(Path, Predicate):
#'destination_transport'
)
# Helper Methods
def _getExplanationRelatedSimulationMovementValueList(self, explanation):
explanation_cache = _getExplanationCache(explanation)
return explanation_cache.getBusinessPathRelatedSimulationMovementValueList(self)
# XXX-JPS UNkonwn ?
security.declareProtected(Permissions.AccessContentsInformation,
'getArrowCategoryDict')
def getArrowCategoryDict(self, context=None, **kw): # XXX-JPS do we need it in API ?
......@@ -271,6 +247,22 @@ class BusinessPath(Path, Predicate):
method_id = self.getCompletionDateMethodId()
method = getattr(movement, method_id) # We wish to raise if it does not exist
return method()
def getCompletionDate(self, explanation):
"""Returns the date of completion of the movemnet
based on paremeters of the business path. This complete date can be
the start date, the stop date, the date of a given workflow transition
on the explaining delivery, etc.
XXX - DOC
movement -- a Simulation Movement
"""
date_list = []
for movement in self._getExplanationRelatedSimulationMovementValueList(explanation):
date_list.append(self.getMovementCompletionDate(movement))
return max(date_list)
security.declareProtected(Permissions.AccessContentsInformation,
'getExpectedQuantity')
......@@ -363,6 +355,15 @@ class BusinessPath(Path, Predicate):
return False
return True
def isDelivered(self, explanation):
"""XXX
"""
for simulation_movement in self._getExplanationRelatedSimulationMovementValueList(
explanation):
if not simulation_movement.getDelivery():
return False
return True
def build(self, explanation):
"""Builds all related movements in the simulation using the builders
defined on the Business Path.
......
This diff is collapsed.
......@@ -51,12 +51,12 @@ class ExplanationCache:
"""
# Define share properties
self.explanation = explanation
self.portal_catalog = getToolByName(explanation 'portal_catalog')
self.portal_catalog = getToolByName(explanation, 'portal_catalog')
self.simulation_movement_cache = {} # Simulation Movement Cache
self.explanation_uid_cache = []
self.explanation_path_pattern_cache = []
def getDeliveryMovementList(self):
def _getDeliveryMovementList(self):
"""Returns self is explanation is a delivery line
of the list of explanation delivery lines if explanation
is a delivery
......@@ -80,7 +80,7 @@ class ExplanationCache:
return self.explanation_uid_cache
result = set()
# For each delivery movement
for movement in self.getDeliveryMovementList():
for movement in self._getDeliveryMovementList():
# For each simulation movement
for simulation_movement in movement.getDeliveryRelatedValueList():
result.add(simulation_movement.getExplanationUid()) # XXX-JPS use new API later
......@@ -117,7 +117,7 @@ class ExplanationCache:
local_path_dict[simulation_movement_id] = simulation_movement
# For each delivery movement
for movement in self.getDeliveryMovementList():
for movement in self._getDeliveryMovementList():
# For each simulation movement
for simulation_movement in movement.getDeliveryRelatedValueList():
updatePathDict(simulation_movement)
......@@ -133,7 +133,7 @@ class ExplanationCache:
else:
browsePathDict('%s/%s' % (prefix, key), value) # Recursing with string append is slow XXX-JPS
browsePathDict('', path_dict)
browsePathDict('/', path_dict)
self.explanation_path_pattern_cache = result
return result
......@@ -143,7 +143,7 @@ class ExplanationCache:
"""
return self.getSimulationMovementList(causality_uid=business_path.getUid())
def getSimulationMovementList(self, **kw)
def getSimulationMovementList(self, **kw):
"""Search Simulation Movements related to our explanation.
Cache result so that the second time we saarch for the same
list we need not involve the catalog again.
......@@ -157,9 +157,48 @@ class ExplanationCache:
**kw)
return self.simulation_movement_cache[kw_tuple]
def geBusinessPathClosure(business_path):
"""Creates a Business Process by filtering out all Business Path
in self which are not related to a simulation movement
which is either or parent or a child of explanation simulations movements
caused by 'business_path'
cache keys: business_path (simple) then path_set
XXX-JPS PSEUDO CODE
"""
new_business_process = BusinessProcess()
accepted_path = []
explanation_cache = _getExplanationCache(explanation)
path_list = explanation_cache.getSimulationPathPatternList()
path_list = map(lambda x:x[0:-1], path_list) # Remove trailing %
path_set = set()
for simulation_movement in business_path.\
_getExplanationRelatedSimulationMovementValueList(explanation):
simulation_path = simulation_movement.getPath()
for path in path_list:
if simulation_path.startswith(path):
path_set.add(path) # This selection path is part of explanation
for business_path in self.getBusinessPathValueList():
if business_path.hasMovementsIn(explanation, path_set):
accepted_path.append(business_path)
new_business_process.addValueList(business_path)
return new_business_process
def _getExplanationCache(explanation):
if explanation.isinstance(ExplanationCache):
return explanation
# Return cached value if any
tv = getTransactionalVariable(explanation)
if tv.get('explanation_cache', None) is None:
tv['explanation_cache'] = ExplanationCache(explanation)
return tv.get('explanation_cache')
def _getBusinessPathClosure(explanation, business_path):
"""Returns a
"""
explanation_cache = _getExplanationCache(explanation)
return explanation_cache.getBusinessPathClosure(business_path)
......@@ -59,6 +59,15 @@ class IBusinessPath(Interface):
movement -- a Simulation Movement
"""
def getCompletionDate(explanation):
"""Returns the date of completion of the movemnet
based on paremeters of the business path. This completion date can be
the start date, the stop date, the date of a given workflow transition
on the explaining delivery, etc.
XXXXXXXXXXXXXXXx
"""
def getExpectedQuantity(amount):
"""Returns the new quantity for the provided amount taking
into account the efficiency or the quantity defined on the business path.
......@@ -116,6 +125,10 @@ class IBusinessPath(Interface):
not yet completed (ex. in 'delivered' state).
"""
def isDelivered(explanation):
"""XXX
"""
def build(explanation):
"""Builds all related movements in the simulation using the builders
defined on the Business Path
......
......@@ -231,7 +231,7 @@ class ITradeStateProcess(Interface):
implicitely defines a simulation subtree
"""
def getLatestPartiallyCompletedTradeState(explanation):
def getLatestPartiallyCompletedTradeStateList(explanation):
"""Returns the list of completed trade states which predecessor
states are completed and for which no successor state
is partially completed in the context of given explanation.
......
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