0% found this document useful (0 votes)
75 views

Technical Training v7 Exercises

This document provides an overview of technical training exercises for OpenERP. It discusses installing and configuring OpenERP, building OpenERP modules, creating views, modeling relationships between objects, inheritance, ORM methods, advanced views, workflows, security, wizards, internationalization, reporting, and web services. The document serves as an introduction to key concepts and components in developing applications with the OpenERP platform.

Uploaded by

RogerioFalcone
Copyright
© © All Rights Reserved
Available Formats
Download as RTF, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
75 views

Technical Training v7 Exercises

This document provides an overview of technical training exercises for OpenERP. It discusses installing and configuring OpenERP, building OpenERP modules, creating views, modeling relationships between objects, inheritance, ORM methods, advanced views, workflows, security, wizards, internationalization, reporting, and web services. The document serves as an introduction to key concepts and components in developing applications with the OpenERP platform.

Uploaded by

RogerioFalcone
Copyright
© © All Rights Reserved
Available Formats
Download as RTF, PDF, TXT or read online on Scribd
You are on page 1/ 36

Technical Training - Exercises

OpenERP

Contents
1 Configuration
1.1 Open Source RAD with OpenObject . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
1.2 Installing OpenERP . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
OpenERP Architecture . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
1.3 Package installation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
1.4 Installing from source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Typical bazaar checkout procedure (on Debian-based Linux) . . . . . . . . . . . . . . . . . . . .
1.5 Database creation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

3
3
3
3
4
4
4
5

2 Build an OpenERP module


2.1 Composition of a module . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.2 Module Structure . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.3 Object Service - ORM . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Predefined osv.Model attributes for business objects . . . . . . . . . . . . . . . . . . . . . . . . .
2.4 ORM field types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Common attributes supported by all fields (optional unless specified) . . . . . . . . . . . . . . . .
Simple fields . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.5 Special/Reserved field names . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.6 Actions and Menus . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

5
5
5
6
6
6
7
7
7
7

3 Building views: basics


3.1 Generic view declaration . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
3.2 Tree views . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
3.3 Form views . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

8
8
9
9

4 Relations between Objects


4.1 Relational fields . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

10
10

5 Inheritance
5.1 Inheritance mechanisms . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Predefined osv.Model attributes for business objects . . . . . . . . . . . . . . . . . . . . . . . . .
5.2 View inheritance . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

12
12
12
12

Domains . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

13

6 ORM Methods
6.1 Functional fields . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
6.2 Onchange . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
6.3 Predefined osv.Model attributes for business objects . . . . . . . . . . . . . . . . . . . . . . . . .

13
13
14
15

7 Advanced Views
7.1 List & Tree . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
7.2 Calendars . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
7.3 Search Views . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
7.4 Gantt Charts . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
7.5 (Charts) Graphs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
7.6 Kanban Boards . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

15
15
16
16
17
18
18

8 Workflows

19

9 Security
9.1 Group-based access control mechanisms . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
9.2 Access rights . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
9.3 Record rules . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

20
20
20
21

10 Wizards
10.1 Wizard objects (osv.TransientModel) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
10.2 Wizard execution . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
10.3 Wizard views . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

21
21
22
22

11 Internationalization

23

12 Reporting
12.1 Printed reports . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Expressions used in OpenERP report templates . . . . . . . . . . . . . . . . . . . . . . . . . . .
RML Reports . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
WebKit reports . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
12.2 Dashboards . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

23
23
24
24
25
25

13 WebServices
13.1 XML-RPC Library . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
13.2 OpenERP Client Library . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

25
26
26

Based on a real case, this chapter covers: building an OpenERP module and its interface, Views,
Reports, Workflows, Security aspects, Wizards, WebServices, Internationalization, Rapid
Application Development (RAD) and Performance Optimization.

1 Configuration
1.1 Open Source RAD with OpenObject
OpenERP is a modern Enterprise Management Software, released under the AGPL license, and featuring CRM,
HR, Sales, Accounting, Manufacturing, Inventory, Project Management, ... It is based on OpenObject, a modular,
scalable, and intuitive Rapid Application Development (RAD) framework written in Python.

OpenObject features a complete and modular toolbox for quickly building applications:
integrated Object-Relationship Mapping (ORM) support, template-based Model-View-Controller
(MVC) interfaces, a report generation system, automated internationalization, and much more.

Python is a high-level dynamic programming language, ideal for RAD, combining power with
clear syntax, and a core kept small by design.
Tip:
Useful links
Main website, with OpenERP downloads: www.openerp.com
Functional & technical documentation: doc.openerp.com
Community resources: www.launchpad.net/openobject
Integration server: demo.openerp.com
Learning Python: doc.python.org
OpenERP E-Learning platform: edu.openerp.com

1.2 Installing OpenERP


OpenERP is distributed as packages/installers for most platforms, but can of course be installed from
the source on any platform.
Note:
The procedure for installing OpenERP is likely to evolve (dependencies and so on), so make sure to always check the
specific documentation (packaged & on website) for the latest procedures. See http://doc.openerp.com/install.

OpenERP Architecture
OpenERP uses the well-known client-server paradigm, with different pieces of software acting as
client and server depending on the desired configuration.
OpenERP provides a web interface accessible using any modern browser.

1.3 Package installation


Windows
Linux

