Passed
Push — master ( d85f52...eb777d )
by Jordi
04:24
created

AnalysisServiceInfoView.is_accredited()   A

Complexity

Conditions 1

Size

Total Lines 4
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 4
dl 0
loc 4
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
# SENAITE.CORE is free software: you can redistribute it and/or modify it under
6
# the terms of the GNU General Public License as published by the Free Software
7
# Foundation, version 2.
8
#
9
# This program is distributed in the hope that it will be useful, but WITHOUT
10
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
11
# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
12
# details.
13
#
14
# You should have received a copy of the GNU General Public License along with
15
# this program; if not, write to the Free Software Foundation, Inc., 51
16
# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
17
#
18
# Copyright 2018-2019 by it's authors.
19
# Some rights reserved, see README and LICENSE.
20
21
import json
22
23
import plone
24
import plone.protect
25
from bika.lims import api
26
from bika.lims.browser import BrowserView
27
from bika.lims.config import POINTS_OF_CAPTURE
28
from bika.lims.content.analysisservice import getContainers
29
from bika.lims.interfaces import IAnalysisService
30
from bika.lims.interfaces import IJSONReadExtender
31
from bika.lims.jsonapi import get_include_fields
32
from bika.lims.jsonapi import load_field_values
33
from bika.lims.utils import get_image
34
from magnitude import mg
35
from plone.memoize import view
36
from Products.CMFCore.utils import getToolByName
37
from Products.Five.browser.pagetemplatefile import ViewPageTemplateFile
38
from zope.component import adapts
39
from zope.interface import implements
40
from zope.i18n.locales import locales
41
42
43
class AnalysisServiceInfoView(BrowserView):
44
    """Show details of the Analysis Service
45
    """
46
    template = ViewPageTemplateFile("templates/analysisservice_info.pt")
47
48
    def __init__(self, context, request):
49
        super(AnalysisServiceInfoView, self).__init__(context, request)
50
51
    def __call__(self):
52
        # disable the editable border
53
        self.request.set("disable_border", 1)
54
        return self.template()
55
56
    @view.memoize
57
    def show_prices(self):
58
        """Checks if prices should be shown or not
59
        """
60
        setup = api.get_setup()
61
        return setup.getShowPrices()
62
63
    @view.memoize
64
    def get_currency_symbol(self):
65
        """Get the currency Symbol
66
        """
67
        locale = locales.getLocale('en')
68
        setup = api.get_setup()
69
        currency = setup.getCurrency()
70
        return locale.numbers.currencies[currency].symbol
71
72
    def get_icon_for(self, typename):
73
        image = "{}_big.png".format(typename)
74
        return get_image(
75
            image, width="20px", style="vertical-align: baseline;")
76
77
    @view.memoize
78
    def get_service(self):
79
        service_uid = self.request.form.get("service_uid")
80
        return api.get_object_by_uid(service_uid, None)
81
82
    @view.memoize
83
    def get_service_url(self):
84
        service = self.get_service()
85
        return api.get_url(service)
86
87
    @view.memoize
88
    def is_accredited(self):
89
        service = self.get_service()
90
        return service.getAccredited()
91
92
    def get_analysis_or_service(self):
93
        analysis = self.get_analysis()
94
        if analysis:
95
            return analysis
96
        return self.get_service()
97
98
    def get_methods(self):
99
        if not self.get_service():
100
            return None
101
        return self.get_service().getMethods()
102
103
    @view.memoize
104
    def get_analysis(self):
105
        analysis_uid = self.request.form.get("analysis_uid")
106
        return api.get_object_by_uid(analysis_uid, None)
107
108
    @view.memoize
109
    def get_calculation(self):
110
        if not self.get_analysis_or_service():
111
            return None
112
        return self.get_analysis_or_service().getCalculation()
113
114
    def get_dependent_services(self):
115
        if not self.get_calculation():
116
            return []
117
        return self.get_calculation().getDependentServices()
118
119
    def get_calculation_dependencies(self):
120
        if not self.get_calculation():
121
            return []
122
        return self.get_calculation().getCalculationDependencies()
123
124
    def analysis_log_view(self):
