def after_reject(obj): """Method triggered after a 'reject' transition for the Analysis Request passed in is performed. Transitions and sets the rejection reasons to the parent Sample. Also transitions the analyses assigned to the AR bika.lims.workflow.AfterTransitionEventHandler :param obj: Analysis Request affected by the transition :type obj: AnalysisRequest """ sample = obj.getSample() if not sample: return if getCurrentState(sample) != 'rejected': doActionFor(sample, 'reject') reasons = obj.getRejectionReasons() sample.setRejectionReasons(reasons) # Deactivate all analyses from this Analysis Request ans = obj.getAnalyses(full_objects=True) for analysis in ans: doActionFor(analysis, 'reject') if obj.bika_setup.getNotifyOnRejection(): # Import here to brake circular importing somewhere from bika.lims.utils.analysisrequest import notify_rejection # Notify the Client about the Rejection. notify_rejection(obj)
def after_reject(analysis_request): """Method triggered after a 'reject' transition for the Analysis Request passed in is performed. Cascades the transition to descendants (partitions) and analyses as well. If "notify on rejection" setting is enabled, sends a notification to the client contact. """ do_action_to_descendants(analysis_request, "reject") do_action_to_analyses(analysis_request, "reject") # TODO Workflow - AnalysisRequest - Revisit rejection notification if not analysis_request.bika_setup.getNotifyOnSampleRejection(): return ancestor = analysis_request.getParentAnalysisRequest() if ancestor and api.get_workflow_status_of(ancestor) == "rejected": # No need to notify, notification done by the ancestor return # Notify the Client about the Rejection. from bika.lims.utils.analysisrequest import notify_rejection notify_rejection(analysis_request)
def __call__(self): form = self.request.form # Form submit toggle form_submitted = form.get("submitted", False) # Buttons form_continue = form.get("button_continue", False) form_cancel = form.get("button_cancel", False) # Is Rejection Workflow Enabled if not self.is_rejection_workflow_enabled: return self.redirect( message=_("Rejection workflow is not enabled"), level="warning") # Get the objects from request samples = self.get_samples_from_request() # No Samples selected if not samples: return self.redirect(message=_("No items selected"), level="warning") # Handle rejection if form_submitted and form_continue: logger.info("*** REJECT SAMPLES ***") processed = [] for sample in form.get("samples", []): sample_uid = sample.get("uid", "") reasons = sample.get("reasons", []) other = sample.get("other_reasons", "") if not sample_uid: continue # Omit if no rejection reason specified if not any([reasons, other]): continue # This is quite bizarre! # AR's Rejection reasons is a RecordsField, but with one # record only, that contains both predefined and other reasons. obj = api.get_object_by_uid(sample_uid) rejection_reasons = {"other": other, "selected": reasons} obj.setRejectionReasons([rejection_reasons]) wf.doActionFor(obj, "reject") processed.append(obj) # Client needs to be notified? if sample.get("notify", "") == "on": notify_rejection(obj) if not processed: return self.redirect(message=_("No samples were rejected")) message = _("Rejected {} samples: {}").format( len(processed), ", ".join(map(api.get_id, processed))) return self.redirect(message=message) # Handle cancel if form_submitted and form_cancel: logger.info("*** CANCEL REJECTION ***") return self.redirect(message=_("Rejection cancelled")) return self.template()