From b17126dc762951717a534e12fc0360692b8fe736 Mon Sep 17 00:00:00 2001 From: Ramon Bartl Date: Thu, 15 Feb 2018 13:10:14 +0100 Subject: [PATCH 1/9] PEP8 only --- .../widgets/analysisprofileanalyseswidget.py | 181 +++++++++--------- 1 file changed, 90 insertions(+), 91 deletions(-) diff --git a/bika/lims/browser/widgets/analysisprofileanalyseswidget.py b/bika/lims/browser/widgets/analysisprofileanalyseswidget.py index e44cdc1dc6..779719493b 100644 --- a/bika/lims/browser/widgets/analysisprofileanalyseswidget.py +++ b/bika/lims/browser/widgets/analysisprofileanalyseswidget.py @@ -6,27 +6,27 @@ # Some rights reserved. See LICENSE.rst, CONTRIBUTORS.rst. from AccessControl import ClassSecurityInfo -from Products.Archetypes.Registry import registerWidget, registerPropertyType -from Products.Archetypes.Widget import TypesWidget -from Products.CMFCore.utils import getToolByName -from bika.lims.browser import BrowserView from bika.lims import bikaMessageFactory as _ -from bika.lims.utils import t from bika.lims.browser.bika_listing import BikaListingView +from Products.Archetypes.Registry import registerWidget +from Products.Archetypes.Widget import TypesWidget +from Products.CMFCore.utils import getToolByName from zope.i18n.locales import locales -from operator import itemgetter -import json + class AnalysisProfileAnalysesView(BikaListingView): - """ bika listing to display Analyses table for an Analysis Profile. + """View to display Analyses table for an Analysis Profile. """ def __init__(self, context, request, fieldvalue=[], allow_edit=False): super(AnalysisProfileAnalysesView, self).__init__(context, request) + self.catalog = "bika_setup_catalog" - self.contentFilter = {'portal_type': 'AnalysisService', - 'sort_on': 'sortable_title', - 'inactive_state': 'active',} + self.contentFilter = { + "portal_type": "AnalysisService", + "sort_on": "sortable_title", + "inactive_state": "active", + } self.context_actions = {} self.base_url = self.context.absolute_url() self.view_url = self.base_url @@ -48,119 +48,118 @@ def __init__(self, context, request, fieldvalue=[], allow_edit=False): self.expand_all_categories = False self.ajax_categories = True self.ajax_categories_url = self.context.absolute_url() + \ - "/analysisprofile_analysesview" - self.category_index = 'getCategoryTitle' + "/analysisprofile_analysesview" + self.category_index = "getCategoryTitle" self.columns = { - 'Title': {'title': _('Service'), - 'index': 'sortable_title', - 'sortable': False,}, - 'Price': {'title': _('Price'), - 'sortable': False,}, + "Title": { + "title": _("Service"), + "index": "sortable_title", + "sortable": False, + }, + "Price": { + "title": _("Price"), + "sortable": False, + }, } self.review_states = [ - {'id':'default', - 'title': _('All'), - 'contentFilter':{}, - 'columns': ['Title', - 'Price', - ], - 'transitions': [{'id':'empty'}, ], # none - }, + { + "id": "default", + "title": _("All"), + "contentFilter": {}, + "columns": [ + "Title", + "Price", + ], + "transitions": [ + {"id": "empty"}, + ], + }, ] - if not self.context.bika_setup.getShowPrices(): - self.review_states[0]['columns'].remove('Price') + self.review_states[0]["columns"].remove("Price") self.fieldvalue = fieldvalue self.selected = [x.UID() for x in fieldvalue] - if self.aq_parent.portal_type == 'AnalysisProfile': + if self.aq_parent.portal_type == "AnalysisProfile": # Custom settings for the Analysis Services assigned to # the Analysis Profile # https://jira.bikalabs.com/browse/LIMS-1324 self.profile = self.aq_parent - self.columns['Hidden'] = {'title': _('Hidden'), - 'sortable': False, - 'type': 'boolean'} - self.review_states[0]['columns'].insert(1, 'Hidden') - + self.columns["Hidden"] = { + "title": _("Hidden"), + "sortable": False, + "type": "boolean", + } + self.review_states[0]["columns"].insert(1, "Hidden") def folderitems(self): self.categories = [] - bsc = getToolByName(self.context, 'bika_setup_catalog') - wf = getToolByName(self.context, 'portal_workflow') - mtool = getToolByName(self.context, 'portal_membership') + mtool = getToolByName(self.context, "portal_membership") member = mtool.getAuthenticatedMember() roles = member.getRoles() - self.allow_edit = 'LabManager' in roles or 'Manager' in roles + self.allow_edit = "LabManager" in roles or "Manager" in roles items = BikaListingView.folderitems(self) - for x in range(len(items)): - if not items[x].has_key('obj'): continue - obj = items[x]['obj'] + for item in items: + if "obj" not in item: + continue + obj = item["obj"] cat = obj.getCategoryTitle() # Category (upper C) is for display column value - items[x]['Category'] = cat + item["Category"] = cat if self.do_cats: # category is for bika_listing to groups entries - items[x]['category'] = cat + item["category"] = cat if cat not in self.categories: self.categories.append(cat) analyses = [a.UID() for a in self.fieldvalue] - items[x]['selected'] = items[x]['uid'] in analyses - - items[x]['class']['Title'] = 'service_title' + item["selected"] = item["uid"] in analyses + item["class"]["Title"] = "service_title" calculation = obj.getCalculation() - items[x]['Calculation'] = calculation and calculation.Title() + item["Calculation"] = calculation and calculation.Title() - locale = locales.getLocale('en') + locale = locales.getLocale("en") currency = self.context.bika_setup.getCurrency() symbol = locale.numbers.currencies[currency].symbol - items[x]['Price'] = "%s %s" % (symbol, obj.getPrice()) - items[x]['class']['Price'] = 'nowrap' + item["Price"] = "{} {}".format(symbol, obj.getPrice()) + item["class"]["Price"] = "nowrap" - after_icons = '' + after_icons = "" if obj.getAccredited(): - after_icons += ""%(self.context.absolute_url(), - _("Accredited")) + after_icons += "".format( + self.context.absolute_url(), _("Accredited")) if obj.getReportDryMatter(): - after_icons += ""%(self.context.absolute_url(), - _("Can be reported as dry matter")) - if obj.getAttachmentOption() == 'r': - after_icons += ""%(self.context.absolute_url(), - _("Attachment required")) - if obj.getAttachmentOption() == 'n': - after_icons += ""%(self.context.absolute_url(), - _('Attachment not permitted')) + after_icons += "".format( + self.context.absolute_url(), _("Can be reported as dry matter")) + if obj.getAttachmentOption() == "r": + after_icons += "".format( + self.context.absolute_url(), _("Attachment required")) + if obj.getAttachmentOption() == "n": + after_icons += "".format( + self.context.absolute_url(), _('Attachment not permitted')) if after_icons: - items[x]['after']['Title'] = after_icons + item["after"]["Title"] = after_icons if self.profile: # Display analyses for this Analysis Service in results? ser = self.profile.getAnalysisServiceSettings(obj.UID()) - items[x]['allow_edit'] = ['Hidden', ] - items[x]['Hidden'] = ser.get('hidden', obj.getHidden()) + item["allow_edit"] = ["Hidden", ] + item["Hidden"] = ser.get("hidden", obj.getHidden()) self.categories.sort() return items + class AnalysisProfileAnalysesWidget(TypesWidget): _properties = TypesWidget._properties.copy() _properties.update({ @@ -172,40 +171,40 @@ class AnalysisProfileAnalysesWidget(TypesWidget): security = ClassSecurityInfo() security.declarePublic('process_form') - def process_form(self, instance, field, form, empty_marker = None, - emptyReturnsMarker = False): + + def process_form(self, instance, field, form, empty_marker=None, + emptyReturnsMarker=False): """ Return a list of dictionaries fit for AnalysisProfile/Analyses field consumption. """ - bsc = getToolByName(instance, 'bika_setup_catalog') - value = [] - service_uids = form.get('uids', None) + service_uids = form.get("uids", None) - if instance.portal_type == 'AnalysisProfile': + if instance.portal_type == "AnalysisProfile": # Hidden analyses? outs = [] - hiddenans = form.get('Hidden', {}) + hiddenans = form.get("Hidden", {}) if service_uids: for uid in service_uids: - hidden = hiddenans.get(uid, '') - hidden = True if hidden == 'on' else False - outs.append({'uid':uid, 'hidden':hidden}) + hidden = hiddenans.get(uid, "") + hidden = True if hidden == "on" else False + outs.append({"uid": uid, "hidden": hidden}) instance.setAnalysisServicesSettings(outs) return service_uids, {} - security.declarePublic('Analyses') - def Analyses(self, field, allow_edit = False): + security.declarePublic("Analyses") + + def Analyses(self, field, allow_edit=False): """ Print analyses table """ fieldvalue = getattr(field, field.accessor)() view = AnalysisProfileAnalysesView(self, - self.REQUEST, - fieldvalue = fieldvalue, - allow_edit = allow_edit) - return view.contents_table(table_only = True) + self.REQUEST, + fieldvalue=fieldvalue, + allow_edit=allow_edit) + return view.contents_table(table_only=True) + registerWidget(AnalysisProfileAnalysesWidget, - title = 'Analysis Profile Analyses selector', - description = ('Analysis Profile Analyses selector'), - ) + title='Analysis Profile Analyses selector', + description=('Analysis Profile Analyses selector'),) From 2516eadb350fb60bd6bc9dc22de4c9cf6f1013a2 Mon Sep 17 00:00:00 2001 From: Ramon Bartl Date: Thu, 15 Feb 2018 14:12:13 +0100 Subject: [PATCH 2/9] refactored to use folderitem --- .../widgets/analysisprofileanalyseswidget.py | 108 +++++++++--------- 1 file changed, 51 insertions(+), 57 deletions(-) diff --git a/bika/lims/browser/widgets/analysisprofileanalyseswidget.py b/bika/lims/browser/widgets/analysisprofileanalyseswidget.py index 779719493b..a129bd7ac8 100644 --- a/bika/lims/browser/widgets/analysisprofileanalyseswidget.py +++ b/bika/lims/browser/widgets/analysisprofileanalyseswidget.py @@ -96,68 +96,62 @@ def __init__(self, context, request, fieldvalue=[], allow_edit=False): } self.review_states[0]["columns"].insert(1, "Hidden") - def folderitems(self): - self.categories = [] - + def before_render(self): mtool = getToolByName(self.context, "portal_membership") member = mtool.getAuthenticatedMember() roles = member.getRoles() self.allow_edit = "LabManager" in roles or "Manager" in roles - - items = BikaListingView.folderitems(self) - - for item in items: - if "obj" not in item: - continue - obj = item["obj"] - - cat = obj.getCategoryTitle() - # Category (upper C) is for display column value - item["Category"] = cat - if self.do_cats: - # category is for bika_listing to groups entries - item["category"] = cat - if cat not in self.categories: - self.categories.append(cat) - - analyses = [a.UID() for a in self.fieldvalue] - - item["selected"] = item["uid"] in analyses - item["class"]["Title"] = "service_title" - - calculation = obj.getCalculation() - item["Calculation"] = calculation and calculation.Title() - - locale = locales.getLocale("en") - currency = self.context.bika_setup.getCurrency() - symbol = locale.numbers.currencies[currency].symbol - item["Price"] = "{} {}".format(symbol, obj.getPrice()) - item["class"]["Price"] = "nowrap" - - after_icons = "" - if obj.getAccredited(): - after_icons += "".format( - self.context.absolute_url(), _("Accredited")) - if obj.getReportDryMatter(): - after_icons += "".format( - self.context.absolute_url(), _("Can be reported as dry matter")) - if obj.getAttachmentOption() == "r": - after_icons += "".format( - self.context.absolute_url(), _("Attachment required")) - if obj.getAttachmentOption() == "n": - after_icons += "".format( - self.context.absolute_url(), _('Attachment not permitted')) - if after_icons: - item["after"]["Title"] = after_icons - - if self.profile: - # Display analyses for this Analysis Service in results? - ser = self.profile.getAnalysisServiceSettings(obj.UID()) - item["allow_edit"] = ["Hidden", ] - item["Hidden"] = ser.get("hidden", obj.getHidden()) - self.categories.sort() - return items + + def folderitem(self, obj, item, index): + """Processed per Analysis + """ + cat = obj.getCategoryTitle() + # Category (upper C) is for display column value + item["Category"] = cat + if self.do_cats: + # category is for bika_listing to groups entries + item["category"] = cat + if cat not in self.categories: + self.categories.append(cat) + + analyses = [a.UID() for a in self.fieldvalue] + + item["selected"] = item["uid"] in analyses + item["class"]["Title"] = "service_title" + + calculation = obj.getCalculation() + item["Calculation"] = calculation and calculation.Title() + + locale = locales.getLocale("en") + currency = self.context.bika_setup.getCurrency() + symbol = locale.numbers.currencies[currency].symbol + item["Price"] = "{} {}".format(symbol, obj.getPrice()) + item["class"]["Price"] = "nowrap" + + after_icons = "" + if obj.getAccredited(): + after_icons += "".format( + self.context.absolute_url(), _("Accredited")) + if obj.getReportDryMatter(): + after_icons += "".format( + self.context.absolute_url(), _("Can be reported as dry matter")) + if obj.getAttachmentOption() == "r": + after_icons += "".format( + self.context.absolute_url(), _("Attachment required")) + if obj.getAttachmentOption() == "n": + after_icons += "".format( + self.context.absolute_url(), _('Attachment not permitted')) + if after_icons: + item["after"]["Title"] = after_icons + + if self.profile: + # Display analyses for this Analysis Service in results? + ser = self.profile.getAnalysisServiceSettings(obj.UID()) + item["allow_edit"] = ["Hidden", ] + item["Hidden"] = ser.get("hidden", obj.getHidden()) + + return item class AnalysisProfileAnalysesWidget(TypesWidget): From 89f09db9aa7699e9b384ebaaddf312c3664440e5 Mon Sep 17 00:00:00 2001 From: Ramon Bartl Date: Thu, 15 Feb 2018 14:47:36 +0100 Subject: [PATCH 3/9] Pass correct context to AnalysisProfileAnalysesView --- .../browser/widgets/analysisprofileanalyseswidget.py | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/bika/lims/browser/widgets/analysisprofileanalyseswidget.py b/bika/lims/browser/widgets/analysisprofileanalyseswidget.py index a129bd7ac8..be69d83bb6 100644 --- a/bika/lims/browser/widgets/analysisprofileanalyseswidget.py +++ b/bika/lims/browser/widgets/analysisprofileanalyseswidget.py @@ -173,6 +173,10 @@ def process_form(self, instance, field, form, empty_marker=None, """ service_uids = form.get("uids", None) + # remember the context, because we need to pass that later to the + # listing view (see method `Analyses` below) + self.instance = instance + if instance.portal_type == "AnalysisProfile": # Hidden analyses? outs = [] @@ -192,7 +196,11 @@ def Analyses(self, field, allow_edit=False): """ Print analyses table """ fieldvalue = getattr(field, field.accessor)() - view = AnalysisProfileAnalysesView(self, + + # N.B. we do not want to pass the field as the context to + # AnalysisProfileAnalysesView, but rather the holding instance + instance = getattr(self, "instance", field.aq_parent) + view = AnalysisProfileAnalysesView(instance, self.REQUEST, fieldvalue=fieldvalue, allow_edit=allow_edit) From 095fda3ff4df3e6a31b977fdba2dd556710288d9 Mon Sep 17 00:00:00 2001 From: Ramon Bartl Date: Thu, 15 Feb 2018 14:48:01 +0100 Subject: [PATCH 4/9] Add Unit to the listing --- .../lims/browser/widgets/analysisprofileanalyseswidget.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/bika/lims/browser/widgets/analysisprofileanalyseswidget.py b/bika/lims/browser/widgets/analysisprofileanalyseswidget.py index be69d83bb6..9820d0dc51 100644 --- a/bika/lims/browser/widgets/analysisprofileanalyseswidget.py +++ b/bika/lims/browser/widgets/analysisprofileanalyseswidget.py @@ -57,6 +57,11 @@ def __init__(self, context, request, fieldvalue=[], allow_edit=False): "index": "sortable_title", "sortable": False, }, + "Unit": { + "title": _("Unit"), + "index": "getUnit", + "sortable": False, + }, "Price": { "title": _("Price"), "sortable": False, @@ -70,6 +75,7 @@ def __init__(self, context, request, fieldvalue=[], allow_edit=False): "contentFilter": {}, "columns": [ "Title", + "Unit", "Price", ], "transitions": [ @@ -97,6 +103,8 @@ def __init__(self, context, request, fieldvalue=[], allow_edit=False): self.review_states[0]["columns"].insert(1, "Hidden") def before_render(self): + """Before render hook + """ mtool = getToolByName(self.context, "portal_membership") member = mtool.getAuthenticatedMember() roles = member.getRoles() From 32bee8556c93c59c196f1d591c27403762d49e66 Mon Sep 17 00:00:00 2001 From: Ramon Bartl Date: Thu, 15 Feb 2018 14:56:27 +0100 Subject: [PATCH 5/9] docstring only --- bika/lims/browser/widgets/analysisprofileanalyseswidget.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/bika/lims/browser/widgets/analysisprofileanalyseswidget.py b/bika/lims/browser/widgets/analysisprofileanalyseswidget.py index 9820d0dc51..27390bcb13 100644 --- a/bika/lims/browser/widgets/analysisprofileanalyseswidget.py +++ b/bika/lims/browser/widgets/analysisprofileanalyseswidget.py @@ -103,8 +103,6 @@ def __init__(self, context, request, fieldvalue=[], allow_edit=False): self.review_states[0]["columns"].insert(1, "Hidden") def before_render(self): - """Before render hook - """ mtool = getToolByName(self.context, "portal_membership") member = mtool.getAuthenticatedMember() roles = member.getRoles() From 2bea6de04ec8f9694b392b9f51955da9501f1a66 Mon Sep 17 00:00:00 2001 From: Ramon Bartl Date: Thu, 15 Feb 2018 15:21:12 +0100 Subject: [PATCH 6/9] Changelog updated --- CHANGES.rst | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGES.rst b/CHANGES.rst index e3c4f0dbab..b3253bb972 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -10,6 +10,7 @@ Changelog **Changed** +- #659 Display the Unit in Profile Analyses Listing - #655 Updated German Translations - #647 Refactored bika.lims.bikalisting.js + several functional fixtures - #637 Deassociate Analysis Request portal type from `worksheetanalysis_workflow` From 24b27e5aa356259cc61f2d2da7d78ce2a0c182bd Mon Sep 17 00:00:00 2001 From: Ramon Bartl Date: Thu, 15 Feb 2018 15:30:09 +0100 Subject: [PATCH 7/9] Handle format strings as unicode --- .../browser/widgets/analysisprofileanalyseswidget.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/bika/lims/browser/widgets/analysisprofileanalyseswidget.py b/bika/lims/browser/widgets/analysisprofileanalyseswidget.py index 27390bcb13..67f9fd5ecc 100644 --- a/bika/lims/browser/widgets/analysisprofileanalyseswidget.py +++ b/bika/lims/browser/widgets/analysisprofileanalyseswidget.py @@ -132,21 +132,21 @@ def folderitem(self, obj, item, index): locale = locales.getLocale("en") currency = self.context.bika_setup.getCurrency() symbol = locale.numbers.currencies[currency].symbol - item["Price"] = "{} {}".format(symbol, obj.getPrice()) + item["Price"] = u"{} {}".format(symbol, obj.getPrice()) item["class"]["Price"] = "nowrap" after_icons = "" if obj.getAccredited(): - after_icons += "".format( + after_icons += u"".format( self.context.absolute_url(), _("Accredited")) if obj.getReportDryMatter(): - after_icons += "".format( + after_icons += u"".format( self.context.absolute_url(), _("Can be reported as dry matter")) if obj.getAttachmentOption() == "r": - after_icons += "".format( + after_icons += u"".format( self.context.absolute_url(), _("Attachment required")) if obj.getAttachmentOption() == "n": - after_icons += "".format( + after_icons += u"".format( self.context.absolute_url(), _('Attachment not permitted')) if after_icons: item["after"]["Title"] = after_icons From 98a5eae0ecefe18712b8d8aa8c28bde306bc2148 Mon Sep 17 00:00:00 2001 From: Ramon Bartl Date: Thu, 15 Feb 2018 16:47:37 +0100 Subject: [PATCH 8/9] Sort in folderitems --- .../lims/browser/widgets/analysisprofileanalyseswidget.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/bika/lims/browser/widgets/analysisprofileanalyseswidget.py b/bika/lims/browser/widgets/analysisprofileanalyseswidget.py index 67f9fd5ecc..90e5e34940 100644 --- a/bika/lims/browser/widgets/analysisprofileanalyseswidget.py +++ b/bika/lims/browser/widgets/analysisprofileanalyseswidget.py @@ -102,15 +102,19 @@ def __init__(self, context, request, fieldvalue=[], allow_edit=False): } self.review_states[0]["columns"].insert(1, "Hidden") - def before_render(self): + def folderitems(self): + """Processed once for all analyses + """ + items = super(AnalysisProfileAnalysesView, self).folderitems() mtool = getToolByName(self.context, "portal_membership") member = mtool.getAuthenticatedMember() roles = member.getRoles() self.allow_edit = "LabManager" in roles or "Manager" in roles self.categories.sort() + return items def folderitem(self, obj, item, index): - """Processed per Analysis + """Processed once per analysis """ cat = obj.getCategoryTitle() # Category (upper C) is for display column value From 56a9d3998fdeaf69d1d11e038452df6753e497e5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jordi=20Puiggen=C3=A9?= Date: Thu, 15 Feb 2018 17:00:29 +0100 Subject: [PATCH 9/9] Assign self.allow_edit before rendering the items --- bika/lims/browser/widgets/analysisprofileanalyseswidget.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bika/lims/browser/widgets/analysisprofileanalyseswidget.py b/bika/lims/browser/widgets/analysisprofileanalyseswidget.py index 90e5e34940..9bfb905ac5 100644 --- a/bika/lims/browser/widgets/analysisprofileanalyseswidget.py +++ b/bika/lims/browser/widgets/analysisprofileanalyseswidget.py @@ -105,11 +105,11 @@ def __init__(self, context, request, fieldvalue=[], allow_edit=False): def folderitems(self): """Processed once for all analyses """ - items = super(AnalysisProfileAnalysesView, self).folderitems() mtool = getToolByName(self.context, "portal_membership") member = mtool.getAuthenticatedMember() roles = member.getRoles() self.allow_edit = "LabManager" in roles or "Manager" in roles + items = super(AnalysisProfileAnalysesView, self).folderitems() self.categories.sort() return items