From 1c7a75da8f26ee2c6798a006356322e000d97c10 Mon Sep 17 00:00:00 2001 From: Alexandre Boeglin <alex@nexedi.com> Date: Fri, 27 Jan 2006 14:06:30 +0000 Subject: [PATCH] Portal Type Workflow Chain are now separated from Portal Type exports. Portal Type Workflow Chain and Portal Type Role Definition added to guess of Portal Type Properties. git-svn-id: https://svn.erp5.org/repos/public/erp5/trunk@5385 20353a03-c40f-0410-a6d1-a30d3c3de9de --- product/ERP5/Document/BusinessTemplate.py | 161 ++++++++++++++---- .../ERP5/PropertySheet/BusinessTemplate.py | 5 + 2 files changed, 137 insertions(+), 29 deletions(-) diff --git a/product/ERP5/Document/BusinessTemplate.py b/product/ERP5/Document/BusinessTemplate.py index 201ef95beb..216245fedb 100755 --- a/product/ERP5/Document/BusinessTemplate.py +++ b/product/ERP5/Document/BusinessTemplate.py @@ -971,8 +971,8 @@ class WorkflowTemplateItem(ObjectTemplateItem): class PortalTypeTemplateItem(ObjectTemplateItem): - workflow_chain = None - + # XXX : this method is kept temporarily, but can be removed once all bt5 are + # re-exported with separated workflow-chain information def _getChainByType(self, context): """ This is used in order to construct the full list @@ -1004,6 +1004,8 @@ class PortalTypeTemplateItem(ObjectTemplateItem): def __init__(self, id_list, tool_id='portal_types', **kw): ObjectTemplateItem.__init__(self, id_list, tool_id=tool_id, **kw) + # XXX : this statement can be removed once all bt5 have separated + # workflow-chain information self._workflow_chain_archive = PersistentMapping() def build(self, context, **kw): @@ -1011,7 +1013,6 @@ class PortalTypeTemplateItem(ObjectTemplateItem): for relative_url in self._archive.keys(): obj = p.unrestrictedTraverse(relative_url) obj = obj._getCopy(context) - id_list = obj.objectIds() # remove actions and properties action_len = len(obj.listActions()) obj.deleteActions(selections=range(action_len)) @@ -1029,30 +1030,9 @@ class PortalTypeTemplateItem(ObjectTemplateItem): setattr(obj, '_roles', []) self._objects[relative_url] = obj obj.wl_clearLocks() - # also export workflow chain - (default_chain, chain_dict) = self._getChainByType(context) - for obj in self._objects.values(): - portal_type = obj.id - self._workflow_chain_archive[portal_type] = chain_dict['chain_%s' % portal_type] - - def export(self, context, bta, **kw): - if len(self._objects.keys()) == 0: - return - root_path = os.path.join(bta.path, self.__class__.__name__) - # export portal type object - ObjectTemplateItem.export(self, context, bta, **kw) - # export workflow chain - xml_data = '<workflow_chain>' - keys = self._workflow_chain_archive.keys() - keys.sort() - for key in keys: - xml_data += os.linesep+' <chain>' - xml_data += os.linesep+' <type>%s</type>' %(key,) - xml_data += os.linesep+' <workflow>%s</workflow>' %(self._workflow_chain_archive[key],) - xml_data += os.linesep+' </chain>' - xml_data += os.linesep+'</workflow_chain>' - bta.addObject(obj=xml_data, name='workflow_chain_type', path=root_path) + # XXX : this method is kept temporarily, but can be removed once all bt5 are + # re-exported with separated workflow-chain information def install(self, context, trashbin, **kw): ObjectTemplateItem.install(self, context, trashbin, **kw) update_dict = kw.get('object_to_update') @@ -1076,11 +1056,14 @@ class PortalTypeTemplateItem(ObjectTemplateItem): continue obj = object_list[path] portal_type = obj.id - chain_dict['chain_%s' % portal_type] = \ - self._workflow_chain_archive[portal_type] + if self._workflow_chain_archive.has_key(portal_type): + chain_dict['chain_%s' % portal_type] = \ + self._workflow_chain_archive[portal_type] context.portal_workflow.manage_changeWorkflows(default_chain, props=chain_dict) + # XXX : this method is kept temporarily, but can be removed once all bt5 are + # re-exported with separated workflow-chain information def _importFile(self, file_name, file): if 'workflow_chain_type.xml' in file_name: # import workflow chain for portal_type @@ -1100,6 +1083,106 @@ class PortalTypeTemplateItem(ObjectTemplateItem): ObjectTemplateItem._importFile(self, file_name, file) +class PortalTypeTemplateWorkflowChainItem(BaseTemplateItem): + + def _getChainByType(self, context): + """ + This is used in order to construct the full list + of mapping between type and list of workflow associated + This is only useful in order to use + portal_workflow.manage_changeWorkflows + """ + pw = context.portal_workflow + cbt = pw._chains_by_type + ti = pw._listTypeInfo() + types_info = [] + for t in ti: + id = t.getId() + title = t.Title() + if title == id: + title = None + if cbt is not None and cbt.has_key(id): + chain = ', '.join(cbt[id]) + else: + chain = '(Default)' + types_info.append({'id': id, + 'title': title, + 'chain': chain}) + new_dict = {} + for item in types_info: + new_dict['chain_%s' % item['id']] = item['chain'] + default_chain=', '.join(pw._default_chain) + return (default_chain, new_dict) + + def __init__(self, id_list, **kw): + id_list = ['portal_type_workflow_chain/%s' % id for id in id_list] + BaseTemplateItem.__init__(self, id_list, **kw) + + def build(self, context, **kw): + p = context.getPortalObject() + (default_chain, chain_dict) = self._getChainByType(context) + for relative_url in self._archive.keys(): + portal_type = relative_url.split('/', 1)[1] + self._objects[relative_url] = chain_dict['chain_%s' % portal_type] + + def generateXml(self, path=None): + xml_data = '<workflow_chain>' + keys = self._objects.keys() + keys.sort() + for key in keys: + xml_data += os.linesep+' <chain>' + xml_data += os.linesep+' <type>%s</type>' %(key,) + xml_data += os.linesep+' <workflow>%s</workflow>' %(self._objects[key],) + xml_data += os.linesep+' </chain>' + xml_data += os.linesep+'</workflow_chain>' + return xml_data + + def export(self, context, bta, **kw): + if len(self._objects.keys()) == 0: + return + root_path = os.path.join(bta.path, self.__class__.__name__) + bta.addFolder(name=root_path) + # export workflow chain + xml_data = self.generateXml() + bta.addObject(obj=xml_data, name='workflow_chain_type', path=root_path) + + def install(self, context, trashbin, **kw): + update_dict = kw.get('object_to_update') + force = kw.get('force') + # We now need to setup the list of workflows corresponding to + # each portal type + (default_chain, chain_dict) = self._getChainByType(context) + # Set the default chain to the empty string is probably the + # best solution, by default it is 'default_workflow', wich is + # not very usefull + default_chain = '' + for path in self._objects.keys(): + if update_dict.has_key(path) or force: + if not force: + action = update_dict[path] + if action == 'nothing': + continue + portal_type = path.split('/', 1)[1] + chain_dict['chain_%s' % portal_type] = self._objects[path] + context.portal_workflow.manage_changeWorkflows(default_chain, + props=chain_dict) + + def _importFile(self, file_name, file): + # import workflow chain for portal_type + dict = {} + xml = parse(file) + chain_list = xml.getElementsByTagName('chain') + for chain in chain_list: + ptype = chain.getElementsByTagName('type')[0].childNodes[0].data + workflow_list = chain.getElementsByTagName('workflow')[0].childNodes + if len(workflow_list) == 0: + workflow = '' + else: + workflow = workflow_list[0].data + dict[str(ptype)] = str(workflow) + self._objects = dict + + class PortalTypeAllowedContentTypeTemplateItem(BaseTemplateItem): xml_tag = 'allowed_content_type_list' @@ -3306,6 +3389,7 @@ Business Template is a set of definitions, such as skins, portal types and categ '_catalog_method_item', '_site_property_item', '_portal_type_item', + '_portal_type_workflow_chain_item', '_portal_type_allowed_content_type_item', '_portal_type_hidden_content_type_item', '_portal_type_property_sheet_item', @@ -3374,6 +3458,8 @@ Business Template is a set of definitions, such as skins, portal types and categ # Store all datas self._portal_type_item = \ PortalTypeTemplateItem(self.getTemplatePortalTypeIdList()) + self._portal_type_workflow_chain_item = \ + PortalTypeTemplateWorkflowChainItem(self.getTemplatePortalTypeWorkflowChainList()) self._workflow_item = \ WorkflowTemplateItem(self.getTemplateWorkflowIdList()) self._skin_item = \ @@ -3807,6 +3893,13 @@ Business Template is a set of definitions, such as skins, portal types and categ """ return self._getOrderedList('template_portal_type_id') + def getTemplatePortalTypeWorkflowChainList(self): + """ + We have to set this method because we want an + ordered list + """ + return self._getOrderedList('template_portal_type_workflow_chain') + def getTemplatePathList(self): """ We have to set this method because we want an @@ -3925,6 +4018,8 @@ Business Template is a set of definitions, such as skins, portal types and categ self._portal_type_item = \ PortalTypeTemplateItem(self.getTemplatePortalTypeIdList()) + self._portal_type_workflow_chain_item = \ + PortalTypeTemplateWorkflowChainItem(self.getTemplatePortalTypeWorkflowChainList()) self._workflow_item = \ WorkflowTemplateItem(self.getTemplateWorkflowIdList()) self._skin_item = \ @@ -4023,6 +4118,7 @@ Business Template is a set of definitions, such as skins, portal types and categ 'CatalogMethod' : '_catalog_method_item', 'SiteProperty' : '_site_property_item', 'PortalType' : '_portal_type_item', + 'PortalTypeWorkflowChain' : '_portal_type_workflow_chain_item', 'PortalTypeAllowedContentType' : '_portal_type_allowed_content_type_item', 'PortalHiddenAllowedContentType' : '_portal_type_hidden_content_type_item', 'PortalTypePropertySheet' : '_portal_type_property_sheet_item', @@ -4085,7 +4181,8 @@ Business Template is a set of definitions, such as skins, portal types and categ '_catalog_request_key_item', '_catalog_multivalue_key_item', '_catalog_topic_key_item', '_portal_type_allowed_content_type_item', '_portal_type_hidden_content_type_item', '_portal_type_property_sheet_item', '_portal_type_roles_item', - '_portal_type_base_category_item', '_local_roles_item',] + '_portal_type_base_category_item', '_local_roles_item', + '_portal_type_workflow_chain_item'] item_list_3 = ['_document_item', '_property_sheet_item', '_constraint_item', '_extension_item', '_test_item', '_message_translation_item'] @@ -4150,12 +4247,16 @@ Business Template is a set of definitions, such as skins, portal types and categ bt_action_list = getattr(self, 'template_action_path', []) or [] bt_action_list = list(bt_action_list) bt_portal_types_id_list = list(self.getTemplatePortalTypeIdList()) + bt_portal_type_roles_list = [] p = self.getPortalObject() for id in bt_portal_types_id_list: try: portal_type = p.unrestrictedTraverse('portal_types/'+id) except KeyError: continue + if len(getattr(portal_type, '_roles', ())) > 0: + bt_portal_type_roles_list.append(id) + allowed_content_type_list = [] hidden_content_type_list = [] property_sheet_list = [] @@ -4191,6 +4292,8 @@ Business Template is a set of definitions, such as skins, portal types and categ bt_base_category_list.sort() bt_action_list.sort() + setattr(self, 'template_portal_type_workflow_chain', bt_portal_types_id_list) + setattr(self, 'template_portal_type_roles', bt_portal_type_roles_list) setattr(self, 'template_portal_type_allowed_content_type', bt_allowed_content_type_list) setattr(self, 'template_portal_type_hidden_content_type', bt_hidden_content_type_list) setattr(self, 'template_portal_type_property_sheet', bt_property_sheet_list) diff --git a/product/ERP5/PropertySheet/BusinessTemplate.py b/product/ERP5/PropertySheet/BusinessTemplate.py index 6cc8c4c8db..7956ad30f9 100755 --- a/product/ERP5/PropertySheet/BusinessTemplate.py +++ b/product/ERP5/PropertySheet/BusinessTemplate.py @@ -37,6 +37,11 @@ class BusinessTemplate: 'type' : 'lines', 'mode' : 'w', 'default' : () }, + { 'id' : 'template_portal_type_workflow_chain', + 'description' : 'A list of workflow chains of portal types used by this template', + 'type' : 'lines', + 'mode' : 'w', + 'default' : () }, { 'id' : 'template_portal_type_allowed_content_type', 'description' : 'A list of allowed content types for portal types', 'type' : 'lines', -- 2.30.9