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