Passed
Push — master ( ef1ceb...20aa4c )
by Jordi
06:12
created

AnalysisRequestAnalysesView.show_prices()   A

Complexity

Conditions 1

Size

Total Lines 6
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 4
dl 0
loc 6
rs 10
c 0
b 0
f 0
cc 1
nop 1
1
# -*- coding: utf-8 -*-
2
#
3
# This file is part of SENAITE.CORE
4
#
5
# Copyright 2018 by it's authors.
6
# Some rights reserved. See LICENSE.rst, CONTRIBUTORS.rst.
7
8
import collections
9
10
from bika.lims import api
11
from bika.lims import bikaMessageFactory as _
12
from bika.lims.browser.bika_listing import BikaListingView
13
from bika.lims.content.analysisspec import ResultsRangeDict
14
from bika.lims.utils import dicts_to_dict
15
from bika.lims.utils import get_image
16
from bika.lims.utils import logged_in_client
17
from bika.lims.utils import t
18
from bika.lims.workflow import wasTransitionPerformed
19
from plone.memoize import view
20
from Products.Five.browser.pagetemplatefile import ViewPageTemplateFile
21
from zope.i18n.locales import locales
22
23
24
class AnalysisRequestAnalysesView(BikaListingView):
25
    """AR Manage Analyses View
26
    """
27
    template = ViewPageTemplateFile("templates/analysisrequest_analyses.pt")
28
29
    def __init__(self, context, request):
30
        super(AnalysisRequestAnalysesView, self).__init__(context, request)
31
32
        self.catalog = "bika_setup_catalog"
33
        self.contentFilter = {
34
            "portal_type": "AnalysisService",
35
            "sort_on": "sortable_title",
36
            "sort_order": "ascending",
37
            "inactive_state": "active"
38
        }
39
        self.context_actions = {}
40
        self.icon = "{}/{}".format(
41
            self.portal_url,
42
            "++resource++bika.lims.images/analysisservice_big.png"
43
        )
44
        self.show_sort_column = False
45
        self.show_select_row = False
46
        self.show_select_all_checkbox = False
47
        self.show_select_column = True
48
        self.table_only = True
49
        self.pagesize = 999999
50
        self.show_search = False
51
52
        self.categories = []
53
        self.selected = []
54
        self.do_cats = self.context.bika_setup.getCategoriseAnalysisServices()
55
        if self.do_cats:
56
            self.show_categories = True
57
            self.expand_all_categories = False
58
            self.ajax_categories = True
59
            self.category_index = "getCategoryTitle"
60
61
        self.columns = collections.OrderedDict((
62
            ("Title", {
63
                "title": _("Service"),
64
                "index": "sortable_title",
65
                "sortable": False}),
66
            ("Unit", {
67
                "title": _("Unit"),
68
                "sortable": False}),
69
            ("Hidden", {
70
                "title": _("Hidden"),
71
                "sortable": False,
72
                "type": "boolean"}),
73
            ("Price", {
74
                "title": _("Price"),
75
                "sortable": False}),
76
            ("Partition", {
77
                "title": _("Partition"),
78
                "sortable": False,
79
                "type": "choices"}),
80
            ("warn_min", {
81
                "title": _("Min warn")}),
82
            ("min", {
83
                "title": _("Min")}),
84
            ("warn_max", {
85
                "title": _("Max warn")}),
86
            ("max", {
87
                "title": _("Max")}),
88
        ))
89
90
        columns = ["Title", "Unit", "Hidden", ]
91
        if self.show_prices():
92
            columns.append("Price")
93
        if self.show_partitions():
94
            columns.append("Partition")
95
        if self.show_ar_specs():
96
            columns.append("warn_min")
97
            columns.append("min")
98
            columns.append("warn_max")
99
            columns.append("max")
100
101
        self.review_states = [
102
            {
103
                "id": "default",
104
                "title": _("All"),
105
                "contentFilter": {"inactive_state": "active"},
106
                "columns": columns,
107
                "transitions": [],
108
                "custom_transitions": [
109
                    {
110
                        "id": "save_analyses_button",
111
                        "title": _("Save")
112
                    }
113
                ],
114
            },
115
        ]
116
117
    def update(self):
118
        """Update hook
119
        """
120
        super(AnalysisRequestAnalysesView, self).update()
121
        analyses = self.context.getAnalyses(full_objects=True)
122
        self.analyses = dict([(a.getServiceUID(), a) for a in analyses])
123
        self.selected = self.analyses.keys()
124
125
    @view.memoize
126
    def show_prices(self):
127
        """Checks if prices should be shown or not
128
        """
129
        setup = api.get_setup()
130
        return setup.getShowPrices()
131
132
    @view.memoize
133
    def show_partitions(self):
134
        """Checks if partitions should be shown
135
        """
136
        setup = api.get_setup()
137
        return setup.getShowPartitions()
138
139
    @view.memoize
140
    def show_ar_specs(self):
141
        """Checks if AR specs should be shown or not
142
        """
143
        setup = api.get_setup()
144
        return setup.getEnableARSpecs()
145
146
    @view.memoize
147
    def allow_department_filtering(self):
148
        """Checks if department filtering is allowed
149
        """
150
        setup = api.get_setup()
151
        return setup.getAllowDepartmentFiltering()
152
153
    @view.memoize
154
    def get_results_range(self):
155
        """Get the results Range from the AR
156
        """
