Completed
Branch master (9edffc)
by Jordi
04:36
created

PrintForm.getAnalysisRequestBySample()   C

Complexity

Conditions 8

Size

Total Lines 67
Code Lines 48

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 48
dl 0
loc 67
rs 6.8351
c 0
b 0
f 0
cc 8
nop 1

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

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
from bika.lims import bikaMessageFactory as _, t
9
from Products.CMFCore.utils import getToolByName
10
from Products.CMFPlone.utils import safe_unicode
11
from bika.lims.utils import to_utf8, createPdf
12
from bika.lims.browser import BrowserView
13
from Products.Five.browser.pagetemplatefile import ViewPageTemplateFile
14
from plone.resource.utils import iterDirectoriesOfType, queryResourceDirectory
15
import App
16
import tempfile
17
import os
18
import glob
19
import traceback
20
21
22
class PrintForm(BrowserView):
23
    template = ViewPageTemplateFile("templates/print_form.pt")
24
    _DEFAULT_TEMPLATE = 'default_form.pt'
25
    _TEMPLATES_DIR = 'templates/print'
26
    _TEMPLATES_ADDON_DIR = 'samplingrounds'
27
    _current_sr_index = 0
28
    _samplingrounds = []
29
30
    def __call__(self):
31 View Code Duplication
        if self.context.portal_type == 'SamplingRound':
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
32
            self._samplingrounds = [self.context]
33
34
        elif self.context.portal_type == 'SamplingRounds' \
35
                and self.request.get('items', ''):
36
            uids = self.request.get('items').split(',')
37
            uc = getToolByName(self.context, 'uid_catalog')
38
            self._samplingrounds = [obj.getObject() for obj in uc(UID=uids)]
39
40
        else:
41
            # Warn and redirect to referer
42
            logger.warning('PrintView: type not allowed: %s' %
0 ignored issues
show
Comprehensibility Best Practice introduced by
Undefined variable 'logger'
Loading history...
Comprehensibility Best Practice introduced by
The variable logger does not seem to be defined.
Loading history...
43
                            self.context.portal_type)
44
            self.destination_url = self.request.get_header("referer",
45
                                   self.context.absolute_url())
46
47
        # Do print?
48
        if self.request.form.get('pdf', '0') == '1':
49
            response = self.request.response
50
            response.setHeader("Content-type", "application/pdf")
51
            response.setHeader("Content-Disposition", "inline")
52
            response.setHeader("filename", "temp.pdf")
53
            return self.pdfFromPOST()
54
        else:
55
            return self.template()
56
57
    def getSamplingRoundObj(self):
58
        """Returns the sampling round object
59
        """
60
        return self.context
61
62 View Code Duplication
    def getSRTemplates(self):
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
63
        """
64
        Returns a DisplayList with the available templates found in
65
        browser/samplinground/templates/
66
        """
67
        this_dir = os.path.dirname(os.path.abspath(__file__))
68
        templates_dir = os.path.join(this_dir, self._TEMPLATES_DIR)
69
        tempath = '%s/%s' % (templates_dir, '*.pt')
70
        templates = [t.split('/')[-1] for t in glob.glob(tempath)]
71
        out = []
72
        for template in templates:
73
            out.append({'id': template, 'title': template[:-3]})
74
        for templates_resource in iterDirectoriesOfType(self._TEMPLATES_ADDON_DIR):
75
            prefix = templates_resource.__name__
76
            templates = [
77
                tpl for tpl in templates_resource.listDirectory()
78
                if tpl.endswith('.pt')
79
                ]
80
            for template in templates:
81
                out.append({
82
                    'id': '{0}:{1}'.format(prefix, template),
83
                    'title': '{0} ({1})'.format(template[:-3], prefix),
84
                })
85
        return out
86
87 View Code Duplication
    def getFormTemplate(self):
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
88
        """Returns the current samplinground rendered with the template
89
            specified in the request (param 'template').
90
            Moves the iterator to the next samplinground available.
91
        """
92
        templates_dir = self._TEMPLATES_DIR
93
        embedt = self.request.get('template', self._DEFAULT_TEMPLATE)
94
        if embedt.find(':') >= 0:
95
            prefix, embedt = embedt.split(':')
96
            templates_dir = queryResourceDirectory(self._TEMPLATES_ADDON_DIR, prefix).directory
97
        embed = ViewPageTemplateFile(os.path.join(templates_dir, embedt))
98
        reptemplate = ""
99
        try:
100
            reptemplate = embed(self)
101
        except:
102
            tbex = traceback.format_exc()
103
            wsid = self._samplingrounds[self._current_sr_index].id
104
            reptemplate = "<div class='error-print'>%s - %s '%s':<pre>%s</pre></div>" % (wsid, _("Unable to load the template"), embedt, tbex)
105
        if self._current_sr_index < len(self._samplingrounds):
106
            self._current_sr_index += 1
107
        return reptemplate
108
109 View Code Duplication
    def getCSS(self):
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
110
        """ Returns the css style to be used for the current template.
111
            If the selected template is 'default.pt', this method will
112
            return the content from 'default.css'. If no css file found
113
            for the current template, returns empty string
114
        """
