Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Compliance of Analyses from Samples with Specification #1506

Merged
merged 65 commits into from
Jan 31, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
65 commits
Select commit Hold shift + click to select a range
a9a6f9c
Better handling of Specification + ResultsRange in Sample
xispa Jan 19, 2020
9f965bf
Added viewlet for Specification vs Results Range differences
xispa Jan 19, 2020
3223886
Viewlet for when field change is populated to partitions
xispa Jan 20, 2020
c6ecd41
Added IAnalysisRequestWithPartitions interface
xispa Jan 20, 2020
4d48dd8
Store ResultsRange directly to Analyses
xispa Jan 20, 2020
fce8121
Typo
xispa Jan 21, 2020
78ad28a
Add uid property in ResultsRangeDict
xispa Jan 21, 2020
b8aed86
When a new Specification is applied, apply changes to analyses too
xispa Jan 21, 2020
045e413
Refactor create_analysisrequest function
xispa Jan 21, 2020
d17d8ff
Refactor aranalysesfield
xispa Jan 21, 2020
ce062e3
SpecificationsField must return empty dict instead of None
xispa Jan 21, 2020
7953041
When Specification's results ranges are changed, reapply to Sample
xispa Jan 21, 2020
85afa68
Compare with previous snapshot, not with the first one
xispa Jan 21, 2020
7720f3e
Sample's ResultsRange does not get updated when applied to single ana…
xispa Jan 21, 2020
a1ddfcf
Some functions from aranalysesfield return a list now
xispa Jan 21, 2020
d678899
Fix NameError: global name 'api' is not defined
xispa Jan 21, 2020
4850539
Merge branch 'master' into specs-inconsistencies
xispa Jan 21, 2020
c3d5bd1
Ensure ResultsRangeField always return a copy
xispa Jan 21, 2020
e977716
Added doctest
xispa Jan 21, 2020
902762e
More rules in doctest
xispa Jan 21, 2020
f08795e
Ensure no duplicates are stored in Sample's ResultsRange
xispa Jan 21, 2020
c9e4847
More test use cases
xispa Jan 21, 2020
104a865
Populate Sample ResultsRange settings to partitions
xispa Jan 21, 2020
53ca631
Use case for when Partitions are used with specs assignment
xispa Jan 21, 2020
be07d62
aranalysesfield clean-up
xispa Jan 22, 2020
64eb918
Fix possible recursion error when fetching calculation dependencies
xispa Jan 22, 2020
7d2ab9b
Remove unnecessary stuff from the doctest
xispa Jan 22, 2020
25aa1c0
Make setAnalyses from ARAnalysesField to not return anything
xispa Jan 22, 2020
49565e2
SpecificationsField -> ResultsRangesField
xispa Jan 22, 2020
1abd2a2
A bit of clean-up
xispa Jan 22, 2020
2103bec
Ensure ResultsRange value is always stored as a built-in dict
xispa Jan 22, 2020
aaa0485
Assume that an analysis is added w/o specs, it does not break compliance
xispa Jan 22, 2020
9c0b3c5
Remove getResultsRangeDict from analysisspecs
xispa Jan 22, 2020
bfa362a
Populate Sample's ResultsRanges to Partitions on creation
xispa Jan 22, 2020
894482b
Add some comments
xispa Jan 22, 2020
1d228e1
Revisit InternalUse
xispa Jan 22, 2020
48efff0
Apply result ranges to analyses that are not yet submitted only
xispa Jan 22, 2020
50a4bf5
Viewlet for when analyses with non-compliant ranges
xispa Jan 23, 2020
6d2deef
Fix unexpected keyword argument 'remove_primary_analyses'
xispa Jan 23, 2020
d7aa06b
Better messages
xispa Jan 23, 2020
40310d1
Emphasize analyses with non-compliant ranges in analyses listing
xispa Jan 23, 2020
d08bfeb
Fix test
xispa Jan 23, 2020
7b5e918
Changelog
xispa Jan 23, 2020
b767436
Remove unnecessary code
xispa Jan 23, 2020
1109aa3
Merge branch 'master' of github.com:senaite/senaite.core into specs-i…
xispa Jan 28, 2020
d91f8ac
Sample can have multiple analyses with same Keyword
xispa Jan 28, 2020
0981217
Skip invalid/cancelled analyses while setting results range
xispa Jan 29, 2020
ede9506
Always store results ranges as str
xispa Jan 29, 2020
ed2db9a
Omit services not present in sample when checking if specs is out-of-…
xispa Jan 29, 2020
ee1a3ca
Added viewlet in Sample for when dynamic spec is assigned
xispa Jan 29, 2020
b1e8c1f
Remove unnecessary code
xispa Jan 29, 2020
baac0b2
Fix test
xispa Jan 29, 2020
c78a3cd
Upgrade step
xispa Jan 30, 2020
ed6a004
Bad comment
xispa Jan 30, 2020
b36e10f
Better equals for ResultRangeDict
xispa Jan 30, 2020
04425c1
specifications --> results_ranges
xispa Jan 30, 2020
91467bc
Remove internal imports of ResultsRangeDict
xispa Jan 30, 2020
c9b239f
Non-supported "error" subfield is imported in specs through setup data
xispa Jan 31, 2020
656c9b1
Revert "Remove internal imports of ResultsRangeDict"
xispa Jan 31, 2020
98df11a
Removed "primary bound" viewlet
ramonski Jan 31, 2020
7b938f2
Commit changes during the migration step to free some memory
ramonski Jan 31, 2020
7d94ebb
Minor cleanup and PEP8
ramonski Jan 31, 2020
a8ed74f
Preserve the sample specification if no changes are done
ramonski Jan 31, 2020
ae4c87b
Do not re-assign the Specification unless different value
xispa Jan 31, 2020
6b83f3b
Remove unnecessary log.error
xispa Jan 31, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions CHANGES.rst
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@ Changelog

