[IMP] Multiple improvements: eval_param is set on the controller, the subprocess to get the version of wkhtmltopdf is only open at OpenERP start, better exceptions handling (try to avoid exceptions shallowing) and the rpc call from the webclient to know the version of wkhtmltopdf is only done once
bzr revid: sle@openerp.com-20140321164716-uksuu6hsjj7q3698
This commit is contained in:
parent
5ac5805da0
commit
8581b1847f
|
@ -35,11 +35,13 @@ class ReportController(Controller):
|
||||||
@route('/report/<reportname>/<docids>', type='http', auth='user', website=True, multilang=True)
|
@route('/report/<reportname>/<docids>', type='http', auth='user', website=True, multilang=True)
|
||||||
def report_html(self, reportname, docids):
|
def report_html(self, reportname, docids):
|
||||||
cr, uid, context = request.cr, request.uid, request.context
|
cr, uid, context = request.cr, request.uid, request.context
|
||||||
|
docids = self._eval_params(docids)
|
||||||
return request.registry['report'].get_html(cr, uid, docids, reportname, context=context)
|
return request.registry['report'].get_html(cr, uid, docids, reportname, context=context)
|
||||||
|
|
||||||
@route('/report/pdf/report/<reportname>/<docids>', type='http', auth="user", website=True)
|
@route('/report/pdf/report/<reportname>/<docids>', type='http', auth="user", website=True)
|
||||||
def report_pdf(self, reportname, docids):
|
def report_pdf(self, reportname, docids):
|
||||||
cr, uid, context = request.cr, request.uid, request.context
|
cr, uid, context = request.cr, request.uid, request.context
|
||||||
|
docids = self._eval_params(docids)
|
||||||
pdf = request.registry['report'].get_pdf(cr, uid, docids, reportname, context=context)
|
pdf = request.registry['report'].get_pdf(cr, uid, docids, reportname, context=context)
|
||||||
pdfhttpheaders = [('Content-Type', 'application/pdf'), ('Content-Length', len(pdf))]
|
pdfhttpheaders = [('Content-Type', 'application/pdf'), ('Content-Length', len(pdf))]
|
||||||
return request.make_response(pdf, headers=pdfhttpheaders)
|
return request.make_response(pdf, headers=pdfhttpheaders)
|
||||||
|
@ -51,14 +53,14 @@ class ReportController(Controller):
|
||||||
def report_html_particular(self, reportname, **data):
|
def report_html_particular(self, reportname, **data):
|
||||||
cr, uid, context = request.cr, request.uid, request.context
|
cr, uid, context = request.cr, request.uid, request.context
|
||||||
report_obj = request.registry['report']
|
report_obj = request.registry['report']
|
||||||
data = report_obj.eval_params(data) # Sanitizing
|
data = self._eval_params(data) # Sanitizing
|
||||||
return report_obj.get_html(cr, uid, [], reportname, data=data, context=context)
|
return report_obj.get_html(cr, uid, [], reportname, data=data, context=context)
|
||||||
|
|
||||||
@route('/report/pdf/report/<reportname>', type='http', auth='user', website=True, multilang=True)
|
@route('/report/pdf/report/<reportname>', type='http', auth='user', website=True, multilang=True)
|
||||||
def report_pdf_particular(self, reportname, **data):
|
def report_pdf_particular(self, reportname, **data):
|
||||||
cr, uid, context = request.cr, request.uid, request.context
|
cr, uid, context = request.cr, request.uid, request.context
|
||||||
report_obj = request.registry['report']
|
report_obj = request.registry['report']
|
||||||
data = report_obj.eval_params(data) # Sanitizing
|
data = self._eval_params(data) # Sanitizing
|
||||||
pdf = report_obj.get_pdf(cr, uid, [], reportname, data=data, context=context)
|
pdf = report_obj.get_pdf(cr, uid, [], reportname, data=data, context=context)
|
||||||
pdfhttpheaders = [('Content-Type', 'application/pdf'), ('Content-Length', len(pdf))]
|
pdfhttpheaders = [('Content-Type', 'application/pdf'), ('Content-Length', len(pdf))]
|
||||||
return request.make_response(pdf, headers=pdfhttpheaders)
|
return request.make_response(pdf, headers=pdfhttpheaders)
|
||||||
|
@ -121,4 +123,29 @@ class ReportController(Controller):
|
||||||
|
|
||||||
@route(['/report/check_wkhtmltopdf'], type='json', auth="user")
|
@route(['/report/check_wkhtmltopdf'], type='json', auth="user")
|
||||||
def check_wkhtmltopdf(self):
|
def check_wkhtmltopdf(self):
|
||||||
return request.registry['report'].check_wkhtmltopdf()
|
return request.registry['report']._check_wkhtmltopdf()
|
||||||
|
|
||||||
|
def _eval_params(self, param):
|
||||||
|
"""Parse a dict generated by the webclient (javascript) into a python dict.
|
||||||
|
"""
|
||||||
|
if isinstance(param, dict):
|
||||||
|
for key, value in param.iteritems():
|
||||||
|
if value.lower() == 'false':
|
||||||
|
param[key] = False
|
||||||
|
elif value.lower() == 'true':
|
||||||
|
param[key] = True
|
||||||
|
elif ',' in value:
|
||||||
|
param[key] = [int(i) for i in value.split(',')]
|
||||||
|
else:
|
||||||
|
try:
|
||||||
|
param[key] = int(value)
|
||||||
|
except (ValueError, TypeError):
|
||||||
|
pass
|
||||||
|
else:
|
||||||
|
if isinstance(param, (str, unicode)):
|
||||||
|
param = [int(i) for i in param.split(',')]
|
||||||
|
if isinstance(param, list):
|
||||||
|
param = list(set(param))
|
||||||
|
if isinstance(param, int):
|
||||||
|
param = [param]
|
||||||
|
return param
|
||||||
|
|
|
@ -35,6 +35,7 @@ import lxml.html
|
||||||
import cStringIO
|
import cStringIO
|
||||||
import subprocess
|
import subprocess
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
|
from functools import partial
|
||||||
from distutils.version import LooseVersion
|
from distutils.version import LooseVersion
|
||||||
try:
|
try:
|
||||||
from pyPdf import PdfFileWriter, PdfFileReader
|
from pyPdf import PdfFileWriter, PdfFileReader
|
||||||
|
@ -45,6 +46,24 @@ except ImportError:
|
||||||
_logger = logging.getLogger(__name__)
|
_logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
"""Check the presence of wkhtmltopdf and return its version."""
|
||||||
|
wkhtmltopdf_state = 'install'
|
||||||
|
try:
|
||||||
|
process = subprocess.Popen(
|
||||||
|
['wkhtmltopdf', '--version'], stdout=subprocess.PIPE, stderr=subprocess.PIPE
|
||||||
|
)
|
||||||
|
except OSError:
|
||||||
|
_logger.error('You need wkhtmltopdf to print a pdf version of the reports.')
|
||||||
|
else:
|
||||||
|
out, err = process.communicate()
|
||||||
|
version = out.splitlines()[1].strip()
|
||||||
|
version = version.split(' ')[1]
|
||||||
|
if LooseVersion(version) < LooseVersion('0.12.0'):
|
||||||
|
_logger.warning('Upgrade wkhtmltopdf to (at least) 0.12.0')
|
||||||
|
wkhtmltopdf_state = 'upgrade'
|
||||||
|
wkhtmltopdf_state = 'ok'
|
||||||
|
|
||||||
|
|
||||||
class Report(osv.Model):
|
class Report(osv.Model):
|
||||||
_name = "report"
|
_name = "report"
|
||||||
_description = "Report"
|
_description = "Report"
|
||||||
|
@ -55,7 +74,7 @@ class Report(osv.Model):
|
||||||
# Extension of ir_ui_view.render with arguments frequently used in reports
|
# Extension of ir_ui_view.render with arguments frequently used in reports
|
||||||
#--------------------------------------------------------------------------
|
#--------------------------------------------------------------------------
|
||||||
|
|
||||||
def get_digits(self, cr, uid, obj=None, f=None, dp=None):
|
def _get_digits(self, cr, uid, obj=None, f=None, dp=None):
|
||||||
d = DEFAULT_DIGITS = 2
|
d = DEFAULT_DIGITS = 2
|
||||||
if dp:
|
if dp:
|
||||||
decimal_precision_obj = self.pool['decimal.precision']
|
decimal_precision_obj = self.pool['decimal.precision']
|
||||||
|
@ -101,9 +120,9 @@ class Report(osv.Model):
|
||||||
|
|
||||||
if digits is None:
|
if digits is None:
|
||||||
if dp:
|
if dp:
|
||||||
digits = self.get_digits(cr, uid, dp=dp)
|
digits = self._get_digits(cr, uid, dp=dp)
|
||||||
else:
|
else:
|
||||||
digits = self.get_digits(cr, uid, value)
|
digits = self._get_digits(cr, uid, value)
|
||||||
|
|
||||||
if isinstance(value, (str, unicode)) and not value:
|
if isinstance(value, (str, unicode)) and not value:
|
||||||
return ''
|
return ''
|
||||||
|
@ -192,8 +211,8 @@ class Report(osv.Model):
|
||||||
|
|
||||||
values.update({
|
values.update({
|
||||||
'time': time,
|
'time': time,
|
||||||
'formatLang': lambda *args, **kwargs: self.formatLang(*args, cr=cr, uid=uid, **kwargs),
|
'formatLang': partial(self.formatLang, cr=cr, uid=uid),
|
||||||
'get_digits': self.get_digits,
|
'get_digits': self._get_digits,
|
||||||
'render_doc': render_doc,
|
'render_doc': render_doc,
|
||||||
'editable': True, # Will active inherit_branding
|
'editable': True, # Will active inherit_branding
|
||||||
'res_company': self.pool['res.users'].browse(cr, uid, uid).company_id
|
'res_company': self.pool['res.users'].browse(cr, uid, uid).company_id
|
||||||
|
@ -208,35 +227,22 @@ class Report(osv.Model):
|
||||||
def get_html(self, cr, uid, ids, report_name, data=None, context=None):
|
def get_html(self, cr, uid, ids, report_name, data=None, context=None):
|
||||||
"""This method generates and returns html version of a report.
|
"""This method generates and returns html version of a report.
|
||||||
"""
|
"""
|
||||||
if context is None:
|
|
||||||
context = {}
|
|
||||||
|
|
||||||
if isinstance(ids, (str, unicode)):
|
|
||||||
ids = [int(i) for i in ids.split(',')]
|
|
||||||
if isinstance(ids, list):
|
|
||||||
ids = list(set(ids))
|
|
||||||
if isinstance(ids, int):
|
|
||||||
ids = [ids]
|
|
||||||
|
|
||||||
# If the report is using a custom model to render its html, we must use it.
|
# If the report is using a custom model to render its html, we must use it.
|
||||||
# Otherwise, fallback on the generic html rendering.
|
# Otherwise, fallback on the generic html rendering.
|
||||||
try:
|
try:
|
||||||
report_model_name = 'report.%s' % report_name
|
report_model_name = 'report.%s' % report_name
|
||||||
particularreport_obj = self.pool[report_model_name]
|
particularreport_obj = self.pool[report_model_name]
|
||||||
return particularreport_obj.render_html(cr, uid, ids, data=data, context=context)
|
return particularreport_obj.render_html(cr, uid, ids, data={'form': data}, context=context)
|
||||||
except:
|
except KeyError:
|
||||||
pass
|
report = self._get_report_from_name(cr, uid, report_name)
|
||||||
|
report_obj = self.pool[report.model]
|
||||||
report = self._get_report_from_name(cr, uid, report_name)
|
docs = report_obj.browse(cr, uid, ids, context=context)
|
||||||
report_obj = self.pool[report.model]
|
docargs = {
|
||||||
docs = report_obj.browse(cr, uid, ids, context=context)
|
'doc_ids': ids,
|
||||||
|
'doc_model': report.model,
|
||||||
docargs = {
|
'docs': docs,
|
||||||
'doc_ids': ids,
|
}
|
||||||
'doc_model': report.model,
|
return self.render(cr, uid, [], report.report_name, docargs, context=context)
|
||||||
'docs': docs,
|
|
||||||
}
|
|
||||||
return self.render(cr, uid, [], report.report_name, docargs, context=context)
|
|
||||||
|
|
||||||
def get_pdf(self, cr, uid, ids, report_name, html=None, data=None, context=None):
|
def get_pdf(self, cr, uid, ids, report_name, html=None, data=None, context=None):
|
||||||
"""This method generates and returns pdf version of a report.
|
"""This method generates and returns pdf version of a report.
|
||||||
|
@ -244,13 +250,6 @@ class Report(osv.Model):
|
||||||
if context is None:
|
if context is None:
|
||||||
context = {}
|
context = {}
|
||||||
|
|
||||||
if isinstance(ids, (str, unicode)):
|
|
||||||
ids = [int(i) for i in ids.split(',')]
|
|
||||||
if isinstance(ids, list):
|
|
||||||
ids = list(set(ids))
|
|
||||||
if isinstance(ids, int):
|
|
||||||
ids = [ids]
|
|
||||||
|
|
||||||
if html is None:
|
if html is None:
|
||||||
html = self.get_html(cr, uid, ids, report_name, data=data, context=context)
|
html = self.get_html(cr, uid, ids, report_name, data=data, context=context)
|
||||||
|
|
||||||
|
@ -260,7 +259,7 @@ class Report(osv.Model):
|
||||||
report = self._get_report_from_name(cr, uid, report_name)
|
report = self._get_report_from_name(cr, uid, report_name)
|
||||||
|
|
||||||
# Check attachment_use field. If set to true and an existing pdf is already saved, load
|
# Check attachment_use field. If set to true and an existing pdf is already saved, load
|
||||||
# this one now. If not, mark save it.
|
# this one now. Else, mark save it.
|
||||||
save_in_attachment = {}
|
save_in_attachment = {}
|
||||||
|
|
||||||
if report.attachment_use is True:
|
if report.attachment_use is True:
|
||||||
|
@ -307,7 +306,7 @@ class Report(osv.Model):
|
||||||
base_url = self.pool['ir.config_parameter'].get_param(cr, uid, 'web.base.url')
|
base_url = self.pool['ir.config_parameter'].get_param(cr, uid, 'web.base.url')
|
||||||
|
|
||||||
minimalhtml = """
|
minimalhtml = """
|
||||||
<base href="{3}">
|
<base href="{base_url}">
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html style="height: 0;">
|
<html style="height: 0;">
|
||||||
<head>
|
<head>
|
||||||
|
@ -315,11 +314,11 @@ class Report(osv.Model):
|
||||||
<link href="/web/static/lib/bootstrap/css/bootstrap.css" rel="stylesheet"/>
|
<link href="/web/static/lib/bootstrap/css/bootstrap.css" rel="stylesheet"/>
|
||||||
<link href="/website/static/src/css/website.css" rel="stylesheet"/>
|
<link href="/website/static/src/css/website.css" rel="stylesheet"/>
|
||||||
<link href="/web/static/lib/fontawesome/css/font-awesome.css" rel="stylesheet"/>
|
<link href="/web/static/lib/fontawesome/css/font-awesome.css" rel="stylesheet"/>
|
||||||
<style type='text/css'>{0}</style>
|
<style type='text/css'>{css}</style>
|
||||||
{1}
|
{subst}
|
||||||
</head>
|
</head>
|
||||||
<body class="container" onload='subst()'>
|
<body class="container" onload='subst()'>
|
||||||
{2}
|
{body}
|
||||||
</body>
|
</body>
|
||||||
</html>"""
|
</html>"""
|
||||||
|
|
||||||
|
@ -333,12 +332,12 @@ class Report(osv.Model):
|
||||||
|
|
||||||
for node in root.xpath("//div[@class='header']"):
|
for node in root.xpath("//div[@class='header']"):
|
||||||
body = lxml.html.tostring(node)
|
body = lxml.html.tostring(node)
|
||||||
header = minimalhtml.format(css, subst, body, base_url)
|
header = minimalhtml.format(css=css, subst=subst, body=body, base_url=base_url)
|
||||||
headerhtml.append(header)
|
headerhtml.append(header)
|
||||||
|
|
||||||
for node in root.xpath("//div[@class='footer']"):
|
for node in root.xpath("//div[@class='footer']"):
|
||||||
body = lxml.html.tostring(node)
|
body = lxml.html.tostring(node)
|
||||||
footer = minimalhtml.format(css, subst, body, base_url)
|
footer = minimalhtml.format(css=css, subst=subst, body=body, base_url=base_url)
|
||||||
footerhtml.append(footer)
|
footerhtml.append(footer)
|
||||||
|
|
||||||
for node in root.xpath("//div[@class='page']"):
|
for node in root.xpath("//div[@class='page']"):
|
||||||
|
@ -346,16 +345,16 @@ class Report(osv.Model):
|
||||||
# must set a relation between report ids and report's content. We use the QWeb
|
# must set a relation between report ids and report's content. We use the QWeb
|
||||||
# branding in order to do so: searching after a node having a data-oe-model
|
# branding in order to do so: searching after a node having a data-oe-model
|
||||||
# attribute with the value of the current report model and read its oe-id attribute
|
# attribute with the value of the current report model and read its oe-id attribute
|
||||||
oemodelnode = node.find(".//*[@data-oe-model='" + report.model + "']")
|
oemodelnode = node.find(".//*[@data-oe-model='%s']" % report.model)
|
||||||
if oemodelnode is not None:
|
if oemodelnode is not None:
|
||||||
reportid = oemodelnode.get('data-oe-id', False)
|
reportid = oemodelnode.get('data-oe-id')
|
||||||
if reportid is not False:
|
if reportid:
|
||||||
reportid = int(reportid)
|
reportid = int(reportid)
|
||||||
else:
|
else:
|
||||||
reportid = False
|
reportid = False
|
||||||
|
|
||||||
body = lxml.html.tostring(node)
|
body = lxml.html.tostring(node)
|
||||||
reportcontent = minimalhtml.format(css, '', body, base_url)
|
reportcontent = minimalhtml.format(css=css, subst='', body=body, base_url=base_url)
|
||||||
contenthtml.append(tuple([reportid, reportcontent]))
|
contenthtml.append(tuple([reportid, reportcontent]))
|
||||||
|
|
||||||
except lxml.etree.XMLSyntaxError:
|
except lxml.etree.XMLSyntaxError:
|
||||||
|
@ -414,27 +413,8 @@ class Report(osv.Model):
|
||||||
# Report generation helpers
|
# Report generation helpers
|
||||||
#--------------------------------------------------------------------------
|
#--------------------------------------------------------------------------
|
||||||
|
|
||||||
def check_wkhtmltopdf(self):
|
def _check_wkhtmltopdf(self):
|
||||||
"""Check the presence of wkhtmltopdf and return its version. If wkhtmltopdf
|
return wkhtmltopdf_state
|
||||||
cannot be found, return False.
|
|
||||||
"""
|
|
||||||
try:
|
|
||||||
process = subprocess.Popen(['wkhtmltopdf', '--version'], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
|
||||||
out, err = process.communicate()
|
|
||||||
if err:
|
|
||||||
raise
|
|
||||||
|
|
||||||
version = out.splitlines()[1].strip()
|
|
||||||
version = version.split(' ')[1]
|
|
||||||
|
|
||||||
if LooseVersion(version) < LooseVersion('0.12.0'):
|
|
||||||
_logger.warning('Upgrade WKHTMLTOPDF to (at least) 0.12.0')
|
|
||||||
return 'upgrade'
|
|
||||||
|
|
||||||
return True
|
|
||||||
except:
|
|
||||||
_logger.error('You need WKHTMLTOPDF to print a pdf version of this report.')
|
|
||||||
return False
|
|
||||||
|
|
||||||
def _generate_wkhtml_pdf(self, cr, uid, headers, footers, bodies, landscape, paperformat, spec_paperformat_args=None, save_in_attachment=None):
|
def _generate_wkhtml_pdf(self, cr, uid, headers, footers, bodies, landscape, paperformat, spec_paperformat_args=None, save_in_attachment=None):
|
||||||
"""Execute wkhtmltopdf as a subprocess in order to convert html given in input into a pdf
|
"""Execute wkhtmltopdf as a subprocess in order to convert html given in input into a pdf
|
||||||
|
@ -450,14 +430,14 @@ class Report(osv.Model):
|
||||||
:returns: Content of the pdf as a string
|
:returns: Content of the pdf as a string
|
||||||
"""
|
"""
|
||||||
command = ['wkhtmltopdf']
|
command = ['wkhtmltopdf']
|
||||||
|
command_args = []
|
||||||
tmp_dir = tempfile.gettempdir()
|
tmp_dir = tempfile.gettempdir()
|
||||||
|
|
||||||
command_args = []
|
|
||||||
# Passing the cookie to wkhtmltopdf in order to resolve URL.
|
# Passing the cookie to wkhtmltopdf in order to resolve URL.
|
||||||
try:
|
try:
|
||||||
from openerp.addons.web.http import request
|
from openerp.addons.web.http import request
|
||||||
command_args.extend(['--cookie', 'session_id', request.httprequest.cookies['session_id']])
|
command_args.extend(['--cookie', 'session_id', request.session.sid])
|
||||||
except:
|
except AttributeError:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
# Display arguments
|
# Display arguments
|
||||||
|
@ -510,8 +490,8 @@ class Report(osv.Model):
|
||||||
content_file.flush()
|
content_file.flush()
|
||||||
|
|
||||||
try:
|
try:
|
||||||
# If the server is running with only one worker, increase it to two to be able
|
# If the server is running with only one worker, ask to create a secund to be able
|
||||||
# to serve the http request from wkhtmltopdf.
|
# to serve the http request of wkhtmltopdf subprocess.
|
||||||
if config['workers'] == 1:
|
if config['workers'] == 1:
|
||||||
ppid = psutil.Process(os.getpid()).ppid
|
ppid = psutil.Process(os.getpid()).ppid
|
||||||
os.kill(ppid, signal.SIGTTIN)
|
os.kill(ppid, signal.SIGTTIN)
|
||||||
|
@ -629,26 +609,3 @@ class Report(osv.Model):
|
||||||
content = merged.read()
|
content = merged.read()
|
||||||
merged.close()
|
merged.close()
|
||||||
return content
|
return content
|
||||||
|
|
||||||
def eval_params(self, dict_param):
|
|
||||||
"""Parse a dict generated by the webclient (javascript) into a python dict.
|
|
||||||
"""
|
|
||||||
for key, value in dict_param.iteritems():
|
|
||||||
if value.lower() == 'false':
|
|
||||||
dict_param[key] = False
|
|
||||||
elif value.lower() == 'true':
|
|
||||||
dict_param[key] = True
|
|
||||||
elif ',' in value:
|
|
||||||
dict_param[key] = [int(i) for i in value.split(',')]
|
|
||||||
elif '%2C' in value:
|
|
||||||
dict_param[key] = [int(i) for i in value.split('%2C')]
|
|
||||||
else:
|
|
||||||
try:
|
|
||||||
i = int(value)
|
|
||||||
dict_param[key] = i
|
|
||||||
except (ValueError, TypeError):
|
|
||||||
pass
|
|
||||||
|
|
||||||
data = {}
|
|
||||||
data['form'] = dict_param
|
|
||||||
return data
|
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
openerp.report = function(instance) {
|
openerp.report = function(instance) {
|
||||||
|
var wkhtmltopdf_state;
|
||||||
|
|
||||||
instance.web.ActionManager = instance.web.ActionManager.extend({
|
instance.web.ActionManager = instance.web.ActionManager.extend({
|
||||||
ir_actions_report_xml: function(action, options) {
|
ir_actions_report_xml: function(action, options) {
|
||||||
|
@ -12,7 +13,7 @@ openerp.report = function(instance) {
|
||||||
// QWeb reports
|
// QWeb reports
|
||||||
if ('report_type' in action && (action.report_type == 'qweb-html' || action.report_type == 'qweb-pdf' || action.report_type == 'controller')) {
|
if ('report_type' in action && (action.report_type == 'qweb-html' || action.report_type == 'qweb-pdf' || action.report_type == 'controller')) {
|
||||||
|
|
||||||
var report_url = ''
|
var report_url = '';
|
||||||
switch (action.report_type) {
|
switch (action.report_type) {
|
||||||
case 'qweb-html':
|
case 'qweb-html':
|
||||||
report_url = '/report/' + action.report_name;
|
report_url = '/report/' + action.report_name;
|
||||||
|
@ -55,20 +56,19 @@ openerp.report = function(instance) {
|
||||||
} else {
|
} else {
|
||||||
// Trigger the download of the pdf report
|
// Trigger the download of the pdf report
|
||||||
var c = openerp.webclient.crashmanager;
|
var c = openerp.webclient.crashmanager;
|
||||||
var response = new Array()
|
var response = new Array();
|
||||||
response[0] = report_url
|
response[0] = report_url;
|
||||||
response[1] = action.report_type
|
response[1] = action.report_type;
|
||||||
|
|
||||||
openerp.session.rpc('/report/check_wkhtmltopdf').then(function (presence) {
|
(wkhtmltopdf_state = wkhtmltopdf_state || openerp.session.rpc('/report/check_wkhtmltopdf')).then(function (presence) {
|
||||||
// Fallback of qweb-pdf if wkhtmltopdf is not installed
|
// Fallback of qweb-pdf if wkhtmltopdf is not installed
|
||||||
if (!presence && action.report_type == 'qweb-pdf') {
|
if (presence == 'install' && action.report_type == 'qweb-pdf') {
|
||||||
self.do_notify(_t('Report'), _t('Unable to find Wkhtmltopdf on this \
|
self.do_notify(_t('Report'), _t('Unable to find Wkhtmltopdf on this \
|
||||||
system. The report will be shown in html.<br><br><a href="http://wkhtmltopdf.org/" target="_blank">\
|
system. The report will be shown in html.<br><br><a href="http://wkhtmltopdf.org/" target="_blank">\
|
||||||
wkhtmltopdf.org</a>'), true);
|
wkhtmltopdf.org</a>'), true);
|
||||||
window.open(report_url.substring(12), '_blank', 'height=768,width=1024');
|
window.open(report_url.substring(12), '_blank', 'height=768,width=1024');
|
||||||
instance.web.unblockUI();
|
instance.web.unblockUI();
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
if (presence == 'upgrade') {
|
if (presence == 'upgrade') {
|
||||||
self.do_notify(_t('Report'), _t('You should upgrade your version of\
|
self.do_notify(_t('Report'), _t('You should upgrade your version of\
|
||||||
Wkhtmltopdf to at least 0.12.0 in order to get a correct display of headers and footers as well as\
|
Wkhtmltopdf to at least 0.12.0 in order to get a correct display of headers and footers as well as\
|
||||||
|
|
Loading…
Reference in New Issue