Exemple #1
0
    def get_items(self):
        return [
            {
                'class': 'responsible',
                'label': _('label_by_author', default='by'),
                'content': self.responsible_link(),
                'replace': True
            },
            {
                'class': 'review_state',
                'label': _('label_workflow_state_byline', default='State'),
                'content': self.workflow_state(),
                'replace': False
            },
            {
                'class': 'last_modified',
                'label': _('label_last_modified', default='last modified'),
                'content': self.modified(),
                'replace': False
            },
            {
                'class': 'document_created',
                'label': _('label_created', default='created'),
                'content': self.created(),
                'replace': False
            },
            {
                'class': 'sequenceNumber',
                'label': _('label_sequence_number', default='Sequence Number'),
                'content': self.sequence_number(),
                'replace': False
            },

        ]
            def handleAdd(self, action):
                # create the dossier
                data, errors = self.extractData()
                if errors:
                    self.status = self.formErrorsMessage
                    return
                obj = self.createAndAdd(data)
                if obj is not None:
                    # mark only as finished if we get the new object
                    self._finishedAdd = True

                # Get a properly aq wrapped object
                dossier = self.context.get(obj.id)

                dm = getUtility(IWizardDataStorage)
                oguid = self.request.get('oguid')
                dmkey = 'accept:%s' % oguid

                # forwarding
                if dm.get(dmkey, 'is_forwarding'):
                    if dm.get(dmkey, 'is_only_assign'):
                        task = assign_forwarding_to_dossier(
                            self.context, oguid, dossier, dm.get(
                                dmkey, 'text'))

                        IStatusMessage(self.request).addStatusMessage(
                            _(u'The forwarding is now assigned to the new '
                              'dossier'),
                            'info')

                        self.request.RESPONSE.redirect(
                            '%s/edit' % task.absolute_url())

                    else:
                        task = accept_forwarding_with_successor(
                            self.context,
                            oguid,
                            dm.get(dmkey, 'text'),
                            dossier=dossier)

                        IStatusMessage(self.request).addStatusMessage(
                            _(u'The forwarding has been stored in the '
                              u'local inbox and the succesor task has been'
                              u' created'), 'info')

                        self.request.RESPONSE.redirect(
                            '%s/edit' % task.absolute_url())

                else:
                    # create the successor task, accept the predecessor
                    task = accept_task_with_successor(
                        dossier,
                        oguid,
                        dm.get(dmkey, 'text'))

                    IStatusMessage(self.request).addStatusMessage(
                        _(u'The new dossier has been created and the task '
                          u'has been copied to the new dossier.'), 'info')

                    self.request.RESPONSE.redirect(task.absolute_url())
Exemple #3
0
    def _update(self, transition, text):
        response = super(WorkflowResponseSyncerReceiver, self)._update(transition, text)

        transition = self.request.get('transition')
        responsible = self.request.get('responsible')
        responsible_client = self.request.get('responsible_client')

        wftool = getToolByName(self.context, 'portal_workflow')

        # change workflow state
        before = wftool.getInfoFor(self.context, 'review_state')
        before = wftool.getTitleForStateOnType(before, self.context.Type())

        with elevated_privileges():
            wftool.doActionFor(self.context, transition)

        after = wftool.getInfoFor(self.context, 'review_state')
        after = wftool.getTitleForStateOnType(after, self.context.Type())

        if responsible and responsible is not 'None':
            # special handling for reassign
            response.add_change(
                'responsible',
                _(u"label_responsible", default=u"Responsible"),
                ITask(self.context).responsible,
                responsible)

            ITask(self.context).responsible_client = responsible_client
            ITask(self.context).responsible = responsible

        notify(ObjectModifiedEvent(self.context))
        response.add_change('review_state', _(u'Issue state'), before, after)
Exemple #4
0
 def __call__(self):
     form = self.request.form
     context = aq_inner(self.context)
     status = IStatusMessage(self.request)
     if not self.can_edit_response:
         msg = _(u"You are not allowed to edit responses.")
         msg = translate(msg, 'Poi', context=self.request)
         status.addStatusMessage(msg, type='error')
     else:
         response_id = form.get('response_id', None)
         if response_id is None:
             msg = _(u"No response selected for saving.")
             msg = translate(msg, 'Poi', context=self.request)
             status.addStatusMessage(msg, type='error')
         else:
             response = self.folder[response_id]
             response_text = form.get('response', u'')
             response.text = response_text
             # Remove cached rendered response.
             response.rendered_text = None
             msg = _(u"Changes saved to response id ${response_id}.",
                     mapping=dict(response_id=response_id))
             msg = translate(msg, 'Poi', context=self.request)
             status.addStatusMessage(msg, type='info')
             # Fire event.  We put the context in the descriptions
             # so event handlers can use this fully acquisition
             # wrapped object to do their thing.  Feels like
             # cheating, but it gets the job done.  Arguably we
             # could turn the two arguments around and signal that
             # the issue has changed, with the response in the
             # event descriptions.
             modified(response, context)
     self.request.response.redirect(context.absolute_url())
Exemple #5
0
def method_vocabulary_factory(context):

    return SimpleVocabulary([
            SimpleTerm(value=u'existing_dossier',
                title=_(u'existing_dossier', default=u'existing dossier',)),

            SimpleTerm(value=u'new_dossier',
                title=_(u'new_dossier', default=u'new dossier',)),
            ])
    def msg(self):
        if not self.response.get_change('responsible'):
            return _('old_transition_msg_reject',
                     default=u'Rejected by ${user}.',
                     mapping=self._msg_mapping)

        return _('transition_msg_reject',
                 u'Rejected by ${old_responsible}. Task assigned to '
                 'responsible ${new_responsible}',
                 mapping=self._msg_mapping)
    def msg(self):
        # Accepting a team task changes the responsible.
        if self.response.get_change('responsible'):
            return _(u'transition_msg_accept_team_task',
                     default=u'Accepted by ${user}, responsible changed from '
                     '${old_responsible} to ${new_responsible}.',
                     mapping=self._msg_mapping)

        return _('transition_msg_accept', u'Accepted by ${user}',
                 mapping=self._msg_mapping)
    def summary(self):
        actor = Actor.lookup(self.context.Creator())
        msg = _('label_task_added', u'New task opened by ${user}',
                mapping={'user': actor.get_label(with_principal=False)})

        if self.context.is_private:
            msg = _('label_private_task_added',
                    default=u'New task (private) opened by ${user}',
                    mapping={'user': actor.get_label(with_principal=False)})

        return self.translate_to_all_languages(msg)
Exemple #9
0
    def get_main_attributes(self):
        """ return a list of widgets,
        which should be displayed in the attributes box
        """

        task = self.context.get_sql_object()

        def _format_date(date):
            if not date:
                return ''
            return api.portal.get().toLocalizedTime(date)

        items = [
            {
                'label': _('label_task_title', u'Task title'),
                'value': task.title,
            },
            {
                'label': _('label_parent_dossier_title'),
                'value': task.containing_dossier,
            },
            {
                'label': _(u"label_text", default=u"Text"),
                'value': task.text,
            },
            {
                'label': _(u'label_task_type', default=u'Task Type'),
                'value': self.context.get_task_type_label(),
            },
            {
                'label': _('label_workflow_state'),
                'value': task.get_state_label(),
                'is_html': True,
            },
            {
                'label': _(u"label_deadline", default=u"Deadline"),
                'value': task.get_deadline_label(format="long"),
                'is_html': True,
            },
            {
                'label': _(u"label_issuer", default=u"Issuer"),
                'css_class': "issuer",
                'value': task.get_issuer_label(),
                'is_html': True,
            },
            {
                'label': _(u"label_responsible", default=u"Responsible"),
                'value': task.get_responsible_label(),
                'is_html': True,
            },
            {
                'label': _(u"label_date_of_completion",
                           default=u"Date of completion"),
                'value': _format_date(task.get_completed()),
            },

        ]

        return items
