def test_TaskServiceValidation1(self): """ Test TaskServiceValidation adaptations """ # is function added self.assertIn('n_plus_1', [fct['fct_id'] for fct in get_registry_functions()]) # is local roles modified fti = getUtility(IDexterityFTI, name='task') lr = getattr(fti, 'localroles') self.assertIn('n_plus_1', lr['assigned_group']['to_do']) self.assertIn('n_plus_1', lr['parents_assigned_groups']['to_do']) for ptype in ('ClassificationFolder', 'ClassificationSubfolder'): fti = getUtility(IDexterityFTI, name=ptype) lr = getattr(fti, 'localroles') self.assertIn('n_plus_1', lr['treating_groups']['active'], ptype) self.assertIn('n_plus_1', lr['recipient_groups']['active'], ptype) # check collection folder = self.portal['tasks']['task-searches'] self.assertTrue(folder['to_assign'].enabled) self.assertTrue(folder['to_close'].enabled) self.assertFalse(folder['to_treat_in_my_group'].showNumberOfItems) # check annotations config = get_dms_config(['review_levels', 'task']) self.assertIn('_n_plus_1', config) config = get_dms_config(['review_states', 'task']) self.assertIn('to_assign', config) self.assertIn('realized', config)
def test_IMPreManagerAdaptation(self): """ Test wf adaptation modifications """ # check workflow self.assertSetEqual( set(self.imw.states), { 'created', 'proposed_to_pre_manager', 'proposed_to_manager', 'proposed_to_agent', 'in_treatment', 'closed' }) self.assertSetEqual( set(self.imw.transitions), { 'back_to_creation', 'back_to_pre_manager', 'back_to_manager', 'back_to_agent', 'back_to_treatment', 'propose_to_pre_manager', 'propose_to_manager', 'propose_to_agent', 'treat', 'close' }) self.assertSetEqual(set(self.imw.states['created'].transitions), { 'propose_to_pre_manager', 'propose_to_manager', 'propose_to_agent' }) self.assertSetEqual( set(self.imw.states['proposed_to_pre_manager'].transitions), {'back_to_creation', 'propose_to_manager'}) self.assertSetEqual( set(self.imw.states['proposed_to_manager'].transitions), {'back_to_creation', 'back_to_pre_manager', 'propose_to_agent'}) self.assertSetEqual( set(self.imw.states['proposed_to_agent'].transitions), {'back_to_creation', 'back_to_manager', 'treat', 'close'}) self.assertSetEqual(set(self.imw.states['in_treatment'].transitions), {'back_to_agent', 'close'}) self.assertSetEqual(set(self.imw.states['closed'].transitions), {'back_to_treatment', 'back_to_agent'}) # check local roles fti = getUtility(IDexterityFTI, name='dmsincomingmail') lr = getattr(fti, 'localroles') self.assertIn('proposed_to_pre_manager', lr['static_config']) self.assertIn('pre_manager', lr['static_config']['proposed_to_manager']) self.assertIn('pre_manager', lr['static_config']['proposed_to_agent']) # check collection folder = self.portal['incoming-mail']['mail-searches'] self.assertIn('searchfor_proposed_to_pre_manager', folder) self.assertEqual( folder.getObjectPosition('searchfor_proposed_to_manager'), 12) self.assertEqual( folder.getObjectPosition('searchfor_proposed_to_pre_manager'), 11) # check annotations config = get_dms_config(['review_levels', 'dmsincomingmail']) self.assertIn('pre_manager', config) config = get_dms_config(['review_states', 'dmsincomingmail']) self.assertIn('proposed_to_pre_manager', config) # check voc factory = getUtility(IVocabularyFactory, u'imio.dms.mail.IMReviewStatesVocabulary') self.assertEqual(len(factory(self.portal)), 6) # check configuration lst = api.portal.get_registry_record( 'imio.actionspanel.browser.registry.IImioActionsPanelConfig.transitions' ) self.assertIn('dmsincomingmail.back_to_pre_manager|', lst)
def test_dms_config(self): annot = IAnnotations(self.portal) set_dms_config(['a'], value='dict') lst = set_dms_config(['a', 'b'], value='list') self.assertTrue(isinstance(annot['imio.dms.mail'], PersistentDict)) self.assertTrue(isinstance(annot['imio.dms.mail']['a'], PersistentDict)) self.assertTrue( isinstance(annot['imio.dms.mail']['a']['b'], PersistentList)) lst.append(1) self.assertEqual(get_dms_config(['a', 'b']), [1]) set_dms_config(['a', 'b'], value='plone') self.assertTrue(isinstance(annot['imio.dms.mail']['a']['b'], str)) self.assertEqual(get_dms_config(['a', 'b']), 'plone')
def dms_config(self): try: get_dms_config() return except KeyError: pass set_dms_config( ['review_levels', 'dmsincomingmail'], # i_e ok OrderedDict([('dir_general', { 'st': ['proposed_to_manager'] }), ('_validateur', { 'st': ['proposed_to_service_chief'], 'org': 'treating_groups' })])) set_dms_config(['review_levels', 'task'], OrderedDict([('_validateur', { 'st': ['to_assign', 'realized'], 'org': 'assigned_group' })])) set_dms_config(['review_levels', 'dmsoutgoingmail'], OrderedDict([('_validateur', { 'st': ['proposed_to_service_chief'], 'org': 'treating_groups' })])) set_dms_config( ['review_states', 'dmsincomingmail'], # i_e ok OrderedDict([('proposed_to_manager', { 'group': 'dir_general' }), ('proposed_to_service_chief', { 'group': '_validateur', 'org': 'treating_groups' })])) set_dms_config(['review_states', 'task'], OrderedDict([('to_assign', { 'group': '_validateur', 'org': 'assigned_group' }), ('realized', { 'group': '_validateur', 'org': 'assigned_group' })])) set_dms_config(['review_states', 'dmsoutgoingmail'], OrderedDict([('proposed_to_service_chief', { 'group': '_validateur', 'org': 'treating_groups' })]))
def task_transition(task, event): """ update indexes after a transition """ task.reindexObject(['state_group']) if event.transition: if event.transition.id == 'do_to_assign': task.auto_to_do_flag = False # Set auto_to_do_flag on task if : # assigned_user is set OR # level n_plus_1 is not there OR # users in level n_plus_1 if task.assigned_user: task.auto_to_do_flag = True elif not [dic for dic in get_applied_adaptations() if dic['adaptation'] == 'imio.dms.mail.wfadaptations.TaskServiceValidation']: task.auto_to_do_flag = True else: transitions_levels = get_dms_config(['transitions_levels', 'task']) if task.assigned_group and transitions_levels['created'][task.assigned_group][0] != 'do_to_assign': task.auto_to_do_flag = True elif event.transition.id == 'back_in_to_assign': # Remove auto_to_do_flag on task. task.auto_to_do_flag = False
def validation_criterion(context, portal_type): """ Return a query criterion corresponding to current user validation level """ if portal_type == 'dmsincoming_email': portal_type = 'dmsincomingmail' # i_e ok groups = api.group.get_groups(user=api.user.get_current()) groups_ids = [g.id for g in groups] config = get_dms_config(['review_levels', portal_type]) # set_dms_config(['review_levels', 'dmsincomingmail'], # i_e ok # OrderedDict([('dir_general', {'st': ['proposed_to_manager']}), # ('_n_plus_1', {'st': ['proposed_to_n_plus_1'], 'org': 'treating_groups'})])) ret = {'state_group': {'query': []}} for group_or_suffix in config: if not group_or_suffix.startswith('_'): if group_or_suffix in groups_ids: for state in config[group_or_suffix]['st']: ret['state_group']['query'].append(state) else: # get orgs of user groups with suffix orgs = organizations_with_suffixes(groups, [group_or_suffix[1:]]) if orgs: for state in config[group_or_suffix]['st']: for org in orgs: ret['state_group']['query'].append('%s,%s' % (state, org)) return ret
def updatewidgets_assigned_user_description(the_form): """ Set a description if the field must be completed """ state = api.content.get_state(the_form.context) treating_group = the_form.context.treating_groups transitions_levels = get_dms_config( ['transitions_levels', 'dmsincomingmail']) # i_e ok if state in transitions_levels and treating_group in transitions_levels[ state]: transition = transitions_levels[state][treating_group][0] transitions_auc = get_dms_config( ['transitions_auc', 'dmsincomingmail']) # i_e ok if transition in transitions_auc and not transitions_auc[ transition].get(treating_group, False): the_form.widgets['ITask.assigned_user'].field = copy.copy( the_form.widgets['ITask.assigned_user'].field) the_form.widgets['ITask.assigned_user'].field.description = _( u'You must select an assigned user ' u'before you can propose to an agent !')
def test_im_workflow0(self): """ Check workflow """ self.imw = self.pw['incomingmail_workflow'] self.assertSetEqual(set(self.imw.states), {'created', 'proposed_to_manager', 'proposed_to_agent', 'in_treatment', 'closed'}) self.assertSetEqual(set(self.imw.transitions), {'back_to_creation', 'back_to_manager', 'back_to_agent', 'back_to_treatment', 'propose_to_manager', 'propose_to_agent', 'treat', 'close'}) self.assertSetEqual(set(self.imw.states['created'].transitions), {'propose_to_manager', 'propose_to_agent'}) self.assertSetEqual(set(self.imw.states['proposed_to_manager'].transitions), {'back_to_creation', 'propose_to_agent'}) self.assertSetEqual(set(self.imw.states['proposed_to_agent'].transitions), {'back_to_creation', 'back_to_manager', 'treat', 'close'}) self.assertSetEqual(set(self.imw.states['in_treatment'].transitions), {'back_to_agent', 'close'}) self.assertSetEqual(set(self.imw.states['closed'].transitions), {'back_to_treatment', 'back_to_agent'}) # default annotations wf_from_to = get_dms_config(['wf_from_to', 'dmsincomingmail', 'n_plus']) self.assertSetEqual(set(wf_from_to['to']), {('closed', 'close'), ('proposed_to_agent', 'propose_to_agent')})
def state_group_index(obj): """Indexer of 'state_group' for IDmsDocument. Stores: * state,org_uid when validation is at org level * state only otherwise """ # No acquisition pb because state_group isn't an attr state = api.content.get_state(obj=obj) portal_type = obj.portal_type if portal_type == 'dmsincoming_email': portal_type = 'dmsincomingmail' # i_e ok # elif portal_type == 'dmsoutgoing_email': # portal_type = 'dmsoutgoingmail' # set_dms_config(['review_states', 'dmsincomingmail'], # i_e ok # OrderedDict([('proposed_to_manager', {'group': 'dir_general'}), # ('proposed_to_n_plus_1', {'group': '_n_plus_1', 'org': 'treating_groups'})])) config = get_dms_config(['review_states', portal_type]) if state not in config or not config[state]['group'].startswith('_'): return state else: return "%s,%s" % (state, getattr(obj, config[state]['org']))
def highest_validation_criterion(portal_type): """ Return a query criterion corresponding to current user highest validation level NO MORE USED """ if portal_type == 'dmsincoming_email': portal_type = 'dmsincomingmail' # i_e ok groups = api.group.get_groups(user=api.user.get_current()) highest_level = highest_review_level(portal_type, str([g.id for g in groups])) if highest_level is None: return default_criterias[portal_type] ret = {} review_levels = get_dms_config(['review_levels']) criterias = review_levels[portal_type][highest_level] if 'st' in criterias: ret['review_state'] = {'query': criterias['st']} if 'org' in criterias: organizations = [] for group in groups: if group.id.endswith(highest_level): organizations.append(group.id[:-len(highest_level)]) ret[criterias['org']] = {'query': organizations} return ret
def test_update_transitions_levels_config(self): # dmsincomingmail # config = get_dms_config(['transitions_levels', 'dmsincomingmail']) self.assertSetEqual( set(config.keys()), {'created', 'proposed_to_manager', 'proposed_to_agent', 'closed'}) self.assertEqual(config['created'], config['proposed_to_manager']) self.assertEqual(config['created'], config['proposed_to_agent']) self.assertEqual(config['created'], config['closed']) for state in config: for org in config[state]: self.assertEqual(config[state][org], ('propose_to_agent', 'from_states')) org1, org2 = get_registry_organizations()[0:2] # we simulate the adding of a level without user api.group.create('{}_n_plus_1'.format(org1), 'N+1') set_dms_config(['wf_from_to', 'dmsincomingmail', 'n_plus', 'to'], [('closed', 'close'), ('proposed_to_agent', 'propose_to_agent'), ('proposed_to_n_plus_1', 'propose_to_n_plus_1')]) update_transitions_levels_config(['dmsincomingmail']) config = get_dms_config(['transitions_levels', 'dmsincomingmail']) self.assertEqual(config['proposed_to_n_plus_1'][org1], ('propose_to_agent', 'from_states')) self.assertEqual(config['proposed_to_manager'][org1], ('propose_to_agent', 'from_states')) self.assertEqual(config['proposed_to_manager'][org2], ('propose_to_agent', 'from_states')) self.assertEqual(config['proposed_to_agent'][org1], ('propose_to_agent', 'from_states')) self.assertEqual(config['closed'][org1], ('propose_to_agent', 'from_states')) # we simulate the adding of a level and a user update_transitions_levels_config(['dmsincomingmail'], 'add', '{}_n_plus_1'.format(org1)) config = get_dms_config(['transitions_levels', 'dmsincomingmail']) self.assertEqual(config['proposed_to_n_plus_1'][org1], ('propose_to_agent', 'from_states')) self.assertEqual(config['proposed_to_manager'][org1], ('propose_to_n_plus_1', 'from_states')) self.assertEqual(config['proposed_to_manager'][org2], ('propose_to_agent', 'from_states')) self.assertEqual(config['proposed_to_agent'][org1], ('propose_to_agent', 'back_to_n_plus_1')) self.assertEqual(config['proposed_to_agent'][org2], ('propose_to_agent', 'from_states')) # dmsoutgoingmail # config = get_dms_config(['transitions_levels', 'dmsoutgoingmail']) self.assertSetEqual(set(config.keys()), {'created', 'to_be_signed', 'sent'}) self.assertEqual(config['created'], config['to_be_signed']) for state in config: for org in config[state]: self.assertEqual(config[state][org], ('', '')) org1, org2 = get_registry_organizations()[0:2] # we simulate the adding of a level without user api.group.create('{}_n_plus_1'.format(org1), 'N+1') update_transitions_levels_config(['dmsoutgoingmail']) config = get_dms_config(['transitions_levels', 'dmsoutgoingmail']) self.assertEqual(config['created'][org1], ('', '')) self.assertEqual(config['to_be_signed'][org1], ('', '')) self.assertEqual(config['created'][org2], ('', '')) self.assertEqual(config['to_be_signed'][org2], ('', '')) # we simulate the adding of a level and a user update_transitions_levels_config(['dmsoutgoingmail'], 'add', '{}_n_plus_1'.format(org1)) config = get_dms_config(['transitions_levels', 'dmsoutgoingmail']) self.assertEqual(config['created'][org1], ('propose_to_n_plus_1', '')) self.assertEqual(config['to_be_signed'][org1], ('', 'back_to_n_plus_1')) self.assertEqual(config['created'][org2], ('', '')) self.assertEqual(config['to_be_signed'][org2], ('', '')) # task # config = get_dms_config(['transitions_levels', 'task']) for org in config['created']: self.assertEqual(config['created'][org], ('', '')) for org in config['to_do']: self.assertEqual(config['to_do'][org], ('', 'back_in_created2')) org1, org2 = get_registry_organizations()[0:2] # we simulate the adding of a level without user api.group.create('{}_n_plus_1'.format(org1), 'N+1') update_transitions_levels_config(['task']) config = get_dms_config(['transitions_levels', 'task']) self.assertEqual(config['to_do'][org1], ('', 'back_in_created2')) self.assertEqual(config['to_do'][org2], ('', 'back_in_created2')) # we simulate the adding of a level and a user update_transitions_levels_config(['task'], 'add', '{}_n_plus_1'.format(org1)) config = get_dms_config(['transitions_levels', 'task']) self.assertEqual(config['created'][org1], ('do_to_assign', '')) self.assertEqual(config['to_do'][org1], ('', 'back_in_to_assign')) self.assertEqual(config['created'][org2], ('', '')) self.assertEqual(config['to_do'][org2], ('', 'back_in_created2'))
def test_update_transitions_auc_config(self): api.portal.set_registry_record(AUC_RECORD, u'no_check') # no check config = get_dms_config(['transitions_auc', 'dmsincomingmail']) self.assertSetEqual(set(config.keys()), {'close', 'propose_to_agent'}) self.assertTrue(all( config['propose_to_agent'].values())) # can always do transition self.assertTrue(all( config['close'].values())) # can always do transition # n_plus_1 api.portal.set_registry_record(AUC_RECORD, u'n_plus_1') # only one transition config = get_dms_config(['transitions_auc', 'dmsincomingmail']) self.assertSetEqual(set(config.keys()), {'close', 'propose_to_agent'}) self.assertTrue(all(config['propose_to_agent'].values())) self.assertTrue(all(config['close'].values())) # we simulate the adding of a level without user org1, org2 = get_registry_organizations()[0:2] api.group.create('{}_n_plus_1'.format(org1), 'N+1') set_dms_config(['wf_from_to', 'dmsincomingmail', 'n_plus', 'to'], [('closed', 'close'), ('proposed_to_agent', 'propose_to_agent'), ('proposed_to_n_plus_1', 'propose_to_n_plus_1')]) update_transitions_auc_config('dmsincomingmail') config = get_dms_config(['transitions_auc', 'dmsincomingmail']) self.assertSetEqual( set(config.keys()), {'close', 'propose_to_n_plus_1', 'propose_to_agent'}) self.assertTrue(all(config['propose_to_n_plus_1'].values())) self.assertTrue(all(config['propose_to_agent'].values())) self.assertTrue(all(config['close'].values())) # we simulate the adding of a level and a user update_transitions_auc_config('dmsincomingmail', 'add', '{}_n_plus_1'.format(org1)) config = get_dms_config(['transitions_auc', 'dmsincomingmail']) self.assertTrue(config['propose_to_n_plus_1'][org1]) self.assertFalse(config['propose_to_agent'] [org1]) # cannot do transition because user self.assertTrue(config['propose_to_agent'][org2]) # mandatory # reset config set_dms_config(['transitions_auc', 'dmsincomingmail'], value='dict') set_dms_config(['wf_from_to', 'dmsincomingmail', 'n_plus', 'to'], [('closed', 'close'), ('proposed_to_agent', 'propose_to_agent')]) api.portal.set_registry_record(AUC_RECORD, 'mandatory') config = get_dms_config(['transitions_auc', 'dmsincomingmail']) self.assertFalse(any( config['propose_to_agent'].values())) # all is False self.assertTrue(all(config['close'].values())) # we simulate the adding of a level without user set_dms_config(['wf_from_to', 'dmsincomingmail', 'n_plus', 'to'], [('closed', 'close'), ('proposed_to_agent', 'propose_to_agent'), ('proposed_to_n_plus_1', 'propose_to_n_plus_1')]) update_transitions_auc_config('dmsincomingmail') config = get_dms_config(['transitions_auc', 'dmsincomingmail']) self.assertSetEqual( set(config.keys()), {'close', 'propose_to_n_plus_1', 'propose_to_agent'}) self.assertFalse(any( config['propose_to_n_plus_1'].values())) # all is False self.assertFalse(any( config['propose_to_agent'].values())) # all is False self.assertTrue(all(config['close'].values())) # we simulate the adding of a level and a user update_transitions_auc_config('dmsincomingmail', 'add', '{}_n_plus_1'.format(org1)) config = get_dms_config(['transitions_auc', 'dmsincomingmail']) self.assertTrue(config['propose_to_n_plus_1'] [org1]) # can do transition because user self.assertFalse(config['propose_to_n_plus_1'][org2]) self.assertFalse(config['propose_to_agent'][org1]) self.assertFalse(config['propose_to_agent'][org2])
def test_OMServiceValidation1(self): """ Test OMServiceValidation adaptations """ # is function added self.assertIn('n_plus_1', [fct['fct_id'] for fct in get_registry_functions()]) # is local roles modified fti = getUtility(IDexterityFTI, name='dmsoutgoingmail') lr = getattr(fti, 'localroles') self.assertIn('proposed_to_n_plus_1', lr['treating_groups']) self.assertIn('proposed_to_n_plus_1', lr['recipient_groups']) self.assertIn('validated', lr['treating_groups']) self.assertIn('validated', lr['recipient_groups']) for ptype in ('ClassificationFolder', 'ClassificationSubfolder'): fti = getUtility(IDexterityFTI, name=ptype) lr = getattr(fti, 'localroles') self.assertIn('n_plus_1', lr['treating_groups']['active'], ptype) self.assertIn('n_plus_1', lr['recipient_groups']['active'], ptype) # check collection folder = self.portal['outgoing-mail']['mail-searches'] self.assertIn('searchfor_proposed_to_n_plus_1', folder) self.assertIn('searchfor_validated', folder) self.assertEqual( folder.getObjectPosition('searchfor_proposed_to_n_plus_1'), 10) self.assertEqual(folder.getObjectPosition('searchfor_validated'), 11) self.assertEqual(folder.getObjectPosition('searchfor_to_be_signed'), 12) self.assertIn('proposed_to_n_plus_1', [ dic['v'] for dic in folder['om_treating'].query if dic['i'] == 'review_state' ][0]) self.assertIn('validated', [ dic['v'] for dic in folder['om_treating'].query if dic['i'] == 'review_state' ][0]) self.assertTrue(folder['to_validate'].enabled) # check annotations config = get_dms_config(['review_levels', 'dmsoutgoingmail']) self.assertIn('_n_plus_1', config) config = get_dms_config(['review_states', 'dmsoutgoingmail']) self.assertIn('proposed_to_n_plus_1', config) # check vocabularies factory = getUtility( IVocabularyFactory, u'collective.eeafaceted.collectionwidget.cachedcollectionvocabulary' ) self.assertEqual(len(factory(folder, folder)), 14) factory = getUtility(IVocabularyFactory, u'imio.dms.mail.OMReviewStatesVocabulary') self.assertEqual(len(factory(folder)), 6) # check configuration lst = api.portal.get_registry_record( 'imio.actionspanel.browser.registry.IImioActionsPanelConfig.transitions' ) self.assertIn('dmsoutgoingmail.back_to_n_plus_1|', lst) self.assertIn('dmsoutgoingmail.back_to_validated|', lst) lst = api.portal.get_registry_record( 'imio.dms.mail.browser.settings.IImioDmsMailConfig.omail_remark_states' ) self.assertIn('proposed_to_n_plus_1', lst) self.assertIn('validated', lst)
def test_IMServiceValidation1(self): """ Test IMServiceValidation adaptations """ # is function added self.assertIn('n_plus_1', [fct['fct_id'] for fct in get_registry_functions()]) # is local roles modified for ptype in ('dmsincomingmail', 'dmsincoming_email'): fti = getUtility(IDexterityFTI, name=ptype) lr = getattr(fti, 'localroles') self.assertIn('proposed_to_n_plus_1', lr['static_config'], ptype) self.assertIn('proposed_to_n_plus_1', lr['treating_groups'], ptype) self.assertIn('proposed_to_n_plus_1', lr['recipient_groups'], ptype) for ptype in ('ClassificationFolder', 'ClassificationSubfolder'): fti = getUtility(IDexterityFTI, name=ptype) lr = getattr(fti, 'localroles') self.assertIn('n_plus_1', lr['treating_groups']['active'], ptype) self.assertIn('n_plus_1', lr['recipient_groups']['active'], ptype) # check collection folder = self.portal['incoming-mail']['mail-searches'] self.assertIn('searchfor_proposed_to_n_plus_1', folder) self.assertEqual( folder.getObjectPosition('searchfor_proposed_to_agent'), 13) self.assertEqual( folder.getObjectPosition('searchfor_proposed_to_n_plus_1'), 12) self.assertFalse(folder['to_treat_in_my_group'].showNumberOfItems) # check annotations config = get_dms_config(['review_levels', 'dmsincomingmail']) self.assertIn('_n_plus_1', config) config = get_dms_config(['review_states', 'dmsincomingmail']) self.assertIn('proposed_to_n_plus_1', config) config = get_dms_config(['transitions_auc', 'dmsincomingmail']) self.assertIn('propose_to_n_plus_1', config) config = get_dms_config(['transitions_levels', 'dmsincomingmail']) self.assertEqual(config['proposed_to_manager'].values()[0][0], 'propose_to_n_plus_1') self.assertEqual(config['proposed_to_agent'].values()[0][1], 'back_to_n_plus_1') wf_from_to = get_dms_config( ['wf_from_to', 'dmsincomingmail', 'n_plus']) self.assertListEqual(wf_from_to['to'], [('closed', 'close'), ('proposed_to_agent', 'propose_to_agent'), ('proposed_to_n_plus_1', 'propose_to_n_plus_1')]) # check vocabularies factory = getUtility( IVocabularyFactory, u'collective.eeafaceted.collectionwidget.cachedcollectionvocabulary' ) self.assertEqual(len(factory(folder, folder)), 16) factory = getUtility(IVocabularyFactory, u'imio.dms.mail.IMReviewStatesVocabulary') self.assertEqual(len(factory(folder)), 6) # check configuration lst = api.portal.get_registry_record( 'imio.actionspanel.browser.registry.IImioActionsPanelConfig.transitions' ) self.assertIn('dmsincomingmail.back_to_n_plus_1|', lst) self.assertIn('dmsincoming_email.back_to_n_plus_1|', lst) lst = api.portal.get_registry_record( 'imio.dms.mail.browser.settings.IImioDmsMailConfig.imail_remark_states' ) self.assertIn('proposed_to_n_plus_1', lst)
def run(self): logger.info('Migrating to imio.dms.mail 2.3...') # check if oo port or solr port must be changed update_solr_config() update_oo_config() # add new dms config used in update_transitions_levels_config if 'wf_from_to' not in get_dms_config(): set_dms_config( ['wf_from_to', 'dmsincomingmail', 'n_plus', 'from'], # i_e ok [('created', 'back_to_creation'), ('proposed_to_manager', 'back_to_manager')]) set_dms_config( ['wf_from_to', 'dmsincomingmail', 'n_plus', 'to'], # i_e ok [('proposed_to_agent', 'propose_to_agent')]) set_dms_config(['wf_from_to', 'dmsoutgoingmail', 'n_plus', 'from'], [('created', 'back_to_creation')]) set_dms_config(['wf_from_to', 'dmsoutgoingmail', 'n_plus', 'to'], [('to_be_signed', 'propose_to_be_signed')]) self.cleanRegistries() self.correct_actions() auc_stored = self.registry[AUC_RECORD] self.upgradeProfile('collective.contact.plonegroup:default') self.install( ['collective.contact.importexport', 'collective.fontawesome']) self.runProfileSteps('plonetheme.imioapps', steps=['viewlets']) # to hide messages-viewlet if not self.portal.portal_quickinstaller.isProductInstalled( 'collective.wfadaptations'): self.install(['collective.wfadaptations']) self.runProfileSteps('imio.dms.mail', steps=['actions', 'plone.app.registry'], run_dependencies=False) # add new task collection createTaskCollections(self.portal['tasks']['task-searches']) # migrate assigned_user_check self.update_assigned_user_check(auc_stored) # remove service_chief related self.remove_service_chief() # do various global adaptations self.update_site() # update daterange criteria self.update_dashboards() # update templates self.runProfileSteps('imio.dms.mail', steps=['imiodmsmail-update-templates'], profile='singles') # upgrade all except 'imio.dms.mail:default'. Needed with bin/upgrade-portals self.upgradeAll(omit=['imio.dms.mail:default']) self.runProfileSteps('imio.dms.mail', steps=['cssregistry', 'jsregistry']) # set jqueryui autocomplete to False. If not, contact autocomplete doesn't work self.registry[ 'collective.js.jqueryui.controlpanel.IJQueryUIPlugins.ui_autocomplete'] = False for prod in [ 'collective.contact.core', 'collective.contact.widget', 'collective.dms.batchimport', 'collective.dms.mailcontent', 'collective.eeafaceted.batchactions', 'collective.eeafaceted.collectionwidget', 'collective.eeafaceted.dashboard', 'collective.eeafaceted.z3ctable', 'collective.fingerpointing', 'collective.messagesviewlet', 'collective.wfadaptations', 'collective.z3cform.datetimewidget', 'communesplone.layout', 'eea.facetednavigation', 'eea.jquery', 'imio.actionspanel', 'imio.dashboard', 'imio.dms.mail', 'imio.history', 'plone.formwidget.autocomplete', 'plone.formwidget.contenttree', 'plonetheme.classic', 'plonetheme.imio.apps' ]: mark_last_version(self.portal, product=prod) # self.refreshDatabase() self.finish()
def remove_service_chief(self): # remove collection logger.info('Modifying workflows') for folder in (self.imf['mail-searches'], self.omf['mail-searches']): if 'searchfor_proposed_to_service_chief' in folder: api.content.delete( obj=folder['searchfor_proposed_to_service_chief']) # clean dms config for ptype in ('dmsincomingmail', 'dmsoutgoingmail', 'task'): # i_e ok config = get_dms_config(['review_levels', ptype]) if '_validateur' in config: del config['_validateur'] set_dms_config(keys=['review_levels', ptype], value=config) config = get_dms_config(['review_states', ptype]) if 'proposed_to_service_chief' in config: del config['proposed_to_service_chief'] set_dms_config(keys=['review_states', ptype], value=config) def remove_localrole_validateur(dic1): for state1 in dic1: if 'validateur' in dic1[state1]: del dic1[state1]['validateur'] # clean local roles for ptype in ('dmsincomingmail', 'dmsoutgoingmail'): # i_e ok fti = getUtility(IDexterityFTI, name=ptype) lr = getattr(fti, 'localroles') lrg = lr['static_config'] if 'proposed_to_service_chief' in lrg: del lrg['proposed_to_service_chief'] remove_localrole_validateur(lrg) lrg = lr['treating_groups'] if 'proposed_to_service_chief' in lrg: del lrg['proposed_to_service_chief'] remove_localrole_validateur(lrg) lrg = lr['recipient_groups'] if 'proposed_to_service_chief' in lrg: del lrg['proposed_to_service_chief'] remove_localrole_validateur(lrg) lr._p_changed = True # on task fti = getUtility(IDexterityFTI, name='task') lr = getattr(fti, 'localroles') lrg = lr['assigned_group'] if 'validateur' in lrg['to_do']: remove_localrole_validateur(lrg) lrg = lr['parents_assigned_groups'] if 'validateur' in lrg['to_do']: remove_localrole_validateur(lrg) lr._p_changed = True # update registry lst = api.portal.get_registry_record( 'imio.actionspanel.browser.registry.IImioActionsPanelConfig.transitions' ) for entry in ('dmsincomingmail.back_to_service_chief|', 'dmsoutgoingmail.back_to_service_chief|'): if entry not in lst: break lst.remove(entry) else: api.portal.set_registry_record( 'imio.actionspanel.browser.registry.IImioActionsPanelConfig.transitions', lst) # update remark states for attr in ('imail_remark_states', 'omail_remark_states'): lst = (api.portal.get_registry_record( 'imio.dms.mail.browser.settings.IImioDmsMailConfig.{}'.format( attr)) or []) if 'proposed_to_service_chief' in lst: lst.remove('proposed_to_service_chief') api.portal.set_registry_record( 'imio.dms.mail.browser.settings.IImioDmsMailConfig.{}'. format(attr), lst) # Manage workflows and wfadaptations functions = get_registry_functions() if 'validateur' not in [fct['fct_id'] for fct in functions]: return # apply the following only once def remove_adaptation_from_registry(name): record = api.portal.get_registry_record(RECORD_NAME) api.portal.set_registry_record( RECORD_NAME, [d for d in record if d['adaptation'] != name]) # reset workflows self.runProfileSteps('imio.dms.mail', steps=['workflow']) # self.portal.portal_workflow.updateRoleMappings() # done later # Apply workflow adaptations if necessary applied_wfa = [dic['adaptation'] for dic in get_applied_adaptations()] n_plus_1_params = { 'validation_level': 1, 'state_title': u'À valider par le chef de service', 'forward_transition_title': u'Proposer au chef de service', 'backward_transition_title': u'Renvoyer au chef de service', 'function_title': u'N+1' } task_adapt = True for wkf, acr in (('incomingmail_workflow', 'IM'), ('outgoingmail_workflow', 'OM')): if u'imio.dms.mail.wfadaptations.{}SkipProposeToServiceChief'.format( acr) in applied_wfa: remove_adaptation_from_registry( u'imio.dms.mail.wfadaptations.{}SkipProposeToServiceChief'. format(acr)) task_adapt = False if acr == 'OM': folder = self.omf['mail-searches'] if folder['to_validate'].enabled: folder['to_validate'].enabled = False folder['to_validate'].reindexObject() else: logger.info( 'Applying {}ServiceValidation wf adaptation'.format(acr)) sva = getattr(wfadaptations, '{}ServiceValidation'.format(acr))() sva.reapply = True adapt_is_applied = sva.patch_workflow(wkf, **n_plus_1_params) if adapt_is_applied: add_applied_adaptation( 'imio.dms.mail.wfadaptations.{}ServiceValidation'. format(acr), wkf, True, **n_plus_1_params) # update task_workflow update_task_workflow(self.portal) if task_adapt: tsva = TaskServiceValidation() adapt_is_applied = tsva.patch_workflow('task_workflow', **{}) if adapt_is_applied: add_applied_adaptation( 'imio.dms.mail.wfadaptations.TaskServiceValidation', 'task_workflow', False) else: # update collections folder = self.portal['tasks']['task-searches'] for cid in ('to_assign', 'to_close'): if folder[cid].enabled: folder[cid].enabled = False folder[cid].reindexObject() invalidate_cachekey_volatile_for( 'collective.eeafaceted.collectionwidget.cachedcollectionvocabulary' ) # replace EmergencyZoneAdaptation im_workflow = self.wtool['incomingmail_workflow'] if u'imio.dms.mail.wfadaptations.EmergencyZone' in applied_wfa: state = im_workflow.states['proposed_to_manager'] state.title = u'À valider par le CZ'.encode('utf8') for tr, tit in (('back_to_manager', u'Renvoyer au CZ'), ('propose_to_manager', u'Proposer au CZ')): transition = im_workflow.transitions[tr] transition.title = tit.encode('utf8') logger.info('Removing EmergencyZone wf adaptation') remove_adaptation_from_registry( u'imio.dms.mail.wfadaptations.EmergencyZone') # redo OMToPrintAdaptation if u'imio.dms.mail.wfadaptations.OMToPrint' in applied_wfa: logger.info('Applying OMToPrint wf adaptation') tpa = OMToPrintAdaptation() tpa.patch_workflow('outgoingmail_workflow') # redo IMPreManagerValidation if u'imio.dms.mail.wfadaptations.IMPreManagerValidation' in applied_wfa: logger.info('Applying IMPreManagerValidation wf adaptation') params = [ dic['parameters'] for dic in get_applied_adaptations() if dic['adaptation'] == u'imio.dms.mail.wfadaptations.IMPreManagerValidation' ][0] remove_adaptation_from_registry( u'imio.dms.mail.wfadaptations.IMPreManagerValidation') del params['collection_title'] pmva = IMPreManagerValidation() adapt_is_applied = pmva.patch_workflow('incomingmail_workflow', **params) if adapt_is_applied: add_applied_adaptation( 'imio.dms.mail.wfadaptations.IMPreManagerValidation', 'incoming_mail', False, **params) # update wf history to replace review_state and correct history config = { 'dmsincomingmail': { 'wf': 'incomingmail_workflow', # i_e ok 'st': { 'proposed_to_service_chief': 'proposed_to_n_plus_1' }, 'tr': { 'propose_to_service_chief': 'propose_to_n_plus_1', 'back_to_service_chief': 'back_to_n_plus_1' } }, 'dmsoutgoingmail': { 'wf': 'outgoingmail_workflow', 'st': { 'proposed_to_service_chief': 'proposed_to_n_plus_1' }, 'tr': { 'propose_to_service_chief': 'propose_to_n_plus_1', 'back_to_service_chief': 'back_to_n_plus_1' } } } for pt in config: logger.info('Updating history and indexes of {} type'.format(pt)) for i, brain in enumerate(self.catalog(portal_type=pt), 1): obj = brain.getObject() if i % 10000 == 0: logger.info('On brain {}'.format(i)) # update history wfh = [] wkf = self.wtool[config[pt]['wf']] for status in obj.workflow_history.get(config[pt]['wf']): # replace old state by new one if status['review_state'] in config[pt]['st']: status['review_state'] = config[pt]['st'][ status['review_state']] # replace old transition by new one if status['action'] in config[pt]['tr']: status['action'] = config[pt]['tr'][status['action']] wfh.append(status) obj.workflow_history[config[pt]['wf']] = tuple(wfh) # update permissions and roles wkf.updateRoleMappingsFor(obj) # update state_group (use dms_config), permissions, state obj.reindexObject(idxs=[ 'allowedRolesAndUsers', 'review_state', 'state_group' ]) for child in obj.objectValues(): child.reindexObject(idxs=['allowedRolesAndUsers']) # migrate plone groups # First unregister group deletion handlers globalSiteManager.unregisterHandler(pg_group_deleted, (IGroupDeletedEvent, )) globalSiteManager.unregisterHandler(group_deleted, (IGroupDeletedEvent, )) globalSiteManager.unregisterHandler(group_assignment, (IPrincipalAddedToGroupEvent, )) globalSiteManager.unregisterHandler( group_unassignment, (IPrincipalRemovedFromGroupEvent, )) # move users from _validateur to _n_plus_1 for group in api.group.get_groups(): if group.id.endswith('_validateur'): org = group.id.split('_')[0] np1group = api.group.get('{}_n_plus_1'.format(org)) if np1group: for user in api.user.get_users(group=group): api.group.add_user(group=np1group, user=user) api.group.remove_user(group=group, user=user) api.group.delete(group=group) # register again group deletion handlers globalSiteManager.registerHandler(pg_group_deleted, (IGroupDeletedEvent, )) globalSiteManager.registerHandler(group_deleted, (IGroupDeletedEvent, )) globalSiteManager.registerHandler(group_assignment, (IPrincipalAddedToGroupEvent, )) globalSiteManager.registerHandler(group_unassignment, (IPrincipalRemovedFromGroupEvent, )) # remove validateur function functions = get_registry_functions() if 'validateur' in [fct['fct_id'] for fct in functions]: set_registry_functions( [fct for fct in functions if fct['fct_id'] != 'validateur'])