def test_content_category_changed_default_values(self):
        """While content_category is changed on an element, the default values for fields
           to_print/confidential/to_sign/signed are reapplied with new content_category
           default values if it was still the default vlue of the original content_category."""
        category_group = self.portal.config['group-1']
        category_group.to_be_printed_activated = True
        category_group.confidentiality_activated = True
        category_group.signed_activated = True
        category11 = self.portal.config['group-1']['category-1-1']
        category11_id = calculate_category_id(category11)
        obj = api.content.create(
            id='file2',
            type='File',
            file=self.file,
            container=self.portal,
            content_category=category11_id)
        self.assertFalse(obj.confidential)
        self.assertFalse(obj.to_sign)
        self.assertFalse(obj.signed)
        self.assertIsNone(obj.to_print)
        # now enable everything on category-1-2 and use it
        category12 = self.portal.config['group-1']['category-1-2']
        category12.to_print = False
        category12.confidential = True
        category12.to_sign = True
        category12.signed = True
        category12_id = calculate_category_id(category12)
        adapted_obj = IconifiedCategorization(obj)
        setattr(adapted_obj, 'content_category', category12_id)
        notify(ObjectModifiedEvent(obj))

        # changed to True on obj an in parent's categorized_elements
        parent_cat_elements = obj.aq_parent.categorized_elements[obj.UID()]
        self.assertTrue(obj.confidential)
        self.assertTrue(parent_cat_elements['confidential'])
        self.assertTrue(obj.to_sign)
        self.assertTrue(parent_cat_elements['to_sign'])
        self.assertTrue(obj.signed)
        self.assertTrue(parent_cat_elements['signed'])
        # to_print could not be set to False because not printable
        self.assertIsNone(obj.to_print)
        self.assertIsNone(parent_cat_elements['to_print'])

        # enable conversion and back to category11
        category11.to_print = True
        gsettings = GlobalSettings(self.portal)
        gsettings.auto_layout_file_types = CONVERTABLE_TYPES.keys()
        # set to_print to False, aka the default value of category12
        obj.to_print = False
        setattr(adapted_obj, 'content_category', category11_id)
        notify(ObjectModifiedEvent(obj))
        self.assertTrue(obj.to_print)
        self.assertTrue(parent_cat_elements['to_print'])

        # if original content_category does not exist, it does not fail
        # but default values are not reapplied
        obj.content_category = 'unkown_content_category'
        setattr(adapted_obj, 'content_category', category12_id)
        notify(ObjectModifiedEvent(obj))
        self.assertEqual(obj.content_category, category12_id)
 def test_ws_getItemInfosWithAnnexesTypes(self):
     """
       Test that getting an item with an annex_type return only the annexes
       with the corresponding annexTypeId attribute.
     """
     cfg = self.meetingConfig
     self.changeUser('pmCreator1')
     self.failUnless(
         len(self.portal.portal_catalog(portal_type='MeetingItemPma')) == 0)
     # prepare data for a default item
     req = self._prepareCreationData()
     # add one annex
     data = {
         'title': 'My annex 1',
         'filename': 'smallTestFile.pdf',
         'file': 'smallTestFile.pdf'
     }
     req._creationData._annexes = [self._prepareAnnexInfo(**data)]
     # create the item
     newItem, reponse = self._createItem(req)
     financial_annex_type_id = calculate_category_id(
         cfg.annexes_types.item_annexes.get('financial-analysis'))
     item_annex_type_id = calculate_category_id(
         cfg.annexes_types.item_annexes.get('item-annex'))
     allowed_annexes_types = [financial_annex_type_id, item_annex_type_id]
     # get informations about the item, by default 'allowed_annexes_types' is empty
     resp = self._getItemInfos(newItem.UID(),
                               showAnnexes=True,
                               toBeDeserialized=False)
     # we have 1 annex
     self.assertEqual(len(resp._itemInfo[0]._annexes), 1)
     # the returned annex is the one created
     self.assertEqual(resp._itemInfo[0]._annexes[0]._title, 'My annex 1')
     self.assertEqual(resp._itemInfo[0]._annexes[0]._filename,
                      'smallTestFile.pdf')
     # filter on 'item_annex_type' annex type
     allowed_annexes_types = [financial_annex_type_id]
     resp = self._getItemInfos(newItem.UID(),
                               showAnnexes=True,
                               allowed_annexes_types=allowed_annexes_types,
                               toBeDeserialized=False)
     # we have 1 annex
     self.assertEqual(len(resp._itemInfo[0]._annexes), 1)
     # the returned annex is the one created
     self.assertEqual(resp._itemInfo[0]._annexes[0]._title, 'My annex 1')
     self.assertIn(resp._itemInfo[0]._annexes[0]._annexTypeId,
                   allowed_annexes_types)
     # filter on 'financial_annex_type_id' annex type
     allowed_annexes_types = [item_annex_type_id]
     resp = self._getItemInfos(newItem.UID(),
                               showAnnexes=True,
                               allowed_annexes_types=allowed_annexes_types,
                               toBeDeserialized=False)
     # we have 0 annex
     self.assertEqual(len(resp._itemInfo[0]._annexes), 0)
