示例#1
0
 def synchToggle(self, itemUid, discussAction):
     """
       This is a synchronous way of toggling toDiscuss.
       The asynchronous asynchToggle here above will only reload the clicked icon.
       If for some reason it is necessary that the page is fully reloaded,
       like for example to display a portal_message or because something else
       has changed on the page, this is the method to use.
       Here, it manages for example the fact that a reviewer can ask
       an item to be discussed and that will display a portal_message to this user.
     """
     item = uuidToObject(itemUid, unrestricted=True)
     if discussAction == 'ask':
         # I must send a mail to MeetingManagers for notifying them that a reviewer
         # wants to discuss this item.
         sendMailEnabled = sendMailIfRelevant(item,
                                              'askDiscussItem',
                                              'meetingmanagers',
                                              isSuffix=True)
         if sendMailEnabled:
             msgId = 'to_discuss_ask_mail_sent'
         else:
             msgId = 'to_discuss_ask_mail_not_sent'
         self.context.plone_utils.addPortalMessage(
             item.translate(msgId, domain='PloneMeeting'))
     elif discussAction == 'toggle':
         # I must toggle the "toDiscuss" switch on the item
         toDiscuss = not item.getToDiscuss()
         item.setToDiscuss(toDiscuss)
         item.adapted().onDiscussChanged(toDiscuss)
     self.context._update_after_edit(idxs=['to_discuss'])
     return self.request.RESPONSE.redirect(self.request['HTTP_REFERER'])
示例#2
0
 def createItemFromTemplate(self, templateUID):
     '''The user wants to create an item from a item template that lies in
        this meeting configuration. Item id is in the request.'''
     templateItem = uuidToObject(templateUID, unrestricted=True)
     # Create the new item by duplicating the template item
     member_id = get_current_user_id()
     template_path_and_title = safe_unicode(
         self._template_path_and_title(templateItem))
     cloneEventActionLabel = translate(
         'create_meeting_item_from_template_label_comments',
         domain='imio.history',
         mapping={
             'template_path_and_title': template_path_and_title,
         },
         context=self.request)
     # if a proposingGroup is defined on itemTemplate and current user is creator
     # for this proposingGroup, we keep it
     keepProposingGroup = False
     proposingGroup = templateItem.getProposingGroup()
     if get_plone_group_id(
             proposingGroup,
             'creators') in self.tool.get_plone_groups_for_user():
         keepProposingGroup = True
     newItem = templateItem.clone(
         newOwnerId=member_id,
         cloneEventAction='create_meeting_item_from_template',
         cloneEventActionLabel=cloneEventActionLabel,
         destFolder=self.context,
         newPortalType=self.cfg.getItemTypeName(),
         keepProposingGroup=keepProposingGroup,
         keep_ftw_labels=True)
     # set _at_creation_flag to True so if user cancel first edit, it will be removed
     newItem._at_creation_flag = True
     return newItem
示例#3
0
 def pl_items(self):
     """Inspired from z3c.form.widget displayValue method"""
     items = []
     for token in self.value:
         # Ignore no value entries. They are in the request only.
         if token == self.noValueToken:
             continue
         folder = uuidToObject(token, unrestricted=True)
         if not folder:
             items.append(token)
             continue
         adapted = PrettyLinkAdapter(folder,
                                     showLockedIcon=False,
                                     target='_blank',
                                     showIcons=True,
                                     showContentIcon=True)
         if folder.portal_type == 'ClassificationSubfolder':
             cf_adapted = PrettyLinkAdapter(folder.cf_parent(),
                                            showLockedIcon=False,
                                            target='_blank',
                                            showIcons=True,
                                            showContentIcon=True)
             items.append(cf_adapted.getLink() + adapted.getLink())
         else:
             items.append(adapted.getLink())
     return items
示例#4
0
 def AsyncRenderSearchTerm__call__(self):
     """ """
     self.collection_uid = self.request.get('collection_uid')
     self.tool = api.portal.get_tool('portal_plonemeeting')
     self.cfg = self.tool.getMeetingConfig(self.context)
     self.collection = uuidToObject(self.collection_uid, unrestricted=True)
     self.brains = self.collection.results(batch=False, brains=True)
     rendered_term = ViewPageTemplateFile(
         "templates/term_searchmeetings.pt")(self)
     return rendered_term
