Commit 275e4b38 authored by Łukasz Nowak's avatar Łukasz Nowak

Avoid isBuildable API and backward compatbility change.

Business Link can be found on movement by using predicate, so there is no need
to require it while calling isBuildable.

And in case if no Business Link is found: directly on indirectly, drop to
previous behaviour.
parent 3826a2f9
...@@ -98,7 +98,7 @@ class SimulatedDeliveryBuilder(BuilderMixin): ...@@ -98,7 +98,7 @@ class SimulatedDeliveryBuilder(BuilderMixin):
pass pass
@UnrestrictedMethod @UnrestrictedMethod
def searchMovementList(self, applied_rule_uid=None, business_link_list=None, **kw): def searchMovementList(self, applied_rule_uid=None, **kw):
""" """
defines how to query all Simulation Movements which meet certain criteria defines how to query all Simulation Movements which meet certain criteria
(including the above path path definition). (including the above path path definition).
...@@ -112,24 +112,18 @@ class SimulatedDeliveryBuilder(BuilderMixin): ...@@ -112,24 +112,18 @@ class SimulatedDeliveryBuilder(BuilderMixin):
# Search only child movement from this applied rule # Search only child movement from this applied rule
if applied_rule_uid is not None: if applied_rule_uid is not None:
kw['parent_uid'] = applied_rule_uid kw['parent_uid'] = applied_rule_uid
if business_link_list is None:
business_link_list = []
# XXX Add profile query # XXX Add profile query
# Add resource query # Add resource query
if self.getResourcePortalType() not in ('', None): if self.getResourcePortalType() not in ('', None):
kw['resourceType'] = self.getResourcePortalType() kw['resourceType'] = self.getResourcePortalType()
if self.getSimulationSelectMethodId() in ['', None]: if self.getSimulationSelectMethodId() in ['', None]:
prefilter_movement_list = [x.getObject() for x in self.portal_catalog(**kw)] movement_list = [x.getObject() for x in self.portal_catalog(**kw)]
else: else:
select_method = getattr(self.getPortalObject(), self.getSimulationSelectMethodId()) select_method = getattr(self.getPortalObject(), self.getSimulationSelectMethodId())
prefilter_movement_list = select_method(**kw) movement_list = select_method(**kw)
# XXX Use buildSQLQuery will be better # XXX Use buildSQLQuery will be better
movement_list = [] movement_list = [x for x in movement_list if \
for movement in prefilter_movement_list: x.getDeliveryValueList()==[] and x.isBuildable()]
for business_link in business_link_list:
if movement.isBuildable(business_link):
if movement.getDeliveryValueList()==[]:
movement_list.append(movement)
# XXX Add predicate test # XXX Add predicate test
# XXX FIXME Check that there is no double in the list # XXX FIXME Check that there is no double in the list
# Because we can't trust simulation_select_method # Because we can't trust simulation_select_method
......
...@@ -615,9 +615,19 @@ class SimulationMovement(PropertyRecordableMixin, Movement, ExplainableMixin): ...@@ -615,9 +615,19 @@ class SimulationMovement(PropertyRecordableMixin, Movement, ExplainableMixin):
else: else:
return getTreeDelivered(self, ignore_first=ignore_first) return getTreeDelivered(self, ignore_first=ignore_first)
def _getBusinessLinkByPredicate(self):
business_link_list = self.asComposedDocument().getBusinessLinkValueList(
context=self)
if len(business_link_list) > 1:
raise ValueError('Simulation Movement %s composed document matched more '
'than one Business Link.' % self.getPath())
if len(business_link_list) == 0:
return None
return business_link_list[0]
security.declareProtected(Permissions.AccessContentsInformation, security.declareProtected(Permissions.AccessContentsInformation,
'isBuildable') 'isBuildable')
def isBuildable(self, business_link): def isBuildable(self):
"""Simulation Movement buildable logic""" """Simulation Movement buildable logic"""
if self.getDelivery(): if self.getDelivery():
# already delivered # already delivered
...@@ -625,25 +635,27 @@ class SimulationMovement(PropertyRecordableMixin, Movement, ExplainableMixin): ...@@ -625,25 +635,27 @@ class SimulationMovement(PropertyRecordableMixin, Movement, ExplainableMixin):
# might be buildable - business path dependent # might be buildable - business path dependent
explanation_value = self.getExplanationValue() explanation_value = self.getExplanationValue()
if business_link is None or explanation_value is None: if explanation_value is None:
# without Business Link and explanation it is impossible to check # Without explanation movements are buildable
# precisely if movement is buildable return True
# Note: It breaks compatilibity with old simulation code which did not
# use Business Process at all, here assumption is inverted
return False
## XXX Code below following line has been moved to BusinessPath (cf r37116) ## XXX Code below following line has been moved to BusinessPath (cf r37116)
#return len(business_path.filterBuildableMovementList([self])) == 1 #return len(business_path.filterBuildableMovementList([self])) == 1
predecessor_state = business_link.getPredecessor() business_link_value = self.getCausalityValue(portal_type='Business Link')
if business_link_value is None:
business_link_value = self._getBusinessLinkByPredicate()
if business_link_value is None:
# No directly on indirectly set Business Link -- old simulation movement
return True
predecessor_state = business_link_value.getPredecessor()
if predecessor_state is None: if predecessor_state is None:
# first one, can be built # first one, can be built
return True # XXX-JPS wrong cause root is marked return True # XXX-JPS wrong cause root is marked
# movement is not built, and corresponding business path # movement is not built, and corresponding business path
# has predecessors: check movements related to those predecessors! # has predecessors: check movements related to those predecessors!
composed_document = self.asComposedDocument() predecessor_link_list = self.asComposedDocument().getBusinessLinkValueList(
predecessor_link_list = composed_document.getBusinessLinkValueList(
successor=predecessor_state) successor=predecessor_state)
def isBuiltAndCompleted(simulation, path): def isBuiltAndCompleted(simulation, path):
...@@ -657,20 +669,14 @@ class SimulationMovement(PropertyRecordableMixin, Movement, ExplainableMixin): ...@@ -657,20 +669,14 @@ class SimulationMovement(PropertyRecordableMixin, Movement, ExplainableMixin):
causality_dict = {} causality_dict = {}
current = self.getParentValue().getParentValue() current = self.getParentValue().getParentValue()
while current.getPortalType() == "Simulation Movement": while current.getPortalType() == "Simulation Movement":
business_link = current.getCausality(portal_type='Business Link') current_business_link = current.getCausality(portal_type='Business Link')
if business_link is None: if current_business_link is None:
# no direct business link set on movement, use predicate to find one current_business_link_value = current._getBusinessLinkByPredicate()
business_link_list = composed_document.getBusinessLinkValueList( if current_business_link_value is None:
context=current) raise ValueError('Simulation Movement %s has no Business Link '
if len(business_link_list) > 1: 'related and no Business Link from composed document matches'%
raise ValueError('Business Link predicate matches too many ' current.getPath())
'movements.') causality_dict[current_business_link_value.getRelativeUrl()] = current
if len(business_link_list) == 0:
raise ValueError('Simulation Movement has no Business Link related '
'and no Business Link from current Business Process matches')
business_link = business_link_list[0].getRelativeUrl()
causality_dict[business_link] = current
current = current.getParentValue().getParentValue() current = current.getParentValue().getParentValue()
remaining_path_set = set() remaining_path_set = set()
......
...@@ -126,7 +126,6 @@ class BuilderMixin(XMLObject, Amount, Predicate): ...@@ -126,7 +126,6 @@ class BuilderMixin(XMLObject, Amount, Predicate):
kw['path'] = explanation_cache.getSimulationPathPatternList() kw['path'] = explanation_cache.getSimulationPathPatternList()
if business_link is not None: if business_link is not None:
kw['causality_uid'] = business_link.getUid() kw['causality_uid'] = business_link.getUid()
business_link_value_list = [business_link]
elif kw.get('causality_uid') is None: elif kw.get('causality_uid') is None:
business_link_value_list = self.getRelatedBusinessLinkValueList() business_link_value_list = self.getRelatedBusinessLinkValueList()
if len(business_link_value_list) > 0: if len(business_link_value_list) > 0:
...@@ -135,7 +134,6 @@ class BuilderMixin(XMLObject, Amount, Predicate): ...@@ -135,7 +134,6 @@ class BuilderMixin(XMLObject, Amount, Predicate):
movement_list = self.searchMovementList( movement_list = self.searchMovementList(
delivery_relative_url_list=delivery_relative_url_list, delivery_relative_url_list=delivery_relative_url_list,
applied_rule_uid=applied_rule_uid, applied_rule_uid=applied_rule_uid,
business_link_list=business_link_value_list,
**kw) **kw)
if not movement_list: if not movement_list:
return [] return []
......
...@@ -189,8 +189,7 @@ class MovementCollectionUpdaterMixin: ...@@ -189,8 +189,7 @@ class MovementCollectionUpdaterMixin:
modified_movement_list.append(movement) modified_movement_list.append(movement)
for movement in modified_movement_list: for movement in modified_movement_list:
# for each touched non buildable movement reset causality_list # for each touched non buildable movement reset causality_list
if not movement.isBuildable(movement.getCausalityValue( if not movement.isBuildable():
portal_type='Business Link')):
movement.setCausalityList([q.getRelativeUrl() for q in \ movement.setCausalityList([q.getRelativeUrl() for q in \
movement.getCausalityValueList() if q.getPortalType() \ movement.getCausalityValueList() if q.getPortalType() \
not in self.getPortalBusinessLinkTypeList()]) not in self.getPortalBusinessLinkTypeList()])
...@@ -437,7 +437,7 @@ class TestTradeModelLine(TestTradeModelLineMixin): ...@@ -437,7 +437,7 @@ class TestTradeModelLine(TestTradeModelLineMixin):
sm = result_dict.pop(use) sm = result_dict.pop(use)
business_link_list = sm.asComposedDocument().getBusinessLinkValueList(context=sm) business_link_list = sm.asComposedDocument().getBusinessLinkValueList(context=sm)
self.assertEqual(len(business_link_list), 1) self.assertEqual(len(business_link_list), 1)
is_buildable = sm.isBuildable(business_link_list[0]) is_buildable = sm.isBuildable()
self.assertEqual(str(sm.getTotalPrice() or 0.0), str(total_price)) self.assertEqual(str(sm.getTotalPrice() or 0.0), str(total_price))
if is_buildable: if is_buildable:
self.assertEqual(3, len(sm.getCausalityValueList())) self.assertEqual(3, len(sm.getCausalityValueList()))
......
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