Пример #3
0
    def _turn_ids_into_uids(self, data):
        # turn annex_type id into content_category calculated id
        content_category = data.get("content_category", None)
        annex_type = None
        # get selectable categories
        if data["@type"] == "annexDecision":
            self.request.set('force_use_item_decision_annexes_group', True)
        vocab = get_vocab(self.context,
                          'collective.iconifiedcategory.categories')
        # when content_category provided, it must exist
        if content_category is not None:
            annex_group = get_annexes_config(self.context,
                                             data["@type"],
                                             annex_group=True)
            # get given content_category or the first one
            annex_type = annex_group.get(content_category)
            if not annex_type:
                raise BadRequest(ANNEX_CONTENT_CATEGORY_ERROR %
                                 content_category)
            annex_type_value = calculate_category_id(annex_type)
            if annex_type_value not in vocab:
                raise BadRequest(ANNEX_CONTENT_CATEGORY_ERROR %
                                 content_category)
        else:
            # use the default annex_type, the first selectable
            if not vocab._terms:
                raise BadRequest(ANNEX_NO_CONTENT_CATEGORY_AVAILABLE_ERROR)
            annex_type_value = vocab._terms[0].token
        data["content_category"] = annex_type_value
        # cleanup
        if data["@type"] == "annexDecision":
            self.request.set('force_use_item_decision_annexes_group', False)

        return data
    def test_content_category_confidential_on_creation(self):
        """ """
        category_group = self.portal.config['group-1']
        category = self.portal.config['group-1']['category-1-1']
        content_category_id = calculate_category_id(category)
        category_group.confidentiality_activated = True

        # set to False
        category.confidential = False
        file2 = api.content.create(
            id='file2',
            type='File',
            file=self.file,
            container=self.portal,
            content_category=content_category_id)
        self.assertFalse(file2.confidential)

        # set to True
        category.confidential = True
        file3 = api.content.create(
            id='file3',
            type='File',
            file=self.file,
            container=self.portal,
            content_category=content_category_id)
        self.assertTrue(file3.confidential)