示例#5
0
 def get_classification_folders(self, sep=u', '):
     om = self.real_context
     if not om.classification_folders:
         return []
     ret = []
     for fld in om.classification_folders:
         obj = uuidToObject(fld, unrestricted=True)
         ret.append(obj.internal_reference_no)
     ret = sep.join(ret)
     return ret
示例#6
0
 def _migrateDeliberationToSignAnnexType(self):
     """Make the annex_type confidential by default."""
     logger.info('Migrating deliberation-to-sign annex_type...')
     for cfg in self.tool.objectValues('MeetingConfig'):
         pod_template_path = cfg.getMeetingItemTemplatesToStoreAsAnnex()
         if pod_template_path:
             pod_template = cfg.podtemplates.get(
                 pod_template_path[0].split('__')[0])
             annex_type_uid = pod_template.store_as_annex
             annex_type = uuidToObject(annex_type_uid, unrestricted=True)
             annex_type.confidential = True
     logger.info('Done.')
示例#7
0
 def validate_position_types(data):
     """Can not remove a position_type used by a held_position."""
     directory = data.__context__
     stored_position_types_token = [
         stored['token'] for stored in directory.position_types
     ]
     position_types = [value['token'] for value in data.position_types]
     removed_position_types = set(stored_position_types_token).difference(
         position_types)
     if removed_position_types:
         catalog = api.portal.get_tool('portal_catalog')
         # check if used by a held_position
         hp_brains = catalog.unrestrictedSearchResults(
             portal_type='held_position')
         for hp_brain in hp_brains:
             hp = hp_brain.getObject()
             if hp.position_type in removed_position_types:
                 msg = translate('removed_position_type_in_use_error',
                                 mapping={
                                     'removed_position_type':
                                     hp.position_type,
                                     'hp_url': hp.absolute_url()
                                 },
                                 domain='PloneMeeting',
                                 context=directory.REQUEST)
                 raise WidgetActionExecutionError('position_types',
                                                  Invalid(msg))
         # check if used as a redefined position_type
         # for an attendee on an item, this information is stored on the meeting
         meeting_brains = catalog.unrestrictedSearchResults(
             object_provides=IMeeting.__identifier__)
         for meeting_brain in meeting_brains:
             meeting = meeting_brain.getObject()
             redefined_positions = meeting._get_item_redefined_positions()
             for item_uid, infos in redefined_positions.items():
                 for hp_uid, pos_infos in infos.items():
                     if pos_infos[
                             'position_type'] in removed_position_types:
                         item = uuidToObject(item_uid, unrestricted=True)
                         msg = translate(
                             'removed_redefined_position_type_in_use_error',
                             mapping={
                                 'removed_position_type':
                                 pos_infos['position_type'],
                                 'item_url':
                                 item.absolute_url()
                             },
                             domain='PloneMeeting',
                             context=directory.REQUEST)
                         raise WidgetActionExecutionError(
                             'position_types', Invalid(msg))
示例#8
0
def sender_index(obj):
    """Indexer of 'sender_index' for IImioDmsOutgoingMail.

    Stores:
        * the sender UID
        * the organizations chain UIDs if the sender is held position, prefixed by 'l:'
    """
    if not obj.sender:
        return common_marker
    index = [obj.sender]
    sender = uuidToObject(obj.sender, unrestricted=True)
    # during a clear and rebuild, the sender is maybe not yet indexed...
    if sender:
        add_parent_organizations(sender.get_organization(), index)
    return index