All-in-one installer, and separate installers for server, client, and webserver are on the website
openerp-server and openerp-client packages are available via corresponding package manager
(e.g. Synaptic on Ubuntu) OR using BaZaar bzr branch lp:openerp (or openerp/trunk for the
trunk version) when identified on Launchpad, then cd openerp (cd trunk in the trunk version)
and ./bzr_set.py

1.4 Installing from source


There are two alternatives:

1. using a tarball provided on the website, or


2. directly getting the source using Bazaar (distributed Source Version Control).
You also need to install the required dependencies (PostgreSQL and a few Python libraries - see
documentation on doc.openerp.com).
Note:
OpenERP being Python-based, no compilation step is needed.

Typical bazaar checkout procedure (on Debian-based Linux)


$ sudo apt-get install
$ bzr branch
lp:openerp
$ cd openerp
&& python

bzr
./bzr_set.py

# install bazaar
version
# retrieve source installer
# fetch code and
perform

control
setup

1.5 Database creation


After installation, run the server and the client. From the login screen of the web client, click on
Manage Databases to create a new database (default super admin password is admin). Each
database has its own modules and configuration.
Note:
Demonstration data can also be included.

2 Build an OpenERP module


2.1 Composition of a module

A module can contain the following elements :

Business object : declared as Python classes extending the OpenObject class osv.Model, the
persistence of these resource is completly managed by OpenObject,

Data : XML/CSV files with meta-data (views and workflows declaration), configuration data
(modules parametrization) and demo data (optional bu recommended for testing),

Wizards : stateful interactive forms used to assist users, often available as contextual actions on resources,

Reports : RML (XML format). MAKO or OpenOffice report templates, to be merged with any kind
of business data, and generate HTML, ODT or PDF reports.

2.2 Module Structure


Each module is contained in its own directory within either the server/bin/addons directory or another
directory of addons, configured in server installation.
Note:
Configure addons locations
By default, the only directory of addons known by the server is server/bin/addons. It is possible to add new
addons by 1) copying them in server/bin/addons, or creating a symbolic link to each of them in this directory, or 2)
specifying another directory containing addons to the server. The later can be accomplished either by running the
server with the addons-path= option, or by configuring this option in the openerp_serverrc file, automatically
generated under Linux in your home directory by the server when executed with the save option. You can
provide several addons to the addons_path = option, separating them using commas.

The __init__.py file is the Python module descriptor, because an OpenERP module is also a regular
Python module. It contains the importation instruction applied to all Python files of the module, without
the .py extension. For example, if a module contains a single python file named mymodule.py:

import mymodule
The __openerp__.py file is really the declaration of the OpenERP module. It is mandatory in each module. It
contains a single python dictionary with several important pieces of informations, such as the name of the
module, its description, the list of other OpenERP modules the installation of which is required for the current
module to work properly. It also contains, among other things, a reference to all the data files (xml, csv, yml...) of
the module. Its general structure is the following (see official documentation for a full file description):
{
"name": "MyModule", "version":
"1.0", "depends": ["base"],
"author": "Author Name",
"category": "Category",
"description": """
Description text
""", data: [
mymodule_view.xml,
#all other data files, except demo data and tests
], demo: [
#files containg demo data
], test: [
#files containg tests
],
installable: True,
auto_install: False,
}

Exercise 1 - Module Creation


Create the empty module Open Academy, with a __openerp__.py file. Install it under OpenERP.

2.3 Object Service - ORM


Key component of OpenObject, the Object Service (OSV) implements a complete Object-Relational
mapping layer, freeing developers from having to write basic SQL plumbing. Business objects are
declared as Python classes inheriting from the osv.Model class, which makes them part of the
OpenObject Model, and magically persisted by the ORM layer.
Predefined osv.Model attributes for business objects
_name (required)
_columns (required)
_defaults
_rec_name
...

business object name, in dot-notation (in module namespace)


dictionary {field names > object fields declarations }
dictionary: { field names > functions providing defaults } _defaults[name] = lambda
self,cr,uid,context: eggs
Alternative field to use as name, used by osvs name_get() (default: name)
...

2.4 ORM field types


Objects may contain three types of fields: simple, relational, and functional. Simple types are integers, floats,
booleans, strings, etc. Relational fields represent the relationships between objects (one2many, many2one,
many2many). Functional fields are not stored in the database but calculated on-the-fly as Python functions.

Common attributes supported by all fields (optional unless specified)

string : Field label (required)


required : True if mandatory
readonly : True if not editable
help : Help tooltip
select : 1 to include in search views and optimize for list filtering (with database index) business
object name, in dot-notation (in module namespace)

context : Dictionary with contextual parameters (for relational fields)


Simple fields

boolean(...) integer(...) date(...) datetime(...) time(...)


start_date: fields.date(Start Date)
active: fields.boolean(Active)
priority: fields.integer(Priority)

char(string,size,translate=False,..) text(string, translate=False,...) [Text-based fields]


translate: True if field values can be translated by users
size: maximum size for char fields (!41,45)

float(string, digits=None, ...) [Floating-point value with arbitrary precision and scale]
digits: tuple (precision, scale) (!58) . If digits is not provided, its a float, not a decimal type.

2.5 Special/Reserved field names


A few field names are reserved for pre-defined behavior in OpenObject. Some of them are created
automatically by the system, and in that case any field with that name will be ignored.
id
unique system identifier for the object (created by ORM, do not add it)
name defines the value used by default to display the record in lists, etc. if missing, set _rec_name to specify
another field to use for this purpose
...
See technical Memento for further details
Exercise 2 - Define a model
Define a new data model Course in the module openacademy. A course has a name, or title,
and a description. The course name is required.