Пример #5
0
 def migrate_annex(self):
     qi = self.context.portal_quickinstaller
     if not qi.isProductInstalled('imio.annex'):
         qi.installProduct('imio.annex')
     self.runProfileSteps('imio.project.pst', steps=['typeinfo'], run_dependencies=False)
     brains = self.catalog(object_provides=IProjectSpace.__identifier__)
     for brain in brains:
         pst_obj = brain.getObject()
         behaviour = ISelectableConstrainTypes(pst_obj)
         behaviour.setConstrainTypesMode(1)
         behaviour.setLocallyAllowedTypes(['strategicobjective', 'annex', ])
         behaviour.setImmediatelyAddableTypes(['strategicobjective', 'annex', ])
     portal = api.portal.get()
     configure_iconified_category(portal)
     annexTypeId = calculate_category_id(portal.categorization.annexes.get('annexes-pst'))
     brains = self.catalog(object_provides=IFile.__identifier__)
     for brain in brains:
         file_obj = brain.getObject()
         parent = file_obj.aq_parent
         if parent.portal_type in ['pstprojectspace', 'strategicobjective', 'operationalobjective',
                                   'pstaction', 'pstsubaction', 'task']:
             annexId = file_obj.id
             api.content.delete(obj=parent[annexId])
             api.content.create(
                 container=parent,
                 type='annex',
                 id=annexId,
                 title=file_obj.Title(),
                 description=file_obj.Description(),
                 content_category=annexTypeId,
                 file=file_obj.file,
             )
             transaction.commit()
    def test_content_category_to_print_on_creation(self):
        """ """
        category_group = self.portal.config['group-1']
        category = self.portal.config['group-1']['category-1-1']
        content_category_id = calculate_category_id(category)
        category_group.to_be_printed_activated = True
        # enable conversion
        gsettings = GlobalSettings(self.portal)
        gsettings.auto_layout_file_types = CONVERTABLE_TYPES.keys()

        # set to False
        category.to_print = False
        file2 = api.content.create(
            id='file2',
            type='File',
            file=self.file,
            container=self.portal,
            content_category=content_category_id)
        self.assertFalse(file2.to_print)

        # set to True
        category.to_print = True
        file3 = api.content.create(
            id='file3',
            type='File',
            file=self.file,
            container=self.portal,
            content_category=content_category_id)
        self.assertTrue(file3.to_print)
 def __call__(self, context):
     terms = []
     categories = self._get_categories(context)
     for category in categories:
         category_id = utils.calculate_category_id(category)
         terms.append(SimpleVocabulary.createTerm(
             category_id,
             category_id,
             category.Title(),
         ))
         subcategories = self._get_subcategories(context, category)
         for subcategory in subcategories:
             subcategory_id = utils.calculate_category_id(subcategory.getObject())
             terms.append(SimpleVocabulary.createTerm(
                 subcategory_id,
                 subcategory_id,
                 subcategory.Title,
             ))
     return SimpleVocabulary(terms)
Пример #8
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
 def test_table_render_special_chars(self):
     """Special chars used in :
        - element's title;
        - category title;
        - subcategory title."""
     category = api.content.create(
         type='ContentCategory',
         title='Category \xc3\xa0',
         icon=self.icon,
         container=self.portal.config['group-1'],
     )
     subcategory = api.content.create(
         type='ContentSubcategory',
         title='Subcategory \xc3\xa0',
         icon=self.icon,
         container=category,
     )
     document = api.content.create(
         type='Document',
         title='Document \xc3\xa0',
         container=self.portal,
         content_category=utils.calculate_category_id(category),
         to_print=False,
         confidential=False,
     )
     document2 = api.content.create(
         type='Document',
         title='Document \xc3\xa0',
         container=self.portal,
         content_category=utils.calculate_category_id(subcategory),
         to_print=False,
         confidential=False,
     )
     view = self.portal.restrictedTraverse('@@iconifiedcategory')
     result = view()
     self.assertTrue(category.title in result)
     self.assertTrue(subcategory.title in result)
     self.assertTrue(document.title in result)
     self.assertTrue(document2.title in result)
Пример #10
0
 def __call__(self, *args, **kwargs):
     self.request.response.setHeader('Content-Type', 'text/css')
     content = []
     css = (u".{0} {{ padding-left: 1.4em; background: "
            u"transparent url('{1}') no-repeat top left; "
            u"background-size: contain; }}")
     if utils.has_config_root(self.context) is False:
         return ''
     categories = utils.get_categories(self.context)
     for category in categories:
         obj = category._unrestrictedGetObject()
         category_id = utils.calculate_category_id(obj)
         url = u'{0}/@@download'.format(obj.absolute_url())
         content.append(css.format(utils.format_id_css(category_id), url))
     return ' '.join(content)
 def test_content_category_not_set_if_not_activated(self):
     """ """
     category_group = self.portal.config['group-1']
     category = self.portal.config['group-1']['category-1-1']
     content_category_id = calculate_category_id(category)
     category_group.to_be_printed_activated = False
     category_group.confidentiality_activated = False
     category.to_print = True
     category.confidential = True
     obj = api.content.create(
         id='file2',
         type='File',
         file=self.file,
         container=self.portal,
         content_category=content_category_id)
     self.assertFalse(obj.to_print)
     self.assertFalse(obj.confidential)
    def test_content_category_to_sign_signed_on_creation(self):
        """ """
        category_group = self.portal.config['group-1']
        category = self.portal.config['group-1']['category-1-1']
        content_category_id = calculate_category_id(category)
        category_group.signed_activated = True

        # set to False both attributes
        category.to_sign = False
        category.signed = False
        file2 = api.content.create(
            id='file2',
            type='File',
            file=self.file,
            container=self.portal,
            content_category=content_category_id)
        self.assertFalse(file2.to_sign)
        self.assertFalse(file2.signed)

        # set True for to_sign, False for signed
        category.to_sign = True
        category.signed = False
        file3 = api.content.create(
            id='file3',
            type='File',
            file=self.file,
            container=self.portal,
            content_category=content_category_id)
        self.assertTrue(file3.to_sign)
        self.assertFalse(file3.signed)

        # set True for both attributes
        category.to_sign = True
        category.signed = True
        file4 = api.content.create(
            id='file4',
            type='File',
            file=self.file,
            container=self.portal,
            content_category=content_category_id)
        self.assertTrue(file4.to_sign)
        self.assertTrue(file4.signed)
