You are on page 1of 18

Open Source RAD with OpenObject

PREAMBLE OpenERP is a modern Enterprise Management Software, released under the AGPL license, and featuring CRM,
HR, Sales, Accounting, Manufacturing, n!entor", Pro#ect Management, $$$ t is %ased on OpenObject, a modular,
scala%le, and intuiti!e Rapid Application Development (RAD) framewor& written in P"thon$
OpenObject features a complete and modular tool%o' for (uic&l" %uilding applications) integrated Object-
Relationship Mapping (ORM) support, template*%ased Model-View-Controller (MVC) interfaces, a report generation
s"stem, automated internationali+ation, and much more$
Python is a high*le!el d"namic programming language, ideal for RAD, com%ining power with clear s"nta', and a core
&ept small %" design$
Tip: Useful links
Main we%site, with ,penERP downloads) www$openerp$com
-unctional . technical documentation) doc$openerp$com
Communit" resources) www$launchpad$net/openo%#ect
ntegration ser!er) test$openo%#ect$com
Learning P"thon) doc$p"thon$org
,penERP E*Learning platform) edu$openerp$com
Installing OpenERP
,penERP is distri%uted as pac&ages/installers for most platforms, %ut can of course %e installed from the source on
an" platform$
OpenERP Architecture
,penERP uses the well*&nown client*ser!er paradigm, with different pieces of software acting as client and ser!er
depending on the desired configuration$Client software
,penERP pro!ides a thic& des&top client 0G1234 on all platforms, and a we% interface is also accessi%le using an"
modern %rowser$
Tip: Installation procedure
1he procedure for installing ,penERP is li&el" to e!ol!e 0dependencies and so on4, so ma&e sure to alwa"s chec& the
specific documentation 0pac&aged . on we%site4 for the latest procedures$ See http)//doc$openerp$com/install
Package installation
5indows all*in*one installer, and separate installers for ser!er, client, and we%ser!er are on the we%site
Linu'
openerp-server and openerp-client pac&ages are a!aila%le !ia corresponding pac&age manager
0e$g$ S"naptic on 6%untu4
Mac
loo& online for pac&age installers for the G12 client, as well as tutorials for installing the ser!er 0e$g$
de!team$ta&ti&$%e4
Installing from source
1here are two alternati!es) using a tar%all pro!ided on the we%site, or directl" getting the source using Ba+aar
0distri%uted Source 7ersion Control4$ 8ou also need to install the re(uired dependencies 0PostgreS9L and a few P"thon
li%raries : see documentation on doc$openerp$com4$
Compilation tip: ,penERP %eing P"thon*%ased, no compilation step is needed
Typical baaar checkout proce!ure "on Debian#base! $inu%&
$ sudo apt-get install bzr # install bazaar version control
$ bzr branch lp:openerp # retrieve source installer
$ cd openerp && python ./bzr_set.py # fetch code and perform setup
Database creation
After installation, run the ser!er and the client$ -rom the G12 client, use ile!Databases!"ew Database to create a
new data%ase 0default super admin password is admin4$ Each data%ase has its own modules and config, and demo
data can %e included$
'uil!ing an OpenERP mo!ule( i!ea
C,;1E<1 1he code samples used in this memento are ta&en from a h"pothetical idea module$ 1he purpose of this
module would %e to help creati!e minds, who often come up with ideas that cannot %e pursued immediatel", and are
too easil" forgotten if not logged somewhere$ t could %e used to record these ideas, sort them and rate them$
Copyright 2010 Open Object Press - All rights reserved See license on p. 18. 118
1
2
!
Note: Modular development
,pen,%#ect uses modules as feature containers, to foster maintaina%le and ro%ust de!elopment$ Modules pro!ide
feature isolation, an appropriate le!el of a%straction, and o%!ious M7C patterns$
)omposition of a mo!ule
A module ma" contain an" of the following elements)
business objects) declared as P"thon classes e'tending the osv.osv ,pen,%#ect class, the persistence of these
resources is completel" managed %" ,pen,%#ect =
data) <ML/CS7 files with meta*data 0!iews and wor&flows declaration4, configuration data 0modules
parametri+ation4 and demo data 0optional %ut recommended for testing, e$g$ sample ideas4 =
i!ards) stateful interacti!e forms used to assist users, often a!aila%le as conte'tual actions on resources =
reports) RML 0<ML format4, MA2, or ,pen,ffice report templates, to %e merged with an" &ind of %usiness data,
and generate H1ML, ,>1 or P>- reports$
Typical mo!ule structure
Each module is contained in its own director" within the server/bin/addons director" in the ser!er installation$
Note) 8ou can declare "our own add*ons director" in the configuration file of ,penERP 0passed to the ser!er with the
-c option4 using the addons_path option$
addons/
|- idea/ # he module directory
|- test/ # !nit testing data
|- i"#n/ # ranslation files
|- report/ # $eport definitions
|- security/ # %eclaration of groups and access rights
|- &izard/ # 'izards definitions
|- __init__.py # (ython pac)age initialization *re+uired,
|- __openerp__.py # module declaration *re+uired,
|- idea.py # (ython classes- the module.s ob/ects
|- installer.py # 0nstaller python declaration
|- idea_installer.1ml # 0nstaller 234 declaration
|- idea_vie&.1ml # 5ie&s *forms-lists,- menus and actions
|- idea_&or)flo&.1ml # 'or)flo& definitions
|- idea_demo.1ml # %emo data
|- idea_data.1ml # (opulation data
1he __init__.py file is the P"thon module descriptor, %ecause an ,penERP module is also a regular P"thon module$
**init**+py(
# 0mport all files & directories containing python code
import idea- &izard- report
1he __openerp__.py file 0ma" also %e named __terp__.py (deprecated44 is the ,penERP descriptor and contains a single
P"thon dictionar" with the actual declaration of the module) its name, dependencies, description, and composition$
**openerp**+py(
6
.name. : .0dea.-
.version. : .".7.-
.author. : .8pen9$(.-
.description. : .0deas management module.-
.category.: .9nterprise 0nnovation.-
.&ebsite.: .http://&&&.openerp.com.-
.depends. : :.base.;- # list of dependencies- conditioning startup order
.data. : : # data files to load at module init
.security/groups.1ml.- # al&ays load groups first<
.security/ir.model.access.csv.- # load access rights after groups
.idea_&or)flo&/&or)flo&.1ml.-
.idea_vie&/vie&s.1ml.-
.&izard/&izard.1ml.-
.report/report.1ml.-
;-
.demo.: :.idea_demo/demo.1ml.;- # demo data
.test.: :.test/test.1ml.;- # unit test data
.e1ternal_dependencies.: 6.python.::.ma)o.-.simple/son.;-
.bin.::.&hich.;= # e1ternal dependencies
.active.: >alse- # &hether to install automatically at ne& %? creation
.certificate.: 7"@ABCDE#F7"@- # certificate number
.installable.: rue-
=
Copyright 2010 Open Object Press - All rights reserved See license on p. 18. 218
"
#
$
%
8
&
10
11
12
1!
1"
1#
1$
1%
18
1&
20
21
22
2!
2"
2#
2$
2%
28
2&
!0
!1
!2
!!
!"
!#
!$
!%
!8
!&
"0
"1
"2
"!
""
"#
Object Ser,ice - OR.
2e" component of ,pen,%#ect, the ,%#ect Ser!ice 0,S74 implements a complete ,%#ect*Relational mapping la"er,
freeing de!elopers from ha!ing to write %asic S9L plum%ing$
Business o%#ects are declared as P"thon classes inheriting from the osv.osv class, which ma&es them part of the
,pen,%#ect Model, and magicall" persisted %" the ,RM la"er$Predefined attri%utes are used in the P"thon class to
specif" a %usiness o%#ect?s characteristics for the ,RM)
i!ea+py(
from osv import osv- fields
class idea idea*osv.osv,:
_name G .idea.idea.
_columns G 6
.name.: fields.char*.itle.- sizeGDB- re+uiredGrue- translateGrue,-
.state.: fields.selection*:*.draft.-.%raft.,-
*.confirmed.-.Honfirmed.,;-.Itate.-re+uiredGrue-readonlyGrue,-
# %escription is read-only &hen not draft<
.description.: fields.te1t*.%escription.- readonlyGrue-
statesG6.draft.: :*.readonly.- >alse,;= ,-
.active.: fields.boolean*.Jctive.,-
.invent_date.: fields.date*.0nvent date.,-
# by convention- many@one fields end &ith ._id.
.inventor_id.: fields.many@one*.res.partner.-.0nventor.,-
.inventor_country_id.: fields.related*.inventor_id.-.country.-
readonlyGrue- typeG.many@one.-
relationG.res.country.- stringG.Hountry.,-
# by convention- K@many fields end &ith ._ids.
.vote_ids.: fields.one@many*.idea.vote.-.idea_id.-.5otes.,-
.sponsor_ids.: fields.many@many*.res.partner.-.idea_sponsor_rel.-
.idea_id.-.sponsor_id.-.Iponsors.,-
.score.: fields.float*.Icore.-digitsG*@-",,-
.category_id. G many@one*.idea.category.- .Hategory.,-
=
_defaults G 6
.active.: "- # ideas are active by default
.state.: .draft.- # ideas are in draft state by default
=
def _chec)_name*self-cr-uid-ids,:
for idea in self.bro&se*cr- uid- ids,:
if .spam. in idea.name: return >alse # Han.t create ideas &ith spam<
return rue
_s+l_constraints G :*.name_uni+.-.uni+ue*name,.- .0dea must be uni+ue<.,;
_constraints G :*_chec)_name-.(lease avoid spam in ideas <.- :.name.;,;
idea*, # 0nstantiate the class
Pre!efine! os,+os, attributes for business objects
_name 're()ired* b)siness object n+,e- in dot-not+tion 'in ,od)le n+,esp+ce*
_columns 're()ired* diction+ry ./ield n+,es 0 object /ields decl+r+tions 1
_defaults diction+ry2 . /ield n+,es 0 de/+)lt v+l)es 1. A de/+)lt v+l)e c+n be + /)nction or + liter+l.
_defaults:.name.; G lambda self-cr-uid-conte1t: .eggs.
_auto i/ True 'de/+)lt* the O34 5ill cre+te the d+t+b+se t+ble set to False to cre+te yo)r o5n t+blevie5 5ithin
the init() ,ethod
_inherit _name o/ the p+rent b)siness object '/or prototype inherit+nce*
_inherits /or ,)ltiple instance inherit+nce ,ech+nis,2 diction+ry ,+pping the 6name o/ the p+rent b)siness objects
to the n+,es o/ the corresponding /oreign 7ey /ields to )se
_constraints list o/ t)ples de/ining the Python constr+ints- in the /or,
(func_name, message, fields). 'message ,+y be c+ll+ble* '0%0*
_sql_constraints list o/ t)ples de/ining the S89 constr+ints- in the /or,
(name, sql_def, message). 'message ,+y be c+ll+ble* '0$&*
_log_access :/ ;r)e 'de/+)lt*- " /ields 'cre+te6)id- cre+te6d+te- 5rite6)id- 5rite6d+te* 5ill be )sed to log record-level
oper+tions- ,+de +ccessible vi+ osv<s perm_read() /)nction
_order =+,e o/ the /ield )sed to sort the records in lists 'de/+)lt2 <id<*
_rec_name Altern+tive /ield to )se +s n+,e- )sed by osv<s name_get() 'de/+)lt2 <name'*
_sql S89 code to cre+te the t+blevie5 /or this object 'i/ _auto is >+lse* c+n be repl+ced by S89 e?ec)tion in
the init() ,ethod
_table S89 t+ble n+,e to )se 'de/+)lt2 _name 5ith dots <.< repl+ced by )nderscores <6<*
Copyright 2010 Open Object Press - All rights reserved See license on p. 18. !18
"$
"%
"8
"&
#0
#1
#2
#!
#"
##
#$
#%
#8
#&
$0
$1
$2
$!
$"
$#
$$
$%
$8
$&
%0
%1
%2
%!
%"
%#
%$
%%
%8
%&
80
Inheritance mechanisms
OR. fiel! types
,%#ects ma" contain @ t"pes of fields) simple, relational, and functional$ #imple t"pes are integers, floats, %ooleans,
strings, etc$ Relational fields represent the relationships %etween o%#ects 0oneAman", man"Aone, man"Aman"4$
$nctional fields are not stored in the data%ase %ut calculated on*the*fl" as P"thon functions$
Relevant e%amples in the idea class above are indicated with the corresponding line n$mbers (!&&,&&)
OR. fiel!s types
Common attributes supported by all fields (optional unless specified)
string: /ield l+bel (required)
required: True i/ ,+nd+tory
readonly: True i/ not edit+ble
help: help tooltip
select: True to opti,i@e /or list /iltering '5ith d+t+b+se
inde?*- to incl)de in se+rch vie5s
contet: diction+ry 5ith conte?t)+l p+r+,eters '/or rel+tion+l /ields*
change_default: ;r)e i/ /ield sho)ld be )s+ble +s condition /or de/+)lt v+l)es
in clients
states: dyn+,ic ch+nges to this /ield<s co,,on +ttrib)tes b+sed on the state
/ield '0"2-"$*
"imple fields
boolean(...) integer(...) !ate(...) !atetime(...) time(...) .active.: fields.boolean*.Jctive.,-
.priority.: fields.integer*.(riority.,-
.start_date.: fields.date*.Itart %ate.,-
char(string,si!e,translate"#alse,..) te%t(string,
translate"#alse, $)
Text-based fields
translate: True i/ /ield v+l)es c+n be tr+nsl+ted by )sers
si!e: ,+?i,), si@e /or char /ields '0"1-"#*
float(string, digits"%one, ...)
Floating-point value with arbitrary precision and scale
digits: t)ple 'precision- sc+le* '0#8* . :/ digits is not provided- it<s + /lo+t- not
+ deci,+l type.
selection(values, string, ...)
Field allowing selection among a set of predefined values
values: list o/ v+l)es '7ey-l+bel t)ples* or /)nction ret)rning s)ch + list
(required) '0"2*
binary(string, filters"%one, ...)
Field for storing a file or binary content.
filters: option+l /ilen+,e /ilters
.picture.: fields.binary*.(icture.-
filtersG.K.png-K.gif.,
reference(string, selection, si!e,..)
Field with dynamic relationship to any other object
associated with an assistant widget
selection: ,odel _name o/ +llo5ed objects types +nd corresponding l+bel
's+,e /or,+t +s values /or selection /ields* (required)
si!e: si@e o/ te?t col),n )sed to store it '+s te?t2 <model_name,ob&ect_id'*
(required)
.contact.: fields.reference*.Hontact.-:
*.res.partner.-.(artner.,-
*.res.partner.contact.-.Hontact.,;- "@#,
Relational fields
Common attributes supported by relational fields domain: option+l restriction in the /or, o/ +rg),ents /or se+rch 'see
search'**
many/one(ob&, ondelete"'set null', $) '0#0*
!elationship towards a parent object (using a foreign "ey)
ob&: _name o/ destin+tion object (required)
ondelete: deletion h+ndling- e.g. <set null<- <cascade<- see PostgreS89
doc),ent+tion
one/many(ob&, field_id, $) '0##*
#irtual relationship towards multiple objects (inverse of
many$one)
ob&: _name o/ destin+tion object (required)
field_id: /ield n+,e o/ inverse ,+ny2one- i.e. corresponding /oreign 7ey
(required)
many/many(ob&, rel, field', field(, $) '0#$*
%idirectional multiple relationship between objects
ob&: _name o/ destin+tion object (required)
rel2 rel+tionship t+ble to )se (required)
field': n+,e o/ /ield in rel t+ble storing the id o/ the c)rrent object (required)
field(: n+,e o/ /ield in rel t+ble storing the id o/ the t+rget object (required)
Copyright 2010 Open Object Press - All rights reserved See license on p. 18. "18
OR. fiel!s types
#unctional fields
function(fnct, arg"%one, fnct_inv"%one, fnct_inv_arg"%one, type"'float', fnct_search"%one, ob&"%one, method"#alse,
store"#alse, multi"#alse,$)
Functional field simulating a real field computed rather than stored
fnct: /)nction to co,p)te the /ield v+l)e (required)
def fnct(self, cr, uid, ids, field_name, arg, contet)
ret)rns + diction+ry ) ids*values + 5ith v+l)es o/ type type
fnct_inv: /)nction )sed to 5rite + v+l)e in the /ield inste+d
def fnct_inv(ob&, cr, uid, id, name, value, fnct_inv_arg, contet)
type: type o/ si,)l+ted /ield '+ny other type besides </)nction<*
fnct_search: /)nction )sed to se+rch on this /ield
def fnct_search(ob&, cr, uid, ob&, name, args)
ret)rns + list o/ t)ples +rg),ents /or search()- e.g. ,('id','in',,',-,./)/
ob&2 ,odel _name o/ si,)l+ted /ield i/ it is + rel+tion+l /ield
store, multi2 opti,i@+tion ,ech+nis,s 'see )s+ge in Per/or,+nce Section*
relate!(f', f(, $, type"'float', $) &hortcut field e'uivalent to browsing chained fields
f',f(,...: ch+ined /ields to re+ch t+rget (f1 required) '0#1*
type2 type o/ t+rget /ield
property(ob&, type"'float', vie0_load"%one, group_name"%one, $)
(ynamic attribute with specific access rights
ob&: object (required)
type2 type o/ e()iv+lent /ield

Tip: relational fields s$mmetr$
oneAman" B man"Aone are s"mmetric
man"Aman" B man"Aman" are s"mmetric when in!ersed 0swap field' and field()
oneAman" B man"Aone 3 man"Aone B oneAman" C man"Aman"
Special 0 Reser,e! fiel! names
A few field names are reser!ed for pre*defined %eha!ior in ,pen,%#ect$ Some of them are created automaticall" %"
the s"stem, and in that case an" field with that name will %e ignored$
id )ni()e syste, identi/ier /or the object 'cre+ted by O34- do not +dd it*
name de/ines the v+l)e )sed by de/+)lt to displ+y the record in lists- etc.
i/ ,issing- set _rec_name to speci/y +nother /ield to )se /or this p)rpose
active de/ines visibility2 records 5ith active set to False +re hidden by de/+)lt
sequence de/ines order +nd +llo5s dr+gAdrop reordering i/ incl)ded in list vie5s
state de/ines li/e-cycle st+ges /or the object- )sed /or 5or7/lo5s
parent_id de/ines tree str)ct)re on records- +nd en+bles child_of oper+tor
parent_left-
parent_right
)sed in conj)nction 5ith _parent_store /l+g on object- +llo5s /+ster +ccess to tree str)ct)res 'see +lso )erformance
*ptimi+ation section*
create_date-
create_uid-
0rite_date-
0rite_uid
)sed to log cre+tor- l+st )pd+ter- d+te o/ cre+tion +nd l+st )pd+te d+te o/ the record. dis+bled i/ _log_access /l+g is set to
False
'cre+ted by O34- do not +dd the,*
1orking with the OR.
nheriting from the osv.osv class ma&es all the ,RM methods a!aila%le on %usiness o%#ects$ 1hese methods ma" %e
in!o&ed on the self o%#ect within the P"thon class itself 0see e'amples in the ta%le %elow4, or from outside the class %"
first o%taining an instance !ia the ,RM pool s"stem$
OR. usage sample
class idea@ idea@*osv.osv,:
_name G .idea.idea.
_inherit G .idea.idea.
def _score_calc*self-cr-uid-ids-field-arg-conte1tGLone,:
res G 6=
# his loop generates only @ +ueries than)s to bro&se*,<
for idea in self.bro&se*cr-uid-ids-conte1tGconte1t,:
sum_vote G sum*:v.vote for v in idea.vote_ids;,
avg_vote G sum_vote/len*idea.vote_ids,
res:idea.id; G avg_vote
return res
_columns G 6
# $eplace static score &ith average of votes
.score.:fields.function*_score_calc-typeG.float.-methodGrue,
=
idea@*,
Copyright 2010 Open Object Press - All rights reserved See license on p. 18. #18
81
82
8!
8"
8#
8$
8%
88
8&
&0
&1
&2
&!
&"
&#
&$
OR. .etho!s on os,+os, objects
*&# generic accessor self.pool.get('ob&ect_name') ,+y be )sed to obt+in + ,odel cl+ss /ro,
+ny5here
Common parameters used by multiple methods cr: d+t+b+se connection 'c)rsor*
uid: id o/ )ser per/or,ing the oper+tion
ids: list o/ record ids- or single integer 5hen there is only one id
contet: option+l diction+ry o/ conte?t)+l p+r+,eters- s)ch +s )ser
l+ng)+ge 6 .lang.: .en_!I.- ... =
create(cr, uid, values, contet"%one)
Creates a new record with the specified value
!eturns, id of the new record
values: diction+ry o/ /ield v+l)es /or the record
idea_id G self.create*cr- uid-
6 .name.: .Ipam recipe.-
.description. : .spam & eggs.-
.inventor_id.: BC-=,
search(cr, uid, args, offset"1, limit"%one, order"%one,
contet"%one, count"#alse)
!eturns, list of ids of records matching the given criteria
args: list o/ t)ples speci/ying se+rch criteri+
offset2 option+l n),ber o/ records to s7ip
limit2 option+l ,+? n),ber o/ records to ret)rn
order2 option+l col),ns to sort by 'de/+)lt2 self._order*
count2 i/ True- ret)rns only the n),ber o/ records ,+tching the criteri+- not
their ids
#Operators: G- <G- M- MG- N- NG- li)e- ili)e-
#in- not in- child_of- parent_left- parent_right
#Prefix operators: .&. *default,- .|.- .<.
#>etch non-spam partner shops O partner AB
ids G self.search*cr- uid-
: '|'- *.partner_id.- '!='- AB,-
'!'- *.name.- 'ilike'- .spam.,- ;-
orderG.partner_id.,
rea!(cr, user, ids, fields"%one, contet"%one)
!eturns, list of dictionaries with re'uested field values
fields: option+l list o/ /ield n+,es to ret)rn 'de/+)lt2 +ll /ields*
results G self.read*cr- uid- :B@-BA;-
:.name.- .inventor_id.;,
print .0nventor:.- results:7;:.inventor_id.;
write(cr, uid, ids, values, contet"%one)
-pdates records with given ids with the given values.
!eturns, True
values: diction+ry o/ /ield v+l)es to )pd+te
self.&rite*cr- uid- :B@-BA;-
6 .name.: .spam & eggs.-
.partner_id.: @B-=,
copy(cr, uid, id, defaults,contet"%one)
(uplicates record with given id updating it with de/+)lts values.
!eturns, True
defaults: diction+ry o/ /ield v+l)es to ch+nge be/ore s+ving the d)plic+ted
object
unlink(cr, uid, ids, contet"%one)
(eletes records with the given ids
!eturns, True
self.unlin)*cr- uid- :B@-BA;,
browse(cr, uid, ids, contet"%one)
Fetches records as objects allowing to use dot-notation to
browse fields and relations
!eturns, object or list of objects re'uested
idea G self.bro&se*cr- uid- B@,
print .0dea description:.- idea.description
print .0nventor country code:.-
idea.inventor_id.address:7;.country_id.code
for vote in idea.vote_ids:
print .5ote P@.@f. P vote.vote
!efault*get(cr, uid, fields, contet"%one)
!eturns, a dictionary of the default values for fields (set on the
object class by the user preferences or via the context)
fields2 list o/ /ield n+,es
defs G self.default_get*cr-uid-
:.name.-.active.;,
# active should be rue by default
assert defs:.active.;
log(cr, uid, id, details"2rue)
!eturns, id of the record created in res.log
message2 ,ess+ge to 5rite
contet2 i/ p+ssed then conte?t is stored in db
self.log*cr- uid- st.id- _*.Itatement Ps is confirmed-
/ournal items are created.., P *st_number-,,
perm*rea!(cr, uid, ids, details"2rue)
!eturns, a list of ownership dictionaries for each re'uested
record
details2 i/ True- 3_uid /ields +re repl+ced 5ith the n+,e o/ the )ser
ret)rned diction+ries cont+in2 object id 'id*- cre+tor )ser id 'create_uid*-
cre+tion d+te 'create_date*- )pd+ter )ser id '0rite_uid*- )pd+te d+te
'0rite_date*
perms G self.perm_read*cr-uid-:B@-BA;,
print .creator:.- perms:7;.get*.create_uid.- .n/a.,
rea!*group(cr, uid, domain, fields, groupby, offset"1,
limit"%one, contet"%one)
!eturns, list of dictionaries (one dictionary for each record)
containing,
the values of fields grouped by the fields in ..groupby..
argument
__domain, list of tuples specifying the search criteria
__context, dictionary with argument li"e ..groupby..
domain2 list speci/ying se+rch criteri+ BB</ield6n+,e<- <oper+tor<- <v+l)e<C- ...C
fields2 list o/ /ields present in the list vie5 speci/ied on the object
groupby2 list o/ /ields on 5hich to gro)pby the records
offset2 option+l n),ber o/ records to s7ip
limit2 option+l ,+? n),ber o/ records to ret)rn
Copyright 2010 Open Object Press - All rights reserved See license on p. 18. $18
OR. .etho!s on os,+os, objects
fiel!s*get(cr, uid, fields"%one, contet"%one)
!eturns a dictionary of field dictionaries each one describing a
field of the business object
fields: list o/ /ield n+,es
class idea idea*osv.osv,:
*...,
_columns G 6
.name. : fields.char*.Lame.-sizeGDB,
*...,
def test_fields_get*self-cr-uid,:
assert*self.fields_get*.name.,:.size.; GG DB,
fiel!s*,iew*get(cr, uid, vie0_id"%one, vie0_type"'form',
contet"%one, toolbar"#alse)
!eturns a dictionary describing the composition of the re'uested
view (including inherited views and extensions)
vie0_id: id o/ the vie5 or %one
vie0_type2 type o/ vie5 to ret)rn i/ vie56id is %one '</or,<-<tree<- ...*
toolbar2 True to incl)de conte?t)+l +ctions
def test_fields_vie&_get*self-cr-uid,:
idea_ob/ G self.pool.get*.idea.idea.,
form_vie& G idea_ob/.fields_vie&_get*cr-uid,
name*get(cr, uid, ids, contet")+)
!eturns tuples with the text representation of re'uested objects
for to-many relationships
# 0deas should be sho&n &ith invention date
def name_get*self-cr-uid-ids,:
res G :;
for r in self.read*cr-uid-ids:.name.-.create_date.;,
res.append**r:.id.;- .Ps *Ps,. *r:.name.;-year,,
return res
name*search(cr, uid, name"'', args"%one, operator"'ili4e',
contet"%one, limit"51)
!eturns list of object names matching the criteria used to provide
completion for to-many relationships. /'uivalent of search() on
name 0 name_get()

name: object n+,e to se+rch /or
operator2 oper+tor /or n+,e criterion
args, limit2 s+,e +s /or search()*
# Hountries can be searched by code or name
def name_search*self-cr-uid-nameG..-
argsG:;-operatorG.ili)e.-conte1tG6=-
limitG#7,:
ids G :;
if name and len*name, GG @:
ids G self.search*cr- user-
:*.code.- .G.- name,; O args-
limitGlimit- conte1tGconte1t,
if not ids:
ids G self.search*cr- user-
:*.name.- operator- name,; O args-
limitGlimit- conte1tGconte1t,
return self.name_get*cr-uid-ids,
e%port*!ata(cr, uid, ids, fields, contet"%one)
/xports fields for selected objects returning a dictionary with a
datas matrix. -sed when exporting data via client menu.
fields: list o/ /ield n+,es
contet ,+y cont+in import_comp 'de/+)lt2 False* to ,+7e e?ported d+t+
co,p+tible 5ith import_data() ',+y prevent e?porting so,e /ields*
import*!ata(cr, uid, fields, data, mode"'init',
current_module"'', noupdate"#alse, contet"%one,
filename"%one)
1mports given data in the given module -sed when exporting data
via client menu
fields: list o/ /ield n+,es
data: d+t+ to i,port 'see eport_data()*
mode: <init< or <)pd+te< /or record cre+tion
current_module2 ,od)le n+,e
noupdate: /l+g /or record cre+tion
filename2 option+l /ile to store p+rti+l i,port st+te /or recovery
Tip: use read() through we%ser!ice calls, %ut alwa"s bro0se() internall"
'uil!ing the mo!ule interface
1o construct a module, the main mechanism is to insert data records declaring the module interface components$
Each module element is a regular data record) menus, !iews, actions, access rights, etc$
)ommon 2.$ structure
<ML files declared in a module?s updateD'ml attri%ute contain record declarations in the following form)
NQ1ml versionGR".7R encodingGRutf-#RQM
NopenerpM
NdataM
Nrecord modelGRob/ect_model_nameR idGRob/ect_1ml_idRM
Nfield nameGRfield"RMvalue"N/fieldM
Nfield nameGRfield@RMvalue@N/fieldM
N/recordM
Nrecord modelGRob/ect_model_name@R idGRob/ect_1ml_id@RM
Nfield nameGRfield"R refGRmodule.ob/ect_1ml_idR/M
Nfield nameGRfield@R evalGRref*.module.ob/ect_1ml_id.,R/M
N/recordM
N/dataM
N/openerpM
Each t"pe of record 0!iew, menu, action4 support a specific set of child entities and attri%utes, %ut all share the
following special attri%utes)
Copyright 2010 Open Object Press - All rights reserved See license on p. 18. %18
&%
&8
&&
100
101
102
10!
10"
10#
10$
10%
108
10&
id the uni(ue 0per module4 <ML identifier of this record 0'mlDid4
ref used instead of element content to reference another record 0wor&s cross*module %" prepending the module
name4
eval used instead of element content to pro!ide !alue as a P"thon e'pression, that can use the ref() method to find
the data%ase id for a gi!en 'mlDid
Tip: %M& Rela'N( validation
,pen,%#ect !alidates the s"nta' and structure of <ML files, according to a Rela';G grammar, found in
server/bin/import_ml.rng$
-or manual chec& use 'mllint) mllint 6relang /path/to/import_ml.rng 7file8
Common C") s$nta'
CS7 files can also %e added in update_ml, and the records will %e inserted %" the ,S7?s importDdata04 method, using
the CS7 filename to determine the target o%#ect model$ 1he ,RM automaticall" reconnects relationships %ased on the
following special column names)
id (ml_id) column containing identifiers for relationships
many(one_field reconnect man"Aone using name_search()
many(one_field:id reconnect man"Aone %ased on o%#ect?s ml_id
many(one_field.id reconnect man"Aone %ased on o%#ect?s database id
many(many_field reconnects !ia name_search(), repeat for multiple !alues
many(many_field:id reconnects with o%#ect?s ml_id, repeat for multiple !alues
many(many_field.id reconnects with o%#ect?s database id, repeat for multiple !alues
one(many_field/field creates one(many destination record and sets field !alue
ir+mo!el+access+cs,
RidR-RnameR-Rmodel_id:idR-Rgroup_id:idR-Rperm_readR-Rperm_&riteR-Rperm_createR-Rperm_unlin)R
Raccess_idea_ideaR-Ridea.ideaR-Rmodel_idea_ideaR-Rbase.group_userR-"-7-7-7
Raccess_idea_voteR-Ridea.voteR-Rmodel_idea_voteR-Rbase.group_userR-"-7-7-7
.enus an! actions
Actions are declared as regular records and can %e triggered in @ wa"s)
%" clic&ing on menu items lin&ed to a specific action
%" clic&ing on %uttons in !iews, if these are connected to actions
as conte'tual actions on an o%#ect

*ction declaration
Nrecord modelGRir.actions.act_&indo&R idGRaction_idRM
Nfield nameGRnameRMaction.nameN/fieldM
Nfield nameGRvie&_idR refGRvie&_idR/M
Nfield nameGRdomainRM:list of A-tuples *ma1 @C7 characters,;N/fieldM
Nfield nameGRconte1tRM6conte1t dictionary *ma1 @C7 characters,=N/fieldM
Nfield nameGRres_modelRMob/ect.model.nameN/fieldM
Nfield nameGRvie&_typeRMform|treeN/fieldM
Nfield nameGRvie&_modeRMform-tree-calendar-graphN/fieldM
Nfield nameGRtargetRMne&N/fieldM
Nfield nameGRsearch_vie&_idR refGRsearch_vie&_idR/M
N/recordM
id identi/ier o/ the +ction in t+ble ir.actions.act_0indo0- ,)st be )ni()e
name +ction n+,e (required)
view2id speci/ic vie5 to open 'i/ ,issing- highest priority vie5 o/ given type is )sed*
domain t)ple 'see search() +rg),ents* /or /iltering the content o/ the vie5
context conte?t diction+ry to p+ss to the vie5. >or the se+rch vie52 'search_default_fieldname':'value'
res2model object ,odel on 5hich the vie5 to open is de/ined
view2type set to form to open records in edit ,ode- set to tree /or + tree vie5 only
view2mode i/ view2type is form- list +llo5ed ,odes /or vie5ing records 'form tree ...*
target set to new to open the vie5 in + ne5 5indo5
search2view2id identi/ier o/ the se+rch vie5 to repl+ce de/+)lt se+rch /or, 'new in version 3.$*
Menu declaration
1he menuitem entit" is a shortcut for declaring an ir.ui.menu record and connect it with a corresponding action !ia an
ir.model.data record$
Nmenuitem idGRmenu_idR parentGRparent_menu_idR
nameGRlabelR actionGRaction_idR iconGRicon-codeR
groupsGRgroupname"-groupname@R se+uenceGR"7R/M
id identi/ier o/ the ,en)ite,- ,)st be )ni()e
parent id o/ the p+rent ,en) in the hier+rchy
name Option+l ,en) l+bel 'de/+)lt2 +ction n+,e*
action identi/ier o/ +ction to e?ec)te- i/ +ny
icon icon to )se /or this ,en) 'e.g. terp-graph- &T*C42*)/5- see doc.opernerp.co,*
groups list o/ gro)ps th+t c+n see this ,en) ite, 'i/ ,issing- +ll gro)ps c+n see it*
se'uence integer inde? /or ordering sibling ,en)ite,s '10-20-!0..*
Copyright 2010 Open Object Press - All rights reserved See license on p. 18. 818
110
111
112
11!
11"
11#
11$
11%
118
11&
120
121
122
12!
12"
12#
12$
3iews an! inheritance
7iews form a hierarch"$ Se!eral !iews of the same t"pe can %e declared on the same o%#ect, and will %e used
depending on their priorities$ B" declaring an inherited !iew it is possi%le to add/remo!e features in a !iew$
4eneric ,iew !eclaration
Nrecord modelGRir.ui.vie&R idGRvie&_idRM
Nfield nameGRnameRMvie&.nameN/fieldM
Nfield nameGRmodelRMob/ect_nameN/fieldM
Nfield nameGRtypeRMformN/fieldM N<-- tree-form-calendar-search-graph-gantt --M
Nfield nameGRpriorityR evalGR"DR/M
Nfield nameGRarchR typeGR1mlRM
N<-- vie& content: NformM- NtreeM- NgraphM- S --M
N/fieldM
N/recordM
id )ni()e vie5 identi/ier
name vie5 n+,e
model object ,odel on 5hich the vie5 is de/ined 's+,e +s res2model in +ctions*
type vie5 type2 form- tree- graph- calendar- search gantt 'search is ne5 in #.2*
priority vie5 priority- s,+ller is higher 'de/+)lt2 1$*
arch +rchitect)re o/ the vie5- see v+rio)s vie5 types belo5
5orms "to ,iew0e!it recor!s&
-orms allow creation/edition or resources, and correspond to 7form8 elements$
Allo5ed ele,ents all (see 'orm elements below)
Nform stringGR0dea formRM
Ngroup colGRDR colspanGRBRM
Ngroup colspanGRCR colGRDRM
Nfield nameGRnameR selectGR"R colspanGRDR/M
Nfield nameGRinventor_idR selectGR"R/M
Nfield nameGRinventor_country_idR /M
Nfield nameGRscoreR selectGR@R/M
N/groupM
Ngroup colspanGR"R colGR@RM
Nfield nameGRactiveR/MNfield nameGRinvent_dateR/M
N/groupM
N/groupM
Nnoteboo) colspanGRBRM
Npage stringGRTeneralRM
Nseparator stringGR%escriptionR/M
Nfield colspanGRBR nameGRdescriptionR nolabelGR"R/M
N/pageM
Npage stringGR5otesRM
Nfield colspanGRBR nameGRvote_idsR nolabelGR"R selectGR"RM
NtreeM
Nfield nameGRpartner_idR/M
Nfield nameGRvoteR/M
N/treeM
N/fieldM
N/pageM
Npage stringGRIponsorsRM
Nfield colspanGRBR nameGRsponsor_idsR nolabelGR"R selectGR"R/M
N/pageM
N/noteboo)M
Nfield nameGRstateR/M
Nbutton nameGRdo_confirmR stringGRHonfirmR iconGRgt)-o)R typeGRob/ectR/M
N/formM
Copyright 2010 Open Object Press - All rights reserved See license on p. 18. &18
12%
128
12&
1!0
1!1
1!2
1!!
1!"
1!#
1!$
1!%
1!8
1!&
1"0
1"1
1"2
1"!
1""
1"#
1"$
1"%
1"8
1"&
1#0
1#1
1#2
1#!
1#"
1##
1#$
1#%
1#8
1#&
1$0
1$1
1$2
1$!
1$"
1$#
1$$
1$%
5orm Elements
Co,,on +ttrib)tes /or +ll ele,ents2
string: l+bel o/ the ele,ent
nolabel2 1 to hide the /ield l+bel
colspan2 n),ber o/ col),n on 5hich the /ield ,)st sp+n
ro0span2 n),ber o/ ro5s on 5hich the /ield ,)st sp+n
col2 n),ber o/ col),n this ele,ent ,)st +lloc+te to its child ele,ents
invisible2 6 to hide this ele,ent co,pletely
eval2 ev+l)+te this Python code +s ele,ent content 'content is string by de/+)lt*
attrs2 Python ,+p de/ining dyn+,ic conditions on these +ttrib)tes2 readonly- invisible- required b+sed on se+rch t)ples on other /ield v+l)es
field +)to,+tic 5idgets depending on the corresponding /ield type. Attrib)tes2
string: l+bel o/ the /ield- +lso /or se+rch 'overrides /ield n+,e*
select2 6 to sho5 the /ield in nor,+l se+rch- $ /or +dv+nced only
nolabel2 1 to hide the /ield l+bel
required2 override required /ield +ttrib)te
readonly2 override readonly /ield +ttrib)te
pass0ord2 True to hide ch+r+cters typed in this /ield
contet: Python code decl+ring + conte?t diction+ry
domain2 Python code decl+ring list o/ t)ples /or restricting v+l)es
on_change2 Python ,ethod c+ll to trigger 5hen v+l)e is ch+nged
completion2 6 to en+ble +)to-co,pletion o/ v+l)es 5hen possible
groups2 co,,+-sep+r+ted list o/ gro)p 'id* +llo5ed to see this /ield
0idget2 select +ltern+tive 5idget 'one$many2list many$many url email image float2time reference text2wi"i
text2html progressbar*
properties dyn+,ic 5idget sho5ing +ll +v+il+ble properties 'no +ttrib)te*
button clic7+ble 5idget +ssoci+ted 5ith +ctions. Speci/ic +ttrib)tes2
type2 type o/ b)tton2 wor"flow 'de/+)lt*- object- or action
name2 5or7/lo5 sign+l- /)nction n+,e '5itho)t p+rentheses* or +ction to c+ll 'depending on type*
confirm2 te?t o/ con/ir,+tion ,ess+ge 5hen clic7ed
states2 co,,+-sep+r+ted list o/ st+tes in 5hich this b)tton is sho5n
icon2 option+l icon '+ll D;E S;OCE icons e.g. gt"-o"*
separator hori@ont+l sep+r+tor line /or str)ct)ring vie5s- 5ith option+l l+bel
newline pl+ce-holder /or co,pleting the c)rrent line o/ the vie5
label /ree-te?t c+ption or legend in the /or,
group )sed to org+nise /ields in gro)ps 5ith option+l l+bel '+dds /r+,e*
noteboo" page noteboo" ele,ents +re t+b cont+iners /or page ele,ents. Attrib)tes2
name2 l+bel /or the t+bp+ge
position2 t+bs position in noteboo7 'inside top bottom left right*
html html ele,ents +re cont+iners /or +ny F;49 code. 7or"s only in the web client
Dynamic ,iews
n addition to what can %e done with states and attrs attri%utes, functions ma" %e called %" !iew elements 0!ia %uttons
of t"pe ob&ect, or on_change attri%utes on fields4 to o%tain d"namic %eha!ior$ 1hese functions ma" alter the !iew
interface %" returning a P"thon map with the following entries)
value + diction+ry o/ /ield n+,es +nd their )pd+ted v+l)es
domain + diction+ry o/ /ield n+,es +nd their )pd+ted do,+ins o/ v+l)e
warning + diction+ry 5ith + title +nd message to sho5 + 5+rning di+log
$ists0Trees
Lists include 'ield elements, are created with t"pe tree, and ha!e a 7tree8 parent element$
Attrib)tes colors2 list o/ colors ,+pped to Python conditions
editable: top or bottom to +llo5 in-pl+ce edit
toolbar2 set to True to displ+y the top level o/ object hier+rchies +s + side
toolb+r 'e?+,ple2 the ,en)*
Allo5ed ele,ents 'ield, gro$p, separator, tree, b$tton, 'ilter, newline
Ntree stringGR0dea HategoriesR toolbarGR"R colorsGRblue:stateGGdraftRM
Nfield nameGRnameR conte1tGR6.group_by.: :.inventor_id.;=R/M
Nfield nameGRstateR/M
N/treeM
)alen!ars
7iews used to displa" date fields as calendar e!ents 07calendar8 parent4
Attrib)tes color2 n+,e o/ /ield /or color seg,ent+tion
date_start: n+,e o/ /ield cont+ining event st+rt d+teti,e
day_length: length o/ + c+lend+r d+y in ho)rs 'de/+)lt2 8*
date_stop: n+,e o/ /ield cont+ining event stop d+teti,e
or
date_delay: n+,e o/ /ield cont+ining event d)r+tion
Allo5ed ele,ents 'ield (to de'ine the label 'or each calendar event)
Ncalendar stringGR0deasR date_startGRinvent_dateR colorGRinventor_idRM
Nfield nameGRnameR/M
N/calendarM
Copyright 2010 Open Object Press - All rights reserved See license on p. 18. 1018
1$8
1$&
1%0
1%1
1%2
1%!
1%"
4antt )harts
Bar chart t"picall" used to show pro#ect schedule 07gantt8 parent element4
Attrib)tes same as 7calendar8
Allo5ed ele,ents 'ield, level
level ele,ents +re )sed to de/ine the D+ntt ch+rt levels- 5ith the enclosed /ield )sed +s l+bel /or th+t drill-
do5n level
Ngantt stringGR0deasR date_startGRinvent_dateR colorGRinventor_idRM
Nlevel ob/ectGRidea.ideaR lin)GRidR domainGR:;RM
Nfield nameGRinventor_idR/M
N/levelM
N/ganttM
)harts "4raphs&
7iews used to displa" statistical charts 07graph8 parent element4
Tip: charts are most useful with custom !iews e'tracting read"*to*use statistics
Attrib)tes type: type o/ ch+rt2 bar- pie 'de/+)lt*
orientation2 hori+ontal vertical
Allo5ed ele,ents 'ield, with specific %eha!ior)
/irst /ield in vie5 is G +?is- 2
nd
one is H- !
rd
one is I
2 /ields re()ired- !
rd
one is option+l
group +ttrib)te de/ines the D3OJP KH /ield 'set to 1*
operator +ttrib)te sets the +ggreg+tion oper+tor to )se /or other /ields 5hen one /ield is gro)ped
'9,3,33,min,ma*
Ngraph stringGRotal idea score by 0nventorR typeGRbarRM
Nfield nameGRinventor_idR /M
Nfield nameGRscoreR operatorGROR/M
N/graphM
Diagrams
Edita%le wor&flow*li&e !iews 07diagram8 parent element4
Allo5ed
ele,ents
node has the following attri%utes)
ob&ect +ttrib)te de/ines the object represented by the node. ;his object ,)st h+ve + many$one rel+tion 5ith the ,odel o/ the di+gr+,
shape +ttrib)te is + list o/ sh+pes ,+pped to Python conditions
bgcolor +ttrib)te is + list o/ b+c7gro)nd colors ,+pped to Python conditions
arrow has the following attri%utes(
ob&ect +ttrib)te de/ines the object represented by the tr+nsition '+rro5*. ;his object ,)st h+ve t5o many$one rel+tions 5ith objects
represented by nodes
source +nd destination +ttrib)tes- respectively the so)rce +nd the destin+tion nodes o/ the tr+nsition
label +ttrib)te de/ines the l+bel o/ the tr+nsition
Search ,iews
Search !iews are used to customi+e the search panel on top of list !iews, and are declared with the search t"pe, and a
top*le!el 7search8 element$ After defining a search !iew with a uni(ue id, add it to the action opening the list !iew
using the search_vie0_id field in its declaration$ Attri%ute select":2rue: in field of a !iew or select"2rue in a field of the
p"thon class result in adding this field in the default search !iew 0no declaration needed4$ Howe!er an inde' is
created onl" when the attri%ute is added in the p"thon class
Allo5ed ele,ents 'ield, gro$p, separator, label, search, 'ilter, newline, properties
filter ele,ents +llo5 de/ining b)tton /or
- do,+in /ilters domainGU:*inventor_id-.G.-uid,;U
- group by conte1tGU6.country_visibleGU"U- #options
.group_by.:.inventor_id.=U #group by
+dding + contet +ttrib)te to /ields ,+7es 5idgets th+t +lter the se+rch conte?t ')se/)l /or conte?t-sensitive
/ields- e.g. pricelist-dependent prices*
Nsearch stringGRIearch 0deasRM
Ngroup colGRDR colspanGRBR e1pandGR7RM
Nfilter stringGR3y 0deasR iconGRterp-partnerR
domainGR:*.inventor_id.-.G.-uid,;R
helpGR3y o&n ideasR/M
Nfield nameGRnameR selectGRrueR/M
Nfield nameGRdescriptionR selectGRrueR/M
Nfield nameGRinventor_idR selectGRrueR/M
Nseparator orientationGUverticalRM
N<-- follo&ing conte1t field is for illustration only --M
Nfield nameGRinventor_country_idR selectGRrueR &idgetGRselectionR
conte1tGR6.inventor_country.: self=R/M
N/groupM
N/searchM
Copyright 2010 Open Object Press - All rights reserved See license on p. 18. 1118
1%#
1%$
1%%
1%8
1%&
180
181
182
18!
18"
18#
18$
18%
188
18&
1&0
1&1
1&2
1&!
1&"
1&#
1&$
1&%
1&8
)ie In+eritance
E'isting !iews should %e modif"ing through inherited !iews, ne!er directl"$ An inherited !iew references its parent
!iew using the inherit_id field, and ma" add or modif" e'isting elements in the !iew %" referencing them through <Path
e'pressions, specif"ing the appropriate position$
Tip: <Path reference can %e found at www$w@$org/1R/'path
position inside2 pl+ced inside ,+tch 'de/+)lt*
replace2 repl+ce ,+tch
before2 pl+ced be/ore ,+tch
after2 pl+ced +/ter ,+tch
attributes2 )sed 5ith 7attribute8 t+gs to +dd ne5
+ttrib)tes
N<-- improved idea categories list --M
Nrecord idGRidea_category_list@R modelGRir.ui.vie&RM
Nfield nameGRnameRMid.category.list@N/fieldM
Nfield nameGRmodelRMir.ui.vie&N/fieldM
Nfield nameGRinherit_idR refGRid_category_listR/M
Nfield nameGRarchR typeGR1mlRM
N1path e1prGR/tree/field:VnameG.description.;R positionGRafterRM
Nfield nameGRidea_idsR stringGRLumber of ideasR/M
N/1pathM
N/fieldM
N/recordM
Reports
1here are se!eral report engines in ,penERP, to produce reports from different sources and in man" formats$
Special e'pressions used inside report templates produce d"namic data and/or modif" the report structure at
rendering time$
Custom report parsers ma" %e written to support additional e'pressions$
Alternati,e Report 5ormats (see doc.openerp.com)
s'wArml ,pen,ffice E$F templates 0$s'w4 con!erted to RML with s'wArml tool, and the RML rendered in
H1ML or P>-
rml RML templates rendered directl" as H1ML or P>-
'ml,'sl)rml <ML data 3 <SL)RML st"lesheets to generate RML
odtAodt ,pen,ffice templates 0$odt4 used to produce directl" ,pen,ffice documents 0$odt4 0As of
,penERP G$A4
ma&o Ma&o template li%rar" used to produce H1ML output, %" em%edding P"thon code and ,penERP
e'pressions within an" te't file 0As of ,penERP G$A4
E%pressions use! in OpenERP report templates
,, 7content8 // dou%le %rac&ets content is e!aluated as a P"thon e'pression %ased on the following
e'pressions
;redefined epressions:
ob&ects contains the list of records to print
data comes from the wi+ard launching the report
user contains the current user 0as per bro0se()4
time gi!es access to P"thon time module
repeat<n(list,'var','tag') repeats the current parent element named tag for each o%#ect in list, ma&ing the o%#ect
a!aila%le as var during each loop
set2ag('tag'','tag(') replaces the parent RML tag' with tag(
remove;arent%ode('tag') remo!es parent RML element tag
format=ang(value, digits"(, date"#alse, date_time"#alse, grouping"2rue, monetary"#alse) can %e used to format a date,
time or amount according to the locale
set=ang('lang_code') sets the current language and locale for translations
Report !eclaration
N<-- he follo&ing creates records in ir.actions.report.1ml model --M
Nreport idGRidea_reportR stringGR(rint 0deasR modelGRidea.ideaR
nameGRidea.reportR rmlGRidea/report/idea.rmlR M
N<-- !se addons/base_report_designer/wizard/tiny_sxw2rml/tiny_sxw2rmlpy
to generate the $34 template file from a .s1& template --M
id )ni()e report identi/ier
name n+,e /or the report (required)
string report title (required)
model object ,odel on 5hich the report is de/ined (required)
rml sxw xml xsl p+th to report te,pl+te so)rces 'st+rting /ro, addons*- depending on report
auto set to False to )se + c)sto, p+rser- by s)bcl+ssing report_s0.rml_parse +nd decl+ring the report +s /ollo5s2
report_s0.report_s0(report_name, ob&ect_model,rml_path,parser"custom>lass)
Copyright 2010 Open Object Press - All rights reserved See license on p. 18. 1218
1&&
200
201
202
20!
20"
20#
20$
20%
208
20&
210
211
212
21!
21"
header set to False to s)ppress report he+der 'de/+)lt2 True*
groups co,,+-sep+r+ted list o/ gro)ps +llo5ed to vie5 this report
menu set to True to lin7 the report 5ith the Print icon 'de/+)lt2 True*
"eywords speci/y report type 7ey5ord 'de/+)lt2 client2print2multi*
Tip: RML 6ser Guide) www$reportla%$com/docs/rmlApdf*userguide$pdf
?ample @A= report etract:
NstoryM
Nbloc)able styleGRableRM
NtrM
NtdMNpara styleGRitleRM0dea nameN/paraM N/tdM
NtdMNpara styleGRitleRMIcoreN/paraM N/tdM
N/trM
NtrM
NtdMNparaM:: repeat0n*ob/ects-.o.-.tr., ;; :: o.name ;;N/paraMN/tdM
NtdMNparaM:: o.score ;;N/paraMN/tdM
N/trM
N/bloc)ableM
N/storyM
1orkflows
5or&flows ma" %e associated with an" o%#ect in ,penERP, and are entirel" customi+a%le$
5or&flows are used to structure and manage the lifec"cles of %usiness o%#ects and documents,
and define transitions, triggers, etc$ with graphical tools$
5or&flows, acti!ities 0nodes or actions4 and transitions 0conditions4 are declared as <ML records,
as usual$ 1he to&ens that na!igate in wor&flows are called wor)items$
1orkflow !eclaration
5or&flows are declared on o%#ects that possess a state field 0see the e'ample idea class in the
,RM section4
Nrecord idGR&)f_ideaR modelGR&or)flo&RM
Nfield nameGRnameRMidea.basicN/fieldM
Nfield nameGRosvRMidea.ideaN/fieldM
Nfield nameGRon_createR evalGR"R/M
N/recordM
id )ni()e 5or7/lo5 record identi/ier
name n+,e /or the 5or7/lo5 (required)
osv object ,odel on 5hich the 5or7/lo5 is de/ined (required)
on2create i/ True- + 5or7ite, is inst+nti+ted +)to,+tic+lly /or e+ch ne5 osv record
,orkflo *ctivities -nodes.
Nrecord idGRact_confirmedR modelGR&or)flo&.activityRM
Nfield nameGRnameRMconfirmedN/fieldM
Nfield nameGR&)f_idR refGR&)f_ideaR/M
Nfield nameGR)indRMfunctionN/fieldM
Nfield nameGRactionRMaction_confirmed*,N/fieldM
N/recordM
id )ni()e +ctivity identi/ier
w"f2id p+rent 5or7/lo5 identi/ier
name +ctivity node l+bel
flow2start True to ,+7e it + <begin< node- receiving + 5or7ite, /or e+ch 5or7/lo5 inst+nce
flow2stop True to ,+7e it +n <end< node- ter,in+ting the 5or7/lo5 5hen +ll ite,s re+ch it
join2mode logic+l beh+vior o/ this node reg+rding inco,ing tr+nsitions2
8*!2 +ctiv+te on the /irst inco,ing tr+nsition 'de/+)lt*
95(2 5+its /or +ll inco,ing tr+nsitions to beco,e v+lid
split2mode logic+l beh+vior o/ this node reg+rding o)tgoing tr+nsitions2
8*!2 one v+lid tr+nsition necess+ry- send 5or7ite, on it 'de/+)lt*
*!2 send 5or7ite,s on +ll v+lid tr+nsitions '0 or ,ore*- se()enti+lly
95(2 send + 5or7ite, on +ll v+lid tr+nsitions +t once '/or7*
"ind type o/ +ction to per/or, 5hen node is +ctiv+ted by + tr+nsition2
dummy to per/or, no oper+tion 5hen +ctiv+ted 'de/+)lt*
function to invo7e + /)nction deter,ined by action
subflow to e?ec)te the s)b/lo5 5ith subflow2id- invo7ing action to deter,ine the record id o/ the record /or 5hich the
s)b/lo5 sho)ld be inst+nti+ted. :/ +ction ret)rns no res)lt- the 5or7ite, is deleted.
stopall to ter,in+te the 5or7/lo5 )pon +ctiv+tion
subflow2id i/ 7ind subflow- id o/ the s)b/lo5 to e?ec)te ')se ref +ttrib)te or search 5ith + t)ple*
action object ,ethod c+ll- )sed i/ 7ind is function or subflow. ;his /)nction sho)ld +lso )pd+te the state /ield o/ the object- e.g. /or +
function 7ind2
def action_confirmed*self- cr- uid- ids,:
self.&rite*cr- uid- ids- 6 .state. : .confirmed. =,
# S perform other tas)s
return rue
Copyright 2010 Open Object Press - All rights reserved See license on p. 18. 1!18
21#
21$
21%
218
21&
220
221
222
22!
22"
22#
22$
22%
228
22&
2!0
2!1
2!2
2!!
2!"
2!#
2!$
2!%
1orkflow Transitions "e!ges&
Conditions are e!aluated in this order) groupDid, signal, condition e'pression
Nrecord idGRtrans_idea_draft_confirmedR modelGR&or)flo&.transitionRM
Nfield nameGRact_fromR refGRact_draftR/M
Nfield nameGRact_toR refGRact_confirmedR/M
Nfield nameGRsignalRMbutton_confirmN/fieldM
Nfield nameGRgroup_idR refGRidea_managerR/M
Nfield nameGRconditionRM" GG "N/fieldM
N/recordM
act2from act2to identi/iers o/ the so)rce +nd destin+tion +ctivities
signal n+,e o/ + b)tton o/ type 5or7/lo5 th+t triggers this tr+nsition
group2id re/erence to the gro)p the )ser ,)st belong to in order to trigger the tr+nsition
condition Python e?pression th+t ,)st ev+l)+te to True /or tr+nsition to be triggered
Tip: 1he 5e% client features a graphical wor&flow editor, !ia the C$stomise!Manage *or)'lows
lin& at the %ottom left in lists and forms$
Security
Access control mechanisms must %e com%ined to achie!e a coherent securit" polic"$
4roup#base! access control mechanisms
Groups are created as normal records on the res.groups model, and granted menu access !ia menu definitions$
Howe!er e!en without a menu, o%#ects ma" still %e accessi%le indirectl", so actual object/level permissions
0create,read,write,$nlin)4 must %e defined for groups$ 1he" are usuall" inserted !ia CS7 files inside modules$ t is also
possi%le to restrict access to specific fields on a !iew or o%#ect using the field?s groups attri%ute$
ir+mo!el+access+cs,
RidR-RnameR-Rmodel_id:idR-Rgroup_id:idR-Rperm_readR-Rperm_&riteR-Rperm_createR-Rperm_unlin)R
Raccess_idea_ideaR-Ridea.ideaR-Rmodel_idea_ideaR-Rbase.group_userR-"-"-"-7
Raccess_idea_voteR-Ridea.voteR-Rmodel_idea_voteR-Rbase.group_userR-"-"-"-7
1iar!s
5i+ards descri%e stateful interacti!e sessions with the user through d"namic forms$ As of ,penERP !G$F, wi+ards
ma&e use of the osv+memor, in*memor" persistence to allow constructing wi+ards from regular %usiness o%#ects and
!iews$
1iar! objects "os,*memory&
n*memor" o%#ects are created %" e'tending os!$os!Dmemor")
from osv import fields-osv
import datetime
class cleanup_&izard cleanup_&izard*osv.osv_memory,:
_name G .idea.cleanup.&izard.
_columns G 6
.idea_age.: fields.integer*.Jge *in days,.,-
=
def cleanup*self-cr-uid-ids-conte1tG6=,:
idea_ob/ G self.pool.get*.idea.idea.,
for &iz in self.bro&se*cr-uid-ids,:
if &iz.idea_age NG A:
raise osv.e1cept_osv*.!ser9rror.-.(lease select a larger age.,
limit G datetime.date.today*,-datetime.timedelta*daysG&iz.idea_age,
ids_to_del G idea_ob/.search*cr-uid- :*.create_date.- .N. -
limit.strftime*.PW-Pm-Pd 77:77:77.,,;-conte1tGconte1t,
idea_ob/.unlin)*cr-uid-ids_to_del,
return 6=
cleanup_&izard*,
3iews
5i+ards use regular !iews and their %uttons ma" use a special cancel attri%ute to close the wi+ard window when
clic&ed$
Nrecord idGR&izard_idea_cleanupR modelGRir.ui.vie&RM
Nfield nameGRnameRMidea.cleanup.&izard.formN/fieldM
Nfield nameGRmodelRMidea.cleanup.&izardN/fieldM
Nfield nameGRtypeRMformN/fieldM
Nfield nameGRarchR typeGR1mlRM
Nform stringGR0dea Hleanup 'izardRM
Nlabel colspanGRBR stringGRIelect the age of ideas to cleanupR/M
Nfield nameGRidea_ageR stringGRJge *days,R/M
Ngroup colspanGRBRM
Nbutton stringGRHancelR specialGRcancelR iconGRgt)-cancelR/M
Nbutton stringGRHleanupR nameGRcleanupR typeGRob/ectR iconGRgt)-o)R/M
N/groupM
N/formM
N/fieldM
N/recordM
Copyright 2010 Open Object Press - All rights reserved See license on p. 18. 1"18
2!8
2!&
2"0
2"1
2"2
2"!
2""
2"#
2"$
2"%
2"8
2"&
2#0
2#1
2#2
2#!
2#"
2##
2#$
2#%
2#8
2#&
2$0
2$1
2$2
2$!
2$"
2$#
2$$
2$%
2$8
2$&
2%0
2%1
2%2
2%!
2%"
2%#
2%$
2%%
2%8
2%&
280
1iar! e%ecution
Such wi+ards can %e launched !ia regular action records, with a special target field used to open the wi+ard !iew in a
new window$ t can also %e associated to a launcher in the conte't %ar 0the side panel4 using the following action)
Nact_&indo& idGRaction_idea_cleanup_&izardR nameGRHleanup ideasR
res_modelGRidea.cleanup.&izardR src_modelGRidea.ideaR
vie&_typeGRformR vie&_modeGRformR
)ey@GRclient_action_multiR targetGRne&R
N<-- )ey@ can also be client_print_multi or client_action_relate --M
multiGRrueR/M
1ebSer,ices - 2.$#RP)
,penERP is accessi%le through <ML*RPC interfaces, for which li%raries e'ist in man" languages$
Python e%ample
import 1mlrpclib
# ... define X8I- (8$- %?- !I9$- (JII
url G .http://Ps:Pd/1mlrpc/common. P *X8I-(8$,
soc) G 1mlrpclib.Ierver(ro1y*url,
uid G soc).login*%?-!I9$-(JII,
print R4ogged in as Ps *uid:Pd,R P *!I9$-uid,
# Hreate a ne& idea
url G .http://Ps:Pd/1mlrpc/ob/ect. P *X8I-(8$,
soc) G 1mlrpclib.Ierver(ro1y*url,
args G 6
.name. : .Jnother idea.-
.description. : .his is another idea of mine.-
.inventor_id.: uid-
=
idea_id G soc).e1ecute*%?-uid-(JII-.idea.idea.-.create.-args,
P6P e%ample
NQ
include*.1mlrpc.inc.,Y // !se php1mlrpc library- available on sourceforge
// ... define $X8I- $(8$- $%?- $!I9$- $(JII
$client G ne& 1mlrpc_client*Rhttp://$X8I:$(8$/1mlrpc/commonR,Y
$msg G ne& 1mlrpcmsg*RloginR,Y
$msg-Madd(aram*ne& 1mlrpcval*$%?- RstringR,,Y
$msg-Madd(aram*ne& 1mlrpcval*$!I9$- RstringR,,Y
$msg-Madd(aram*ne& 1mlrpcval*$(JII- RstringR,,Y
resp G $client-Msend*$msg,Y
uid G $resp-Mvalue*,-Mscalarval*,
echo R4ogged in as $!I9$ *uid:$uid,R
// Hreate a ne& idea
$array5al G array*
.name.GMne& 1mlrpcval*RJnother 0deaR- RstringR, -
.description.GMne& 1mlrpcval*Rhis is another idea of mineR - RstringR,-
.inventor_id.GMne& 1mlrpcval*$uid- RintR,-
,Y
$msg G ne& 1mlrpcmsg*.e1ecute.,Y
$msg-Madd(aram*ne& 1mlrpcval*$%?- RstringR,,Y
$msg-Madd(aram*ne& 1mlrpcval*$uid- RintR,,Y
$msg-Madd(aram*ne& 1mlrpcval*$(JII- RstringR,,Y
$msg-Madd(aram*ne& 1mlrpcval*Ridea.ideaR- RstringR,,Y
$msg-Madd(aram*ne& 1mlrpcval*RcreateR- RstringR,,Y
$msg-Madd(aram*ne& 1mlrpcval*$array5al- RstructR,,Y
$resp G $client-Msend*$msg,Y
QM
Internationaliation
Each module can pro!ide its own translations within the i'5n director", %" ha!ing files named =B%C.po where =B%C is
the locale code for the countr", or countr" and language com%ination when the" differ 0e$g$ pt.po and pt_D@.po4$
1ranslations will %e loaded automaticall" %" ,penERP for all ena%led languages$
>e!elopers alwa"s use English when creating a module, then e'port the module terms using ,penERP?s gette't -O.
e'port feature 0Bdministration82ranslations8?port a 2ranslation #ile without specif"ing a language4 , to create the module
template P,1 file, and then deri!e the translated P, files$
Man" >E?s ha!e plugins or modes for editing and merging P,/P,1 files$
Tip: 1he G;6 gette1t format 0Porta%le ,%#ect4 used %" ,penERP is integrated into LaunchPad, ma&ing it an online
colla%orati!e translation platform, with automatic translation features$


Copyright 2010 Open Object Press - All rights reserved See license on p. 18. 1#18
281
282
28!
28"
28#
28$
28%
288
28&
2&0
2&1
2&2
2&!
2&"
2&#
2&$
2&%
2&8
2&&
!00
!01
!02
!0!
!0"
!0#
!0$
!0%
!08
!0&
!10
!11
!12
!1!
!1"
!1#
!1$
!1%
!18
!1&
!20
!21
!22
!2!
!2"
!2#
!2$
!2%
!28
!2&
|- idea/ # he module directory
|- i"#n/ # ranslation files
| - idea.pot idea.pot # ranslation emplate *e1ported from 8pen9$(,
| - fr.po # >rench translation
| - pt_?$.po # ?razilian (ortuguese translation
| *...,
Tip: B" default ,penERP?s P,1 e'port onl" e'tracts la%els inside <ML records or inside field definitions in P"thon code,
%ut an" P"thon string can %e translated %" surrounding it with the tools.translate._ method 0e$g$ _*.4abel., 4
Rapi! Application De,elopment
.o!ule recor!er
1he base_module_record module can %e used to e'port a set of changes in the form of a new module$ t should %e used
for all customi+ations that should %e carried on through migrations and updates$ t has A modes)
Start/Pause/Stop mode, where all operations 0on %usiness o%#ects or user interface4 are recorded until the recorder
is stopped or paused$
>ate* and model*%ased mode where all changes performed after a gi!en date on the gi!en models 0o%#ect t"pes4
are e'ported$ $
Report )reator ",iew& an! Report Designer "print& mo!ules
1he base_report_creator module can %e used to automate the creation of custom statistics !iews, e$g$ to construct
dash%oards$ 1he resulting dash%oards can then %e e'ported using the base_module_record module$
1he base_report_designer module can %e used in con#unction with the ,pen,ffice plugin to pro!ide a user*friendl"
interface for selecting data from ,penERP and designing report templates within ,pen,ffice$
7uality assessment mo!ule
5hen writing "ou module, use the base_module_quality module to test !arious aspects of "our module) coding
standards, code duplication, code efficienc", etc$ 0we% client onl"4$ Ma&e sure to pro!ide a lot of demo data$
8nit tests
6nit test files are regular ,penERP <ML files, with regular record elements plus an appropriate com%ination of function,
0or4flo0 and assert elements to test the module?s %usiness logic$
1he continuous integration ser!er will automaticall" e'ecute unit tests and pro!ide feed%ac&$ 6nit tests can also %e
used as installation chec&s if "ou reference the <ML file in the update_ml section of "our module descriptor$
i!ea*unit*test+%ml
Nrecord idGRidea_test_"R modelGRidea.ideaRM
Nfield nameGRnameRM!nit est 0deaN/fieldM
Nfield nameGRdescriptionRMJ sample idea for performing testsN/fieldM
Nfield nameGRinvent_dateRM@7"77"7"N/fieldM
N/recordM
Nassert idGRidea_test_"R modelGRidea.ideaR severityGR&arningR
stringGRLe& idea is not draft<RM
Ntest e1prGRstateRMdraftN/fieldM
N/assertM
N&or)flo& refGRidea_test_"R modelGRidea.ideaR actionGRbutton_confirmR
uidGRbase.user_adminR/M
Nassert idGRidea_test_"R modelGRidea.ideaR severityGR&arningR
stringGRHonfirm button does not &or)<RM
Ntest e1prGRstate GG .confirmed.R/M
N/assertM
Nfunction modelGRidea.ideaR nameGRunlin)RM
Nvalue evalGRref*.idea_test_".,R/M
N/functionM
Nassert searchGR:*.name.-.G.-.!nit est 0dea.;R modelGRidea.ideaR countGR7R
severityGR&arningR stringGRest data is not deleted *name is uni+ue<,R/M
Co,,on +ttrib)tes2
model2 t+rget object ,odel n+,e
id2 xml2id o/ the record to test 'assert* or to ,ove in 5or7/lo5 '0or4flo0*
uid2 option+l id o/ )ser to per/or, oper+tion 'function or 0or4flo0*
assert Per/or, test's* +nd /+il 5ith given string i/ tests do not p+ss.
string2 error ,ess+ge in c+se o/ test /+il)re
severity2 error severity in c+se o/ test /+il)re 'debug,info,error,0arning,critical*
search2 do,+in o/ se+rch to per/or, i/ id is not provided 'e+ch record is tested*
count2 i/ se+rch is provided n),ber o/ e?pected records '/+il)re i/ not veri/ied*
7test8 children 5ith epr Python e?pression th+t ,)st ev+l)+te to 2rue or to the te?t content o/ the ele,ent. :t c+n )se +ny
/ield o/ the object- Python b)ilt-ins +nd the ref() ,ethod th+t ret)rns the d+t+b+se id /or + given xml2id.
function C+ll ,ethod on the given ,odel- p+ssing the value children +s +rg),ents.
name2 n+,e o/ ,ethod to c+ll
7value8 children 5ith Python e?pressions- th+t c+n )se the ref() ,ethod
0or4flo0 Send + 5or7/lo5 sign+l on + given object
ref2 xml2id o/ object to send 5or7/lo5 sign+l to
action2 n+,e o/ 5or7/lo5 sign+l to send
Copyright 2010 Open Object Press - All rights reserved See license on p. 18. 1$18
!!0
!!1
!!2
!!!
!!"
!!#
!!$
!!%
!!8
!!&
!"0
!"1
!"2
!"!
!""
!"#
!"$
!"%
!"8
!"&
!#0
!#1
!#2
!#!
!#"
!##
Recurrent jobs
1he ir.cron model is used to setup recurrent tas&s$
Nrecord idGRtas)_idR modelGRir.cronRM
Nfield nameGRnameRMas) titleN/fieldM
Nfield nameGRuser_idR refGRmodule.user_1ml_idRM
Nfield nameGRinterval_typeRMminutes|hours|days|&or)_days|&ee)s|monthsN/fieldM
Nfield nameGRinterval_numberR evalGRNnumberMR/M
Nfield nameGRnumbercallR evalGRNnumber-negative for unlimitedMR/M
Nfield nameGRdoallR evalGRrue|>alseR/M N<-- $epeat missed callsQ --M
Nfield nameGRmodelRMmodel.nameN/fieldM
Nfield nameGRfunctionRMname_of_model_function_to_callN/fieldM
Nfield nameGRargsR evalGRpython code for arguments tupleR/M
Nfield nameGRpriorityR evalGRNinteger-smaller is higherMR/M
N/recordM
Performance Optimiation
As Enterprise Management Software t"picall" has to deal with large amounts of records, "ou ma" want to pa"
attention to the following anti-patterns, to o%tain consistent performance)
>o not place bro0se() calls inside loops, put them %efore and access onl" the %rowsed o%#ects inside the loop$ 1he
,RM will optimi+e the num%er of data%ase (ueries %ased on the browsed attri%utes$
A!oid recursion on o%#ect hierarchies 0o%#ects with a parent_id relationship4, %" adding parent_left and parent_right
integer fields on "our o%#ect, and setting _parent_store to 2rue in "our o%#ect class$ 1he ,RM will use a modi'ied
preorder tree traversal to %e a%le to perform recursi!e operations 0e$g$ child_of4 with data%ase (ueries in O(/)
instead of O(n)
>o not use function fields lightl", especiall" if "ou include them in tree !iews$ 1o optimi+e function fields, two
mechanisms are a!aila%le)
multi) all fields sharing the same multi attri%ute !alue will %e computed with one single call to the function, which
should then return a dictionar" of !alues in its values map
store) function fields with a store attri%ute will %e stored in the data%ase, and recomputed on demand when the
rele!ant trigger o%#ects are modified$ 1he format for the trigger specification is as follows) store G 6.model.:
*_ref_fnct- fields- priority,= 0see e'ample %elow4
def _get_idea_from_vote*self-cr-uid-ids-conte1tG6=,:
res G 6=
vote_ids G self.pool.get*.idea.vote.,.bro&se*cr-uid-ids-conte1tGconte1t,
for v in vote_ids:
res:v.idea_id.id; G rue # Itore the idea identifiers in a set
return res.)eys*,
def _compute*self-cr-uid-ids-field_name-arg-conte1tG6=,:
res G 6=
for idea in self.bro&se*cr-uid-ids-conte1tGconte1t,:
vote_num G len*idea.vote_ids,
vote_sum G sum*:v.vote for v in idea.vote_ids;,
res:idea.id; G 6
.vote_sum.: vote_sum-
.vote_avg.: *vote_sum/vote_num, if vote_num else 7.7-
=
return res
_columns G 6
# hese fields are recomputed &henever one of the votes changes
.vote_avg.: fields.function*_compute- methodGrue- stringG.5otes Jverage.-
store G 6.idea.vote.: *_get_idea_from_vote-:.vote.;-"7,=-multiG.votes.,-
.vote_sum.: fields.function*_compute- methodGrue- stringG.5otes Ium.-
store G 6.idea.vote.: *_get_idea_from_vote-:.vote.;-"7,=-multiG.votes.,-
=
)ommunity 0 )ontributing
,penERP pro#ects are hosted on LaunchPad0LP4, where all pro#ect resources ma" %e found) Ba+aar %ranches, %ug trac&ing,
%lueprints, roadmap, -A9s, etc$ Create a free account on launchpad$net to %e a%le to contri%ute$
$aunchpa! groups
Group* Members Bazaar/LP restrictions
*pen/!) :uality Team
(;openerp)
OpenL3P Core ;e+, C+n ,erge +nd co,,it on o//ici+l br+nches.
*pen/!) Commiters
(;openerp-commiter)
Selected +ctive co,,)nity ,e,bers C+n ,+r7 br+nches to be ,erged into o//ici+l br+nch. C+n co,,it on
extra-addons br+nch
*pen/!) (rivers
(;openerp-drivers)
Selected +ctive co,,)nity ,e,bers C+n con/ir, b)gs +nd set ,ilestones on b)gs bl)eprints
*pen/!) Community
(;openerp-community)
Open gro)p- +nyone c+n join C+n cre+te co,,)nity br+nches 5here everyone c+n contrib)te
0Members of upper 1roups are also members of loer 1roups
Copyright 2010 Open Object Press - All rights reserved See license on p. 18. 1%18
!#$
!#%
!#8
!#&
!$0
!$1
!$2
!$!
!$"
!$#
!$$
!$%
!$8
!$&
!%0
!%1
!%2
!%!
!%"
!%#
!%$
!%%
!%8
!%&
!80
!81
!82
!8!
!8"
!8#
!8$
!8%
!88
!8&
!&0
$icense
Cop"right H AFEF ,pen ,%#ect Press$ All rights reser!ed$
8ou ma" ta&e electronic cop" of this wor& and distri%ute it if "ou don?t change the content$ 8ou can also print a cop" to %e
read %" "ourself onl"$
5e ha!e contracts with different pu%lishers in different countries to sell and distri%ute paper or electronic %ased !ersions of
this wor& 0translated or not4 in %oo&stores$ 1his helps to distri%ute and promote the ,pen ERP product$ t also helps us to
create incenti!es to pa" contri%utors and authors with the ro"alties$
>ue to this, grants to translate, modif" or sell this wor& are strictl" for%idden, unless ,penERP s$a$ 0representing ,pen
,%#ect Press4 gi!es "ou a written authori+ation for this$
5hile e!er" precaution has %een ta&en in the preparation of this wor&, the pu%lisher and the authors assume no
responsi%ilit" for errors or omissions, or for damages resulting from the use of the information contained herein$
Pu%lished %" ,pen ,%#ect Press, Grand RosiIre, Belgium
Copyright 2010 Open Object Press - All rights reserved See license on p. 18. 1818

You might also like