Exemple #10
0
    def copy_documents(self, task, dossier, documents):
        doc_transporter = getUtility(ITaskDocumentsTransporter)

        comment = _(u'version_message_closed_task',
                    default=u'Document copied from task (task closed)')
        intids_mapping = doc_transporter.copy_documents_from_remote_task(
            task, dossier, documents=documents, comment=comment)

        IStatusMessage(self.request).addStatusMessage(
            _(u'${num} documents were copied.',
              mapping={'num': len(intids_mapping)}), 'info')
Exemple #11
0
    def copy_documents(self, task, dossier, documents):
        doc_transporter = getUtility(ITaskDocumentsTransporter)

        with CustomInitialVersionMessage(
            _(u"version_message_closed_task", default=u"Document copied from task (task closed)"), dossier.REQUEST
        ):
            intids_mapping = doc_transporter.copy_documents_from_remote_task(task, dossier, documents=documents)

        IStatusMessage(self.request).addStatusMessage(
            _(u"${num} documents were copied.", mapping={"num": len(intids_mapping)}), "info"
        )
Exemple #12
0
    def get_main_attributes(self):
        """ return a list of widgets,
        which should be displayed in the attributes box
        """

        def _get_state():
            state = getToolByName(self.context, "portal_workflow").getInfoFor(self.context, "review_state")

            return "<span class=wf-%s>%s</span>" % (state, translate(state, domain="plone", context=self.request))

        def _get_parent_dossier_title():
            finder = queryAdapter(self.context, name="parent-dossier-finder")
            if not finder:
                return

            dossier = finder.find_dossier()
            if not dossier:
                return None

            return dossier.Title()

        def _get_issuer():
            info = getUtility(IContactInformation)
            task = ITask(self.context)

            client_id = get_client_id()
            predecessors = self.get_predecessor_task()

            if predecessors and predecessors[0].task_type != "forwarding_task_type":
                client_id = predecessors[0].client_id
            else:
                client_id = get_client_id()

            client = client_title_helper(task, client_id)

            return client + " / " + info.render_link(task.issuer)

        def _get_task_widget_value(attr):
            field = ITask.get(attr)
            field = Field(field, interface=field.interface, prefix="")
            return get_field_widget(self.context, field).render()

        items = [
            {"label": _("label_task_title"), "value": _get_task_widget_value("title")},
            {"label": _("label_parent_dossier_title"), "value": _get_parent_dossier_title()},
            {"label": _(u"label_text", default=u"Text"), "value": _get_task_widget_value("text")},
            {"label": _(u"label_task_type", default=u"Task Type"), "value": _get_task_widget_value("task_type")},
            {"label": _("label_workflow_state"), "value": _get_state()},
            {"label": _(u"label_deadline", default=u"Deadline"), "value": _get_task_widget_value("deadline")},
            {"label": _(u"label_issuer", default=u"Issuer"), "value": _get_issuer()},
            {"label": _(u"label_responsible", default=u"Responsible"), "value": self.get_task_info(self.context)},
            {
                "label": _(u"label_date_of_completion", default=u"Date of completion"),
                "value": _get_task_widget_value("date_of_completion"),
            },
        ]

        return items
    def render(self):

        if not IInternalOpengeverRequestLayer.providedBy(self.request):
            raise Forbidden()

        transition = self.request.get('transition')
        text = self.request.get('text')
        responsible = self.request.get('responsible')
        responsible_client = self.request.get('responsible_client')

        if self.is_already_done(transition, text):
            # Set correct content type for text response
            self.request.response.setHeader("Content-type", "text/plain")

            return 'OK'

        wftool = getToolByName(self.context, 'portal_workflow')

        # change workflow state
        before = wftool.getInfoFor(self.context, 'review_state')
        before = wftool.getTitleForStateOnType(before, self.context.Type())

        wftool.doActionFor(self.context, transition)

        after = wftool.getInfoFor(self.context, 'review_state')
        after = wftool.getTitleForStateOnType(after, self.context.Type())

        # create response
        response = add_simple_response(
            self.context,
            transition=transition,
            text=text)

        if responsible and responsible is not 'None':
            # special handling for reassign
            response.add_change(
                'reponsible',
                _(u"label_responsible", default=u"Responsible"),
                ITask(self.context).responsible,
                responsible)

            ITask(self.context).responsible_client = responsible_client
            ITask(self.context).responsible = responsible

            notify(ObjectModifiedEvent(self.context))

        response.add_change('review_state', _(u'Issue state'),
                            before, after)

        # Set correct content type for text response
        self.request.response.setHeader("Content-type", "text/plain")

        return 'OK'
Exemple #14
0
    def render(self):
        data = self.request.get('data', None)
        assert data is not None, 'Bad request: no delivery data found'
        data = json.loads(data)

        if self.is_already_delivered(data):
            return ok_response()

        mtool = getToolByName(self.context, 'portal_membership')
        member = mtool.getAuthenticatedMember()

        if not member.checkPermission('Add portal content', self.context):
            raise Unauthorized()

        # Set the "X-CREATING-SUCCESSOR" flag for preventing the event
        # handler from creating additional responses per added document.
        self.request.set('X-CREATING-SUCCESSOR', True)

        # Create the delivered documents:
        transporter = Transporter()
        documents = []

        message = _(
            u'version_message_resolved_task',
            default=u'Document copied from task (task resolved)')

        if data.get(
            'transition') == 'task-transition-in-progress-tested-and-closed':
            message = _(
                u'version_message_closed_task',
                default=u'Document copied from task (task closed)')

        with CustomInitialVersionMessage(message, self.context.REQUEST):
            for item in data['documents']:
                doc = transporter.create(item, self.context)

                # append `RE:` prefix to the document title
                doc.title = '%s: %s' % (
                    translate(
                        _(u'answer_prefix', default=u'RE'),
                        context=self.context.REQUEST),
                    doc.title)

                documents.append(doc)
                notify(ObjectAddedEvent(doc))

        # Change workflow state of predecessor task:
        util.change_task_workflow_state(
            self.context, data['transition'], text=data['text'],
            added_object=documents)

        return ok_response()
Exemple #15
0
 def collect_description_data(self, language):
     """Returns a list with [label, value] pairs.
     """
     return [
         [_('label_task_title', u'Task title'), self.context.title],
         [_('label_deadline', u'Deadline'),
          api.portal.get_localized_time(str(self.context.deadline))],
         [_('label_task_type', u'Task Type'),
          self.context.get_task_type_label(language=language)],
         [_('label_dossier_title', u'Dossier title'),
          self.parent.title],
         [_('label_text', u'Text'),
          self.context.text if self.context.text else u'-' ]
     ]
Exemple #16
0
    def redirect(self):
        """Redirects to task if the current user still has View permission,
        otherwise it redirects to portal.
        """
        if api.user.has_permission('View', obj=self.context):
            msg = _(u'msg_successfully_reassigned',
                    default=u'Task successfully reassigned.')
            api.portal.show_message(msg, request=self.request, type='info')
            return self.request.RESPONSE.redirect(self.context.absolute_url())

        msg = _(u'msg_successfully_reassigned_no_longer_permission',
                default=u'Task successfully reassigned. You are no '
                'longer permitted to access the task.')
        api.portal.show_message(msg, request=self.request, type='info')
        return self.request.RESPONSE.redirect(api.portal.get().absolute_url())
Exemple #17
0
    def render(self):
        data = self.request.get("data", None)
        assert data is not None, "Bad request: no delivery data found"
        data = json.loads(data)

        if self.is_already_delivered(data):
            # Set correct content type for text response
            self.request.response.setHeader("Content-type", "tex/plain")
            return "OK"

        mtool = getToolByName(self.context, "portal_membership")
        member = mtool.getAuthenticatedMember()

        if not member.checkPermission("Add portal content", self.context):
            raise Unauthorized()

        # Set the "X-CREATING-SUCCESSOR" flag for preventing the event
        # handler from creating additional responses per added document.
        self.request.set("X-CREATING-SUCCESSOR", True)

        # Create the delivered documents:
        transporter = getUtility(ITransporter)
        documents = []

        message = _(u"version_message_resolved_task", default=u"Document copied from task (task resolved)")

        if data.get("transition") == "task-transition-in-progress-tested-and-closed":
            message = _(u"version_message_closed_task", default=u"Document copied from task (task closed)")

        with CustomInitialVersionMessage(message, self.context.REQUEST):
            for item in encode_after_json(data["documents"]):
                doc = transporter._create_object(self.context, item)

                # append `RE:` prefix to the document title
                doc.title = "%s: %s" % (
                    translate(_(u"answer_prefix", default=u"RE"), context=self.context.REQUEST),
                    doc.title,
                )

                documents.append(doc)
                notify(ObjectAddedEvent(doc))

        # Change workflow state of predecessor task:
        util.change_task_workflow_state(self.context, data["transition"], text=data["text"], added_object=documents)

        # Set correct content type for text response
        self.request.response.setHeader("Content-type", "tex/plain")
        return "OK"
