diff --git a/bika/lims/browser/worksheet/views/add_analyses.py b/bika/lims/browser/worksheet/views/add_analyses.py index 6157547f0b..52e386f340 100644 --- a/bika/lims/browser/worksheet/views/add_analyses.py +++ b/bika/lims/browser/worksheet/views/add_analyses.py @@ -38,9 +38,11 @@ def __init__(self, context, request): self.context_actions = {} # initial review state for first form display of the worksheet # add_analyses search view - first batch of analyses, latest first. + self.sort_on = 'Priority' self.contentFilter = {'portal_type': 'Analysis', 'review_state':'sample_received', 'worksheetanalysis_review_state':'unassigned', + 'sort_on': 'getPrioritySortkey', 'cancellation_state':'active'} self.base_url = self.context.absolute_url() self.view_url = self.base_url + "/add_analyses" diff --git a/bika/lims/browser/worksheet/workflow.py b/bika/lims/browser/worksheet/workflow.py index 58dc38e4da..8d1e41a5c7 100644 --- a/bika/lims/browser/worksheet/workflow.py +++ b/bika/lims/browser/worksheet/workflow.py @@ -8,8 +8,10 @@ from AccessControl import getSecurityManager from bika.lims import bikaMessageFactory as _ from bika.lims import PMF +from bika.lims.api import get_tool from bika.lims.browser.bika_listing import WorkflowAction from bika.lims.browser.referenceanalysis import AnalysesRetractedListReport +from bika.lims.catalog.analysis_catalog import CATALOG_ANALYSIS_LISTING from bika.lims.permissions import EditResults, EditWorksheet, ManageWorksheets from bika.lims.subscribers import doActionFor from bika.lims.subscribers import skip @@ -105,16 +107,17 @@ def __call__(self): self.request.response.redirect(self.context.absolute_url()) return - selected_analyses = WorkflowAction._get_selected_items(self) - selected_analysis_uids = selected_analyses.keys() - if selected_analyses: - for uid in selected_analysis_uids: - analysis = rc.lookupObject(uid) - # Double-check the state first - if (workflow.getInfoFor(analysis, 'worksheetanalysis_review_state') == 'unassigned' - and workflow.getInfoFor(analysis, 'review_state') == 'sample_received' - and workflow.getInfoFor(analysis, 'cancellation_state') == 'active'): - self.context.addAnalysis(analysis) + analysis_uids = form.get("uids", []) + if analysis_uids: + # We retrieve the analyses from the database sorted by AR ID + # ascending, so the positions of the ARs inside the WS are + # consistent with the order of the ARs + catalog = get_tool(CATALOG_ANALYSIS_LISTING) + brains = catalog({'UID': analysis_uids, + 'sort_on': 'getRequestID'}) + for brain in brains: + analysis = brain.getObject() + self.context.addAnalysis(analysis) self.destination_url = self.context.absolute_url() self.request.response.redirect(self.destination_url) diff --git a/bika/lims/content/abstractroutineanalysis.py b/bika/lims/content/abstractroutineanalysis.py index 7a45f1c666..0c1e3c33b1 100644 --- a/bika/lims/content/abstractroutineanalysis.py +++ b/bika/lims/content/abstractroutineanalysis.py @@ -16,6 +16,7 @@ from bika.lims.browser.fields import HistoryAwareReferenceField, \ InterimFieldsField, UIDReferenceField from bika.lims.browser.widgets import DecimalWidget, RecordsWidget +from bika.lims.catalog.indexers.baseanalysis import sortable_title from bika.lims.content.abstractanalysis import AbstractAnalysis from bika.lims.content.abstractanalysis import schema from bika.lims.content.reflexrule import doReflexRuleAction @@ -477,13 +478,20 @@ def getDependencies(self): @security.public def getPrioritySortkey(self): """ - Returns the key that will be used to sort the current Analysis - Delegates to getPrioritySortKey function from the AnalysisRequest + Returns the key that will be used to sort the current Analysis, from + most prioritary to less prioritary. :return: string used for sorting """ analysis_request = self.getRequest() - if analysis_request: - return analysis_request.getPrioritySortkey() + if analysis_request is None: + return None + ar_sort_key = analysis_request.getPrioritySortkey() + ar_id = analysis_request.getId().lower() + title = sortable_title(self) + if callable(title): + title = title() + return '{}.{}.{}'.format(ar_sort_key, ar_id, title) + @security.public def getHidden(self): diff --git a/bika/lims/upgrade/configure.zcml b/bika/lims/upgrade/configure.zcml index f868f4edcd..85c5e43410 100644 --- a/bika/lims/upgrade/configure.zcml +++ b/bika/lims/upgrade/configure.zcml @@ -24,4 +24,11 @@ handler="bika.lims.upgrade.v01_01_000.upgrade" profile="bika.lims:default"/> + + diff --git a/bika/lims/upgrade/utils.py b/bika/lims/upgrade/utils.py index 1c0576785b..4462694b1e 100644 --- a/bika/lims/upgrade/utils.py +++ b/bika/lims/upgrade/utils.py @@ -286,6 +286,16 @@ def addColumn(self, catalog, column): self.refreshcatalog.append(cat.id) transaction.commit() + def reindexIndex(self, catalog, index): + cat = self._getCatalog(catalog) + if index not in cat.indexes(): + logger.warn("Index {} not found in {}".format(index, catalog)) + return + indexes = self.reindexcatalog.get(cat.id, []) + if index not in indexes: + indexes.append(index) + self.reindexcatalog[cat.id] = indexes + def refreshCatalogs(self): """ It reindexes the modified catalogs but, while cleanAndRebuildCatalogs diff --git a/bika/lims/upgrade/v01_01_001.py b/bika/lims/upgrade/v01_01_001.py new file mode 100644 index 0000000000..73aea1f31d --- /dev/null +++ b/bika/lims/upgrade/v01_01_001.py @@ -0,0 +1,37 @@ +from Acquisition import aq_inner +from Acquisition import aq_parent +from bika.lims import logger +from bika.lims.catalog import CATALOG_ANALYSIS_LISTING +from bika.lims.config import PROJECTNAME as product +from bika.lims.upgrade import upgradestep +from bika.lims.upgrade.utils import UpgradeUtils + +version = '1.1.1' +profile = 'profile-{0}:default'.format(product) + + +@upgradestep(product, version) +def upgrade(tool): + portal = aq_parent(aq_inner(tool)) + setup = portal.portal_setup + ut = UpgradeUtils(portal) + ver_from = ut.getInstalledVersion(product) + + if ut.isOlderVersion(product, version): + logger.info("Skipping upgrade of {0}: {1} > {2}".format( + product, ver_from, version)) + # The currently installed version is more recent than the target + # version of this upgradestep + return True + + logger.info("Upgrading {0}: {1} -> {2}".format(product, ver_from, version)) + + # Reindex getPrioritySortkey index. The priority sort key from analyses + # takes also into account analyses have to be sorted by their sortkey, so + # two analyses with same priority, same AR, but different sort key values + # don't get mixed. + ut.reindexIndex(CATALOG_ANALYSIS_LISTING, 'getPrioritySortkey') + ut.refreshCatalogs() + + logger.info("{0} upgraded to version {1}".format(product, version)) + return True