The module provides a way of defining dynamic relationships between objects. We use the following concepts:
analytic.dimension
analytic.structure
analytic.code
These objects can be seen in
Technical >> Analytics
under
Settings
.
Dimensions act as labels for data points that can be used to perform analyses. Structures define mappings between models and dimensions, they can be configured through the Settings menu. Codes are the objects that are bound to instances of dimension models, they allow us to define dynamic relationships.
Example: Your company has several product lines and you would like
to analyse expenses related to these product lines in your
accounting system. You would then define a
product line dimension and some structures that bind the
product line dimension to product.product
,
invoice.line
, account.move.line
models.
Analytic Structure provides the MetaAnalytic
metaclass
(see MetaAnalytic) that injects new
behaviors into Odoo models. Dimension models and models that define
analytic fields must use MetaAnalytic
and define
various class attributes.
A dimension model is declared with the
_dimension
attribute (see
AnalyticDimensions). The metaclass
automatically creates analytic.dimension
records for
each dimension model. Once a model is declared as a dimension, every
new instance will automatically create a new
analytic.code
record that points to the relevant
analytic.dimension
record.
A model that is declared with the _analytic
attribute
(see AnalyticFields) can reference
dimension objects. The MetaAnalytic
will automatically
create a number of M2O fields that point to analytic codes. The
number of fields that will be added depends on the configuration
(See
ConfigureAnalyticFields).
They are named with a predefined prefix and a number or slot eg.
a1_id
, a2_id
, a3_id
, ...
These analytic fields will be displayed in views with the names of the dimensions they point to thanks to view manipulation magic.
Schematic:
| AnalyticModel Code DimensionModel Dimension | ----- ---- -------------- --------- | an_id ----------> id,name <-- analytic_code_id | | n_id ---------------------> id,name
The relationship between a model and a dimension is configured by analytic structures. Structure define how models point to dimensions and what analytic field to use.
Example: You have a dimension D
you wish to bind to
model A
. You would create an
analytic.structure
record for A
that
references D
through the Analysis 1
slot.
This would allow you to use the a1_id
field (assuming
the default prefix is used) to reference D
records.
You cannot delete analytic codes that are referenced by objects. The goal of this constraint is to ensure the integrity of your analyses.
In your OpenERP server's configuration file, you can set several optional parameters related to the analytic module.:
[analytic] key = value ...
Those options must be grouped under the [analytic] category. If the category doesn't exist, add it to your configuration file.
key (default value): description
analytic_size (5): define the maximum number of analytic dimensions that can be associated with a model.
translate (False): enable or disable the translation of field values on analytic dimensions (name) and codes (name and description).
At the beginning of the source file, import the MetaAnalytic metaclass:
from openerp.addons.analytic_structure.MetaAnalytic import MetaAnalytic
Inside your Model class, define MetaAnalytic to be used as metaclass:
__metaclass__ = MetaAnalytic
First of all, make sure you are using the MetaAnalytic metaclass. Then, add the _analytic attribute to your class, using the following syntax.
Use the analytic fields associated with the model:
_analytic = True
Use analytic fields associated with another model:
_analytic = 'account_move_line'
Use several analytic field structures, associated with different prefixes:
_analytic = { 'a': 'account_asset_asset', 't': 'account_move_line', }
Analytic fields can be added to the view individually, like any other field:
<field name="a1_id" />
'a' is the prefix associated with the structure. By default, it is 'a'. '1' is the dimension's ordering as defined by the analytic structure.
You can also use a field named 'analytic_dimensions' to insert every analytic field within a given structure (defined by its prefix) that wasn't explicitly placed in the view. This field is automatically generated when you call the Metaclass
<field name="analytic_dimensions" required="1" prefix="t" />
The prefix can be omitted for a structure that uses the default prefix 'a'. Any other attribute will be propagated to the analytic fields.
Warning: analytic fields should generally not be used inside nested sub-views. If possible, create a separate record and use the context to specify the view:
<field name="order_line" colspan="4" nolabel="1" context="{ 'form_view_ref' : 'module.view_id', 'tree_view_ref' : 'module.view_id' }"/>
Para-analytic fields are a more advanced feature of analytic_structure. They differ from ordinary analytics fields in two ways:
Para-analytic fields are defined in with the
_para_analytic
attribute. For each entry in
_para_analytic
the MetaAnalytic
metaclass
will create a number fields. The number of fields depend on
analytic_size
in the configuration file (see
ConfigureAnalyticFields).
Each entry is key-value pair of a dict where the key is a (prefix, suffix) tuple and the value a dict containing the following:
model
the name of the referenced dimension model
(doesn't do anything special)
type
a field class, the field type to use
default
default value for the fields
args
list of arguments to inject in
type
constructor
kwargs
dict of keyword arguments to inject in
type
constructor.
Here is declaration that will create fields with the names
a1_b
, a2_b
, a3_b
, ...
from openerp import fields # ... # Inside a class _para_analytic = { ('a', 'b'): { 'model': 'account_move_line', 'type': fields.Boolean, 'default': True, 'args': ("field is optional"), 'kwargs': dict(required=True), } }
Models that define the _analytic
attribute can override
the _validate_analytic_fields
to perform validation on
analytic fields. The method is called every time the model's
create
and write
methods are called.
Odoo 8.0 Method signature:
where analytic
is a dict containing in the same
information given in the _analytic
class attribute, in
the expanded form.
The method signals failure by raising an exception, just like
methods decorated with api.constrains()
.
First of all, make sure you are using the MetaAnalytic metaclass. Then, add the _dimension attribute to your class, using the following syntax.
Bind the model to an analytic dimension named after the model, using default values:
_dimension = True
Bind the model to an analytic dimension with a specified name, using default values:
_dimension = 'Funding Source'
Bind the model to an analytic dimension, using either custom or default values:
_dimension = { 'name': 'School', 'column': 'analytic_code_id', 'ref_id': 'school_analytic_dimension', 'ref_module': 'my_module', 'sync_parent': False, 'rel_description': True, 'rel_active': (u"Active", 'active_code'), 'use_inherits': False, 'use_code_name_methods': False, 'code_name': 'name', 'code_description': 'description', 'parent_column': 'analytic_code_id', 'required': True, }
key (default value): description
name
(= _description
or
_name
): The name of the analytic dimension. This name
is only used when creating the dimension in the database.
column (analytic_id): The field that links each record to an analytic code.
ref_id
(= _name
+
analytic_dimension_id
): The external ID that will be
used by the analytic dimension. By setting this value, you can allow
two models to use the same dimension, or a model to use an already
existing one.
ref_module
(empty string): The name of the module
associated with the dimension record. Change this value in order to
use a dimension defined in a data file.
sync_parent
(False
): Controls the
synchronization of the codes' parent-child hierarchy with that of
the model. When using an inherited, renamed parent field, you must
give the parent field name rather than simply True
.
use_inherits
(special): Determines whether the analytic
codes should be bound to the records by inheritance, or through a
simple many2one field. Inheritance allows for better
synchronization, but can only be used if there are no duplicate
fields between the two objects. The default value is
True
if the model has no 'name' and 'code_parent_id'
field as well as no inheritance of any kind, and
False
otherwise. If the object has inheritances that do
not cause conflicts, you can set it to True
.
rel_active
(False
): Create a related field
in the model, targeting the analytic code field 'active' and with an
appropriate store parameter. This is useful when the model doesn't
inherit analytic_code and/or when it already has a field named
'active'. Can take a pair of string values: (field label, field
name). If given a string, the default field name 'active' will be
used. If given True
, the default field label 'Active'
will also be used.
rel_description
(False
): Same as
rel_active for the code field 'description'. If given a string, the
default field name 'description' will be used. If given
True
, the default field label 'Description' will also
be used.
use_code_name_methods
(False
): Set to
True
in order to override the methods name_get and
name_search, using those of analytic code. This allows the analytic
code's description to be displayed (and searched) along with the
entry's name in many2one fields targeting the model.
code_name
(name
): Name of the record
field, which will define the name of the created analytic code. The
default value is 'name'.
code_description
(description
): Name of
the record field, which will define the description of the created
analytic code. The default value is 'description'.
parent_column
(column): Name of the parent record
(sync_parent) field, which contains the parent code of the analytic
code to create. The default value is given by column
.
required
(True
): Whether the new field
should be marked as required. Set to False
when you
expect data without bound analytics.
Differences between the various "active" fields: