diff --git a/addons/account/views/report_invoice.xml b/addons/account/views/report_invoice.xml index 6c4b701c6cf..a250eb9ebf7 100644 --- a/addons/account/views/report_invoice.xml +++ b/addons/account/views/report_invoice.xml @@ -5,7 +5,7 @@
-
+
diff --git a/addons/account/views/report_overdue.xml b/addons/account/views/report_overdue.xml index bc522aa8b9d..df3934ff0de 100644 --- a/addons/account/views/report_overdue.xml +++ b/addons/account/views/report_overdue.xml @@ -5,7 +5,7 @@
-
+

diff --git a/addons/account_followup/views/report_followup.xml b/addons/account_followup/views/report_followup.xml index 6c79fe4cc55..c0d98e7bb28 100644 --- a/addons/account_followup/views/report_followup.xml +++ b/addons/account_followup/views/report_followup.xml @@ -7,7 +7,7 @@
-
+
diff --git a/addons/hr_payroll/views/report_payslip.xml b/addons/hr_payroll/views/report_payslip.xml index 5ac9dfa557e..b30cb089d1a 100644 --- a/addons/hr_payroll/views/report_payslip.xml +++ b/addons/hr_payroll/views/report_payslip.xml @@ -19,7 +19,7 @@ Address -
diff --git a/addons/lunch/views/report_lunchorder.xml b/addons/lunch/views/report_lunchorder.xml index 93d43f6521d..30401bc142b 100644 --- a/addons/lunch/views/report_lunchorder.xml +++ b/addons/lunch/views/report_lunchorder.xml @@ -8,7 +8,7 @@
-
+
diff --git a/addons/mrp_repair/views/report_mrprepairorder.xml b/addons/mrp_repair/views/report_mrprepairorder.xml index 0ea3f22167c..2897fee1fd9 100644 --- a/addons/mrp_repair/views/report_mrprepairorder.xml +++ b/addons/mrp_repair/views/report_mrprepairorder.xml @@ -22,7 +22,7 @@

VAT:

-
+
diff --git a/addons/purchase/views/report_purchaseorder.xml b/addons/purchase/views/report_purchaseorder.xml index c03e535ff75..bd1f1846cd5 100644 --- a/addons/purchase/views/report_purchaseorder.xml +++ b/addons/purchase/views/report_purchaseorder.xml @@ -23,7 +23,7 @@

VAT:

-
+
diff --git a/addons/purchase/views/report_purchasequotation.xml b/addons/purchase/views/report_purchasequotation.xml index 68e8995ddd8..7f6c8f5bb78 100644 --- a/addons/purchase/views/report_purchasequotation.xml +++ b/addons/purchase/views/report_purchasequotation.xml @@ -23,7 +23,7 @@

VAT:

-
+
diff --git a/addons/report/controllers/main.py b/addons/report/controllers/main.py index d3a683cccdc..800c10140b6 100644 --- a/addons/report/controllers/main.py +++ b/addons/report/controllers/main.py @@ -64,7 +64,7 @@ class ReportController(Controller): # Misc. route utils #------------------------------------------------------ @route(['/report/barcode', '/report/barcode//'], type='http', auth="user") - def report_barcode(self, type, value, width=300, height=50): + def report_barcode(self, type, value, width=600, height=100): """Contoller able to render barcode images thanks to reportlab. Samples: diff --git a/addons/report/data/report_paperformat.xml b/addons/report/data/report_paperformat.xml index 275d65edd13..f05e0afb6f0 100644 --- a/addons/report/data/report_paperformat.xml +++ b/addons/report/data/report_paperformat.xml @@ -9,7 +9,7 @@ 0 Portrait 40 - 20 + 23 7 7 diff --git a/addons/report/models/report.py b/addons/report/models/report.py index fed6a2335ee..6d118021775 100644 --- a/addons/report/models/report.py +++ b/addons/report/models/report.py @@ -25,10 +25,8 @@ from openerp.tools.translate import _ from openerp.addons.web.http import request from openerp.tools.safe_eval import safe_eval as eval -import os +import re import time -import psutil -import signal import base64 import logging import tempfile @@ -52,15 +50,19 @@ try: ['wkhtmltopdf', '--version'], stdout=subprocess.PIPE, stderr=subprocess.PIPE ) except OSError: - _logger.error('You need wkhtmltopdf to print a pdf version of the reports.') + _logger.info('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] + version = re.search('([0-9.]+)', out).group(0) if LooseVersion(version) < LooseVersion('0.12.0'): - _logger.warning('Upgrade wkhtmltopdf to (at least) 0.12.0') + _logger.info('Upgrade wkhtmltopdf to (at least) 0.12.0') wkhtmltopdf_state = 'upgrade' - wkhtmltopdf_state = 'ok' + else: + wkhtmltopdf_state = 'ok' + + if config['workers'] == 1: + _logger.info('You need to start OpenERP with at least two workers to print a pdf version of the reports.') + wkhtmltopdf_state = 'workers' class Report(osv.Model): @@ -342,19 +344,20 @@ class Report(osv.Model): command_args = [] tmp_dir = tempfile.gettempdir() - # Passing the cookie to wkhtmltopdf in order to resolve URL. + # Passing the cookie to wkhtmltopdf in order to resolve internal links. try: if request: command_args.extend(['--cookie', 'session_id', request.session.sid]) except AttributeError: pass - # Display arguments + # Wkhtmltopdf arguments + command_args.extend(['--quiet']) # Less verbose error messages if paperformat: + # Convert the paperformat record into arguments command_args.extend(self._build_wkhtmltopdf_args(paperformat, spec_paperformat_args)) - command_args.extend(['--load-error-handling', 'ignore']) - + # Force the landscape orientation if necessary if landscape and '--orientation' in command_args: command_args_copy = list(command_args) for index, elem in enumerate(command_args_copy): @@ -365,61 +368,46 @@ class Report(osv.Model): elif landscape and not '--orientation' in command_args: command_args.extend(['--orientation', 'landscape']) + # Execute WKhtmltopdf pdfdocuments = [] - # HTML to PDF thanks to WKhtmltopdf for index, reporthtml in enumerate(bodies): - command_arg_local = [] - pdfreport = tempfile.NamedTemporaryFile(suffix='.pdf', prefix='report.tmp.', - mode='w+b') - # Directly load the document if we have it + local_command_args = [] + pdfreport = tempfile.NamedTemporaryFile(suffix='.pdf', prefix='report.tmp.', mode='w+b') + + # Directly load the document if we already have it if save_in_attachment and save_in_attachment['loaded_documents'].get(reporthtml[0]): pdfreport.write(save_in_attachment['loaded_documents'].get(reporthtml[0])) pdfreport.seek(0) pdfdocuments.append(pdfreport) continue - # Header stuff + # Wkhtmltopdf handles header/footer as separate pages. Create them if necessary. if headers: - head_file = tempfile.NamedTemporaryFile(suffix='.html', prefix='report.header.tmp.', - dir=tmp_dir, mode='w+') + head_file = tempfile.NamedTemporaryFile(suffix='.html', prefix='report.header.tmp.', dir=tmp_dir, mode='w+') head_file.write(headers[index]) head_file.seek(0) - command_arg_local.extend(['--header-html', head_file.name]) - - # Footer stuff + local_command_args.extend(['--header-html', head_file.name]) if footers: - foot_file = tempfile.NamedTemporaryFile(suffix='.html', prefix='report.footer.tmp.', - dir=tmp_dir, mode='w+') + foot_file = tempfile.NamedTemporaryFile(suffix='.html', prefix='report.footer.tmp.', dir=tmp_dir, mode='w+') foot_file.write(footers[index]) foot_file.seek(0) - command_arg_local.extend(['--footer-html', foot_file.name]) + local_command_args.extend(['--footer-html', foot_file.name]) # Body stuff - content_file = tempfile.NamedTemporaryFile(suffix='.html', prefix='report.body.tmp.', - dir=tmp_dir, mode='w+') + content_file = tempfile.NamedTemporaryFile(suffix='.html', prefix='report.body.tmp.', dir=tmp_dir, mode='w+') content_file.write(reporthtml[1]) content_file.seek(0) try: - # If the server is running with only one worker, ask to create a secund to be able - # to serve the http request of wkhtmltopdf subprocess. - if config['workers'] == 1: - ppid = psutil.Process(os.getpid()).ppid - os.kill(ppid, signal.SIGTTIN) - - wkhtmltopdf = command + command_args + command_arg_local + wkhtmltopdf = command + command_args + local_command_args wkhtmltopdf += [content_file.name] + [pdfreport.name] - process = subprocess.Popen(wkhtmltopdf, stdout=subprocess.PIPE, - stderr=subprocess.PIPE) + process = subprocess.Popen(wkhtmltopdf, stdout=subprocess.PIPE, stderr=subprocess.PIPE) out, err = process.communicate() - if config['workers'] == 1: - os.kill(ppid, signal.SIGTTOU) - - if process.returncode != 0: + if process.returncode not in [0, 1]: raise osv.except_osv(_('Report (PDF)'), - _('wkhtmltopdf failed with error code = %s. ' + _('Wkhtmltopdf failed (error code: %s). ' 'Message: %s') % (str(process.returncode), err)) # Save the pdf in attachment if marked @@ -445,7 +433,7 @@ class Report(osv.Model): except: raise - # Get and return the full pdf + # Return the entire document if len(pdfdocuments) == 1: content = pdfdocuments[0].read() pdfdocuments[0].close() diff --git a/addons/report/static/src/js/qwebactionmanager.js b/addons/report/static/src/js/qwebactionmanager.js index 7e55661be86..cb0f3921482 100644 --- a/addons/report/static/src/js/qwebactionmanager.js +++ b/addons/report/static/src/js/qwebactionmanager.js @@ -54,34 +54,35 @@ openerp.report = function(instance) { if (action.report_type == 'qweb-html') { window.open(report_url, '_blank', 'height=900,width=1280'); instance.web.unblockUI(); - } else { + } else if (action.report_type === 'qweb-pdf') { // Trigger the download of the pdf/controller report - - if (action.report_type == 'qweb-pdf') { - (wkhtmltopdf_state = wkhtmltopdf_state || openerp.session.rpc('/report/check_wkhtmltopdf')).then(function (presence) { - // Fallback of qweb-pdf if wkhtmltopdf is not installed - if (presence == 'install' && action.report_type == 'qweb-pdf') { - self.do_notify(_t('Report'), _t('Unable to find Wkhtmltopdf on this \ - system. The report will be shown in html.

