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())
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)
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())
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)
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
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')
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" )
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'
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()
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'-' ] ]
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())
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"
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
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
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()})
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())
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())
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'))
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()
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')))
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) })
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
def label(self): return _('transition_label_cancelled', u'Task cancelled')
def msg(self): return _('transition_msg_cancel', u'Cancelled by ${user}', mapping=self._msg_mapping)
class ITaskCommentResponseFormSchema(Interface): text = schema.Text( title=_('label_response', default="Response"), required=True, )
def msg(self): return _('transition_msg_refuse', u'Refused by ${user}', mapping=self._msg_mapping)
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
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)
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
def label(self): return _('transition_label_reassign', u'Task reassigned')
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'))
def label(self): return _('transition_label_add_subtask', u'Subtask added to task')
def label(self): return _('transition_label_assign_to_dossier', u'Forwarding assigned to Dossier')
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())
def label(self): return _('transition_label_revise', u'Task revised')
def label(self): return _('transition_label_close', u'Task closed')
def label(self): return _('transition_label_reopen', u'Task reopened')
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.'))
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)
def msg(self): return _('transition_msg_accept', u'Accepted by ${user}', mapping=self._msg_mapping)
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)
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)
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()
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)
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
def label(self): return _('transition_label_modify_deadline', u'Task deadline modified')
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