115
        template = self.request.get('template', self._DEFAULT_TEMPLATE)
116
        content = ''
117
        if template.find(':') >= 0:
118
            prefix, template = template.split(':')
119
            resource = queryResourceDirectory(
120
                self._TEMPLATES_ADDON_DIR, prefix)
121
            css = '{0}.css'.format(template[:-3])
122
            if css in resource.listDirectory():
123
                content = resource.readFile(css)
124
        else:
125
            this_dir = os.path.dirname(os.path.abspath(__file__))
126
            templates_dir = os.path.join(this_dir, self._TEMPLATES_DIR)
127
            path = '%s/%s.css' % (templates_dir, template[:-3])
128
            with open(path, 'r') as content_file:
129
                content = content_file.read()
130
        return content
131
132
    def getAnalysisRequestTemplatesInfo(self):
133
        """
134
        Returns a lost of dicts with the analysis request templates infomration
135
        [{'uid':'xxxx','id':'xxxx','title':'xxx','url':'xxx'}, ...]
136
        """
137
        arts_list = []
138
        for art in self.context.ar_templates:
139
            pc = getToolByName(self.context, 'portal_catalog')
140
            contentFilter = {'portal_type': 'ARTemplate',
141
                             'UID': art}
142
            art_brain = pc(contentFilter)
143
            if len(art_brain) == 1:
144
                art_obj = art_brain[0].getObject()
145
                arts_list.append({
146
                    'uid': art_obj.UID(),
147
                    'id': art_obj.id,
148
                    'title': art_obj.title,
149
                    'url': art_obj.absolute_url(),
150
                })
151
        return arts_list
152
153
    def getAnalysisRequestBySample(self):
154
        """
155
        Returns a list of dictionaries sorted by Sample Partition/Container
156
        [{'requests and partition info'}, ...]
157
        """
158
        # rows will contain the data for each html row
159
        rows = []
160
        # columns will be used to sort and define the columns
161
        columns = {
162
            'column_order': [
163
                'sample_id',
164
                'sample_type',
165
                'sampling_point',
166
                'sampling_date',
167
                'analyses',
168
                ],
169
            'titles': {
170
                'sample_id': _('Sample ID'),
171
                'sample_type': _('Sample Type'),
172
                'sampling_point': _('Sampling Point'),
173
                'sampling_date': _('Sampling Date'),
174
                'analyses': _('Analysis'),
175
            }
176
        }
177
        ars = self.context.getAnalysisRequests()
178
        for ar in ars:
179
            ar = ar.getObject()
180
            arcell = False
181
            analyses = ar.getAnalyses()
182
            numans = len(analyses)
183
            for analysis in analyses:
184
                row = {
185
                    'sample_id': {
186
                        'hidden': True if arcell else False,
187
                        'rowspan': numans,
188
                        'value': ar.getId(),
189
                        },
190
                    'sample_type': {
191
                        'hidden': True if arcell else False,
192
                        'rowspan': numans,
193
                        'value': ar.getSampleType().title,
194
                        },
195
                    'sampling_point': {
196
                        'hidden': True if arcell else False,
197
                        'rowspan': numans,
198
                        'value': ar.getSamplePoint().title if ar.getSamplePoint() else '',
199
                        },
200
                    'sampling_date': {
201
                        'hidden': True if arcell else False,
202
                        'rowspan': numans,
203
                        'value': self.context.sampling_date,
204
                        },
205
                    'analyses': {
206
                        'title': analysis.title,
207
                        'units': analysis.getUnit,
208
                    },
209
                }
210
                rows.append(row)
211
                arcell = True
212
213
        # table will contain the data that from where the html
214
        # will take the info
215
        table = {
216
            'columns': columns,
217
            'rows': rows,
218
        }
219
        return table
220
221
    def getLab(self):
222
        return self.context.bika_setup.laboratory.getLabURL()
223
224
    def getLogo(self):
225
        portal = self.context.portal_url.getPortalObject()
226
        return "%s/logo_print.png" % portal.absolute_url()
227
228
    def pdfFromPOST(self):
229
        """
230
        It returns the pdf for the sampling rounds printed
231
        """
232
        html = self.request.form.get('html')
233
        style = self.request.form.get('style')
234
        reporthtml = "<html><head>%s</head><body><div id='report'>%s</body></html>" % (style, html)
235
        return self.printFromHTML(safe_unicode(reporthtml).encode('utf-8'))
236
237
    def printFromHTML(self, sr_html):
238
        """
239
        Tis function generates a pdf file from the html
240
        :sr_html: the html to use to generate the pdf
241
        """
242
        # HTML written to debug file
243
        debug_mode = App.config.getConfiguration().debug_mode
244
        if debug_mode:
245
            tmp_fn = tempfile.mktemp(suffix=".html")
246
            open(tmp_fn, "wb").write(sr_html)
247
248
        # Creates the pdf
249
        # we must supply the file ourself so that createPdf leaves it alone.
250
        pdf_fn = tempfile.mktemp(suffix=".pdf")
251
        pdf_report = createPdf(htmlreport=sr_html, outfile=pdf_fn)
252
        return pdf_report
253