Exemple #18
0
def _create_yearfolder(inbox, year):
    """creates the yearfolder for the given year"""

    _sm = AccessControl.getSecurityManager()
    AccessControl.SecurityManagement.newSecurityManager(
        inbox.REQUEST,
        AccessControl.SecurityManagement.SpecialUsers.system)
    try:
        # for creating the folder, we need to be a superuser since
        # normal user should not be able to add year folders.
        # --- help i18ndude ---
        msg = _(u'yearfolder_title', default=u'Closed ${year}',
                mapping=dict(year=str(year)))
        # --- / help i18ndude ---
        folder_title = translate(str(msg), msg.domain, msg.mapping,
                                 context=inbox.REQUEST, default=msg.default)
        folder = createContentInContainer(
            inbox, 'opengever.inbox.yearfolder',
            title=folder_title, id=year)
    except:
        AccessControl.SecurityManagement.setSecurityManager(_sm)
        raise
    else:
        AccessControl.SecurityManagement.setSecurityManager(_sm)

    return folder
Exemple #19
0
    def reminder_options(self):
        options = []
        reminder_option = TaskReminder().get_reminder(self.context)

        options.append({
            'option_type': 'no-reminder',
            'option_title': translate(_('no_reminder', default='No reminder'),
                                      context=self.request),
            'sort_order': -1,
            'selected': reminder_option is None,
            'showSpinner': False,
            })

        for option in TASK_REMINDER_OPTIONS.values():
            selected = option.option_type == reminder_option.option_type if \
                reminder_option else None
            options.append({
                'option_type': option.option_type,
                'sort_order': option.sort_order,
                'option_title': translate(
                    option.option_title, context=self.request),
                'selected': selected,
                'showSpinner': False,
            })

        return options
Exemple #20
0
    def msg(self):

        successor = self.response.get_succesor()
        return _('transition_msg_assign_to_dossier',
                 u'Assigned to dossier by ${user} successor=${successor}',
                 mapping={'user': self.response.creator_link(),
                          'successor': successor.get_link()})
Exemple #21
0
def validate_no_teams(context, responsible):
    if responsible and not context.is_open():
        if ActorLookup(responsible).is_team():
            raise Invalid(
                _(u'error_no_team_responsible_in_progress_state',
                  default=u'Team responsibles are only allowed if the task or '
                  u'forwarding is open.'))
    def handle_continue(self, action):
        data, errors = self.extractData()

        if not errors:
            oguid = self.request.get('oguid')
            key = 'accept:%s' % oguid
            dm = getUtility(IWizardDataStorage)
            text = dm.get(key, 'text')

            # forwarding
            if dm.get(key, 'is_forwarding'):
                if dm.get(key, 'is_only_assign'):
                    transition_data = {
                        'text': text,
                        'dossier': IUUID(data['dossier'])}

                    wftool = api.portal.get_tool('portal_workflow')
                    task = wftool.doActionFor(
                        Oguid.parse(oguid).resolve_object(),
                        'forwarding-transition-assign-to-dossier',
                        comment=transition_data['text'],
                        transition_params=transition_data)

                    IStatusMessage(self.request).addStatusMessage(
                        _(u'The forwarding is now assigned to the dossier'),
                        'info')
                    self.request.RESPONSE.redirect(
                        '%s/edit' % task.absolute_url())

                else:
                    task = accept_forwarding_with_successor(
                        self.context, oguid, text, dossier=data['dossier'])
                    IStatusMessage(self.request).addStatusMessage(
                        _(u'The forwarding has been stored in the local inbox '
                          u'and the succesor task has been created'), 'info')
                    self.request.RESPONSE.redirect(
                        '%s/edit' % task.absolute_url())

            # task
            else:
                task = accept_task_with_successor(
                    data['dossier'], oguid, text)

                IStatusMessage(self.request).addStatusMessage(
                    _(u'The task has been copied to the selected dossier and '
                      u'accepted.'), 'info')
                self.request.RESPONSE.redirect(task.absolute_url())
Exemple #23
0
    def redirect(self):
        """Redirects to task if the current user still has View permission,
        otherwise it redirects to portal.
        """
        if not api.user.has_permission('View', obj=self.context):
            msg = _(u'msg_transition_successful_no_longer_permission_to_access',
                    default=u'Review state successfully changed, you are no '
                    'longer permitted to access the task.')
            api.portal.show_message(msg, request=self.request, type='info')
            url = api.portal.get().absolute_url()
        else:
            msg = _(u'msg_transition_successful',
                    default=u'Review state successfully changed.')
            api.portal.show_message(msg, request=self.request, type='info')
            url = self.context.absolute_url()

        return self.request.RESPONSE.redirect(url)
 def handle_copy(self, action):
     data, errors = self.extractData()
     if not self.available():
         IStatusMessage(self.request).addStatusMessage(_(
                 u'error_copying_related_documents_not_possible',
                 default=u"It's not possible to copy related documents."))
     if not errors and data['copy_documents']:
         self.copy_documents(data['target_client'])
         info = getUtility(IContactInformation)
         client = info.get_client_by_id(data['target_client'])
         IStatusMessage(self.request).addStatusMessage(
             _(u'info_copied_related_documents',
               default=u'All related documents were copied to the inbox of '
               'the client ${client}.',
               mapping=dict(client=client.title)), type='info')
     if not errors:
         return self.request.RESPONSE.redirect(self.context.absolute_url())
Exemple #25
0
 def revoke_permissions_is_not_changed_when_disabled(data):
     if not is_optional_task_permissions_revoking_enabled():
         # Because the z3c.form.validator.Data object has implemented a
         # getattr fallback, which fetches the value from the context, we
         # need to check if the revoke_permissions value was part of the input-data.
         if 'revoke_permissions' in data._Data_data___ and not data.revoke_permissions:
             raise Invalid(_(u'error_revoke_permissions_feature_is_disabled',
                             default=u'The revoke permissions feature is disabled'))
Exemple #26
0
    def msg(self):
        docs, subtasks = self.response.get_added_objects()
        label = u' '.join([doc.title for doc in docs])

        return _('transition_add_document',
                 u'Document ${doc} added by ${user}',
                 mapping={'user': self.response.creator_link(),
                          'doc': label})
 def reassign_team_task(self, response):
     old_responsible = ITask(self.context).responsible
     ITask(self.context).responsible = api.user.get_current().getId()
     response.add_change(
         'responsible',
         _(u"label_responsible", default=u"Responsible"),
         old_responsible, ITask(self.context).responsible)
     self.context.sync()
Exemple #28
0
    def __call__(self, factories):
        factories = super(TaskPostFactoryMenu, self).__call__(factories)
        for factory in factories:
            if factory['title'] == u'Task':
                factory['title'] = _(u'Subtask')
                factory['extra']['class'] = 'icon-task-subtask'

        return factories
    def steps(self):
        # Default: 3 steps. But if more than one dossier type is addable on
        # the selected repository folder, display 3 steps and also show the
        # the dossier step selection step.

        if IRepositoryFolder.providedBy(self.context) and \
                len(allowed_dossier_types_vocabulary(self.context)) > 1:
            return (
                ('accept_choose_method',
                 _(u'step_1', default=u'Step 1')),

                ('accept_select_repositoryfolder',
                 _(u'step_2', default=u'Step 2')),

                ('accept_select_dossier_type',
                 _(u'step_3', default=u'Step 3')),

                ('accept_dossier_add_form',
                 _(u'step_4', default=u'Step 4')))

        return (
            ('accept_choose_method',
             _(u'step_1', default=u'Step 1')),

            ('accept_select_repositoryfolder',
             _(u'step_2', default=u'Step 2')),

            ('accept_dossier_add_form',
             _(u'step_3', default=u'Step 3')))
Exemple #30
0
 def reminder_init_state(self):
     return json.dumps({
         'endpoint': self.context.absolute_url() + '/@reminder',
         'reminder_options': self.reminder_options(),
         'error_msg': translate(_('error_while_updating_task_reminder',
                                  default="There was an error while "
                                          "updating the reminder"),
                                context=self.request)
     })
Exemple #31
0
    def get_main_attributes(self):
        """Return a list of widgets.

        Should be displayed in the attributes box.
        """
        task = self.context.get_sql_object()

        def _format_date(date):
            if not date:
                return ''

            return api.portal.get().toLocalizedTime(date)

        def _format_description(description):
            if not description:
                return ''

            return api.portal.get_tool(name='portal_transforms').convertTo(
                'text/html',
                description,
                mimetype='text/x-web-intelligent',
            )

        items = [
            {
                'label': _('label_task_title', u'Task title'),
                'value': task.title,
            },
            {
                'label': _('label_parent_dossier_title'),
                'value': task.containing_dossier,
            },
            {
                'label': _(u"label_text", default=u"Text"),
                'value': _format_description(task.text),
                'is_html': True,
            },
            {
                'label': _(u'label_task_type', default=u'Task Type'),
                'value': self.context.get_task_type_label(),
            },
            {
                'label': _('label_workflow_state'),
                'value': task.get_state_label(),
                'is_html': True,
            },
            {
                'label': _(u"label_deadline", default=u"Deadline"),
                'value': task.get_deadline_label(fmt="long"),
                'is_html': True,
            },
            {
                'label': _(u"label_issuer", default=u"Issuer"),
                'css_class': "issuer",
                'value': task.get_issuer_label(),
                'is_html': True,
            },
            {
                'label': _(u"label_responsible", default=u"Responsible"),
                'value': task.get_responsible_label(),
                'is_html': True,
            },
            {
                'label':
                _(u"label_date_of_completion", default=u"Date of completion"),
                'value':
                _format_date(task.get_completed()),
            },
        ]

        return items
Exemple #32
0
 def label(self):
     return _('transition_label_cancelled', u'Task cancelled')
Exemple #33
0
 def msg(self):
     return _('transition_msg_cancel', u'Cancelled by ${user}',
              mapping=self._msg_mapping)
Exemple #34
0
class ITaskCommentResponseFormSchema(Interface):
    text = schema.Text(
        title=_('label_response', default="Response"),
        required=True,
    )
Exemple #35
0
 def msg(self):
     return _('transition_msg_refuse', u'Refused by ${user}',
              mapping=self._msg_mapping)
Exemple #36
0
class AssignTaskForm(Form):
    """Form for assigning task.
    """

    fields = Fields(IAssignSchema)
    fields['responsible'].widgetFactory[INPUT_MODE] = ParameterizedWidget(
        KeywordWidget, async=True)

    ignoreContext = True
    allow_prefill_from_GET_request = True  # XXX

    label = _(u'title_assign_task', u'Assign task')

    def updateActions(self):
        super(AssignTaskForm, self).updateActions()
        self.actions["save"].addClass("context")

    @buttonAndHandler(_(u'button_assign', default=u'Assign'), name='save')
    def handle_assign(self, action):
        data, errors = self.extractData()

        if not errors:
            update_reponsible_field_data(data)
            if self.context.responsible_client == data['responsible_client'] \
                    and self.context.responsible == data['responsible']:
                # no changes
                msg = _(u'error_same_responsible',
                        default=u'No changes: same responsible selected')
                IStatusMessage(self.request).addStatusMessage(msg,
                                                              type='error')
                return self.request.RESPONSE.redirect(
                    self.context.absolute_url())

            self.reassign_task(**data)
            return self.request.RESPONSE.redirect(self.context.absolute_url())

    def reassign_task(self, **kwargs):
        response = self.add_response(**kwargs)
        self.update_task(**kwargs)
        notify(ObjectModifiedEvent(self.context))
        self.record_activity(response)
        self.sync_remote_task(**kwargs)

    def update_task(self, **kwargs):
        self.context.responsible_client = kwargs.get('responsible_client')
        self.context.responsible = kwargs.get('responsible')

    def add_response(self, **kwargs):
        return add_simple_response(self.context,
                                   text=kwargs.get('text'),
                                   field_changes=(
                                       (ITask['responsible'],
                                        kwargs.get('responsible')),
                                       (ITask['responsible_client'],
                                        kwargs.get('responsible_client')),
                                   ),
                                   transition=kwargs.get('transition'))

    def sync_remote_task(self, **kwargs):
        sync_task_response(self.context,
                           self.request,
                           'workflow',
                           kwargs.get('transition'),
                           kwargs.get('text'),
                           responsible=kwargs.get('responsible'),
                           responsible_client=kwargs.get('responsible_client'))

    def record_activity(self, response):
        TaskReassignActivity(self.context, self.context.REQUEST,
                             response).record()

    @buttonAndHandler(_(u'button_cancel', default=u'Cancel'))
    def handle_cancel(self, action):
        return self.request.RESPONSE.redirect('.')

    def updateWidgets(self):
        super(AssignTaskForm, self).updateWidgets()
        self.widgets['transition'].mode = HIDDEN_MODE
Exemple #37
0
    def deliver_documents_and_complete_task(self, formdata, response):
        """Delivers the selected documents to the predecesser task and
        complete the task:

        - Copy the documents to the predecessor task (no new responses)
        - Execute workflow transition (no new response)
        - Add a new response indicating the workflow transition, the added
        documents and containing the entered response text.
        """

        # add documents to the response
        response.added_object = PersistentList()

        predecessor = Task.query.by_oguid(self.context.predecessor)

        transporter = Transporter()
        intids = getUtility(IIntIds)

        data = {'documents': [],
                'text': formdata['text'],
                'transition': formdata['transition']}

        related_ids = []
        if getattr(self.context, 'relatedItems'):
            related_ids = [item.to_id for item in self.context.relatedItems]

        for doc_intid in formdata['documents']:
            doc = intids.getObject(int(doc_intid))
            data['documents'].append(transporter.extract(doc))

            # add a releation when a document from the dossier was selected
            if int(doc_intid) not in related_ids:
                # check if its a relation
                if aq_parent(aq_inner(doc)) != self.context:
                    # add relation to doc on task
                    if self.context.relatedItems:
                        self.context.relatedItems.append(
                            RelationValue(int(doc_intid)))
                    else:
                        self.context.relatedItems = [
                            RelationValue(int(doc_intid))]

                    # add response change entry for this relation
                    if not response.relatedItems:
                        response.relatedItems = [RelationValue(int(doc_intid))]
                    else:
                        response.relatedItems.append(
                            RelationValue(int(doc_intid)))

                    # set relation flag
                    doc._v__is_relation = True
                    response.add_change('relatedItems',
                        _(u'label_related_items', default=u"Related Items"),
                        '',
                        linked(doc, doc.Title()))

                else:
                    # add entry to the response for this document
                    response.added_object.append(RelationValue(int(doc_intid)))
            else:
                # append only the relation on the response
                doc._v__is_relation = True
                response.add_change('relatedItems',
                    _(u'label_related_items', default=u"Related Items"),
                    '',
                    linked(doc, doc.Title()))

        request_data = {'data': json.dumps(data)}
        response = dispatch_request(
            predecessor.admin_unit_id,
            '@@complete_successor_task-receive_delivery',
            predecessor.physical_path,
            data=request_data)

        response_body = response.read()
        if response_body.strip() != 'OK':
            raise Exception('Delivering documents and updating task failed '
                            'on remote client %s.' % predecessor.admin_unit_id)