示例#9
0
 def findIncomingMails(self, mail_type='', start_date=''):
     """
         Request the catalog
         mail_type :
         start_date : string date at format YYYYMMDD
     """
     kw = {}
     kw['portal_type'] = ('dmsincomingmail', 'dmsincoming_email')
     #kw['review_state'] = ('published',)
     kw['created'] = {
         "query": [
             DateTime() - 5,
         ],
         "range": "min"
     }
     #        kw['modified'] = {"query": [DateTime()-5, ], "range": "min"}
     #        kw['sort_on'] = 'created'
     results = {'1_no_group': {'mails': [], 'title': 'listing_no_group'}}
     if not start_date:
         start_date = DateTime().strftime('%Y%m%d')
     for brain in self.pc(kw):
         obj = brain.getObject()
         if mail_type and obj.mail_type.encode('utf8') != mail_type:
             continue
         if obj.reception_date.strftime('%Y%m%d') < start_date:
             continue
         if obj.treating_groups:
             tg = obj.treating_groups
             if not tg in results:
                 results[tg] = {'mails': []}
                 title = tg
                 tgroup = uuidToObject(tg, unrestricted=True)
                 if tgroup is not None:
                     title = tgroup.get_full_title(separator=' - ',
                                                   first_index=1)
                 results[tg]['title'] = title
             results[tg]['mails'].append(obj)
         else:
             results['1_no_group']['mails'].append(obj)
     if not results['1_no_group']['mails']:
         del results['1_no_group']
     for service in results.keys():
         results[service]['mails'].sort(lambda x, y: cmp(
             x.internal_reference_no, y.internal_reference_no))
     return results
示例#10
0
    def get_sender_info(self):
        """Returns related sender information:

        * the held_position, in 'hp' key
        * the related person, in 'person' key
        * the related organization, in 'org' key

        :return: dict containing 3 keys
        """
        if not self.sender:
            return {}
        sender = uuidToObject(self.sender, unrestricted=True)
        if not sender:
            return {}
        return {
            'hp': sender,
            'person': sender.get_person(),
            'org': sender.get_organization()
        }
示例#11
0
 def group_by_tg(self, brains):
     results = {'1_no_group': {'mails': [], 'title': translate('listing_no_group', domain="imio.dms.mail",
                                                               context=self.request)}}
     for brain in brains:
         obj = brain.getObject()
         tg = brain.treating_groups
         if tg:
             if tg not in results:
                 results[tg] = {'mails': []}
                 title = tg
                 tgroup = uuidToObject(tg, unrestricted=True)
                 if tgroup is not None:
                     title = tgroup.get_full_title(separator=' - ', first_index=1)
                 results[tg]['title'] = title
             results[tg]['mails'].append(obj)
         else:
             results['1_no_group']['mails'].append(obj)
     if not results['1_no_group']['mails']:
         del results['1_no_group']
     return results
示例#12
0
 def _update_description(self):
     """Display concerned person as description."""
     person_uid = person_uid_default()
     if person_uid:
         hp = uuidToObject(person_uid, unrestricted=True)
         self.description = self.context.get_attendee_short_title(hp)
示例#13
0
 def get_treating_groups(self):
     om = self.real_context
     if not om.treating_groups:
         return None
     return uuidToObject(om.treating_groups, unrestricted=True)
