forked from OCA/reporting-engine
-
Notifications
You must be signed in to change notification settings - Fork 2
/
report_assembler.py
126 lines (107 loc) · 4.69 KB
/
report_assembler.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
# -*- coding: utf-8 -*-
##############################################################################
#
# Author: Yannick Vaucher
# Copyright 2013 Camptocamp SA
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
import time
import base64
from PyPDF2 import PdfFileReader, PdfFileWriter
from StringIO import StringIO
from openerp.netsvc import ExportService
from openerp.report import report_sxw
from openerp import pooler
_POLLING_DELAY = 0.25
def assemble_pdf(pdf_list):
"""
Assemble a list of pdf
"""
# Even though we are using PyPDF2 we can't use PdfFileMerger
# as this issue still exists in mostly used wktohtml reports version
# http://code.google.com/p/wkhtmltopdf/issues/detail?id=635
#merger = PdfFileMerger()
#merger.append(fileobj=StringIO(invoice_pdf))
#merger.append(fileobj=StringIO(bvr_pdf))
#with tempfile.TemporaryFile() as merged_pdf:
#merger.write(merged_pdf)
#return merged_pdf.read(), 'pdf'
output = PdfFileWriter()
for pdf in pdf_list:
reader = PdfFileReader(StringIO(pdf))
for page in range(reader.getNumPages()):
output.addPage(reader.getPage(page))
s = StringIO()
output.write(s)
return s.getvalue()
class PDFReportAssembler(report_sxw.report_sxw):
""" PDFReportAssembler allows to put 2 pdf reports in one single pdf"""
def _generate_all_pdf(self, cr, uid, ids, data, report_ids, context=None):
"""
Return a list of pdf encoded in base64
"""
pool = pooler.get_pool(cr.dbname)
report_obj = pool.get('ir.actions.report.xml')
spool = ExportService._services['report']
pdf_reports = []
report_list = report_obj.browse(cr, uid, report_ids, context=context)
for report in report_list:
report_key = spool.exp_report(cr.dbname, uid, report.report_name,
ids, datas=data, context=context)
while 1:
res = spool.exp_report_get(cr.dbname, uid, report_key)
if res.get('state'):
break
time.sleep(_POLLING_DELAY)
pdf = base64.b64decode(res.get('result'))
pdf_reports.append(pdf)
return pdf_reports
def _get_report_ids(self, cr, uid, ids, context=None):
"""
Hook to define the list of report to print
"""
return []
def create_single_pdf(self, cr, uid, ids, data, report_xml, context=None):
"""Call both report to assemble both pdf"""
report_ids = self._get_report_ids(cr, uid, ids, context=context)
pdf_reports = self._generate_all_pdf(cr, uid, ids, data, report_ids, context=context)
pdf_assemblage = assemble_pdf(pdf_reports)
return pdf_assemblage, 'pdf'
def create(self, cr, uid, ids, data, context=None):
"""We override the create function in order to handle generator
Code taken from report openoffice. Thanks guys :) """
pool = pooler.get_pool(cr.dbname)
ir_obj = pool.get('ir.actions.report.xml')
report_xml_ids = ir_obj.search(cr, uid,
[('report_name', '=', self.name[7:])], context=context)
if report_xml_ids:
report_xml = ir_obj.browse(cr,
uid,
report_xml_ids[0],
context=context)
report_xml.report_rml = None
report_xml.report_rml_content = None
report_xml.report_sxw_content_data = None
report_xml.report_sxw_content = None
report_xml.report_sxw = None
else:
return super(PDFReportAssembler, self).create(cr, uid, ids, data, context)
if report_xml.report_type != 'assemblage':
return super(PDFReportAssembler, self).create(cr, uid, ids, data, context)
result = self.create_source_pdf(cr, uid, ids, data, report_xml, context)
if not result:
return (False, False)
return result