Пример #13
0
 def test_restapi_add_item_with_annexes(self):
     """When creating an item, we may add annexes as __children__."""
     cfg = self.meetingConfig
     self.changeUser("pmManager")
     endpoint_url = "{0}/@item".format(self.portal_url)
     json = {
         "config_id":
         cfg.getId(),
         "proposingGroup":
         self.developers.getId(),
         "title":
         "My item",
         "__children__": [
             {
                 "@type": "annex",
                 "title": "My annex",
                 "content_category": "item-annex",
                 "file": {
                     "data": "123456",
                     "encoding": "ascii",
                     "filename": "file.txt",
                 },
             },
         ],
     }
     response = self.api_session.post(endpoint_url, json=json)
     transaction.begin()
     self.assertEqual(response.status_code, 201, response.content)
     pmFolder = self.getMeetingFolder()
     item = pmFolder.objectValues()[-1]
     self.assertEqual(item.Title(), json["title"])
     annex = get_annexes(item)[0]
     self.assertEqual(annex.title, json["__children__"][0]["title"])
     self.assertEqual(
         annex.content_category,
         calculate_category_id(
             cfg.annexes_types.item_annexes.get("item-annex")),
     )
     self.assertEqual(annex.file.filename,
                      json["__children__"][0]["file"]["filename"])
     self.assertEqual(annex.file.size, 6)
     self.assertEqual(annex.file.contentType, "text/plain")
Пример #14
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
    def test_content_category_to_print_only_set_if_convertible_when_conversion_enabled(self):
        """ """
        category_group = self.portal.config['group-1']
        category = self.portal.config['group-1']['category-1-1']
        content_category_id = calculate_category_id(category)
        category_group.to_be_printed_activated = True

        # set to True
        category.to_print = True
        file2 = api.content.create(
            id='file2',
            type='File',
            file=self.file,
            container=self.portal,
            content_category=content_category_id)
        # enable conversion
        gsettings = GlobalSettings(self.portal)
        gsettings.auto_layout_file_types = CONVERTABLE_TYPES.keys()
        file2.file.contentType = 'text/unknown'

        notify(ObjectModifiedEvent(file2))
        self.assertIsNone(file2.to_print)
Пример #16
0
    def _manage_after_scan_change_annex_type_to(self, the_file):
        """Change annex annex_type if defined in annex_type.after_scan_change_annex_type_to."""
        old_annex_type = get_category_object(the_file, the_file.content_category)
        after_scan_change_annex_type_to = old_annex_type.after_scan_change_annex_type_to
        # can not query on 'None'
        if not after_scan_change_annex_type_to:
            return

        brains = api.content.find(UID=old_annex_type.after_scan_change_annex_type_to)
        if not brains:
            return
        to_annex_type = brains[0].getObject()
        the_file.content_category = calculate_category_id(to_annex_type)

        # for items, the annex_type can move from item_annex type to item_decision_annex type
        # and the other way round, in this case, the annex portal_type changed
        if the_file.aq_parent.portal_type.startswith('MeetingItem'):
            old_annex_type_group = old_annex_type.get_category_group()
            to_annex_type_group = to_annex_type.get_category_group()
            if old_annex_type_group != to_annex_type_group:
                new_portal_type = 'annex'
                if to_annex_type_group.getId() == 'item_decision_annexes':
                    new_portal_type = 'annexDecision'
                the_file.portal_type = new_portal_type