示例#14
0
def contact_plonegroup_change(event):
    """Event handler when contact.plonegroup records are modified.

    * update workflow dms config (new groups).
    * invalidate vocabulary caches.
    * set localroles on contacts for _encodeur groups.
    * add a directory by organization in templates/om, templates/oem and contacts/contact-lists-folder.
    * set local roles on contacts, incoming-mail for group_encoder.
    """
    if (IRecordModifiedEvent.providedBy(event) and event.record.interfaceName and
            event.record.interface == IContactPlonegroupConfig):
        registry = getUtility(IRegistry)
        s_orgs = get_registry_organizations()
        s_fcts = get_registry_functions()
        if not s_fcts or not s_orgs:
            return
        # we update dms config
        update_transitions_auc_config('dmsincomingmail')  # i_e ok
        update_transitions_levels_config(['dmsincomingmail', 'dmsoutgoingmail', 'task'])  # i_e ok
        # invalidate vocabularies caches
        invalidate_cachekey_volatile_for('imio.dms.mail.vocabularies.CreatingGroupVocabulary')
        invalidate_cachekey_volatile_for('imio.dms.mail.vocabularies.ActiveCreatingGroupVocabulary')
        invalidate_cachekey_volatile_for('imio.dms.mail.vocabularies.TreatingGroupsWithDeactivatedVocabulary')
        invalidate_cachekey_volatile_for('imio.dms.mail.vocabularies.TreatingGroupsForFacetedFilterVocabulary')

        portal = api.portal.get()
        # contributor on a contact can edit too
        for folder in (portal['outgoing-mail'], portal['contacts'],
                       portal['contacts']['contact-lists-folder']['common']):
            dic = folder.__ac_local_roles__
            for principal in dic.keys():
                if principal.endswith('_encodeur'):
                    del dic[principal]
            for uid in s_orgs:
                dic["%s_encodeur" % uid] = ['Contributor']
            folder._p_changed = True
        # we add a directory by organization in templates/om
        om_folder = portal.templates.om
        oem_folder = portal.templates.oem
        base_model = om_folder.get('main', None)
        cl_folder = portal.contacts['contact-lists-folder']
        for uid in s_orgs:
            obj = uuidToObject(uid, unrestricted=True)
            full_title = obj.get_full_title(separator=' - ', first_index=1)
            if uid not in om_folder:
                folder = api.content.create(container=om_folder, type='Folder', id=uid, title=full_title)
                # alsoProvides(folder, IActionsPanelFolderOnlyAdd)  # made now in subscriber
                # alsoProvides(folder, INextPrevNotNavigable)
                roles = ['Reader']
                if registry['imio.dms.mail.browser.settings.IImioDmsMailConfig.org_templates_encoder_can_edit']:
                    roles += ['Contributor', 'Editor']
                api.group.grant_roles(groupname='%s_encodeur' % uid, roles=roles, obj=folder)
                folder.reindexObjectSecurity()
                if base_model and base_model.has_been_modified():
                    logger.info("Copying %s in %s" % (base_model, '/'.join(folder.getPhysicalPath())))
                    api.content.copy(source=base_model, target=folder)
            if uid not in oem_folder:
                folder = api.content.create(container=oem_folder, type='Folder', id=uid, title=full_title)
                roles = ['Reader']
                if registry['imio.dms.mail.browser.settings.IImioDmsMailConfig.org_email_templates_encoder_can_edit']:
                    roles += ['Contributor', 'Editor']
                api.group.grant_roles(groupname='%s_encodeur' % uid, roles=roles, obj=folder)
                folder.reindexObjectSecurity()
                # if base_model and base_model.has_been_modified():
                #    logger.info("Copying %s in %s" % (base_model, '/'.join(folder.getPhysicalPath())))
                #    api.content.copy(source=base_model, target=folder)
            if uid not in cl_folder:
                folder = api.content.create(container=cl_folder, type='Folder', id=uid, title=full_title)
                folder.setLayout('folder_tabular_view')
                roles = ['Reader', 'Contributor', 'Editor']
                api.group.grant_roles(groupname='%s_encodeur' % uid, roles=roles, obj=folder)
                folder.reindexObjectSecurity()
        # we manage local roles to give needed permissions related to group_encoder
        options_config = {portal['incoming-mail']: ['imail_group_encoder'],
                          portal['outgoing-mail']: ['omail_group_encoder'],
                          portal['contacts']: ['imail_group_encoder', 'omail_group_encoder', 'contact_group_encoder'],
                          portal['contacts']['contact-lists-folder']['common']: ['imail_group_encoder',
                                                                                 'omail_group_encoder',
                                                                                 'contact_group_encoder']}
        ge_config = {opt: api.portal.get_registry_record('imio.dms.mail.browser.settings.IImioDmsMailConfig.{}'.format(
            opt), default=False) for opt in ('imail_group_encoder', 'omail_group_encoder', 'contact_group_encoder')}

        group_encoder_config = [dic for dic in s_fcts if dic['fct_id'] == CREATING_GROUP_SUFFIX]  # noqa F812
        if group_encoder_config:
            orgs = group_encoder_config[0]['fct_orgs']
            for folder in options_config:
                if any([ge_config[opt] for opt in options_config[folder]]):
                    dic = folder.__ac_local_roles__
                    for principal in dic.keys():
                        if principal.endswith(CREATING_GROUP_SUFFIX):
                            del dic[principal]
                    for uid in orgs:
                        dic["{}_{}".format(uid, CREATING_GROUP_SUFFIX)] = ['Contributor']
                    folder._p_changed = True
示例#15
0
def create_persons_from_users(portal,
                              start='firstname',
                              functions=['encodeur'],
                              userid=''):
    """
        create own personnel from plone users
    """
    pf = portal['contacts']['personnel-folder']
    users = {}
    groups = api.group.get_groups()
    for group in groups:
        if '_' not in group.id or group.id in [
                'createurs_dossier', 'dir_general', 'lecteurs_globaux_ce',
                'lecteurs_globaux_cs'
        ]:
            continue
        parts = group.id.split('_')
        org_uid = function = None
        if len(parts) > 1:
            org_uid = parts[0]
            function = '_'.join(parts[1:])
        if function and function not in functions:
            continue
        for user in api.user.get_users(group=group):
            if userid and user.id != userid:
                continue
            if user.id not in users and user.id not in ['scanner']:
                users[user.id] = {'pers': {}, 'orgs': []}
                firstname, lastname = separate_fullname(user, start=start)
                users[user.id]['pers'] = {
                    'lastname': lastname,
                    'firstname': firstname,
                    'email': safe_unicode(user.getProperty('email')),
                    'use_parent_address': False
                }
            if org_uid and org_uid not in users[user.id]['orgs']:
                users[user.id]['orgs'].append(org_uid)

    intids = getUtility(IIntIds)
    out = []
    # logger.info(users)
    for userid in users:
        email = users[userid]['pers'].pop('email')
        exist = portal.portal_catalog.unrestrictedSearchResults(
            mail_type=userid, portal_type='person')
        if userid in pf:
            pers = pf[userid]
        elif exist:
            pers = exist[0]._unrestrictedGetObject()
        else:
            out.append(u"person created for user %s, fn:'%s', ln:'%s'" %
                       (userid, users[userid]['pers']['firstname'],
                        users[userid]['pers']['lastname']))
            logger.info(out[-1])
            pers = api.content.create(container=pf,
                                      type='person',
                                      id=userid,
                                      userid=userid,
                                      **users[userid]['pers'])
        if api.content.get_state(pers) == 'deactivated':
            api.content.transition(pers, 'activate')
        hps = [
            b._unrestrictedGetObject()
            for b in portal.portal_catalog.unrestrictedSearchResults(
                path='/'.join(pers.getPhysicalPath()),
                portal_type='held_position')
        ]
        orgs = dict([(hp.get_organization(), hp) for hp in hps])
        for uid in users[userid]['orgs']:
            org = uuidToObject(uid, unrestricted=True)
            if not org:
                continue
            if uid in pers:
                hp = pers[uid]
            elif org in orgs:
                hp = orgs[org]
            else:
                out.append(u" -> hp created with org '%s'" %
                           org.get_full_title())
                logger.info(out[-1])
                hp = api.content.create(container=pers,
                                        id=uid,
                                        type='held_position',
                                        **{
                                            'email':
                                            email,
                                            'position':
                                            RelationValue(intids.getId(org)),
                                            'use_parent_address':
                                            True
                                        })
            if api.content.get_state(hp) == 'deactivated':
                api.content.transition(hp, 'activate')
    return out