2.6 Actions and Menus


Actions are declared as regular records and can be triggered in three ways:

1. by clicking on menu items linked to a specific action


2. by clicking on buttons in views, if these are connected to actions
3. as contextual actions on an object
Menus are also regular records in the ORM. However, they are declared with the tag <menuitem>.
This is a shortcut for declaring an ir.ui.menu record, and connect it with a corresponding action via
an ir.model.data record.

The following example defines a menu item to display the list of ideas. The action associated to the
menu mentions the model of the records to display, and which views are enabled; in this example,
only the tree and form views will be available. There are other optional fields for actions, see the
documentation for a complete description of them.
<record model="ir.actions.act_window" id="action_list_ideas"> <field
name="name">Ideas</field>
<field name="res_model">idea.idea</field> <field
name="view_mode">tree,form</field>
</record>
<menuitem id="menu_ideas" parent="menu_root" name="Ideas" sequence="10"
action="action_list_ideas"/>

Note:
The action is usually declared before its corresponding menu in the XML file.
This is because the record action_id must exist in the database to allow the ORM to create the menu record.

Exercise 3 - Define new menu entries


Define new menu entries to access courses and sessions under the OpenAcademy menu entry;
one should be able to 1) display a list of all the courses and 2) create/modify new courses.

3 Building views: basics


Exercise 1 - Customise a view through the view editor of the web interface
Create a tree view for the Course object, displaying the name of the course and its description.
Views form a hierarchy. Several views of the same type can be declared on the same object, and will
be used depending on their priorities.
It is also possible to add/remove elements in a view by declaring an inherited view (see View inheritance).

3.1 Generic view declaration


A view is declared as a record of the model ir.ui.view. Such a record is declared in XML as
<record model="ir.ui.view" id="view_id"> <field
name="name">view.name</field> <field
name="model">object_name</field>
<field name="type">form</field>
<!-- tree,form,calendar,search,graph,gantt -->
<field name="priority" eval="16"/> <field
name="arch" type="xml">
<!-- view content: <form>, <tree>, <graph>, ... -->
</field>
</record>

Notice that the content of the view is itself defined as XML. Hence, the field arch of the record must be
declared of type XML, in order to parse the content of that element as the fields value.

3.2 Tree views


Tree views, also called list views, display records in a tabular form. They are defined with the XML element
<tree>. In its simplest form, it mentions the fields that must be used as the columns of the table.
<tree string="Idea list"> <field
name="name"/> <field
name="inventor_id"/>
</tree>

3.3 Form views


Forms allow the creation/edition of resources, and are defined by XML elements <form>. The following example shows how a form view can be spatially structured with separators, groups, notebooks, etc. Consult
the documentation to find out all the possible elements you can place on a form.
<form string="Idea form"> <group
colspan="2" col="2">
<separator string="General stuff" colspan="2"/> <field
name="name"/>
<field name="inventor_id"/>
</group>
<group colspan="2" col="2">
<separator string="Dates" colspan="2"/> <field
name="active"/>
<field name="invent_date" readonly="1"/>
</group>
<notebook colspan="4">
<page string="Description">
<field name="description" nolabel="1"/>
</page>
</notebook>
<field name="state"/>
</form>

Now with the new version 7 you can write html in your form
<form string="Idea Form v7" version="7.0">
<header>
<button string="Confirm" type="object"
name="action_confirm"
states="draft" class="oe_highlight" /> <button
string="Mark as done" type="object"
name="action_done"
states="confirmed" class="oe_highlight"/> <button
string="Reset to draft" type="object"
name="action_draft"
states="confirmed,done" />
<field name="state" widget="statusbar"/>
</header>
<sheet>
<div class="oe_title">
<label for="name" class="oe_edit_only" string="Idea Name" /> <h1><field
name="name" /></h1>
</div>
<separator string="General" colspan="2" /> <group
colspan="2" col="2">
<field name="description" placeholder="Idea description..." />
</group>

</sheet>
</form>

Exercise 2 - Customise tree and form views using XML


Create your own tree and form views for the Course object. Data displayed should be:
In the tree view, the name of the course;
In the form view, the name and the description of the course.

Exercise 3 - Notebooks
In the Course form view, put the description field under a tab, such that it will be easier to add
other tabs later, containing additional information.

4 Relations between Objects


Exercise 1 - Create classes
Create the classes Session and Attendee, and add a menu item and an action to display the
sessions. A session has a name (required), a start date, a duration (in days) and a number of
seats. An attendee has a name, which is not required.

4.1 Relational fields


Relational fields are fields with values that refer to other objects.

Common attributes supported by relational fields


domain: optional restriction in the form of arguments for search (see search())

many2one(obj, ondelete=set null,...) : simple relationship towards another object (using a foreign key)

obj: _name of destination object (required)


ondelete: deletion handling: set null, cascade, restrict (see PostgreSQL documentation).

one2many(obj, field_id, ...) : virtual relationship towards multiple objects (inverse of many2one).
A one2many relational field provides a kind of container relation: the records on the other side
of the relation can be seen as contained in the record on this side.

obj: _name of destination object (required)

10

field_id: field name of inverse many2one, i.e., corresponding foreign key (required)

