1
|
|
|
# -*- coding: utf-8 -*- |
2
|
|
|
# |
3
|
|
|
# This file is part of SENAITE.HEALTH. |
4
|
|
|
# |
5
|
|
|
# SENAITE.HEALTH is free software: you can redistribute it and/or modify it |
6
|
|
|
# under the terms of the GNU General Public License as published by the Free |
7
|
|
|
# Software 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
|
|
|
from DateTime import DateTime |
22
|
|
|
from Products.Five.browser.pagetemplatefile import ViewPageTemplateFile |
23
|
|
|
from bika.lims import bikaMessageFactory as _b |
24
|
|
|
from bika.lims.browser import BrowserView |
25
|
|
|
|
26
|
|
|
|
27
|
|
|
class BatchPublishView(BrowserView): |
28
|
|
|
"""Publish a single Batch. |
29
|
|
|
""" |
30
|
|
|
|
31
|
|
|
template = ViewPageTemplateFile("publish.pt") |
32
|
|
|
|
33
|
|
|
def __call__(self): |
34
|
|
|
|
35
|
|
|
pc = self.portal_catalog |
36
|
|
|
bc = self.bika_catalog |
37
|
|
|
bsc = self.bika_setup_catalog |
38
|
|
|
self.checkPermission = self.context.portal_membership.checkPermission |
39
|
|
|
self.now = DateTime() |
40
|
|
|
self.SamplingWorkflowEnabled = self.context.bika_setup.getSamplingWorkflowEnabled() |
41
|
|
|
|
42
|
|
|
# Client details (if client is associated) |
43
|
|
|
self.client = None |
44
|
|
|
client_uid = hasattr(self.context, 'getClientUID') and self.context.getClientUID() |
45
|
|
|
if client_uid: |
46
|
|
|
proxies = pc(portal_type='Client', UID=client_uid) |
47
|
|
|
if proxies: |
|
|
|
|
48
|
|
|
self.client = proxies[0].getObject() |
49
|
|
|
client_address = self.client.getPostalAddress() \ |
50
|
|
|
or self.contact.getBillingAddress() \ |
51
|
|
|
or self.contact.getPhysicalAddress() |
52
|
|
|
if client_address: |
53
|
|
|
_keys = ['address', 'city', 'state', 'zip', 'country'] |
54
|
|
|
_list = [client_address.get(v) for v in _keys if client_address.get(v)] |
55
|
|
|
self.client_address = "<br/>".join(_list).replace("\n", "<br/>") |
56
|
|
|
if self.client_address.endswith("<br/>"): |
57
|
|
|
self.client_address = self.client_address[:-5] |
58
|
|
|
else: |
59
|
|
|
self.client_address = None |
60
|
|
|
|
61
|
|
|
# Reporter |
62
|
|
|
self.member = self.context.portal_membership.getAuthenticatedMember() |
63
|
|
|
self.username = self.member.getUserName() |
64
|
|
|
self.reporter = self.user_fullname(self.username) |
65
|
|
|
self.reporter_email = self.user_email(self.username) |
66
|
|
|
self.reporter_signature = "" |
67
|
|
|
c = [x for x in self.bika_setup_catalog(portal_type='LabContact') |
68
|
|
|
if x.getObject().getUsername() == self.username] |
69
|
|
|
if c: |
70
|
|
|
sf = c[0].getObject().getSignature() |
71
|
|
|
if sf: |
72
|
|
|
self.reporter_signature = sf.absolute_url() + "/Signature" |
73
|
|
|
|
74
|
|
|
# laboratory |
75
|
|
|
self.laboratory = self.context.bika_setup.laboratory |
76
|
|
|
self.accredited = self.laboratory.getLaboratoryAccredited() |
77
|
|
|
lab_address = self.laboratory.getPrintAddress() |
78
|
|
|
if lab_address: |
79
|
|
|
_keys = ['address', 'city', 'state', 'zip', 'country'] |
80
|
|
|
_list = [lab_address.get(v) for v in _keys if lab_address.get(v)] |
81
|
|
|
self.lab_address = "<br/>".join(_list).replace("\n", "<br/>") |
82
|
|
|
if self.lab_address.endswith("<br/>"): |
83
|
|
|
self.lab_address = self.lab_address[:-5] |
84
|
|
|
else: |
85
|
|
|
self.lab_address = None |
86
|
|
|
|
87
|
|
|
# Analysis Request results |
88
|
|
|
self.ars = [] |
89
|
|
|
self.ar_headers = [_b("Request ID"), |
90
|
|
|
_b("Date Requested"), |
91
|
|
|
_b("Sample Type"), |
92
|
|
|
_b("Sample Point")] |
93
|
|
|
self.analysis_headers = [_b("Analysis Service"), |
94
|
|
|
_b("Method"), |
95
|
|
|
_b("Result"), |
96
|
|
|
_b("Analyst")] |
97
|
|
|
for ar in self.context.getAnalysisRequests(): |
98
|
|
|
datecreated = ar.created() |
99
|
|
|
datereceived = ar.getDateReceived() |
100
|
|
|
datepublished = ar.getDatePublished() |
101
|
|
|
datalines = [] |
102
|
|
|
for analysis in ar.getAnalyses(full_objects=True): |
103
|
|
|
method = analysis.getMethod() |
104
|
|
|
sample = ar.getSample() |
105
|
|
|
result = analysis.getResult() |
106
|
|
|
try: |
107
|
|
|
precision = analysis.getPrecision() |
108
|
|
|
if not precision: |
109
|
|
|
precision = "2" |
110
|
|
|
result = float(result) |
111
|
|
|
formatted_result = str("%." + precision + "f") % result |
112
|
|
|
except (TypeError, ValueError): |
113
|
|
|
precision = "2" |
114
|
|
|
formatted_result = result |
115
|
|
|
datalines.append({_b("Analysis Service"): analysis.Title(), |
116
|
|
|
_b("Method"): method and method.Title() or "", |
117
|
|
|
_b("Result"): formatted_result, |
118
|
|
|
_b("Analyst"): self.user_fullname(analysis.getAnalyst()), |
119
|
|
|
_b("Remarks"): analysis.getRemarks()}) |
120
|
|
|
self.ars.append({ |
121
|
|
|
_b("Request ID"): ar.getRequestID(), |
122
|
|
|
_b("Date Requested"): self.ulocalized_time(datecreated), # requested->created |
123
|
|
|
_b("Sample Type"): sample.getSampleType() and sample.getSampleType().Title() or '', |
|
|
|
|
124
|
|
|
_b("Sample Point"): sample.getSamplePoint() and sample.getSamplePoint().Title() or '', |
125
|
|
|
_b("datalines"): datalines, |
126
|
|
|
}) |
127
|
|
|
|
128
|
|
|
# Create Report |
129
|
|
|
fn = self.context.Title() + " " + self.ulocalized_time(self.now) |
130
|
|
|
report_html = self.template() |
131
|
|
|
|
132
|
|
|
debug_mode = App.config.getConfiguration().debug_mode |
|
|
|
|
133
|
|
|
if debug_mode: |
134
|
|
|
open(os.path.join(Globals.INSTANCE_HOME, 'var', fn + ".html"), |
|
|
|
|
135
|
|
|
"w").write(report_html) |
136
|
|
|
|
137
|
|
|
pisa.showLogging() |
|
|
|
|
138
|
|
|
ramdisk = StringIO() |
|
|
|
|
139
|
|
|
pdf = pisa.CreatePDF(report_html, ramdisk) |
140
|
|
|
pdf_data = ramdisk.getvalue() |
141
|
|
|
ramdisk.close() |
142
|
|
|
|
143
|
|
|
if debug_mode: |
144
|
|
|
open(os.path.join(Globals.INSTANCE_HOME, 'var', fn + ".pdf"), |
145
|
|
|
"wb").write(pdf_data) |
146
|
|
|
|
147
|
|
|
# Email to who? |
148
|
|
|
|
149
|
|
|
# Send PDF to browser |
150
|
|
|
if not pdf.err: |
151
|
|
|
setheader = self.request.RESPONSE.setHeader |
152
|
|
|
setheader('Content-Type', 'application/pdf') |
153
|
|
|
setheader("Content-Disposition", "attachment;filename=\"%s\"" % fn) |
154
|
|
|
self.request.RESPONSE.write(pdf_data) |
155
|
|
|
|