parent
51ea2a3dde
commit
ec6fa5d3d9
|
@ -370,10 +370,36 @@ server actions:
|
||||||
|
|
||||||
.. _reference/actions/report:
|
.. _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:
|
.. _reference/actions/client:
|
||||||
|
|
||||||
|
|
|
@ -1,37 +1,126 @@
|
||||||
.. _reference/reports:
|
.. highlight:: xml
|
||||||
|
|
||||||
============
|
============
|
||||||
QWeb Reports
|
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
|
If you want to create a report on a certain model, you will need to define
|
||||||
the PDF output. These details include margins, header line, ... Everything
|
this :ref:`reference/reports/report` and the
|
||||||
related to the printed pdf. Defining a paper format is not mandatory as there
|
:ref:`reference/reports/templates` it will use. If you wish, you can also
|
||||||
is a default one set on the company. If you want a specific report to be
|
specify a specific :ref:`reference/reports/paper_formats` for this
|
||||||
associated to a specific paper format , just link the ir.actions.report.xml to
|
report. Finally, if you need access to more than your model, you can define a
|
||||||
it.
|
: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
|
Report
|
||||||
the following:
|
======
|
||||||
|
|
||||||
|
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``
|
``docs``
|
||||||
records for the current report
|
records for the current report
|
||||||
``doc_ids``
|
``doc_ids``
|
||||||
list of ids for the ``docs`` records
|
list of ids for the ``docs`` records
|
||||||
``doc_model``
|
``doc_model``
|
||||||
model for teh ``docs`` records
|
model for the ``docs`` records
|
||||||
``time``
|
``time``
|
||||||
a reference to time_ from the Python standard library
|
a reference to :mod:`python:time` from the Python standard library
|
||||||
``translate_doc``
|
``translate_doc``
|
||||||
a function to translate a part of a report. It must be used as follow:
|
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-foreach="doc_ids" t-as="doc_id">
|
||||||
<t t-raw="translate_doc(doc_id, doc_model, 'partner_id.lang', account.report_invoice_document')"/>
|
<t t-raw="translate_doc(doc_id, doc_model, 'partner_id.lang', account.report_invoice_document')"/>
|
||||||
|
@ -39,36 +128,182 @@ the following:
|
||||||
``user``
|
``user``
|
||||||
``res.user`` record for the user printing the report
|
``res.user`` record for the user printing the report
|
||||||
``res_company``
|
``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
|
Translatable Templates
|
||||||
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".
|
|
||||||
|
|
||||||
For a particular report, you have to write an Odoo Model containing a
|
If you wish to translate reports (to the language of a partner, for example),
|
||||||
render_html method. Classically, this method returns a call to the original
|
you need to define two templates:
|
||||||
**QWeb render** with a **custom rendering context**.
|
|
||||||
|
* 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::
|
||||||
|
|
||||||
|
<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
|
.. code-block:: python
|
||||||
|
|
||||||
from openerp import api, models
|
from openerp import api, models
|
||||||
|
|
||||||
|
|
||||||
class ParticularReport(models.AbstractModel):
|
class ParticularReport(models.AbstractModel):
|
||||||
_name = 'report.<<module.reportname>>'
|
_name = 'report.module.report_name'
|
||||||
@api.multi
|
@api.multi
|
||||||
def render_html(self, data=None):
|
def render_html(self, data=None):
|
||||||
report_obj = self.env['report']
|
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 = {
|
docargs = {
|
||||||
'doc_ids': self._ids,
|
'doc_ids': self._ids,
|
||||||
'doc_model': report.model,
|
'doc_model': report.model,
|
||||||
'docs': self,
|
'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
|
||||||
|
|
Loading…
Reference in New Issue