many2many(obj, rel, field1, field2, ...) : bidirectional multiple relationship between objects. This is
the most general kind of relation: a record may be related to any number of records on the other
side, and vice-versa.

obj: _name of destination object (required)


rel: relationship table to use
field1: name of field in rel table storing the id of the current object
field2: name of field in rel table storing the id of the target object
Note that the parameters rel, field1 and field2 are optional. When they are not given, the ORM
automatically generates suitable values for them.
Exercise 2 - Relations many2one
Using a many2one relational field, modify the classes Course, Session and Attendee to reflect
their relations with other objects, defined as follows.

Exercise 3 - Inverse relation one2many


Using the inverse relational field one2many, modify the classes Course, Session and Attendee to
reflect their relations with other objects, defined as follows.

Exercise 4 - Modify the views


Modify the tree and form views for the Course object and create these views for the Session
object. Data displayed should be, for the Course object:
in the tree view, the name of the course and the responsible for that course;
in the form view, the name and the responsible on the top, as well as the description of the
course in one tab and, and the related sessions in a second tab.
For the Session object:
in the tree view, the name of the session and the related course;
in the form view, all the fields of the Session object.
Since the amount of data to display is quite large, try to arrange the form views in such a way
that information looks clear.

11

5 Inheritance
5.1 Inheritance mechanisms

Predefined osv.Model attributes for business objects


_inherit
_inherits

_name of the parent business object (for prototype inheritance)


for multiple / instance inheritance mechanism: dictionary mapping the _name of the
parent business objects to the names of the corresponding foreign key fields to use

5.2 View inheritance


Existing views should be modified through inherited views, and never directly. An inherited view references
its parent view using the field inherit_id, and may add or modify existing elements in the view by
referencing them through element selectors or XPath expressions (specifying the appropriate position).

position

inside: placed inside match (default)


before: placed before match
attributes : to change attribute of
the tag

replace: replace match


after: placed after match

Tip:
XPath reference can be found at www.w3.org/TR/xpath
<!-- improved idea categories list -->
<record id="idea_category_list2" model="ir.ui.view"> <field
name="name">id.category.list2</field> <field
name="model">ir.ui.view</field>
<field name="inherit_id" ref="id_category_list"/> <field
name="arch" type="xml">
<!-- find field name, and insert field reference before it --> <field name="name"
position="before">
<field name="reference />
</field>

12

<!-- find field description inside tree, and add the field idea_ids after it --> <xpath
expr="/tree/field[@name=description]" position="after">
<field name="idea_ids" string="Number of ideas"/> </xpath>
</field>
</record>

Exercise 1 - Add an inheritance mechanism


Using class inheritance, create a Partner class which modifies the existing Partner class,
adding a is_instructor boolean field, and the list of the sessions this partner will attend to. Using
views inheri-tance, modify the existing partners form view to display the new fields.

Domains
Domains are used to select a subset of records from a model, according to a list of criteria. Each criteria is
a tuple of three element: a field name, an operator (see the technical memento for details), and a value. For
instance, the following domain selects all products of type service that have a unit_price greater than 1000.
[(product_type, =, service), (unit_price, >, 1000)]

By default, criteria are combined with the logic operator AND. One can insert the logic operators &,
|, ! (respectively AND, OR, NOT) inside domains. They are introduced using a prefix notation, i.e.,
the operator is put before its arguments. The example below encodes the condition: being of type
service OR NOT having a unit price between 1000 and 2000.
[|, (product_type, =, service),
!, &, (unit_price, >=, 1000), (unit_price, <, 2000)]

Exercise 2 - domain
Add a mechanism allowing the Session form view to allow the user to choose the instructor only
among the partners the Instructor field of which is set to True.

Exercise 3 - domain
We now decide to create new categories among the partners: Teacher/Teacher Level 1 and
Teacher/Teacher Level 2. Modify the domain defined in the previous exercise to allow the user to
choose the instructor among the partners the Instructor field of which is set to True or those
who are in one of the categories we defined.

6 ORM Methods
6.1 Functional fields
function(fnct, arg=None, fnct_inv=None, fnct_inv_arg=None, type=float, fnct_search=None, obj=None,
store=False, multi=False, ...) : Functional field simulating a real field, computed rather than stored

fnct [function to compute the field value (required)]


def fnct(self, cr, uid, ids, field_name, arg, context) returns a dictionary { ids!values } with
values of type type

fnct_inv [function used to write a value in the field instead]


13

def fnct_inv(obj, cr, uid, id, name, value, fnct_inv_arg, context)

type : type of simulated field (any other type besides function)


obj : model _name of simulated field if it is a relational field
fnct_search [function used to search on this field]
def fnct_search(obj, cr, uid, obj, name, args) returns a list of tuples arguments for search(),
e.g. [(id,in,[1,3,5])]

store, multi : optimization mechanisms (see usage in Performance Section)


related(f1, f2, ..., type=float, ...) [Shortcut field equivalent to browsing chained fields]

f1,f2,... : chained fields to reach target (f1 required)


type : type of target field
obj : model _name of target field if it is a relational field
property(obj, type=float, view_load=None, group_name=None, ...) [Dynamic attribute with specific
access rights]

obj : object (required)


type : type of equivalent field
Exercise 1 - Functional fields
Add a functional field to the Session class, that contains the percentage of taken seats in a
session. Display that percentage in the session tree and form views. Once it is done, try to
display it under the form of a progressbar.

