parent
51ea2a3dde
commit
ec6fa5d3d9
|
@ -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:
|
||||
|
||||
|
|
|
@ -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="{"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
|
||||
|
||||
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
|
||||
|
|
Loading…
Reference in New Issue