class ReclassificationEditorialReview(WorkItemBaseForm): """ The base class works for the items of the quotationtool.classify workflow, too.""" label = EditorBranchForm.label info = _( 'reclassification-review-info', u"The database item below has recently been reclassified. The selections of category labels from the form below need to be reviewed before the show up in the database." ) @button.buttonAndHandler(_(u"Accept (Save to item)"), name="accept") def handleAccept(self, action): self._handle('accept') @button.buttonAndHandler(_(u"Reject (Keep old selections)"), name="reject") def handleReject(self, action): self._handle('reject') @button.buttonAndHandler(_(u"Postpone (Save as draft)"), name="postpone") def handlePostpone(self, action): self._handle('postpone') @button.buttonAndHandler(_(u"Cancel"), name="cancel") def handleCancel(self, action): self.request.response.redirect(self.nextURL())
def OFFstartHook(self): if not interfaces.ICategorizable.providedBy(self.object_): raise ProcessError( _( 'icategorizable-not-provided', u"Database item can't be classified/categorized. (ICategorizable not provided.)" ))
class EditorialReviewForm(EditorBranchForm): """ For the editorial review in the split branch.""" info = _( 'attribution-editorial-review-info', u"The database item below has recently been created and categorized by a user. Please review the selection of category labels in the form below." )
def finish(self, finish, message): if not finish in ('postpone', 'accept', 'reject'): raise ProcessError( _(u"Error finishing workitem: $finish", mapping={'finish': finish})) self.message = message self._removeFromWorkList() self.participant.activity.workItemFinished(self, finish, message, self.history)
class DisplayForm(AttributionFieldsMixin, form.DisplayForm): """Show the attributions on a categorizable object. """ zope.interface.implements(ITabbedContentLayout) label = _('attribution-label', u"Categorization") ignoreContext = False
def update(self): # assert that there are no other classification processes if findWorkItemsForItemAndProcessId(self.context, 'quotationtool.reclassify') or \ findWorkItemsForItemAndProcessId(self.context, 'quotationtool.classify'): raise UserError( _(u"This database item is subject of a classification task already. It must be finished before a new classification process is started." )) super(ReclassificationForm, self).update() self.updateAttributionSubForm() if self.checkPermission(): self.info = self.info_for_editors
def __call__(self): ctxt = removeAllProxies(self.context) item = ctxt.participant.activity.process.context.item label = zope.component.queryMultiAdapter((item, self.request), name='label') if not label: return _(u"Unkown") try: return translate(label(), context=self.request) except Exception: return label()
class EditorBranchForm(WorkItemBaseForm): """ For editorial review.""" label = _('attribution-editorbranch-label', u"Categorization Task") info = _( 'attribution-editorbranch-info', u"The database item below has been created recently and has not yet been categorized. Please select category labels from the form below." ) @button.buttonAndHandler(_(u"Finish (Save to item)"), name="finish") def handleFinish(self, action): self._handle('finish') @button.buttonAndHandler(_(u"Postpone (Save as draft)"), name="postpone") def handlePostpone(self, action): self._handle('postpone') @button.buttonAndHandler(_(u"Cancel"), name="cancel") def handleCancel(self, action): self.request.response.redirect(self.nextURL())
class ContributorBranchForm(WorkItemBaseForm): """ For contributor work item in the split branch.""" label = EditorBranchForm.label info = EditorBranchForm.info @button.buttonAndHandler(_(u"Finish"), name="finish") def handleFinish(self, action): self._handle('finish') @button.buttonAndHandler(_(u"Postpone (Save as draft)"), name="postpone") def handlePostpone(self, action): self._handle('postpone') @button.buttonAndHandler(_(u"Cancel"), name="cancel") def handleCancel(self, action): self.request.response.redirect(self.nextURL()) def nextURL(self): for location in LocationIterator(self.context): if zope.component.interfaces.ISite.providedBy(location): break return absoluteURL(location, self.request) + u"/account/@@worklist.html"
def classifySubscriber(item, event): """ A subscriber for an object event that fires a quotationtool.classify workflow process for this item.""" pd = zope.component.getUtility(IProcessDefinition, name='quotationtool.classify') context = ClassificationContext(item) process = pd(context) contributor = u"unkown" for principal in getInteraction().participations: if IPrincipal.providedBy(principal): contributor = principal.id elif IRequest.providedBy(principal): contributor = principal.principal.id break history = IWorkflowHistory(item) process.start(contributor, datetime.datetime.now(), _(u"Newly created items need to be classified."), history, PersistentAttribution())
class AttributionCriterium(criterium.SetSearchCriterium): """ Search criterium""" indexOrName = ATTRIBUTION_INDEX label = _('attribution-criterium', u"Category Label")
def __call__(self): return _('categoriescontainer-label', u"Classification")
def __call__(self): return _(u"Re-Classification")
class ReclassificationForm(form.Form): """ A reclassification form. Depending on permissions the form starts a reclassification workflow (for normal quotationtool.Members) or writes the new selections to the context item (for quotationtool.Editors).""" zope.interface.implements(ITabbedContentLayout) fields = field.Fields(comment) label = _(u"Reclassify") info = _( 'reclassification-info', u"Please select category labels from the form below. Your selections will soon be reviewed by the editors of this website and then show up in the database." ) info_for_editors = _( 'reclassification-info-for-editors', u"Please select category labels from the form below.") ignoreContext = True ignoreReadOnly = True process_started = False def checkPermission(self): interaction = getInteraction() return interaction.checkPermission( 'quotationtool.workflow.DoEditorialReview', self.context) def update(self): # assert that there are no other classification processes if findWorkItemsForItemAndProcessId(self.context, 'quotationtool.reclassify') or \ findWorkItemsForItemAndProcessId(self.context, 'quotationtool.classify'): raise UserError( _(u"This database item is subject of a classification task already. It must be finished before a new classification process is started." )) super(ReclassificationForm, self).update() self.updateAttributionSubForm() if self.checkPermission(): self.info = self.info_for_editors def updateAttributionSubForm(self): self.attribution = ReAttributionSubForm(self.context, self.request, self) self.attribution.update() @button.buttonAndHandler(_(u"Apply"), name='reclassify') def handleReclassify(self, action): self.updateAttributionSubForm() data, errors = self.extractData() if errors: self.status = self.formErrorsMessage return history = IWorkflowHistory(self.context) principal = getattr(self.request, 'principal', None) if self.checkPermission(): # store input data to context (attribution.getContent() returns it) self.attribution.storeToWorkItem() else: # store input data to persistent attribution pattr = PersistentAttribution() attr_data, attr_errors = self.attribution.extractData() categories = [] for catset in attr_data.values(): for cat in catset: categories.append(cat.__name__) pattr.set(categories) # start workflow process self.process_started = True pd = zope.component.getUtility(IProcessDefinition, name='quotationtool.reclassify') context = ReclassificationContext(removeAllProxies(self.context)) proc = pd(context) proc.start(getattr(principal, 'id', u"Unknown"), datetime.datetime.now(), data['workflow-message'], removeAllProxies(history), removeAllProxies(pattr)) # write history history.append( UserNotation(getattr(principal, 'id', u"Unknown"), data['workflow-message'])) zope.event.notify(ObjectModifiedEvent(self.context)) # redirect to next url self.request.response.redirect(self.nextURL()) @button.buttonAndHandler(_(u"Cancel"), name="cancel") def handleCancel(self, action): self.request.response.redirect(self.nextURL()) def nextURL(self): return absoluteURL(self.context, self.request) + u"/@@attribution.html"
def getCategorizableItem(self): ctxt = removeAllProxies(self.context) return ctxt.participant.activity.process.context.item def storeToWorkItem(self): data, errors = self.extractData() categories = [] for catset in data.values(): for cat in catset: categories.append(cat.__name__) attr = interfaces.IAttribution(self.getContent()) attr.set(categories) comment = zope.schema.Text( title=_('classification-comment-title', u"Message"), description=_( 'classification-comment-desc', u"If you want to leave a message about your decisions you can leave it here." ), required=False, ) comment.__name__ = 'workflow-message' class WorkItemBaseForm(AttributionFieldsMixin, form.Form): zope.interface.implements(IWorkItemForm) fields = field.Fields(comment)