6.2 Onchange
<!-- on_change example in xml -->
<field name="amount" on_change="onchange_price(unit_price,amount)" /> <field
name="unit_price" on_change="onchange_price(unit_price,amount)" /> <field name="price" />

def onchange_price(self, cr, uid, ids, unit_price, amount, context=None):


""" change the price when the unit price or the amount is changed """
return { value : {price : unit_price * amount}}

Exercise 2 - Onchange methods


Modify the Session form view and the Session class in such a way that the percentage of taken
seats refreshes whenever the number of available seats or the number of attendees changes,
without having to save the modifications.

Exercise 3 - warning
Modify this onchange function to raise a warning when the number of seats is under zero.

14

6.3 Predefined osv.Model attributes for business objects


_constraints
_sql_constraints

list of tuples defining the Python constraints, in the form (func_name, message,
fields).
list of tuples defining the SQL constraints, in the form (name, sql_def, message).

Exercise 4 - Add constraints


Add a constraint which checks that the course description and the course title are not the same.

Exercise 5 - Add an sql constraint


Add an sql constraint to check that a Course has a unique name.

Exercise 6 - Add a duplicate option


Since we added a constraint for the Course name uniqueness, it is not possible to use the
duplicate function anymore (Form > Duplicate). Re-implement your own copy method which
allows to duplicate the Course object, changing the original name into Copy of [original name].

Exercise 7 - Active objects Default values


Define the start_date default value as today. Add a field active in the class Session, and set the
session as active by default. See the class attribute _defaults in the technical memento.

7 Advanced Views
7.1 List & Tree
Lists include field elements, are created with type tree, and have a <tree> parent element.
Attributes

Allowed elements

colors: list of colors mapped to Python conditions


editable: top or bottom to allow in-place edit
toolbar: set to True to display the top level of object hierarchies as a side toolbar
(example: the menu)
field, group, separator, tree, button, filter, newline

<tree string="Idea Categories" toolbar="1" colors="blue:state==draft"> <field name="name"/>


<field name="state"/>
</tree>

Exercise 1 - List coloring


Modify the Session tree view in such a way that sessions lasting less than 5 days are colored
blue, and the ones lasting more than 15 days are colored red.

15

Note:
duration field Beware! If the duration field is not declared in the view, the client will not be aware of
its existence. That would result in an error.

7.2 Calendars
Views used to display date fields as calendar events (<calendar> parent).
Attributes

Allowed elements

color: name of field for color segmentation


date_start: name of field containing event start date/time
date_stop: name of field containing event stop date/time OR
day_length: length of a calendar day in hours (default: 8)
date_delay: name of field containing event duration
field (to define the label for each calendar event)

<calendar string="Ideas" date_start="invent_date" color="inventor_id"> <field


name="name"/>
</calendar>

Exercise 2 - Calendar view


Add a Calendar view to the Session object enabling the user to view the events associated to
the Open Academy.

7.3 Search Views


Search views are used to customize the search panel on top of list views, and are declared with the
search type, and a top-level <search> element. After defining a search view with a unique id, add it to
the action opening the list view using the search_view_id field in its declaration.
Allowed elements

field, group, separator, label, search, filter, newline, properties


filter elements allow defining button for domain filters
adding a context attribute to fields makes widgets that alter the search context
(useful for context-sensitive fields, e.g. pricelist-dependent prices)

<search string="Ideas">
<filter name="my_ideas" domain="[(inventor_id,=,uid)]" string="My Ideas"
icon="terp-partner"/>
<field name="name"/> <field
name="description"/> <field
name="inventor_id"/>
<field name="country_id" widget="selection"/>
</search>

16

The action record that opens such a view may initialize search fields by its field context. The value of
the field context is a Python dictionary that can modify the clients behavior. The keys of the dictionary
are given a meaning depending on the following convention.

The key default_foo initializes the field foo to the corresponding value in the form view.
The key search_default_foo initializes the field foo to the corresponding value in the search
view. Note that filter elements are like boolean fields.
Exercise 3 - Search views
Add a search view containing: 1) a field to search the courses based on their title and 2) a button to
filter the courses of which the current user is the responsible. Make the latter selected by default.

7.4 Gantt Charts


Bar chart typically used to show project schedule (<gantt> parent element).
Attributes
Allowed elements

same as <calendar>
field, level
level elements are used to define the Gantt chart levels, with the enclosed
field used as label for that drill-down level

<gantt string="Ideas" date_start="invent_date" color="inventor_id"> <level


object="idea.idea" link="id" domain="[]">
<field name="inventor_id"/>
</level>
</gantt>

Exercise 4 - Gantt charts


Add a Gantt Chart enabling the user to view the sessions scheduling linked to the Open
Academy module. The sessions should be grouped by instructor.

17

7.5 (Charts) Graphs


Views used to display statistical charts (<graph> parent element).

Attribut
es

Allowed
element
s

type: type of chart: bar, pie (default)


orientation: horizontal, vertical
field, with specific behavior:
first field in view is X axis, 2nd
one is Y, 3rd one is Z
2 fields required, 3rd one is
optional
group attribute defines the
GROUP BY field (set to 1)
operator attribute sets the
aggregation operator to use for
other fields when one field is
grouped (+,*,**,min,max)

<graph
strin
g="
Tota
l
idea
scor
e by
Inve
ntor
"
type
="b
ar">
<fie
ld
na
me
="in
vent
or_i
d" /
>
<field name="score" operator="+"/>
</graph>

