Technical Training v7 Exercises
Technical Training v7 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
5
5
5
6
6
6
7
7
7
7
8
8
9
9
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
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.
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
bzr
./bzr_set.py
# install bazaar
version
# retrieve source installer
# fetch code and
perform
control
setup
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.
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,
}
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.
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.
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.
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 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.
many2one(obj, ondelete=set null,...) : simple relationship towards another object (using a foreign key)
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.
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.
11
5 Inheritance
5.1 Inheritance mechanisms
position
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>
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
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" />
Exercise 3 - warning
Modify this onchange function to raise a warning when the number of seats is under zero.
14
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).
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
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
<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.
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
17
Attribut
es
Allowed
element
s
<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>
<
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>
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
9 Security
Access control mechanisms must be configured to achieve a coherent security policy.
20
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>
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.
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).
22
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) )
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).
Predefined expressions :
24
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.
26
inventor_id: connection.user_id,
}
idea_id = idea_model.create(values)
27