[FIX] doc: remove <act_window> and <report>

* remove <report> and <act_window> form the backend tutorial
* remove documentation for <report> in the report doc

Also various fixes and improvements:

* add ACL to the wizard in the tutorial, as transients now require ACLs
* fix indentation & spacing in rST
* reword a few bits
* improve styling of footnote references (and recompile stylesheet
  with recent lessc which apparently changes its output formatting
  quite a bit)
This commit is contained in:
Xavier Morel
2020-07-28 13:03:13 +00:00
parent 48335c04bf
commit 96a3265118
7 changed files with 273 additions and 156 deletions
+113 -12
View File
@@ -1298,7 +1298,7 @@ small,
mark,
.mark {
background-color: #fcf8e3;
padding: .2em;
padding: 0.2em;
}
.text-left {
text-align: left;
@@ -1601,13 +1601,71 @@ pre code {
margin-left: -15px;
margin-right: -15px;
}
.col-xs-1, .col-sm-1, .col-md-1, .col-lg-1, .col-xs-2, .col-sm-2, .col-md-2, .col-lg-2, .col-xs-3, .col-sm-3, .col-md-3, .col-lg-3, .col-xs-4, .col-sm-4, .col-md-4, .col-lg-4, .col-xs-5, .col-sm-5, .col-md-5, .col-lg-5, .col-xs-6, .col-sm-6, .col-md-6, .col-lg-6, .col-xs-7, .col-sm-7, .col-md-7, .col-lg-7, .col-xs-8, .col-sm-8, .col-md-8, .col-lg-8, .col-xs-9, .col-sm-9, .col-md-9, .col-lg-9, .col-xs-10, .col-sm-10, .col-md-10, .col-lg-10, .col-xs-11, .col-sm-11, .col-md-11, .col-lg-11, .col-xs-12, .col-sm-12, .col-md-12, .col-lg-12 {
.col-xs-1,
.col-sm-1,
.col-md-1,
.col-lg-1,
.col-xs-2,
.col-sm-2,
.col-md-2,
.col-lg-2,
.col-xs-3,
.col-sm-3,
.col-md-3,
.col-lg-3,
.col-xs-4,
.col-sm-4,
.col-md-4,
.col-lg-4,
.col-xs-5,
.col-sm-5,
.col-md-5,
.col-lg-5,
.col-xs-6,
.col-sm-6,
.col-md-6,
.col-lg-6,
.col-xs-7,
.col-sm-7,
.col-md-7,
.col-lg-7,
.col-xs-8,
.col-sm-8,
.col-md-8,
.col-lg-8,
.col-xs-9,
.col-sm-9,
.col-md-9,
.col-lg-9,
.col-xs-10,
.col-sm-10,
.col-md-10,
.col-lg-10,
.col-xs-11,
.col-sm-11,
.col-md-11,
.col-lg-11,
.col-xs-12,
.col-sm-12,
.col-md-12,
.col-lg-12 {
position: relative;
min-height: 1px;
padding-left: 15px;
padding-right: 15px;
}
.col-xs-1, .col-xs-2, .col-xs-3, .col-xs-4, .col-xs-5, .col-xs-6, .col-xs-7, .col-xs-8, .col-xs-9, .col-xs-10, .col-xs-11, .col-xs-12 {
.col-xs-1,
.col-xs-2,
.col-xs-3,
.col-xs-4,
.col-xs-5,
.col-xs-6,
.col-xs-7,
.col-xs-8,
.col-xs-9,
.col-xs-10,
.col-xs-11,
.col-xs-12 {
float: left;
}
.col-xs-12 {
@@ -1764,7 +1822,18 @@ pre code {
margin-left: 0%;
}
@media (min-width: 768px) {
.col-sm-1, .col-sm-2, .col-sm-3, .col-sm-4, .col-sm-5, .col-sm-6, .col-sm-7, .col-sm-8, .col-sm-9, .col-sm-10, .col-sm-11, .col-sm-12 {
.col-sm-1,
.col-sm-2,
.col-sm-3,
.col-sm-4,
.col-sm-5,
.col-sm-6,
.col-sm-7,
.col-sm-8,
.col-sm-9,
.col-sm-10,
.col-sm-11,
.col-sm-12 {
float: left;
}
.col-sm-12 {
@@ -1922,7 +1991,18 @@ pre code {
}
}
@media (min-width: 992px) {
.col-md-1, .col-md-2, .col-md-3, .col-md-4, .col-md-5, .col-md-6, .col-md-7, .col-md-8, .col-md-9, .col-md-10, .col-md-11, .col-md-12 {
.col-md-1,
.col-md-2,
.col-md-3,
.col-md-4,
.col-md-5,
.col-md-6,
.col-md-7,
.col-md-8,
.col-md-9,
.col-md-10,
.col-md-11,
.col-md-12 {
float: left;
}
.col-md-12 {
@@ -2080,7 +2160,18 @@ pre code {
}
}
@media (min-width: 1200px) {
.col-lg-1, .col-lg-2, .col-lg-3, .col-lg-4, .col-lg-5, .col-lg-6, .col-lg-7, .col-lg-8, .col-lg-9, .col-lg-10, .col-lg-11, .col-lg-12 {
.col-lg-1,
.col-lg-2,
.col-lg-3,
.col-lg-4,
.col-lg-5,
.col-lg-6,
.col-lg-7,
.col-lg-8,
.col-lg-9,
.col-lg-10,
.col-lg-11,
.col-lg-12 {
float: left;
}
.col-lg-12 {
@@ -4827,7 +4918,7 @@ fieldset[disabled] .navbar-inverse .btn-link:focus {
}
.label {
display: inline;
padding: .2em .6em .3em;
padding: 0.2em 0.6em 0.3em;
font-size: 75%;
font-weight: bold;
line-height: 1;
@@ -4835,7 +4926,7 @@ fieldset[disabled] .navbar-inverse .btn-link:focus {
text-align: center;
white-space: nowrap;
vertical-align: baseline;
border-radius: .25em;
border-radius: 0.25em;
}
a.label:hover,
a.label:focus {
@@ -6756,11 +6847,11 @@ button.close {
}
[class^="mdi-"].pull-left,
[class*="mdi-"].pull-left {
margin-right: .3em;
margin-right: 0.3em;
}
[class^="mdi-"].pull-right,
[class*="mdi-"].pull-right {
margin-left: .3em;
margin-left: 0.3em;
}
[class^="mdi-"].mdi-lg:before,
[class*="mdi-"].mdi-lg:before,
@@ -9293,6 +9384,16 @@ h6 {
color: white;
}
}
.footnote-ref {
vertical-align: super;
font-size: 1ex;
}
.footnote-ref:before {
content: '[';
}
.footnote-ref:after {
content: ']';
}
article.doc-body > section {
padding-bottom: 10px;
}
@@ -10585,7 +10686,7 @@ main.index .card figcaption {
background-repeat: no-repeat;
display: none;
}
@media only screen and (-webkit-min-device-pixel-ratio: 2), only screen and (min--moz-device-pixel-ratio: 2), only screen and (-o-min-device-pixel-ratio: 2/1), only screen and (min-device-pixel-ratio: 2), only screen and (min-resolution: 192dpi), only screen and (min-resolution: 2dppx) {
@media only screen and (-webkit-min-device-pixel-ratio: 2), only screen and (min--moz-device-pixel-ratio: 2), only screen and (-o-min-device-pixel-ratio: 2), only screen and (min-device-pixel-ratio: 2), only screen and (min-resolution: 192dpi), only screen and (min-resolution: 2dppx) {
.o_main_header > .o_main_header_main > .o_primary_nav .o_secondary_nav > .container > .row > div .o_nav_app_family > span {
background-image: url("img/2x_apps_families_s.png");
}
@@ -11645,7 +11746,7 @@ aside {
}
body main article h2,
body main article .h2 {
font-size: 1.642857143em;
font-size: 1.64285714em;
}
body main article h3,
body main article .h3 {
@@ -33,6 +33,13 @@ h1, h2, h3, h4, h5, h6 {
border-bottom: 2px solid #f4f6f7;
}
.footnote-ref {
&:before {content: '[';}
&:after {content: ']';}
vertical-align: super;
font-size: 1ex;
}
article.doc-body {
// Vertical rhythm
@@ -171,4 +178,4 @@ article.doc-body {
background-color: #fff7d1;
}
}
}
}
+60 -37
View File
@@ -275,6 +275,8 @@ be declared in the ``'data'`` list (always loaded) or in the ``'demo'`` list
:ref:`odoo-bin -u openacademy <reference/cmdline>` to save the changes
to your database.
.. _howtos/module/actions:
Actions and Menus
-----------------
@@ -375,6 +377,8 @@ lists all the fields to display in the table (each field as a column):
<field name="inventor_id"/>
</tree>
.. _howtos/module/views/form:
Form views
----------
@@ -1353,6 +1357,8 @@ the same convention as the method :meth:`~odoo.models.Model.write` of the ORM.
.. patch::
.. _howto/module/wizard:
Wizards
=======
@@ -1389,27 +1395,33 @@ session, or for a list of sessions at once.
Launching wizards
-----------------
Wizards are launched by ``ir.actions.act_window`` records, with the field
``target`` set to the value ``new``. The latter opens the wizard view into a
popup window. The action may be triggered by a menu item.
Wizards are simply :ref:`window actions <howtos/module/actions>` with a ``target``
field set to the value ``new``, which opens the view
(usually :ref:`a form <howtos/module/views/form>`) in a separate dialog. The
action may be triggered via a menu item, but is more generally triggered by a
button.
There is another way to launch the wizard: using an ``ir.actions.act_window``
record like above, but with an extra field ``binding_model_id`` that specifies in the
context of which model the action is available. The wizard will appear in the
contextual actions of the model, above the main view. Because of some internal
hooks in the ORM, such an action is declared in XML with the tag ``act_window``.
An other way to launch wizards is through the :menuselection:`Action` menu of
a tree or form view. This is done through the ``binding_model_id`` field of the
action. Setting this field will make the action appear on the views of the model
the action is "bound" to.
.. code:: xml
<act_window id="launch_the_wizard"
name="Launch the Wizard"
binding_model="context.model.name"
res_model="wizard.model.name"
view_mode="form"
target="new"/>
<record id="launch_the_wizard" model="ir.actions.act_window">
<field name="name">Launch the Wizard</field>
<field name="model">wizard.model.name</field>
<field name="view_mode">form</field>
<field name="target">new<field>
<field name="binding_model_id" ref="model_context_model_ref"/>
</record>
Wizards use regular views and their buttons may use the attribute
``special="cancel"`` to close the wizard window without saving.
.. tip::
While wizards use regular views and buttons, normally clicking any button in
a form would first save the form then close the dialog. Because this is
often undesirable in wizards, a special attribute ``special="cancel"`` is
available which immediately closes the wizard without saving the form.
.. exercise:: Launch the wizard
@@ -1523,24 +1535,35 @@ Odoo uses a report engine based on :ref:`reference/qweb`,
A report is a combination two elements:
* an ``ir.actions.report``, for which a ``<report>`` shortcut element is
provided, it sets up various basic parameters for the report (default
type, whether the report should be saved to the database after generation,…)
* an ``ir.actions.report`` which configures various basic parameters for the
report (default type, whether the report should be saved to the database
after generation,…)
.. code-block:: xml
<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')"
/>
<record id="account_invoices" model="ir.actions.report">
<field name="name">Invoices</field>
<field name="model">account.invoice</field>
<field name="report_type">qweb-pdf</field>
<field name="report_name">account.report_invoice</field>
<field name="report_file">account.report_invoice</field>
<field name="attachment_use" eval="True"/>
<field name="attachment">(object.state in ('open','paid')) and
('INV'+(object.number or '').replace('/','')+'.pdf')</field>
<field name="binding_model_id" ref="model_account_invoice"/>
<field name="binding_type">report</field>
</record>
.. tip::
Because it largerly a standard action, as with :ref:`howto/module/wizard`
it is generally useful to add the report as a *contextual item* on the
tree and / or form views of the model being reported on via the
``binding_model_id`` field.
Here we are also using ``binding_type`` in order for the report to be in
the *report* contextual menu rather than the *action* one. There is no
technical difference but putting elements in the right place helps users.
* A standard :ref:`QWeb view <reference/views/qweb>` for the actual report:
@@ -1556,13 +1579,13 @@ A report is a combination two elements:
</t>
</t>
the standard rendering context provides a number of elements, the most
important being:
the standard rendering context provides a number of elements, the most
important being:
``docs``
the records for which the report is printed
``user``
the user printing the report
``docs``
the records for which the report is printed
``user``
the user printing the report
Because reports are standard web pages, they are available through a URL and
output parameters can be manipulated through this URL, for instance the HTML
+13 -11
View File
@@ -13,20 +13,22 @@ Index: addons/openacademy/__manifest__.py
],
# only loaded in demonstration mode
'demo': [
Index: addons/openacademy/reports.xml
Index: foo/openacademy/reports.xml
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ addons/openacademy/reports.xml 2014-08-29 08:41:12.663540061 +0200
@@ -0,0 +1,30 @@
--- /dev/null
+++ foo/openacademy/reports.xml
@@ -0,0 +1,32 @@
+<odoo>
+
+ <report
+ id="report_session"
+ model="openacademy.session"
+ string="Session Report"
+ name="openacademy.report_session_view"
+ file="openacademy.report_session"
+ report_type="qweb-pdf" />
+ <record id="report_session" model="ir.actions.report">
+ <field name="name">Session Report</field>
+ <field name="model">openacademy.session</field>
+ <field name="report_type">qweb-pdf</field>
+ <field name="report_name">openacademy.report_session_view</field>
+ <field name="report_file">openacademy.report_session</field>
+ <field name="binding_model_id" ref="model_openacademy_session"/>
+ <field name="binding_type">report</field>
+ </record>
+
+ <template id="report_session_view">
+ <t t-call="web.html_container">
+11
View File
@@ -23,3 +23,14 @@ Index: addons/openacademy/wizard.py
+ session_id = fields.Many2one('openacademy.session',
+ string="Session", required=True)
+ attendee_ids = fields.Many2many('res.partner', string="Attendees")
Index: foo/openacademy/security/ir.model.access.csv
===================================================================
--- foo.orig/openacademy/security/ir.model.access.csv
+++ foo/openacademy/security/ir.model.access.csv
@@ -1,5 +1,6 @@
id,name,model_id/id,group_id/id,perm_read,perm_write,perm_create,perm_unlink
course_manager,course manager,model_openacademy_course,group_manager,1,1,1,1
session_manager,session manager,model_openacademy_session,group_manager,1,1,1,1
+wizard_manager,wizard session manager,model_openacademy_wizard,group_manager,1,1,1,1
course_read_all,course all,model_openacademy_course,,1,0,0,0
session_read_all,session all,model_openacademy_session,,1,0,0,0
+11 -10
View File
@@ -13,11 +13,11 @@ Index: addons/openacademy/wizard.py
- string="Session", required=True)
+ string="Session", required=True, default=_default_session)
attendee_ids = fields.Many2many('res.partner', string="Attendees")
Index: addons/openacademy/views/openacademy.xml
Index: foo/openacademy/views/openacademy.xml
===================================================================
--- addons.orig/openacademy/views/openacademy.xml
+++ addons/openacademy/views/openacademy.xml
@@ -223,4 +223,24 @@
--- foo.orig/openacademy/views/openacademy.xml
+++ foo/openacademy/views/openacademy.xml
@@ -220,4 +220,25 @@
parent="openacademy_menu"
action="session_list_action"/>
@@ -34,11 +34,12 @@ Index: addons/openacademy/views/openacademy.xml
+ </field>
+ </record>
+
+ <act_window id="launch_session_wizard"
+ name="Add Attendees"
+ binding_model="openacademy.session"
+ res_model="openacademy.wizard"
+ view_mode="form"
+ target="new"/>
+ <record id="launch_session_wizard" model="ir.actions.act_window">
+ <field name="name">Add Attendees</field>
+ <field name="res_model">openacademy.wizard</field>
+ <field name="view_mode">form</field>
+ <field name="target">new</field>
+ <field name="binding_model_id" ref="model_openacademy_session"/>
+ </record>
+
</odoo>
+57 -85
View File
@@ -4,83 +4,42 @@
.. _reference/reports:
.. _reference/reports/report:
============
QWeb Reports
============
Reports are written in HTML/QWeb, like all regular views in Odoo. You can use
Reports are written in HTML/QWeb, like website views in Odoo. You can use
the usual :ref:`QWeb control flow tools <reference/qweb>`. The PDF rendering
itself is performed by wkhtmltopdf_.
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.
Reports are declared using a :ref:`report action <reference/actions/report>`,
and a :ref:`reference/reports/templates` for the action to use.
.. _reference/reports/report:
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
``file``
The path to the main report file (depending on Report Type)
or empty if the content is in another field
``print_report_name``
the name of your report (which will be the name of the PDF output)
``groups``
:class:`~odoo.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``
``paperformat``
external id of the paperformat you wish to use (defaults to the company's
paperformat if not specified)
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')"
/>
It useful or necessary, it is possible to specify a
:ref:`reference/reports/paper_formats` for the report report.
.. _reference/reports/templates:
Report template
===============
Report templates will always provide the following variables:
``time``
a reference to :mod:`python:time` from the Python standard library
``user``
``res.user`` record for the user printing the report
``res_company``
record for the current ``user``'s company
``website``
the current website object, if any (this item can be present but ``None``)
``wen_base_url``
the base url for the webserver
``context_timestamp``
a function taking :class:`python:datetime.datetime` in UTC\ [#unzoned]_ and
converting it to the timezone of the user printing the report
Minimal viable template
-----------------------
@@ -107,7 +66,7 @@ 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:
By default, the rendering context will also expose the following items:
``docs``
records for the current report
@@ -115,15 +74,10 @@ There are some specific variables accessible in reports, mainly:
list of ids for the ``docs`` records
``doc_model``
model for the ``docs`` records
``time``
a reference to :mod:`python:time` from the Python standard library
``user``
``res.user`` record for the user printing the report
``res_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>`.
:ref:`a custom report <reference/reports/custom_reports>`, however in that case
you will have to provide the items above if you need them.
Translatable Templates
----------------------
@@ -226,6 +180,7 @@ Useful Remarks
</t>
</xpath>
</template>
* If it appears that your PDF report is missing the styles, please check
:ref:`these instructions <reference/backend/reporting/printed-reports/pdf-without-styles>`.
@@ -282,12 +237,16 @@ Example::
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 ``_get_report_values`` and pass objects in the ``docargs`` dictionary:
By default, the reporting system builds rendering values based on the target
model specified through the ``model`` field.
However, it will first look for a model named
:samp:`report.{module.report_name}` and call that model's
``_get_report_values(doc_ids, data)`` in order to prepare the rendering data for
the template.
This can be used to include arbitrary items to use or display while rendering
the template, such as data from additional models:
.. code-block:: python
@@ -296,16 +255,24 @@ the function ``_get_report_values`` and pass objects in the ``docargs`` dictiona
class ParticularReport(models.AbstractModel):
_name = 'report.module.report_name'
@api.model
def _get_report_values(self, docids, data=None):
report_obj = self.env['ir.actions.report']
report = report_obj._get_report_from_name('module.report_name')
docargs = {
'doc_ids': docids,
'doc_model': report.model,
'docs': self,
# get the report action back as we will need its data
report = self.env['ir.actions.report']._get_report_from_name('module.report_name')
# get the records selected for this rendering of the report
obj = self.env[report.model].browse(docids)
# return a custom rendering context
return {
'lines': docids.get_lines()
}
return docargs
.. warning::
When using a custom report, the "default" document-related items
(``doc_ids``, ``doc_model`` and ``docs``) will *not* be included. If you
want them, you will need to include them yourself.
In the example above, the rendering context will contain the "global" values
as well as the ``lines`` we put in there but nothing else.
.. _reference/reports/custom_fonts:
@@ -351,4 +318,9 @@ For example, you can access a Sale Order report in html mode by going to
Or you can access the pdf version at
\http://<server-address>/report/pdf/sale.report_saleorder/38
.. [#unzoned] it does not matter what timezone the :class:`python:datetime`
object is actually in (including no timezone), its timezone will
unconditionally be *set* to UTC before being adjusted to the
user's
.. _wkhtmltopdf: https://wkhtmltopdf.org