Ejemplo n.º 1
0
def guard_verify(analysis_request):
    """Returns whether the transition "verify" can be performed or not.
    Returns True if at there is at least one analysis in a non-dettached state
    and all analyses in a non-detached state are in "verified" state.
    """
    # Discard detached analyses
    analyses = analysis_request.getAnalyses(full_objects=True)
    analyses = filter(
        lambda an: api.get_workflow_status_of(an) not in
        ANALYSIS_DETACHED_STATES, analyses)

    # If not all analyses are for internal use, rely on "regular" analyses
    internals = map(IInternalUse.providedBy, analyses)
    omit_internals = not all(internals)

    analyses_ready = False
    for analysis in analyses:
        # Omit analyses for internal use
        if omit_internals and IInternalUse.providedBy(analysis):
            continue

        # All analyses must be in verified (or further) status
        if not IVerified.providedBy(analysis):
            return False

        analyses_ready = True
    return analyses_ready
Ejemplo n.º 2
0
def guard_submit(analysis_request):
    """Return whether the transition "submit" can be performed or not.
    Returns True if there is at least one analysis in a non-detached state and
    all analyses in a non-detached analyses have been submitted.
    """
    # Discard detached analyses
    analyses = analysis_request.getAnalyses(full_objects=True)
    analyses = filter(
        lambda an: api.get_workflow_status_of(an) not in
        ANALYSIS_DETACHED_STATES, analyses)

    # If not all analyses are for internal use, rely on "regular" analyses
    internals = map(IInternalUse.providedBy, analyses)
    omit_internals = not all(internals)

    analyses_ready = False
    for analysis in analyses:
        # Omit analyses for internal use
        if omit_internals and IInternalUse.providedBy(analysis):
            continue

        analysis_status = api.get_workflow_status_of(analysis)
        if analysis_status in ['assigned', 'unassigned', 'registered']:
            return False

        analyses_ready = True
    return analyses_ready
Ejemplo n.º 3
0
def ObjectModifiedEventHandler(instance, event):
    """Actions to be taken when AnalysisRequest object is modified
    """
    # If Internal Use value has been modified, apply suitable permissions
    internal_use = instance.getInternalUse()
    if internal_use != IInternalUse.providedBy(instance):

        # Update permissions for current sample
        update_internal_use_permissions(instance)

        # Mark/Unmark all analyses with IInternalUse to control their
        # visibility in results reports
        for analysis in instance.objectValues("Analysis"):
            if internal_use:
                alsoProvides(analysis, IInternalUse)
            else:
                noLongerProvides(analysis, IInternalUse)

            # Reindex analysis security in catalogs
            analysis.reindexObjectSecurity()

        # If internal use is True, cascade same setting to partitions
        if internal_use:
            for partition in instance.getDescendants():
                partition.setInternalUse(internal_use)
                # Notify the partition has been modified
                modified(partition)
Ejemplo n.º 4
0
 def get_analyses(self, model_or_collection):
     """Returns a flat list of all analyses for the given model or collection
     """
     collection = self.to_list(model_or_collection)
     analyses = chain(*map(lambda m: m.Analyses, collection))
     # Boil out analyses meant to be used for internal use only
     analyses = filter(lambda an: not IInternalUse.providedBy(an.instance),
                       analyses)
     return self.sort_items(analyses)
Ejemplo n.º 5
0
def guard_publish(analysis_request):
    """Returns whether the transition "publish" can be performed or not.
    Returns True if the analysis request is not labeled for internal use or if
    at least one of the contained analyses is not for internal use
    """
    if IInternalUse.providedBy(analysis_request):
        return False
    # Note we return True without checking anything else because this
    # transition is only available when sample is in verified status
    return True
Ejemplo n.º 6
0
def guard_prepublish(analysis_request):
    """Returns whether 'prepublish' transition can be perform or not. Returns
    True if the analysis request has at least one analysis in 'verified' or in
    'to_be_verified' status. Otherwise, return False
    """
    if IInternalUse.providedBy(analysis_request):
        return False

    valid_states = ['verified', 'to_be_verified']
    for analysis in analysis_request.getAnalyses():
        analysis = api.get_object(analysis)
        if api.get_workflow_status_of(analysis) in valid_states:
            return True
    return False
Ejemplo n.º 7
0
def after_submit(analysis):
    """Event fired when an analysis result gets submitted
    """
    if not IASTAnalysis.providedBy(analysis):
        return

    # Check that values for all interim fields are set
    interim_fields = analysis.getInterimFields()
    values = map(lambda interim: interim.get("value"), interim_fields)
    if not all(values):
        return

    # All siblings for same microorganism and sample have to be submitted
    siblings = utils.get_ast_siblings(analysis)
    submitted = map(ISubmitted.providedBy, siblings)
    if not all(submitted):
        return

    # Calculate the hidden analyses and results
    analyses = siblings + [analysis]

    # We only do report results from "resistance" analysis
    resistance = filter(lambda an: an.getKeyword() == RESISTANCE_KEY, analyses)
    resistance = resistance[0]

    # Results are the values (R/S/+/-) set for resistance' interim fields
    results = resistance.getInterimFields()

    # Find out the resistance results to report
    report_analysis = filter(lambda an: an.getKeyword() == REPORT_KEY,
                             analyses)
    if report_analysis:
        # The results to be reported are defined by the Y/N values set for the
        # interim fields of the "selective reporting" analysis
        to_report = report_analysis[0].getInterimFields()

        # XXX senaite.app.listing has no support boolean type for interim fields
        to_report = filter(lambda k: k.get("value") == "1", to_report)

        # Get the abbreviation of microorganisms (keyword)
        keywords = map(lambda k: k.get("keyword"), to_report)

        # Filter the interim fields from resistance
        results = filter(lambda r: r.get("keyword") in keywords, results)

    # The "selected" result options are those to be reported
    options = resistance.getResultOptions()

    def to_report(option):
        key = option.get("InterimKeyword")
        val = option.get("InterimValue")
        for target in results:
            if key == target.get("keyword") and val == target.get("value"):
                return True
        return False

    # Remove the antibiotics to not report from options
    options = filter(to_report, options)

    # The final result is a list with result option values
    result = map(lambda o: o.get("ResultValue"), options)

    # No need to keep track of this in audit (this is internal)
    noLongerProvides(resistance, IAuditable)

    # Set the final result
    capture_date = resistance.getResultCaptureDate()
    resistance.setResult(result)
    resistance.setResultCaptureDate(capture_date)

    # We do want to report this resistance analysis
    if IInternalUse.providedBy(resistance):
        noLongerProvides(resistance, IInternalUse)

    # Re-enable the audit for this analysis
    alsoProvides(resistance, IAuditable)