Merge remote-tracking branch 'odoo/saas-4' into saas-4-report-fixes-sle
authorSimon Lejeune <sle@openerp.com>
Fri, 23 May 2014 13:38:56 +0000 (15:38 +0200)
committerSimon Lejeune <sle@openerp.com>
Fri, 23 May 2014 13:38:56 +0000 (15:38 +0200)
16 files changed:
addons/account/views/report_invoice.xml
addons/account/views/report_overdue.xml
addons/account_followup/views/report_followup.xml
addons/hr_payroll/views/report_payslip.xml
addons/lunch/views/report_lunchorder.xml
addons/mrp_repair/views/report_mrprepairorder.xml
addons/purchase/views/report_purchaseorder.xml
addons/purchase/views/report_purchasequotation.xml
addons/report/controllers/main.py
addons/report/data/report_paperformat.xml
addons/report/models/report.py
addons/report/static/src/js/qwebactionmanager.js
addons/report_intrastat/views/report_intrastatinvoice.xml
addons/sale/views/report_saleorder.xml
openerp/addons/base/ir/ir_actions.py
openerp/tools/test_reports.py

index 6c4b701..a250eb9 100644 (file)
@@ -5,7 +5,7 @@
     <t t-call="report.external_layout">
         <div class="page">
             <div class="row">
-                <div class="col-xs-4 col-xs-offset-8">
+                <div class="col-xs-5 col-xs-offset-7">
                     <address t-field="o.partner_id"
                         t-field-options='{"widget": "contact", "fields": ["address", "name"], "no_marker": true}' />
                     <span t-field="o.partner_id.vat"/>
index bc522aa..df3934f 100644 (file)
@@ -5,7 +5,7 @@
     <t t-call="report.external_layout">
         <div class="page">
             <div class="row">
-                <div class="col-xs-4 col-xs-offset-6">
+                <div class="col-xs-5 col-xs-offset-7">
                     <span t-field="o.name"/><br/>
                     <span t-raw="addresses[o.id].replace('\n\n', '\n').replace('\n', '&lt;br&gt;')"/>
                      <span t-field="o.vat"/>
index 6c79fe4..c0d98e7 100644 (file)
@@ -7,7 +7,7 @@
             <t t-call="report.external_layout">
                 <div class="page">
                     <div class="row">
-                        <div class="col-xs-4 col-xs-offset-6">
+                        <div class="col-xs-5 col-xs-offset-7">
                             <div t-field="o.partner_id" 
                                 t-field-options='{"widget": "contact", "fields": ["address", "name", "phone", "fax"], "no_marker": true}'/>
                              <span t-field="o.partner_id.vat"/>
index 5ac9dfa..b30cb08 100644 (file)
@@ -19,7 +19,7 @@
                         <tr>
                             <td><strong>Address</strong></td>
                             <td colspan="3">
-                                <div t-filed="o.employee_id.address_home_id"
+                                <div t-field="o.employee_id.address_home_id"
                                     t-field-options='{"widget": "contact", "fields": ["address", "name", "phone", "fax"], "no_marker": true}'/>
                             </td>
                         </tr>
index 93d43f6..30401bc 100644 (file)
@@ -8,7 +8,7 @@
                     <div class="oe_structure"/>
 
                     <div class="row">
-                        <div class="col-xs-4 col-xs-offset-7">
+                        <div class="col-xs-5 col-xs-offset-7">
                             <div t-field="user.partner_id"
                                 t-field-options='{"widget": "contact", "fields": ["address", "name"], "no_marker": true}' />
                         </div>
index 0ea3f22..2897fee 100644 (file)
@@ -22,7 +22,7 @@
                                 <p t-if="o.partner_id.vat">VAT: <span t-field="o.partner_id.vat"/></p>
                             </div>                        
                         </div>
-                        <div class="col-xs-4 col-xs-offset-2">
+                        <div class="col-xs-5 col-xs-offset-1">
                             <div t-field="o.partner_id"
                                 t-field-options='{"widget": "contact", "fields": ["address", "name"], "no_marker": true}' />
                         </div>
index c03e535..bd1f184 100644 (file)
@@ -23,7 +23,7 @@
                                 <p t-if="o.partner_id.vat">VAT: <span t-field="o.partner_id.vat"/></p>
                             </div>
                         </div>
-                        <div class="col-xs-4 col-xs-offset-2">
+                        <div class="col-xs-5 col-xs-offset-1">
                             <div t-field="o.partner_id" 
                                 t-field-options='{"widget": "contact", "fields": ["address", "name", "phone", "fax"], "no_marker": true}'/>
                         </div>
index 68e8995..7f6c8f5 100644 (file)
@@ -23,7 +23,7 @@
                                 <p t-if="o.partner_id.vat">VAT: <span t-field="o.partner_id.vat"/></p>
                             </div>
                         </div>
-                        <div class="col-xs-4 col-xs-offset-2">
+                        <div class="col-xs-5 col-xs-offset-1">
                             <div t-field="o.partner_id" 
                                 t-field-options='{"widget": "contact", "fields": ["address", "name", "phone", "fax"], "no_marker": true}'/>
                         </div>
index d3a683c..800c101 100644 (file)
@@ -64,7 +64,7 @@ class ReportController(Controller):
     # Misc. route utils
     #------------------------------------------------------
     @route(['/report/barcode', '/report/barcode/<type>/<path:value>'], 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: 
             <img t-att-src="'/report/barcode/QR/%s' % o.name"/>
index 275d65e..f05e0af 100644 (file)
@@ -9,7 +9,7 @@
             <field name="page_width">0</field>
             <field name="orientation">Portrait</field>
             <field name="margin_top">40</field>
-            <field name="margin_bottom">20</field>
+            <field name="margin_bottom">23</field>
             <field name="margin_left">7</field>
             <field name="margin_right">7</field>
             <field name="header_line" eval="False" />
index fed6a23..6d11802 100644 (file)
@@ -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()
index 7e55661..cb0f392 100644 (file)
@@ -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.<br><br><a href="http://wkhtmltopdf.org/" target="_blank">\
-    wkhtmltopdf.org</a>'), 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.<br><br><a href="http://wkhtmltopdf.org/" \
-     target="_blank">wkhtmltopdf.org</a>'), 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.<br><br><a href="http://wkhtmltopdf.org/" target="_blank">\
+wkhtmltopdf.org</a>'), 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.<br><br><a href="http://wkhtmltopdf.org/" \
+ target="_blank">wkhtmltopdf.org</a>'), 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);
index c534f80..abf4bdd 100644 (file)
@@ -5,7 +5,7 @@
     <t t-call="report.external_layout">
         <div class="page">
             <div class="row">
-                <div class="col-xs-4 col-xs-offset-8">
+                <div class="col-xs-5 col-xs-offset-7">
                     <address t-field="o.partner_id"
                         t-field-options='{"widget": "contact", "fields": ["address", "name"], "no_marker": true}' />
                     <span t-field="o.partner_id.vat"/>
index c23e680..5c198c6 100644 (file)
@@ -19,7 +19,7 @@
                         <p t-if="o.partner_id.vat">VAT: <span t-field="o.partner_id.vat"/></p>
                     </div>                        
                 </div>
-                <div class="col-xs-4 col-xs-offset-2">
+                <div class="col-xs-5 col-xs-offset-1">
                     <div t-field="o.partner_id"
                         t-field-options='{"widget": "contact", "fields": ["address", "name"], "no_marker": true}' />
                 </div>
index 4e17795..8aa968a 100644 (file)
@@ -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:
-
index c008c20..305d2b0 100644 (file)
@@ -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)