diff options
| author | Damien Bouvy <dbo@odoo.com> | 2015-01-27 10:25:53 +0100 |
|---|---|---|
| committer | Xavier Morel <xmo@odoo.com> | 2015-01-27 11:49:02 +0100 |
| commit | ec6fa5d3d97b7110c89790adead4ad49469a3885 (patch) | |
| tree | baf47429c3debb589223138f06de305830d425cc /doc/reference/reports.rst | |
| parent | 51ea2a3dded1175643d4cd34e7ef27b5cd149610 (diff) | |
[IMP] doc: documentation for qweb reports
closes #4876
Diffstat (limited to 'doc/reference/reports.rst')
| -rw-r--r-- | doc/reference/reports.rst | 297 |
1 files changed, 266 insertions, 31 deletions
diff --git a/doc/reference/reports.rst b/doc/reference/reports.rst index 7dfbfb1c8c7..6f33100aedd 100644 --- a/doc/reference/reports.rst +++ b/doc/reference/reports.rst @@ -1,37 +1,126 @@ -.. _reference/reports: +.. highlight:: xml ============ QWeb Reports ============ -Paper Formats -------------- +Reports are written in HTML/QWeb, like all regular views in Odoo. You can use +the usual :ref:`QWeb control flow tools <reference/qweb>`. The PDF rendering +itself is performed by wkhtmltopdf_. -There is a model called Paper Format allowing to define details specific to -the PDF output. These details include margins, header line, ... Everything -related to the printed pdf. Defining a paper format is not mandatory as there -is a default one set on the company. If you want a specific report to be -associated to a specific paper format , just link the ir.actions.report.xml to -it. +If you want to create a report on a certain model, you will need to define +this :ref:`reference/reports/report` and the +:ref:`reference/reports/templates` it will use. If you wish, you can also +specify a specific :ref:`reference/reports/paper_formats` for this +report. Finally, if you need access to more than your model, you can define a +:ref:`reference/reports/custom_reports` class that gives you access to more +models and records in the template. -Expressions used in Odoo report templates ------------------------------------------ +.. _reference/reports/report: -There are some magic variables used in the report rendering. The main ones are -the following: +Report +====== + +Every report must be declared by a :ref:`report action +<reference/actions/report>`. + +For simplicity, a shortcut ``<report>`` element is available to define a +report, rather than have to set up :ref:`the action +<reference/actions/report>` and its surroundings manually. That ``<report>`` +can take the following attributes: + +``id`` + the generated record's :term:`external id` +``name`` (mandatory) + only useful as a mnemonic/description of the report when looking for one + in a list of some sort +``model`` (mandatory) + the model your report will be about +``report_type`` (mandatory) + either ``qweb-pdf`` for PDF reports or ``qweb-html`` for HTML +``report_name`` + the name of your report (which will be the name of the PDF output) +``groups`` + :class:`~openerp.fields.Many2many` field to the groups allowed to view/use + the current report +``attachment_use`` + if set to True, the report will be stored as an attachment of the record + using the name generated by the ``attachment`` expression; you can use + this if you need your report to be generated only once (for legal reasons, + for example) +``attachment`` + python expression that defines the name of the report; the record is + acessible as the variable ``object`` + +.. warning:: + + The paper format cannot currently be declared via the ``<report>`` + shortcut, it must be added afterwards using a ``<record>`` extension on the + report action itself:: + + <record id="<report_id>" model="ir.actions.report.xml"> + <field name="paperformat_id" ref="<paperformat>"/> + </record> + +Example:: + + <report + id="account_invoices" + model="account.invoice" + string="Invoices" + report_type="qweb-pdf" + name="account.report_invoice" + file="account.report_invoice" + attachment_use="True" + attachment="(object.state in ('open','paid')) and + ('INV'+(object.number or '').replace('/','')+'.pdf')" + /> + +.. _reference/reports/templates: + +Report template +=============== + + +Minimal viable template +----------------------- + +A minimal template would look like:: + + <template id="report_invoice"> + <t t-call="report.html_container"> + <t t-foreach="docs" t-as="o"> + <t t-call="report.external_layout"> + <div class="page"> + <h2>Report title</h2> + <p>This object's name is <span t-field="o.name"/></p> + </div> + </t> + </t> + </t> + </template> + +Calling ``external_layout`` will add the default header and footer on your +report. The PDF body will be the content inside the ``<div +class="page">``. The template's ``id`` must be the name specified in the +report declaration; for example ``account.report_invoice`` for the above +report. Since this is a QWeb template, you can access all the fields of the +``docs`` objects received by the template. + +There are some specific variables accessible in reports, mainly: ``docs`` records for the current report ``doc_ids`` list of ids for the ``docs`` records ``doc_model`` - model for teh ``docs`` records + model for the ``docs`` records ``time`` - a reference to time_ from the Python standard library + a reference to :mod:`python:time` from the Python standard library ``translate_doc`` a function to translate a part of a report. It must be used as follow: - .. code-block:: xml + :: <t t-foreach="doc_ids" t-as="doc_id"> <t t-raw="translate_doc(doc_id, doc_model, 'partner_id.lang', account.report_invoice_document')"/> @@ -39,36 +128,182 @@ the following: ``user`` ``res.user`` record for the user printing the report ``res_company`` - record the current ``user``'s company + record for the current ``user``'s company + +If you wish to access other records/models in the template, you will need +:ref:`a custom report <reference/reports/custom_reports>`. + +Translatable Templates +---------------------- + +If you wish to translate reports (to the language of a partner, for example), +you need to define two templates: + +* The main report template +* The translatable document + +You can then call translate_doc from your main template to obtain the +translated document. If you wish to see the details of the translation in the +backend, you can go to :menuselection:`Settings --> Reports --> Report --> +<report_name> --> Search associated QWeb views --> <translatable_document> --> +Associated translations`. + +For example, let's look at the Sale Order report from the Sale module:: + + <!-- Main template --> + <template id="sale.report_saleorder"> + <t t-call="report.html_container"> + <t t-foreach="doc_ids" t-as="doc_id"> + <t t-raw="translate_doc(doc_id, doc_model, 'partner_id.lang', 'sale.report_saleorder_document')"/> + </t> + </t> + </template> + + <!-- Translatable template --> + <template id="report_saleorder_document"> + <t t-call="report.external_layout"> + <div class="page"> + <div class="oe_structure"/> + <div class="row"> + <div class="col-xs-6"> + <strong t-if="o.partner_shipping_id == o.partner_invoice_id">Invoice and shipping address:</strong> + <strong t-if="o.partner_shipping_id != o.partner_invoice_id">Invoice address:</strong> + <div t-field="o.partner_invoice_id" t-field-options="{"no_marker": true}"/> + <...> + <div class="oe_structure"/> + </div> + </t> + </template> + + +The main template calls translate_doc with ``partner_id.lang`` as a parameter, +which means it uses :ref:`a custom report model +<reference/reports/custom_reports>` to access a ``res.partner`` record. + +Barcodes +-------- + +Barcodes are images returned by a controller and can easily be embedded in +reports thanks to the QWeb syntax: + +.. code-block:: html + + <img t-att-src="'/report/barcode/QR/%s' % 'My text in qr code'"/> + +More parameters can be passed as a query string + +.. code-block:: html + + <img t-att-src="'/report/barcode/? + type=%s&value=%s&width=%s&height=%s'%('QR', 'text', 200, 200)"/> + + +Useful Remarks +-------------- +* Twitter Bootstrap and FontAwesome classes can be used in your report + template +* Local CSS can be put directly in the template + +* Global CSS can be inserted in the main report layout by inheriting its + template and inserting your CSS:: -Custom report -------------- + <template id="report_saleorder_style" inherit_id="report.layout"> + <xpath expr="//style" position="after"> + <style type="text/css"> + .example-css-class { + background-color: red; + } + </style> + </xpath> + </template> -A generic report use the default rendering context, containing the magic -variables as explained before. If you want a new rendering context containing -anything you want to process your data Odoo AbstractModel, a custom module is -needed. These reports are called "particular report". +.. _reference/reports/paper_formats: -For a particular report, you have to write an Odoo Model containing a -render_html method. Classically, this method returns a call to the original -**QWeb render** with a **custom rendering context**. +Paper Format +============ + +Paper formats are records of ``report.paperformat`` and can contain the +following attributes: + +``name`` (mandatory) + only useful as a mnemonic/description of the report when looking for one + in a list of some sort +``description`` + a small description of your format +``format`` + either a predefined format (A0 to A9, B0 to B10, Legal, Letter, + Tabloid,...) or ``custom``; A4 by default. You cannot use a non-custom + format if you define the page dimensions. +``dpi`` + output DPI; 90 by default +``margin_top``, ``margin_bottom``, ``margin_left``, ``margin_right`` + margin sizes in mm +``page_height``, ``page_width`` + page dimensions in mm +``orientation`` + Landscape or Portrait +``header_line`` + boolean to display a header line +``header_spacing`` + header spacing in mm + +Example:: + + <record id="paperformat_frenchcheck" model="report.paperformat"> + <field name="name">French Bank Check</field> + <field name="default" eval="True"/> + <field name="format">custom</field> + <field name="page_height">80</field> + <field name="page_width">175</field> + <field name="orientation">Portrait</field> + <field name="margin_top">3</field> + <field name="margin_bottom">3</field> + <field name="margin_left">3</field> + <field name="margin_right">3</field> + <field name="header_line" eval="False"/> + <field name="header_spacing">3</field> + <field name="dpi">80</field> + </record> + +.. _reference/reports/custom_reports: + +Custom Reports +============== + +The report model has a default ``get_html`` function that looks for a model +named :samp:`report.{module.report_name}`. If it exists, it will use it to +call the QWeb engine; otherwise a generic function will be used. If you wish +to customize your reports by including more things in the template (like +records of others models, for example), you can define this model, overwrite +the function ``render_html`` and pass objects in the ``docargs`` dictionnary: .. code-block:: python from openerp import api, models - class ParticularReport(models.AbstractModel): - _name = 'report.<<module.reportname>>' + _name = 'report.module.report_name' @api.multi def render_html(self, data=None): report_obj = self.env['report'] - report = report_obj._get_report_from_name('<<module.reportname>>') + report = report_obj._get_report_from_name('module.report_name') docargs = { 'doc_ids': self._ids, 'doc_model': report.model, 'docs': self, } - return report_obj.render('<<module.reportname>>', docargs) + return report_obj.render('module.report_name', docargs) + +Reports are web pages +===================== + +Reports are dynamically generated by the report module and can be accessed +directly via URL: + +For example, you can access a Sale Order report in html mode by going to +\http://<server-address>/report/html/sale.report_saleorder/38 + +Or you can access the pdf version at +\http://<server-address>/report/pdf/sale.report_saleorder/38 -.. _time: https://docs.python.org/2/library/time.html +.. _wkhtmltopdf: http://wkhtmltopdf.org |
