def _migrate_categories_to_groups_in_charge_field(self): logger.info("Migrating Category to Groups in charge field") catalog = api.portal.get_tool("portal_catalog") own_org = get_own_organization() # First we create the appropriate groupsInCharge logger.info("Adapting MeetingConfig...") cfg = catalog(portal_type="MeetingConfig", id=self.meeting_config_id)[0].getObject() categories = cfg.categories for cat_id, category in categories.contentItems(): if cat_id not in own_org.objectIds(): data = { "id": cat_id, "title": category.Title(), "description": category.Description() } api.content.create(container=own_org, type="organization", **data) new_org_uid = org_id_to_uid(cat_id) enabled_plonegroup_org_uids = api.portal.get_registry_record( ORGANIZATIONS_REGISTRY) if new_org_uid not in enabled_plonegroup_org_uids: api.portal.set_registry_record( ORGANIZATIONS_REGISTRY, enabled_plonegroup_org_uids + [new_org_uid]) ordered_group_in_charge_uids = cfg.getOrderedGroupsInCharge() if new_org_uid not in ordered_group_in_charge_uids: cfg.setOrderedGroupsInCharge(ordered_group_in_charge_uids + (new_org_uid, )) category.enabled = False # Next we migrate the category to groupsInCharge on MeetingItems brains = catalog(portal_type=( cfg.getItemTypeName(), cfg.getItemTypeName(configType="MeetingItemRecurring"), cfg.getItemTypeName(configType="MeetingItemTemplate"), )) pghandler = ZLogHandler(steps=1000) pghandler.init("Adapting items...", len(brains)) for i, brain in enumerate(brains): pghandler.report(i) item = brain.getObject() if item.getCategory() != u"_none_": item.setGroupsInCharge([org_id_to_uid(item.getCategory())]) item.setCategory(None) item.reindexObject(idxs=["getGroupsInCharge", "getCategory"]) pghandler.finish() logger.info("Done migrating Categories to Groups in charge field")
def _createFinancesGroup(self): """ Create the finances group. """ context = self.portal.portal_setup._getImportContext('Products.MeetingCharleroi:testing') initializer = ToolInitializer(context, PROJECTNAME) # create echevin2 first as it is a group in charge of finances org orgs, active_orgs, savedOrgsData = initializer.addOrgs([charleroi_import_data.ech2_grp]) for org in orgs: org_uid = org.UID() self._select_organization(org_uid) dirfin_grp = deepcopy(charleroi_import_data.dirfin_grp) dirfin_grp.groups_in_charge = [org_id_to_uid(group_in_charge_id) for group_in_charge_id in dirfin_grp.groups_in_charge] orgs, active_orgs, savedOrgsData = initializer.addOrgs([dirfin_grp]) initializer.data = initializer.getProfileData() for org in orgs: org_uid = org.UID() org.item_advice_states = initializer._correct_advice_states(dirfin_grp.item_advice_states) org.item_advice_edit_states = initializer._correct_advice_states(dirfin_grp.item_advice_edit_states) self._select_organization(org_uid) select_org_for_function(org_uid, 'financialcontrollers') select_org_for_function(org_uid, 'financialeditors') select_org_for_function(org_uid, 'financialmanagers') select_org_for_function(org_uid, 'financialreviewers') # clean forever cache on utils finance_group_uid _memos.clear()
def finance_group_uids(raise_on_error=False): """ """ res = [] for fin_grp_id in FINANCE_GROUP_IDS: org_uid = org_id_to_uid(fin_grp_id, raise_on_error=raise_on_error) if org_uid: res.append(org_uid) return res
def not_copy_group_uids(raise_on_error=False): """ """ res = [] for not_copy_grp_id in NOT_COPY_GROUP_IDS: org_uid = org_id_to_uid(not_copy_grp_id, raise_on_error=raise_on_error) if org_uid: res.append(org_uid) return res
def _get_org_uid(field_name, field_value): """Get org UID as given field_value may be an UID or an id.""" if field_value in org_uids: return field_value else: org_uid = org_id_to_uid(field_value, raise_on_error=False) if org_uid is None: raise BadRequest(ORG_FIELD_VALUE_ERROR % (field_value, field_name)) return org_uid
def test_idea_getIDEAPrintableItems(self): self.changeUser('admin') group = get_organization(org_id_to_uid('developers')) group.Title = u"Développeurs - DSI" self.changeUser('pmManager') meeting = self.create('Meeting', date='2007/12/11 09:00:00') item1 = self.create('MeetingItem', title='The first item') self.presentItem(item1) item2 = self.create('MeetingItem', title='The second item') self.presentItem(item2) meeting.adapted().getIDEAPrintableItemsByCategory()
def test_pm_InsertItemOnPoliceThenOtherGroups(self): '''Test inserting an item using the "on_police_then_other_groups" sorting method.''' self._setupPoliceGroup() self.meetingConfig.setInsertingMethodsOnAddItem(({ 'insertingMethod': 'on_police_then_other_groups', 'reverse': '0' }, )) self.changeUser('pmManager') # create items with various groups itemDev1 = self.create('MeetingItem') itemDev2 = self.create('MeetingItem') itemDev3 = self.create('MeetingItem') itemVen1 = self.create('MeetingItem', proposingGroup=self.vendors_uid) itemVen2 = self.create('MeetingItem', proposingGroup=self.vendors_uid) itemPol1 = self.create( 'MeetingItem', proposingGroup=org_id_to_uid(POLICE_GROUP_PREFIX)) itemPol2 = self.create( 'MeetingItem', proposingGroup=org_id_to_uid(POLICE_GROUP_PREFIX)) meeting = self.create('Meeting', date=DateTime()) for item in [ itemDev1, itemDev2, itemDev3, itemVen1, itemVen2, itemPol1, itemPol2, ]: self.presentItem(item) police_uid = org_id_to_uid(POLICE_GROUP_PREFIX) orderedItems = meeting.getItems(ordered=True) self.assertEqual([item.getId() for item in orderedItems], ['o6', 'o7', 'o1', 'o2', 'o3', 'o4', 'o5']) self.assertEqual([item.getProposingGroup() for item in orderedItems], [ police_uid, police_uid, self.developers_uid, self.developers_uid, self.developers_uid, self.vendors_uid, self.vendors_uid ])
def addCategory(self, cfg, descr, classifier=False): '''Creates a category or a classifier (depending on p_classifier) from p_descr, a CategoryDescriptor instance.''' if classifier: folder = getattr(cfg, TOOL_FOLDER_CLASSIFIERS) else: folder = getattr(cfg, TOOL_FOLDER_CATEGORIES) data = descr.getData() cat = api.content.create(container=folder, type='meetingcategory', **data) # adapt org related values as we have org id on descriptor and we need to set org UID if cat.using_groups: cat.using_groups = ([ org_id_to_uid(using_group) for using_group in cat.using_groups ]) if cat.groups_in_charge: cat.groups_in_charge = ([ org_id_to_uid(gic) for gic in cat.groups_in_charge ]) return cat
def test_CouncilPublicItemsAreInsertedUsingIndetemineeCategoryWhereSecretItemsAreLeftValidated( self): """Items with confidentiality 'public' coming from College are inserted in a Council meeting a will use the 'indeterminee' category. Items with confidentiality 'secret' coming from the College will stay 'validated' and are not automatically inserted into a meeting.""" self.setMeetingConfig('meeting-config-council') self.setupCouncilConfig() self.changeUser('pmManager') # Council council_meeting = self.create('Meeting', date=DateTime() + 1) # College self.setMeetingConfig('meeting-config-college') publicItem = self.create('MeetingItem') publicItem.setOtherMeetingConfigsClonableTo( (u'meeting-config-council', )) publicItem.setOtherMeetingConfigsClonableToPrivacy(()) gic2_uid = org_id_to_uid('groupincharge2') publicItem.setProposingGroupWithGroupInCharge( '{0}__groupincharge__{1}'.format(self.developers_uid, gic2_uid)) secretItem = self.create('MeetingItem') secretItem.setOtherMeetingConfigsClonableTo( (u'meeting-config-council', )) secretItem.setOtherMeetingConfigsClonableToPrivacy( (u'meeting-config-council', )) secretItem.setProposingGroupWithGroupInCharge( '{0}__groupincharge__{1}'.format(self.developers_uid, gic2_uid)) college_meeting = self.create('Meeting', date=DateTime('2017/02/12')) self.presentItem(publicItem) self.presentItem(secretItem) self.closeMeeting(college_meeting) council_publicItem = publicItem.getItemClonedToOtherMC( 'meeting-config-council') # groupsInCharge were kept self.assertEqual((council_publicItem.getProposingGroup(), council_publicItem.getGroupsInCharge(first=True)), (publicItem.getProposingGroup(), publicItem.getGroupsInCharge(first=True))) council_secretItem = secretItem.getItemClonedToOtherMC( 'meeting-config-council') # groupsInCharge were kept self.assertEqual((council_secretItem.getProposingGroup(), council_secretItem.getGroupsInCharge(first=True)), (secretItem.getProposingGroup(), secretItem.getGroupsInCharge(first=True))) # publicItem was presented into the council_meeting, no matter the 'PUBLISHED' object is the college_meeting self.assertEqual(self.request['PUBLISHED'], college_meeting) self.assertEqual(council_publicItem.getMeeting(), council_meeting) self.assertEqual(council_publicItem.getCategory(), COUNCIL_DEFAULT_CATEGORY) # secretItem is not presented and is still validated self.assertFalse(council_secretItem.hasMeeting())
def test_CollegeCommunicationItemIsInsertedAsNormalItem(self): """ """ collegeMeeting, collegeExtraMeeting = self.setupCollegeDemoData() self.portal.REQUEST['PUBLISHED'] = collegeMeeting self.freezeMeeting(collegeMeeting) self.assertEqual(collegeMeeting.queryState(), 'frozen') commItem = self.create('MeetingItem') commItem.setCategory('communication') commItem.setPreferredMeeting(collegeMeeting.UID()) gic2_uid = org_id_to_uid('groupincharge2') commItem.setProposingGroupWithGroupInCharge( '{0}__groupincharge__{1}'.format(self.developers_uid, gic2_uid)) self.presentItem(commItem) self.assertEqual(commItem.getMeeting(), collegeMeeting) self.assertEqual(commItem.getListType(), 'normal')
def _createRecurringItems(self): """ """ if self.meetingConfig.getId() == 'meeting-config-college': items = charleroi_import_data.collegeMeeting.recurringItems else: items = charleroi_import_data.councilMeeting.recurringItems for item in items: gic2_uid = org_id_to_uid('groupincharge2') group_in_charge_value = '{0}__groupincharge__{0}'.format( self.developers_uid, gic2_uid) data = {'id': item.id, 'title': item.title, 'description': item.description, 'category': item.category, 'proposingGroup': self.developers_uid, 'proposingGroupWithGroupInCharge': group_in_charge_value, 'decision': item.decision, 'meetingTransitionInsertingMe': item.meetingTransitionInsertingMe} self.create('MeetingItemRecurring', **data)
def _testWholeDecisionProcessCouncil(self): """ This test covers the whole decision workflow. Items are created from College directly as 'validated'. """ # meeting-config-college is tested in test_pm_WholeDecisionProcessCollege # we do the test for the council config self.setMeetingConfig('meeting-config-council') # items come from College or could be created by a MeetingManager directly 'validated' # apply WFAdaptation defined in zcharleroi.import_data cfg = self.meetingConfig self.setupCouncilConfig() itemWF = self.wfTool.getWorkflowsFor(cfg.getItemTypeName())[0] self.assertFalse('itemcreated' in itemWF.states) self.assertFalse('proposed' in itemWF.states) self.assertTrue('validated' in itemWF.states) self.assertEqual(itemWF.initial_state, 'validated') self.changeUser('pmManager') gic2_uid = org_id_to_uid('groupincharge2') dev_group_in_charge = '{0}__groupincharge__{1}'.format(self.developers_uid, gic2_uid) item1 = self.create('MeetingItem', title='The first item', proposingGroupWithGroupInCharge=dev_group_in_charge) self.addAnnex(item1) self.addAnnex(item1, relatedTo='item_decision') self.assertEqual(item1.queryState(), 'validated') meeting = self.create('Meeting', date='2016/12/11 09:00:00') item2 = self.create('MeetingItem', title='The second item', preferredMeeting=meeting.UID(), proposingGroupWithGroupInCharge=dev_group_in_charge) self.presentItem(item1) item1.setDecision(self.decisionText) self.decideMeeting(meeting) self.assertEqual(meeting.queryState(), 'decided') item2.setDecision(self.decisionText) self.presentItem(item2) self.do(meeting, 'close') self.assertEqual(item1.queryState(), 'accepted') self.assertEqual(item2.queryState(), 'accepted')
def addItemToConfig(self, cfg, descr, isRecurring=True): '''Adds a recurring item or item template from a RecurringItemDescriptor or a ItemTemplateDescriptor depending on p_isRecurring.''' if isRecurring: folder = getattr(cfg, TOOL_FOLDER_RECURRING_ITEMS) else: folder = getattr(cfg, TOOL_FOLDER_ITEM_TEMPLATES) data = descr.__dict__ itemType = isRecurring and \ cfg.getItemTypeName(configType='MeetingItemRecurring') or \ cfg.getItemTypeName(configType='MeetingItemTemplate') folder.invokeFactory(itemType, **data) item = getattr(folder, descr.id) # adapt org related values as we have org id on descriptor and we need to set org UID if item.proposingGroup: item.setProposingGroup(org_id_to_uid(item.proposingGroup)) if item.groupsInCharge: item.setGroupsInCharge([ org_id_to_uid(grp_in_charge) for grp_in_charge in item.groupsInCharge ]) if item.proposingGroupWithGroupInCharge: proposing_group_id, group_in_charge_id = item.proposingGroupWithGroupInCharge.split( '__groupincharge__') proposing_group_uid = org_id_to_uid(proposing_group_id) group_in_charge_uid = org_id_to_uid(group_in_charge_id) item.setProposingGroup(proposing_group_uid) item.setGroupsInCharge((group_in_charge_uid, )) item.proposingGroupWithGroupInCharge = '{0}__groupincharge__{1}'.format( proposing_group_uid, group_in_charge_uid) if item.associatedGroups: item.setAssociatedGroups([ org_id_to_uid(associated_group) for associated_group in item.associatedGroups ]) if item.templateUsingGroups: item.setTemplateUsingGroups([ org_id_to_uid(template_using_group) for template_using_group in item.templateUsingGroups ]) # disable _at_rename_after_creation for itemTemplates and recurringItems item._at_rename_after_creation = False # call processForm passing dummy values so existing values are not touched item.processForm(values={'dummy': None}) return item
def test_pm_org_id_to_uid(self): """Test the utils.org_id_to_uid function.""" self.changeUser('pmManager') # org UID self.assertIsNone(org_id_to_uid('')) self.assertEqual(org_id_to_uid(self.developers.getId()), self.developers_uid) self.assertEqual(org_id_to_uid(self.vendors.getId()), self.vendors_uid) # org UID with suffix dev_id_creators = "{0}_creators".format(self.developers.getId()) dev_uid_creators = "{0}_creators".format(self.developers.UID()) self.assertEqual(org_id_to_uid(dev_id_creators), dev_uid_creators) ven_id_creators = "{0}_creators".format(self.vendors.getId()) ven_uid_creators = "{0}_creators".format(self.vendors.UID()) self.assertEqual(org_id_to_uid(ven_id_creators), ven_uid_creators) # raise_on_error self.assertRaises(KeyError, org_id_to_uid, "wrong/path") self.assertIsNone(org_id_to_uid("wrong/path", raise_on_error=False))
def createMeetingConfig(self, configData, source): '''Creates a new meeting configuration from p_configData which is a MeetingConfigDescriptor instance. p_source is a string that corresponds to the absolute path of a profile; additional (binary) data like images or templates that need to be attached to some sub-objects of the meeting config will be searched there.''' cData = configData.getData() # turn org ids into org uids for field_name in [ 'orderedAssociatedOrganizations', 'orderedContacts', 'orderedGroupsInCharge', 'orderedItemInitiators', 'powerAdvisersGroups', 'selectableCopyGroups', 'selectableAdvisers', 'usingGroups' ]: data = cData.get(field_name) try: data = [ org_id_to_uid(suffixed_group_id) for suffixed_group_id in data if org_id_to_uid(suffixed_group_id, raise_on_error=False) ] except KeyError: logger.warning( 'Error while turning org ids to org uids for field_name {0}' .format(field_name)) data = [] cData[field_name] = data # manage customAdvisers, turn 'org' value from org id to uid ca = cData.get('customAdvisers') adapted_ca = [] for v in ca: new_value = v.copy() new_value['org'] = org_id_to_uid(new_value['org']) adapted_ca.append(new_value) cData['customAdvisers'] = adapted_ca # return if already exists if cData['id'] in self.tool.objectIds(): logger.info( 'A MeetingConfig with id {0} already exists, passing...'. format(cData['id'])) return self.tool.invokeFactory('MeetingConfig', **cData) cfgId = configData.id cfg = getattr(self.tool, cfgId) cfg._at_creation_flag = True # for tests where config id is shuffled, save the real id if "__real_id__" in cData: cfg.__real_id__ = cData["__real_id__"] # TextArea fields are not set properly. for field in cfg.Schema().fields(): fieldName = field.getName() widgetName = field.widget.getName() if (widgetName == 'TextAreaWidget') and fieldName in cData: field.set(cfg, cData[fieldName], mimetype='text/html') # call processForm passing dummy values so existing values are not touched cfg.processForm(values={'dummy': None}) # Validates meeting config (validation seems not to be triggered # automatically when an object is created from code). errors = [] for field in cfg.Schema().fields(): error = field.validate(cfg.getField(field.getName()).get(cfg), cfg) if error: errors.append("'%s': %s" % (field.getName(), error)) if errors: raise PloneMeetingError( MEETING_CONFIG_ERROR % (safe_unicode(cfg.Title()), cfg.getId(), u'\n'.join(errors))) if not configData.active: self.portal.portal_wokflow.doActionFor(cfg, 'deactivate') # Adds the sub-objects within the config: categories, classifiers, items in config, ... for descr in configData.categories: self.addCategory(cfg, descr) for descr in configData.classifiers: self.addCategory(cfg, descr, classifier=True) for descr in configData.recurringItems: self.addItemToConfig(cfg, descr) for descr in configData.itemTemplates: self.addItemToConfig(cfg, descr, isRecurring=False) # configure ContentCategoryGroups before adding annex_types # this will enable confidentiality, to_sign/signed, ... if necessary for category_group_id, attrs in configData.category_group_activated_attrs.items( ): category_group = cfg.annexes_types.get(category_group_id) for attr in attrs: if not hasattr(category_group, attr): raise PloneMeetingError( 'Attribute {0} does not exist on {1} of {2}'.format( attr, category_group_id, cfgId)) setattr(category_group, attr, True) for descr in configData.annexTypes: self.addAnnexType(cfg, descr, source) # first create style templates so it exist before being used by a pod template for descr in configData.styleTemplates: self.addPodTemplate(cfg, descr, source) for descr in configData.podTemplates: self.addPodTemplate(cfg, descr, source) # manage MeetingManagers groupsTool = self.portal.portal_groups for userId in configData.meetingManagers: groupsTool.addPrincipalToGroup( userId, '{0}_{1}'.format(cfg.getId(), MEETINGMANAGERS_GROUP_SUFFIX)) # manage annex confidentiality, enable it on relevant CategoryGroup if configData.itemAnnexConfidentialVisibleFor: cfg.annexes_types.item_annexes.confidentiality_activated = True cfg.annexes_types.item_decision_annexes.confidentiality_activated = True if configData.adviceAnnexConfidentialVisibleFor: cfg.annexes_types.advice_annexes.confidentiality_activated = True if configData.meetingAnnexConfidentialVisibleFor: cfg.annexes_types.meeting_annexes.confidentiality_activated = True return cfg
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
def test_LateExtraCollege(self): """When an item is presented into a Council meeting and is coming from a College item that is presented to a College meeting, the listType used is not 'late' but 'lateextracollege'.""" cfg = self.meetingConfig cfgId = cfg.getId() cfg2 = self.meetingConfig2 cfg2Id = cfg2.getId() # items will be immediatelly presented to the Council meeting while sent self.setupCollegeConfig() cfg.setItemAutoSentToOtherMCStates(('itemfrozen', )) # create 2 College meetings, one extraordinarySession and one normal session # then send an item from each to a Council meeting self.changeUser('pmManager') # create the Council meeting self.setMeetingConfig(cfg2Id) self.setupCouncilConfig() councilMeeting = self.create('Meeting', date=DateTime('2017/01/01')) self.freezeMeeting(councilMeeting) # create elements in College self.setMeetingConfig(cfgId) collegeMeeting1 = self.create('Meeting', date=DateTime('2016/12/15')) item1 = self.create('MeetingItem') item1.setDecision(self.decisionText) item1.setOtherMeetingConfigsClonableTo((cfg2Id, )) gic2_uid = org_id_to_uid('groupincharge2') dev_group_in_charge = '{0}__groupincharge__{1}'.format( self.developers_uid, gic2_uid) item1.setProposingGroupWithGroupInCharge(dev_group_in_charge) self.presentItem(item1) self.freezeMeeting(collegeMeeting1) collegeMeeting2 = self.create('Meeting', date=DateTime('2016/12/20')) collegeMeeting2.setExtraordinarySession(True) item2 = self.create('MeetingItem') item2.setDecision(self.decisionText) item2.setOtherMeetingConfigsClonableTo((cfg2Id, )) item2.setProposingGroupWithGroupInCharge(dev_group_in_charge) self.presentItem(item2) self.freezeMeeting(collegeMeeting2) # now in the council, present the new items self.setCurrentMeeting(councilMeeting) itemFromExtraSession = item2.getItemClonedToOtherMC(cfg2Id) itemFromExtraSession.setPreferredMeeting(councilMeeting.UID()) itemFromExtraSession.setCategory('deployment') communicationitem = itemFromExtraSession.clone() communicationitem.setCategory(COMMUNICATION_CAT_ID) self.presentItem(itemFromExtraSession) self.assertEqual(itemFromExtraSession.getListType(), 'lateextracollege') self.presentItem(communicationitem) self.assertNotEqual(communicationitem.getListType(), 'lateextracollege') itemNotFromExtraSession = item1.getItemClonedToOtherMC(cfg2Id) itemNotFromExtraSession.setPreferredMeeting(councilMeeting.UID()) itemNotFromExtraSession.setCategory('deployment') self.presentItem(itemNotFromExtraSession) self.assertEqual(itemNotFromExtraSession.getListType(), 'late') # items are inserted following listType and listType 'lateextracollege' # will be after 'late' self.assertEqual([ item.getListType() for item in councilMeeting.getItems(ordered=True) ], ['late', 'lateextracollege', 'communication'])
def finance_group_uid(raise_on_error=False): """ """ return org_id_to_uid(FINANCE_GROUP_ID, raise_on_error=raise_on_error)
def test_ListTypeCommunication(self): self.setupCollegeConfig() self.create('meetingcategory', id='%ss' % COMMUNICATION_CAT_ID, title='Communications') self.changeUser('pmManager') collegeMeeting = self.create('Meeting', date=DateTime('2016/12/15')) item1 = self.create('MeetingItem') gic2_uid = org_id_to_uid('groupincharge2') dev_group_in_charge = '{0}__groupincharge__{1}'.format( self.developers_uid, gic2_uid) item1.setProposingGroupWithGroupInCharge(dev_group_in_charge) self.presentItem(item1) item2 = self.create('MeetingItem', category=COMMUNICATION_CAT_ID) item2.setProposingGroupWithGroupInCharge(dev_group_in_charge) self.presentItem(item2) self.freezeMeeting(collegeMeeting) item3 = self.create('MeetingItem', category='%ss' % COMMUNICATION_CAT_ID, preferredMeeting=collegeMeeting.UID()) item3.setProposingGroupWithGroupInCharge(dev_group_in_charge) self.presentItem(item3) item4 = self.create('MeetingItem') item4.setProposingGroupWithGroupInCharge(dev_group_in_charge) self.presentItem(item4) listTypes = set([ item.getListType() for item in collegeMeeting.getItems(ordered=True) ]) self.assertSetEqual(listTypes, {'late', 'normal'}) self.setMeetingConfig(self.meetingConfig2.getId()) self.setupCouncilConfig() self.create('meetingcategory', id='%ss' % COMMUNICATION_CAT_ID, title='Communications') councilMeeting = self.create('Meeting', date=DateTime('2017/01/01')) self.setCurrentMeeting(councilMeeting) self.changeUser('pmManager') item1 = self.create('MeetingItem') item1.setProposingGroupWithGroupInCharge(dev_group_in_charge) self.presentItem(item1) item2 = self.create('MeetingItem', category=COMMUNICATION_CAT_ID) item2.setProposingGroupWithGroupInCharge(dev_group_in_charge) self.presentItem(item2) self.assertEqual(item2.getListType(), 'communication') self.freezeMeeting(councilMeeting) item3 = self.create('MeetingItem', category='%ss' % COMMUNICATION_CAT_ID, preferredMeeting=councilMeeting.UID()) item3.setProposingGroupWithGroupInCharge(dev_group_in_charge) self.presentItem(item3) self.assertEqual(item3.getListType(), 'communication') item4 = self.create('MeetingItem', preferredMeeting=councilMeeting.UID()) item4.setProposingGroupWithGroupInCharge(dev_group_in_charge) self.presentItem(item4) self.assertEqual([ item.getListType() for item in councilMeeting.getItems(ordered=True) ], ['normal', 'late', 'communication', 'communication'])
def test_GetPrintableItemsForAgenda(self): ''' Return the items for agenda. ''' return pm = api.portal.get_tool('portal_plonemeeting') self.changeUser('admin') # make categories available self.meetingConfig.setUseGroupsAsCategories(False) self._setupPoliceGroup() # find groups in charge within meeting groups. for group in pm.getMeetingGroups(): groupId = group.getId() if groupId == 'groupincharge1': gic1 = group elif groupId == 'groupincharge2': gic2 = group # get the categories needed to complete the tests. develCat = self.meetingConfig.categories.get('development') eventsCat = self.meetingConfig.categories.get('events') researchCat = self.meetingConfig.categories.get('research') commuCat = self.meetingConfig.categories.get('communication') self.changeUser('pmManager') meeting = self._createMeetingWithItems() # switch to council self.setMeetingConfig(self.meetingConfig2.getId()) meetingCouncil = self._createMeetingWithItems(withItems=False, meetingDate=DateTime() + 1) meetingCouncil2 = self._createMeetingWithItems(withItems=False, meetingDate=DateTime() + 30) meetingCouncilUID = meetingCouncil.UID() meetingCouncilUID2 = meetingCouncil2.UID() self.setMeetingConfig(self.meetingConfig.getId()) # item late itemLate = self.create('MeetingItem') itemLate.setProposingGroup(self.vendors_uid) itemLate.setAssociatedGroups((self.developers_uid, )) itemLate.setCategory('research') itemLate.setListType('late') self.presentItem(itemLate) # item depose itemDepo = self.create('MeetingItem') itemDepo.setProposingGroup(self.vendors_uid) itemDepo.setAssociatedGroups((self.developers_uid, )) itemDepo.setCategory('research') self.presentItem(itemDepo) itemDepo.setListType('depose') # item council "emergency" to next meeting itemNextCouncil = self.create('MeetingItem') itemNextCouncil.setProposingGroup(self.vendors_uid) itemNextCouncil.setAssociatedGroups((self.developers_uid, )) itemNextCouncil.setCategory('research') itemNextCouncil.setOtherMeetingConfigsClonableTo( u'meeting-config-council') itemNextCouncil.setPreferredMeeting(meetingCouncilUID) self.presentItem(itemNextCouncil) # item council "emergency" to next meeting late itemNCLate = self.create('MeetingItem') itemNCLate.setProposingGroup(self.vendors_uid) itemNCLate.setAssociatedGroups((self.developers_uid, )) itemNCLate.setCategory('research') itemNCLate.setOtherMeetingConfigsClonableTo(u'meeting-config-council') itemNCLate.setPreferredMeeting(meetingCouncilUID) itemNCLate.setListType('late') self.presentItem(itemNCLate) # item council "emergency" to next meeting depose itemNCDepose = self.create('MeetingItem') itemNCDepose.setProposingGroup(self.vendors_uid) itemNCDepose.setAssociatedGroups((self.developers_uid, )) itemNCDepose.setCategory('research') itemNCDepose.setOtherMeetingConfigsClonableTo( u'meeting-config-council') itemNCDepose.setPreferredMeeting(meetingCouncilUID) itemNCDepose.setListType('depose') self.presentItem(itemNCDepose) # item council to next month meeting itemNextMonthCouncil = self.create('MeetingItem') itemNextMonthCouncil.setProposingGroup(self.vendors_uid) itemNextMonthCouncil.setAssociatedGroups((self.developers_uid, )) itemNextMonthCouncil.setCategory('research') itemNextMonthCouncil.setOtherMeetingConfigsClonableTo( u'meeting-config-council') itemNextMonthCouncil.setPreferredMeeting(meetingCouncilUID2) self.presentItem(itemNextMonthCouncil) # item council to next month meeting late itemNMCLate = self.create('MeetingItem') itemNMCLate.setProposingGroup(self.vendors_uid) itemNMCLate.setAssociatedGroups((self.developers_uid, )) itemNMCLate.setCategory('research') itemNMCLate.setOtherMeetingConfigsClonableTo(u'meeting-config-council') itemNMCLate.setPreferredMeeting(meetingCouncilUID2) itemNMCLate.setListType('late') self.presentItem(itemNMCLate) # item council to next month meeting depose itemNMCDepose = self.create('MeetingItem') itemNMCDepose.setProposingGroup(self.vendors_uid) itemNMCDepose.setAssociatedGroups((self.developers_uid, )) itemNMCDepose.setCategory('research') itemNMCDepose.setOtherMeetingConfigsClonableTo( u'meeting-config-council') itemNMCDepose.setPreferredMeeting(meetingCouncilUID2) itemNMCDepose.setListType('depose') self.presentItem(itemNMCDepose) orderedItems = meeting.getItems(listTypes=['normal', 'late', 'depose'], ordered=True) item1 = orderedItems[0] item2 = orderedItems[1] item3 = orderedItems[2] item3.setOtherMeetingConfigsClonableTo(u'meeting-config-council') item4 = orderedItems[3] item4.setOtherMeetingConfigsClonableTo(u'meeting-config-council') item5 = orderedItems[4] item5.setCategory('communication') itemUids = [item.UID() for item in orderedItems] # Prescriptive items (normal, late and depose) standardPrescriItems = meeting.adapted().getPrintableItemsForAgenda( itemUids, standard=True, itemType='prescriptive') standardLateItems = meeting.adapted().getPrintableItemsForAgenda( itemUids, standard=True, listTypes='late', itemType='prescriptive') standardDeposeItems = meeting.adapted().getPrintableItemsForAgenda( itemUids, standard=True, listTypes='depose', itemType='prescriptive') # To council items (normal, late and depose) standardCouncilItems = meeting.adapted().getPrintableItemsForAgenda( itemUids, standard=True, itemType='toCouncil') standardCouncilLateItems = meeting.adapted( ).getPrintableItemsForAgenda(itemUids, standard=True, itemType='toCouncil', listTypes='late') standardCouncilDeposeItems = meeting.adapted( ).getPrintableItemsForAgenda(itemUids, standard=True, itemType='toCouncil', listTypes='depose') # Communication items standardCommuItems = meeting.adapted().getPrintableItemsForAgenda( itemUids, standard=True, itemType='communication') self.assertEqual(len(standardPrescriItems[gic2][develCat]), 1) self.assertEqual(standardPrescriItems[gic2][develCat][0], item1) self.assertEqual(len(standardPrescriItems[gic2][eventsCat]), 1) self.assertEqual(standardPrescriItems[gic2][eventsCat][0], item2) self.assertEqual( len(standardCouncilItems[meetingCouncil][gic1][develCat]), 1) self.assertEqual( standardCouncilItems[meetingCouncil][gic1][develCat][0], item4) self.assertEqual( len(standardCouncilItems[meetingCouncil][gic1][researchCat]), 1) self.assertEqual( standardCouncilItems[meetingCouncil][gic1][researchCat][0], item3) self.assertEqual(standardCommuItems[0][0], commuCat) self.assertEqual(standardCommuItems[0][1], item5) self.assertEqual(len(standardLateItems[gic1][researchCat]), 1) self.assertEqual(standardLateItems[gic1][researchCat][0], itemLate) self.assertEqual(len(standardDeposeItems[gic1][researchCat]), 1) self.assertEqual(standardDeposeItems[gic1][researchCat][0], itemDepo) # self.assertEqual(len(standardEmergencyItems[gic1][researchCat]), 1) # self.assertEqual(standardEmergencyItems[gic1][researchCat][0], itemEmer) # self.assertEqual(len(standardComplItems[gic1][researchCat]), 1) # self.assertEqual(standardComplItems[gic1][researchCat][0], itemCompl) # Every item in the meeting is now from the police group for item in meeting.getItems(listTypes=['normal', 'late', 'depose']): item.setProposingGroup(org_id_to_uid(POLICE_GROUP_PREFIX)) # Police prescriptive items (normal, late and depose) policePrescriItems = meeting.adapted().getPrintableItemsForAgenda( itemUids, standard=False, itemType='prescriptive') policeLateItems = meeting.adapted().getPrintableItemsForAgenda( itemUids, standard=False, listTypes=['late'], itemType='prescriptive') policeDeposeItems = meeting.adapted().getPrintableItemsForAgenda( itemUids, standard=False, listTypes=['depose'], itemType='prescriptive') # Police to council items (normal, emergency and # complementary(emergency+late)) policeCouncilItems = meeting.adapted().getPrintableItemsForAgenda( itemUids, standard=False, itemType='toCouncil') policeEmergencyItems = meeting.adapted().getPrintableItemsForAgenda( itemUids, standard=False, itemType='toCouncil') policeComplItems = meeting.adapted().getPrintableItemsForAgenda( itemUids, standard=False, itemType='toCouncil', listTypes=['late']) # Police communication items policeCommuItems = meeting.adapted().getPrintableItemsForAgenda( itemUids, standard=False, itemType='communication') self.assertEqual(len(policePrescriItems[gic1][develCat]), 1) self.assertEqual(policePrescriItems[gic1][develCat][0], item1) self.assertEqual(len(policePrescriItems[gic1][eventsCat]), 1) self.assertEqual(policePrescriItems[gic1][eventsCat][0], item2) self.assertEqual(len(policeCouncilItems[gic1][develCat]), 1) self.assertEqual(policeCouncilItems[gic1][develCat][0], item4) self.assertEqual(len(policeCouncilItems[gic1][researchCat]), 1) self.assertEqual(policeCouncilItems[gic1][researchCat][0], item3) self.assertEqual(policeCommuItems[0][0], commuCat) self.assertEqual(policeCommuItems[0][1], item5) self.assertEqual(len(policeLateItems[gic1][researchCat]), 1) self.assertEqual(policeLateItems[gic1][researchCat][0], itemLate) self.assertEqual(len(policeDeposeItems[gic1][researchCat]), 1) self.assertEqual(policeDeposeItems[gic1][researchCat][0], itemDepo) self.assertEqual(len(policeEmergencyItems[gic1][researchCat]), 1) self.assertEqual(policeEmergencyItems[gic1][researchCat][0], itemEmer) self.assertEqual(len(policeComplItems[gic1][researchCat]), 1) self.assertEqual(policeComplItems[gic1][researchCat][0], itemCompl)
def bg_group_uid(raise_on_error=False): """ """ return org_id_to_uid(BOURGMESTRE_GROUP_ID, raise_on_error=raise_on_error)
def _hook_after_mgroups_to_orgs(self): """Migrate attributes that were using MeetingGroups : - MeetingConfig.archivingRefs.restrict_to_groups; - MeetingCategory.groupsInCharge; - MeetingItem.financeAdvice. Remove every users from _observers Plone groups. Then manage copyGroups and powerObservers at the end.""" logger.info("Adapting organizations...") own_org = get_own_organization() own_org_ids = own_org.objectIds() for cfg in self.tool.objectValues('MeetingConfig'): # MeetingConfig.archivingRefs archivingRefs = deepcopy(cfg.getArchivingRefs()) migratedArchivingRefs = [] for archivingRef in archivingRefs: migratedArchivingRef = archivingRef.copy() migratedArchivingRef['restrict_to_groups'] = [ org_id_to_uid(mGroupId) for mGroupId in migratedArchivingRef['restrict_to_groups'] if mGroupId in own_org_ids] migratedArchivingRefs.append(migratedArchivingRef) cfg.setArchivingRefs(migratedArchivingRefs) # MeetingCategory.groupsInCharge for category in cfg.getCategories(onlySelectable=False, caching=False): groupsInCharge = category.getGroupsInCharge() migratedGroupsInCharge = [org_id_to_uid(mGroupId) for mGroupId in groupsInCharge] category.setGroupsInCharge(migratedGroupsInCharge) own_org = get_own_organization() for brain in self.portal.portal_catalog(meta_type='MeetingItem'): item = brain.getObject() financeAdvice = item.getFinanceAdvice() if financeAdvice != '_none_': finance_org_uid = own_org.get(financeAdvice).UID() item.setFinanceAdvice(finance_org_uid) # remove users from Plone groups ending with _observers logger.info('Removing every users from observers groups...') pGroups = api.group.get_groups() for pGroup in pGroups: if pGroup.getId().endswith('_observers'): for member_id in pGroup.getMemberIds(): api.group.remove_user(group=pGroup, username=member_id) # migrate copyGroups : # - adapt configuration, use _copygroup instead _observers # - adapt copyGroups on every items (including item templates) logger.info("Adapting copyGroups...") for cfg in self.tool.objectValues('MeetingConfig'): selectableCopyGroups = cfg.getSelectableCopyGroups() patched_selectableCopyGroups = [ copyGroup.replace('_observers', '_incopy') for copyGroup in selectableCopyGroups] cfg.setSelectableCopyGroups(patched_selectableCopyGroups) for brain in self.portal.portal_catalog(meta_type='MeetingItem'): item = brain.getObject() copyGroups = item.getCopyGroups() patched_copyGroups = [copyGroup.replace('_observers', '_incopy') for copyGroup in copyGroups] item.setCopyGroups(patched_copyGroups) # configure powerobsevers logger.info("Adapting powerObservers...") for cfg in self.tool.objectValues('MeetingConfig'): power_observers = deepcopy(cfg.getPowerObservers()) if len(power_observers) == 2: if cfg.getId() in ['meeting-config-college', 'meeting-config-council']: cfg.setPowerObservers(deepcopy(collegeMeeting.powerObservers)) elif cfg.getId() in ['meeting-config-bourgmestre']: cfg.setPowerObservers(deepcopy(bourgmestreMeeting.powerObservers)) cfg._createOrUpdateAllPloneGroups(force_update_access=True)
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')
properties, member) if failMessage is not None: raise BadRequest(failMessage) member.setMemberProperties(properties) out.append("User '%s' is added" % row_id) else: out.append("User %s already exists" % row_id) # attribute roles group_title = safe_unicode(row['grouptitle']) org_id = normalizeString(group_title, self) for organization in ORGANIZATIONS: if normalized_org_titles_equals(organization.Title(), group_title): org_id = organization.id org_uid = org_id_to_uid(org_id) plone_groups = [] if row['observers']: plone_groups.append(org_uid + '_observers') if row['creators']: plone_groups.append(org_uid + '_creators') if row['level1reviewers']: plone_groups.append(org_uid + '_level1reviewers') if row['level2reviewers']: plone_groups.append(org_uid + '_level2reviewers') if row['level3reviewers']: plone_groups.append(org_uid + '_level3reviewers') if row['level4reviewers']: plone_groups.append(org_uid + '_level4reviewers') if row['advisers']:
def treasury_group_cec_uid(raise_on_error=False): """ """ return org_id_to_uid(TREASURY_GROUP_ID, raise_on_error=raise_on_error)
def _demoData(site, userId, firstTwoGroupIds, dates=[], baseDate=None, templateId='template5'): """ """ wfTool = api.portal.get_tool('portal_workflow') tool = api.portal.get_tool('portal_plonemeeting') cfg1 = tool.objectValues('MeetingConfig')[0] cfg1_id = cfg1.getId() cfg2 = tool.objectValues('MeetingConfig')[1] cfg2_id = cfg2.getId() def _add_finance_advice(item, newItem, last_transition): if item['toDiscuss'] and \ item['category'] in ['affaires-juridiques', 'remboursement'] and \ last_transition == 'prevalidate': finance_group = finance_group_uid() if finance_group: finance_advice_id = '{0}__rowid__unique_id_002'.format( finance_group) optional_advisers = get_vocab( newItem, 'Products.PloneMeeting.vocabularies.itemoptionaladvicesvocabulary' ) if finance_advice_id not in optional_advisers: _memos.clear() finance_group = finance_group_uid() finance_advice_id = '{0}__rowid__unique_id_002'.format( finance_group) newItem.setOptionalAdvisers((finance_advice_id, )) newItem.updateLocalRoles() wfTool.doActionFor(newItem, 'wait_advices_from_prevalidated') newItem.setCompleteness('completeness_complete') newItem.updateLocalRoles() with api.env.adopt_user('dfin'): advice = createContentInContainer( newItem, 'meetingadvicefinances', **{ 'advice_group': finance_group, 'advice_type': u'positive_finance', 'advice_comment': RichTextValue(u'Mon commentaire') }) wfTool.doActionFor(advice, 'proposeToFinancialEditor') wfTool.doActionFor(advice, 'proposeToFinancialReviewer') wfTool.doActionFor(advice, 'proposeToFinancialManager') wfTool.doActionFor(advice, 'signFinancialAdvice') return True return False tool = api.portal.get_tool('portal_plonemeeting') 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') # create 5 meetings : 2 passed, 1 current and 2 future if not dates: baseDate = DateTime() dates = [ baseDate - 13, baseDate - 6, baseDate + 1, baseDate + 8, baseDate + 15 ] mTool.createMemberArea(userId) secrFolder = tool.getPloneMeetingFolder(cfg1_id, userId) for date in dates: meetingId = secrFolder.invokeFactory('MeetingCollege', id=date.strftime('%Y%m%d')) meeting = getattr(secrFolder, meetingId) meeting.setDate(date) pTool.changeOwnershipOf(meeting, userId) meeting.processForm() # -13 meeting is closed if date == baseDate - 13: wfTool.doActionFor(meeting, 'freeze') wfTool.doActionFor(meeting, 'decide') wfTool.doActionFor(meeting, 'close') # -6 is meeting we will insert items into if date == baseDate - 6: meetingForItems = meeting # +1 is an extraordinary meeting we will insert extralate items into if date == baseDate + 1: meeting.setExtraordinarySession(True) meetingForExtraLateItems = meeting # 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 = ( # dirgen { 'templateId': templateId, 'title': u'Exemple point 1', 'proposingGroup': org_id_to_uid(firstTwoGroupIds[0]), 'category': COUNCIL_DEFAULT_CATEGORY, 'toDiscuss': True, 'otherMeetingConfigsClonableToEmergency': (), 'otherMeetingConfigsClonableToPrivacy': (cfg2_id, ), 'otherMeetingConfigsClonableTo': (cfg2_id, ) }, { 'templateId': templateId, 'title': u'Exemple point 2', 'proposingGroup': org_id_to_uid(firstTwoGroupIds[0]), 'category': COUNCIL_DEFAULT_CATEGORY, 'toDiscuss': True, 'otherMeetingConfigsClonableToEmergency': (), 'otherMeetingConfigsClonableToPrivacy': (), 'otherMeetingConfigsClonableTo': (cfg2_id, ) }, { 'templateId': templateId, 'title': u'Exemple point 3', 'proposingGroup': org_id_to_uid(firstTwoGroupIds[0]), 'category': 'remboursement', 'toDiscuss': True, 'otherMeetingConfigsClonableToEmergency': (), 'otherMeetingConfigsClonableToPrivacy': (), 'otherMeetingConfigsClonableTo': () }, { 'templateId': templateId, 'title': u'Exemple point 4', 'proposingGroup': org_id_to_uid(firstTwoGroupIds[0]), 'category': COUNCIL_DEFAULT_CATEGORY, 'toDiscuss': False, 'otherMeetingConfigsClonableToEmergency': (), 'otherMeetingConfigsClonableToPrivacy': (cfg2_id, ), 'otherMeetingConfigsClonableTo': (cfg2_id, ) }, { 'templateId': templateId, 'title': u'Exemple point 5', 'proposingGroup': org_id_to_uid(firstTwoGroupIds[0]), 'category': 'remboursement', 'toDiscuss': False, 'otherMeetingConfigsClonableToEmergency': (), 'otherMeetingConfigsClonableToPrivacy': (), 'otherMeetingConfigsClonableTo': () }, # conseil arret oj { 'templateId': templateId, 'title': u'Conseil Communal - OJ', 'proposingGroup': org_id_to_uid(firstTwoGroupIds[0]), 'category': CC_ARRET_OJ_CAT_ID, 'toDiscuss': True, 'otherMeetingConfigsClonableToEmergency': (), 'otherMeetingConfigsClonableToPrivacy': (), 'otherMeetingConfigsClonableTo': () }, # communication { 'templateId': templateId, 'title': u'Communication 1', 'proposingGroup': org_id_to_uid(firstTwoGroupIds[0]), 'category': COMMUNICATION_CAT_ID, 'toDiscuss': True, 'otherMeetingConfigsClonableToEmergency': (), 'otherMeetingConfigsClonableToPrivacy': (), 'otherMeetingConfigsClonableTo': () }, { 'templateId': templateId, 'title': u'Communication 2', 'proposingGroup': org_id_to_uid(firstTwoGroupIds[0]), 'category': COMMUNICATION_CAT_ID, 'toDiscuss': True, 'otherMeetingConfigsClonableToEmergency': (), 'otherMeetingConfigsClonableToPrivacy': (), 'otherMeetingConfigsClonableTo': () }, { 'templateId': templateId, 'title': u'Communication 3', 'proposingGroup': org_id_to_uid(firstTwoGroupIds[0]), 'category': COMMUNICATION_CAT_ID, 'toDiscuss': True, 'otherMeetingConfigsClonableToEmergency': (), 'otherMeetingConfigsClonableToPrivacy': (), 'otherMeetingConfigsClonableTo': () }, # personnel { 'templateId': templateId, 'title': u'Exemple point 6', 'proposingGroup': org_id_to_uid(firstTwoGroupIds[1]), 'category': COUNCIL_DEFAULT_CATEGORY, 'toDiscuss': True, 'otherMeetingConfigsClonableToEmergency': (), 'otherMeetingConfigsClonableToPrivacy': (), 'otherMeetingConfigsClonableTo': (cfg2_id, ) }, { 'templateId': templateId, 'title': u'Exemple point 7', 'proposingGroup': org_id_to_uid(firstTwoGroupIds[1]), 'category': COUNCIL_DEFAULT_CATEGORY, 'toDiscuss': True, 'otherMeetingConfigsClonableToEmergency': (), 'otherMeetingConfigsClonableToPrivacy': (), 'otherMeetingConfigsClonableTo': (cfg2_id, ) }, { 'templateId': templateId, 'title': u'Exemple point 8', 'proposingGroup': org_id_to_uid(firstTwoGroupIds[1]), 'category': 'remboursement', 'toDiscuss': True, 'otherMeetingConfigsClonableToEmergency': (), 'otherMeetingConfigsClonableToPrivacy': (), 'otherMeetingConfigsClonableTo': () }, { 'templateId': templateId, 'title': u'Exemple point 9', 'proposingGroup': org_id_to_uid(firstTwoGroupIds[1]), 'category': COUNCIL_DEFAULT_CATEGORY, 'toDiscuss': False, 'otherMeetingConfigsClonableToEmergency': (), 'otherMeetingConfigsClonableToPrivacy': (cfg2_id, ), 'otherMeetingConfigsClonableTo': (cfg2_id, ) }, { 'templateId': templateId, 'title': u'Exemple point 10', 'proposingGroup': org_id_to_uid(firstTwoGroupIds[1]), 'category': 'remboursement', 'toDiscuss': False, 'otherMeetingConfigsClonableToEmergency': (), 'otherMeetingConfigsClonableToPrivacy': (), 'otherMeetingConfigsClonableTo': () }, # police { 'templateId': templateId, 'title': u'Communication Police 1', 'proposingGroup': org_id_to_uid(POLICE_GROUP_PREFIX), 'category': COMMUNICATION_CAT_ID, 'toDiscuss': True, 'otherMeetingConfigsClonableToEmergency': (), 'otherMeetingConfigsClonableToPrivacy': (), 'otherMeetingConfigsClonableTo': () }, { 'templateId': templateId, 'title': u'Communication Police 2', 'proposingGroup': org_id_to_uid(POLICE_GROUP_PREFIX + '-compta'), 'category': COMMUNICATION_CAT_ID, 'toDiscuss': True, 'otherMeetingConfigsClonableToEmergency': (), 'otherMeetingConfigsClonableToPrivacy': (), 'otherMeetingConfigsClonableTo': () }, { 'templateId': templateId, 'title': u'Communication Police 3', 'proposingGroup': org_id_to_uid(POLICE_GROUP_PREFIX), 'category': COMMUNICATION_CAT_ID, 'toDiscuss': True, 'otherMeetingConfigsClonableToEmergency': (), 'otherMeetingConfigsClonableToPrivacy': (), 'otherMeetingConfigsClonableTo': () }, { 'templateId': templateId, 'title': u'Exemple point 11', 'proposingGroup': org_id_to_uid(POLICE_GROUP_PREFIX), 'category': COUNCIL_DEFAULT_CATEGORY, 'toDiscuss': True, 'otherMeetingConfigsClonableToEmergency': (), 'otherMeetingConfigsClonableToPrivacy': (), 'otherMeetingConfigsClonableTo': (cfg2_id, ) }, { 'templateId': templateId, 'title': u'Exemple point 12', 'proposingGroup': org_id_to_uid(POLICE_GROUP_PREFIX + '-compta'), 'category': COUNCIL_DEFAULT_CATEGORY, 'toDiscuss': True, 'otherMeetingConfigsClonableToEmergency': (), 'otherMeetingConfigsClonableToPrivacy': (cfg2_id, ), 'otherMeetingConfigsClonableTo': (cfg2_id, ) }, { 'templateId': templateId, 'title': u'Exemple point 13', 'proposingGroup': org_id_to_uid(POLICE_GROUP_PREFIX), 'category': 'remboursement', 'toDiscuss': True, 'otherMeetingConfigsClonableToEmergency': (), 'otherMeetingConfigsClonableToPrivacy': (), 'otherMeetingConfigsClonableTo': () }, { 'templateId': templateId, 'title': u'Exemple point 14', 'proposingGroup': org_id_to_uid(POLICE_GROUP_PREFIX + '-compta'), 'category': COUNCIL_DEFAULT_CATEGORY, 'toDiscuss': False, 'otherMeetingConfigsClonableToEmergency': (), 'otherMeetingConfigsClonableToPrivacy': (cfg2_id, ), 'otherMeetingConfigsClonableTo': (cfg2_id, ) }, { 'templateId': templateId, 'title': u'Exemple point 15', 'proposingGroup': org_id_to_uid(POLICE_GROUP_PREFIX), 'category': 'remboursement', 'toDiscuss': False, 'otherMeetingConfigsClonableToEmergency': (), 'otherMeetingConfigsClonableToPrivacy': (), 'otherMeetingConfigsClonableTo': () }, { 'templateId': templateId, 'title': u'Point Emergency Conseil Police', 'proposingGroup': org_id_to_uid(POLICE_GROUP_PREFIX), 'category': COUNCIL_DEFAULT_CATEGORY, 'toDiscuss': False, 'otherMeetingConfigsClonableToEmergency': (cfg2_id, ), 'otherMeetingConfigsClonableToPrivacy': (), 'otherMeetingConfigsClonableTo': (cfg2_id, ) }, { 'templateId': templateId, 'title': u'Point Emergency Conseil Normal', 'proposingGroup': org_id_to_uid(firstTwoGroupIds[0]), 'category': COUNCIL_DEFAULT_CATEGORY, 'toDiscuss': True, 'otherMeetingConfigsClonableToEmergency': (cfg2_id, ), 'otherMeetingConfigsClonableToPrivacy': (), 'otherMeetingConfigsClonableTo': (cfg2_id, ) }, ) lateItems = ( # dirgen { 'templateId': templateId, 'title': u'Point urgent 1', 'proposingGroup': org_id_to_uid(firstTwoGroupIds[0]), 'category': COUNCIL_DEFAULT_CATEGORY, 'toDiscuss': True, 'otherMeetingConfigsClonableToEmergency': (), 'otherMeetingConfigsClonableToPrivacy': (), 'otherMeetingConfigsClonableTo': (cfg2_id, ), 'bourgmestreObservations': u'Observation Bourgmestre Point urgent 1' }, { 'templateId': templateId, 'title': u'Point urgent 2', 'proposingGroup': org_id_to_uid(firstTwoGroupIds[0]), 'category': COUNCIL_DEFAULT_CATEGORY, 'toDiscuss': True, 'otherMeetingConfigsClonableToEmergency': (), 'otherMeetingConfigsClonableToPrivacy': (cfg2_id, ), 'otherMeetingConfigsClonableTo': (cfg2_id, ) }, # police { 'templateId': templateId, 'title': u'Point urgent Police 1', 'proposingGroup': org_id_to_uid(POLICE_GROUP_PREFIX), 'category': COUNCIL_DEFAULT_CATEGORY, 'toDiscuss': True, 'otherMeetingConfigsClonableToEmergency': (), 'otherMeetingConfigsClonableToPrivacy': (), 'otherMeetingConfigsClonableTo': (cfg2_id, ) }, { 'templateId': templateId, 'title': u'Point urgent Police 2', 'proposingGroup': org_id_to_uid(POLICE_GROUP_PREFIX + '-compta'), 'category': COUNCIL_DEFAULT_CATEGORY, 'toDiscuss': True, 'otherMeetingConfigsClonableToEmergency': (), 'otherMeetingConfigsClonableToPrivacy': (cfg2_id, ), 'otherMeetingConfigsClonableTo': (cfg2_id, ) }, { 'templateId': templateId, 'title': u'Point urgent Police 3', 'proposingGroup': org_id_to_uid(POLICE_GROUP_PREFIX + '-compta'), 'category': 'remboursement', 'toDiscuss': True, 'otherMeetingConfigsClonableToEmergency': (), 'otherMeetingConfigsClonableToPrivacy': (), 'otherMeetingConfigsClonableTo': () }, { 'templateId': templateId, 'title': u'Point urgent Police 4', 'proposingGroup': org_id_to_uid(POLICE_GROUP_PREFIX), 'category': COUNCIL_DEFAULT_CATEGORY, 'toDiscuss': False, 'otherMeetingConfigsClonableToEmergency': (), 'otherMeetingConfigsClonableToPrivacy': (), 'otherMeetingConfigsClonableTo': (cfg2_id, ) }, { 'templateId': templateId, 'title': u'Point urgent Police 5', 'proposingGroup': org_id_to_uid(POLICE_GROUP_PREFIX), 'category': 'remboursement', 'toDiscuss': False, 'otherMeetingConfigsClonableToEmergency': (), 'otherMeetingConfigsClonableToPrivacy': (), 'otherMeetingConfigsClonableTo': () }, { 'templateId': templateId, 'title': u'Exemple point 5', 'proposingGroup': org_id_to_uid(firstTwoGroupIds[1]), 'category': 'remboursement', 'toDiscuss': False, 'otherMeetingConfigsClonableToEmergency': (), 'otherMeetingConfigsClonableToPrivacy': (), 'otherMeetingConfigsClonableTo': () }, { 'templateId': templateId, 'title': u'Exemple point 5', 'proposingGroup': org_id_to_uid(firstTwoGroupIds[1]), 'category': 'remboursement', 'toDiscuss': False, 'otherMeetingConfigsClonableToEmergency': (), 'otherMeetingConfigsClonableToPrivacy': (), 'otherMeetingConfigsClonableTo': () }, { 'templateId': templateId, 'title': u'Point Complementaire Conseil Police', 'proposingGroup': org_id_to_uid(POLICE_GROUP_PREFIX), 'category': COUNCIL_DEFAULT_CATEGORY, 'toDiscuss': False, 'otherMeetingConfigsClonableToEmergency': (cfg2_id, ), 'otherMeetingConfigsClonableToPrivacy': (), 'otherMeetingConfigsClonableTo': (cfg2_id, ) }, { 'templateId': templateId, 'title': u'Point Complementaire Conseil Normal', 'proposingGroup': org_id_to_uid(firstTwoGroupIds[0]), 'category': COUNCIL_DEFAULT_CATEGORY, 'toDiscuss': True, 'otherMeetingConfigsClonableToEmergency': (cfg2_id, ), 'otherMeetingConfigsClonableToPrivacy': (cfg2_id, ), 'otherMeetingConfigsClonableTo': (cfg2_id, ) }, ) deposeItems = ( { 'templateId': templateId, 'title': u'Point depose en séance standard', 'proposingGroup': org_id_to_uid(firstTwoGroupIds[1]), 'category': 'remboursement', 'toDiscuss': False, 'otherMeetingConfigsClonableToEmergency': (), 'otherMeetingConfigsClonableToPrivacy': (), 'otherMeetingConfigsClonableTo': () }, { 'templateId': templateId, 'title': u'Point depose Police', 'proposingGroup': org_id_to_uid(POLICE_GROUP_PREFIX), 'category': 'remboursement', 'toDiscuss': True, 'otherMeetingConfigsClonableToEmergency': (), 'otherMeetingConfigsClonableToPrivacy': (), 'otherMeetingConfigsClonableTo': () }, ) extraLateItems = ( { 'templateId': templateId, 'title': u'Point urgent séance extraordinaire 1', 'proposingGroup': org_id_to_uid(firstTwoGroupIds[1]), 'category': COUNCIL_DEFAULT_CATEGORY, 'toDiscuss': False, 'otherMeetingConfigsClonableToEmergency': (cfg2_id, ), 'otherMeetingConfigsClonableToPrivacy': (cfg2_id, ), 'otherMeetingConfigsClonableTo': (cfg2_id, ), 'bourgmestreObservations': u'Observation Bourgmestre Point urgent séance extraordinaire 1' }, { 'templateId': templateId, 'title': u'Point urgent Police séance extraordinaire 1', 'proposingGroup': org_id_to_uid(POLICE_GROUP_PREFIX), 'category': COUNCIL_DEFAULT_CATEGORY, 'toDiscuss': True, 'otherMeetingConfigsClonableToEmergency': (cfg2_id, ), 'otherMeetingConfigsClonableToPrivacy': (), 'otherMeetingConfigsClonableTo': (cfg2_id, ) }, ) userFolder = tool.getPloneMeetingFolder(cfg1_id, userId) for step in ('normal', 'late', 'depose', 'extra_late'): if step == 'late': wfTool.doActionFor(meetingForItems, 'freeze') items = lateItems elif step == 'depose': items = deposeItems elif step == 'extra_late': wfTool.doActionFor(meetingForExtraLateItems, 'freeze') items = extraLateItems for item in items: # get the template then clone it template = getattr( tool.getMeetingConfig(userFolder).itemtemplates, item['templateId']) newItem = template.clone(newOwnerId=userId, destFolder=userFolder, newPortalType=cfg1.getItemTypeName()) newItem.setOtherMeetingConfigsClonableToEmergency( item['otherMeetingConfigsClonableToEmergency']) newItem.setOtherMeetingConfigsClonableToPrivacy( item['otherMeetingConfigsClonableToPrivacy']) newItem.setTitle(item['title']) newItem.setProposingGroup(item['proposingGroup']) # manage MeetingItem.groupInCharge groupInCharge = newItem.getProposingGroup( theObject=True).get_groups_in_charge()[0] value = '{0}__groupincharge__{1}'.format( newItem.getProposingGroup(), groupInCharge) newItem.setProposingGroupWithGroupInCharge(value) newItem.setItemAssemblyExcused('Roger Bidon') newItem.setItemAssemblyAbsents('Jean-Michel Jamaila') newItem.setCategory(item['category']) newItem.setToDiscuss(item['toDiscuss']) newItem.setOtherMeetingConfigsClonableTo( item['otherMeetingConfigsClonableTo']) newItem.setPreferredMeeting(meetingForItems.UID()) newItem.reindexObject() if step == 'extra_late': site.REQUEST['PUBLISHED'] = meetingForExtraLateItems else: site.REQUEST['PUBLISHED'] = meetingForItems item_received_finances_advice = False for transition in cfg1.getTransitionsForPresentingAnItem(): if item_received_finances_advice and transition == 'validate': continue wfTool.doActionFor(newItem, transition) item_received_finances_advice = _add_finance_advice( item, newItem, transition) if step == 'depose': newItem.setListType('depose') newItem.reindexObject(idxs=['listType']) return meetingForItems, meetingForExtraLateItems
def hr_group_uid(raise_on_error=False): """ """ return org_id_to_uid(HR_CONFIDENTIAL_GROUP_ID, raise_on_error=raise_on_error)
def _addDemoData( site, # need 2 proposing_groups=['dirgen', 'secretariat'], # need 4 categories=[ u'assurances', u'autorites-provinciales', u'contentieux', u'intercommunales' ], # need 4 associated_groups=['ag1', 'ag2', 'ag3', 'ag4', 'ag5'], # need 5 groupsInCharge=[ 'dp-eric-massin', 'dp-fabienne-capot', 'dp-fabienne-devilers', 'dp-pascal-lafosse', 'dp-serge-hustache' ], userId='dgen'): """ """ items = ( { 'title': u'Exemple point 1', 'proposingGroup': proposing_groups[0], 'category': categories[0], 'associatedGroups': [associated_groups[0]], 'groupsInCharge': [groupsInCharge[0]], }, { 'title': u'Exemple point 2', 'proposingGroup': proposing_groups[0], 'category': categories[2], 'associatedGroups': [associated_groups[1]], 'groupsInCharge': [groupsInCharge[0]], }, { 'title': u'Exemple point 3', 'proposingGroup': proposing_groups[0], 'category': categories[1], 'associatedGroups': [associated_groups[0], associated_groups[1]], 'groupsInCharge': [groupsInCharge[1]], }, { 'title': u'Exemple point 4', 'proposingGroup': proposing_groups[1], 'category': categories[0], 'associatedGroups': [associated_groups[1]], 'groupsInCharge': [groupsInCharge[1]], }, { 'title': u'Exemple point 5', 'proposingGroup': proposing_groups[0], 'category': categories[2], 'associatedGroups': [associated_groups[1]], 'groupsInCharge': [groupsInCharge[2]], }, { 'title': u'Exemple point 6', 'proposingGroup': proposing_groups[1], 'category': categories[1], 'associatedGroups': [associated_groups[3]], 'groupsInCharge': [groupsInCharge[2]], }, { 'title': u'Exemple point 7', 'proposingGroup': proposing_groups[1], 'category': categories[1], 'associatedGroups': [], 'groupsInCharge': [groupsInCharge[0], groupsInCharge[2]], }, { 'title': u'Exemple point 8', 'proposingGroup': proposing_groups[0], 'category': categories[1], 'associatedGroups': [associated_groups[2]], 'groupsInCharge': [groupsInCharge[0]], }, { 'title': u'Exemple point 9', 'proposingGroup': proposing_groups[1], 'category': categories[3], 'associatedGroups': [associated_groups[0], associated_groups[2]], 'groupsInCharge': [groupsInCharge[3]], }, { 'title': u'Exemple point 10', 'proposingGroup': proposing_groups[0], 'category': categories[3], 'associatedGroups': [associated_groups[0], associated_groups[2]], 'groupsInCharge': [groupsInCharge[0], groupsInCharge[2], groupsInCharge[3]], }, { 'title': u'Exemple point 11', 'proposingGroup': proposing_groups[1], 'category': categories[0], 'associatedGroups': [associated_groups[2]], 'groupsInCharge': [groupsInCharge[0], groupsInCharge[4]], }, { 'title': u'Exemple point 12', 'proposingGroup': proposing_groups[0], 'category': categories[3], 'associatedGroups': [associated_groups[3]], 'groupsInCharge': [groupsInCharge[3]], }, ) # create a meeting and insert items # 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 mTool = api.portal.get_tool('portal_membership') wfTool = api.portal.get_tool('portal_workflow') tool = api.portal.get_tool('portal_plonemeeting') members = mTool.getMembersFolder() if members is None: _createObjectByType('Folder', site, id='Members') if not mTool.getMemberareaCreationFlag(): mTool.setMemberareaCreationFlag() mTool.createMemberArea(userId) # in tests, the MeetingConfig id is generated cfg1 = tool.objectValues('MeetingConfig')[0] cfg1_id = cfg1.getId() userFolder = tool.getPloneMeetingFolder(cfg1_id, userId) date = datetime.now() - timedelta(days=1) with api.env.adopt_user(userId): # avoid problems with cached methods when using adopt_user tool.invalidateAllCache() meeting = api.content.create(container=userFolder, type='MeetingZCollege', id=date.strftime('%Y%m%d'), date=date) i = 1 cfg = tool.getMeetingConfig(meeting) site.REQUEST['PUBLISHED'] = meeting for item in items: newItem = api.content.create( container=userFolder, type='MeetingItemZCollege', id=str(i), title=item['title'], proposingGroup=org_id_to_uid(item['proposingGroup']), category=item['category'], associatedGroups=[ org_id_to_uid(associatedGroup) for associatedGroup in item['associatedGroups'] ], groupsInCharge=[ org_id_to_uid(groupInCharge) for groupInCharge in item['groupsInCharge'] ], description=SAMPLE_TEXT, motivation=SAMPLE_TEXT, decision=SAMPLE_TEXT) for transition in cfg.getTransitionsForPresentingAnItem(): wfTool.doActionFor(newItem, transition) return meeting
def gm_group_uid(raise_on_error=False): """ """ return org_id_to_uid(GENERAL_MANAGER_GROUP_ID, raise_on_error=raise_on_error)
def _addCouncilDemoData(collegeMeeting, collegeExtraMeeting, userId='dgen', firstTwoGroupIds=('dirgen', 'personnel'), templateId='template1'): '''This needs to be called after 'addCollegeDemoData'.''' # create 1 meeting, insert some items, then freeze it and insert other items portal = api.portal.get() tool = api.portal.get_tool('portal_plonemeeting') wfTool = api.portal.get_tool('portal_workflow') wfTool = api.portal.get_tool('portal_workflow') tool = api.portal.get_tool('portal_plonemeeting') cfg2 = tool.objectValues('MeetingConfig')[1] cfg2Id = cfg2.getId() dgenFolder = tool.getPloneMeetingFolder(cfg2Id, userId) date = DateTime() + 1 with api.env.adopt_user(userId): councilCategoryIds = ['designations', 'engagements', 'contentieux'] meetingId = dgenFolder.invokeFactory('MeetingCouncil', date=date, id=date.strftime('%Y%m%d')) meeting = getattr(dgenFolder, meetingId) meeting.processForm() portal.REQUEST['PUBLISHED'] = meeting # get every items to send to council without emergency itemsToCouncilNoEmergency = [ item for item in collegeMeeting.getItems(ordered=True) if item.getOtherMeetingConfigsClonableTo() and not item.getOtherMeetingConfigsClonableToEmergency() ] # send to council every items i = 0 for item in itemsToCouncilNoEmergency: councilItem = item.cloneToOtherMeetingConfig(cfg2Id) # 'secret' items do not have a category, define one so it can be presented # 'public' items are automatically presented in the onItemDuplicated event if councilItem.getPrivacy() == 'secret': councilItem.setCategory(councilCategoryIds[i]) i = i + 1 if i == len(councilCategoryIds): i = 0 wfTool.doActionFor(councilItem, 'present') # freeze the meeting and insert emergency items itemsToCouncilEmergency = [ item for item in collegeMeeting.getItems(ordered=True) if item.getOtherMeetingConfigsClonableTo() and item.getOtherMeetingConfigsClonableToEmergency() ] wfTool.doActionFor(meeting, 'freeze') for item in itemsToCouncilEmergency[1:]: councilItem = item.cloneToOtherMeetingConfig(cfg2Id) if councilItem.getPrivacy() == 'secret': councilItem.setCategory(councilCategoryIds[1]) wfTool.doActionFor(councilItem, 'present') # present items from collegeExtraMeeting for item in collegeExtraMeeting.getItems(): if item.getOtherMeetingConfigsClonableTo(): councilItem = item.cloneToOtherMeetingConfig(cfg2Id) if councilItem.getPrivacy() == 'secret': councilItem.setCategory(councilCategoryIds[2]) wfTool.doActionFor(councilItem, 'present') # now add some special items, aka items using categories "proposes-par-un-conseiller" # "interventions" and "questions-actualite" # more over add some items using privacy "secret_heading" special_items = ( # 'secret_heading' { 'templateId': templateId, 'title': u'Point entête 1', 'proposingGroup': org_id_to_uid(firstTwoGroupIds[0]), 'category': councilCategoryIds[0], 'privacy': 'secret_heading', 'itemInitiator': (), 'pollType': 'secret', 'pollTypeObservations': '', 'bourgmestreObservations': u'Observation Bourgmestre Point entête 1' }, { 'templateId': templateId, 'title': u'Point entête 2', 'proposingGroup': org_id_to_uid(firstTwoGroupIds[0]), 'category': councilCategoryIds[1], 'privacy': 'secret_heading', 'itemInitiator': (), 'pollType': 'secret', 'pollTypeObservations': '' }, { 'templateId': templateId, 'title': u'Point entête 3', 'proposingGroup': org_id_to_uid(firstTwoGroupIds[0]), 'category': councilCategoryIds[2], 'privacy': 'secret_heading', 'itemInitiator': (), 'pollType': 'secret', 'pollTypeObservations': '<p>Petite note vote secret</p>' }, # items using special categories { 'templateId': templateId, 'title': u'Proposition de motion 1', 'proposingGroup': org_id_to_uid(firstTwoGroupIds[0]), 'category': COUNCIL_SPECIAL_CATEGORIES[0], 'privacy': 'public', 'itemInitiator': (), 'pollType': 'freehand', 'pollTypeObservations': '', 'bourgmestreObservations': u'Observation Bourgmestre Point Proposition de motion 1' }, { 'templateId': templateId, 'title': u'Proposition de motion 2', 'proposingGroup': org_id_to_uid(firstTwoGroupIds[0]), 'category': COUNCIL_SPECIAL_CATEGORIES[0], 'privacy': 'public', 'itemInitiator': (), 'pollType': 'freehand', 'pollTypeObservations': '' }, { 'templateId': templateId, 'title': u'Point proposé par un conseiller 1', 'proposingGroup': org_id_to_uid(firstTwoGroupIds[0]), 'category': COUNCIL_SPECIAL_CATEGORIES[1], 'privacy': 'public', 'itemInitiator': ('DESGXA103', ), 'pollType': 'freehand', 'pollTypeObservations': '' }, { 'templateId': templateId, 'title': u'Point proposé par un conseiller 2', 'proposingGroup': org_id_to_uid(firstTwoGroupIds[0]), 'category': COUNCIL_SPECIAL_CATEGORIES[1], 'privacy': 'public', 'itemInitiator': ('DESGXA103', 'DEVIFA128'), 'pollType': 'freehand', 'pollTypeObservations': '', 'bourgmestreObservations': u'Observation Bourgmestre Point proposé par un conseiller 2' }, { 'templateId': templateId, 'title': u'Intervention 1', 'proposingGroup': org_id_to_uid(firstTwoGroupIds[0]), 'category': COUNCIL_SPECIAL_CATEGORIES[2], 'privacy': 'public', 'itemInitiator': (), 'pollType': 'freehand', 'pollTypeObservations': '<p>Une autre petite note</p>' }, { 'templateId': templateId, 'title': u'Question d\'actualité 1', 'proposingGroup': org_id_to_uid(firstTwoGroupIds[0]), 'category': COUNCIL_SPECIAL_CATEGORIES[3], 'privacy': 'public', 'itemInitiator': (), 'pollType': 'freehand', 'pollTypeObservations': '' }, { 'templateId': templateId, 'title': u'Huis clos entête 1', 'proposingGroup': org_id_to_uid(firstTwoGroupIds[0]), 'category': COUNCIL_SPECIAL_CATEGORIES[3], 'privacy': 'public', 'itemInitiator': (), 'pollType': 'freehand', 'pollTypeObservations': '' }, { 'templateId': templateId, 'title': u'Question d\'actualité 1', 'proposingGroup': org_id_to_uid(firstTwoGroupIds[0]), 'category': COUNCIL_SPECIAL_CATEGORIES[3], 'privacy': 'public', 'itemInitiator': (), 'pollType': 'freehand', 'pollTypeObservations': '', 'bourgmestreObservations': u'Observation Bourgmestre Question d\'actualité 1' }, { 'templateId': templateId, 'title': u'Approuve le procès-verbal de la séance à huis-clos du ...', 'proposingGroup': org_id_to_uid(firstTwoGroupIds[0]), 'category': 'entetes', 'privacy': 'secret', 'itemInitiator': (), 'pollType': 'freehand', 'pollTypeObservations': '' }, ) userFolder = tool.getPloneMeetingFolder(cfg2Id, userId) i = 1 wfTool.doActionFor(meeting, 'backToCreated') for item in special_items: # just insert 2 first items in the 'created' meeting, others will be inserted in a frozen meeting if i == 3: wfTool.doActionFor(meeting, 'freeze') i = i + 1 # get the template then clone it template = getattr( tool.getMeetingConfig(userFolder).itemtemplates, item['templateId']) newItem = template.clone(newOwnerId=userId, destFolder=userFolder, newPortalType=cfg2.getItemTypeName()) newItem.setTitle(item['title']) newItem.setItemAssemblyExcused('Roger Bidon') newItem.setItemAssemblyAbsents('Jean-Michel Jamaila') newItem.setProposingGroup(item['proposingGroup']) # manage MeetingItem.groupInCharge groupInCharge = newItem.getProposingGroup( theObject=True).get_groups_in_charge()[0] value = '{0}__groupincharge__{1}'.format( newItem.getProposingGroup(), groupInCharge) newItem.setProposingGroupWithGroupInCharge(value) newItem.setPreferredMeeting(meeting.UID()) newItem.setPrivacy(item['privacy']) newItem.setItemInitiator(item['itemInitiator']) newItem.setCategory(item['category']) newItem.setPollType(item['pollType']) newItem.setPollTypeObservations(item['pollTypeObservations'], mimetype='text/html') if 'bourgmestreObservations' in item: newItem.setBourgmestreObservations( item['bourgmestreObservations']) newItem.reindexObject() wfTool.doActionFor(newItem, 'present') return meeting