\ - wkhtmltopdf.org'), true); - report_url = report_url.substring(12) - window.open('/report/html/' + report_url, '_blank', 'height=768,width=1024'); - instance.web.unblockUI(); - return; - } else { - if (presence == 'upgrade') { - 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\ - support for table-breaking between pages.

wkhtmltopdf.org'), true); - } - } - return trigger_download(self.session, response, c); - }); - } - else if (action.report_type == 'controller') { + (wkhtmltopdf_state = wkhtmltopdf_state || openerp.session.rpc('/report/check_wkhtmltopdf')).then(function (presence) { + // Fallback on html if wkhtmltopdf is not installed or if OpenERP is started with one worker + if (presence === 'install') { + self.do_notify(_t('Report'), _t('Unable to find Wkhtmltopdf on this \ +system. The report will be shown in html.

\ +wkhtmltopdf.org'), true); + report_url = report_url.substring(12) + window.open('/report/html/' + report_url, '_blank', 'height=768,width=1024'); + instance.web.unblockUI(); + return; + } else if (presence === 'workers') { + self.do_notify(_t('Report'), _t('You need to start OpenERP with at least two \ +workers to print a pdf version of the reports.'), true); + report_url = report_url.substring(12) + window.open('/report/html/' + report_url, '_blank', 'height=768,width=1024'); + instance.web.unblockUI(); + return; + } else if (presence === 'upgrade') { + 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\ + support for table-breaking between pages.

wkhtmltopdf.org'), true); + } return trigger_download(self.session, response, c); - } + }); + } else if (action.report_type === 'controller') { + return trigger_download(self.session, response, c); } } else { return self._super(action, options); diff --git a/addons/report_intrastat/views/report_intrastatinvoice.xml b/addons/report_intrastat/views/report_intrastatinvoice.xml index c534f808c95..abf4bdd56ba 100644 --- a/addons/report_intrastat/views/report_intrastatinvoice.xml +++ b/addons/report_intrastat/views/report_intrastatinvoice.xml @@ -5,7 +5,7 @@
-
+
diff --git a/addons/sale/views/report_saleorder.xml b/addons/sale/views/report_saleorder.xml index c23e680e664..5c198c635a3 100644 --- a/addons/sale/views/report_saleorder.xml +++ b/addons/sale/views/report_saleorder.xml @@ -19,7 +19,7 @@

VAT:

-
+
diff --git a/openerp/addons/base/ir/ir_actions.py b/openerp/addons/base/ir/ir_actions.py index 4e177959792..8aa968a3b3a 100644 --- a/openerp/addons/base/ir/ir_actions.py +++ b/openerp/addons/base/ir/ir_actions.py @@ -41,6 +41,7 @@ import openerp.workflow _logger = logging.getLogger(__name__) + class actions(osv.osv): _name = 'ir.actions.actions' _table = 'ir_actions' @@ -129,9 +130,15 @@ class ir_actions_report_xml(osv.osv): Look up a report definition and render the report for the provided IDs. """ new_report = self._lookup_report(cr, name) - # in order to use current yml test files with qweb reports - if isinstance(new_report, (str, unicode)): - return self.pool['report'].get_pdf(cr, uid, res_ids, new_report, data=data, context=context), 'pdf' + + if isinstance(new_report, (str, unicode)): # Qweb report + # The only case where a QWeb report is rendered with this method occurs when running + # yml tests originally written for RML reports. + if openerp.tools.config['test_enable'] and not tools.config['test_report_directory']: + # Only generate the pdf when a destination folder has been provided. + return self.pool['report'].get_html(cr, uid, res_ids, new_report, data=data, context=context), 'html' + else: + return self.pool['report'].get_pdf(cr, uid, res_ids, new_report, data=data, context=context), 'pdf' else: return new_report.create(cr, uid, res_ids, data, context) @@ -1170,7 +1177,4 @@ class ir_actions_act_client(osv.osv): } - - # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: - diff --git a/openerp/tools/test_reports.py b/openerp/tools/test_reports.py index c008c20ae29..305d2b0f115 100644 --- a/openerp/tools/test_reports.py +++ b/openerp/tools/test_reports.py @@ -87,8 +87,7 @@ def try_report(cr, uid, rname, ids, data=None, context=None, our_module=None, re if ('[[' in line) or ('[ [' in line): _logger.error("Report %s may have bad expression near: \"%s\".", rname, line[80:]) # TODO more checks, what else can be a sign of a faulty report? - elif res_format == 'foobar': - # TODO + elif res_format == 'html': pass else: _logger.warning("Report %s produced a \"%s\" chunk, cannot examine it", rname, res_format)