示例#1
0
    def addAnnex(self,
                 context,
                 annexType=None,
                 annexTitle=None,
                 relatedTo=None,
                 to_print=False,
                 confidential=False,
                 to_sign=False,
                 signed=False,
                 publishable=False,
                 annexFile=None):
        '''Adds an annex to p_item.
           If no p_annexType is provided, self.annexFileType is used.
           If no p_annexTitle is specified, the predefined title of the annex type is used.'''

        if annexType is None:
            if context.getTagName() == 'MeetingItem':
                if not relatedTo:
                    annexType = self.annexFileType
                elif relatedTo == 'item_decision':
                    annexType = self.annexFileTypeDecision
            elif context.portal_type.startswith('meetingadvice'):
                annexType = self.annexFileTypeAdvice
            elif context.getTagName() == 'Meeting':
                annexType = self.annexFileTypeMeeting

        # get complete annexType id that is like
        # 'meeting-config-id-annexes_types_-_item_annexes_-_financial-analysis'
        if relatedTo == 'item_decision':
            context.REQUEST.set('force_use_item_decision_annexes_group', True)
        annexes_config_root = get_config_root(context)
        if relatedTo == 'item_decision':
            context.REQUEST.set('force_use_item_decision_annexes_group', False)
        annexTypeId = calculate_category_id(annexes_config_root.get(annexType))

        annexContentType = 'annex'
        if relatedTo == 'item_decision':
            annexContentType = 'annexDecision'

        theAnnex = createContentInContainer(
            container=context,
            portal_type=annexContentType,
            title=annexTitle or 'Annex',
            file=self._annex_file_content(annexFile=annexFile),
            content_category=annexTypeId,
            to_print=to_print,
            confidential=confidential,
            to_sign=to_sign,
            signed=signed,
            publishable=publishable)
        # need to commit the transaction so the stored blob is correct
        # if not done, accessing the blob will raise 'BlobError: Uncommitted changes'
        transaction.commit()
        return theAnnex
示例#2
0
    def _enable_annex_config(self,
                             obj,
                             param="confidentiality",
                             related_to=None,
                             enable=True):
        """p_fct possible values are :
           - confidentiality (default);
           - to_be_printed;
           - signed;
           - publishable."""
        if related_to == 'item_decision':
            self.request.set('force_use_item_decision_annexes_group', True)
        annexes_config_root = get_config_root(obj)
        if related_to == 'item_decision':
            self.request.set('force_use_item_decision_annexes_group', False)

        annex_group = get_group(annexes_config_root, obj)
        attr_name = "{0}_activated".format(param)
        setattr(annex_group, attr_name, enable)
示例#3
0
    def add_annex(
        self,
        context,
        path,
        annex_type=None,
        annex_title=None,
        to_print=False,
        confidential=False,
    ):
        """Adds an annex to p_item.
           If no p_annexType is provided, self.annexFileType is used.
           If no p_annexTitle is specified, the predefined title of the annex type is used."""
        # _path = self._check_file_exists(path)

        if annex_type is None:
            annex_type = "annexe"

        # get complete annexType id that is like
        # 'meeting-config-id-annexes_types_-_item_annexes_-_financial-analysis'
        annexes_config_root = get_config_root(context)
        annex_type_id = calculate_category_id(
            annexes_config_root.get(annex_type))

        annex_portal_type = "annex"
        file_ext = path[path.rindex("."):].lower()
        content_type = content_types[file_ext]

        the_annex = createContentInContainer(
            container=context,
            portal_type=annex_portal_type,
            title=annex_title or "Annex",
            file=self._annex_file_content(path),
            content_category=annex_type_id,
            content_type=content_type,
            contentType=content_type,
            to_print=to_print,
            confidential=confidential,
        )
        return the_annex
示例#4
0
def addDemoData(context):
    ''' '''
    if isNotMeetingCommunesDemoProfile(context):
        return

    site = context.getSite()
    tool = api.portal.get_tool('portal_plonemeeting')
    cfg = tool.objectValues('MeetingConfig')[0]
    wfTool = api.portal.get_tool('portal_workflow')
    pTool = api.portal.get_tool('plone_utils')
    mTool = api.portal.get_tool('portal_membership')
    # first we need to be sure that our IPoneMeetingLayer is set correctly
    # https://dev.plone.org/ticket/11673
    from zope.event import notify
    from zope.traversing.interfaces import BeforeTraverseEvent
    notify(BeforeTraverseEvent(site, site.REQUEST))
    # we will create elements for some users, make sure their personal
    # area is correctly configured
    # first make sure the 'Members' folder exists
    members = mTool.getMembersFolder()
    if members is None:
        _createObjectByType('Folder', site, id='Members')
    mTool.createMemberArea('agentPers')
    mTool.createMemberArea('agentInfo')
    mTool.createMemberArea('agentCompta')
    # create 5 meetings : 2 passed, 1 current and 2 future
    today = datetime.now()
    dates = [
        today - timedelta(days=13), today - timedelta(days=6),
        today + timedelta(days=1), today + timedelta(days=8),
        today + timedelta(days=15)
    ]

    # items dict here : the key is the user we will create the item for
    # we use item templates so content is created for the demo
    items = {
        'agentPers': (
            {
                'templateId': 'template3',
                'title': u'Engagement temporaire d\'un informaticien',
                'budgetRelated': True,
                'review_state': 'validated',
            },
            {
                'templateId': 'template2',
                'title': u'Contrôle médical de Mr Antonio',
                'budgetRelated': False,
                'review_state': 'proposed',
            },
            {
                'templateId': 'template2',
                'title': u'Contrôle médical de Mlle Debbeus',
                'budgetRelated': False,
                'review_state': 'proposed',
            },
            {
                'templateId': 'template2',
                'title': u'Contrôle médical de Mme Hanck',
                'budgetRelated': False,
                'review_state': 'validated',
            },
            {
                'templateId': 'template4',
                'title':
                u'Prestation réduite Mme Untelle, instritutrice maternelle',
                'budgetRelated': False,
                'review_state': 'validated',
            },
        ),
        'agentInfo': (
            {
                'templateId': 'template5',
                'title': u'Achat nouveaux serveurs',
                'budgetRelated': True,
                'review_state': 'validated',
            },
            {
                'templateId': 'template5',
                'title': u'Marché public, contestation entreprise Untelle SA',
                'budgetRelated': False,
                'review_state': 'validated',
            },
        ),
        'agentCompta': (
            {
                'templateId': 'template5',
                'title': u'Présentation budget 2014',
                'budgetRelated': True,
                'review_state': 'validated',
            },
            {
                'templateId': 'template5',
                'title': u'Plainte de Mme Daise, taxe immondice',
                'budgetRelated': False,
                'review_state': 'validated',
            },
            {
                'templateId': 'template5',
                'title': u'Plainte de Mme Uneautre, taxe piscine',
                'budgetRelated': False,
                'review_state': 'proposed',
            },
        ),
        'dgen': (
            {
                'templateId': 'template1',
                'title': u'Tutelle CPAS : point 1 BP du 15 juin',
                'budgetRelated': False,
                'review_state': 'created',
            },
            {
                'templateId': 'template5',
                'title': u'Tutelle CPAS : point 2 BP du 15 juin',
                'budgetRelated': False,
                'review_state': 'proposed',
            },
            {
                'templateId': 'template5',
                'title': u'Tutelle CPAS : point 16 BP du 15 juin',
                'budgetRelated': True,
                'review_state': 'validated',
            },
        ),
    }
    # login as 'dgen'
    mTool.createMemberArea('dgen')

    for cfg in tool.objectValues('MeetingConfig'):
        # cleanMemoize so ToolPloneMeeting.getMeetingConfig returns the correct MeetingConfig
        cleanMemoize(site)
        secrFolder = tool.getPloneMeetingFolder(cfg.getId(), 'dgen')
        # build attendees and signatories passed to Meeting._doUpdateContacts
        # attendees OrderedDict([('uid1', 'attendee'), ('uid2', 'attendee'), ('uid3', 'absent')])
        # signatories {'uid1': '1'}
        attendees = OrderedDict()
        signatories = {}
        for hp_uid in cfg.getOrderedContacts():
            attendees[hp_uid] = 'attendee'
        signatories = {attendees.keys()[1]: '1', attendees.keys()[0]: '2'}
        # create meetings
        for date in dates:
            meetingId = secrFolder.invokeFactory(cfg.getMeetingTypeName(),
                                                 id=date.strftime('%Y%m%d'),
                                                 date=date)
            meeting = getattr(secrFolder, meetingId)
            pTool.changeOwnershipOf(meeting, 'dgen')
            meeting._do_update_contacts(attendees=attendees,
                                        signatories=signatories)
            # -13 meeting is closed
            if date == today - timedelta(days=13):
                wfTool.doActionFor(meeting, 'freeze')
                wfTool.doActionFor(meeting, 'decide')
                wfTool.doActionFor(meeting, 'close')
            # -6 meeting is frozen
            if date == today - timedelta(days=6):
                wfTool.doActionFor(meeting, 'freeze')
                wfTool.doActionFor(meeting, 'decide')
            meeting.reindexObject()

            for item in meeting.get_items():
                pTool.changeOwnershipOf(item, 'dgen')

        # create items
        for userId in items:
            userFolder = tool.getPloneMeetingFolder(cfg.getId(), userId)
            for item in items[userId]:
                # get the template then clone it
                template = getattr(
                    tool.getMeetingConfig(userFolder).itemtemplates,
                    item['templateId'])
                with api.env.adopt_user(username=userId):
                    tool.invalidateAllCache()
                    newItem = template.clone(
                        newOwnerId=userId,
                        destFolder=userFolder,
                        newPortalType=cfg.getItemTypeName())
                    newItem.setTitle(item['title'])
                    newItem.setBudgetRelated(item['budgetRelated'])
                    if item['review_state'] == 'proposed':
                        wfTool.doActionFor(newItem, 'propose')

                if item['review_state'] == 'validated':
                    wfTool.doActionFor(newItem, 'validate')
                # add annexe and advice for one item in College
                if item['templateId'] == 'template3' and cfg.id == 'meeting-config-college':
                    cpt = 1
                    annexes_config_root = get_config_root(newItem)
                    for annexType in ('annexe', 'annexe', 'annexeBudget',
                                      'annexeCahier'):
                        annex_title = u'CV Informaticien N°2016-%s' % (cpt)
                        annex_file = namedfile.NamedBlobFile(
                            'Je suis le contenu du fichier',
                            filename=u'CV-0%s.txt' % (cpt))
                        annexTypeId = calculate_category_id(
                            annexes_config_root.get(annexType))
                        annex_id = normalize_name(site.REQUEST, annex_title)
                        api.content.create(container=newItem,
                                           id=annex_id,
                                           type='annex',
                                           title=annex_title,
                                           file=annex_file,
                                           content_category=annexTypeId,
                                           to_print=False,
                                           confidential=False)
                        cpt += 1
                    newItem.setOptionalAdvisers(
                        ('{0}__rowid__unique_id_003'.format(
                            org_id_to_uid('dirfin')),
                         org_id_to_uid('informatique')))
                    newItem.at_post_create_script()
                    createContentInContainer(
                        newItem, 'meetingadvice', **{
                            'advice_group': org_id_to_uid('informatique'),
                            'advice_type': u'positive',
                            'advice_comment': RichTextValue(SAMPLE_TEXT),
                            'advice_observations': RichTextValue()
                        })
                if item['templateId'] == 'template5' and cfg.id == 'meeting-config-college':
                    newItem.setOptionalAdvisers((org_id_to_uid('dirgen'), ))
                    newItem.at_post_create_script()
                    createContentInContainer(
                        newItem, 'meetingadvice', **{
                            'advice_group': org_id_to_uid('dirgen'),
                            'advice_type': u'negative',
                            'advice_comment': RichTextValue(SAMPLE_TEXT),
                            'advice_observations': RichTextValue(SAMPLE_TEXT)
                        })

                newItem.reindexObject()

        # adapt some parameters for config
        cfg.setAnnexToPrintMode('enabled_for_info')