示例#16
0
    def run(self):
        self.data = self.profileData
        if not self.data:
            return self.noDataMessage
        # Register classes again, after model adaptations have been performed
        # (see comment in __init__.py)
        registerClasses()
        # if we already have existing organizations, we do not add additional ones
        own_org = get_own_organization()
        alreadyHaveGroups = bool(own_org.objectValues())
        savedMeetingConfigsToCloneTo = {}
        savedOrgsData = {}
        if not alreadyHaveGroups or self.data.forceAddUsersAndGroups:
            # 1) create organizations so we have org UIDS to initialize 'fct_orgs'
            orgs, active_orgs, savedOrgsData = self.addOrgs(self.data.orgs)
            # 2) create plonegroup functions (suffixes) to create Plone groups
            functions = get_registry_functions()
            function_ids = [function['fct_id'] for function in functions]
            # append new functions
            suffixes = MEETING_GROUP_SUFFIXES + EXTRA_GROUP_SUFFIXES
            for suffix in suffixes:
                if suffix['fct_id'] not in function_ids:
                    copied_suffix = suffix.copy()
                    copied_suffix['fct_title'] = translate(
                        suffix['fct_title'],
                        domain='PloneMeeting',
                        context=self.request)
                    # if org_path not found, do not fail but log, it is often the case in tests
                    # in which we do not add additional organizations because it breaks some tests
                    copied_suffix['fct_orgs'] = []
                    for org_path in suffix['fct_orgs']:
                        try:
                            fct_org = own_org.restrictedTraverse(org_path)
                        except KeyError:
                            logger.warning(
                                "Could not find an organization with path {0} "
                                "while setting 'fct_orgs' for {1}".format(
                                    org_path, suffix['fct_id']))
                            continue
                        copied_suffix['fct_orgs'].append(fct_org.UID())
                    functions.append(copied_suffix)
            # 3) manage organizations, set every organizations so every Plone groups are created
            # then disable orgs that are not active
            invalidate_soev_cache()
            invalidate_ssoev_cache()
            already_active_orgs = get_registry_organizations()
            org_uids = [
                org_uid for org_uid in get_organizations(only_selected=False,
                                                         the_objects=False)
                if org_uid not in already_active_orgs
            ]
            set_registry_organizations(org_uids)
            set_registry_functions(functions)
            active_org_uids = [org.UID() for org in active_orgs]
            set_registry_organizations(already_active_orgs + active_org_uids)
            # 4) add users to Plone groups
            self.addUsers(self.data.orgs)
            # 5) now that organizations are created, we add persons and held_positions
            self.addPersonsAndHeldPositions(self.data.persons,
                                            source=self.profilePath)

        created_cfgs = []
        for mConfig in self.data.meetingConfigs:
            # XXX we need to defer the management of the 'meetingConfigsToCloneTo'
            # defined on the mConfig after the creation of every mConfigs because
            # if we defined in mConfig1.meetingConfigsToCloneTo the mConfig2 id,
            # it will try to getattr this meetingConfig2 id that does not exist yet...
            # so save defined values, removed them from mConfig and manage that after
            savedMeetingConfigsToCloneTo[
                mConfig.id] = mConfig.meetingConfigsToCloneTo
            mConfig.meetingConfigsToCloneTo = []
            cfg = self.createMeetingConfig(mConfig, source=self.profilePath)
            if cfg:
                created_cfgs.append(cfg)
                self._finishConfigFor(cfg, data=mConfig)

        # manage other_mc_correspondences
        for created_cfg in created_cfgs:
            self._manageOtherMCCorrespondences(created_cfg)

        # now that every meetingConfigs have been created, we can manage the meetingConfigsToCloneTo
        # and orgs advice states related fields
        for mConfigId in savedMeetingConfigsToCloneTo:
            if not savedMeetingConfigsToCloneTo[mConfigId]:
                continue
            # initialize the attribute on the meetingConfig and call _updateCloneToOtherMCActions
            cfg = getattr(self.tool, mConfigId)
            # validate the MeetingConfig.meetingConfigsToCloneTo data that we are about to set
            # first replace cfg1 and cfg2 by corresponding cfg id
            adapted_cfgsToCloneTo = deepcopy(
                savedMeetingConfigsToCloneTo[mConfigId])
            for cfgToCloneTo in adapted_cfgsToCloneTo:
                cfgToCloneTo['meeting_config'] = self.cfg_num_to_id(
                    cfgToCloneTo['meeting_config'])
            error = cfg.validate_meetingConfigsToCloneTo(adapted_cfgsToCloneTo)
            if error:
                raise PloneMeetingError(MEETING_CONFIG_ERROR %
                                        (cfg.Title(), cfg.getId(), error))
            cfg.setMeetingConfigsToCloneTo(adapted_cfgsToCloneTo)
            cfg._updateCloneToOtherMCActions()
        for org_uid, values in savedOrgsData.items():
            org = uuidToObject(org_uid, unrestricted=True)
            # turn cfg1__state__itemcreated into meeting-config-id__state__itemcreated
            org.item_advice_states = self._correct_advice_states(
                values['item_advice_states'])
            org.item_advice_edit_states = self._correct_advice_states(
                values['item_advice_edit_states'])
            org.item_advice_view_states = self._correct_advice_states(
                values['item_advice_view_states'])
            org.groups_in_charge = [
                org_id_to_uid(group_id)
                for group_id in values['groups_in_charge']
            ]

        # finally, create the current user (admin) member area
        self.portal.portal_membership.createMemberArea()
        # at the end, add users outside PloneMeeting groups because
        # they could have to be added in groups created by the MeetingConfig
        if not alreadyHaveGroups:
            # adapt userDescr.ploneGroups to turn cfg_num into cfg_id
            self.addUsersOutsideGroups(self.data.usersOutsideGroups)

        # commit before continuing so elements like scales on annex types are correctly saved
        transaction.commit()
        return self.successMessage
