From 26cd75696c121aa3e61207abc26a77447be90cf4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jordi=20Puiggen=C3=A9?= <jp@naralabs.com> Date: Thu, 5 Dec 2024 14:14:23 +0100 Subject: [PATCH] Fix method is not updated on instrument update in worksheet --- src/bika/lims/content/instrument.py | 30 ++++++++++----- src/bika/lims/content/worksheet.py | 57 +++++++++++++++++------------ 2 files changed, 55 insertions(+), 32 deletions(-) diff --git a/src/bika/lims/content/instrument.py b/src/bika/lims/content/instrument.py index f1ad9af24d..6495ff2b58 100644 --- a/src/bika/lims/content/instrument.py +++ b/src/bika/lims/content/instrument.py @@ -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(( @@ -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" + ) ), ), @@ -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. diff --git a/src/bika/lims/content/worksheet.py b/src/bika/lims/content/worksheet.py index f0b51372d2..c05b1930a3 100644 --- a/src/bika/lims/content/worksheet.py +++ b/src/bika/lims/content/worksheet.py @@ -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