Commit fb337da4 authored by Julien Muchembled's avatar Julien Muchembled

TradeCondition: merge and simplify find{Effective,}SpecialiseValueList

git-svn-id: https://svn.erp5.org/repos/public/erp5/trunk@34023 20353a03-c40f-0410-a6d1-a30d3c3de9de
parent 1aca044a
...@@ -30,6 +30,7 @@ ...@@ -30,6 +30,7 @@
# #
############################################################################## ##############################################################################
from collections import deque
from AccessControl import ClassSecurityInfo from AccessControl import ClassSecurityInfo
from Products.ERP5Type import Permissions, PropertySheet, interfaces from Products.ERP5Type import Permissions, PropertySheet, interfaces
...@@ -123,45 +124,44 @@ class TradeCondition(Path, Transformation, XMLMatrix): ...@@ -123,45 +124,44 @@ class TradeCondition(Path, Transformation, XMLMatrix):
'findSpecialiseValueList') 'findSpecialiseValueList')
def findSpecialiseValueList(self, context, portal_type_list=None): def findSpecialiseValueList(self, context, portal_type_list=None):
"""Returns a list of specialised objects representing inheritance tree. """Returns a list of specialised objects representing inheritance tree.
Uses Breadth First Search.
""" """
if portal_type_list is None: return self.findEffectiveSpecialiseValueList(context,
portal_type_list = self.getPortalAmountGeneratorTypeList() portal_type_list=portal_type_list)
if context.getPortalType() in portal_type_list:
specialise_value_list = [context]
visited_trade_condition_list = [context]
else:
specialise_value_list = context.getSpecialiseValueList()
visited_trade_condition_list = context.getSpecialiseValueList(\
portal_type=portal_type_list)
while len(specialise_value_list) != 0: security.declareProtected(Permissions.AccessContentsInformation,
specialise = specialise_value_list.pop(0) 'findEffectiveSpecialiseValueList')
def findEffectiveSpecialiseValueList(self, context, start_date=None,
stop_date=None, portal_type_list=None):
"""Return a list of effective specialised objects that is the
inheritance tree.
An effective object is an object which have start_date and stop_date
included to the range of the given parameters start_date and stop_date.
This algorithm uses Breadth First Search.
"""
portal_type_set = set(portal_type_list or
self.getPortalAmountGeneratorTypeList())
def getEffectiveModel(model):
try: try:
# all children getEffectiveModel = model.getEffectiveModel
child_specialised_value_list = specialise.getSpecialiseValueList()
# only children that match the portal_type given
child_visited_trade_condition_set = set(specialise.\
getSpecialiseValueList(portal_type=portal_type_list))
except AttributeError: except AttributeError:
# it is possible, that specialised object cannot be specialised return model
# anymore return getEffectiveModel(start_date, stop_date)
continue filtered_list = []
# Use a set for faster lookups. We do not use sets everywhere specialise_value_list = deque((getEffectiveModel(context),))
# because search order does matter specialise_value_set = set(specialise_value_list)
intersection = set(child_specialised_value_list).intersection(\ specialise_index = 0
set(visited_trade_condition_list)) while specialise_value_list:
for model in child_specialised_value_list: context = specialise_value_list.popleft()
# don't add model that have already been visited. This permit to if context.getPortalType() in portal_type_set:
# visit all the tree and to prevent having circular dependency filtered_list.append(context)
if model not in intersection: for specialise_value in map(getEffectiveModel,
specialise_value_list.append(model) context.getSpecialiseValueList()):
# only add those who matches the portal type given if specialise_value not in specialise_value_set:
if model in child_visited_trade_condition_set: specialise_value_set.add(specialise_value)
visited_trade_condition_list.append(model) specialise_value_list.append(specialise_value)
return filtered_list
return visited_trade_condition_list
security.declareProtected(Permissions.AccessContentsInformation, security.declareProtected(Permissions.AccessContentsInformation,
'getTradeModelLineComposedList') 'getTradeModelLineComposedList')
...@@ -338,66 +338,6 @@ class TradeCondition(Path, Transformation, XMLMatrix): ...@@ -338,66 +338,6 @@ class TradeCondition(Path, Transformation, XMLMatrix):
reference_dict[obj.getProperty('reference', obj.getId())] = obj.getId() reference_dict[obj.getProperty('reference', obj.getId())] = obj.getId()
return reference_dict return reference_dict
security.declareProtected(Permissions.AccessContentsInformation,
'findEffectiveSpecialiseValueList')
def findEffectiveSpecialiseValueList(self, context, start_date=None,
stop_date=None, portal_type_list=None, effective_model_list=None):
"""Return a list of effective specialised objects that is the
inheritance tree.
An effective object is an object which have start_date and stop_date
included to the range of the given parameters start_date and stop_date.
If no start_date and stop_date are provided, findSpecialiseValueList
result is returned.
This algorithm uses Breadth First Search.
"""
if start_date is None and stop_date is None:
# if dates are not defined, return findSpecialiseValueList result
return self.findSpecialiseValueList(context=context)
if effective_model_list is None:
effective_model_list = []
visited_trade_condition_list = []
if portal_type_list is None:
portal_type_list = self.getPortalAmountGeneratorTypeList()
if context.getPortalType() in portal_type_list:
effective_model = context.getEffectiveModel(
start_date=start_date, stop_date=stop_date)
if effective_model is not None:
effective_model_list = [effective_model]
visited_trade_condition_list = [effective_model]
else:
model_list = context.getSpecialiseValueList(\
portal_type=portal_type_list)
effective_model_list = [model.getEffectiveModel(\
start_date=start_date, stop_date=stop_date) for model in\
model_list]
visited_trade_condition_list = [model.getEffectiveModel(\
start_date=start_date, stop_date=stop_date) for model in\
model_list]
# remove None models
effective_model_list = [ob for ob in effective_model_list if ob is not None]
while len(effective_model_list) != 0:
specialise = effective_model_list.pop(0)
effective_specialise = specialise.getEffectiveModel(start_date=start_date,
stop_date=stop_date)
child_list = []
if effective_specialise is not None:
child_list = effective_specialise.getSpecialiseValueList(\
portal_type=portal_type_list)
intersection = set(child_list).intersection(\
set(visited_trade_condition_list))
for model in child_list:
effective_model = model.getEffectiveModel(start_date=start_date,
stop_date=stop_date)
if effective_model is not None and effective_model not in intersection:
# don't add model that are already been visited. This permit to
# visit all model tree, and to not have circular dependency
effective_model_list.append(effective_model)
visited_trade_condition_list.append(effective_model)
return visited_trade_condition_list
security.declareProtected(Permissions.AccessContentsInformation, security.declareProtected(Permissions.AccessContentsInformation,
'getInheritanceReferenceDict') 'getInheritanceReferenceDict')
def getInheritanceReferenceDict(self, portal_type_list, def getInheritanceReferenceDict(self, portal_type_list,
...@@ -463,9 +403,6 @@ class TradeCondition(Path, Transformation, XMLMatrix): ...@@ -463,9 +403,6 @@ class TradeCondition(Path, Transformation, XMLMatrix):
def getModelInheritanceEffectiveProperty(self, paysheet, property_name): def getModelInheritanceEffectiveProperty(self, paysheet, property_name):
"""Get a property from an effective model """Get a property from an effective model
""" """
v = self.getProperty(property_name)
if v:
return v
model_list = self.findEffectiveSpecialiseValueList(context=self, model_list = self.findEffectiveSpecialiseValueList(context=self,
start_date=paysheet.getStartDate(), stop_date=paysheet.getStopDate()) start_date=paysheet.getStartDate(), stop_date=paysheet.getStopDate())
for specialised_model in model_list: for specialised_model in model_list:
......
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