Пример #17
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')
    def test_ws_getItemInfosWithAnnexesRequest(self):
        """
          Test that getting an item with a given UID returns valuable informations and linked annexes
        """
        cfg = self.meetingConfig
        self.changeUser('pmCreator1')
        self.failUnless(
            len(self.portal.portal_catalog(portal_type='MeetingItemPga')) == 0)
        # prepare data for a default item
        req = self._prepareCreationData()
        # add one annex
        data = {
            'title': 'My annex 1',
            'filename': 'smallTestFile.pdf',
            'file': 'smallTestFile.pdf'
        }
        req._creationData._annexes = [self._prepareAnnexInfo(**data)]
        # create the item
        newItem, reponse = self._createItem(req)
        newItemUID = newItem.UID()
        # get informations about the item, by default 'showAnnexes' is False
        resp = self._getItemInfos(newItemUID)
        expected = """<ns1:getItemInfosResponse xmlns:ns1="http://ws4pm.imio.be" """ \
            """xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" """ \
            """xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" """ \
            """xmlns:ZSI="http://www.zolera.com/schemas/ZSI/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" """ \
            """xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <itemInfo xsi:type="ns1:ItemInfo">
    <UID>{0}</UID>
    <id>{1}</id>
    <title>My new item title</title>
    <creator>pmCreator1</creator>
    <creation_date>{2}</creation_date>
    <modification_date>{3}</modification_date>
    <category>development</category>
    <description>&lt;p&gt;Description&lt;/p&gt;</description>
    <detailedDescription>&lt;p&gt;Detailed description&lt;/p&gt;</detailedDescription>
    <decision>&lt;p&gt;Décision&lt;/p&gt;</decision>
    <preferredMeeting/>
    <preferred_meeting_date>1950-01-01T00:00:00.006Z</preferred_meeting_date>
    <review_state>itemcreated</review_state>
    <meeting_date>1950-01-01T00:00:00.006Z</meeting_date>
    <absolute_url>http://nohost/plone/Members/pmCreator1/mymeetings/plonegov-assembly/{4}</absolute_url>
    <externalIdentifier/>
    <extraInfos/>
  </itemInfo>
</ns1:getItemInfosResponse>
""".format(newItemUID,
                newItem.getId(),
                gDateTime.get_formatted_content(gDateTime(), localtime(newItem.created())),
                gDateTime.get_formatted_content(gDateTime(), localtime(newItem.modified())),
                newItem.getId())
        # annexes are not shown by default
        self.assertEqual(expected, resp)
        # now with 'showAnnexes=True'
        financial_annex_type_id = calculate_category_id(
            cfg.annexes_types.item_annexes.get('financial-analysis'))
        item_annex_type_id = calculate_category_id(
            cfg.annexes_types.item_annexes.get('item-annex'))
        resp = self._getItemInfos(newItemUID, showAnnexes=True)
        expected = """<ns1:getItemInfosResponse xmlns:ns1="http://ws4pm.imio.be" """ \
            """xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" """ \
            """xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" """ \
            """xmlns:ZSI="http://www.zolera.com/schemas/ZSI/" """ \
            """xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <itemInfo xsi:type="ns1:ItemInfo">
    <UID>{0}</UID>
    <id>{1}</id>
    <title>My new item title</title>
    <creator>pmCreator1</creator>
    <creation_date>{2}</creation_date>
    <modification_date>{3}</modification_date>
    <category>development</category>
    <description>&lt;p&gt;Description&lt;/p&gt;</description>
    <detailedDescription>&lt;p&gt;Detailed description&lt;/p&gt;</detailedDescription>
    <decision>&lt;p&gt;Décision&lt;/p&gt;</decision>
    <preferredMeeting/>
    <preferred_meeting_date>1950-01-01T00:00:00.006Z</preferred_meeting_date>
    <review_state>itemcreated</review_state>
    <meeting_date>1950-01-01T00:00:00.006Z</meeting_date>
    <absolute_url>http://nohost/plone/Members/pmCreator1/mymeetings/plonegov-assembly/{4}</absolute_url>
    <externalIdentifier/>
    <extraInfos/>
    <annexes xsi:type="ns1:AnnexInfo">
      <id>smalltestfile.pdf</id>
      <title>My annex 1</title>
      <annexTypeId>{5}</annexTypeId>
      <filename>smallTestFile.pdf</filename>
      <file>
{6}</file>
    </annexes>
  </itemInfo>
</ns1:getItemInfosResponse>
""".format(newItemUID,
                newItem.getId(),
                gDateTime.get_formatted_content(gDateTime(), localtime(newItem.created())),
                gDateTime.get_formatted_content(gDateTime(), localtime(newItem.modified())),
                newItem.getId(),
                financial_annex_type_id,
                base64.encodestring(get_annexes(newItem)[0].file.data))
        # one annex is shown
        self.assertEqual(expected, resp)
        # now check with several (2) annexes...
        afile = open(
            os.path.join(os.path.dirname(__file__), 'mediumTestFile.odt'))
        annex_file = afile.read()
        afile.close()
        api.content.create(
            title='My BeautifulTestFile title',
            type='annex',
            file=namedfile.NamedBlobFile(
                annex_file, filename=safe_unicode(u'myBeautifulTestFile.odt')),
            container=newItem,
            content_category=item_annex_type_id,
            to_print=False,
            confidential=False)

        resp = self._getItemInfos(newItemUID, showAnnexes=True)
        expected = """<ns1:getItemInfosResponse xmlns:ns1="http://ws4pm.imio.be" """ \
            """xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" """ \
            """xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" """ \
            """xmlns:ZSI="http://www.zolera.com/schemas/ZSI/" """ \
            """xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <itemInfo xsi:type="ns1:ItemInfo">
    <UID>{0}</UID>
    <id>{1}</id>
    <title>My new item title</title>
    <creator>pmCreator1</creator>
    <creation_date>{2}</creation_date>
    <modification_date>{3}</modification_date>
    <category>development</category>
    <description>&lt;p&gt;Description&lt;/p&gt;</description>
    <detailedDescription>&lt;p&gt;Detailed description&lt;/p&gt;</detailedDescription>
    <decision>&lt;p&gt;Décision&lt;/p&gt;</decision>
    <preferredMeeting/>
    <preferred_meeting_date>1950-01-01T00:00:00.006Z</preferred_meeting_date>
    <review_state>itemcreated</review_state>
    <meeting_date>1950-01-01T00:00:00.006Z</meeting_date>
    <absolute_url>http://nohost/plone/Members/pmCreator1/mymeetings/plonegov-assembly/{4}</absolute_url>
    <externalIdentifier/>
    <extraInfos/>
    <annexes xsi:type="ns1:AnnexInfo">
      <id>{5}</id>
      <title>My annex 1</title>
      <annexTypeId>{6}</annexTypeId>
      <filename>smallTestFile.pdf</filename>
      <file>
{7}</file>
    </annexes>
    <annexes xsi:type="ns1:AnnexInfo">
      <id>{8}</id>
      <title>My BeautifulTestFile title</title>
      <annexTypeId>{9}</annexTypeId>
      <filename>myBeautifulTestFile.odt</filename>
      <file>
{10}</file>
    </annexes>
  </itemInfo>
</ns1:getItemInfosResponse>
""".format(newItemUID,
                newItem.getId(),
                gDateTime.get_formatted_content(gDateTime(), localtime(newItem.created())),
                gDateTime.get_formatted_content(gDateTime(), localtime(newItem.modified())),
                newItem.getId(),
                get_annexes(newItem)[0].id,
                financial_annex_type_id,
                base64.encodestring(get_annexes(newItem)[0].file.data),
                get_annexes(newItem)[1].id,
                item_annex_type_id,
                base64.encodestring(get_annexes(newItem)[1].file.data))
        # 2 annexes are shown
        self.assertEqual(expected, resp)