Exercise 5 - Graph view


Add a Graph view that displays, for
each course, the number of
attendees under the form of a bar
chart. You can create it either for the
Course object or for the Session
object.

7.6 Kanban Boards


Those views are available since OpenERP
6.1, and may be used to organize tasks,
production processes, etc. A kanban view
presents a set of columns of cards; each
card represents a record, and columns

represent the values of a given field. For


instance, project tasks may be organized
by stage (each column is a stage), or by
responsible (each column is a user), and
so on.
The following example is a simplification of
the Kanban view of leads. The view is
defined with qweb templates, and can mix
form elements with HTML elements.
<record
model="ir.ui.v
iew"
id="view_ope
nacad_sessio
n_kanban">
<field
name="name
">openacad.s
ession.kanba
n</field>
<
f
i
e
l
d
n
a
m
e
=
"
m
o
d
e
l
"
>
o
p
e
n
a
c
a
d
e
m
y
.
s
e
s
s
i
o
n
<
/
f
i
e
l
d
>

<
f
i
e
l
d
n
a
m
e
=
"
t
y
p
e
"
>
k
a
n
b
a
n
<
/
f
i
e
l
d
>
<field name="arch" type="xml">
<k
a
n
b
a
n
d
e
f
a
u
l
t
_
g
r
o
u
p
_
b
y
=
"
c
o
u
r
s
e
_
i
d

"
>
<
f
i
e
l
d
n
a
m
e
=
"
c
o
l
o
r
"
/
>
<templates>
<t t-name="kanban-box">
<div t-attfclass="oe_kanban_color_#{kanban_getcolor(rec
ord.color.raw_value)} oe_kanban <div
class="oe_dropdown_kanban">
<!-- dropdown menu -->
<d
i
v
c
l
a
s
s
=
"
o
e
_
d
r
o
p
d
o
w
n
_
t
o
g
g
l
e
"
>
<
s
p
a
n

c
l
a
s
s
=
"
o
e
_
e
"
>

<
/
s
p
a
n
>
<
u
l
c
l
a
s
s
=
"
o
e
_
d
r
o
p
d
o
w
n
_
m
e
n
u
"
>
<li><a type="delete">Delete</a></li>
<li><ul class="oe_kanban_colorpicker"
data-field="color"/></li>
</ul>
</div>
<div class="oe_clear"></div>
</div>

18

<div t-attf-class="oe_kanban_content">
<!-- title -->
Session name : <field name="name"/> <br/> Start date :
<field name="start_date"/> <br/> duration : <field
name="duration"/>
</div>
</t>
</templates>
</kanban>
</field>
</record>

Exercise 6 - Kanban view


Add a Kanban view that displays sessions grouped by course (columns are thus courses).

8 Workflows
Workflows are models associated to business objects describing their dynamics. Workflows are also
used to track processes that evolve over time.
Exercise 1 - Static Workflow
Add a state field that will be used for defining a workflow on the object Session. A session can
have three possible states: Draft (default), Confirmed and Done. In the session form, add a
(read-only) field to visualize the state, and buttons to change it. The valid transitions are:
Draft ! Confirmed

Confirmed ! Draft
Confirmed ! Done
Done ! Draft
A sales order generates an invoice and a shipping order is an example of workflow used in OpenERP.

Workflows may be associated with any object in OpenERP, and are entirely customizable. Workflows are
used to structure and manage the lifecycles of business objects and documents, and define transitions,
triggers, etc. with graphical tools. Workflows, activities (nodes or actions) and transitions (conditions) are
declared as XML records, as usual. The tokens that navigate in workflows are called workitems.

19

Exercise 2 - Dynamic workflow editor


Using the workflow editor, create the same workflow as the one defined earlier for the Session
object. Trans-form the Session form view such that the buttons change the state in the workflow.
Note:
A workflow associated to a session is created during the creation of that session. There is therefore
no workflow instance associated to session instances created before the definition of the workflow.

Exercise 3 - Automatic transitions


Add a transition Draft !Confirmed that is triggered automatically when the number of attendees in
a session is more than half the number of seats of that session.

Exercise 4 - XML workflows


Install the module base_module_record. Use it to export the workflow created in the workflow
editor into an XML file, that you can incorporate in your module.

Exercise 5 - Server actions


Create server actions and modify the previous workflow in order to re-create the same behaviour
as previ-ously, but without using the Python methods of the Session class.

9 Security
Access control mechanisms must be configured to achieve a coherent security policy.

9.1 Group-based access control mechanisms


Groups are created as normal records on the model res.groups, and granted menu access via menu definitions.
However even without a menu, objects may still be accessible indirectly, so actual object-level permissions (read,
write, create, unlink) must be defined for groups. They are usually inserted via CSV files inside modules. It is also
possible to restrict access to specific fields on a view or object using the fields groups attribute.

9.2 Access rights


Access rights are defined as records of the model ir.model.access. Each access right is associated to a
model, a group (or no group for global access), and a set of permissions: read, write, create, unlink. Such
access rights are usually created by a CSV file named after its model: ir.model.access.csv.
id,name,model_id/id,group_id/id,perm_read,perm_write,perm_create,perm_unlink
access_idea_idea,idea.idea,model_idea_idea,base.group_user,1,1,1,0
access_idea_vote,idea.vote,model_idea_vote,base.group_user,1,1,1,0

