Commit ead87b6a authored by Julien Muchembled's avatar Julien Muchembled

composition: make objectValues return original objects instead of temporary copies

git-svn-id: https://svn.erp5.org/repos/public/erp5/trunk@34285 20353a03-c40f-0410-a6d1-a30d3c3de9de
parent 06126d39
...@@ -31,6 +31,7 @@ from AccessControl import ClassSecurityInfo ...@@ -31,6 +31,7 @@ from AccessControl import ClassSecurityInfo
from Acquisition import aq_base from Acquisition import aq_base
from Products.ERP5Type import Permissions from Products.ERP5Type import Permissions
from Products.ERP5Type.Cache import transactional_cached from Products.ERP5Type.Cache import transactional_cached
from Products.ERP5Type.Utils import sortValueList
from Products.ERP5.Document.Predicate import Predicate from Products.ERP5.Document.Predicate import Predicate
from Products.ZSQLCatalog.SQLCatalog import Query, ComplexQuery from Products.ZSQLCatalog.SQLCatalog import Query, ComplexQuery
...@@ -78,7 +79,6 @@ def _getEffectiveModel(self, start_date=None, stop_date=None): ...@@ -78,7 +79,6 @@ def _getEffectiveModel(self, start_date=None, stop_date=None):
def _findPredicateList(*container_list): def _findPredicateList(*container_list):
predicate_list = [] predicate_list = []
reference_dict = {} reference_dict = {}
line_count = 0
for container in container_list: for container in container_list:
for ob in container.contentValues(): for ob in container.contentValues():
if isinstance(ob, Predicate): if isinstance(ob, Predicate):
...@@ -89,9 +89,7 @@ def _findPredicateList(*container_list): ...@@ -89,9 +89,7 @@ def _findPredicateList(*container_list):
if reference in reference_set: if reference in reference_set:
continue continue
reference_set.add(reference) reference_set.add(reference)
id = str(line_count) predicate_list.append(ob)
line_count += 1
predicate_list.append(aq_base(ob.asContext(id=id)))
return predicate_list return predicate_list
...@@ -101,20 +99,13 @@ class asComposedDocument(object): ...@@ -101,20 +99,13 @@ class asComposedDocument(object):
The returned value is a temporary copy of the given object. The list of all The returned value is a temporary copy of the given object. The list of all
effective models (specialise values) is stored in a private attribute. effective models (specialise values) is stored in a private attribute.
Collecting predicates (from effective models) is done lazily. Predicates can Collecting predicates (from effective models) is done lazily. Predicates can
be accessed through standard Folder API (ex: contentValues). be accessed through contentValues/objectValues.
""" """
def __new__(cls, orig_self): def __new__(cls, orig_self):
if '_effective_model_list' in orig_self.__dict__:
assert False, "not used yet (remove this line if needed)"
return orig_self # if asComposedDocument is called on a composed
# document after any access to its subobjects
self = orig_self.asContext() self = orig_self.asContext()
self._initBTrees()
base_class = self.__class__ base_class = self.__class__
# this allows to intercept first access to '_folder_handler' self.__class__ = type(base_class.__name__, (cls, base_class), {})
self.__class__ = type(base_class.__name__, (cls, base_class),
{'__module__': base_class.__module__})
self._effective_model_list = orig_self._findEffectiveSpecialiseValueList() self._effective_model_list = orig_self._findEffectiveSpecialiseValueList()
return self return self
...@@ -125,20 +116,29 @@ class asComposedDocument(object): ...@@ -125,20 +116,29 @@ class asComposedDocument(object):
def asComposedDocument(self): def asComposedDocument(self):
assert False, "not used yet (remove this line if needed)" assert False, "not used yet (remove this line if needed)"
return self # if asComposedDocument is called on a composed return self
# document before any access to its subobjects
@property @property
def _folder_handler(self): def _folder_handler(self):
# restore the original class assert False
# because we don't need to hook _folder_handler anymore
self.__class__ = self.__class__.__bases__[1] def __getattr__(self, name):
# we filter out objects without any subobject to make the cache of raise AttributeError(name)
# '_findPredicateList' useful. Otherwise, the key would be always different
# (starting with 'orig_self'). def objectValues(self, spec=None, meta_type=None, portal_type=None,
for ob in _findPredicateList(*filter(len, self._effective_model_list)): sort_on=None, sort_order=None, checked_permission=None,
self._setOb(ob.id, ob) **kw):
return self._folder_handler assert spec is meta_type is checked_permission is None, "not useful yet"
object_list = getattr(aq_base(self), '_predicate_list', None)
if object_list is None:
object_list = _findPredicateList(*filter(len, self._effective_model_list))
self._predicate_list = object_list
if portal_type is not None:
if isinstance(portal_type, str):
portal_type = (portal_type,)
object_list = filter(lambda x: x.getPortalType() in portal_type,
object_list)
return sortValueList(object_list, sort_on, sort_order, **kw)
class CompositionMixin: class CompositionMixin:
......
...@@ -2476,8 +2476,6 @@ class TestTradeModelLine(TestTradeModelLineMixin): ...@@ -2476,8 +2476,6 @@ class TestTradeModelLine(TestTradeModelLineMixin):
# change target level to `movement`. # change target level to `movement`.
tax.edit(target_level=TARGET_LEVEL_MOVEMENT) tax.edit(target_level=TARGET_LEVEL_MOVEMENT)
transaction.commit() # flush transactional cache
amount_list = trade_condition.getAggregatedAmountList(order) amount_list = trade_condition.getAggregatedAmountList(order)
self.assertEqual(2, len(amount_list)) self.assertEqual(2, len(amount_list))
self.assertEqual(1, self.assertEqual(1,
...@@ -2578,7 +2576,6 @@ return current_movement ...@@ -2578,7 +2576,6 @@ return current_movement
extra_fee_a.edit(target_level=TARGET_LEVEL_DELIVERY) extra_fee_a.edit(target_level=TARGET_LEVEL_DELIVERY)
extra_fee_b.edit(target_level=TARGET_LEVEL_DELIVERY) extra_fee_b.edit(target_level=TARGET_LEVEL_DELIVERY)
tax.edit(target_level=TARGET_LEVEL_DELIVERY) tax.edit(target_level=TARGET_LEVEL_DELIVERY)
transaction.commit() # flush transactional cache
amount_list = trade_condition.getAggregatedAmountList(order) amount_list = trade_condition.getAggregatedAmountList(order)
self.assertEqual(4, len(amount_list)) self.assertEqual(4, len(amount_list))
self.assertEqual(100 + 1 - 10 + 1500*0.05, self.assertEqual(100 + 1 - 10 + 1500*0.05,
...@@ -2637,7 +2634,6 @@ return current_movement ...@@ -2637,7 +2634,6 @@ return current_movement
# change tax trade model line to `movement` level # change tax trade model line to `movement` level
tax.edit(target_level=TARGET_LEVEL_MOVEMENT) tax.edit(target_level=TARGET_LEVEL_MOVEMENT)
transaction.commit() # flush transactional cache
def getTotalAmount(amount_list): def getTotalAmount(amount_list):
result = 0 result = 0
......
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