diff --git a/product/ERP5/Document/Transformation.py b/product/ERP5/Document/Transformation.py index 14e38f64645fbe43c7c2260da7d60978f6bf2c39..a4a80bcd3f784ff6b63d206783b9cb89e2867b5b 100755 --- a/product/ERP5/Document/Transformation.py +++ b/product/ERP5/Document/Transformation.py @@ -2,6 +2,8 @@ # # Copyright (c) 2002 Coramy SAS and Contributors. All Rights Reserved. # Thierry_Faucher <Thierry_Faucher@coramy.com> +# Copyright (c) 2004 Nexedi SARL and Contributors. All Rights Reserved. +# Romain Courteaud <romain@nexedi.com> # # WARNING: This program as such is intended to be used by professional # programmers who take the whole responsability of assessing all potential @@ -37,6 +39,7 @@ from Products.ERP5.Variated import Variated from Products.ERP5.Document.Domain import Domain +import string from zLOG import LOG class Transformation(XMLObject, Domain, Variated): @@ -46,26 +49,13 @@ class Transformation(XMLObject, Domain, Variated): Use of default_resource... (to define the variation range, to ...) - - About ranges: - - getDomainBaseCategoryList -> base categories which allow to select state... - - getDomainRangeBaseCategoryList -> base categories which allow to select state... - - getDomainCategoryList -> bonne id?.... = DomainValue... - base category which defines the state - (and other things) - - getDomainRangeCategoryList -> bonne id?.... = DomainValue... + XXX Transformation works only for a miximum of 3 variation base category... + Matrixbox must be rewrite for a clean implementation of n base category """ meta_type = 'ERP5 Transformation' portal_type = 'Transformation' - add_permission = Permissions.AddPortalContent - isPortalContent = 1 - isRADContent = 1 # Declarative security security = ClassSecurityInfo() @@ -78,139 +68,82 @@ class Transformation(XMLObject, Domain, Variated): , PropertySheet.DublinCore , PropertySheet.VariationRange , PropertySheet.Domain + #, PropertySheet.Resource + , PropertySheet.TransformedResource + , PropertySheet.Path , PropertySheet.Transformation ) # Declarative interfaces __implements__ = ( Interface.Variated, ) - # Factory Type Information - factory_type_information = \ - { 'id' : portal_type - , 'meta_type' : meta_type - , 'description' : """\ -une gamme...""" - , 'icon' : 'transformation_icon.gif' - , 'product' : 'ERP5' - , 'factory' : 'addTransformation' - , 'immediate_view' : 'transformation_view' - , 'allow_discussion' : 1 - , 'allowed_content_types': ('Transformed Resource', - ) - , 'filter_content_types' : 1 - , 'global_allow' : 1 - , 'actions' : - ( { 'id' : 'view' - , 'name' : 'View' - , 'category' : 'object_view' - , 'action' : 'transformation_view' - , 'permissions' : ( - Permissions.View, ) - } - , { 'id' : 'list' - , 'name' : 'Object Contents' - , 'category' : 'object_action' - , 'action' : 'folder_contents' - , 'permissions' : ( - Permissions.View, ) - } - , { 'id' : 'print' - , 'name' : 'Print' - , 'category' : 'object_print' - , 'action' : 'transformation_print' - , 'permissions' : ( - Permissions.View, ) - } - , { 'id' : 'metadata' - , 'name' : 'Metadata' - , 'category' : 'object_view' - , 'action' : 'metadata_edit' - , 'permissions' : ( - Permissions.View, ) - } - , { 'id' : 'translate' - , 'name' : 'Translate' - , 'category' : 'object_action' - , 'action' : 'translation_template_view' - , 'permissions' : ( - Permissions.TranslateContent, ) - } - ) - } - - security.declareProtected(Permissions.AccessContentsInformation, - 'getVariationRangeBaseCategoryList') + + security.declareProtected(Permissions.AccessContentsInformation, 'updateVariationCategoryList') + def updateVariationCategoryList(self): + """ + Check if variation category list of the resource changed and update transformation + and transformation line + """ + self.setVariationBaseCategoryList( self.getVariationBaseCategoryList() ) + transformation_line_list = self.contentValues() + for transformation_line in transformation_line_list: + transformation_line.updateVariationCategoryList() + + security.declareProtected(Permissions.AccessContentsInformation, 'getVariationRangeBaseCategoryList') def getVariationRangeBaseCategoryList(self): """ Returns possible variation base_category ids of the - default resource of this transformation + default resource which can be used a variation axis + in the transformation. """ - resource = self.getDefaultResourceValue() + #resource = self.getDefaultResourceValue() + resource = self.getResourceValue() if resource is not None: + #result = [''] + resource.getVariationBaseCategoryList() result = resource.getVariationBaseCategoryList() else: - result = self.getBaseCategoryIds() + # XXX result = self.getBaseCategoryIds() + # Why calling this method ? + # Get a global variable which define a list of variation base category + # XXX I don' t like this approch, maybe can we define this variable + # on Transformation property sheet ? (Romain) + result = self.getPortalVariationBaseCategoryList() return result - security.declareProtected(Permissions.AccessContentsInformation, - 'getTransformationVariationRangeCategoryList') - def getTransformationVariationRangeCategoryList(self): - """ - Possible categories (ie. of the default resource) - """ - return self.getResourceValue().getVariationCategoryList(base_category_list= - self.getTransformationVariationBaseCategoryList()) - - security.declareProtected(Permissions.AccessContentsInformation, - 'getTransformationVariationCategoryList') - def getTransformationVariationCategoryList(self): - """ - Possible categories (ie. of the default resource) - """ - return self.getVariationCategoryList(base_category_list= - self.getTransformationVariationBaseCategoryList()) - - security.declareProtected(Permissions.AccessContentsInformation, - 'getTransformationVariationRangeBaseCategoryList') - def getTransformationVariationRangeBaseCategoryList(self): - """ - Returns possible variation base_category ids of the - default resource which can be used a variation axis - in the transformation (ie. all ids of - getVariationRangeBaseCategoryList except ids which - are used as a transformation state as defined in - domain_base_category) - """ - result = ['',] + list(self.getVariationRangeBaseCategoryList()) - forbidden_id = self.getDomainBaseCategoryList() - forbidden_id = asList(forbidden_id) # This will soon be useless - return rejectIn(result, forbidden_id) - - security.declareProtected(Permissions.AccessContentsInformation, - 'getVariationRangeBaseCategoryItemList') + security.declareProtected(Permissions.AccessContentsInformation, 'getVariationRangeBaseCategoryItemList') def getVariationRangeBaseCategoryItemList(self): """ - Returns possible variations of the resource + Returns possible variations of the transformation as a list of tuples (id, title). This is mostly useful in ERP5Form instances to generate selection menus. """ - return self.portal_categories.getItemList(self.getVariationRangeBaseCategoryList()) + return self.portal_categories.getItemList( self.getVariationRangeBaseCategoryList() ) + - security.declareProtected(Permissions.AccessContentsInformation, - 'getTransformationVariationRangeBaseCategoryItemList') - def getTransformationVariationRangeBaseCategoryItemList(self): + security.declareProtected(Permissions.AccessContentsInformation,'getVariationRangeCategoryList') + def getVariationRangeCategoryList(self, base_category_list = ()): """ - Returns possible variations of the transformation - as a list of tuples (id, title). This is mostly - useful in ERP5Form instances to generate selection - menus. + Returns possible variation category values for the + transformation according to the default resource. + Possible category values is provided as a list of + id. + User may want to define generic transformation without + any resource define. + Result is left display. """ - return self.portal_categories.getItemList( - self.getTransformationVariationRangeBaseCategoryList()) + if base_category_list is (): + base_category_list = self.getVariationBaseCategoryList() + + resource = self.getResourceValue() + if resource != None: + result = resource.getVariationRangeCategoryList(base_category_list) + else: + # No resource is define on transformation. We want to display content of base categories + result = self.portal_categories.getCategoryChildList(base_category_list, base=1) + return result - security.declareProtected(Permissions.AccessContentsInformation, - 'getVariationRangeCategoryItemList') + security.declareProtected(Permissions.AccessContentsInformation,'getVariationRangeCategoryItemList') def getVariationRangeCategoryItemList(self, base_category_list = ()): """ Returns possible variation category values for the @@ -219,33 +152,105 @@ une gamme...""" tuples (id, title). This is mostly useful in ERP5Form instances to generate selection menus. + User may want to define generic transformation without + any resource define. """ if base_category_list is (): base_category_list = self.getVariationBaseCategoryList() - try: - result = self.getDefaultResourceValue( - ).getVariationRangeCategoryItemList(base_category_list) - except: - result = self.portal_categories.getCategoryChildItemList(base_category_list, - base=1) + + resource = self.getResourceValue() + if resource != None: + result = resource.getVariationRangeCategoryItemList(base_category_list) + else: + # No resource is define on transformation. We want to display content of base categories + result = self.portal_categories.getCategoryChildTitleItemList(base_category_list, base=1, display_none_category=0) return result - # Aliases to simplify access to range information for TransformedResources - security.declareProtected(Permissions.AccessContentsInformation, - 'getTransformationVariationBaseCategoryList') - def getTransformationVariationBaseCategoryList(self): + security.declareProtected(Permissions.AccessContentsInformation, 'getVariationBaseCategoryItemList') + def getVariationBaseCategoryItemList(self): """ - Returns a list of base_category ids for this tranformation + Returns a list of base_category tuples for this tranformation """ - return self.getVariationBaseCategoryList() + return self.portal_categories.getItemList(self.getVariationBaseCategoryList()) - security.declareProtected(Permissions.AccessContentsInformation, - 'getTransformationVariationBaseCategoryItemList') - def getTransformationVariationBaseCategoryItemList(self): + + security.declareProtected(Permissions.AccessContentsInformation, '_setVariationBaseCategoryList') + def _setVariationBaseCategoryList(self, value): """ - Returns a list of base_category tuples for this tranformation + Define the possible base categories """ - return self.portal_categories.getItemList(self.getVariationBaseCategoryList()) +# XXX TransformedResource works only for a maximum of 3 variation base category... +# Matrixbox must be rewrite for a clean implementation of n base category + if len(value) <= 3: + self._baseSetVariationBaseCategoryList(value) + else: + raise MoreThan3VariationBaseCategory + + # create relations between resource variation and transformation + self._setVariationCategoryList( self.getVariationRangeCategoryList() ) + + security.declareProtected(Permissions.AccessContentsInformation, 'setVariationBaseCategoryList') + def setVariationBaseCategoryList(self, value): + """ + Define the possible base categories and reindex object + """ + self._setVariationBaseCategoryList(value) + self.reindexObject() + + + security.declareProtected(Permissions.AccessContentsInformation, 'getVariationCategoryItemList') + def getVariationCategoryItemList(self, base_category_list=()): + """ + Returns a list of variation tuples for this tranformation + Result is left display. + """ + if base_category_list == (): + base_category_list = self.getVariationBaseCategoryList() + + variation_category_item_list = map(lambda x: (x,x), self.getVariationCategoryList( base_category_list=base_category_list )) + + return variation_category_item_list + + security.declareProtected(Permissions.AccessContentsInformation, 'getVariationCategoryItemList') + def getVariationCategoryItemList(self, base_category_list = (), base=1, display_id='getTitleOrId', current_category=None): + """ + Returns the list of possible variations + XXX Copied and modified from Variated + Result is left display. + """ + variation_category_item_list = [] + +# What is this parameter ? +# if current_category is not None: +# variation_category_item_list.append((current_category,current_category)) + + if base_category_list == (): + base_category_list = self.getVariationBaseCategoryList() + + variation_category_list = self.getVariationCategoryList(base_category_list=base_category_list) + + for variation_category in variation_category_list: + resource = self.portal_categories.resolveCategory(variation_category) + + if resource.getPortalType() == 'Category': + # Category is unusable if only Title is displayed... + value = getattr(resource, 'getLogicalPath')() + else: + # And displaying LogicalPath for variation is unusable for user... + value = getattr(resource, display_id)() + + if base: + index = variation_category.find('/') + base_category = variation_category[:index] + label = base_category+'/'+value + else: + label = value + + # Result is left display + variation_category_item_list.append((label, variation_category )) + + return variation_category_item_list + # This is the main method to do any BOM related calculation security.declareProtected(Permissions.AccessContentsInformation, 'getAggregatedAmountList') @@ -260,95 +265,79 @@ une gamme...""" # LOG('getAggregatedAmountList',0,str((context, REQUEST, kw))) REQUEST = self.asContext(context=context, REQUEST=REQUEST, **kw) # First we need to get the list of transformations which this transformation depends on - # At this moment, we only consider 1 dependency - transformation_list = [self] + self.getSpecialiseValueList() + # XXX At this moment, we only consider 1 dependency + template_transformation_list = self.getSpecialiseValueList() + # We consider that the specific parameters to take into account # are acquired through the REQUEST parameter # The REQUEST can either be a Zope REQUEST or a dictionnary provided by the use - if REQUEST is None: - # At this moment XXXXXXXXXXXXXXXXXXXXXXXX - # we initialize the request to a default value in order - # to make sure we have something to test MappedValues on - REQUEST = {'categories': ('taille/enfant/08 ans','coloris/modele/701C402/2')} - # We define some initial values - # result holds a list of dictionaries - # price holds a list of dictionaries - summary_list = [] - grand_total_variated_source_base_price = 0.0 - grand_total_source_base_price = 0.0 - grand_total_base_price = 0.0 - grand_total_variated_base_price = 0.0 - grand_total_variated_source_base_price = 0.0 - grand_total_duration = 0.0 +# if REQUEST is None: +# # At this moment XXX +# # we initialize the request to a default value in order +# # to make sure we have something to test MappedValues on +# #REQUEST = {'categories': ('taille/enfant/08 ans','coloris/modele/701C402/2')} +# REQUEST = {} + + result = None # Browse all involved transformations and create one line per line of transformation # Currently, we do not consider abstractions, we just add whatever we find in all # transformations - for transformation in transformation_list: + for transformation in [self] + transformation_list: # Browse each transformed or assorted resource of the current transformation for transformed_resource in transformation.objectValues(): - #LOG("for transformed_resource in transformation",0,transformed_resource.getId()) - line_item_list, total_base_price, total_source_base_price, \ - total_variated_base_price, total_variated_source_base_price, duration \ - = transformed_resource.getAggregatedAmountList(REQUEST) - summary_list += line_item_list - grand_total_base_price += total_base_price - grand_total_source_base_price += total_source_base_price - grand_total_variated_base_price += total_variated_base_price - grand_total_variated_source_base_price += total_variated_source_base_price - grand_total_duration += duration - - #LOG("Transformation Agg summary",0, - # str(map(lambda o: (o.resource_id, o.quantity_defined_by), summary_list))) - - # Return values as a tuple - return map(lambda x: x.__dict__, summary_list) , grand_total_base_price, \ - grand_total_source_base_price, grand_total_duration, \ - grand_total_variated_base_price, grand_total_variated_source_base_price - - # UPDATED BY JPS - - # XXX This should not be there, but in Document/TransformedResource.py or something like - # this, but actually this does not work, we should find why. - security.declareProtected(Permissions.ModifyPortalContent, '_setVariationBaseCategoryList') - def _setVariationBaseCategoryList(self, new_base_category_list): - """ - We override the default behaviour generated by Utils.py in order - to update all TransformedResource contained in this transformation - """ - # Get the list of previous base_category that have been removed or kept - removed_base_category = [] - kept_base_category = [] - for cat in self.getVariationBaseCategoryList(): - if cat in new_base_category_list: - kept_base_category += [cat] - else: - removed_base_category += [cat] - - # Update variation_base_category_list - self.variation_base_category_list = new_base_category_list - - # Make sure there is no reference to categories - # of removed_base_category - # in categories - if len(removed_base_category) > 0: - self._setCategoryMembership(removed_base_category, [], base=1) - - # Filter all fields which are based on base_category - if self.getVariationBaseCategoryLine() not in new_base_category_list: - self._setVariationBaseCategoryLine(None) - if self.getVariationBaseCategoryColumn() not in new_base_category_list: - self._setVariationBaseCategoryColumn(None) - self._setVariationBaseCategoryTabList(keepIn(self.getVariationBaseCategoryTabList(), - new_base_category_list)) - - # Make sure that all sub-objects use a valid range - # We simply call range functions on each object to force - # range update in XMLMatrix - for o in self.objectValues(): - if hasattr(o,'v_variation_base_category_list'): - o.setVVariationBaseCategoryList(keepIn(o.getVVariationBaseCategoryList(), - new_base_category_list)) - if hasattr(o,'q_variation_base_category_list'): - o.setQVariationBaseCategoryList(keepIn(o.getQVariationBaseCategoryList(), - new_base_category_list)) + + if result==None: + result = transformed_resource.getAggregatedAmountList(REQUEST) + else: + result += transformed_resource.getAggregatedAmountList(REQUEST) + + return result + + +# # UPDATED BY JPS +# +# # XXX This should not be there, but in Document/TransformedResource.py or something like +# # this, but actually this does not work, we should find why. +# security.declareProtected(Permissions.ModifyPortalContent, '_setVariationBaseCategoryList') +# def _setVariationBaseCategoryList(self, new_base_category_list): +# """ +# We override the default behaviour generated by Utils.py in order +# to update all TransformedResource contained in this transformation +# """ +# # Get the list of previous base_category that have been removed or kept +# removed_base_category = [] +# kept_base_category = [] +# for cat in self.getVariationBaseCategoryList(): +# if cat in new_base_category_list: +# kept_base_category += [cat] +# else: +# removed_base_category += [cat] +# +# # Update variation_base_category_list +# self.variation_base_category_list = new_base_category_list +# +# # Make sure there is no reference to categories +# # of removed_base_category +# # in categories +# if len(removed_base_category) > 0: +# self._setCategoryMembership(removed_base_category, [], base=1) +# +# # Filter all fields which are based on base_category +# if self.getVariationBaseCategoryLine() not in new_base_category_list: +# self._setVariationBaseCategoryLine(None) +# if self.getVariationBaseCategoryColumn() not in new_base_category_list: +# self._setVariationBaseCategoryColumn(None) +# self._setVariationBaseCategoryTabList(keepIn(self.getVariationBaseCategoryTabList(), +# new_base_category_list)) +# +# # Make sure that all sub-objects use a valid range +# # We simply call range functions on each object to force +# # range update in XMLMatrix +# for o in self.objectValues(): +# if hasattr(o,'v_variation_base_category_list'): +# o.setVVariationBaseCategoryList(keepIn(o.getVVariationBaseCategoryList(), +# new_base_category_list)) +# if hasattr(o,'q_variation_base_category_list'): +# o.setQVariationBaseCategoryList(keepIn(o.getQVariationBaseCategoryList(), +# new_base_category_list))