diff --git a/product/ERP5/Document/BusinessTemplate.py b/product/ERP5/Document/BusinessTemplate.py index 9014dc7d8986c0ddf8d7bb7c95e08ee81b4fde7b..df0138a32a72fc1d2abfe2c84801d595f6f58d59 100644 --- a/product/ERP5/Document/BusinessTemplate.py +++ b/product/ERP5/Document/BusinessTemplate.py @@ -860,6 +860,7 @@ class ObjectTemplateItem(BaseTemplateItem): raise saved_uid_dict = {} subobjects_dict = {} + portal_type_dict = {} # Object already exists old_obj = container._getOb(object_id, None) if old_obj is not None: @@ -872,6 +873,15 @@ class ObjectTemplateItem(BaseTemplateItem): old_groups[path] = deepcopy(old_obj.groups) subobjects_dict = self._backupObject(action, trashbin, container_path, object_id) + # in case of portal types, we want to keep some properties + if getattr(old_obj, 'meta_type', None) == 'ERP5 Type Information': + for attr in ('allowed_content_type_list', + 'hidden_content_type_list', + 'property_sheet_list', + 'base_category_list'): + portal_type_dict[attr] = getattr(old_obj, attr, ()) + portal_type_dict['workflow_chain'] = \ + getChainByType(context)[1].get('chain_' + object_id, '') container.manage_delObjects([object_id]) else: self.onNewObject() @@ -897,43 +907,17 @@ class ObjectTemplateItem(BaseTemplateItem): self.REQUEST.set('is_business_template_installation', 1) obj.manage_afterClone(obj) obj.wl_clearLocks() - # if portal types upgrade, set backup properties - if getattr(obj, 'meta_type', None) == 'ERP5 Type Information' and \ - len(subobjects_dict) > 0: - setattr(obj, 'allowed_content_types', - subobjects_dict['allowed_content_type_list'] or []) - setattr(obj, 'hidden_content_type_list', - subobjects_dict['hidden_content_type_list'] or []) - setattr(obj, 'property_sheet_list', - subobjects_dict['property_sheet_list'] or []) - setattr(obj, 'base_category_list', - subobjects_dict['base_category_list'] or []) - setattr(obj, '_roles', subobjects_dict['roles_list'] or []) - # set actions - action_list = subobjects_dict['action_list'] - for action in action_list: - action_text = action.action - if isinstance(action_text, Expression): - action_text = action_text.text - obj.addAction(id = action.id - , name = action.title - , action = action_text - , condition = action.getCondition() - , permission = action.permissions - , category = action.category - , visible = action.visible - , icon = getattr(action, 'icon', None) and action.icon.text or '' - , priority = action.priority - , description = action.description - ) + if portal_type_dict: # set workflow chain - wf_chain = subobjects_dict['workflow_chain'] + wf_chain = portal_type_dict.pop('workflow_chain') chain_dict = getChainByType(context)[1] default_chain = '' chain_dict['chain_%s' % (object_id)] = wf_chain context.portal_workflow.manage_changeWorkflows(default_chain, props=chain_dict) + # restore some other properties + obj.__dict__.update(portal_type_dict) # import sub objects if there is - elif len(subobjects_dict) > 0: + if subobjects_dict: # get a jar connection = obj._p_jar o = obj @@ -4881,7 +4865,6 @@ Business Template is a set of definitions, such as skins, portal types and categ Return the list of modified/new/removed object between a Business Template and the one installed if exists """ - if check_dependencies: # required because in multi installation, dependencies has already # been checked before and it will failed here as dependencies can be @@ -5730,7 +5713,7 @@ Business Template is a set of definitions, such as skins, portal types and categ portal_type = ttool.getTypeInfo(id) if portal_type is None: continue - if len(getattr(portal_type, '_roles', ())) > 0: + if portal_type.getRoleInformationList(): if id not in bt_portal_type_roles_list: bt_portal_type_roles_list.append(id) @@ -5747,8 +5730,8 @@ Business Template is a set of definitions, such as skins, portal types and categ property_sheet_list = portal_type.property_sheet_list if hasattr(portal_type, 'base_category_list'): base_category_list = portal_type.base_category_list - if hasattr(portal_type, 'listActions'): - action_list = [x.getId() for x in portal_type.listActions()] + for action in portal_type.getActionInformationList(): + action_list.append(action.getReference()) for a_id in allowed_content_type_list: allowed_id = id+' | '+a_id diff --git a/product/ERP5/Tool/TrashTool.py b/product/ERP5/Tool/TrashTool.py index a62313ff7f7e125db7b2943c4bd34c9fc6d6a68f..0760fbe1c84ae330803391266e3aff7d6b19d92f 100644 --- a/product/ERP5/Tool/TrashTool.py +++ b/product/ERP5/Tool/TrashTool.py @@ -120,33 +120,14 @@ class TrashTool(BaseTool): else: object_path = container_path + [object_id] obj = self.unrestrictedTraverse(object_path) - if obj is None: - pass - # in case of portal types, export properties instead of subobjects - elif getattr(obj, 'meta_type', None) == 'ERP5 Type Information': - subobjects_dict = {} - subobjects_dict['allowed_content_type_list'] = getattr(obj, 'allowed_content_types', []) or [] - subobjects_dict['hidden_content_type_list'] = getattr(obj, 'hidden_content_type_list', []) or [] - subobjects_dict['property_sheet_list'] = getattr(obj, 'property_sheet_list', []) or [] - subobjects_dict['base_category_list'] = getattr(obj, 'base_category_list', []) or [] - subobjects_dict['roles_list'] = getattr(obj, '_roles', []) or [] - action_list = obj.listActions() or [] - subobjects_dict['action_list'] = [] - for action in action_list: - subobjects_dict['action_list'].append(action._getCopy(obj)) - wf_chain = getChainByType(self.getPortalObject())[1] - if wf_chain.has_key('chain_%s' % object_id): - subobjects_dict['workflow_chain'] = wf_chain['chain_%s' % object_id] - else: - subobjects_dict['workflow_chain'] = '' - else: + if obj is not None: for subobject_id in list(obj.objectIds()): subobject_path = object_path + [subobject_id] subobject = self.unrestrictedTraverse(subobject_path) subobject_copy = subobject._p_jar.exportFile(subobject._p_oid) subobjects_dict[subobject_id] = subobject_copy if save: # remove subobjecs from backup object - obj.manage_delObjects([subobject_id]) + obj._delObject(subobject_id) return subobjects_dict def newTrashBin(self, bt_title='trash', bt=None): diff --git a/product/ERP5/tests/testBusinessTemplate.py b/product/ERP5/tests/testBusinessTemplate.py index 2bb5593170d1c6df58cafb9d77a2aff54fe7ab64..022a503184ec8ceb34eded3ea350956c740715db 100644 --- a/product/ERP5/tests/testBusinessTemplate.py +++ b/product/ERP5/tests/testBusinessTemplate.py @@ -331,29 +331,25 @@ class TestBusinessTemplate(ERP5TypeTestCase, LogInterceptor): """ pt = self.getTypeTool() # create module object portal type - pt.manage_addTypeInformation(ERP5TypeInformation.meta_type, - id='Geek Object', - typeinfo_name='ERP5Type: ERP5 Person',) - object_type = pt._getOb('Geek Object', None) + object_type = pt.newContent('Geek Object', 'Base Type', + type_factory_method_id='addPerson') self.failUnless(object_type is not None) sequence.edit(object_ptype_id=object_type.getId()) # create module portal type - pt.manage_addTypeInformation(ERP5TypeInformation.meta_type, - id='Geek Module', - typeinfo_name='ERP5Type: ERP5 Folder') - module_type = pt._getOb('Geek Module', None) + module_type = pt.newContent('Geek Module', 'Base Type', + type_factory_method_id='addFolder', + type_filter_content_type=1, + type_allowed_content_type_list=('Geek Object',), + type_hidden_content_type_list=('Geek Object',), + type_base_category_list=('destination',), + type_property_sheet_list=('Version',)) self.failUnless(module_type is not None) - module_type.filter_content_types = 1 - module_type.allowed_content_types = ('Geek Object',) - module_type.hidden_content_type_list = ('Geek Object',) - module_type.base_category_list = ('destination',) - module_type.property_sheet_list = ('Version',) sequence.edit(module_ptype_id=module_type.getId(), - module_ptype_filter_content_types=module_type.filter_content_types, - module_ptype_allowed_content_types=module_type.allowed_content_types, - module_ptype_hidden_content_type_list=module_type.hidden_content_type_list, - module_ptype_base_category_list=module_type.base_category_list, - module_ptype_property_sheet_list=module_type.property_sheet_list) + module_ptype_filter_content_types=module_type.getTypeFilterContentType(), + module_ptype_allowed_content_types=module_type.getTypeAllowedContentTypeList(), + module_ptype_hidden_content_type_list=module_type.getTypeHiddenContentTypeList(), + module_ptype_base_category_list=module_type.getTypeBaseCategoryList(), + module_ptype_property_sheet_list=module_type.getTypePropertySheetList()) def stepModifyPortalTypeInBusinessTemplate(self, sequence=None, sequence_list=None, **kw): """ @@ -374,10 +370,10 @@ class TestBusinessTemplate(ERP5TypeTestCase, LogInterceptor): template_portal_type_hidden_content_type=(), template_portal_type_base_category=('Geek Module | source',), template_portal_type_property_sheet=()) - sequence.edit(module_ptype_allowed_content_types=('Geek Module',), - module_ptype_hidden_content_type_list=(), - module_ptype_base_category_list=('source',), - module_ptype_property_sheet_list=()) + sequence.edit(module_ptype_allowed_content_types=['Geek Module'], + module_ptype_hidden_content_type_list=[], + module_ptype_base_category_list=['source'], + module_ptype_property_sheet_list=[]) def stepAddPortalTypeToBusinessTemplate(self, sequence=None, sequence_list=None, **kw): """ @@ -417,15 +413,17 @@ class TestBusinessTemplate(ERP5TypeTestCase, LogInterceptor): object_type = pt._getOb(object_id, None) self.failUnless(object_type is None) - def stepRemoveViewAction(self, sequence=None, sequence_list=None, **kw): + def stepRemoveFirstAction(self, sequence=None, sequence_list=None, **kw): """ Remove PortalType """ pt = self.getTypeTool() object_id = sequence.get('object_ptype_id') - module_id = sequence.get('module_ptype_id') - object_type = pt._getOb(object_id, None) - object_type.deleteActions([0]) + action_id = sequence.get('first_action_id') + object_type = pt[object_id] + action_id, = [x.getId() for x in object_type.getActionInformationList() + if x.getReference() == action_id] + object_type._delObject(action_id) def stepCheckPortalTypeExists(self, sequence=None, sequence_list=None, **kw): """ @@ -436,15 +434,15 @@ class TestBusinessTemplate(ERP5TypeTestCase, LogInterceptor): module_id = sequence.get('module_ptype_id') module_type = pt._getOb(module_id, None) self.failUnless(module_type is not None) - self.assertEquals(module_type.allowed_content_types, + self.assertEqual(module_type.getTypeAllowedContentTypeList(), sequence.get('module_ptype_allowed_content_types')) - self.assertEquals(module_type.hidden_content_type_list, + self.assertEqual(module_type.getTypeHiddenContentTypeList(), sequence.get('module_ptype_hidden_content_type_list')) - self.assertEquals(module_type.filter_content_types, + self.assertEqual(module_type.getTypeFilterContentType(), sequence.get('module_ptype_filter_content_types')) - self.assertEquals(module_type.base_category_list, + self.assertEqual(module_type.getTypeBaseCategoryList(), sequence.get('module_ptype_base_category_list')) - self.assertEquals(module_type.property_sheet_list, + self.assertEqual(module_type.getTypePropertySheetList(), sequence.get('module_ptype_property_sheet_list')) object_type = pt._getOb(object_id, None) self.failUnless(object_type is not None) @@ -1262,19 +1260,6 @@ class TestBusinessTemplate(ERP5TypeTestCase, LogInterceptor): , priority = 1.5 ) sequence.edit(second_action_id='become_nerd') - def stepCheckActionsOrder(self, sequence=None, sequence_list=None, **kw): - """ - Check Actions Order - """ - pt = self.getTypeTool() - object_id = sequence.get('object_ptype_id') - object_pt = pt._getOb(object_id) - actions_list = object_pt.listActions() - priority = 0 - for action in actions_list: - self.failIf(action.priority < priority) - priority = action.priority - def stepCheckFirstActionExists(self, sequence=None, sequence_list=None, **kw): """ Check presence of action @@ -1283,7 +1268,8 @@ class TestBusinessTemplate(ERP5TypeTestCase, LogInterceptor): object_id = sequence.get('object_ptype_id') object_pt = pt._getOb(object_id) action_id = sequence.get('first_action_id') - self.failUnless(action_id in [x.getId() for x in object_pt.listActions()]) + self.assertTrue(action_id in [x.getReference() + for x in object_pt.getActionInformationList()]) def stepCheckFirstActionNotExists(self, sequence=None, sequence_list=None, **kw): """ @@ -1293,7 +1279,8 @@ class TestBusinessTemplate(ERP5TypeTestCase, LogInterceptor): object_id = sequence.get('object_ptype_id') object_pt = pt._getOb(object_id) action_id = sequence.get('first_action_id') - self.failUnless(action_id not in [x.getId() for x in object_pt.listActions()]) + self.assertTrue(action_id in [x.getReference() + for x in object_pt.getActionInformationList()]) def stepCheckSecondActionExists(self, sequence=None, sequence_list=None, **kw): """ @@ -1303,7 +1290,8 @@ class TestBusinessTemplate(ERP5TypeTestCase, LogInterceptor): object_id = sequence.get('object_ptype_id') object_pt = pt._getOb(object_id) action_id = sequence.get('second_action_id') - self.failUnless(action_id in [x.getId() for x in object_pt.listActions()]) + self.assertTrue(action_id in [x.getReference() + for x in object_pt.getActionInformationList()]) def stepCheckSecondActionNotExists(self, sequence=None, sequence_list=None, **kw): """ @@ -1313,7 +1301,8 @@ class TestBusinessTemplate(ERP5TypeTestCase, LogInterceptor): object_id = sequence.get('object_ptype_id') object_pt = pt._getOb(object_id) action_id = sequence.get('second_action_id') - self.failUnless(action_id not in [x.getId() for x in object_pt.listActions()]) + self.assertTrue(action_id in [x.getReference() + for x in object_pt.getActionInformationList()]) def stepAddSecondActionToBusinessTemplate(self, sequence=None, sequence_list=None, **kw): """ @@ -2218,7 +2207,8 @@ class TestBusinessTemplate(ERP5TypeTestCase, LogInterceptor): """ import_bt = sequence.get('current_bt') diff_list = import_bt.BusinessTemplate_getModifiedObject() - self.assertTrue('portal_types/Geek Object/view' in [line.object_id for line in diff_list]) + self.assertTrue('portal_types/Geek Object/become_geek' + in [line.object_id for line in diff_list]) import_bt.reinstall() def stepInstallCurrentBusinessTemplate(self, sequence=None, sequence_list=None, **kw): @@ -3077,7 +3067,6 @@ class TestBusinessTemplate(ERP5TypeTestCase, LogInterceptor): CheckSkinsLayers \ CheckFirstActionExists \ CheckSecondActionExists \ - CheckActionsOrder \ UninstallBusinessTemplate \ CheckBuiltBuildingState \ CheckNotInstalledInstallationState \ @@ -5054,13 +5043,12 @@ class TestBusinessTemplate(ERP5TypeTestCase, LogInterceptor): pt = self.getTypeTool() object_id = sequence.get('object_ptype_id') object_pt = pt._getOb(object_id) - object_pt.addRole(id='geek_role_definition', - description='A definition with non ascii chars 茅脿猫', - name='Geek Role Definition', - condition='', - category='group/g1\nfunction/f1\n', - base_category_script='Base Category Script', - base_category='group site',) + object_pt.newContent(portal_type='Role Information', + description='A definition with non ascii chars 茅脿猫', + role_name_list=('Geek Role Definition',), + role_category_list=('group/g1','function/f1'), + role_base_category_script_id='Base Category Script', + role_base_category_list=('group','site')) sequence.edit(portal_type_role='geek_role_definition') @@ -5084,18 +5072,12 @@ class TestBusinessTemplate(ERP5TypeTestCase, LogInterceptor): """ pt = self.getTypeTool() object_id = sequence.get('object_ptype_id') - object_pt = pt._getOb(object_id) - role_list = object_pt._roles - role_list = [x for x in role_list if x.id == 'geek_role_definition'] - self.assertEquals(1, len(role_list)) - role = role_list[0] - self.assertEquals('Geek Role Definition', role.title) - self.assertEquals('A definition with non ascii chars 茅脿猫', role.description) - self.assertEquals(('group/g1','function/f1'), role.getCategory()) - self.assertEquals(('group','site'), role.getBaseCategory()) - self.assertEquals('Base Category Script', role.getBaseCategoryScript()) - # role name is a string, not unicode - self.assertTrue(isinstance(role.id, str)) + role, = pt[object_id].getRoleInformationList() + self.assertEqual(['Geek Role Definition'], role.getRoleNameList()) + self.assertEqual('A definition with non ascii chars 茅脿猫', role.getDescription()) + self.assertEqual(['group/g1','function/f1'], role.getRoleCategoryList()) + self.assertEqual(['group','site'], role.getRoleBaseCategoryList()) + self.assertEqual('Base Category Script', role.getRoleBaseCategoryScriptId()) def test_36_CheckPortalTypeRoles(self, quiet=quiet, run=run_all_test): if not run: return @@ -5244,7 +5226,7 @@ class TestBusinessTemplate(ERP5TypeTestCase, LogInterceptor): SaveBusinessTemplate \ InstallCurrentBusinessTemplate Tic \ Tic \ - RemoveViewAction \ + RemoveFirstAction \ ReinstallBusinessTemplate Tic \ ' sequence_list.addSequenceString(sequence_string) diff --git a/product/ERP5/tests/testERP5Core.py b/product/ERP5/tests/testERP5Core.py index de0f4971018762b1c74a536eb13f36e3283b8da1..6078d257c28e7503919e8cd5b5a3fac8401ae2d1 100644 --- a/product/ERP5/tests/testERP5Core.py +++ b/product/ERP5/tests/testERP5Core.py @@ -210,14 +210,12 @@ class TestERP5Core(ERP5TypeTestCase, ZopeTestCase.Functional): translation_service = DummyTranslationService() setGlobalTranslationService(translation_service) # adds a new jump action to Template Tool portal type - self.getTypesTool().getTypeInfo('Template Tool').addAction( - id='dummy_jump_action', - name='Dummy Jump Action', - action='', - condition='', - permission='View', - category='object_jump', - visible=1) + self.getTypesTool().getTypeInfo('Template Tool').newContent( + portal_type='Action Information', + reference='dummy_jump_action', + title='Dummy Jump Action', + action_permission='View', + action_type='object_jump') response = self.publish('%s/portal_templates/view' % self.portal_id, self.auth) self.assertEquals(HTTP_OK, response.getStatus()) diff --git a/product/ERP5Type/ERP5Type.py b/product/ERP5Type/ERP5Type.py index 3eb8dc22d2b8088cf47a9e1a0d06e4704d24d7c7..a479f11deb87ba9a45fa08add746a2f7cf6bd8b4 100644 --- a/product/ERP5Type/ERP5Type.py +++ b/product/ERP5Type/ERP5Type.py @@ -593,6 +593,8 @@ class ERP5TypeInformation(XMLObject, permissions=tuple(action.getActionPermissionList())) for k, v in action.__dict__.iteritems(): if k in ('action', 'condition', 'icon'): + if not v: + continue v = v.__class__(v.text) elif k in ('id', 'float_index', 'action_permission', 'reference'): continue