Passed
Push — master ( 41ae8a...4c101c )
by Jordi
05:16
created

AnalysisServiceInfoView.get_calculation()   A

Complexity

Conditions 2

Size

Total Lines 5
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 5
dl 0
loc 5
rs 10
c 0
b 0
f 0
cc 2
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 json
9
10
import plone
11
import plone.protect
12
from bika.lims import api
13
from bika.lims.browser import BrowserView
14
from bika.lims.config import POINTS_OF_CAPTURE
15
from bika.lims.content.analysisservice import getContainers
16
from bika.lims.interfaces import IAnalysisService
17
from bika.lims.interfaces import IJSONReadExtender
18
from bika.lims.jsonapi import get_include_fields
19
from bika.lims.jsonapi import load_field_values
20
from bika.lims.utils import get_image
21
from magnitude import mg
22
from plone.memoize import view
23
from Products.CMFCore.utils import getToolByName
24
from Products.Five.browser.pagetemplatefile import ViewPageTemplateFile
25
from zope.component import adapts
26
from zope.interface import implements
27
from zope.i18n.locales import locales
28
29
30
class AnalysisServiceInfoView(BrowserView):
31
    """Show details of the Analysis Service
32
    """
33
    template = ViewPageTemplateFile("templates/analysisservice_info.pt")
34
35
    def __init__(self, context, request):
36
        super(AnalysisServiceInfoView, self).__init__(context, request)
37
38
    def __call__(self):
39
        # disable the editable border
40
        self.request.set("disable_border", 1)
41
        return self.template()
42
43
    @view.memoize
44
    def show_prices(self):
45
        """Checks if prices should be shown or not
46
        """
47
        setup = api.get_setup()
48
        return setup.getShowPrices()
49
50
    @view.memoize
51
    def get_currency_symbol(self):
52
        """Get the currency Symbol
53
        """
54
        locale = locales.getLocale('en')
55
        setup = api.get_setup()
56
        currency = setup.getCurrency()
57
        return locale.numbers.currencies[currency].symbol
58
59
    def get_icon_for(self, typename):
60
        image = "{}_big.png".format(typename)
61
        return get_image(
62
            image, width="20px", style="vertical-align: baseline;")
63
64
    @view.memoize
65
    def get_service(self):
66
        service_uid = self.request.form.get("service_uid")
67
        return api.get_object_by_uid(service_uid, None)
68
69
    def get_methods(self):
70
        if not self.get_service():
71
            return None
72
        return self.get_service().getMethods()
73
74
    def get_analysis(self):
75
        analysis_uid = self.request.form.get("analysis_uid")
76
        return api.get_object_by_uid(analysis_uid, None)
77
78
    @view.memoize
79
    def get_calculation(self):
80
        if not self.get_service():
81
            return None
82
        return self.get_service().getCalculation()
83
84
    def get_dependent_services(self):
85
        if not self.get_calculation():
86
            return []
87
        return self.get_calculation().getDependentServices()
88
89
    def get_calculation_dependencies(self):
90
        if not self.get_calculation():
91
            return []
92
        return self.get_calculation().getCalculationDependencies()
93
94
    def analysis_log_view(self):
95
        """Get the log view of the requested analysis
96
        """
97
        analysis = self.get_analysis()
98
        if analysis is None:
99
            return None
100
        view = api.get_view("log", context=analysis, request=self.request)
101
        view.update()
102
        view.before_render()
103
        return view
104
105
106
class ajaxGetContainers(BrowserView):
107
    """ajax Preservation/Container widget filter
108
    request values:
109
    - allow_blank: print blank value in return
110
    - show_container_types
111
    - show_containers
112
    - minvol: magnitude (string).
113
    """
114
    def __call__(self):
115
        plone.protect.CheckAuthenticator(self.request)
116
117
        allow_blank = self.request.get('allow_blank', False) == 'true'
118
        show_container_types = json.loads(self.request.get('show_container_types', 'true'))
119
        show_containers = json.loads(self.request.get('show_containers', 'true'))
120
        minvol = self.request.get("minvol", "0")
121
        try:
122
            minvol = minvol.split()
123
            minvol = mg(float(minvol[0]), " ".join(minvol[1:]))
124
        except:
125
            minvol = mg(0)
126
127
        containers = getContainers(
128
            self.context,
129
            minvol=minvol,
130
            allow_blank=allow_blank,
131
            show_containers=show_containers,
132
            show_container_types=show_container_types,
133
        )
134
135
        return json.dumps(containers)
136
137
138
class ajaxGetServiceInterimFields:
139
    "Tries to fall back to Calculation for defaults"
140
141
    def __init__(self, context, request):
142
        self.context = context
143
        self.request = request
144
145
    def __call__(self):
146
        plone.protect.CheckAuthenticator(self.request)
147
        plone.protect.PostOnly(self.request)
148
        bsc = getToolByName(self.context, 'bika_setup_catalog')
149
        service_url = self.request['service_url']
150
        service_id = service_url.split('/')[-1]
151
        services = bsc(portal_type='AnalysisService', id=service_id)
152
        if services:
153
            service = services[0].getObject()
154
            service_interims = service.getInterimFields()
155
        else:
156
            # portal_factory has no service
157
            return
158
159
        calc = service.getCalculation()
160
        if calc:
161
            calc_interims = calc.getInterimFields()
162
        else:
163
            calc_interims = []
164
165
        # overwrite existing fields in position
166
        for s_i in service_interims:
167
            placed = 0
168
            for c_i in calc_interims:
169
                if s_i['keyword'] == c_i['keyword']:
170
                    c_i['value'] = s_i['value']
171
                    placed = 1
172
                    break
173
            if placed:
174
                continue
175
            # otherwise, create new ones (last)
176
            calc_interims.append(s_i)
177
178
        return json.dumps(calc_interims)
179
180
181
class JSONReadExtender(object):
182
    """- Adds fields to Analysis Service:
183
184
    MethodInstruments - A dictionary of instruments:
185
        keys: Method UID
186
        values: list of instrument UIDs
187
188
    """
189
190
    implements(IJSONReadExtender)
191
    adapts(IAnalysisService)
192
193
    def __init__(self, context):
194
        self.context = context
195
196
    def service_info(self, service):
197
        ret = {
198
            "Category": service.getCategory().Title(),
199
            "Category_uid": service.getCategory().UID(),
200
            "Service": service.Title(),
201
            "Service_uid": service.UID(),
202
            "Keyword": service.getKeyword(),
203
            "PointOfCapture": service.getPointOfCapture(),
204
            "PointOfCapture_title": POINTS_OF_CAPTURE.getValue(service.getPointOfCapture()),
205
        }
206
        return ret
207
208
    def __call__(self, request, data):
209
        include_fields = get_include_fields(request)
210
211
        if not include_fields or "MethodInstruments" in include_fields:
212
            data["MethodInstruments"] = {}
213
            for method in self.context.getAvailableMethods():
214
                for instrument in method.getInstruments():
215
                    if method.UID() not in data["MethodInstruments"]:
216
                        data["MethodInstruments"][method.UID()] = []
217
                    data["MethodInstruments"][method.UID()].append(
218
                        load_field_values(instrument, include_fields=[]))
219