Source code for ploneintranet.todo.handlers

# -*- coding: utf-8 -*-
from .behaviors import IMustRead
from .behaviors import ITodo
from .interfaces import ITodoUtility
from .interfaces import MUST_READ
from plone import api
from ploneintranet.notifications.interfaces import IMessageFactory
from Products.DCWorkflow.interfaces import IAfterTransitionEvent
from zope.component import getUtility
from zope.lifecycleevent.interfaces import IObjectAddedEvent

import logging


log = logging.getLogger(__name__)


[docs]def mark(obj, evt): """The event handler that marks this object as mustread. """ todos = getUtility(ITodoUtility) obj_uuid = api.content.get_uuid(obj) behavior = IMustRead(obj) # Verify if it has been booked in the utility present = todos.query(content_uids=[obj_uuid], verbs=[MUST_READ]) if not behavior.mustread and len(present) > 0: # Ok, so it was present but somehow we don't want it to be "must read" # anymore, so we complete the actions (ugh) todos.complete_action(content_uid=obj_uuid, verb=MUST_READ) if behavior.mustread and len(present) == 0: todos.add_action(content_uid=obj_uuid, verb=MUST_READ)
[docs]def on_delete(obj, evt): """Complete actions for objects marked as must read that have been deleted """ todos = getUtility(ITodoUtility) obj_uuid = api.content.get_uuid(obj) todos.complete_action(content_uid=obj_uuid, verb=MUST_READ)
[docs]def todo_set_role(obj, evt): """ update role for assignees """ todo = ITodo(obj) assignee = todo.assignee if not assignee and IObjectAddedEvent.providedBy(evt): assignee = obj.REQUEST.get("assignee") if assignee: obj.manage_addLocalRoles(assignee, ["Assignee"])
[docs]def _is_change_reported(event, field): for change in event.descriptions: if field in change.attributes: return True return False
[docs]def trigger_user_notifications(obj, recipient, mail_template=""): """ Send out notifications to all channels the user wants """ # XXX check the user prefs # If user wants inline notes # send notification message = IMessageFactory(obj)() tool = api.portal.get_tool("ploneintranet_notifications") try: tool.append_to_user_queue(recipient, message.clone()) except ValueError as ve: log.error("Error adding a notification for task: %s" % str(ve)) # if the user wants email # send an email try: R = obj.REQUEST R.set("recipient", recipient) view = api.content.get_view(mail_template, obj, R) view.send_email() except Exception as e: log.error("Error sending notification mail for task: %s" % str(e))
[docs]def task_update_handler(obj, event): """ * when a task is created the assignee gets a notification * when a task is edited assignee and initiator get notifications * when a task is state changed assignee and initiator get notifications always - the one who did the changes does not get a notification """ # After creation, another event handler may update the workflow state of a # task which will trigger additional messages. # The request is marked to show that the item has just been created. if getattr(obj.REQUEST, "newly_created", False): return # Don't send notifications for planned tasks wft = api.portal.get_tool("portal_workflow") state_id = wft.getInfoFor(obj, "review_state") if state_id == "planned": return creator = obj.initiator assignee = obj.assignee current_user = api.user.get_current() current_user_id = current_user.getId() recipients = set() if creator and creator != current_user.getId(): recipients.add(creator) # Determine the nature of the change change = "modification" if IAfterTransitionEvent.providedBy(event): # In a case, a task is transitioned from 'planned' to 'open' when # the case reaches the milestone of the task. # The assignee may only be first aware of the task when it is set to # 'open', since they may not have permission to view it earlier. So we # send a notification that they have been assigned. old_state = event.old_state.getId() if state_id == "open": change = "assignment" elif old_state == "open" and state_id == "done": change = "modification" else: return elif IObjectAddedEvent.providedBy(event): # When triggered by IObjectAddedEvent the obj.assignee hasn't been set # yet, but we can get it from the request assignee = obj.REQUEST.form.get("assignee", None) if assignee: obj.REQUEST.newly_created = True change = "assignment" elif _is_change_reported(event, "assignee"): # The task has been changed and one of the changes was the assignee. change = "assignment" # Special Case: # An assignee has been set and it is not the current user, so we # need to inform the assignee. if assignee and assignee != current_user_id: recipients.add(assignee) # Trigger the notifications (inline, emails, etc) if change == "assignment": mail_template = "todo-assigned-notification-email" elif change == "modification": mail_template = "todo-changed-notification-email" else: # undefined situation. Should not happen. Abort. log.warning("Change type unknown. Not sending any notification.") for recipient in recipients: trigger_user_notifications(obj, recipient, mail_template=mail_template)