Commit 589f0e5f authored by Julien Muchembled's avatar Julien Muchembled

MappedValue: remove xxxProperty/edit methods to revert to pre-39918 behaviour

Note that type class of Transformation {Optional,Transformed Resource} Resource
is changed to a document inheriting Amount because they are chained to
conversion_interaction_workflow. Otherwise, _setProperty (that is not redefined
anymore) is would point to _doNothing.
The choice of TransformedResource class is questionable. Alternative would be
AmountFilter, or a new class.

This reapplies r41691

git-svn-id: https://svn.erp5.org/repos/public/erp5/trunk@42273 20353a03-c40f-0410-a6d1-a30d3c3de9de
parent bd8be8ad
...@@ -22,10 +22,6 @@ ...@@ -22,10 +22,6 @@
<key> <string>description</string> </key> <key> <string>description</string> </key>
<value> <string>Transformation Operation Cell</string> </value> <value> <string>Transformation Operation Cell</string> </value>
</item> </item>
<item>
<key> <string>factory</string> </key>
<value> <string>addMappedValue</string> </value>
</item>
<item> <item>
<key> <string>filter_content_types</string> </key> <key> <string>filter_content_types</string> </key>
<value> <int>1</int> </value> <value> <int>1</int> </value>
...@@ -58,6 +54,10 @@ ...@@ -58,6 +54,10 @@
<key> <string>title</string> </key> <key> <string>title</string> </key>
<value> <string></string> </value> <value> <string></string> </value>
</item> </item>
<item>
<key> <string>type_class</string> </key>
<value> <string>TransformedResource</string> </value>
</item>
</dictionary> </dictionary>
</pickle> </pickle>
</record> </record>
......
...@@ -22,10 +22,6 @@ ...@@ -22,10 +22,6 @@
<key> <string>description</string> </key> <key> <string>description</string> </key>
<value> <string>Transformation Transformed Resource Cell</string> </value> <value> <string>Transformation Transformed Resource Cell</string> </value>
</item> </item>
<item>
<key> <string>factory</string> </key>
<value> <string>addMappedValue</string> </value>
</item>
<item> <item>
<key> <string>filter_content_types</string> </key> <key> <string>filter_content_types</string> </key>
<value> <int>1</int> </value> <value> <int>1</int> </value>
...@@ -58,6 +54,10 @@ ...@@ -58,6 +54,10 @@
<key> <string>title</string> </key> <key> <string>title</string> </key>
<value> <string></string> </value> <value> <string></string> </value>
</item> </item>
<item>
<key> <string>type_class</string> </key>
<value> <string>TransformedResource</string> </value>
</item>
</dictionary> </dictionary>
</pickle> </pickle>
</record> </record>
......
548 549
\ No newline at end of file \ No newline at end of file
...@@ -39,10 +39,6 @@ _MARKER = [] ...@@ -39,10 +39,6 @@ _MARKER = []
class MappedValue(Predicate): class MappedValue(Predicate):
""" """
A MappedValue allows to associate a value to a predicate A MappedValue allows to associate a value to a predicate
XXX Why do we redefine xxxProperty methods ?
When a property is defined by a property sheet with a specific storage_id,
they break accessors of this property when a value is mapped to it.
""" """
meta_type = 'ERP5 Mapped Value' meta_type = 'ERP5 Mapped Value'
portal_type = 'Mapped Value' portal_type = 'Mapped Value'
...@@ -62,89 +58,19 @@ class MappedValue(Predicate): ...@@ -62,89 +58,19 @@ class MappedValue(Predicate):
# Declarative interfaces # Declarative interfaces
zope.interface.implements(interfaces.IMappedValue, zope.interface.implements(interfaces.IMappedValue,
) )
security.declareProtected(Permissions.AccessContentsInformation, 'getMappedValueBaseCategoryList')
security.declareProtected(Permissions.AccessContentsInformation,
'getMappedValueBaseCategoryList')
def getMappedValueBaseCategoryList(self, d=_MARKER): def getMappedValueBaseCategoryList(self, d=_MARKER):
if TRANSFORMATION_FIX: if TRANSFORMATION_FIX:
# Fix Mapped Value Objects which forgot to define their Mapped Base Categories # Fix Mapped Value Objects which forgot to define their Mapped Base Categories
if not self._baseGetMappedValueBaseCategoryList(): if not self._baseGetMappedValueBaseCategoryList():
if self.getParentValue().getParentValue().getPortalType() == 'Transformation': if self.getParentValue().getParentValue().getPortalType() == 'Transformation':
base_category_dict = {} base_category_set = set()
for category in self.getCategoryList(): for category in self.getCategoryList():
# XXX-JPS additional test required to prevent taking too much ? # XXX-JPS additional test required to prevent taking too much ?
base_category_dict[category.split('/')[0]] = None base_category_set.add(category.split('/')[0])
self._setMappedValueBaseCategoryList(base_category_dict.keys()) self._setMappedValueBaseCategoryList(list(base_category_set))
if d is _MARKER: if d is _MARKER:
return self._baseGetMappedValueBaseCategoryList(d=d) return self._baseGetMappedValueBaseCategoryList(d=d)
return self._baseGetMappedValueBaseCategoryList() return self._baseGetMappedValueBaseCategoryList()
security.declareProtected( Permissions.AccessContentsInformation, 'getProperty' )
def getProperty(self, key, d=_MARKER, **kw):
"""
Use local property instead of calling (acquired) accessor
whenever key is provided by the mapped value.
TODO:
- handle list properties (key ends with _list)
- add unit tests
"""
if key in self.getMappedValuePropertyList():
result = getattr(aq_base(self), key, _MARKER)
if result is not _MARKER:
return result
if d is _MARKER:
return Predicate.getProperty(self, key, **kw) # XXX-JPS I would prefer to use always getProperty
# Is there any reason to overload ?
return Predicate.getProperty(self, key, d=d, **kw)
def getPropertyList(self, key, d=None):
"""
Use local property instead of calling (acquired) accessor
whenever key is provided by the mapped value.
TODO:
- add unit tests
"""
if key in self.getMappedValuePropertyList():
result = getattr(aq_base(self), key, _MARKER)
if result is not _MARKER:
return result
if d is None:
return Predicate.getPropertyList(self, key)
return Predicate.getPropertyList(self, key, d=d)
def _setProperty(self, key, value, type=None, **kw):
"""
Use local property instead of calling (acquired) accessor
whenever key is provided by the mapped value.
TODO:
- handle type
- add unit tests
"""
if key in self.getMappedValuePropertyList():
return setattr(self, key, value)
return Predicate._setProperty(self, key, value, type=type, **kw)
# Check is this method should also be overriden
#def _setPropValue(self, key, value, **kw):
def hasProperty(self, key):
"""
Use local property instead of calling (acquired) accessor
whenever key is provided by the mapped value.
"""
if key in self.getMappedValuePropertyList():
return getattr(self, key, _MARKER) is not _MARKER
return Predicate.hasProperty(self, key)
def _edit(self, **kw):
# We must first prepare the mapped value before we do the edit
edit_order = ['mapped_value_property_list',
'default_mapped_value_property',
'mapped_value_property',
'mapped_value_property_set']
i = len(edit_order)
edit_order += [x for x in kw.pop('edit_order', ()) if x not in edit_order]
# Base._edit updates unordered properties first
edit_order[i:i] = [x for x in kw if x not in edit_order]
return Predicate._edit(self, edit_order=edit_order, **kw)
...@@ -68,10 +68,9 @@ class TradeModelCell(TradeModelLine): ...@@ -68,10 +68,9 @@ class TradeModelCell(TradeModelLine):
""" """
return 0 return 0
security.declareProtected(Permissions.AccessContentsInformation, def getQuantity(self):
'getPrice') """Overridden getter to return None instead 0 if undefined"""
def getPrice(self): return self._baseGetQuantity(None)
return self._baseGetPrice()
security.declareProtected(Permissions.AccessContentsInformation, security.declareProtected(Permissions.AccessContentsInformation,
'getTotalPrice') 'getTotalPrice')
......
...@@ -67,11 +67,3 @@ class TradeModelLine(AmountGeneratorLine): ...@@ -67,11 +67,3 @@ class TradeModelLine(AmountGeneratorLine):
def getMappedValueBaseCategoryList(self): def getMappedValueBaseCategoryList(self):
return self._baseGetMappedValueBaseCategoryList() or ('trade_phase', 'use',) return self._baseGetMappedValueBaseCategoryList() or ('trade_phase', 'use',)
#
security.declareProtected(Permissions.AccessContentsInformation,
'getPrice')
def getPrice(self):
"""
"""
return self._baseGetPrice()
...@@ -65,15 +65,20 @@ class TransformedResource(AmountGeneratorLine): ...@@ -65,15 +65,20 @@ class TransformedResource(AmountGeneratorLine):
def getMappedValuePropertyList(self): def getMappedValuePropertyList(self):
result = self._baseGetMappedValuePropertyList() result = self._baseGetMappedValuePropertyList()
if not result: if not result:
# Since MappedValue does not inherit Amount, and type class of
# Transformation {Operation,Transformed Resource} Cell
# was changed to TransformedResource as a workaround,
# we also need to check if 'self' has a quantity.
# Otherwise, generated amounts could have 0 quantity
# (overridden by cells that only define variation).
result = ['quantity'] result = ['quantity']
# Take into account variation_property_list for each variation # Take into account variation_property_list for each variation
# for which hasProperty is true... # for which hasProperty is true...
# FIXME: Why the resource and not the model line itself ? Or both ?? # FIXME: Why the resource and not the model line itself ? Or both ??
resource = self.getDefaultResourceValue() resource = self.getDefaultResourceValue()
if resource is not None: if resource is not None:
# XXX Using getattr directly is a hack. See MappedValue.__doc__ result += resource.getVariationPropertyList()
result.extend(key for key in resource.getVariationPropertyList() result = filter(self.hasProperty, result)
if getattr(self, key, self) is not self)
return result return result
def getMappedValueBaseCategoryList(self): def getMappedValueBaseCategoryList(self):
......
...@@ -132,29 +132,33 @@ class TestTransformation(TestTransformationMixin, BaseTestUnitConversion): ...@@ -132,29 +132,33 @@ class TestTransformation(TestTransformationMixin, BaseTestUnitConversion):
have additionnals propertysheets on transformations lines and that used have additionnals propertysheets on transformations lines and that used
variation properties variation properties
""" """
# Only for testing purpose, use a property sheet that has nothing to ps_id = self._testMethodName
# do with component. It would have been possible to create a new property_sheet = self.portal.portal_property_sheets.newContent(
# property sheet for this test. ps_id, portal_type='Property Sheet')
property_sheet.newContent(portal_type='Standard Property',
reference='foo',
storage_id='bar',
elementary_type='boolean')
# When one do that, the property sheet should be added to many other types # When one do that, the property sheet should be added to many other types
# like movements, order lines and so on. # like movements, order lines and so on.
self._addPropertySheet('Amount', 'Bug') self._addPropertySheet('Amount', ps_id)
self._addPropertySheet(self.transformed_resource_portal_type, 'Bug') self._addPropertySheet(self.transformed_resource_portal_type, ps_id)
# XXX 'tested' works here because 'storage_id' does not differ
# (see also MappedValue.__doc__)
variation_property_list = ['tested']
transformation = self.createTransformation() transformation = self.createTransformation()
transformed_resource = self.createTransformedResource(transformation) transformed_resource = self.createTransformedResource(transformation)
component = self.createComponent( component = self.createComponent(variation_property_list=['foo'])
variation_property_list=variation_property_list)
transformed_resource.edit( transformed_resource.edit(
resource_value=component, resource_value=component,
quantity=1) quantity=1)
transformed_resource.setTested(True) transformed_resource.setFoo(True)
aggregated_amount, = transformation.getAggregatedAmountList() aggregated_amount, = transformation.getAggregatedAmountList()
# Make sure that the isTested method is working properly on the # Make sure that the isFoo method is working properly on the temp object
# temp object self.assertTrue(aggregated_amount.isFoo())
self.assertTrue(aggregated_amount.isTested())
# XXX aborting a transaction should reset classes
# if they were reset during the transaction
transaction.abort()
self.getTypesTool().resetDynamicDocuments()
def test_variationCategory(self): def test_variationCategory(self):
swimcap = self.createResource( swimcap = self.createResource(
......
...@@ -697,6 +697,8 @@ def initializePortalTypeDynamicWorkflowMethods(self, klass, ptype, prop_holder, ...@@ -697,6 +697,8 @@ def initializePortalTypeDynamicWorkflowMethods(self, klass, ptype, prop_holder,
method_id_list = filter(method_id_matcher.match, method_id_list) method_id_list = filter(method_id_matcher.match, method_id_list)
else: else:
# Single method # Single method
# XXX What if the method does not exist ?
# It's not consistent with regexp based filters.
method_id_list = [imethod_id] method_id_list = [imethod_id]
for method_id in method_id_list: for method_id in method_id_list:
if getattr(klass, method_id, _MARKER) is not _MARKER: if getattr(klass, method_id, _MARKER) is not _MARKER:
......
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