125
        """Get the log view of the requested analysis
126
        """
127
        analysis = self.get_analysis()
128
        if analysis is None:
129
            return None
130
        view = api.get_view("log", context=analysis, request=self.request)
131
        view.update()
132
        view.before_render()
133
        return view
134
135
136
class ajaxGetContainers(BrowserView):
137
    """ajax Preservation/Container widget filter
138
    request values:
139
    - allow_blank: print blank value in return
140
    - show_container_types
141
    - show_containers
142
    - minvol: magnitude (string).
143
    """
144
    def __call__(self):
145
        plone.protect.CheckAuthenticator(self.request)
146
147
        allow_blank = self.request.get('allow_blank', False) == 'true'
148
        show_container_types = json.loads(self.request.get('show_container_types', 'true'))
149
        show_containers = json.loads(self.request.get('show_containers', 'true'))
150
        minvol = self.request.get("minvol", "0")
151
        try:
152
            minvol = minvol.split()
153
            minvol = mg(float(minvol[0]), " ".join(minvol[1:]))
154
        except:
155
            minvol = mg(0)
156
157
        containers = getContainers(
158
            self.context,
159
            minvol=minvol,
160
            allow_blank=allow_blank,
161
            show_containers=show_containers,
162
            show_container_types=show_container_types,
163
        )
164
165
        return json.dumps(containers)
166
167
168
class ajaxGetServiceInterimFields:
169
    "Tries to fall back to Calculation for defaults"
170
171
    def __init__(self, context, request):
172
        self.context = context
173
        self.request = request
174
175
    def __call__(self):
176
        plone.protect.CheckAuthenticator(self.request)
177
        plone.protect.PostOnly(self.request)
178
        bsc = getToolByName(self.context, 'bika_setup_catalog')
179
        service_url = self.request['service_url']
180
        service_id = service_url.split('/')[-1]
181
        services = bsc(portal_type='AnalysisService', id=service_id)
182
        if services:
183
            service = services[0].getObject()
184
            service_interims = service.getInterimFields()
185
        else:
186
            # portal_factory has no service
187
            return
188
189
        calc = service.getCalculation()
190
        if calc:
191
            calc_interims = calc.getInterimFields()
192
        else:
193
            calc_interims = []
194
195
        # overwrite existing fields in position
196
        for s_i in service_interims:
197
            placed = 0
198
            for c_i in calc_interims:
199
                if s_i['keyword'] == c_i['keyword']:
200
                    c_i['value'] = s_i['value']
201
                    placed = 1
202
                    break
203
            if placed:
204
                continue
205
            # otherwise, create new ones (last)
206
            calc_interims.append(s_i)
207
208
        return json.dumps(calc_interims)
209
210
211
class JSONReadExtender(object):
212
    """- Adds fields to Analysis Service:
213
214
    MethodInstruments - A dictionary of instruments:
215
        keys: Method UID
216
        values: list of instrument UIDs
217
218
    """
219
220
    implements(IJSONReadExtender)
221
    adapts(IAnalysisService)
222
223
    def __init__(self, context):
224
        self.context = context
225
226
    def service_info(self, service):
227
        ret = {
228
            "Category": service.getCategory().Title(),
229
            "Category_uid": service.getCategory().UID(),
230
            "Service": service.Title(),
231
            "Service_uid": service.UID(),
232
            "Keyword": service.getKeyword(),
233
            "PointOfCapture": service.getPointOfCapture(),
234
            "PointOfCapture_title": POINTS_OF_CAPTURE.getValue(service.getPointOfCapture()),
235
        }
236
        return ret
237
238
    def __call__(self, request, data):
239
        include_fields = get_include_fields(request)
240
241
        if not include_fields or "MethodInstruments" in include_fields:
242
            data["MethodInstruments"] = {}
243
            for method in self.context.getAvailableMethods():
244
                for instrument in method.getInstruments():
245
                    if method.UID() not in data["MethodInstruments"]:
246
                        data["MethodInstruments"][method.UID()] = []
247
                    data["MethodInstruments"][method.UID()].append(
248
                        load_field_values(instrument, include_fields=[]))
249