[REM] developer: remove references to web_dashboard view
Since odoo/enterprise#31641 the dashboard view no longer exists since it
is now replaced with spreadsheet_dashboard, therefore we remove it from
the backend Views documentation.
Task: 3226581
X-original-commit: e2c880aafe
Part-of: odoo/documentation#4034
This commit is contained in:
parent
0440f5c5cd
commit
b742c44f09
@ -124,7 +124,7 @@ an impact on all view types.
|
||||
``info``, ``warning``, ``danger`` and ``secondary`` displays. The list view supports ``bf``,
|
||||
``it``, ``success``, ``info``, ``warning``, ``danger``, ``muted`` and ``primary`` displays.
|
||||
|
||||
* ``sample`` (``kanban`` & ``list`` & ``gantt`` & ``graph`` & ``pivot`` & ``cohort`` & ``dashboard``)
|
||||
* ``sample`` (``kanban`` & ``list`` & ``gantt`` & ``graph`` & ``pivot`` & ``cohort``)
|
||||
|
||||
Populate the view with a set of sample records if none are found for the current model.
|
||||
This attribute is false by default.
|
||||
@ -577,213 +577,6 @@ attributes:
|
||||
measures (useful for fields that do not make sense aggregated, such as fields in different
|
||||
units, e.g. € and $).
|
||||
|
||||
.. _reference/views/dashboard:
|
||||
|
||||
Dashboard
|
||||
---------
|
||||
|
||||
.. raw:: html
|
||||
|
||||
<span class="badge" style="background-color:#AD5E99">Enterprise feature</span>
|
||||
|
||||
Like pivot and graph view, The dashboard view is used to display aggregate data.
|
||||
However, the dashboard can embed sub views, which makes it possible to have a
|
||||
more complete and interesting look on a given dataset.
|
||||
|
||||
The dashboard view can display sub views, aggregates for some fields (over a
|
||||
domain), or even *formulas* (expressions which involves one or more aggregates).
|
||||
For example, here is a very simple dashboard:
|
||||
|
||||
.. code-block:: xml
|
||||
|
||||
<dashboard>
|
||||
<view type="graph" ref="sale_report.view_order_product_graph"/>
|
||||
<group string="Sale">
|
||||
<aggregate name="price_total" field="price_total" widget="monetary"/>
|
||||
<aggregate name="order_id" field="order_id" string="Orders"/>
|
||||
<formula name="price_average" string="Price Average"
|
||||
value="record.price_total / record.order_id" widget="percentage"/>
|
||||
</group>
|
||||
<view type="pivot" ref="sale_report.view_order_product_pivot"/>
|
||||
</dashboard>
|
||||
|
||||
The root element of the Dashboard view is <dashboard>, it does not accept any
|
||||
attributes.
|
||||
|
||||
There are 5 possible type of tags in a dashboard view:
|
||||
|
||||
.. rst-class:: o-definition-list
|
||||
|
||||
``view``
|
||||
declares a sub view.
|
||||
|
||||
Admissible attributes are:
|
||||
|
||||
.. rst-class:: o-definition-list
|
||||
|
||||
``type`` (mandatory)
|
||||
The type of the sub view. For example, *graph* or *pivot*.
|
||||
|
||||
``ref`` (optional)
|
||||
An xml id for a view. If not given, the default view for the model will
|
||||
be used.
|
||||
|
||||
``name`` (optional)
|
||||
A string which identifies this element. It is mostly
|
||||
useful to be used as a target for an xpath.
|
||||
|
||||
``group``
|
||||
defines a column layout. This is actually very similar to the group element
|
||||
in a form view.
|
||||
|
||||
Admissible attributes are:
|
||||
|
||||
.. rst-class:: o-definition-list
|
||||
|
||||
``string`` (optional)
|
||||
A description which will be displayed as a group title.
|
||||
|
||||
``colspan`` (optional)
|
||||
The number of subcolumns in this group tag. By default, 6.
|
||||
|
||||
``col`` (optional)
|
||||
The number of columns spanned by this group tag (only makes sense inside
|
||||
another group). By default, 6.
|
||||
|
||||
|
||||
``aggregate``
|
||||
declares an aggregate. This is the value of an aggregate for a given field
|
||||
over the current domain.
|
||||
|
||||
Note that aggregates are supposed to be used inside a group tag (otherwise
|
||||
the style will not be properly applied).
|
||||
|
||||
Admissible attributes are:
|
||||
|
||||
.. rst-class:: o-definition-list
|
||||
|
||||
``field`` (mandatory)
|
||||
The field name to use for computing the aggregate. Possible field types
|
||||
are:
|
||||
|
||||
- ``integer`` (default group operator is sum)
|
||||
- ``float`` (default group operator is sum)
|
||||
- ``many2one`` (default group operator is count distinct)
|
||||
|
||||
``name`` (mandatory)
|
||||
A string to identify this aggregate (useful for formulas)
|
||||
|
||||
``string`` (optional)
|
||||
A short description that will be displayed above the value. If not
|
||||
given, it will fall back to the field string.
|
||||
|
||||
``domain`` (optional)
|
||||
An additional restriction on the set of records that we want to aggregate.
|
||||
This domain will be combined with the current domain.
|
||||
|
||||
``domain_label`` (optional)
|
||||
When the user clicks on an aggregate with a domain, it will be added to
|
||||
the search view as a facet. The string displayed for this facet can
|
||||
be customized with this attribute.
|
||||
|
||||
``group_operator`` (optional)
|
||||
A valid postgreSQL aggregate function identifier to use when aggregating
|
||||
values (see https://www.postgresql.org/docs/12/static/functions-aggregate.html).
|
||||
If not provided, By default, the group_operator from the field definition is used.
|
||||
Note that no aggregation of field values is achieved if the group_operator value is "".
|
||||
|
||||
.. note:: The special aggregate function ``count_distinct`` (defined in odoo) can also be used here
|
||||
|
||||
.. code-block:: xml
|
||||
|
||||
<aggregate name="price_total_max" field="price_total" group_operator="max"/>
|
||||
|
||||
|
||||
|
||||
``col`` (optional)
|
||||
The number of columns spanned by this tag (only makes sense inside a
|
||||
group). By default, 1.
|
||||
|
||||
``widget`` (optional)
|
||||
A widget to format the value (like the widget attribute for fields).
|
||||
For example, monetary.
|
||||
|
||||
``help`` (optional)
|
||||
A help message to dipslay in a tooltip (equivalent of help for a field in python)
|
||||
|
||||
``measure`` (optional)
|
||||
This attribute is the name of a field describing the measure that has to be used
|
||||
in the graph and pivot views when clicking on the aggregate.
|
||||
The special value __count__ can be used to use the count measure.
|
||||
|
||||
.. code-block:: xml
|
||||
|
||||
<aggregate name="total_ojects" string="Total Objects" field="id" group_operator="count" measure="__count__"/>
|
||||
|
||||
``clickable`` (optional)
|
||||
A boolean indicating if this aggregate should be clickable or not (default to true).
|
||||
Clicking on a clickable aggregate will change the measures used by the subviews
|
||||
and add the value of the domain attribute (if any) to the search view.
|
||||
|
||||
``value_label`` (optional)
|
||||
A string put on the right of the aggregate value.
|
||||
For example, it can be useful to indicate the unit of measure
|
||||
of the aggregate value.
|
||||
|
||||
``formula``
|
||||
declares a derived value. Formulas are values computed from aggregates.
|
||||
|
||||
Note that like aggregates, formulas are supposed to be used inside a group
|
||||
tag (otherwise the style will not be properly applied).
|
||||
|
||||
Admissible attributes are:
|
||||
|
||||
.. rst-class:: o-definition-list
|
||||
|
||||
``value`` (mandatory)
|
||||
A string expression that will be evaluated, with the builtin python
|
||||
evaluator (in the web client). Every aggregate can be used in the
|
||||
context, in the ``record`` variable. For example,
|
||||
``record.price_total / record.order_id``.
|
||||
|
||||
``name`` (optional)
|
||||
A string to identify this formula
|
||||
|
||||
``string`` (optional)
|
||||
A short description that will be displayed above the formula.
|
||||
|
||||
``col`` (optional)
|
||||
The number of columns spanned by this tag (only makes sense inside a
|
||||
group). By default, 1.
|
||||
|
||||
``widget`` (optional)
|
||||
A widget to format the value (like the widget attribute for fields).
|
||||
For example, monetary. By default, it is 'float'.
|
||||
|
||||
``help`` (optional)
|
||||
A help message to dipslay in a tooltip (equivalent of help for a field in python)
|
||||
|
||||
``value_label`` (optional)
|
||||
A string put on the right of the formula value.
|
||||
For example, it can be useful to indicate the unit of measure
|
||||
of the formula value.
|
||||
|
||||
``widget``
|
||||
Declares a specialized widget to be used to display the information. This is
|
||||
a mechanism similar to the widgets in the form view.
|
||||
|
||||
Admissible attributes are:
|
||||
|
||||
.. rst-class:: o-definition-list
|
||||
|
||||
``name`` (mandatory)
|
||||
A string to identify which widget should be instantiated. The view will
|
||||
look into the ``widget_registry`` to get the proper class.
|
||||
|
||||
``col`` (optional)
|
||||
The number of columns spanned by this tag (only makes sense inside a
|
||||
group). By default, 1.
|
||||
|
||||
.. _reference/views/form:
|
||||
|
||||
Form
|
||||
|
@ -15,7 +15,6 @@ Tutorials
|
||||
tutorials/unit_tests
|
||||
tutorials/mixins
|
||||
tutorials/pdf_reports
|
||||
tutorials/dashboards
|
||||
|
||||
.. cards::
|
||||
|
||||
@ -66,9 +65,3 @@ Tutorials
|
||||
:target: tutorials/pdf_reports
|
||||
|
||||
Use QWeb, Odoo's powerful templating engine, to create custom PDF reports for your documents.
|
||||
|
||||
.. card:: Visualize data in dashboards
|
||||
:target: tutorials/dashboards
|
||||
|
||||
Create data visualization dashboards using the enterprise edition "Dashboard" view and
|
||||
so-called "SQL views".
|
||||
|
@ -1,370 +0,0 @@
|
||||
============================
|
||||
Visualize data in dashboards
|
||||
============================
|
||||
|
||||
.. important::
|
||||
This tutorial is an extension of the :doc:`getting_started` tutorial. Make sure you have
|
||||
completed it and use the `estate` module you have built as a base for the exercises in this
|
||||
tutorial. Fetch the branch `{BRANCH}-core` from the `technical-training-solutions
|
||||
<https://github.com/odoo/technical-training-solutions/tree/{BRANCH}-core>`_ repository if you
|
||||
want to start from a clean base.
|
||||
|
||||
The term "Dashboard" is used in Odoo for objects that display data, but involves different
|
||||
implementations. This tutorial will only focus on the Enterprise view that is used to provide
|
||||
aggregated data visualization. They can be added as a ``view_mode`` to an existing model (i.e. a
|
||||
view you can switch to via the view buttons in the top right of a view), but they are also often
|
||||
used as a view for to a special model customized for data visualization. You may hear these
|
||||
special views referred to as SQL views.
|
||||
|
||||
It is useful to note there is a "Dashboard" app in Odoo Community. This app allows users to create
|
||||
their own customized view of data, but the customization is only visible to each user and can
|
||||
only be viewed within the "Dashboard" app. Technically it is possible to make global dashboards
|
||||
using this ``board`` module, but it is much easier to do as an Enterprise view. Plus it looks nicer
|
||||
and has extra features not available in ``board``. Some other dashboards within Odoo also exist,
|
||||
but they are custom made and are beyond the scope of this tutorial.
|
||||
|
||||
The documentation related to this topic can be found in :ref:`reference/views/dashboard`.
|
||||
|
||||
File Structure
|
||||
==============
|
||||
|
||||
You probably have already guessed that since dashboard views are an Enterprise view, they must have
|
||||
a dependency on an Enterprise module. The Enterprise module is ``web_dashboard``. Don't forget to
|
||||
add it to your manifest file! It is standard to add dashboards intended to be used as a
|
||||
``view_mode`` for one of your module's models (in the ``model`` folder) to the views directory
|
||||
(i.e. the same file that contains the other views for the same model).
|
||||
|
||||
It is standard to create a separate Enterprise module to add extra Enterprise views and features to
|
||||
a Community module. This is done in a similar manner as the module link technique covered within
|
||||
:ref:`tutorials/getting_started/14_other_module`. The difference is that instead of linking 2
|
||||
different modules, we are extending our `estate` module. We do this by creating a new module and
|
||||
adding both the Community module and its necessary Enterprise module dependencies to its manifest.
|
||||
You will commonly see "enterprise" in the module's directory name. To keep this tutorial simple, we
|
||||
will add dashboards to our existing ``estate`` module.
|
||||
|
||||
SQL Views have 2 parts: their xml file (don't forget to add it to your manifest file) and their
|
||||
Python file (don't forget to add it to the appropriate ``__init.py__`` files). The former is the
|
||||
same format as the ``view_mode`` xml while the latter contains a custom model and SQL code to
|
||||
populate its fields. It is standard to add SQL view files to the ``report/`` directory. It
|
||||
is also common to include "report" in the name of the SQL view's files. You may be
|
||||
wondering why do we put the files in a report directory? We saw earlier that the dashboard is
|
||||
for data visualization, therefore it is not editable. You can think of dashboards as interactive
|
||||
reports where you can click on statistics, graphs, and charts to see the specific data contributing
|
||||
to them. Note it is also standard to store the xml code for :doc:`PDF report templates
|
||||
<pdf_reports>` in the report directory.
|
||||
|
||||
It is expected that your work tree will look something like:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
estate
|
||||
├── models
|
||||
│ ├── *.py
|
||||
│ └── __init__.py
|
||||
├── report
|
||||
│ ├── __init__.py
|
||||
│ ├── estate_report.py
|
||||
│ └── estate_report_views.xml
|
||||
├── security
|
||||
│ └── ir.model.access.csv
|
||||
├── views
|
||||
│ ├── *.xml
|
||||
│ └── estate_property_views.xml
|
||||
├── __init__.py
|
||||
└── __manifest__.py
|
||||
|
||||
Dashboard View
|
||||
==============
|
||||
|
||||
.. note::
|
||||
|
||||
**Goal**: at the end of this section, we will have a new dashboard view that displays
|
||||
different property statistics.
|
||||
|
||||
.. image:: dashboards/simple_dashboard.png
|
||||
:align: center
|
||||
:alt: Basic Dashboard view
|
||||
|
||||
Dashboards can display data in different ways, including:
|
||||
|
||||
* showing an ``aggregate`` of a field
|
||||
* using aggregated fields in a ``formula``
|
||||
* using a ``widget``
|
||||
* using another ``view`` as a subview
|
||||
|
||||
There are many useful statistics and visuals we can provide for our real estate example using
|
||||
these options. A full example to reference while doing the exercises in this section is
|
||||
`viewable here <https://github.com/odoo/enterprise/blob/6fd3244ae168dc73c348a9c1870796e89d8ef594/crm_enterprise/views/crm_lead_views.xml#L106-L133>`__
|
||||
(restricted github repository link).
|
||||
|
||||
Data
|
||||
----
|
||||
|
||||
To fully enjoy our dashboard view, we will need good test data to populate it. Test data will
|
||||
allow us to check that the resulting look and statistics are correct. It is a good idea to test
|
||||
with data that will cover most or all of your expected use cases, but is also easy to verify with
|
||||
that your statistics are correct. In our goal's case we are looking at count, sum, average,
|
||||
minimum, and maximum statistics, therefore a good representation set for our dashboard is:
|
||||
|
||||
* At least 3 properties with different property types, expected prices, and average living area.
|
||||
* At least 1 sold property and at least 1 canceled property
|
||||
|
||||
If you don't have a set of data like this already, you can either:
|
||||
|
||||
* Complete :doc:`define_module_data` (if you haven't done so already) and add the extra cases to
|
||||
your demo data (you may need to create a new database to load in the demo data).
|
||||
* Manually create the data in your database.
|
||||
* Copy this `data file
|
||||
<https://github.com/odoo/technical-training-solutions/blob/{BRANCH}-K_dashboard/estate/data/estate_demo.xml>`_
|
||||
into a new directory called ``data`` in your estate module and copy `these lines
|
||||
<https://github.com/odoo/technical-training-solutions/blob/{BRANCH}-K_dashboard/estate/__manifest__.py#L21-L23>`_
|
||||
into your __manifest__.py file (you may need to create a new database to load in the demo data).
|
||||
|
||||
Click through your database data and make sure it is what you expect. Of course you can add the
|
||||
data after you write your dashboard code and then test that your view is working as expected.
|
||||
|
||||
Aggregations
|
||||
------------
|
||||
|
||||
Building a dashboard view is very similar to what you have previously done in
|
||||
:ref:`tutorials/getting_started/07_basicviews`. For the dashboard view, we use the `dashboard` root
|
||||
element and choose from its possible tags (see all the possibilities and their attributes in the
|
||||
:ref:`reference/views/dashboard` documentation). So a simple dashboard example is:
|
||||
|
||||
.. code-block:: xml
|
||||
|
||||
<dashboard>
|
||||
<group>
|
||||
<aggregate name="min_expected_price" string="Min Expected Price" field="expected_price"
|
||||
group_operator="min" help="Lowest expected price."/>
|
||||
</group>
|
||||
</dashboard>
|
||||
|
||||
In this example, ``<group>`` adds styling and ``<aggregate>`` declares an aggregation. We
|
||||
indicate which ``field`` we want to aggregate, what ``string`` to display with the value, and
|
||||
how to aggregate it with the `group_operator` attribute. The `group_operator` can use any valid
|
||||
PostgreSQL aggregate function plus the special Odoo defined ``count_distinct``.
|
||||
|
||||
Hopefully you remember how to add views to a window action `view_mode` (hint, it was
|
||||
covered in :ref:`tutorials/getting_started/06_firstui`). Now let's make some dashboards!
|
||||
|
||||
.. exercise:: Make a dashboard view.
|
||||
|
||||
- Create a dashboard of aggregated values for the ``estate.property`` model. You can
|
||||
look at the **Goal** of this section for some inspiration. Remember to check that your
|
||||
statistics are calculating as you expect and note that the calculated values take into
|
||||
consideration any applied view filters!
|
||||
|
||||
- Bonus: Add in some aggregations that need a `domain` to make sense (remember domains were
|
||||
also covered in :ref:`tutorials/getting_started/07_basicviews`).
|
||||
|
||||
Pie Charts
|
||||
----------
|
||||
|
||||
Adding pie charts to dashboards is a piece of cake using the `<widget>` element. An example is:
|
||||
|
||||
.. code-block:: xml
|
||||
|
||||
<dashboard>
|
||||
<group>
|
||||
<widget name="pie_chart" title="Property Types" attrs="{'groupby': 'property_type_id'}"/>
|
||||
</group>
|
||||
</dashboard>
|
||||
|
||||
In this example, we indicate that we're using the `pie_chart` widget with the `name` attribute and
|
||||
the ``title`` for the pie chart, and that we're grouping it by property type.
|
||||
|
||||
.. exercise:: Add some pie charts.
|
||||
|
||||
- Add the pie charts from the **Goal** of this section to your dashboard. Hint: you will need
|
||||
to add `'measure': selling_price` to your pie chart `attrs` if you want to show selling
|
||||
prices grouped by property type.
|
||||
|
||||
- Hover over and click on the pie charts to check your charts counts values and don't forget
|
||||
that filters will also apply to the charts.
|
||||
|
||||
- Bonus: Add a domain to your selling price pie chart to only include "sold" properties (i.e.
|
||||
not "offer_accepted" ones). Note that the `'` will need to be escaped since it is declared
|
||||
as part of the `attrs`.
|
||||
|
||||
Subviews
|
||||
--------
|
||||
|
||||
Similar to how we can use the list view within the form view (we saw this automatically happen for
|
||||
One2many relationships in :ref:`tutorials/getting_started/08_relations`), we can add other views
|
||||
within our dashboard view. The most commonly added are the pivot and graph views, but the cohort
|
||||
view is also an option. A dashboard with only subviews is:
|
||||
|
||||
.. code-block:: xml
|
||||
|
||||
<dashboard>
|
||||
<view type="graph"/>
|
||||
<view type="pivot"/>
|
||||
</dashboard>
|
||||
|
||||
The `ref` attribute can be added to `<view>` elements to use a specific XML id for that view. If
|
||||
no XML id is provided for a graph or pivot view, then the default view will be used.
|
||||
The cohort view will not work in the dashboard without a specific XML id. If you have already
|
||||
created some of these views, then you are welcome to add them to your dashboard! Sample graph and
|
||||
pivot views are included in the `solution code
|
||||
<https://github.com/odoo/technical-training-solutions/blob/{BRANCH}-K_dashboard/estate/views/estate_property_views.xml#L169-L191>`_
|
||||
that you are welcome to use as well.
|
||||
|
||||
.. exercise:: Add subviews.
|
||||
|
||||
- Add in a graph and a pivot view to your dashboard. Try playing around with the layout of
|
||||
your subviews in relation to your pie charts and aggregated values and refer to the **Goal**
|
||||
of this section for an often used layout. Remember to check that your subviews are
|
||||
displaying your data as expected (and yes, they are also affected by the filters!).
|
||||
|
||||
SQL Views
|
||||
=========
|
||||
|
||||
.. warning::
|
||||
|
||||
This section expects you to have a basic knowledge of SQL. If you have little to no SQL
|
||||
knowledge then `this is a good tutorial to start with <https://selectstarsql.com/>`__
|
||||
and these `exercises <https://www.pgexercises.com/>`__ are good for those who need
|
||||
a refresher or extra practice.
|
||||
|
||||
.. note::
|
||||
|
||||
**Goal**: at the end of this section, we will have a new SQL view that displays different
|
||||
property statistics.
|
||||
|
||||
.. image:: dashboards/report_dashboard.png
|
||||
:align: center
|
||||
:alt: SQL view
|
||||
|
||||
|
||||
Occasionally we want to show data that goes beyond what our model already has in it. We could add
|
||||
a lot of stored computed or related fields (non-stored fields cannot be aggregated
|
||||
or displayed in pie charts), but it would be impractical to store a bunch of fields only for this
|
||||
purpose. We can instead add a custom SQL view to minimize the computational load and keep our
|
||||
model clean of unnecessary fields.
|
||||
|
||||
Model
|
||||
-----
|
||||
|
||||
We will start with the more difficult part: our special report model. This file starts the same as
|
||||
any other model, except that we add 2 attributes ``_auto`` and ``_rec_name``::
|
||||
|
||||
from odoo import fields, models, tools
|
||||
|
||||
|
||||
class EstateReport(models.Model):
|
||||
_name = 'estate.report'
|
||||
_description = "Stock Report"
|
||||
_rec_name = 'id'
|
||||
_auto = False
|
||||
|
||||
``_auto = False`` indicates that we do not want to store the model in the database, and we will
|
||||
create a custom table by overriding the ``BaseModel.init()`` method. ``_rec_name`` indicates
|
||||
which of the model's fields represents a record's name (i.e. the name that will be used in the
|
||||
navigation breadcrumb when opening a record's form view). In this case, I left it as 'id' because
|
||||
our property offers don't have a name. We will need the `tools` import later (i.e.
|
||||
``odoo/odoo/tools``, which is full of all sorts of useful helper methods you will probably use in
|
||||
the future). Note that it is standard to include ``report`` in the model's name.
|
||||
|
||||
Remember, your new model will need to be added to your security file, as you learned in
|
||||
:ref:`tutorials/getting_started/05_securityintro`!
|
||||
|
||||
Then we define the fields we need for our dashboard the same way as any other model (like you
|
||||
learned in :ref:`tutorials/getting_started/04_basicmodel`), except that every field is
|
||||
``readonly=True``. After all, our model is for read-only purposes only.
|
||||
|
||||
Now we override the ``BaseModel.init()`` method mentioned earlier::
|
||||
|
||||
def init(self):
|
||||
tools.drop_view_if_exists(self.env.cr, self._table)
|
||||
self.env.cr.execute("""CREATE or REPLACE VIEW %s as (
|
||||
SELECT
|
||||
%s
|
||||
FROM
|
||||
%s
|
||||
)""" % (self._table, self._select(), self._from()))
|
||||
|
||||
We use ``tools.drop_view_if_exists`` to ensure that we don't create a conflicting view and then
|
||||
execute the SQL query. It is standard to separate the different parts of the query to
|
||||
allow for easier model extension. Exactly how the query is split up across methods is not
|
||||
standardized, but you will often see at minimum ``_select`` and ``_from`` methods [or something
|
||||
similar], and of course all these methods will return strings. The columns from the SELECT
|
||||
will populate our model's fields, so ensure that your column names match your field names
|
||||
or use alias names that match.
|
||||
|
||||
.. exercise:: Create report model.
|
||||
|
||||
- Create a report model with the following fields:
|
||||
|
||||
========================= ========================= =========================
|
||||
Field Type Note
|
||||
========================= ========================= =========================
|
||||
id Integer Corresponds to ``id`` of ``estate.property.offer``
|
||||
offer_state Selection Equals ``state`` choices of ``estate.property.offer``
|
||||
property_id Many2one ``estate.property``
|
||||
property_state Selection Equals ``state`` choices of ``estate.property``
|
||||
property_type_id Many2one ``estate.property.type``
|
||||
========================= ========================= =========================
|
||||
|
||||
and write the SQL query necessary to populate the fields (hint, you will need 2 JOINs).
|
||||
|
||||
You won't be able to check if your model is correct until we create a view for it, but you are
|
||||
welcome to check your query directly in your database to see if the results are as you expect.
|
||||
If you struggle with this exercise, then
|
||||
`here is an example <https://github.com/odoo/odoo/blob/7417d8fc138b9de550bc631435bcc08628c29bed/addons/crm/report/crm_activity_report.py>`__
|
||||
to reference.
|
||||
|
||||
View
|
||||
----
|
||||
|
||||
Now that we have our model, we can make its dashboard view. There is no difference in how it's made,
|
||||
except that its file is in the ``report`` folder. Since it is a new model not linked to
|
||||
any other model, we will also have to add a new menuitem to view our dashboard. Typically, SQL views
|
||||
are added under a first-level menu called *Reporting* (because it's a report, surprise!). Do you
|
||||
remember how to add a ``menuitem``? If not, revisit :ref:`tutorials/getting_started/06_firstui`) again.
|
||||
|
||||
.. exercise:: Create report view.
|
||||
|
||||
- Recreate the dashboard in the **Goal** of this section. Hint: it uses the ``formula`` element,
|
||||
which we did not need for our previous dashboard.
|
||||
|
||||
- Bonus: Create ``list`` and ``form`` views for your new report model so we don't have to see the ugly
|
||||
defaults when you click on your pie charts.
|
||||
|
||||
Extra Tips
|
||||
----------
|
||||
|
||||
**Tip 1** A common mistake in SQL views is not considering the duplication of certain data
|
||||
due to table JOINs. For example, in our **Goal**, we have a pie chart of the offers' property types.
|
||||
We may be tempted to add a similar pie chart with a domain to only include canceled properties,
|
||||
so we think we are only counting the number of canceled properties by property type. In reality, we
|
||||
are still looking at all the offers per property, so any property with more than 1 offer will be
|
||||
counted per offer. This example is easily double-checked by clicking on the pie chart to see its
|
||||
list view:
|
||||
|
||||
.. image:: dashboards/report_list_detail.png
|
||||
:align: center
|
||||
:alt: Pie chart list view
|
||||
|
||||
But for cases such as average aggregations or using a subview such as the pivot view, it is easy to
|
||||
miss this mistake. It is also easy to miss this mistake when you have insufficient test data.
|
||||
To add a number of properties canceled by property type pie chart to this
|
||||
report, we would either have to do a hack (too advanced for this tutorial) or simply exclude it
|
||||
from this report.
|
||||
|
||||
**Tip 2** If you have a field that you do not want as a measure (i.e., in your pivot or
|
||||
graph views), then you can add ``store=False`` to it, and it will not show.
|
||||
|
||||
**Tip 3** If you have a SQL View that depends on context, then instead of overriding
|
||||
``BaseModel.init()`` set the ``_table_query`` property::
|
||||
|
||||
@property
|
||||
def _table_query(self):
|
||||
return 'SELECT %s FROM %s' % (self._select(), self._from())
|
||||
|
||||
The *select* and *from* methods remain the same.
|
||||
|
||||
`Here is an example <{GITHUB_PATH}/addons/account/report/account_invoice_report.py>`__
|
||||
of a report that depends on the currently selected companies (in a multi-company environment) context to
|
||||
determine the currency exchange rates to use for accurately displaying amounts when the selected companies
|
||||
have different currencies.
|
Binary file not shown.
Before Width: | Height: | Size: 22 KiB |
Binary file not shown.
Before Width: | Height: | Size: 20 KiB |
Binary file not shown.
Before Width: | Height: | Size: 45 KiB |
@ -50,11 +50,6 @@ Therefore, it is expected that your work tree will look something like this:
|
||||
├── __init__.py
|
||||
└── __manifest__.py
|
||||
|
||||
Note that you will often see other non-QWeb and non-XML files containing "report" in their name also within
|
||||
the report folder. These are unrelated to the reports covered in this tutorial and are covered in
|
||||
the :doc:`dashboards` tutorial. For now you can think of them as customized views that use direct
|
||||
SQL queries (sometimes referred to as SQL Views).
|
||||
|
||||
Don't forget to add whatever files your template and action view will be into to your ``__manifest__.py``.
|
||||
In this case, you will want to add the files to the ``data`` list and remember that the files listed in a manifest
|
||||
are loaded sequentially!
|
||||
|
Loading…
Reference in New Issue
Block a user