[IMP] doc: documentation for qweb reports

closes #4876
This commit is contained in:
Damien Bouvy 2015-01-27 10:25:53 +01:00 committed by Xavier Morel
parent 51ea2a3dde
commit ec6fa5d3d9
2 changed files with 295 additions and 34 deletions

View File

@ -370,10 +370,36 @@ server actions:
.. _reference/actions/report:
Report Actions
==============
Report Actions (``ir.actions.report.xml``)
==========================================
.. todo:: sle-odoo
Triggers the printing of a report
``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_id``
:class:`~openerp.fields.Many2many` field to the groups allowed to view/use
the current report
``paperformat_id``
:class:`~openerp.fields.Many2one` field to the paper format you wish to
use for this report (if not specified, the company format will be used)
``attachment_use``
if set to ``True``, the report is only generated once the first time it is
requested, and re-printed from the stored report afterwards instead of
being re-generated every time.
Can be used for reports which must only be generated once (e.g. for legal
reasons)
``attachment``
python expression that defines the name of the report; the record is
accessible as the variable ``object``
.. _reference/actions/client:

View File

@ -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
Custom report
-------------
If you wish to access other records/models in the template, you will need
:ref:`a custom report <reference/reports/custom_reports>`.
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".
Translatable Templates
----------------------
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**.
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="{&quot;no_marker&quot;: 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::
<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>
.. _reference/reports/paper_formats:
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)
.. _time: https://docs.python.org/2/library/time.html
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
.. _wkhtmltopdf: http://wkhtmltopdf.org