Exemple #38
0
    def handleSubmit(self, action):
        data, errors = self.extractData()
        if errors:
            errorMessage = '<ul>'
            for error in errors:
                if errorMessage.find(error.message):
                    errorMessage += '<li>' + error.message + '</li>'
            errorMessage += '</ul>'
            self.status = errorMessage
            return None

        else:
            new_response = Response(data.get('text'))
            #define responseTyp
            responseCreator = new_response.creator
            task = aq_inner(self.context)
            transition = data['transition']

            if responseCreator == '(anonymous)':
                new_response.type = 'additional'
            if responseCreator == task.Creator():
                new_response.type = 'clarification'

            new_response.transition = self.transition

            #if util.getManagersVocab.getTerm(responseCreator):
            #   new_response.type =  'reply'
            #check transition
            if transition in ('task-transition-open-resolved',
                              'task-transition-in-progress-resolved'):

                completion_date = datetime.date.today()

            else:
                completion_date = None

            #check other fields
            options = [
                # (task.deadline, data.get('deadline'), 'deadline',
                #  _('deadline')),
                (task.date_of_completion, completion_date,
                 'date_of_completion', _('date_of_completion'))
            ]
            for task_field, resp_field, option, title in options:
                if resp_field and task_field != resp_field:
                    new_response.add_change(option, title, task_field,
                                            resp_field)
                    task.__setattr__(option, resp_field)

            # save relatedItems on task
            related_ids = []
            if getattr(task, 'relatedItems'):
                related_ids = [item.to_id for item in task.relatedItems]

            relatedItems = data.get('relatedItems') or []
            intids = getUtility(IIntIds)
            for item in relatedItems:
                to_id = intids.getId(item)
                # relation allready exists
                item._v__is_relation = True
                if to_id not in related_ids:
                    if getattr(task, 'relatedItems'):
                        task.relatedItems.append(RelationValue(to_id))
                    else:
                        setattr(task, 'relatedItems', [RelationValue(to_id)])

                new_response.add_change(
                    'relatedItems',
                    _(u'label_related_items', default=u"Related Items"), '',
                    linked(item, item.Title()))

            # change workflow state of task
            wftool = getToolByName(self.context, 'portal_workflow')
            before = wftool.getInfoFor(self.context, 'review_state')
            if transition != before:
                before = wftool.getTitleForStateOnType(before, task.Type())
                wftool.doActionFor(self.context, transition)
                after = wftool.getInfoFor(self.context, 'review_state')
                after = wftool.getTitleForStateOnType(after, task.Type())
                new_response.add_change('review_state', _(u'Issue state'),
                                        before, after)

            container = IResponseContainer(self.context)
            container.add(new_response)

            notify(ObjectModifiedEvent(self.context))

            self.record_activity(new_response)

            sync_task_response(self.context, self.request, 'workflow',
                               transition, data.get('text'))

            url = self.context.absolute_url()
            self.request.RESPONSE.redirect(url)
            return new_response
Exemple #39
0
 def label(self):
     return _('transition_label_reassign', u'Task reassigned')
Exemple #40
0
 def label(self):
     return _('transition_label_add_document',
              u'Document added to Task')
 def label(self):
     return self.translate_to_all_languages(
         _('transition_label_default', u'Task opened'))
Exemple #42
0
 def label(self):
     return _('transition_label_add_subtask', u'Subtask added to task')
Exemple #43
0
 def label(self):
     return _('transition_label_assign_to_dossier',
              u'Forwarding assigned to Dossier')
Exemple #44
0
 def label(self):
     return _('transition_label_refuse', u'Forwarding refused')
            def handleAdd(self, action):
                # create the dossier
                data, errors = self.extractData()
                if errors:
                    self.status = self.formErrorsMessage
                    return
                obj = self.createAndAdd(data)
                if obj is not None:
                    # mark only as finished if we get the new object
                    self._finishedAdd = True

                # Get a properly aq wrapped object
                dossier = self.context.get(obj.id)

                dm = getUtility(IWizardDataStorage)
                oguid = self.request.get('oguid')
                dmkey = 'accept:%s' % oguid

                # forwarding
                if dm.get(dmkey, 'is_forwarding'):
                    if dm.get(dmkey, 'is_only_assign'):
                        transition_data = {
                            'text': dm.get(dmkey, 'text'),
                            'dossier': IUUID(dossier)}
                        wftool = api.portal.get_tool('portal_workflow')
                        task = wftool.doActionFor(
                            Oguid.parse(oguid).resolve_object(),
                            'forwarding-transition-assign-to-dossier',
                            comment=transition_data['text'],
                            transition_params=transition_data)

                        IStatusMessage(self.request).addStatusMessage(
                            _(u'The forwarding is now assigned to the new '
                              'dossier'),
                            'info')

                        self.request.RESPONSE.redirect(
                            '%s/edit' % task.absolute_url())

                    else:
                        task = accept_forwarding_with_successor(
                            self.context,
                            oguid,
                            dm.get(dmkey, 'text'),
                            dossier=dossier)

                        IStatusMessage(self.request).addStatusMessage(
                            _(u'The forwarding has been stored in the '
                              u'local inbox and the succesor task has been'
                              u' created'), 'info')

                        self.request.RESPONSE.redirect(
                            '%s/edit' % task.absolute_url())

                else:
                    # create the successor task, accept the predecessor
                    task = accept_task_with_successor(
                        dossier,
                        oguid,
                        dm.get(dmkey, 'text'))

                    IStatusMessage(self.request).addStatusMessage(
                        _(u'The new dossier has been created and the task '
                          u'has been copied to the new dossier.'), 'info')

                    self.request.RESPONSE.redirect(task.absolute_url())
Exemple #46
0
 def label(self):
     return _('transition_label_revise', u'Task revised')
Exemple #47
0
 def label(self):
     return _('transition_label_close', u'Task closed')
Exemple #48
0
 def label(self):
     return _('transition_label_reopen', u'Task reopened')
Exemple #49
0
 def validate(self, value):
     if ActorLookup(value).is_team() and not self.context.is_open():
         raise Invalid(
             _(u'error_no_team_responsible_in_progress_state',
               default=u'Team responsibles are only allowed if the task or '
               u'forwarding is open.'))
Exemple #50
0
 def label(self):
     return _('transition_label_accept', u'Task accepted')
 def summary(self):
     actor = Actor.lookup(self.context.Creator())
     msg = _('label_task_added', u'New task opened by ${user}',
             mapping={'user': actor.get_label(with_principal=False)})
     return self.translate_to_all_languages(msg)
Exemple #52
0
 def msg(self):
     return _('transition_msg_accept', u'Accepted by ${user}',
              mapping=self._msg_mapping)
