diff --git a/bt5/erp5_pdm/PortalTypeTemplateItem/portal_types/Transformation%20Operation%20Cell.xml b/bt5/erp5_pdm/PortalTypeTemplateItem/portal_types/Transformation%20Operation%20Cell.xml index 9e290c8aac9d4f59f5c875ad8e37c41295978b95..eb0b931ea38b0ced4f883a7905db11e852fe07ba 100644 --- a/bt5/erp5_pdm/PortalTypeTemplateItem/portal_types/Transformation%20Operation%20Cell.xml +++ b/bt5/erp5_pdm/PortalTypeTemplateItem/portal_types/Transformation%20Operation%20Cell.xml @@ -22,10 +22,6 @@ <key> <string>description</string> </key> <value> <string>Transformation Operation Cell</string> </value> </item> - <item> - <key> <string>factory</string> </key> - <value> <string>addMappedValue</string> </value> - </item> <item> <key> <string>filter_content_types</string> </key> <value> <int>1</int> </value> @@ -58,6 +54,10 @@ <key> <string>title</string> </key> <value> <string></string> </value> </item> + <item> + <key> <string>type_class</string> </key> + <value> <string>TransformedResource</string> </value> + </item> </dictionary> </pickle> </record> diff --git a/bt5/erp5_pdm/PortalTypeTemplateItem/portal_types/Transformation%20Transformed%20Resource%20Cell.xml b/bt5/erp5_pdm/PortalTypeTemplateItem/portal_types/Transformation%20Transformed%20Resource%20Cell.xml index 8d4edbba624d2991f17253f6fa1d4e9354038a0c..83e4c0ef0f067c1a01a4a584135d4f193cc09a06 100644 --- a/bt5/erp5_pdm/PortalTypeTemplateItem/portal_types/Transformation%20Transformed%20Resource%20Cell.xml +++ b/bt5/erp5_pdm/PortalTypeTemplateItem/portal_types/Transformation%20Transformed%20Resource%20Cell.xml @@ -22,10 +22,6 @@ <key> <string>description</string> </key> <value> <string>Transformation Transformed Resource Cell</string> </value> </item> - <item> - <key> <string>factory</string> </key> - <value> <string>addMappedValue</string> </value> - </item> <item> <key> <string>filter_content_types</string> </key> <value> <int>1</int> </value> @@ -58,6 +54,10 @@ <key> <string>title</string> </key> <value> <string></string> </value> </item> + <item> + <key> <string>type_class</string> </key> + <value> <string>TransformedResource</string> </value> + </item> </dictionary> </pickle> </record> diff --git a/bt5/erp5_pdm/bt/revision b/bt5/erp5_pdm/bt/revision index dd35c6b71fc80057f07694a1d0e0ee7348383b74..e9059e02c3dfa5428d76ae0eb634de170bea91ad 100644 --- a/bt5/erp5_pdm/bt/revision +++ b/bt5/erp5_pdm/bt/revision @@ -1 +1 @@ -548 \ No newline at end of file +549 \ No newline at end of file diff --git a/product/ERP5/Document/MappedValue.py b/product/ERP5/Document/MappedValue.py index 7a8f622993d109ce2b78e9145c97beff920850f7..ff4f5ceac7a2eadf0b70d610212aa2f195ba4cd7 100644 --- a/product/ERP5/Document/MappedValue.py +++ b/product/ERP5/Document/MappedValue.py @@ -39,10 +39,6 @@ _MARKER = [] class MappedValue(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' portal_type = 'Mapped Value' @@ -62,89 +58,19 @@ class MappedValue(Predicate): # Declarative interfaces zope.interface.implements(interfaces.IMappedValue, ) - security.declareProtected(Permissions.AccessContentsInformation, 'getMappedValueBaseCategoryList') + + security.declareProtected(Permissions.AccessContentsInformation, + 'getMappedValueBaseCategoryList') def getMappedValueBaseCategoryList(self, d=_MARKER): if TRANSFORMATION_FIX: # Fix Mapped Value Objects which forgot to define their Mapped Base Categories if not self._baseGetMappedValueBaseCategoryList(): if self.getParentValue().getParentValue().getPortalType() == 'Transformation': - base_category_dict = {} + base_category_set = set() for category in self.getCategoryList(): # XXX-JPS additional test required to prevent taking too much ? - base_category_dict[category.split('/')[0]] = None - self._setMappedValueBaseCategoryList(base_category_dict.keys()) + base_category_set.add(category.split('/')[0]) + self._setMappedValueBaseCategoryList(list(base_category_set)) if d is _MARKER: return self._baseGetMappedValueBaseCategoryList(d=d) 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) diff --git a/product/ERP5/Document/TradeModelCell.py b/product/ERP5/Document/TradeModelCell.py index 483d24656a80da18cc8727dd9003cc378fa8a8ec..8becb978fc027df86a8891b4472734e01e64a3df 100644 --- a/product/ERP5/Document/TradeModelCell.py +++ b/product/ERP5/Document/TradeModelCell.py @@ -68,10 +68,9 @@ class TradeModelCell(TradeModelLine): """ return 0 - security.declareProtected(Permissions.AccessContentsInformation, - 'getPrice') - def getPrice(self): - return self._baseGetPrice() + def getQuantity(self): + """Overridden getter to return None instead 0 if undefined""" + return self._baseGetQuantity(None) security.declareProtected(Permissions.AccessContentsInformation, 'getTotalPrice') diff --git a/product/ERP5/Document/TradeModelLine.py b/product/ERP5/Document/TradeModelLine.py index 31a43a1c82cc82758cf07116f8b13aa27cddc9ac..42edab8a6b0a0684357eb64ddb14cbd4b9c6b253 100644 --- a/product/ERP5/Document/TradeModelLine.py +++ b/product/ERP5/Document/TradeModelLine.py @@ -67,11 +67,3 @@ class TradeModelLine(AmountGeneratorLine): def getMappedValueBaseCategoryList(self): return self._baseGetMappedValueBaseCategoryList() or ('trade_phase', 'use',) - - # - security.declareProtected(Permissions.AccessContentsInformation, - 'getPrice') - def getPrice(self): - """ - """ - return self._baseGetPrice() diff --git a/product/ERP5/Document/TransformedResource.py b/product/ERP5/Document/TransformedResource.py index 26faa772248fc3ef8afe8148af7a59b135f4b642..a116b19d7559de09b484d876ac56572b8ddf2946 100644 --- a/product/ERP5/Document/TransformedResource.py +++ b/product/ERP5/Document/TransformedResource.py @@ -65,15 +65,20 @@ class TransformedResource(AmountGeneratorLine): def getMappedValuePropertyList(self): result = self._baseGetMappedValuePropertyList() 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'] # Take into account variation_property_list for each variation # for which hasProperty is true... # FIXME: Why the resource and not the model line itself ? Or both ?? resource = self.getDefaultResourceValue() if resource is not None: - # XXX Using getattr directly is a hack. See MappedValue.__doc__ - result.extend(key for key in resource.getVariationPropertyList() - if getattr(self, key, self) is not self) + result += resource.getVariationPropertyList() + result = filter(self.hasProperty, result) return result def getMappedValueBaseCategoryList(self): diff --git a/product/ERP5/tests/testTransformation.py b/product/ERP5/tests/testTransformation.py index 0acfbe951297d3196df5a12a83f404adc912ffaf..0f12ad1e5564ef74c2941fa27b06f3a9e30f19c0 100644 --- a/product/ERP5/tests/testTransformation.py +++ b/product/ERP5/tests/testTransformation.py @@ -132,29 +132,33 @@ class TestTransformation(TestTransformationMixin, BaseTestUnitConversion): have additionnals propertysheets on transformations lines and that used variation properties """ - # Only for testing purpose, use a property sheet that has nothing to - # do with component. It would have been possible to create a new - # property sheet for this test. + ps_id = self._testMethodName + property_sheet = self.portal.portal_property_sheets.newContent( + 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 # like movements, order lines and so on. - self._addPropertySheet('Amount', 'Bug') - self._addPropertySheet(self.transformed_resource_portal_type, 'Bug') - # XXX 'tested' works here because 'storage_id' does not differ - # (see also MappedValue.__doc__) - variation_property_list = ['tested'] + self._addPropertySheet('Amount', ps_id) + self._addPropertySheet(self.transformed_resource_portal_type, ps_id) transformation = self.createTransformation() transformed_resource = self.createTransformedResource(transformation) - component = self.createComponent( - variation_property_list=variation_property_list) + component = self.createComponent(variation_property_list=['foo']) transformed_resource.edit( resource_value=component, quantity=1) - transformed_resource.setTested(True) + transformed_resource.setFoo(True) aggregated_amount, = transformation.getAggregatedAmountList() - # Make sure that the isTested method is working properly on the - # temp object - self.assertTrue(aggregated_amount.isTested()) + # Make sure that the isFoo method is working properly on the temp object + self.assertTrue(aggregated_amount.isFoo()) + + # XXX aborting a transaction should reset classes + # if they were reset during the transaction + transaction.abort() + self.getTypesTool().resetDynamicDocuments() def test_variationCategory(self): swimcap = self.createResource( diff --git a/product/ERP5Type/Base.py b/product/ERP5Type/Base.py index 9246abf9b1f0fc15a80eb034579003b0474bcffb..c260617213c8465788ff7f0370d2ca89ce1d5ea1 100644 --- a/product/ERP5Type/Base.py +++ b/product/ERP5Type/Base.py @@ -697,6 +697,8 @@ def initializePortalTypeDynamicWorkflowMethods(self, klass, ptype, prop_holder, method_id_list = filter(method_id_matcher.match, method_id_list) else: # Single method + # XXX What if the method does not exist ? + # It's not consistent with regexp based filters. method_id_list = [imethod_id] for method_id in method_id_list: if getattr(klass, method_id, _MARKER) is not _MARKER: