|
@ -1,4 +1,3 @@ |
|
|
# -*- coding: utf-8 -*- |
|
|
|
|
|
# Copyright 2015 Tecnativa - Antonio Espinosa |
|
|
# Copyright 2015 Tecnativa - Antonio Espinosa |
|
|
# Copyright 2017 Tecnativa - Pedro M. Baeza |
|
|
# Copyright 2017 Tecnativa - Pedro M. Baeza |
|
|
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). |
|
|
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). |
|
@ -28,16 +27,16 @@ def _normalize_filepath(path): |
|
|
return path if os.path.exists(path) else False |
|
|
return path if os.path.exists(path) else False |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class Report(models.Model): |
|
|
|
|
|
_inherit = 'report' |
|
|
|
|
|
|
|
|
class IrActionsReport(models.Model): |
|
|
|
|
|
_inherit = 'ir.actions.report' |
|
|
|
|
|
|
|
|
def _certificate_get(self, report, docids): |
|
|
|
|
|
|
|
|
def _certificate_get(self, res_ids): |
|
|
"""Obtain the proper certificate for the report and the conditions.""" |
|
|
"""Obtain the proper certificate for the report and the conditions.""" |
|
|
if report.report_type != 'qweb-pdf': |
|
|
|
|
|
|
|
|
if self.report_type != 'qweb-pdf': |
|
|
return False |
|
|
return False |
|
|
certificates = self.env['report.certificate'].search([ |
|
|
certificates = self.env['report.certificate'].search([ |
|
|
('company_id', '=', self.env.user.company_id.id), |
|
|
('company_id', '=', self.env.user.company_id.id), |
|
|
('model_id', '=', report.model), |
|
|
|
|
|
|
|
|
('model_id', '=', self.model), |
|
|
]) |
|
|
]) |
|
|
if not certificates: |
|
|
if not certificates: |
|
|
return False |
|
|
return False |
|
@ -47,11 +46,11 @@ class Report(models.Model): |
|
|
_logger.debug( |
|
|
_logger.debug( |
|
|
"Certificate '%s' allows only one document, " |
|
|
"Certificate '%s' allows only one document, " |
|
|
"but printing %d documents", |
|
|
"but printing %d documents", |
|
|
cert.name, len(docids)) |
|
|
|
|
|
|
|
|
cert.name, len(res_ids)) |
|
|
continue |
|
|
continue |
|
|
# Check domain |
|
|
# Check domain |
|
|
if cert.domain: |
|
|
if cert.domain: |
|
|
domain = [('id', 'in', tuple(docids))] |
|
|
|
|
|
|
|
|
domain = [('id', 'in', tuple(res_ids))] |
|
|
domain = domain + safe_eval(cert.domain) |
|
|
domain = domain + safe_eval(cert.domain) |
|
|
docs = self.env[cert.model_id.model].search(domain) |
|
|
docs = self.env[cert.model_id.model].search(domain) |
|
|
if not docs: |
|
|
if not docs: |
|
@ -62,34 +61,34 @@ class Report(models.Model): |
|
|
return cert |
|
|
return cert |
|
|
return False |
|
|
return False |
|
|
|
|
|
|
|
|
def _attach_filename_get(self, docids, certificate): |
|
|
|
|
|
if len(docids) != 1: |
|
|
|
|
|
|
|
|
def _attach_filename_get(self, res_ids, certificate): |
|
|
|
|
|
if len(res_ids) != 1: |
|
|
return False |
|
|
return False |
|
|
doc = self.env[certificate.model_id.model].browse(docids[0]) |
|
|
|
|
|
|
|
|
doc = self.env[certificate.model_id.model].browse(res_ids[0]) |
|
|
return safe_eval(certificate.attachment, { |
|
|
return safe_eval(certificate.attachment, { |
|
|
'object': doc, |
|
|
'object': doc, |
|
|
'time': time |
|
|
'time': time |
|
|
}) |
|
|
}) |
|
|
|
|
|
|
|
|
def _attach_signed_read(self, docids, certificate): |
|
|
|
|
|
if len(docids) != 1: |
|
|
|
|
|
|
|
|
def _attach_signed_read(self, res_ids, certificate): |
|
|
|
|
|
if len(res_ids) != 1: |
|
|
return False |
|
|
return False |
|
|
filename = self._attach_filename_get(docids, certificate) |
|
|
|
|
|
|
|
|
filename = self._attach_filename_get(res_ids, certificate) |
|
|
if not filename: |
|
|
if not filename: |
|
|
return False |
|
|
return False |
|
|
attachment = self.env['ir.attachment'].search([ |
|
|
attachment = self.env['ir.attachment'].search([ |
|
|
('datas_fname', '=', filename), |
|
|
('datas_fname', '=', filename), |
|
|
('res_model', '=', certificate.model_id.model), |
|
|
('res_model', '=', certificate.model_id.model), |
|
|
('res_id', '=', docids[0]), |
|
|
|
|
|
|
|
|
('res_id', '=', res_ids[0]), |
|
|
], limit=1) |
|
|
], limit=1) |
|
|
if attachment: |
|
|
if attachment: |
|
|
return base64.decodestring(attachment.datas) |
|
|
return base64.decodestring(attachment.datas) |
|
|
return False |
|
|
return False |
|
|
|
|
|
|
|
|
def _attach_signed_write(self, docids, certificate, signed): |
|
|
|
|
|
if len(docids) != 1: |
|
|
|
|
|
|
|
|
def _attach_signed_write(self, res_ids, certificate, signed): |
|
|
|
|
|
if len(res_ids) != 1: |
|
|
return False |
|
|
return False |
|
|
filename = self._attach_filename_get(docids, certificate) |
|
|
|
|
|
|
|
|
filename = self._attach_filename_get(res_ids, certificate) |
|
|
if not filename: |
|
|
if not filename: |
|
|
return False |
|
|
return False |
|
|
try: |
|
|
try: |
|
@ -98,7 +97,7 @@ class Report(models.Model): |
|
|
'datas': base64.encodestring(signed), |
|
|
'datas': base64.encodestring(signed), |
|
|
'datas_fname': filename, |
|
|
'datas_fname': filename, |
|
|
'res_model': certificate.model_id.model, |
|
|
'res_model': certificate.model_id.model, |
|
|
'res_id': docids[0], |
|
|
|
|
|
|
|
|
'res_id': res_ids[0], |
|
|
}) |
|
|
}) |
|
|
except AccessError: |
|
|
except AccessError: |
|
|
raise UserError( |
|
|
raise UserError( |
|
@ -108,9 +107,11 @@ class Report(models.Model): |
|
|
|
|
|
|
|
|
def _signer_bin(self, opts): |
|
|
def _signer_bin(self, opts): |
|
|
me = os.path.dirname(__file__) |
|
|
me = os.path.dirname(__file__) |
|
|
|
|
|
irc_param = self.env['ir.config_parameter'].sudo() |
|
|
java_bin = 'java -jar' |
|
|
java_bin = 'java -jar' |
|
|
|
|
|
java_param = irc_param.get_param('report_qweb_signer.java_parameters') |
|
|
jar = '{}/../static/jar/jPdfSign.jar'.format(me) |
|
|
jar = '{}/../static/jar/jPdfSign.jar'.format(me) |
|
|
return '%s %s %s' % (java_bin, jar, opts) |
|
|
|
|
|
|
|
|
return '%s %s %s %s' % (java_bin, java_param, jar, opts) |
|
|
|
|
|
|
|
|
def pdf_sign(self, pdf, certificate): |
|
|
def pdf_sign(self, pdf, certificate): |
|
|
pdfsigned = pdf + '.signed.pdf' |
|
|
pdfsigned = pdf + '.signed.pdf' |
|
@ -132,30 +133,28 @@ class Report(models.Model): |
|
|
(process.returncode, err, out)) |
|
|
(process.returncode, err, out)) |
|
|
return pdfsigned |
|
|
return pdfsigned |
|
|
|
|
|
|
|
|
@api.model |
|
|
|
|
|
def get_pdf(self, docids, report_name, html=None, data=None): |
|
|
|
|
|
report = self._get_report_from_name(report_name) |
|
|
|
|
|
certificate = self._certificate_get(report, docids) |
|
|
|
|
|
|
|
|
@api.multi |
|
|
|
|
|
def render_qweb_pdf(self, res_ids=None, data=None): |
|
|
|
|
|
certificate = self._certificate_get(res_ids) |
|
|
if certificate and certificate.attachment: |
|
|
if certificate and certificate.attachment: |
|
|
signed_content = self._attach_signed_read(docids, certificate) |
|
|
|
|
|
|
|
|
signed_content = self._attach_signed_read(res_ids, certificate) |
|
|
if signed_content: |
|
|
if signed_content: |
|
|
_logger.debug( |
|
|
_logger.debug( |
|
|
"The signed PDF document '%s/%s' was loaded from the " |
|
|
"The signed PDF document '%s/%s' was loaded from the " |
|
|
"database", report_name, docids, |
|
|
|
|
|
|
|
|
"database", self.report_name, res_ids, |
|
|
) |
|
|
) |
|
|
return signed_content |
|
|
return signed_content |
|
|
content = super(Report, self).get_pdf( |
|
|
|
|
|
docids, report_name, html=html, data=data, |
|
|
|
|
|
) |
|
|
|
|
|
|
|
|
content, ext = super(IrActionsReport, self).render_qweb_pdf(res_ids, |
|
|
|
|
|
data) |
|
|
if certificate: |
|
|
if certificate: |
|
|
# Creating temporary origin PDF |
|
|
# Creating temporary origin PDF |
|
|
pdf_fd, pdf = tempfile.mkstemp( |
|
|
pdf_fd, pdf = tempfile.mkstemp( |
|
|
suffix='.pdf', prefix='report.tmp.') |
|
|
suffix='.pdf', prefix='report.tmp.') |
|
|
with closing(os.fdopen(pdf_fd, 'w')) as pf: |
|
|
|
|
|
|
|
|
with closing(os.fdopen(pdf_fd, 'wb')) as pf: |
|
|
pf.write(content) |
|
|
pf.write(content) |
|
|
_logger.debug( |
|
|
_logger.debug( |
|
|
"Signing PDF document '%s' for IDs %s with certificate '%s'", |
|
|
"Signing PDF document '%s' for IDs %s with certificate '%s'", |
|
|
report_name, docids, certificate.name, |
|
|
|
|
|
|
|
|
self.report_name, res_ids, certificate.name, |
|
|
) |
|
|
) |
|
|
signed = self.pdf_sign(pdf, certificate) |
|
|
signed = self.pdf_sign(pdf, certificate) |
|
|
# Read signed PDF |
|
|
# Read signed PDF |
|
@ -169,5 +168,5 @@ class Report(models.Model): |
|
|
except (OSError, IOError): |
|
|
except (OSError, IOError): |
|
|
_logger.error('Error when trying to remove file %s', fname) |
|
|
_logger.error('Error when trying to remove file %s', fname) |
|
|
if certificate.attachment: |
|
|
if certificate.attachment: |
|
|
self._attach_signed_write(docids, certificate, content) |
|
|
|
|
|
return content |
|
|
|
|
|
|
|
|
self._attach_signed_write(res_ids, certificate, content) |
|
|
|
|
|
return content, ext |