Reporting
Printed reports
Odoo 8.0 comes with a new report engine based onQWeb,Twitter BootstrapandWkhtmltopdf.
A report is a combination two elements:
- an
ir.actions.report.xml
, 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,…)
<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')"
/>
A standard QWeb view for the actual report:
<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> </div> </t> </t> </t> 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
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 version of the_Invoice_report is available throughhttp://localhost:8069/report/html/account.report_invoice/1(ifaccount
is installed) and the PDF version throughhttp://localhost:8069/report/pdf/account.report_invoice/1.
Danger
If it appears that your PDF report is missing the styles (i.e. the text appears but the style/layout is different from the html version), probably yourwkhtmltopdfprocess cannot reach your web server to download them.
If you check your server logs and see that the CSS styles are not being downloaded when generating a PDF report, most surely this is the problem.
Thewkhtmltopdfprocess will use theweb.base.url
system parameter as the_root path_to all linked files, but this parameter is automatically updated each time the Administrator is logged in. If your server resides behind some kind of proxy, that could not be reachable. You can fix this by adding one of these system parameters:
report.url
, pointing to an URL reachable from your server (probablyhttp://localhost:8069
or something similar). It will be used for this particular purpose only.web.base.url.freeze
, when set toTrue
, will stop the automatic updates toweb.base.url
.
Exercise
Create a report for the Session model
For each session, it should display session's name, its start and end, and list the session's attendees.
openacademy/\_manifest__.py_
'views/openacademy.xml',
'views/partner.xml',
'views/session_workflow.xml',
'reports.xml',
],
# only loaded in demonstration mode
'demo': [
openacademy/reports.xml
<odoo>
<data>
<report
id="report_session"
model="openacademy.session"
string="Session Report"
name="openacademy.report_session_view"
file="openacademy.report_session"
report_type="qweb-pdf" />
<template id="report_session_view">
<t t-call="report.html_container">
<t t-foreach="docs" t-as="doc">
<t t-call="report.external_layout">
<div class="page">
<h2 t-field="doc.name"/>
<p>From <span t-field="doc.start_date"/> to <span t-field="doc.end_date"/></p>
<h3>Attendees:</h3>
<ul>
<t t-foreach="doc.attendee_ids" t-as="attendee">
<li><span t-field="attendee.name"/></li>
</t>
</ul>
</div>
</t>
</t>
</t>
</template>
</data>
</odoo>
Dashboards
Exercise
Define a Dashboard
Define a dashboard containing the graph view you created, the sessions calendar view and a list view of the courses (switchable to a form view). This dashboard should be available through a menuitem in the menu, and automatically displayed in the web client when the OpenAcademy main menu is selected.
Create a file
openacademy/views/session_board.xml
. It should contain the board view, the actions referenced in that view, an action to open the dashboard and a re-definition of the main menu item to add the dashboard actionNote
Available dashboard styles are
1
,1-1
,1-2
,2-1
and1-1-1
Update
openacademy/__manifest__.py
to reference the new data file
openacademy/\_manifest__.py_
'version': '0.1',
# any module necessary for this one to work correctly
'depends': ['base', 'board'],
# always loaded
'data': [
openacademy/views/session_board.xml
<?xml version="1.0"?>
<odoo>
<data>
<record model="ir.actions.act_window" id="act_session_graph">
<field name="name">Attendees by course</field>
<field name="res_model">openacademy.session</field>
<field name="view_type">form</field>
<field name="view_mode">graph</field>
<field name="view_id"
ref="openacademy.openacademy_session_graph_view"/>
</record>
<record model="ir.actions.act_window" id="act_session_calendar">
<field name="name">Sessions</field>
<field name="res_model">openacademy.session</field>
<field name="view_type">form</field>
<field name="view_mode">calendar</field>
<field name="view_id" ref="openacademy.session_calendar_view"/>
</record>
<record model="ir.actions.act_window" id="act_course_list">
<field name="name">Courses</field>
<field name="res_model">openacademy.course</field>
<field name="view_type">form</field>
<field name="view_mode">tree,form</field>
</record>
<record model="ir.ui.view" id="board_session_form">
<field name="name">Session Dashboard Form</field>
<field name="model">board.board</field>
<field name="type">form</field>
<field name="arch" type="xml">
<form string="Session Dashboard">
<board style="2-1">
<column>
<action
string="Attendees by course"
name="%(act_session_graph)d"
height="150"
width="510"/>
<action
string="Sessions"
name="%(act_session_calendar)d"/>
</column>
<column>
<action
string="Courses"
name="%(act_course_list)d"/>
</column>
</board>
</form>
</field>
</record>
<record model="ir.actions.act_window" id="open_board_session">
<field name="name">Session Dashboard</field>
<field name="res_model">board.board</field>
<field name="view_type">form</field>
<field name="view_mode">form</field>
<field name="usage">menu</field>
<field name="view_id" ref="board_session_form"/>
</record>
<menuitem
name="Session Dashboard" parent="base.menu_reporting_dashboard"
action="open_board_session"
sequence="1"
id="menu_board_session" icon="terp-graph"/>
</data>
</odoo>