示例#5
0
    def test_pm_AnnexToPrintBehaviourWhenCloned(self):
        """When cloning an item with annexes, to the same or another MeetingConfig, the 'toPrint' field
           is kept depending on MeetingConfig.keepOriginalToPrintOfClonedItems.
           If it is True, the original value is kept, if it is False, it will use the
           MeetingConfig.annexToPrintDefault value."""
        cfg = self.meetingConfig
        cfg2 = self.meetingConfig2
        cfg2Id = cfg2.getId()
        cfg.setKeepOriginalToPrintOfClonedItems(False)
        cfg2.setKeepOriginalToPrintOfClonedItems(False)
        self.changeUser('pmManager')
        meeting = self.create('Meeting', date=DateTime('2016/02/02'))
        item = self.create('MeetingItem')
        annex = self.addAnnex(item)
        annex_config = get_config_root(annex)
        annex_group = get_group(annex_config, annex)
        self.assertFalse(annex_group.to_be_printed_activated)
        self.assertFalse(annex.to_print)
        annex.to_print = True
        self.assertTrue(annex.to_print)
        # decide the item so we may add decision annex
        item.setDecision(self.decisionText)
        self.presentItem(item)
        self.decideMeeting(meeting)
        self.do(item, 'accept')
        self.assertEquals(item.queryState(), 'accepted')
        annexDec = self.addAnnex(item, relatedTo='item_decision')
        annexDec_config = get_config_root(annexDec)
        annexDec_group = get_group(annexDec_config, annexDec)
        self.assertFalse(annexDec_group.to_be_printed_activated)
        self.assertFalse(annexDec.to_print)
        annexDec.to_print = True
        self.assertTrue(annexDec.to_print)

        # clone item locally, as keepOriginalToPrintOfClonedItems is False
        # default values defined in the config will be used
        self.assertFalse(cfg.getKeepOriginalToPrintOfClonedItems())
        clonedItem = item.clone()
        annexes = get_annexes(clonedItem, portal_types=['annex'])
        if not annexes:
            pm_logger.info('No annexes found on duplicated item clonedItem')
        cloneItemAnnex = annexes and annexes[0]
        annexesDec = get_annexes(clonedItem, portal_types=['annexDecision'])
        if not annexesDec:
            pm_logger.info(
                'No decision annexes found on duplicated item clonedItem')
        cloneItemAnnexDec = annexesDec and annexesDec[0]
        self.assertFalse(cloneItemAnnex and cloneItemAnnex.to_print)
        self.assertFalse(cloneItemAnnexDec and cloneItemAnnexDec.to_print)

        # enable keepOriginalToPrintOfClonedItems
        # some plugins remove annexes/decision annexes on duplication
        # so make sure we test if an annex is there...
        self.changeUser('siteadmin')
        cfg.setKeepOriginalToPrintOfClonedItems(True)
        self.changeUser('pmManager')
        clonedItem2 = item.clone()
        annexes = get_annexes(clonedItem2, portal_types=['annex'])
        if not annexes:
            pm_logger.info('No annexes found on duplicated item clonedItem2')
        cloneItem2Annex = annexes and annexes[0]
        annexesDec = get_annexes(clonedItem2, portal_types=['annexDecision'])
        if not annexesDec:
            pm_logger.info(
                'No decision annexes found on duplicated item clonedItem2')
        cloneItem2AnnexDec = annexesDec and annexesDec[0]
        self.assertTrue(cloneItem2Annex and cloneItem2Annex.to_print or True)
        self.assertTrue(cloneItem2AnnexDec and cloneItem2AnnexDec.to_print
                        or True)

        # clone item to another MC and test again
        # cfg2.keepOriginalToPrintOfClonedItems is True
        self.assertFalse(cfg2.getKeepOriginalToPrintOfClonedItems())
        item.setOtherMeetingConfigsClonableTo((cfg2Id, ))
        clonedToCfg2 = item.cloneToOtherMeetingConfig(cfg2Id)
        annexes = get_annexes(clonedToCfg2, portal_types=['annex'])
        if not annexes:
            pm_logger.info('No annexes found on duplicated item clonedToCfg2')
        clonedToCfg2Annex = annexes and annexes[0]
        annexesDec = get_annexes(clonedToCfg2, portal_types=['annexDecision'])
        if not annexesDec:
            pm_logger.info(
                'No decision annexes found on duplicated item clonedToCfg2')
        self.assertFalse(clonedToCfg2Annex and clonedToCfg2Annex.to_print)

        # enable keepOriginalToPrintOfClonedItems
        self.changeUser('siteadmin')
        cfg2.setKeepOriginalToPrintOfClonedItems(True)
        self.deleteAsManager(clonedToCfg2.UID())
        # send to cfg2 again
        self.changeUser('pmManager')
        clonedToCfg2Again = item.cloneToOtherMeetingConfig(cfg2Id)
        annexes = get_annexes(clonedToCfg2Again, portal_types=['annex'])
        if not annexes:
            pm_logger.info(
                'No annexes found on duplicated item clonedToCfg2Again')
        clonedToCfg2AgainAnnex = annexes and annexes[0]
        annexesDec = get_annexes(clonedToCfg2Again,
                                 portal_types=['annexDecision'])
        if not annexesDec:
            pm_logger.info(
                'No decision annexes found on duplicated item clonedToCfg2Again'
            )
        self.assertTrue(
            clonedToCfg2AgainAnnex and clonedToCfg2AgainAnnex.to_print or True)