Exemple #53
0
class CompleteSuccessorTaskForm(Form):
    fields = Fields(ICompleteSuccessorTaskSchema)
    fields['documents'].widgetFactory = CheckBoxFieldWidget

    allow_prefill_from_GET_request = True  # XXX

    label = _(u'title_complete_task', u'Complete task')
    ignoreContext = True

    @buttonAndHandler(_(u'button_save', default=u'Save'),
                      name='save')
    def handle_save(self, action):
        data, errors = self.extractData()

        if not errors:
            response = util.change_task_workflow_state(self.context,
                                            data['transition'],
                                            text=data['text'])

            self.deliver_documents_and_complete_task(data, response)

            msg = _(u'The documents were delivered to the issuer and the '
                    u'tasks were completed.')
            IStatusMessage(self.request).addStatusMessage(msg, 'info')

            url = self.context.absolute_url()
            return self.request.RESPONSE.redirect(url)

    @buttonAndHandler(_(u'button_cancel', default=u'Cancel'))
    def handle_cancel(self, action):
        url = self.context.absolute_url()
        return self.request.RESPONSE.redirect(url)

    def updateWidgets(self):
        if self.request.form.get('form.widgets.transition', None) is None:
            self.request.set('form.widgets.transition',
                             self.request.get('transition'))

        # Use text passed from response-add-form.
        if self.request.form.get('form.widgets.text', None) is None:
            dm = getUtility(IWizardDataStorage)
            oguid = ISuccessorTaskController(self.context).get_oguid()
            dmkey = 'delegate:%s' % oguid
            text = dm.get(dmkey, 'text')
            if text:
                self.request.set('form.widgets.text', text)

        Form.updateWidgets(self)

        self.widgets['transition'].mode = HIDDEN_MODE

    def deliver_documents_and_complete_task(self, formdata, response):
        """Delivers the selected documents to the predecesser task and
        complete the task:

        - Copy the documents to the predecessor task (no new responses)
        - Execute workflow transition (no new response)
        - Add a new response indicating the workflow transition, the added
        documents and containing the entered response text.
        """

        # add documents to the response
        response.added_object = PersistentList()

        predecessor = Task.query.by_oguid(self.context.predecessor)

        transporter = Transporter()
        intids = getUtility(IIntIds)

        data = {'documents': [],
                'text': formdata['text'],
                'transition': formdata['transition']}

        related_ids = []
        if getattr(self.context, 'relatedItems'):
            related_ids = [item.to_id for item in self.context.relatedItems]

        for doc_intid in formdata['documents']:
            doc = intids.getObject(int(doc_intid))
            data['documents'].append(transporter.extract(doc))

            # add a releation when a document from the dossier was selected
            if int(doc_intid) not in related_ids:
                # check if its a relation
                if aq_parent(aq_inner(doc)) != self.context:
                    # add relation to doc on task
                    if self.context.relatedItems:
                        self.context.relatedItems.append(
                            RelationValue(int(doc_intid)))
                    else:
                        self.context.relatedItems = [
                            RelationValue(int(doc_intid))]

                    # add response change entry for this relation
                    if not response.relatedItems:
                        response.relatedItems = [RelationValue(int(doc_intid))]
                    else:
                        response.relatedItems.append(
                            RelationValue(int(doc_intid)))

                    # set relation flag
                    doc._v__is_relation = True
                    response.add_change('relatedItems',
                        _(u'label_related_items', default=u"Related Items"),
                        '',
                        linked(doc, doc.Title()))

                else:
                    # add entry to the response for this document
                    response.added_object.append(RelationValue(int(doc_intid)))
            else:
                # append only the relation on the response
                doc._v__is_relation = True
                response.add_change('relatedItems',
                    _(u'label_related_items', default=u"Related Items"),
                    '',
                    linked(doc, doc.Title()))

        request_data = {'data': json.dumps(data)}
        response = dispatch_request(
            predecessor.admin_unit_id,
            '@@complete_successor_task-receive_delivery',
            predecessor.physical_path,
            data=request_data)

        response_body = response.read()
        if response_body.strip() != 'OK':
            raise Exception('Delivering documents and updating task failed '
                            'on remote client %s.' % predecessor.admin_unit_id)
Exemple #54
0
 def reminder_option_date_validator(data):
     if data.reminder_option == ReminderOnDate.option_type and \
             not data.reminder_option_date:
         raise Invalid(
             _(u'no_remind_date_error',
               default=u'Please choose a remind date'))
        class WrappedForm(AcceptWizardNewDossierFormMixin, formclass):
            step_name = 'accept_dossier_add_form'
            passed_data = ['oguid', 'dossier_type']
            step_title = steptitle

            @buttonAndHandler(_(u'button_save', default=u'Save'), name='save')
            def handleAdd(self, action):
                # create the dossier
                data, errors = self.extractData()
                if errors:
                    self.status = self.formErrorsMessage
                    return
                obj = self.createAndAdd(data)
                if obj is not None:
                    # mark only as finished if we get the new object
                    self._finishedAdd = True

                # Get a properly aq wrapped object
                dossier = self.context.get(obj.id)

                dm = getUtility(IWizardDataStorage)
                oguid = self.request.get('oguid')
                dmkey = 'accept:%s' % oguid

                # forwarding
                if dm.get(dmkey, 'is_forwarding'):
                    if dm.get(dmkey, 'is_only_assign'):
                        task = assign_forwarding_to_dossier(
                            self.context, oguid, dossier,
                            dm.get(dmkey, 'text'))

                        IStatusMessage(self.request).addStatusMessage(
                            _(u'The forwarding is now assigned to the new '
                              'dossier'), 'info')

                        self.request.RESPONSE.redirect('%s/edit' %
                                                       task.absolute_url())

                    else:
                        task = accept_forwarding_with_successor(
                            self.context,
                            oguid,
                            dm.get(dmkey, 'text'),
                            dossier=dossier)

                        IStatusMessage(self.request).addStatusMessage(
                            _(u'The forwarding has been stored in the '
                              u'local inbox and the succesor task has been'
                              u' created'), 'info')

                        self.request.RESPONSE.redirect('%s/edit' %
                                                       task.absolute_url())

                else:
                    # create the successor task, accept the predecessor
                    task = accept_task_with_successor(dossier, oguid,
                                                      dm.get(dmkey, 'text'))

                    IStatusMessage(self.request).addStatusMessage(
                        _(u'The new dossier has been created and the task '
                          u'has been copied to the new dossier.'), 'info')

                    self.request.RESPONSE.redirect(task.absolute_url())

            @buttonAndHandler(dexterityMF(u'Cancel'), name='cancel')
            def handleCancel(self, action):
                portal_url = getToolByName(self.context, 'portal_url')
                url = '%s/resolve_oguid?oguid=%s' % (portal_url(),
                                                     self.request.get('oguid'))
                return self.request.RESPONSE.redirect(url)
Exemple #56
0
class TaskTransitionResponseAddForm(form.AddForm, AutoExtensibleForm):

    allow_prefill_from_GET_request = True  # XXX

    fields = field.Fields(ITaskTransitionResponseFormSchema)
    # keep widget for converters (even though field is hidden)
    fields['transition'].widgetFactory = radio.RadioFieldWidget
    fields = fields.omit('date_of_completion')

    @property
    def label(self):
        label = self.context.Title().decode('utf-8')
        transition = translate(self.transition,
                               domain='plone',
                               context=self.request)
        return u'{}: {}'.format(label, transition)

    @property
    def transition(self):
        if not hasattr(self, '_transition'):
            self._transition = self.request.get('form.widgets.transition',
                                                self.request.get('transition'))
            if not self._transition:
                raise BadRequest("A transition is required")
        return self._transition

    def updateActions(self):
        super(TaskTransitionResponseAddForm, self).updateActions()
        self.actions["save"].addClass("context")

    @button.buttonAndHandler(_(u'save', default='Save'), name='save')
    def handleSubmit(self, action):
        data, errors = self.extractData()
        if errors:
            errorMessage = '<ul>'
            for error in errors:
                if errorMessage.find(error.message):
                    errorMessage += '<li>' + error.message + '</li>'
            errorMessage += '</ul>'
            self.status = errorMessage
            return None

        else:
            new_response = Response(data.get('text'))
            #define responseTyp
            responseCreator = new_response.creator
            task = aq_inner(self.context)
            transition = data['transition']

            if responseCreator == '(anonymous)':
                new_response.type = 'additional'
            if responseCreator == task.Creator():
                new_response.type = 'clarification'

            new_response.transition = self.transition

            #if util.getManagersVocab.getTerm(responseCreator):
            #   new_response.type =  'reply'
            #check transition
            if transition in ('task-transition-open-resolved',
                              'task-transition-in-progress-resolved'):

                completion_date = datetime.date.today()

            else:
                completion_date = None

            #check other fields
            options = [
                # (task.deadline, data.get('deadline'), 'deadline',
                #  _('deadline')),
                (task.date_of_completion, completion_date,
                 'date_of_completion', _('date_of_completion'))
            ]
            for task_field, resp_field, option, title in options:
                if resp_field and task_field != resp_field:
                    new_response.add_change(option, title, task_field,
                                            resp_field)
                    task.__setattr__(option, resp_field)

            # save relatedItems on task
            related_ids = []
            if getattr(task, 'relatedItems'):
                related_ids = [item.to_id for item in task.relatedItems]

            relatedItems = data.get('relatedItems') or []
            intids = getUtility(IIntIds)
            for item in relatedItems:
                to_id = intids.getId(item)
                # relation allready exists
                item._v__is_relation = True
                if to_id not in related_ids:
                    if getattr(task, 'relatedItems'):
                        task.relatedItems.append(RelationValue(to_id))
                    else:
                        setattr(task, 'relatedItems', [RelationValue(to_id)])

                new_response.add_change(
                    'relatedItems',
                    _(u'label_related_items', default=u"Related Items"), '',
                    linked(item, item.Title()))

            # change workflow state of task
            wftool = getToolByName(self.context, 'portal_workflow')
            before = wftool.getInfoFor(self.context, 'review_state')
            if transition != before:
                before = wftool.getTitleForStateOnType(before, task.Type())
                wftool.doActionFor(self.context, transition)
                after = wftool.getInfoFor(self.context, 'review_state')
                after = wftool.getTitleForStateOnType(after, task.Type())
                new_response.add_change('review_state', _(u'Issue state'),
                                        before, after)

            container = IResponseContainer(self.context)
            container.add(new_response)

            notify(ObjectModifiedEvent(self.context))

            self.record_activity(new_response)

            sync_task_response(self.context, self.request, 'workflow',
                               transition, data.get('text'))

            url = self.context.absolute_url()
            self.request.RESPONSE.redirect(url)
            return new_response

    @button.buttonAndHandler(
        _(u'cancel', default='Cancel'),
        name='cancel',
    )
    def handleCancel(self, action):
        return self.request.RESPONSE.redirect('.')

    def updateWidgets(self):
        form.AddForm.updateWidgets(self)
        if self.context.portal_type == 'opengever.inbox.forwarding':
            self.widgets['relatedItems'].mode = HIDDEN_MODE
        if not self.is_user_assigned_to_current_org_unit():
            self.widgets['relatedItems'].mode = HIDDEN_MODE

        self.widgets['transition'].mode = HIDDEN_MODE

    def is_user_assigned_to_current_org_unit(self):
        units = ogds_service().assigned_org_units()
        return get_current_org_unit() in units

    def record_activity(self, response):
        TaskTransitionActivity(self.context, self.context.REQUEST,
                               response).record()