**Added**

- #1506 Specification non-compliant viewlet in Sample
- #1506 Sample results ranges out-of-date viewlet in Sample
- #1506 Warn icon in analyses when range is not compliant with Specification
- #1492 Dynamic Analysis Specifications
- #1507 Support for semi-colon character separator in CCEmails field
- #1499 Moved navigation portlet into core
Expand Down Expand Up @@ -36,6 +39,9 @@ Changelog

**Fixed**

- #1506 Changes via manage results don't get applied to partitions
- #1506 Fix recursion error when getting dependencies through Calculation
- #1506 setter from ARAnalysisField does no longer return values
- #1512 QC Analyses listing appears empty in Sample view
- #1510 Error when viewing a Sample w/o Batch as client contact
- #1511 Links to partitions for Internal Use are displayed in partitions viewlet
Expand Down
32 changes: 32 additions & 0 deletions bika/lims/api/analysis.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@
IResultOutOfRange
from zope.component._api import getAdapters

from bika.lims.interfaces.analysis import IRequestAnalysis


def is_out_of_range(brain_or_object, result=_marker):
"""Checks if the result for the analysis passed in is out of range and/or
Expand Down Expand Up @@ -148,3 +150,33 @@ def get_formatted_interval(results_range, default=_marker):
max_bracket = max_operator == 'leq' and ']' or ')'

return "{}{};{}{}".format(min_bracket, min_str, max_str, max_bracket)


def is_result_range_compliant(analysis):
"""Returns whether the result range from the analysis matches with the
result range for the service counterpart defined in the Sample
"""
if not IRequestAnalysis.providedBy(analysis):
return True

rr = analysis.getResultsRange()
service_uid = rr.get("uid", None)
if not api.is_uid(service_uid):
return True

# Compare with Sample
sample = analysis.getRequest()

# If no Specification is set, assume is compliant
specification = sample.getRawSpecification()
if not specification:
return True

# Compare with the Specification that was initially set to the Sample
sample_rr = sample.getResultsRange(search_by=service_uid)
if not sample_rr:
# This service is not defined in Sample's ResultsRange, we
# assume this *does not* break the compliance
return True

return rr == sample_rr
32 changes: 23 additions & 9 deletions bika/lims/browser/analyses/view.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,15 @@
from DateTime import DateTime
from Products.Archetypes.config import REFERENCE_CATALOG
from Products.CMFPlone.utils import safe_unicode
from plone.memoize import view as viewcache
from zope.component import getAdapters

from bika.lims import api
from bika.lims import bikaMessageFactory as _
from bika.lims import logger
from bika.lims.api.analysis import get_formatted_interval
from bika.lims.api.analysis import is_out_of_range
from bika.lims.api.analysis import is_result_range_compliant
from bika.lims.browser.bika_listing import BikaListingView
from bika.lims.catalog import CATALOG_ANALYSIS_LISTING
from bika.lims.config import LDL
Expand All @@ -51,8 +55,6 @@
from bika.lims.utils import get_link
from bika.lims.utils import t
from bika.lims.utils.analysis import format_uncertainty
from plone.memoize import view as viewcache
from zope.component import getAdapters


class AnalysesView(BikaListingView):
Expand Down Expand Up @@ -1033,13 +1035,25 @@ def _folder_item_specifications(self, analysis_brain, item):

# Show an icon if out of range
out_range, out_shoulders = is_out_of_range(analysis_brain)
if not out_range:
return
# At least is out of range
img = get_image("exclamation.png", title=_("Result out of range"))
if not out_shoulders:
img = get_image("warning.png", title=_("Result in shoulder range"))
self._append_html_element(item, "Result", img)
if out_range:
msg = _("Result out of range")
img = get_image("exclamation.png", title=msg)
if not out_shoulders:
msg = _("Result in shoulder range")
img = get_image("warning.png", title=msg)
self._append_html_element(item, "Result", img)

# Show an icon if the analysis range is different from the Sample spec
if IAnalysisRequest.providedBy(self.context):
analysis = self.get_object(analysis_brain)
if not is_result_range_compliant(analysis):
service_uid = analysis_brain.getServiceUID
original = self.context.getResultsRange(search_by=service_uid)
original = get_formatted_interval(original, "")
msg = _("Result range is different from Specification: {}"
.format(original))
img = get_image("warning.png", title=msg)
self._append_html_element(item, "Specification", img)

def _folder_item_verify_icons(self, analysis_brain, item):
"""Set the analysis' verification icons to the item passed in.
Expand Down
2 changes: 1 addition & 1 deletion bika/lims/browser/analysisrequest/add2.py
Original file line number Diff line number Diff line change
Expand Up @@ -1670,7 +1670,7 @@ def ajax_submit(self):
client,
self.request,
record,
specifications=specifications
results_ranges=specifications
)
except (KeyError, RuntimeError) as e:
actions.resume()
Expand Down
22 changes: 17 additions & 5 deletions bika/lims/browser/analysisrequest/manage_analyses.py
Original file line number Diff line number Diff line change
Expand Up @@ -142,12 +142,24 @@ def show_ar_specs(self):

