def test_pm_SendMailIfRelevantIsPermission(self): """ """ cfg = self.meetingConfig cfg.setMailMode("activated") cfg.setMailItemEvents(("item_state_changed_validate", )) self.changeUser('pmManager') item = self.create("MeetingItem", title="My item") params = { "obj": item, "event": "item_state_changed_validate", "value": View, "isPermission": True, "debug": True } recipients, subject, body = sendMailIfRelevant(**params) # not sent to action triggerer self.assertEqual(sorted(recipients), [ u'M. Budget Impact Editor <*****@*****.**>', u'M. PMCreator One <*****@*****.**>', u'M. PMCreator One bee <*****@*****.**>', u'M. PMObserver One <*****@*****.**>', u'M. PMReviewer One <*****@*****.**>', u'M. Power Observer1 <*****@*****.**>', u'Site administrator <*****@*****.**>' ]) # check for editors params["value"] = ModifyPortalContent recipients, subject, body = sendMailIfRelevant(**params) self.assertEqual(sorted(recipients), [ u'M. PMCreator One <*****@*****.**>', u'M. PMCreator One bee <*****@*****.**>', u'Site administrator <*****@*****.**>' ])
def doPublish(self, state_change): """ """ #need to update the adviceIndex where the review_state is stored... self.context.getMeetingItem().updateAdviceIndex(advice=self.context) # Warn users Check if we must warn users sendMailIfRelevant(self.context, 'adviceAdded', 'View', isRole=False)
def do(action, state_change): '''What must I do when a transition is triggered on a meeting ?''' actionsAdapter = state_change.object.wfActions() # Execute first some actions defined in the corresponding adapter actionMethod = getattr(actionsAdapter, action) actionMethod(state_change) # Add recurring items to the meeting if relevant addRecurringItemsIfRelevant(state_change.object, state_change.transition.id) # Send mail if relevant sendMailIfRelevant(state_change.object, state_change.transition.id, 'View') podTransition = 'pod_meeting_%s' % state_change.transition.id freezePodDocumentsIfRelevant(state_change.object, podTransition)
def test_pm_SendMailIfRelevantIsGroupIds(self): """ """ cfg = self.meetingConfig cfg.setMailMode("activated") cfg.setMailItemEvents(("item_state_changed_validate", )) self.changeUser('pmManager') item = self.create("MeetingItem", title="My item") params = { "obj": item, "event": "item_state_changed_validate", "value": [self.developers_creators, self.vendors_creators], "isGroupIds": True, "debug": True } recipients, subject, body = sendMailIfRelevant(**params) dev_creators = get_plone_group(self.developers_uid, 'creators') self.assertEqual(dev_creators.getMemberIds(), ['pmCreator1', 'pmCreator1b', 'pmManager']) vendors_creators = get_plone_group(self.vendors_uid, 'creators') self.assertEqual(vendors_creators.getMemberIds(), ['pmCreator2']) # not sent to action triggerer self.assertEqual(recipients, [ u'M. PMCreator One bee <*****@*****.**>', u'M. PMCreator One <*****@*****.**>', u'M. PMCreator Two <*****@*****.**>' ])
def synchToggle(self, itemUid, discussAction): """ This is a synchronous way of toggling toDiscuss. The asynchronous asynchToggle here above will only reload the clicked icon. If for some reason it is necessary that the page is fully reloaded, like for example to display a portal_message or because something else has changed on the page, this is the method to use. Here, it manages for example the fact that a reviewer can ask an item to be discussed and that will display a portal_message to this user. """ item = uuidToObject(itemUid, unrestricted=True) if discussAction == 'ask': # I must send a mail to MeetingManagers for notifying them that a reviewer # wants to discuss this item. sendMailEnabled = sendMailIfRelevant(item, 'askDiscussItem', 'meetingmanagers', isSuffix=True) if sendMailEnabled: msgId = 'to_discuss_ask_mail_sent' else: msgId = 'to_discuss_ask_mail_not_sent' self.context.plone_utils.addPortalMessage( item.translate(msgId, domain='PloneMeeting')) elif discussAction == 'toggle': # I must toggle the "toDiscuss" switch on the item toDiscuss = not item.getToDiscuss() item.setToDiscuss(toDiscuss) item.adapted().onDiscussChanged(toDiscuss) self.context._update_after_edit(idxs=['to_discuss']) return self.request.RESPONSE.redirect(self.request['HTTP_REFERER'])
def test_pm_SendMailIfRelevant(self): """ """ cfg = self.meetingConfig cfg.setMailMode("deactivated") self.changeUser('pmManager') item = self.create("MeetingItem", title="My item") params = { "obj": item, "event": "itemPresented", "value": "creators", "isSuffix": True, "debug": True } # disabled self.assertIsNone(sendMailIfRelevant(**params)) # enabled but not selected cfg.setMailMode("activated") self.assertIsNone(sendMailIfRelevant(**params)) # enabled and selected cfg.setMailItemEvents(("itemPresented", )) recipients, subject, body = sendMailIfRelevant(**params) dev_creators = get_plone_group(self.developers_uid, 'creators') self.assertEqual(dev_creators.getMemberIds(), ['pmCreator1', 'pmCreator1b', 'pmManager']) # not sent to action triggerer self.assertEqual(recipients, [ u'M. PMCreator One bee <*****@*****.**>', u'M. PMCreator One <*****@*****.**>' ]) self.assertEqual( subject, u"{0} - Item has been inserted into a meeting - My item".format( cfg.Title())) self.assertEqual( body, u"This meeting may still be under construction and is potentially inaccessible. " u"The item is entitled \"My item\". You can access this item here: {0}." .format(item.absolute_url()))
def onAdviceAdded(advice, event): """Called when a meetingadvice is added so we can warn parent item.""" # if advice is added because we are pasting, pass as we will remove the advices... if advice.REQUEST.get('currentlyPastingItems', False): return # update advice_row_id if it was not already done before # for example in a onAdviceTransition event handler that is called # before the onAdviceAdded... if not advice.advice_row_id: advice._updateAdviceRowId() item = advice.getParentNode() item.updateLocalRoles() _addManagedPermissions(advice) # make sure external images used in RichText fields are stored locally storeImagesLocallyDexterity(advice) # notify our own PM event so we are sure that this event is called # after the onAviceAdded event notify(AdviceAfterAddEvent(advice)) # redirect to referer after add if it is not the edit form http_referer = item.REQUEST['HTTP_REFERER'] if not http_referer.endswith('/edit') and not http_referer.endswith( '/@@edit'): advice.REQUEST.RESPONSE.redirect(http_referer + '#adviceAndAnnexes') # update item _advice_update_item(item) # Send mail if relevant sendMailIfRelevant(item, 'adviceEdited', 'MeetingMember', isRole=True) sendMailIfRelevant(item, 'event_add_advice-service_heads', 'MeetingServiceHead', isRole=True)
def onAdviceModified(advice, event): """Called when a meetingadvice is modified so we can warn parent item.""" if advice.REQUEST.get('currentlyStoringExternalImages', False) is True: return # update advice_row_id advice._updateAdviceRowId() item = advice.getParentNode() item.updateLocalRoles() # make sure external images used in RichText fields are stored locally storeImagesLocallyDexterity(advice) # notify our own PM event so we are sure that this event is called # after the onAviceModified event notify(AdviceAfterModifyEvent(advice)) # update item _advice_update_item(item) sendMailIfRelevant(item, 'event_add_advice-service_heads', 'MeetingServiceHead', isRole=True)
def test_pm_SendMailIfRelevantIsUserIds(self): """ """ cfg = self.meetingConfig cfg.setMailMode("activated") cfg.setMailItemEvents(("item_state_changed_validate", )) self.changeUser('pmManager') item = self.create("MeetingItem", title="My item") params = { "obj": item, "event": "item_state_changed_validate", "value": ['pmObserver1', 'pmManager', 'pmCreator2'], "isUserIds": True, "debug": True } recipients, subject, body = sendMailIfRelevant(**params) # not sent to action triggerer self.assertEqual(recipients, [ u'M. PMObserver One <*****@*****.**>', u'M. PMCreator Two <*****@*****.**>' ])
def onAdviceAfterTransition(advice, event): '''Called whenever a transition has been fired on an advice.''' if advice != event.object: return # pass if we are pasting items as advices are not kept if advice.REQUEST.get('currentlyPastingItems', False): return # manage finance workflow, just consider relevant transitions # if it is not a finance wf transition, return if advice.advice_group != finance_group_uid(): return item = advice.getParentNode() itemState = item.queryState() oldStateId = event.old_state.id newStateId = event.new_state.id # initial_state or going back from 'advice_given', we set automatically # advice_hide_during_redaction to True if not event.transition or \ newStateId == 'proposed_to_financial_controller' and oldStateId == 'advice_given': advice.advice_hide_during_redaction = True if newStateId == 'financial_advice_signed': plone_utils = api.portal.get_tool('plone_utils') # final state of the wf, make sure advice is no more hidden during redaction advice.advice_hide_during_redaction = False # if item was still in state 'prevalidated_waiting_advices', # it is automatically validated if advice is 'positive_finance' # otherwise it is sent back to the refadmin if itemState == 'prevalidated_waiting_advices': wfTool = api.portal.get_tool('portal_workflow') if advice.advice_type == 'positive_finance': item.REQUEST.set('mayValidate', True) wfTool.doActionFor( item, 'backTo_validated_from_waiting_advices', comment='item_wf_changed_finance_advice_positive') item.REQUEST.set('mayValidate', False) msg = _AP('backTo_validated_from_waiting_advices_done_descr') else: item.REQUEST.set( 'maybackTo_proposed_to_refadmin_from_waiting_advices', True) wfTool.doActionFor( item, 'backTo_proposed_to_refadmin_from_waiting_advices', comment='item_wf_changed_finance_advice_not_positive') item.REQUEST.set( 'maybackTo_proposed_to_refadmin_from_waiting_advices', False) sendMailIfRelevant( item, 'sentBackToRefAdminWhileSigningNotPositiveFinancesAdvice', 'MeetingReviewer', isRole=True) msg = _AP( 'backTo_proposed_to_refadmin_from_waiting_advices_done_descr' ) plone_utils.addPortalMessage(msg) # in some corner case, we could be here and we are actually already updating advices, # this is the case if we validate an item and it triggers the fact that advice delay is exceeded # this should never be the case as advice delay should have been updated during nightly cron... # but if we are in a '_updateAdvices', do not _updateAdvices again... # also bypass if we are creating the advice as onAdviceAdded is called after onAdviceTransition if event.transition and not item.REQUEST.get('currentlyUpdatingAdvice', False): item.updateLocalRoles() return