Exemple #57
0
class ITask(form.Schema):

    form.fieldset(
        u'common',
        label=_(u'fieldset_common', default=u'Common'),
        fields=[
            u'title',
            u'issuer',
            u'task_type',
            u'responsible_client',
            u'responsible',
            u'deadline',
            u'text',
            u'relatedItems',
        ],
    )

    form.fieldset(
        u'additional',
        label=_(u'fieldset_additional', u'Additional'),
        fields=[
            u'expectedStartOfWork',
            u'expectedDuration',
            u'expectedCost',
            u'effectiveDuration',
            u'effectiveCost',
            u'date_of_completion',
        ],
    )

    dexteritytextindexer.searchable('title')
    title = schema.TextLine(
        title=_(u"label_title", default=u"Title"),
        description=_('help_title', default=u""),
        required=True,
        max_length=256,
    )

    form.widget('issuer', KeywordFieldWidget, async=True)
    issuer = schema.Choice(
        title=_(u"label_issuer", default=u"Issuer"),
        source=UsersContactsInboxesSourceBinder(),
        required=True,
    )

    form.widget(task_type='z3c.form.browser.radio.RadioFieldWidget')
    task_type = schema.Choice(
        title=_(u'label_task_type', default=u'Task Type'),
        description=_('help_task_type', default=u''),
        required=True,
        readonly=False,
        default=None,
        missing_value=None,
        source=util.getTaskTypeVocabulary,
    )

    form.mode(responsible_client='hidden')
    responsible_client = schema.Choice(
        title=_(u'label_resonsible_client', default=u'Responsible Client'),
        description=_(u'help_responsible_client', default=u''),
        vocabulary='opengever.ogds.base.OrgUnitsVocabularyFactory',
        required=True)

    form.widget('responsible', KeywordFieldWidget, async=True)
    responsible = schema.Choice(
        title=_(u"label_responsible", default=u"Responsible"),
        description=_(u"help_responsible", default=""),
        source=AllUsersInboxesAndTeamsSourceBinder(include_teams=True),
        required=True,
    )

    form.widget(deadline=DatePickerFieldWidget)
    deadline = schema.Date(
        title=_(u"label_deadline", default=u"Deadline"),
        description=_(u"help_deadline", default=u""),
        required=True,
        defaultFactory=deadline_default,
    )

    form.widget(date_of_completion=DatePickerFieldWidget)
    form.mode(IAddForm, date_of_completion=HIDDEN_MODE)
    date_of_completion = schema.Date(
        title=_(u"label_date_of_completion", default=u"Date of completion"),
        description=_(u"help_date_of_completion", default=u""),
        required=False,
    )

    dexteritytextindexer.searchable('text')
    form.primary('text')
    text = schema.Text(
        title=_(u"label_text", default=u"Text"),
        description=_(u"help_text", default=u""),
        required=False,
    )

    relatedItems = RelationList(
        title=_(u'label_related_items', default=u'Related Items'),
        default=[],
        missing_value=[],
        value_type=RelationChoice(
            title=u"Related",
            source=DossierPathSourceBinder(
                portal_type=("opengever.document.document", "ftw.mail.mail"),
                navigation_tree_query={
                    'object_provides': [
                        'opengever.dossier.behaviors.dossier.IDossierMarker',
                        'opengever.document.document.IDocumentSchema',
                        'opengever.task.task.ITask',
                        'ftw.mail.mail.IMail',
                    ],
                }),
        ),
        required=False,
    )

    form.widget(expectedStartOfWork=DatePickerFieldWidget)
    expectedStartOfWork = schema.Date(
        title=_(u"label_expectedStartOfWork", default="Start with work"),
        required=False,
    )

    expectedDuration = schema.Float(
        title=_(
            u"label_expectedDuration",
            default="Expected duration",
        ),
        description=_(u"help_expectedDuration", default="Duration in h"),
        required=False,
    )

    expectedCost = schema.Float(
        title=_(u"label_expectedCost", default="expected cost"),
        description=_(u"help_expectedCost", default="Cost in CHF"),
        required=False,
    )

    effectiveDuration = schema.Float(
        title=_(u"label_effectiveDuration", default="effective duration"),
        description=_(u"help_effectiveDuration", default="Duration in h"),
        required=False,
    )

    effectiveCost = schema.Float(
        title=_(u"label_effectiveCost", default="effective cost"),
        description=_(u"help_effectiveCost", default="Cost in CHF"),
        required=False,
    )

    form.omitted('predecessor')
    predecessor = schema.TextLine(title=_(u'label_predecessor',
                                          default=u'Predecessor'),
                                  required=False)
