Beispiel #1
0
 def setUp(self):
     self.portal = self.layer['portal']
     setRoles(self.portal, TEST_USER_ID, ['Manager'])
     self.pw = self.portal.portal_workflow
     self.imw = self.pw['incomingmail_workflow']
     self.imail = sub_create(self.portal['incoming-mail'],
                             'dmsincomingmail', datetime.now(), 'test',
                             **{'title': u'test'})
     api.group.create('abc_group_encoder', 'ABC group encoder')
     self.portal.portal_setup.runImportStepFromProfile(
         'profile-imio.dms.mail:singles',
         'imiodmsmail-im_n_plus_1_wfadaptation',
         run_dependencies=False)
     sva = IMServiceValidation()
     n_plus_2_params = {
         'validation_level': 2,
         'state_title': u'Valider par le chef de département',
         'forward_transition_title': u'Proposer au chef de département',
         'backward_transition_title': u'Renvoyer au chef de département',
         'function_title': u'chef de département'
     }
     adapt_is_applied = sva.patch_workflow('incomingmail_workflow',
                                           **n_plus_2_params)
     if adapt_is_applied:
         add_applied_adaptation(
             'imio.dms.mail.wfadaptations.IMServiceValidation',
             'incomingmail_workflow', True, **n_plus_2_params)
     for uid in get_registry_organizations():
         self.portal.acl_users.source_groups.addPrincipalToGroup(
             'chef', "%s_n_plus_2" % uid)
Beispiel #2
0
 def test_task_transition(self):
     # task = createContentInContainer(self.imail, 'task', id='t1')
     task = get_object(oid='courrier1', ptype='dmsincomingmail')['tache1']
     # no assigned_user and no TaskServiceValidation
     self.assertIsNone(task.assigned_user)
     api.content.transition(task, transition='do_to_assign')
     self.assertEqual(api.content.get_state(task), 'to_do')
     # assigned_user and no TaskServiceValidation
     api.content.transition(task, transition='back_in_created2')
     task.assigned_user = '******'
     api.content.transition(task, transition='do_to_assign')
     self.assertEqual(api.content.get_state(task), 'to_do')
     # no assigned_user but TaskServiceValidation but no user in groups
     api.content.transition(task, transition='back_in_created2')
     task.assigned_user = None
     add_applied_adaptation(
         'imio.dms.mail.wfadaptations.TaskServiceValidation',
         'task_workflow', False)
     api.content.transition(task, transition='do_to_assign')
     self.assertEqual(api.content.get_state(task), 'to_do')
     # no assigned_user but TaskServiceValidation and user in groups
     api.content.transition(task, transition='back_in_created2')
     api.group.create(groupname='{}_n_plus_1'.format(task.assigned_group),
                      groups=['chef'])
     api.content.transition(task, transition='do_to_assign')
     self.assertEqual(api.content.get_state(task), 'to_assign')
Beispiel #3
0
    def test_state_group_index(self):
        dguid = self.pgof['direction-generale'].UID()
        imail = sub_create(
            self.portal['incoming-mail'], 'dmsincomingmail', datetime.now(),
            'id1', **{
                'title': u'test',
                'treating_groups': dguid,
                'assigned_user': u'chef'
            })
        indexer = state_group_index(imail)
        self.assertEqual(indexer(), 'created')
        api.content.transition(obj=imail, to_state='proposed_to_manager')
        self.assertEqual(indexer(), 'proposed_to_manager')
        api.content.transition(obj=imail, to_state='proposed_to_agent')
        self.assertEqual(indexer(), 'proposed_to_agent')

        task = createContentInContainer(imail, 'task', assigned_group=dguid)
        indexer = state_group_index(task)
        self.assertEqual(indexer(), 'created')
        # simulate adaptation
        add_applied_adaptation(
            'imio.dms.mail.wfadaptations.TaskServiceValidation',
            'task_workflow', False)
        api.group.create(groupname='{}_n_plus_1'.format(dguid),
                         groups=['chef'])
        api.content.transition(obj=task, transition='do_to_assign')
        self.assertEqual(indexer(), 'to_assign')
        set_dms_config(['review_states', 'task'],
                       OrderedDict([('to_assign', {
                           'group': '_n_plus_1',
                           'org': 'assigned_group'
                       })]))
        self.assertEqual(indexer(), 'to_assign,%s' % dguid)
Beispiel #4
0
def om_n_plus_1_wfadaptation(context):
    """
        Add n_plus_1 level in outgoingmail_workflow
    """
    if not context.readDataFile("imiodmsmail_singles_marker.txt"):
        return
    logger.info('Apply n_plus_1 level on outgoingmail_workflow')
    site = context.getSite()
    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',
        'validated_from_created': False
    }
    sva = OMServiceValidation()
    adapt_is_applied = sva.patch_workflow('outgoingmail_workflow',
                                          **n_plus_1_params)
    if adapt_is_applied:
        add_applied_adaptation(
            'imio.dms.mail.wfadaptations.OMServiceValidation',
            'outgoingmail_workflow', True, **n_plus_1_params)
    # Add users to activated groups
    if 'chef' in [u.id for u in api.user.get_users()]:
        for uid in get_registry_organizations():
            site.acl_users.source_groups.addPrincipalToGroup(
                'chef', "%s_n_plus_1" % uid)
 def test_add_applied_adaptation(self):
     params = {'param1': 'foo', 'param2': 'bar'}
     add_applied_adaptation(u'adaptation1', u'workflow2', **params)
     self.assertIn(
         {u'workflow': u'workflow2',
          u'adaptation': u'adaptation1',
          u'parameters': u'{"param1": "foo", "param2": "bar"}'
         },
         api.portal.get_registry_record(RECORD_NAME),
         )
     with self.assertRaises(AdaptationAlreadyAppliedException):
         add_applied_adaptation(u'adaptation1', u'workflow1', **params)
Beispiel #6
0
def task_n_plus_1_wfadaptation(context):
    """
        Add n_plus_1 level in task_workflow
    """
    if not context.readDataFile("imiodmsmail_singles_marker.txt"):
        return
    logger.info('Apply n_plus_1 level on task_workflow')
    site = context.getSite()
    sva = TaskServiceValidation()
    adapt_is_applied = sva.patch_workflow('task_workflow', **{})
    if adapt_is_applied:
        add_applied_adaptation(
            'imio.dms.mail.wfadaptations.TaskServiceValidation',
            'task_workflow', True, **{})
    # Add users to activated groups
    if 'chef' in [u.id for u in api.user.get_users()]:
        for uid in get_registry_organizations():
            site.acl_users.source_groups.addPrincipalToGroup(
                'chef', "%s_n_plus_1" % uid)
Beispiel #7
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'])