@view.memoize
def get_results_range(self):
"""Get the results Range from the AR
"""Get the results Range from the Sample, but gives priority to the
result ranges set in analyses. This guarantees that result ranges for
already present analyses are not overriden after form submission
"""
spec = self.context.getResultsRange()
if spec:
return dicts_to_dict(spec, "keyword")
return ResultsRangeDict()
# Extract the result ranges from Sample analyses
analyses = self.analyses.values()
analyses_rrs = map(lambda an: an.getResultsRange(), analyses)
analyses_rrs = filter(None, analyses_rrs)
rrs = dicts_to_dict(analyses_rrs, "keyword")

# Bail out ranges from Sample that are already present in analyses
sample_rrs = self.context.getResultsRange()
sample_rrs = filter(lambda rr: rr["keyword"] not in rrs, sample_rrs)
sample_rrs = dicts_to_dict(sample_rrs, "keyword")

# Extend result ranges with those from Sample
rrs.update(sample_rrs)
return rrs

@view.memoize
def get_currency_symbol(self):
Expand Down
45 changes: 0 additions & 45 deletions bika/lims/browser/analysisspec.py

This file was deleted.

12 changes: 0 additions & 12 deletions bika/lims/browser/analysisspec.zcml

This file was deleted.

1 change: 0 additions & 1 deletion bika/lims/browser/configure.zcml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@
<include file="analysisprofile.zcml"/>
<include file="analysisreport.zcml"/>
<include file="analysisservice.zcml"/>
<include file="analysisspec.zcml"/>
<include file="arimports.zcml"/>
<include file="artemplate.zcml"/>
<include file="attachment.zcml"/>
Expand Down
2 changes: 2 additions & 0 deletions bika/lims/browser/fields/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,3 +30,5 @@
from .proxyfield import ProxyField
from .uidreferencefield import UIDReferenceField
from .emailsfield import EmailsField
from .resultrangefield import ResultRangeField
from .resultsrangesfield import ResultsRangesField
Loading