Exercise 1 - Add access control through the OpenERP interface


Create a new user John Smith. Then create a group OpenAcademy / Session Read with read
access to the Session and Attendee objects.

20

Exercise 2 - Add access control through data files in your module


Using an XML data file, create a group OpenAcademy / Manager, with no access rights defined
yet (just create an empty group).

Exercise 3 - Add access control through data files in your module


Use a CSV file to add read, write, creation and deletion rights on the objects Course, Session
and Attendees to the group OpenAcademy / Manager. You can also create rights associated to
no group, such as a read only access on Course and a read only access on Session.

9.3 Record rules


A record rule restricts the access rights to a subset of records of the given model. A rule is a record of the
model ir.rule, and is associated to a model, a number of groups (many2many field), permissions to which
the restriction applies, and a domain. The domain specifies to which records the access rights are limited.

Here is an example of a rule that prevents the deletion of leads that are not in state cancel. Notice
that the value of the field groups must follow the same convention as the method write of the ORM.
<record id="delete_cancelled_only" model="ir.rule">
<field name="name">Only cancelled leads may be deleted</field> <field
name="model_id" ref="crm.model_crm_lead"/>
<field name="groups" eval="[(4, ref(base.group_sale_manager))]"/> <field
name="perm_read" eval="0"/>
<field name="perm_write" eval="0"/> <field
name="perm_create" eval="0"/> <field
name="perm_unlink" eval="1" />
<field name="domain_force">[(state,=,cancel)]</field>
</record>

Exercise 4 - Record rule


Add a record rule for the model Course and the group OpenAcademy / Manager, that restricts
write and unlink accesses to the responsible of a course. If a course has no responsible, all
users of the group must be able to modify it.

10 Wizards
10.1 Wizard objects (osv.TransientModel)
Wizards describe stateful interactive sessions with the user (or dialog boxes) through dynamic forms.
A wizard is built simply by defining a model that extends the class osv.TransientModel instead of
osv.Model. The class osv.TransientModel extends osv.Model and reuse all its existing
mechanisms, with the following particulari-ties:

Wizard records are not meant to be persistent; they are automatically deleted from the database
after a certain time. This is why they are called transient.

Wizard models do not require explicit access rights: users have all permissions on wizard records.

Wizard records may refer to regular records or wizard records through many2one fields, but
regular records cannot refer to wizard records through a many2one field.

21

We want to create a wizard that allow users to create attendees for a particular session, or for a list of
sessions at once. In a first step, the wizard will work for a single session.
Exercise 1 - Define the wizard class
Create a wizard model (inheriting from osv.TransientModel) with a many2one relationship with
the Session object and a one2many relationship with an Attendee object (wizard object, too). The
new Attendee object has a name field and a many2one relationship with the Partner object.
Define the class CreateAttendeeWizard and implement its structure.

10.2 Wizard execution


Wizards are launched by ir.actions.act_window records, with the field target set to value new. The
latter opens the wizard view into a popup window. The action is triggered by a menu item.
There is another way to launch the wizard: using an ir.actions.act_window record like above, but with
an extra field src_model that specifies in the context of which model the action is available. The
wizard will appear in the contextual actions of the model, on the right-hand side bar. Because of some
internal hooks in the ORM, such an action is declared in XML with the tag act_window.
<act_window id="session_create_attendee_wizard"
name="Add Attendees"
src_model="context_model_name"
res_model="wizard_model_name" view_mode="form"
target="new"
key2="client_action_multi"/>

Note:
The field key2 defines a kind of action category. Its possible values are: client_action_multi (typically for
wizards), client_print_multi (typically for reports), and client_action_relate (typically for related views).

Exercise 2 - Make the wizard available through a menuitem


Create a menuitem and the necessary action to use the wizard.

10.3 Wizard views


Wizards use regular views and their buttons may use the attribute special=cancel to close the wizard
window without saving.
<button string="Do it!" type="object" name="some_action"/> <button
string="Cancel" special="cancel"/>

Exercise 3 - Customise the form view


Customise the form view in order to show all the fields of the class.

Exercise 4 - Create methods


Create the method action_add_attendee in your class CreateAttendeeWizard, implement it, and
add a button in the form view to call it. Add also a button Cancel that closes the wizard window.

22

Exercise 5 - Bind the wizard to the context bar


Bind the wizard to the context bar of the session model.
Hint: use the argument context to define the current session as default value for the field
session_id in the wizard.

Extra Exercise - Wizard on multiple records


Make the wizard able to add attendees to several sessions at once.

11 Internationalization
Each module can provide its own translations within the i18n directory, by having files named
LANG.po where LANG is the locale code for the language, or the language and country combination
when they differ (e.g. pt.po or pt_BR.po). Translations will be loaded automatically by OpenERP for all
enabled languages. Developers always use English when creating a module, then export the module
terms using OpenERPs gettext POT export feature (Settings>Translations>Export a Translation File
without specifying a language), to create the module template POT file, and then derive the translated
PO files. Many IDEs have plugins or modes for editing and merging PO/POT files.
Tip:
The GNU gettext format (Portable Object) used by OpenERP is integrated into LaunchPad, making it
an online collaborative translation platform.
|- idea/
# The module directory
|- i18n/
# Translation
files
| - idea.pot #
Translation
Template (exported from OpenERP)
| - fr.po
# French translation
| - pt_BR.po # Brazilian Portuguese translation
| (...)