示例#17
0
def position_type_default():
    """ """
    person_uid = person_uid_default()
    hp = uuidToObject(person_uid, unrestricted=True)
    position_type = hp.secondary_position_type or hp.position_type
    return position_type
示例#18
0
def group_assignment(event):
    """
        manage the add of a user in a plone group
    """
    invalidate_cachekey_volatile_for('imio.dms.mail.vocabularies.AssignedUsersWithDeactivatedVocabulary')
    invalidate_cachekey_volatile_for('imio.dms.mail.vocabularies.AssignedUsersForFacetedFilterVocabulary')
    if event.group_id.endswith(CREATING_GROUP_SUFFIX):
        invalidate_cachekey_volatile_for('imio.dms.mail.vocabularies.ActiveCreatingGroupVocabulary')
    # we update dms config
    if 'n_plus_' in event.group_id:
        update_transitions_auc_config('dmsincomingmail', action='add', group_id=event.group_id)  # i_e ok
        update_transitions_levels_config(['dmsincomingmail', 'dmsoutgoingmail', 'task'], action='add',  # i_e ok
                                         group_id=event.group_id)
    # we manage the 'lu' label for a new assignment
    # same functions as IncomingMailInCopyGroupUnreadCriterion
    userid = event.principal
    orgs = organizations_with_suffixes([event.group_id], IM_READER_SERVICE_FUNCTIONS, group_as_str=True)
    if orgs:
        days_back = 5
        start = datetime.datetime(1973, 2, 12)
        end = datetime.datetime.now() - datetime.timedelta(days=days_back)
        catalog = api.portal.get_tool('portal_catalog')
        for brain in catalog(portal_type=['dmsincomingmail', 'dmsincoming_email'], recipient_groups=orgs,
                             labels={'not': ['%s:lu' % userid]},
                             created={'query': (start, end), 'range': 'min:max'}):
            # if not brain.recipient_groups:
            #    continue
            obj = brain.getObject()
            labeling = ILabeling(obj)
            user_ids = labeling.storage.setdefault('lu', PersistentList())  # _p_changed is managed
            user_ids.append(userid)  # _p_changed is managed
            obj.reindexObject(idxs=['labels'])
    # we manage the personnel-folder person and held position
    orgs = organizations_with_suffixes([event.group_id], ['encodeur'], group_as_str=True)
    if orgs:
        user = api.user.get(userid)
        start = api.portal.get_registry_record('omail_fullname_used_form', IImioDmsMailConfig, default='firstname')
        firstname, lastname = separate_fullname(user, start=start)
        portal = api.portal.get()
        intids = getUtility(IIntIds)
        pf = portal['contacts']['personnel-folder']
        # exists already
        exist = portal.portal_catalog.unrestrictedSearchResults(mail_type=userid, portal_type='person')
        if userid in pf:
            pers = pf[userid]
        elif exist:
            pers = exist[0]._unrestrictedGetObject()
        else:
            pers = api.content.create(container=pf, type='person', id=userid, userid=userid, lastname=lastname,
                                      firstname=firstname, use_parent_address=False)
        if api.content.get_state(pers) == 'deactivated':
            api.content.transition(pers, 'activate')
        hps = [b._unrestrictedGetObject() for b in
               portal.portal_catalog.unrestrictedSearchResults(path='/'.join(pers.getPhysicalPath()),
                                                               portal_type='held_position')]
        hps_orgs = dict([(hp.get_organization(), hp) for hp in hps])
        uid = orgs[0]
        org = uuidToObject(uid, unrestricted=True)
        if not org:
            return
        if uid in pers:
            hp = pers[uid]
        elif org in hps_orgs:
            hp = hps_orgs[org]
        else:
            hp = api.content.create(container=pers, id=uid, type='held_position',
                                    email=safe_unicode(user.getProperty('email').lower()),
                                    position=RelationValue(intids.getId(org)), use_parent_address=True)
        if api.content.get_state(hp) == 'deactivated':
            api.content.transition(hp, 'activate')