Exemple #58
0
def accept_forwarding_with_successor(context,
                                     predecessor_oguid,
                                     response_text,
                                     dossier=None):

    # the predessecor (the forwarding on the remote client)
    predecessor = Task.query.by_oguid(predecessor_oguid)

    # Set the "X-CREATING-SUCCESSOR" flag for preventing the event handler
    # from creating additional responses per added document.
    context.REQUEST.set('X-CREATING-SUCCESSOR', True)

    # transport the remote forwarding to the inbox or actual yearfolder
    transporter = Transporter()
    inbox = get_current_inbox(context)
    if dossier:
        yearfolder = get_current_yearfolder(inbox=inbox)
        successor_forwarding = transporter.transport_from(
            yearfolder, predecessor.admin_unit_id, predecessor.physical_path)
    else:
        successor_forwarding = transporter.transport_from(
            inbox, predecessor.admin_unit_id, predecessor.physical_path)

    # Replace the issuer with the current inbox
    successor_forwarding.issuer = get_current_org_unit().inbox().id()

    successor_tc = ISuccessorTaskController(successor_forwarding)

    # copy documents and map the intids
    doc_transporter = getUtility(ITaskDocumentsTransporter)

    comment = _(
        u'version_message_accept_forwarding',
        default=u'Document copied from forwarding (forwarding accepted)')
    intids_mapping = doc_transporter.copy_documents_from_remote_task(
        predecessor, successor_forwarding, comment=comment)

    # copy the responses
    response_transporter = IResponseTransporter(successor_forwarding)
    response_transporter.get_responses(predecessor.admin_unit_id,
                                       predecessor.physical_path,
                                       intids_mapping=intids_mapping)

    # Remove current responsible from predecessor and add issuer
    # and responsible to successor's watcher.
    center = notification_center()
    center.remove_task_responsible(Oguid.parse(predecessor_oguid),
                                   successor_forwarding.responsible)
    center.add_task_responsible(successor_forwarding,
                                successor_forwarding.responsible)
    center.add_task_issuer(successor_forwarding, successor_forwarding.issuer)

    # if a dossier is given means that a successor task must
    # be created in a new or a existing dossier
    if dossier:
        # we need all task field values from the forwarding
        fielddata = {}
        for fieldname in ITask.names():
            value = ITask.get(fieldname).get(successor_forwarding)
            fielddata[fieldname] = value

        # Predefine the task_type to avoid tasks with an invalid task_type
        fielddata['task_type'] = FORWARDING_SUCCESSOR_TYPE

        # lets create a new task - the successor task
        task = createContentInContainer(dossier, 'opengever.task.task',
                                        **fielddata)

        # copy documents and map the intids
        intids_mapping = _copy_documents_from_forwarding(
            successor_forwarding, task)

        # copy the responses
        response_transporter = IResponseTransporter(task)
        response_transporter.get_responses(
            get_current_admin_unit().id(),
            '/'.join(successor_forwarding.getPhysicalPath()),
            intids_mapping=intids_mapping)

        # successor
        successor_tc_task = ISuccessorTaskController(task)

    transaction.savepoint()

    # Close the predessecor forwarding
    response_text = response_text or ''
    request_data = {
        'response_text': response_text.encode('utf-8'),
        'successor_oguid': successor_tc.get_oguid(),
        'transition': 'forwarding-transition-accept'
    }

    response = dispatch_request(predecessor.admin_unit_id,
                                '@@store_forwarding_in_yearfolder',
                                path=predecessor.physical_path,
                                data=request_data)

    response_body = response.read()
    if response_body.strip() != 'OK':
        raise TaskRemoteRequestError(
            'Adding the response and changing the workflow state on the '
            'predecessor forwarding failed.')

    if dossier:
        # Update watchers for created successor forwarding and task
        center = notification_center()
        center.remove_task_responsible(successor_forwarding, task.responsible)
        center.add_task_responsible(task, task.responsible)

        # When a successor task exists, we close also the successor forwarding
        change_task_workflow_state(
            successor_forwarding,
            'forwarding-transition-accept',
            text=response_text,
            successor_oguid=successor_tc_task.get_oguid())

    # create the succssor relations
    successor_tc.set_predecessor(predecessor_oguid)
    if dossier:
        successor_tc_task.set_predecessor(successor_tc.get_oguid())
        return task
    return successor_forwarding
Exemple #59
0
 def label(self):
     return _('transition_label_modify_deadline', u'Task deadline modified')
Exemple #60
0
class TaskTransitionResponseAddForm(form.AddForm, AutoExtensibleForm):

    allow_prefill_from_GET_request = True  # XXX

    fields = field.Fields(ITaskTransitionResponseFormSchema)
    # keep widget for converters (even though field is hidden)
    fields['transition'].widgetFactory = radio.RadioFieldWidget
    fields['reminder_option_date'].widgetFactory[
        INPUT_MODE] = DatePickerFieldWidget
    fields = fields.omit('date_of_completion')

    def update(self):
        super(TaskTransitionResponseAddForm, self).update()
        if api.user.is_anonymous():
            # Traversing request from relation widget
            return ''

        disable_edit_bar()

        if self.is_final_transition:
            if self.context.revoke_permissions:
                self.status = _(
                    u'msg_revoking_permissions',
                    default=u'This transtion revokes temporary permissions for '
                    'the responsible user and agency group.')

            else:
                self.status = _(
                    u'msg_not_revoking_permissions',
                    default=u'Temporary permissions will not be revoked by this '
                    'transtion as revoke permissions is unchecked for this task'
                )

    @property
    def label(self):
        label = self.context.Title().decode('utf-8')
        transition = translate(self.transition,
                               domain='plone',
                               context=self.request)
        return u'{}: {}'.format(label, transition)

    @property
    def transition(self):
        # Ignore unauthorized requests (called by the contenttree widget)
        if api.user.get_current() == nobody:
            return

        if not hasattr(self, '_transition'):
            self._transition = self.request.get('form.widgets.transition',
                                                self.request.get('transition'))
            if not self._transition:
                raise BadRequest("A transition is required")
        return self._transition

    @property
    def is_final_transition(self):
        return self.transition in FINAL_TRANSITIONS

    def is_api_supported_transition(self, transition):
        return transition in [
            "task-transition-open-in-progress",
            "task-transition-in-progress-resolved",
            "task-transition-resolved-tested-and-closed",
            "task-transition-in-progress-tested-and-closed"
            "task-transition-open-tested-and-closed",
            "task-transition-open-rejected",
            "task-transition-in-progress-cancelled",
            "task-transition-open-cancelled", "task-transition-cancelled-open",
            "task-transition-rejected-open"
        ]

    def updateActions(self):
        super(TaskTransitionResponseAddForm, self).updateActions()
        self.actions["save"].addClass("context")

    @button.buttonAndHandler(_(u'save', default='Save'), name='save')
    def handleSubmit(self, action):
        data, errors = self.extractData()
        if errors:
            return

        intids = getUtility(IIntIds)
        data['relatedItems'] = [
            intids.getId(item) for item in data['relatedItems']
        ]
        wftool = api.portal.get_tool('portal_workflow')
        wftool.doActionFor(self.context,
                           self.transition,
                           comment=data.get('text'),
                           transition_params=data)

        self.handleReminder(data.get('reminder_option'),
                            data.get('reminder_option_date'))

        return self.redirect()

    @button.buttonAndHandler(
        _(u'cancel', default='Cancel'),
        name='cancel',
    )
    def handleCancel(self, action):
        return self.request.RESPONSE.redirect('.')

    def updateWidgets(self):
        form.AddForm.updateWidgets(self)
        if self.context.portal_type == 'opengever.inbox.forwarding':
            self.widgets['relatedItems'].mode = HIDDEN_MODE
        if not self.is_user_assigned_to_current_org_unit():
            self.widgets['relatedItems'].mode = HIDDEN_MODE

        self.widgets['transition'].mode = HIDDEN_MODE

        if self.transition != 'task-transition-open-in-progress':
            self.widgets['reminder_option'].mode = HIDDEN_MODE
            self.widgets['reminder_option_date'].mode = HIDDEN_MODE

    def handleReminder(self, reminder_option, reminder_option_date):
        params = {}
        if reminder_option == ReminderOnDate.option_type:
            params = {'date': reminder_option_date}

        if reminder_option:
            reminder = Reminder.create(reminder_option, params)
            self.context.set_reminder(reminder)
        else:
            self.context.clear_reminder()

    def redirect(self):
        """Redirects to task if the current user still has View permission,
        otherwise it redirects to portal.
        """
        if not api.user.has_permission('View', obj=self.context):
            msg = _(
                u'msg_transition_successful_no_longer_permission_to_access',
                default=u'Review state successfully changed, you are no '
                'longer permitted to access the task.')
            api.portal.show_message(msg, request=self.request, type='info')
            url = api.portal.get().absolute_url()
        else:
            msg = _(u'msg_transition_successful',
                    default=u'Review state successfully changed.')
            api.portal.show_message(msg, request=self.request, type='info')
            url = self.context.absolute_url()

        return self.request.RESPONSE.redirect(url)

    def is_user_assigned_to_current_org_unit(self):
        units = ogds_service().assigned_org_units()
        return get_current_org_unit() in units