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

Fix method is not updated on instrument change in worksheet #2657

Merged
merged 4 commits into from
Dec 6, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
1 change: 1 addition & 0 deletions CHANGES.rst
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ Changelog
2.6.0 (unreleased)
------------------

- #2657 Methods from analyses are not updated on instrument change in worksheet
- #2656 Fix AnalysisProfile keyword validator fail with non-ascii value
- #2646 Add SelectOtherField and SelectOtherWidget
- #2649 Fix event subscribers are not triggered on analysis initialization
Expand Down
30 changes: 21 additions & 9 deletions src/bika/lims/content/instrument.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@
from senaite.core.catalog import SETUP_CATALOG
from senaite.core.exportimport import instruments
from senaite.core.p3compat import cmp
from zope.deprecation import deprecate
from zope.interface import implements

schema = BikaFolderSchema.copy() + BikaSchema.copy() + Schema((
Expand Down Expand Up @@ -160,15 +161,21 @@
),

UIDReferenceField(
'Methods',
vocabulary='_getAvailableMethods',
allowed_types=('Method',),
relationship='InstrumentMethods',
"Methods",
vocabulary="_getAvailableMethods",
allowed_types=("Method",),
relationship="InstrumentMethods",
required=0,
multiValued=1,
widget=PicklistWidget(
size=10,
label=_("Methods"),
label=_(u"label_instrument_methods",
default=u"Supported methods"),
description=_(
u"description_instrument_methods",
default=u"Methods that are supported by this analytical "
u"instrument"
)
),
),

Expand Down Expand Up @@ -414,11 +421,16 @@ def getMaintenanceTypesList(self):
def getCalibrationAgentsList(self):
return getCalibrationAgents(self)

def getRawMethods(self):
"""Returns the UIDs of the methods supported by this instrument

:returns: Method UIDs
"""
return self.getField("Methods").getRaw(self)

@deprecate("Use getRawMethods instead")
def getMethodUIDs(self):
uids = []
if self.getMethods():
uids = [m.UID() for m in self.getMethods()]
return uids
return self.getRawMethods()

def _getAvailableMethods(self):
""" Returns the available (active) methods.
Expand Down
57 changes: 34 additions & 23 deletions src/bika/lims/content/worksheet.py
Original file line number Diff line number Diff line change
Expand Up @@ -1194,36 +1194,47 @@ def getNumberOfRegularSamples(self):
return len(set(samples))

def setInstrument(self, instrument, override_analyses=False):
""" Sets the specified instrument to the Analysis from the
Worksheet. Only sets the instrument if the Analysis
allows it, according to its Analysis Service and Method.
If an analysis has already assigned an instrument, it won't
be overriden.
The Analyses that don't allow the instrument specified will
not be modified.
Returns the number of analyses affected
"""Assigns the specified analytical instrument to the analyses in this
worksheet that are compatible with the instrument. The system will
attempt to assign the first method supported by the instrument that is
also compatible with each analysis.

By default, the instrument and method assigned to the analysis won't be
replaced unless the analysis does not have an instrument assigned yet
or the parameter override_analyses is set to True. Analyses that are
incompatible with the specified instrument will remain unchanged.
"""
analyses = [an for an in self.getAnalyses()
if (not an.getInstrument() or override_analyses) and
an.isInstrumentAllowed(instrument)]
analyses = self.getAnalyses()
instrument = api.get_object(instrument, default=None)

# find out the methods supported by the instrument, if any
supported_methods = instrument.getRawMethods() if instrument else []

total = 0
for an in analyses:
# An analysis can be done using differents Methods.
# Un method can be supported by more than one Instrument,
# but not all instruments support one method.
# We must force to set the instrument's method too. Otherwise,
# the WS manage results view will display the an's default
# method and its instruments displaying, only the instruments
# for the default method in the picklist.
instr_methods = instrument.getMethods()
meth = instr_methods[0] if instr_methods else None
if meth and an.isMethodAllowed(meth):
if an.getMethod() not in instr_methods:
an.setMethod(meth)

if not override_analyses and an.getRawInstrument():
# skip, no overwrite analysis if an instrument is set
continue

if not an.isInstrumentAllowed(instrument):
# skip, instrument cannot run this analysis
continue

# assign the instrument
an.setInstrument(instrument)
total += 1

if an.getRawMethod() in supported_methods:
# the analysis method is supported by this instrument
continue

# reset and try to assign the first supported method
allowed = an.getRawAllowedMethods()
methods = list(filter(lambda m: m in allowed, supported_methods))
method = methods[0] if methods else None
an.setMethod(method)

self.getField('Instrument').set(self, instrument)
return total

Expand Down