def render(self):
     folder = IResponseContainer(self.context)
     form = self.request.form
     context = aq_inner(self.context)
     if not self.can_edit_response:
         msg = _(u'You are not allowed to edit responses.')
         api.portal.show_message(message=msg, request=self.request, type='error')
     else:
         response_id = form.get('response_id', None)
         if response_id is None:
             msg = _(u'No response selected for saving.')
             api.portal.show_message(message=msg, request=self.request, type='error')
         elif folder[response_id] is None:
             msg = _(u'Response does not exist anymore; perhaps it was removed by another user.')
             api.portal.show_message(message=msg, request=self.request, type='error')
         else:
             response = folder[response_id]
             response_text = form.get('response', u'')
             response.text = response_text
             msg = _(
                 u'Changes saved to response id ${response_id}.',
                 mapping=dict(response_id=response_id)
             )
             api.portal.show_message(message=msg, request=self.request)
             modified(response, context)
     self.request.response.redirect(context.absolute_url())
 def priority_for_display(self):
     """Get the available priorities for this issue.
     """
     vocab = {1: _(u'High'), 2: _(u'Normal'), 3: _(u'Low')}
     options = []
     for value in vocab:
         checked = (value == self.priority) and 'checked' or ''
         options.append(
             dict(value=value, label=vocab[value], checked=checked))
     return options
    def render(self):
        form = self.request.form
        task_has_changed = False

        # XXX: I do not get the point on storing the responsible on the
        #      response annotation; that information is not being used
        #      anywhere so this could be way simpler
        current_responsible = self.context.responsible
        response_text = form.get('response', u'')
        responsible = form.get('responsible', u'')
        if responsible != current_responsible:
            self.context.responsible = responsible
            task_has_changed = True
            new_response = Response(response_text, responsible)
        else:
            new_response = Response(response_text)

        result = self._update_workflow()
        if result:
            old, new = result
            new_response.add_change('review_state', _(u'State'), old, new)
            task_has_changed = True

        result = self._update_text_field('priority')
        if result:
            old, new = result
            new_response.add_change('priority', _(u'Priority'), old, new)
            task_has_changed = True

        result = self._update_text_field('responsible')
        if result:
            old, new = result
            new_response.add_change('responsible', _(u'Responsible'), old, new)
            task_has_changed = True

        result = self._update_date()
        if result:
            old, new = result
            new_response.add_change('provided_date', _(u'Expected date'), old, new)
            task_has_changed = True

        if len(response_text) == 0 and not task_has_changed:
            msg = _(u'No response text added and no issue changes made.')
            api.portal.show_message(message=msg, request=self.request)
        else:
            folder = IResponseContainer(self.context)
            folder.add(new_response)
        self.request.response.redirect(self.context.absolute_url())
    def plain(self):
        context = aq_inner(self.context)
        portal = getSite()
        fromName = portal.getProperty("email_from_name", "")
        portal_membership = getToolByName(portal, "portal_membership")
        member = portal_membership.getAuthenticatedMember()
        memberInfo = portal_membership.getMemberInfo(member.getUserName())
        stateChanger = member.getUserName()
        if memberInfo:
            stateChanger = memberInfo["fullname"] or stateChanger
        mail_text = _(
            "email_task_closed_template",
            u"""The task **${task_title}** has been marked as resolved by **${response_author}**.
Please visit the task and either confirm that it has been
satisfactorily resolved or re-open it.

Response Information
--------------------

Task
  ${task_title} (${task_url})


* This is an automated email, please do not reply - ${from_name}""",
            mapping=dict(
                task_title=su(context.title),
                response_author=su(stateChanger),
                task_url=su(context.absolute_url()),
                from_name=su(fromName),
            ),
        )

        # Translate the body text
        mail_text = translate(mail_text, "s17.taskmanager", context=self.request)
        return mail_text
    def plain(self):
        context = aq_inner(self.context)
        portal = getSite()
        fromName = portal.getProperty("email_from_name", "")
        portal_membership = getToolByName(portal, "portal_membership")
        taskCreator = context.Creator()
        taskCreatorInfo = portal_membership.getMemberInfo(taskCreator)
        taskAuthor = taskCreator
        if taskCreatorInfo:
            taskAuthor = taskCreatorInfo["fullname"] or taskCreator

        taskText = context.text
        if taskText:
            paras = taskText.raw.splitlines()
            taskDetails = "\n\n".join([wrapper.fill(p) for p in paras])
        else:
            taskDetails = _("email_null_task_details", u"""No details in the task """)
        mail_text = _(
            "email_new_task_template",
            u"""A new task has been submitted by **${task_author}**.

Task Information
----------------

Task
  ${task_title} (${task_url})


**Task Details**::

${task_details}


* This is an automated email, please do not reply - ${from_name}""",
            mapping=dict(
                task_title=su(context.title),
                task_author=su(taskAuthor),
                task_details=su(taskDetails),
                task_url=su(context.absolute_url()),
                from_name=su(fromName),
            ),
        )
        # Translate the body text
        mail_text = translate(mail_text, "s17.taskmanager", context=self.request)
        return mail_text
 def subject(self):
     context = aq_inner(self.context)
     subject = _(
         "email_new_response_subject_template", u"Re: ${task_title}", mapping=dict(task_title=su(context.title))
     )
     # Ensure that the subject is unicode and translate it too.
     subject = su(subject)
     subject = translate(subject, "s17.taskmanager", context=self.request)
     return subject
 def subject(self):
     context = aq_inner(self.context)
     subject = _(
         "email_new_task_subject_template", u"[New task: ${task_title}]", mapping=dict(task_title=su(context.title))
     )
     # Make the subject unicode and translate it too.
     subject = su(subject)
     subject = translate(subject, "s17.taskmanager", context=self.request)
     return subject
 def responsibles_for_display(self):
     context = aq_inner(self.context)
     users_factory = getUtility(IVocabularyFactory, name=u'plone.app.vocabularies.Users')
     users = users_factory(context)
     if not self.res:
         options = [
             {'checked': 'checked', 'value': '', 'label': _('Nobody')},
         ]
     else:
         options = [
             {'checked': '', 'value': '', 'label': _('Nobody')},
         ]
     for value in users:
         values = {}
         values['checked'] = (value.token == self.res) and 'checked' or ''
         values['value'] = value.token
         values['label'] = value.title
         options.append(values)
     return options
 def _valid_values(self, fieldname):
     """Return a vocabulary of valid values for a field name.
     """
     if fieldname == 'priority':
         return self.available_priorities
     elif fieldname == 'responsible':
         users = getUtility(
             IVocabularyFactory, name=u'plone.app.vocabularies.Users')
         users = users(self.context)
         return [v.token for v in users]
     else:
         raise AttributeError(_(u'Invalid fieldname specified'))
    def render(self):
        folder = IResponseContainer(self.context)
        context = aq_inner(self.context)

        if not self.can_delete_response:
            msg = _(u'You are not allowed to delete responses.')
            api.portal.show_message(message=msg, request=self.request, type='error')
        else:
            response_id = self.request.form.get('response_id', None)
            if response_id is None:
                msg = _(u'No response selected for removal.')
                api.portal.show_message(message=msg, request=self.request, type='error')
            else:
                try:
                    response_id = int(response_id)
                except ValueError:
                    msg = _(
                        u'Response id ${response_id} is no integer so it cannot be removed.',
                        mapping=dict(response_id=response_id)
                    )
                    api.portal.show_message(message=msg, request=self.request, type='error')
                    self.request.response.redirect(context.absolute_url())
                    return
                if response_id >= len(folder):
                    msg = _(
                        u'Response id ${response_id} does not exist so it cannot be removed.',
                        mapping=dict(response_id=response_id)
                    )
                    api.portal.show_message(message=msg, request=self.request, type='error')
                else:
                    folder.delete(response_id)
                    msg = _(
                        u'Removed response id ${response_id}.',
                        mapping=dict(response_id=response_id)
                    )
                    api.portal.show_message(message=msg, request=self.request)

        self.request.response.redirect(context.absolute_url())
    def transitions_for_display(self):
        """Display the available transitions for this issue.
        """
        context = aq_inner(self.context)
        membership = api.portal.get_tool('portal_membership')
        if not membership.checkPermission('Modify portal content', context):
            return []

        wftool = api.portal.get_tool('portal_workflow')
        transitions = []
        transitions.append(
            dict(value='', label=_(u'No change'), checked='checked'))
        for tdef in wftool.getTransitionsFor(context):
            transitions.append(
                dict(value=tdef['id'], label=tdef['title_or_id'], checked=''))
        return transitions
    def _update_date(self):
        """Compare the value of the provided_date field with the one on the
        request and change it if different.

        :returns: a tuple containing the values (old, new) or False is no
                  update was made
        :rtype: tuple of boolean
        """
        updated = False
        form = self.request.form
        # the date came split in 3 different fields
        day = form.get('date-day', None)
        month = form.get('date-month', None)
        year = form.get('date-year', None)

        if day == '' or year == '':
            # either there were no changes or we want to clear current value
            new = None
        else:
            try:
                year, month, day = map(int, (year, month, day))
                new = date(year, month, day)
            except TypeError, ValueError:
                raise ValueError(_(u'Invalid date specified'))
 def available_priorities(self):
     vocab = {1: _(u'High'), 2: _(u'Normal'), 3: _(u'Low')}
     return vocab
 def subject(self):
     """The subject of the e-mail.
     """
     return _(u"[No subject]")
    def plain(self):
        """When a response is created, send a notification email to all
        tracker managers
        """
        response_id = self.request.get("response_id", -1)
        context = aq_inner(self.context)
        folder = IResponseContainer(context)
        response = folder[response_id]

        portal_url = getToolByName(context, "portal_url")
        portal = portal_url.getPortalObject()
        portal_membership = getToolByName(portal, "portal_membership")
        fromName = su(portal.getProperty("email_from_name", ""))

        creator = response.creator
        creatorInfo = portal_membership.getMemberInfo(creator)
        if creatorInfo and creatorInfo["fullname"]:
            responseAuthor = creatorInfo["fullname"]
        else:
            responseAuthor = creator
        responseAuthor = su(responseAuthor)

        responseText = su(response.text)
        paras = responseText.splitlines()

        # Indent the response details so they are correctly interpreted as
        # a literal block after the double colon behind the 'Response
        # Details' header.
        wrapper = textwrap.TextWrapper(initial_indent=u"    ", subsequent_indent=u"    ")
        responseDetails = u"\n\n".join([wrapper.fill(p) for p in paras])

        if responseDetails:
            header = _("heading_response_details", u"Response Details")
            header = translate(header, "s17.taskmanager", context=self.request)
            responseDetails = u"**%s**::\n\n\n%s" % (header, responseDetails)

        changes = u""
        for change in response.changes:
            before = su(change.get("before"))
            after = su(change.get("after"))
            name = su(change.get("name"))
            # Some changes are workflow changes, which can be translated.
            # Note that workflow changes are in the plone domain.
            before = translate(before, "s17.taskmanager", context=self.request)
            after = translate(after, "s17.taskmanager", context=self.request)
            name = translate(name, "s17.taskmanager", context=self.request)
            changes += u"- %s: %s -> %s\n" % (name, before, after)

        mail_text = _(
            "email_new_response_template",
            u"""A new response has been given to the task **${task_title}**
by **${response_author}**.

Response Information
--------------------

Task
  ${task_title} (${task_url})

${changes}

${response_details}

* This is an automated email, please do not reply - ${from_name}""",
            mapping=dict(
                task_title=su(context.title),
                response_author=responseAuthor,
                response_details=responseDetails,
                task_url=su(context.absolute_url()),
                changes=changes,
                from_name=fromName,
            ),
        )
        mail_text = translate(mail_text, "s17.taskmanager", context=self.request)
        return mail_text
# -*- coding: utf-8 -*-
from plone.app.textfield import RichText
from plone.directives import form
from s17.taskmanager import MessageFactory as _
from zope import schema
from zope.schema.vocabulary import SimpleTerm
from zope.schema.vocabulary import SimpleVocabulary

priorities = SimpleVocabulary([
    SimpleTerm(value=1, title=_(u'High')),
    SimpleTerm(value=2, title=_(u'Normal')),
    SimpleTerm(value=3, title=_(u'Low')),
])


class ITaskPanel(form.Schema):

    responsible = schema.Choice(
        title=_(u'Responsible'),
        description=_(''),
        required=False,
        vocabulary='plone.app.vocabularies.Users',
    )

    can_add_tasks = schema.List(
        title=_(u'Who can add tasks?'),
        description=_(''),
        required=False,
        value_type=schema.Choice(vocabulary='plone.app.vocabularies.Groups'),
    )