Openerp Technical Training v7 Exercises
Openerp Technical Training v7 Exercises
Openerp Technical Training v7 Exercises
Release 7.0
OpenERP
2013-01-21
Contents
1 Conguration 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 12 12 12 12
Build an OpenERP module 2.1 Composition of a module . . . . . . . . . . . . . . . . . . . . . . . 2.2 Module Structure . . . . . . . . . . . . . . . . . . . . . . . . . . . 2.3 Object Service - ORM . . . . . . . . . . . . . . . . . . . . . . . . Predened osv.Model attributes for business objects . . . . . . . . . 2.4 ORM eld types . . . . . . . . . . . . . . . . . . . . . . . . . . . . Common attributes supported by all elds (optional unless specied) Simple elds . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2.5 Special/Reserved eld names . . . . . . . . . . . . . . . . . . . . . 2.6 Actions and Menus . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
Building views: basics 3.1 Generic view declaration . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3.2 Tree views . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3.3 Form views . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Relations between Objects 4.1 Relational elds . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Inheritance 5.1 Inheritance mechanisms . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Predened osv.Model attributes for business objects . . . . . . . . . . . . . . . . . . . . . . . . . 5.2 View inheritance . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Domains . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6 ORM Methods 6.1 Functional elds . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6.2 Onchange . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6.3 Predened osv.Model attributes for business objects . . . . . . . . . . . . . . . . . . . . . . . . . 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 Workows Security 9.1 Group-based access control mechanisms . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9.2 Access rights . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9.3 Record rules . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
13 13 13 14 15 15 15 16 16 17 18 18 19 20 20 20 21 21 21 22 22 23 23 23 24 24 25 25 25 26 26
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
8 9
10 Wizards 10.1 Wizard objects (osv.TransientModel) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10.2 Wizard execution . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10.3 Wizard views . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11 Internationalization 12 Reporting 12.1 Printed reports . . . . . . . . . . . . . . . . . . Expressions used in OpenERP report templates RML Reports . . . . . . . . . . . . . . . . . . WebKit reports . . . . . . . . . . . . . . . . . 12.2 Dashboards . . . . . . . . . . . . . . . . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
Based on a real case, this chapter covers: building an OpenERP module and its interface, Views, Reports, Workows, Security aspects, Wizards, WebServices, Internationalization, Rapid Application Development (RAD) and Performance Optimization.
1 Conguration
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 ObjectRelationship 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 conguration. OpenERP provides a web interface accessible using any modern browser.
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 les with meta-data (views and workows declaration), conguration 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 OpenOfce report templates, to be merged with any kind of business data, and generate HTML, ODT or PDF reports.
import mymodule
The __openerp__.py le 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 les (xml, csv, yml...) of the module. Its general structure is the following (see ofcial documentation for a full le 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 le. Install it under OpenERP.
Common attributes supported by all elds (optional unless specied) 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 ltering (with database index) business object name, in dot-notation (in module namespace) context : Dictionary with contextual parameters (for relational elds) Simple elds boolean(...) integer(...) date(...) datetime(...) time(...) start_date: elds.date(Start Date) active: elds.boolean(Active) priority: elds.integer(Priority) char(string,size,translate=False,..) text(string, translate=False,...) [Text-based elds] translate: True if eld values can be translated by users size: maximum size for char elds (41,45) oat(string, digits=None, ...) [Floating-point value with arbitrary precision and scale] digits: tuple (precision, scale) (58) . If digits is not provided, its a oat, not a decimal type.
The following example denes 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 elds 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 le. This is because the record action_id must exist in the database to allow the ORM to create the menu record.
Exercise 3 - Dene new menu entries Dene 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.
Notice that the content of the view is itself dened as XML. Hence, the eld arch of the record must be declared of type XML, in order to parse the content of that element as the elds 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 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 eld under a tab, such that it will be easier to add other tabs later, containing additional information.
obj: _name of destination object (required) ondelete: deletion handling: set null, cascade, restrict (see PostgreSQL documentation). one2many(obj, eld_id, ...) : virtual relationship towards multiple objects (inverse of many2one). A one2many relational eld 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
eld_id: eld name of inverse many2one, i.e., corresponding foreign key (required) many2many(obj, rel, eld1, eld2, ...) : 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 eld1: name of eld in rel table storing the id of the current object eld2: name of eld in rel table storing the id of the target object Note that the parameters rel, eld1 and eld2 are optional. When they are not given, the ORM automatically generates suitable values for them. Exercise 2 - Relations many2one Using a many2one relational eld, modify the classes Course, Session and Attendee to reect their relations with other objects, dened as follows.
Exercise 3 - Inverse relation one2many Using the inverse relational eld one2many, modify the classes Course, Session and Attendee to reect their relations with other objects, dened 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 elds 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
Predened 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 elds to use
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 modies the existing Partner class, adding a is_instructor boolean eld, and the list of the sessions this partner will attend to. Using views inheritance, modify the existing partners form view to display the new elds.
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 eld 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 prex 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 eld 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 dened in the previous exercise to allow the user to choose the instructor among the partners the Instructor eld of which is set to True or those who are in one of the categories we dened.
6 ORM Methods
6.1 Functional elds
function(fnct, arg=None, fnct_inv=None, fnct_inv_arg=None, type=oat, fnct_search=None, obj=None, store=False, multi=False, ...) : Functional eld simulating a real eld, computed rather than stored fnct [function to compute the eld value (required)] def fnct(self, cr, uid, ids, eld_name, arg, context) returns a dictionary { idsvalues } with values of type type fnct_inv [function used to write a value in the eld instead]
13
def fnct_inv(obj, cr, uid, id, name, value, fnct_inv_arg, context) type : type of simulated eld (any other type besides function) obj : model _name of simulated eld if it is a relational eld fnct_search [function used to search on this eld] 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=oat, ...) [Shortcut eld equivalent to browsing chained elds] f1,f2,... : chained elds to reach target (f1 required) type : type of target eld obj : model _name of target eld if it is a relational eld property(obj, type=oat, view_load=None, group_name=None, ...) [Dynamic attribute with specic access rights] obj : object (required) type : type of equivalent eld Exercise 1 - Functional elds Add a functional eld 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 modications.
Exercise 3 - warning Modify this onchange function to raise a warning when the number of seats is under zero.
14
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 Dene the start_date default value as today. Add a eld 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 eld elements, are created with type tree, and have a <tree> parent element. Attributes 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) eld, group, separator, tree, button, lter, newline
Allowed elements
<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 eld Beware! If the duration eld 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 elds as calendar events (<calendar> parent). Attributes color: name of eld for color segmentation date_start: name of eld containing event start date/time date_stop: name of eld containing event stop date/time OR day_length: length of a calendar day in hours (default: 8) date_delay: name of eld containing event duration
Allowed elements
Exercise 2 - Calendar view Add a Calendar view to the Session object enabling the user to view the events associated to the Open Academy.
<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 elds by its eld context. The value of the eld 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 eld foo to the corresponding value in the form view. The key search_default_foo initializes the eld foo to the corresponding value in the search view. Note that lter elements are like boolean elds. Exercise 3 - Search views Add a search view containing: 1) a eld to search the courses based on their title and 2) a button to lter the courses of which the current user is the responsible. Make the latter selected by default.
<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
Allowed elements
<graph string="Total idea score by Inventor" type="bar"> <field name="inventor_id" /> <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.
<record model="ir.ui.view" id="view_openacad_session_kanban"> <field name="name">openacad.session.kanban</field> <field name="model">openacademy.session</field> <field name="type">kanban</field> <field name="arch" type="xml"> <kanban default_group_by="course_id"> <field name="color"/> <templates> <t t-name="kanban-box"> <div t-attf-class="oe_kanban_color_#{kanban_getcolor(record.color.raw_value)} oe_kanban_ <div class="oe_dropdown_kanban"> <!-- dropdown menu --> <div class="oe_dropdown_toggle"> <span class="oe_e"></span> <ul class="oe_dropdown_menu"> <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 Workows
Workows are models associated to business objects describing their dynamics. Workows are also used to track processes that evolve over time. Exercise 1 - Static Workow Add a state eld that will be used for dening a workow on the object Session. A session can have three possible states: Draft (default), Conrmed and Done. In the session form, add a (read-only) eld to visualize the state, and buttons to change it. The valid transitions are: Draft Conrmed Conrmed Draft Conrmed Done Done Draft A sales order generates an invoice and a shipping order is an example of workow used in OpenERP.
Workows may be associated with any object in OpenERP, and are entirely customizable. Workows are used to structure and manage the lifecycles of business objects and documents, and dene transitions, triggers, etc. with graphical tools. Workows, activities (nodes or actions) and transitions (conditions) are declared as XML records, as usual. The tokens that navigate in workows are called workitems.
19
Exercise 2 - Dynamic workow editor Using the workow editor, create the same workow as the one dened earlier for the Session object. Transform the Session form view such that the buttons change the state in the workow. Note: A workow associated to a session is created during the creation of that session. There is therefore no workow instance associated to session instances created before the denition of the workow.
Exercise 3 - Automatic transitions Add a transition Draft Conrmed 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 workows Install the module base_module_record. Use it to export the workow created in the workow editor into an XML le, that you can incorporate in your module.
Exercise 5 - Server actions Create server actions and modify the previous workow in order to re-create the same behaviour as previously, but without using the Python methods of the Session class.
9 Security
Access control mechanisms must be congured to achieve a coherent security policy.
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 les in your module Using an XML data le, create a group OpenAcademy / Manager, with no access rights dened yet (just create an empty group).
Exercise 3 - Add access control through data les in your module Use a CSV le 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.
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 dening 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 particularities: 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 elds, but regular records cannot refer to wizard records through a many2one eld.
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 rst step, the wizard will work for a single session. Exercise 1 - Dene 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 eld and a many2one relationship with the Partner object. Dene the class CreateAttendeeWizard and implement its structure.
Note: The eld key2 denes 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.
Exercise 3 - Customise the form view Customise the form view in order to show all the elds 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 dene the current session as default value for the eld 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 les 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 le, and then derive the translated PO les. Many IDEs have plugins or modes for editing and merging PO/POT les. Tip: The GNU gettext format (Portable Object) used by OpenERP is integrated into LaunchPad, making it an online collaborative translation platform.
# # # # #
The module directory Translation files Translation Template (exported from OpenERP) French translation Brazilian Portuguese translation
Tip: By default OpenERPs POT export only extracts labels inside XML les or inside eld denitions 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 provided 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 les: 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 reporting engine is a contribution from Camptocamp (http://www.camptocamp.com). Hard coded reports OpenOfce 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
Predened 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 OpenOfce plugin Install the report designer module and add the OpenOfce 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 OpenOfce report to a RML le, 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 le, 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 le 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 - Dene a Dashboard Dene 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 modied via the client interface with contextual views. OpenERP is accessible through XML-RPC interfaces, for which libraries exist in many languages.
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 instructors). 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.
26
Exercise 2 - Add a new service to the client Do the same as Exercise 1, but this time using openerplib.
27