157
        spec = self.context.getResultsRange()
158
        if spec:
159
            return dicts_to_dict(spec, "keyword")
160
        return ResultsRangeDict()
161
162
    @view.memoize
163
    def get_partitions(self):
164
        """Get the partitions
165
        """
166
        sample = self.context.getSample()
167
        return sample.objectValues("SamplePartition")
168
169
    def get_partition(self, analysis):
170
        """Get the partition of the Analysis
171
        """
172
        partition = analysis.getSamplePartition()
173
        if not partition:
174
            return self.get_partitions()[0]
175
        return partition
176
177
    @view.memoize
178
    def get_currency_symbol(self):
179
        """Get the currency Symbol
180
        """
181
        locale = locales.getLocale('en')
182
        setup = api.get_setup()
183
        currency = setup.getCurrency()
184
        return locale.numbers.currencies[currency].symbol
185
186
    def is_submitted(self, obj):
187
        """Check if the "submit" transition was performed
188
        """
189
        return wasTransitionPerformed(obj, "submit")
190
191
    @view.memoize
192
    def get_logged_in_client(self):
193
        """Return the logged in client
194
        """
195
        return logged_in_client(self.context)
196
197
    def get_editable_columns(self, obj):
198
        """Return editable fields
199
        """
200
        columns = ["Partition", "min", "max", "warn_min", "warn_max", "Hidden"]
201
        if not self.get_logged_in_client():
202
            columns.append("Price")
203
        return columns
204
205
    def isItemAllowed(self, obj):
206
        """Checks if the item can be added to the list depending on the
207
        department filter. If the analysis service is not assigned to a
208
        department, show it.
209
        If department filtering is disabled in bika_setup, will return True.
210
        """
211
        if not self.allow_department_filtering():
212
            return True
213
214
        # Gettin the department from analysis service
215
        obj_dep = obj.getDepartment()
216
        result = True
217
        if obj_dep:
218
            # Getting the cookie value
219
            cookie_dep_uid = self.request.get(
220
                "filter_by_department_info", "no")
221
            # Comparing departments' UIDs
222
            result = True if obj_dep.UID() in\
223
                cookie_dep_uid.split(",") else False
224
            return result
225
        return result
226
227
    def folderitems(self):
228
        """XXX refactor if possible to non-classic mode
229
        """
230
        items = super(AnalysisRequestAnalysesView, self).folderitems()
231
        self.categories.sort()
232
        return items
233
234
    def folderitem(self, obj, item, index):
235
        """Service triggered each time an item is iterated in folderitems.
236
237
        The use of this service prevents the extra-loops in child objects.
238
239
        :obj: the instance of the class to be foldered
240
        :item: dict containing the properties of the object to be used by
241
            the template
242
        :index: current index of the item
243
        """
244
        # ensure we have an object and not a brain
245
        obj = api.get_object(obj)
246
        uid = api.get_uid(obj)
247
248
        # settings for this analysis
249
        service_settings = self.context.getAnalysisServiceSettings(uid)
250
        hidden = service_settings.get("hidden", obj.getHidden())
251
252
        # get the category
253
        category = obj.getCategoryTitle()
254
        item["category"] = category
255
        if category not in self.categories:
256
            self.categories.append(category)
257
258
        parts = filter(api.is_active, self.get_partitions())
259
        partitions = map(lambda part: {
260
            "ResultValue": part.Title(), "ResultText": part.getId()}, parts)
261
262
        keyword = obj.getKeyword()
263
        partition = None
264
        if uid in self.analyses:
265
            analysis = self.analyses[uid]
266
            # Might differ from the service keyword
267
            keyword = analysis.getKeyword()
268
            # Mark the row as disabled if the analysis was submitted
269
            item["disabled"] = self.is_submitted(analysis)
270
            # get the hidden status of the analysis
271
            hidden = analysis.getHidden()
272
            # get the partition of the analysis
273
            partition = self.get_partition(analysis)
274
        else:
275
            partition = self.get_partitions()[0]
276
277
        # get the specification of this object
278
        rr = self.get_results_range()
279
        spec = rr.get(keyword, ResultsRangeDict())
280
281
        item["Title"] = obj.Title()
282
        item["Unit"] = obj.getUnit()
283
        item["Price"] = obj.getPrice()
284
        item["before"]["Price"] = self.get_currency_symbol()
285
        item["allow_edit"] = self.get_editable_columns(obj)
286
        item["selected"] = uid in self.selected
287
        item["min"] = str(spec.get("min", ""))
288
        item["max"] = str(spec.get("max", ""))
289
        item["warn_min"] = str(spec.get("warn_min", ""))
290
        item["warn_max"] = str(spec.get("warn_max", ""))
291
        item["Hidden"] = hidden
292
        item["Partition"] = partition.getId()
293
        item["choices"]["Partition"] = partitions
294
295
        # Icons
296
        after_icons = ""
297
        if obj.getAccredited():
298
            after_icons += get_image(
299
                "accredited.png", title=t(_("Accredited")))
300
        if obj.getAttachmentOption() == "r":
301
            after_icons += get_image(
302
                "attach_reqd.png", title=t(_("Attachment required")))
303
        if obj.getAttachmentOption() == "n":
304
            after_icons += get_image(
305
                "attach_no.png", title=t(_('Attachment not permitted')))
306
        if after_icons:
307
            item["after"]["Title"] = after_icons
308
309
        return item
310