示例#19
0
    def __call__(self):
        # 1 send email
        body = self.context.email_body
        msg = create_html_email(body.raw)
        for a_uid in self.context.email_attachments or []:
            a_obj = uuidToObject(a_uid, unrestricted=True)
            if a_obj:
                title = a_obj.title
                if a_obj.file.filename:
                    title = a_obj.file.filename
                if PMH_ENABLED:
                    title = unidecode(title)
                add_attachment(msg, title, content=a_obj.file.data)
        mailhost = get_mail_host(check=False)
        replyto_key = 'imio.dms.mail.browser.settings.IImioDmsMailConfig.omail_replyto_email_send'
        if mailhost.smtp_host == u'localhost' and not PMH_ENABLED:
            api.portal.show_message(_(
                'Your email has not been sent: ${error}.',
                mapping={'error': _(u'Cannot use localhost as smtp')}),
                                    self.request,
                                    type='error')
            return
        elif api.portal.get_registry_record(replyto_key, default=False):
            ret, error = send_email(msg,
                                    self.context.email_subject,
                                    mailhost.smtp_uid,
                                    self.context.email_recipient,
                                    self.context.email_cc,
                                    replyto=self.context.email_sender)
        else:
            ret, error = send_email(msg, self.context.email_subject,
                                    self.context.email_sender,
                                    self.context.email_recipient,
                                    self.context.email_cc)
        if ret:
            api.portal.show_message(_('Your email has been sent.'),
                                    self.request)
        else:
            api.portal.show_message(_(
                'Your email has not been sent: ${error}.',
                mapping={'error': error}),
                                    self.request,
                                    type='error')
            return

        # 2 Update status on omail
        now = datetime.strftime(datetime.now(), '%Y-%m-%d %H:%M')
        status = _tr(u'Email sent at ${date_hour}.',
                     mapping={'date_hour': now})
        if not self.context.email_status:
            self.context.email_status = status
        else:
            self.context.email_status += u' {}'.format(status)
        modified(self.context)

        # 3 Close if necessary
        close = api.portal.get_registry_record(
            'imio.dms.mail.browser.settings.IImioDmsMailConfig.'
            'omail_close_on_email_send')
        if close:
            trans = {
                'created': [
                    'mark_as_sent', 'propose_to_be_signed', 'set_validated',
                    'propose_to_n_plus_1'
                ],
                'scanned': ['mark_as_sent'],
                'proposed_to_n_plus_1':
                ['mark_as_sent', 'propose_to_be_signed', 'set_validated'],
                'to_be_signed': ['mark_as_sent'],
                'validated': ['propose_to_be_signed', 'mark_as_sent']
            }
            state = api.content.get_state(self.context)
            i = 0
            while state != 'sent' and i < 10:
                transitions(self.context, trans.get(state, []))
                state = api.content.get_state(self.context)
                i += 1