Пример #1
0
 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)
Пример #2
0
 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)
Пример #3
0
 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')
Пример #4
0
 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'
                    })]))
Пример #5
0
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
Пример #6
0
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
Пример #7
0
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 !')
Пример #8
0
 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')})
Пример #9
0
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']))
Пример #10
0
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
Пример #11
0
    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'))
Пример #12
0
 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])
Пример #13
0
 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)
Пример #14
0
 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)
Пример #15
0
    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()
Пример #16
0
    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'])