From 7ba4728f3290b26df01045541078273db5c9a710 Mon Sep 17 00:00:00 2001 From: Ramon Bartl Date: Fri, 14 Feb 2020 21:56:36 +0100 Subject: [PATCH 1/6] Moved progress calculation to content class --- .../analysisrequest/analysisrequests.py | 32 +++---------------- bika/lims/catalog/analysisrequest_catalog.py | 1 + bika/lims/content/analysisrequest.py | 26 +++++++++++++++ bika/lims/upgrade/v01_03_003.py | 25 +++++++++++++-- 4 files changed, 54 insertions(+), 30 deletions(-) diff --git a/bika/lims/browser/analysisrequest/analysisrequests.py b/bika/lims/browser/analysisrequest/analysisrequests.py index 55eb107c4a..ef8ebb6831 100644 --- a/bika/lims/browser/analysisrequest/analysisrequests.py +++ b/bika/lims/browser/analysisrequest/analysisrequests.py @@ -84,7 +84,8 @@ def __init__(self, context, request): "sortable": True, }), ("Progress", { "title": "Progress", - "sortable": False, + "index": "getProgress", + "sortable": True, "toggle": True}), ("getId", { "title": _("Sample ID"), @@ -573,7 +574,8 @@ def folderitem(self, obj, item, index): item["getAnalysesNum"] = "" # Progress - progress_perc = self.get_progress_percentage(obj) + progress_perc = obj.getProgress + item["Progress"] = progress_perc item["replace"]["Progress"] = get_progress_bar_html(progress_perc) item["BatchID"] = obj.getBatchID @@ -732,32 +734,6 @@ def folderitem(self, obj, item, index): return item - def get_progress_percentage(self, ar_brain): - """Returns the percentage of completeness of the Analysis Request - """ - review_state = ar_brain.review_state - if review_state == "published": - return 100 - - numbers = ar_brain.getAnalysesNum - - num_analyses = numbers[1] or 0 - if not num_analyses: - return 0 - - # [verified, total, not_submitted, to_be_verified] - num_to_be_verified = numbers[3] or 0 - num_verified = numbers[0] or 0 - - # 2 steps per analysis (submit, verify) plus one step for publish - max_num_steps = (num_analyses * 2) + 1 - num_steps = num_to_be_verified + (num_verified * 2) - if not num_steps: - return 0 - if num_steps > max_num_steps: - return 100 - return (num_steps * 100) / max_num_steps - @property def copy_to_new_allowed(self): mtool = api.get_tool("portal_membership") diff --git a/bika/lims/catalog/analysisrequest_catalog.py b/bika/lims/catalog/analysisrequest_catalog.py index 8bb69662b2..a0ef71c40f 100644 --- a/bika/lims/catalog/analysisrequest_catalog.py +++ b/bika/lims/catalog/analysisrequest_catalog.py @@ -116,6 +116,7 @@ "getSamplingWorkflowEnabled", "assigned_state", "getInternalUse", + "getProgress", ] # Adding basic indexes diff --git a/bika/lims/content/analysisrequest.py b/bika/lims/content/analysisrequest.py index 5d594d1d16..13d8051b4e 100644 --- a/bika/lims/content/analysisrequest.py +++ b/bika/lims/content/analysisrequest.py @@ -2469,5 +2469,31 @@ def process_inline_images(self, html): return html + def getProgress(self): + """Returns the progress in percent of all analyses + """ + review_state = api.get_review_status(self) + if review_state == "published": + return 100 + + numbers = self.getAnalysesNum() + + num_analyses = numbers[1] or 0 + if not num_analyses: + return 0 + + # [verified, total, not_submitted, to_be_verified] + num_to_be_verified = numbers[3] or 0 + num_verified = numbers[0] or 0 + + # 2 steps per analysis (submit, verify) plus one step for publish + max_num_steps = (num_analyses * 2) + 1 + num_steps = num_to_be_verified + (num_verified * 2) + if not num_steps: + return 0 + if num_steps > max_num_steps: + return 100 + return (num_steps * 100) / max_num_steps + registerType(AnalysisRequest, PROJECTNAME) diff --git a/bika/lims/upgrade/v01_03_003.py b/bika/lims/upgrade/v01_03_003.py index f0835eefdc..bc4093be8b 100644 --- a/bika/lims/upgrade/v01_03_003.py +++ b/bika/lims/upgrade/v01_03_003.py @@ -18,14 +18,15 @@ # Copyright 2018-2020 by it's authors. # Some rights reserved, see README and LICENSE. +import re from collections import defaultdict from operator import itemgetter -import re import transaction from bika.lims import api from bika.lims import logger from bika.lims.api.mail import is_valid_email_address +from bika.lims.catalog import BIKA_CATALOG from bika.lims.catalog import CATALOG_ANALYSIS_LISTING from bika.lims.catalog import CATALOG_ANALYSIS_REQUEST_LISTING from bika.lims.catalog.bikasetup_catalog import SETUP_CATALOG @@ -39,6 +40,7 @@ from bika.lims.upgrade import upgradestep from bika.lims.upgrade.utils import UpgradeUtils from Products.Archetypes.config import UID_CATALOG +from Products.ZCatalog.ProgressHandler import ZLogHandler from zope.interface import alsoProvides version = "1.3.3" # Remember version number in metadata.xml and setup.py @@ -385,6 +387,10 @@ def upgrade(tool): # https://github.com/senaite/senaite.core/pull/1542 fix_email_address(portal) + # Add metadata for progress bar + # https://github.com/senaite/senaite.core/pull/ + # Add progress metadata column for Samples + add_metadata(portal, CATALOG_ANALYSIS_REQUEST_LISTING, "getProgress", True) logger.info("{0} upgraded to version {1}".format(product, version)) return True @@ -857,4 +863,19 @@ def fix_email_address(portal, portal_types=None, catalog_id="portal_catalog"): logger.warn("Cannot resolve email address from '{}'" .format(email_address)) - logger.info("Fixing email addresses [DONE]") \ No newline at end of file + logger.info("Fixing email addresses [DONE]") + + +def add_metadata(portal, catalog_id, column, refresh_catalog=False): + logger.info("Adding '{}' metadata to '{}' ...".format(column, catalog_id)) + catalog = api.get_tool(catalog_id) + if column in catalog.schema(): + logger.info("Metadata '{}' already in catalog '{}' [SKIP]" + .format(column, catalog_id)) + return + catalog.addColumn(column) + + if refresh_catalog: + logger.info("Refreshing catalog '{}' ...".format(catalog_id)) + handler = ZLogHandler(steps=100) + catalog.refreshCatalog(pghandler=handler) From ede086850358a72883564fcba9b91a7736fe101b Mon Sep 17 00:00:00 2001 From: Ramon Bartl Date: Fri, 14 Feb 2020 22:02:36 +0100 Subject: [PATCH 2/6] Added progress bars for Batch listing --- bika/lims/browser/batchfolder.py | 15 +++++++++++++-- bika/lims/catalog/__init__.py | 1 + bika/lims/content/batch.py | 11 +++++++++++ bika/lims/setuphandlers.py | 1 + bika/lims/upgrade/v01_03_003.py | 3 +++ 5 files changed, 29 insertions(+), 2 deletions(-) diff --git a/bika/lims/browser/batchfolder.py b/bika/lims/browser/batchfolder.py index d97b4528ba..11be8737ed 100644 --- a/bika/lims/browser/batchfolder.py +++ b/bika/lims/browser/batchfolder.py @@ -21,12 +21,13 @@ import collections from bika.lims import api -from bika.lims.api.security import check_permission from bika.lims import bikaMessageFactory as _ +from bika.lims.api.security import check_permission from bika.lims.browser.bika_listing import BikaListingView from bika.lims.interfaces import IClient from bika.lims.permissions import AddBatch from bika.lims.utils import get_link +from bika.lims.utils import get_progress_bar_html class BatchFolderContentsView(BikaListingView): @@ -41,7 +42,7 @@ def __init__(self, context, request): "portal_type": "Batch", "sort_on": "created", "sort_order": "descending", - "is_active": True + "is_active": True, } self.context_actions = {} @@ -59,6 +60,11 @@ def __init__(self, context, request): ("Title", { "title": _("Title"), "index": "title", }), + ("Progress", { + "title": "Progress", + "index": "getProgress", + "sortable": True, + "toggle": True}), ("BatchID", { "title": _("Batch ID"), "index": "getId", }), @@ -167,6 +173,11 @@ def folderitem(self, obj, item, index): created = api.get_creation_date(obj) date = obj.getBatchDate() + # total sample progress + progress = obj.getProgress() + item["Progress"] = progress + item["replace"]["Progress"] = get_progress_bar_html(progress) + item["BatchID"] = bid item["ClientBatchID"] = cbid item["replace"]["BatchID"] = get_link(url, bid) diff --git a/bika/lims/catalog/__init__.py b/bika/lims/catalog/__init__.py index 708ca3290f..152332bce6 100644 --- a/bika/lims/catalog/__init__.py +++ b/bika/lims/catalog/__init__.py @@ -22,6 +22,7 @@ from .analysisrequest_catalog import CATALOG_ANALYSIS_REQUEST_LISTING # noqa from .analysis_catalog import CATALOG_ANALYSIS_LISTING # noqa from .autoimportlogs_catalog import CATALOG_AUTOIMPORTLOGS_LISTING # noqa +from .bika_catalog import BIKA_CATALOG # noqa from .worksheet_catalog import CATALOG_WORKSHEET_LISTING # noqa from .report_catalog import CATALOG_REPORT_LISTING # noqa from .bikasetup_catalog import SETUP_CATALOG # noqa diff --git a/bika/lims/content/batch.py b/bika/lims/content/batch.py index 7236c0c010..a1032bc02c 100644 --- a/bika/lims/content/batch.py +++ b/bika/lims/content/batch.py @@ -249,5 +249,16 @@ def getLabelNames(self): labels = [label.getObject().title for label in uc(UID=uids)] return labels + def getProgress(self): + """Returns the progress in percent of all samples + """ + total_progress = 0 + samples = self.getAnalysisRequests() + total = len(samples) + if total > 0: + sample_progresses = map(lambda s: s.getProgress(), samples) + total_progress = sum(sample_progresses) / total + return total_progress + registerType(Batch, PROJECTNAME) diff --git a/bika/lims/setuphandlers.py b/bika/lims/setuphandlers.py index 277ee69cf5..0b2f95908d 100644 --- a/bika/lims/setuphandlers.py +++ b/bika/lims/setuphandlers.py @@ -213,6 +213,7 @@ ("bika_catalog", "getDateReceived"), ("bika_catalog", "getDateSampled"), ("bika_catalog", "review_state"), + ("bika_catalog", "getProgress"), ("bika_setup_catalog", "path"), ("bika_setup_catalog", "UID"), diff --git a/bika/lims/upgrade/v01_03_003.py b/bika/lims/upgrade/v01_03_003.py index bc4093be8b..302622c247 100644 --- a/bika/lims/upgrade/v01_03_003.py +++ b/bika/lims/upgrade/v01_03_003.py @@ -391,6 +391,9 @@ def upgrade(tool): # https://github.com/senaite/senaite.core/pull/ # Add progress metadata column for Samples add_metadata(portal, CATALOG_ANALYSIS_REQUEST_LISTING, "getProgress", True) + # Add progress metadata column for Batches + add_metadata(portal, BIKA_CATALOG, "getProgress", True) + logger.info("{0} upgraded to version {1}".format(product, version)) return True From 930b9f87b697c6b85f7c12e63c73b2a66d2276c0 Mon Sep 17 00:00:00 2001 From: Ramon Bartl Date: Fri, 14 Feb 2020 22:10:01 +0100 Subject: [PATCH 3/6] Changelog updated --- CHANGES.rst | 1 + bika/lims/upgrade/v01_03_003.py | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGES.rst b/CHANGES.rst index c55f3d55a1..2e016ed85a 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -7,6 +7,7 @@ Changelog **Added** +- #1544 Progress indicator for Batch listing - #1536 Integrated Setup and Profiles from senaite.lims - #1534 Integrate browser resources from senaite.lims - #1529 Moved contentmenu provider into core diff --git a/bika/lims/upgrade/v01_03_003.py b/bika/lims/upgrade/v01_03_003.py index 302622c247..9f80f548ac 100644 --- a/bika/lims/upgrade/v01_03_003.py +++ b/bika/lims/upgrade/v01_03_003.py @@ -388,7 +388,7 @@ def upgrade(tool): fix_email_address(portal) # Add metadata for progress bar - # https://github.com/senaite/senaite.core/pull/ + # https://github.com/senaite/senaite.core/pull/1544 # Add progress metadata column for Samples add_metadata(portal, CATALOG_ANALYSIS_REQUEST_LISTING, "getProgress", True) # Add progress metadata column for Batches From 5c6f1858a452585192b2593afa5dbe61952476e8 Mon Sep 17 00:00:00 2001 From: Ramon Bartl Date: Fri, 14 Feb 2020 22:43:52 +0100 Subject: [PATCH 4/6] Translate column header --- bika/lims/browser/batchfolder.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bika/lims/browser/batchfolder.py b/bika/lims/browser/batchfolder.py index 11be8737ed..9d94b68c00 100644 --- a/bika/lims/browser/batchfolder.py +++ b/bika/lims/browser/batchfolder.py @@ -61,7 +61,7 @@ def __init__(self, context, request): "title": _("Title"), "index": "title", }), ("Progress", { - "title": "Progress", + "title": _("Progress"), "index": "getProgress", "sortable": True, "toggle": True}), From 1b90b232a8ab709cd7a26a31a03f1fddec05958f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jordi=20Puiggen=C3=A9?= Date: Sat, 15 Feb 2020 00:51:56 +0100 Subject: [PATCH 5/6] Consider Samples in invalid status as completed (end status) --- bika/lims/content/analysisrequest.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bika/lims/content/analysisrequest.py b/bika/lims/content/analysisrequest.py index 13d8051b4e..024221f94d 100644 --- a/bika/lims/content/analysisrequest.py +++ b/bika/lims/content/analysisrequest.py @@ -2473,7 +2473,7 @@ def getProgress(self): """Returns the progress in percent of all analyses """ review_state = api.get_review_status(self) - if review_state == "published": + if review_state in ["published", "invalid"]: return 100 numbers = self.getAnalysesNum() From 21d928eb454f0bf13557fa1316340527c7139543 Mon Sep 17 00:00:00 2001 From: Ramon Bartl Date: Mon, 17 Feb 2020 09:29:47 +0100 Subject: [PATCH 6/6] Consider final states as 100% --- bika/lims/content/analysisrequest.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/bika/lims/content/analysisrequest.py b/bika/lims/content/analysisrequest.py index 024221f94d..123118f3c4 100644 --- a/bika/lims/content/analysisrequest.py +++ b/bika/lims/content/analysisrequest.py @@ -131,6 +131,7 @@ IMG_SRC_RX = re.compile(r'