Tip:
By default OpenERPs POT export only extracts labels inside XML files or inside field definitions in
Python code, but any Python string can be translated this way by surrounding it with the
tools.translate._ method (e.g. _(Label) )

Exercise 1 - Translate a module


Choose a second language for your OpenERP installation. Translate your module using the
facilities pro-vided by OpenERP.

12 Reporting
12.1 Printed reports
Reports in OpenERP can be rendered in different ways:

Custom reports: those reports can be directly created via the client interface, no programming
required. Those reports are represented by business objects (ir.report.custom)

23

High quality personalized reports using openreport: no programming required but you have to
write 2 small XML files:
a template which indicates the data you plan to report
an XSL : RML stylesheet

High quality reports using the WebKit engine: based on Mako HTML templates (
http://www.makotemplates.org) and a tool to convert the result to PDF (wkthtmltopdf). This
report-ing engine is a contribution from Camptocamp ( http://www.camptocamp.com).

Hard coded reports


OpenOffice Writer templates
There are several report engines in OpenERP, to produce reports from different sources and in many formats.

Expressions used in OpenERP report templates


[[ <content> ]] double brackets content is evaluated as a Python expression based on the following expressions

Predefined expressions :

objects contains the list of records to print


data comes from the wizard launching the report
user contains the current user (as per browse())
time gives access to Python time module
repeatIn(list,var,tag) repeats the current parent element named tag for each object in list,
making the object available as var during each loop

setTag(tag1,tag2) replaces the parent RML tag1 with tag2


removeParentNode(tag) removes parent RML element tag
formatLang(value, digits=2, date=False, date_time=False, grouping=True, monetary=False) can
be used to format a date, time or amount according to the locale

setLang(lang_code) sets the current language and locale for translations


RML Reports

Exercise 1 - Install the OpenOffice plugin


Install the report designer module and add the OpenOffice OpenERP plugin.

24

Exercise 2 - Create a new report


Create a report for the Session object, displaying for each session its name, date, duration,
percentage of completion, responsible name and list of attendees.

Exercise 3 - RML
Export the OpenOffice report to a RML file, add it to your module and add an action to the
session object for printing the report.

Exercise 4 - RML
Improve your report. Prevent the start date line from appearing in the report if no value is
associated to it, and display the percentage of taken seats in red if it is lower than 10.

WebKit reports
To generate such reports, install the module report_webkit. A report is made from a Mako template
file, and the report action is declared in XML as
<report string="WebKit invoice"
id="report_webkit_html"
model="account.invoice"
name="webkitaccount.invoice"
file="report_webkit_sample/report/report_webkit_html.mako"
webkit_header="report_webkit.ir_header_webkit_basesample0"
report_type="webkit"
auto="False"/>

This example is taken from the module report_webkit_sample. Open and read the file report/report_webkit_html.mako in that module to see what a Mako template looks like.
Exercise 5 - Create a WebKit report
Create a report for the Session object, displaying for each session its name, date, duration,
percentage of completion, responsible name and list of attendees.

12.2 Dashboards
Exercise 6 - 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.

13 WebServices
The web-service module offer a common interface for all web-services :
SOAP

25

XML-RPC
NET-RPC
Business objects can also be accessed via the distributed object mechanism. They can all be
modified via the client interface with contextual views.
OpenERP is accessible through XML-RPC interfaces, for which libraries exist in many languages.

13.1 XML-RPC Library


The following example is a Python program that interacts with an OpenERP server with the library xmlrpclib.
import xmlrpclib
# ... define HOST, PORT, DB, USER, PASS
url = http://%s:%d/xmlrpc/common % (HOST,PORT) sock =
xmlrpclib.ServerProxy(url)
uid = sock.login(DB,USER,PASS)
print "Logged in as %s (uid:%d)" % (USER,uid)
# Create a new idea
url = http://%s:%d/xmlrpc/object % (HOST,PORT) sock =
xmlrpclib.ServerProxy(url)
args = {
name : Another idea,
description : This is another idea of mine, inventor_id: uid,
}
idea_id = sock.execute(DB,uid,PASS,idea.idea,create,args)

Exercise 1 - Add a new service to the client


Write a Python program able to send XML-RPC requests to a PC running OpenERP (yours, or
your instruc-tors). This program should display all the sessions, and their corresponding number
of seats. It should also create a new session for one of the courses.

13.2 OpenERP Client Library


The OpenERP Client Library ( http://pypi.python.org/pypi/openerp-client-lib) is a Python library to
communicate with an OpenERP server using its web services in an user-friendly way. It provides
simple wrapper objects to abstract the bare XML-RPC calls.
If necessary, install the library:
$ sudo easy_install openerp-client-lib

The following Python program is equivalent to the example above.


import openerplib
# ... define HOST, PORT, DB, USER, PASS
connection = openerplib.get_connection(hostname=HOST, port=PORT, database=DB, login=USER,
password=PASS)
connection.check_login()
print "Logged in as %s (uid:%d)" % (connection.login, connection.user_id)
# create an idea
idea_model = connection.get_model(idea.idea) values = {
name: Another idea,
description: This is another idea of mine,

26

inventor_id: connection.user_id,
}
idea_id = idea_model.create(values)

Exercise 2 - Add a new service to the client


Do the same as Exercise 1, but this time using openerplib.

27

You might also like