You are on page 1of 12

Open Source RAD with OpenERP 7.

PREAMBLE OpenERP is a modern Suite of Business Applications, released under

Compilation tip: OpenERP bein! Python,based, no compilation step is needed

1 2 3 "

the AGPL license, and featuring CRM, HR, Sales, Accounting, Manufacturing, Warehouse Management, Pro ect Management, and more! "t is #ased on a modular, scala#le, and intuiti$e Rapid Application Development (RAD) frame%or& %ritten in P'thon! OpenERP 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 po%er %ith clear s'nta(, and a core &ept small #' design!
Tip: Useful links Main website, with OpenERP downloads: Functional & technical documentation: Community resources: Continous nte!ration ser"er: #earnin! Python: doc.python.or!

T pical !a"aar checkout proce#ure $on De!ian%!ase# &inu'( $ sudo apt-get install bzr # Install Bazaar (version control software) $ bzr cat -d lp:~openerp-dev/openerp-tools/trunk setup s! " s! # #et Installer $ $ake init-v%& # Install 'pen()* % & $ $ake server # +tart 'pen()* +erver wit! e$bedded ,eb

Data!ase creation
After starting the ser$er, open !ttp://local!ost:-&./ in 'our fa$orite #ro%ser! 7ou %ill see the 5ata#ase Manager screen %here 'ou can create a ne% data#ase! Each data#ase has its o%n modules and config, and can #e created in demo mode to test a pre+populated data#ase 2do not use demo mode for a real data#ase:3

)uil#ing an OpenERP mo#ule* i#ea

1he code samples used in this memento are ta&en from a h'pothetical idea module! 1he purpose of this module %ould #e to help creati$e minds, %ho often come up %ith ideas that cannot #e pursued immediatel', and are too easil' forgotten if not logged some%here! "t could #e used to record these ideas, sort them and rate them!

Note: Modular development OpenERP uses modules as %eature containers, to %oster maintainable and robust de"elopment. Modules pro"ide %eature isolation, an appropriate le"el o% abstraction, and ob"ious M-C patterns.

+omposition of a mo#ule
A module ma' contain an' of the follo%ing elements* business objects* declared as P'thon classes e(tending the osv.Model class, the persistence of these resources is completel' managed #' -penERP ; data* 4ML.CS6 files %ith meta+data 2$ie%s and %or&flo%s declaration3, configuration data 2modules parametri,ation3 and demo data 2optional #ut recommended for testing, e!g! sample ideas3 ; wizards* stateful interacti$e forms used to assist users, often a$aila#le as conte(tual actions on resources ; reports* RML 24ML format3, MA<- or -pen-ffice report templates, to #e merged %ith an' &ind of #usiness data, and generate H1ML, -51 or P5= reports!

Installing OpenERP
-penERP is distri#uted as pac&ages.installers for most platforms, #ut can also #e installed from the source on an' platform!

OpenERP Architecture

T pical mo#ule structure

-penERP uses the %ell+&no%n client+ser$er paradigm* the client is running as a /a$ascript application in 'our #ro%ser, connecting to the ser$er using the /S-0+RPC protocol o$er H11P2S3! Ad+hoc clients can also #e easil' %ritten and connect to the ser$er using 4ML+RPC or /S-0+RPC!
Tip: Installation procedure $he procedure %or installin! OpenERP is li&ely to e"ol"e 'dependencies and so on(, so ma&e sure to always chec& the speci%ic documentation 'pac&a!ed & on website( %or the latest procedures. )ee"*.+/install

Each module is contained in its o%n director' %ithin the server/bin/addons director' in the ser$er installation!
Note: .ou can declare your own addons directory in the con%i!uration %ile o% OpenERP 'passed to the ser"er with the -c option( usin! the addons_path option.
# addons/ $ "- idea/ # % "- de$o/ # & "- i3-n/ # ' "- report/ # 10 "- securit1/ # 11 "- view/ # 12 "- wizard/ # 13 "- workflow/ # 1" "- 66init66 p1 # 1# "- 66openerp66 p1 # 1$ "- idea p1 #

Package installation
Windo%s all+in+one installer Linu( Mac all+in+one pac&ages a$aila#le for 5e#ian+#ased 2!de#3 and RedHat+#ased 2!rpm3 distri#utions no all+in+one installer, needs to #e installed from source

0!e $odule director1 2e$o and unit test population data 0ranslation files )eport definitions 2eclaration of groups and access rig!ts 4iews (for$s5lists)5 $enus and actions ,izards definitions ,orkflow definitions *1t!on package initialization (re7uired) $odule declaration (re7uired) *1t!on classes5 t!e $odule8s ob9ects

1he file is the P'thon module descriptor, #ecause an -penERP module is also a regular P'thon module!
1% # I$port all files : directories containing p1t!on code 1& i$port idea5 wizard5 report

Installing from source

1here are t%o alternati$es* using a tar#all pro$ided on the %e#site, or directl' getting the source using Ba,aar 2distri#uted Source 6ersion Control3! 7ou also need to install the re)uired dependencies 2PostgreS8L and a fe% P'thon li#raries 9 see documentation on doc!openerp!com3!

,,init,,.p *

1he is the -penERP module manifest and contains a single P'thon dictionar' %ith the declaration of the module* its name, dependencies, description, and composition! p 1!12

Copyright 2013 Open Object Press - All rights reserved See license on page 12

1' ; 20 8na$e8 : 8Idea85 21 8version8 : 83 &85 22 8aut!or8 : 8'pen()*85 23 8description8 : 8Ideas $anage$ent $odule85 2" 8categor18: 8(nterprise Innovation85 2# 8website8: 8!ttp://www openerp co$85 2$ 8depends8 : <8base8=5 # list of dependencies5 conditioning startup order 2% 8data8 : < # data files to load at $odule install 2& 8securit1/groups >$l85 # alwa1s load groups first? 2' 8securit1/ir $odel access csv85 # load access rig!ts after groups 30 8workflow/workflow >$l85 31 8view/views >$l85 32 8wizard/wizard >$l85 33 8report/report >$l85 3" =5 3# 8de$o8: <8de$o/de$o >$l8=5 # de$o data (for unit tests) 3$ @

,,openerp,,.p *

Pre#efine# os/.os/ attri!utes for !usiness o!-ects

_constraints _sql_constraints _log_access

list o/ t*ples de/ining the Python constraints- in the /or,

(func_name, message, fields) (0%0+

list o/ t*ples de/ining the S89 constraints- in the /or,

(name, sql_def, message) (0$'+

:/ ;r*e (de/a*lt+- " /ields (create6*id- create6date- 5rite6*id5rite6date+ 5ill be *sed to log record-level operations- ,ade accessible via the perm_read() /*nction

O!-ect%Relational .apping Ser/ice 0 OR.

<e' component of -penERP, the -RM is a complete -# ect+Relational mapping la'er, freeing de$elopers from ha$ing to %rite #asic S8L plum#ing! Business o# ects are declared as P'thon classes inheriting from the osv.Model class, %hich ma&es them 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*
3% fro$ osv i$port osv5 fields 3& class idea(osv Aodel): idea 3' 6na$e B 8idea idea8 "0 6colu$ns B ; "1 8na$e8: fields c!ar(80itle85 sizeB.C5 re7uiredB0rue5 translateB0rue)5 "2 8state8: fields selection(<(8draft8582raft8)5 "3 (8confir$ed858Donfir$ed8)=58+tate85re7uiredB0rue5readonl1B0rue)5 "" # 2escription is read-onl1 w!en not draft? "# 8description8: fields te>t(82escription85 readonl1B0rue5 "$ statesB;8draft8: <(8readonl185 Ealse)=@ )5 "% 8active8: fields boolean(8Fctive8)5 "& 8invent6date8: fields date(8Invent date8)5 "' # b1 convention5 $an1Gone fields end wit! 86id8 #0 8inventor6id8: fields $an1Gone(8res partner858Inventor8)5 #1 8inventor6countr16id8: fields related(8inventor6id858countr185 #2 readonl1B0rue5 t1peB8$an1Gone85 #3 relationB8res countr185 stringB8Dountr18)5 #" # b1 convention5 HG$an1 fields end wit! 86ids8 ## 8vote6ids8: fields oneG$an1(8idea vote858idea6id8584otes8)5 #$ 8sponsor6ids8: fields $an1G$an1(8res partner858idea6sponsor6rel85 #% 8idea6id858sponsor6id858+ponsors8)5 #& 8score8: fields float(8+core85digitsB(G53))5 #' 8categor16id8 B $an1Gone(8idea categor185 8Dategor18)5 $0 @ $1 6defaults B ; $2 8active8: 0rue5 # ideas are active b1 default $3 8state8: 8draft85 # ideas are in draft state b1 default $" @ $# def 6c!eck6na$e(self5cr5uid5ids): $$ for idea in self browse(cr5 uid5 ids): $% if 8spa$8 in idea na$e: return Ealse # Dan8t create ideas wit! spa$? $& return 0rue $' 6s7l6constraints B <(8na$e6uni7858uni7ue(na$e)85 8Ideas $ust be uni7ue?8)= %0 6constraints B <(6c!eck6na$e5 8*lease avoid spa$ in ideas ?85 <8na$e8=)= %1

i#ea.p *

_order _rec_name _sql _table

<a,e o/ the /ield *sed to sort the records in lists (de/a*lt2 =id=+ Alternative /ield to *se as na,e- *sed by name_get() (de/a*lt2 =name'+ S89 code to create the table!vie5 /or this object (i/ _auto is >alse+ can be replaced by S89 e?ec*tion in the init() ,ethod S89 table na,e to *se (de/a*lt2 _name 5ith dots = = replaced by *nderscores =6=+

Inheritance mechanisms

Pre#efine# os/.os/ attri!utes for !usiness o!-ects

_name (re)*ired+ _columns (re)*ired+ _defaults _auto _inherit _inherits

OR. fiel# t pes

b*siness object na,e- in dot-notation (in ,od*le na,espace+ dictionary ./ield na,e0/ield declaration 1 dictionary2 ./ield na,e0literal or /*nction providing de/a*lt1
6defaults<8na$e8= B la$bda self5cr5uid5conte>t: 8eggs8

-# 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 #et%een o# ects 2one@man', man'@one, man'@man'3! !"nctional fields are not stored in the data#ase #ut calculated on+the+fl' as P'thon functions! Rele$ant e(amples in the idea class a#o$e are indicated %ith the corresponding line num#ers 2A44,443

i/ True (de/a*lt+ the O34 5ill create the database table set to False to create yo*r o5n table!vie5 5ithin the init() ,ethod
_name o/ the parent b*siness object (/or inheritance+

OR. fiel#s t pes

Common attributes supported by all fields (optional unless specified)

/or decoration inheritance2 dictionary ,apping the 6name o/ the parent b*siness object(s+ to the na,es o/ the corresponding /oreign 7ey /ields to *se

Copyright 2013 Open Object Press - All rights reserved See license on page 12

p 2!12

string /ield label (required) required True i/ ,andatory readonly True i/ not editable help help tooltip select True to create a

OR. fiel#s t pes conte!t dictionary 5ith conte?t*al

OR. fiel#s t pes

function(fnct, arg#&one, fnct_inv#&one, fnct_inv_arg#&one, type#'float', fnct_search#&one, ob'#&one, store#$alse, multi#$alse,%)

database inde? on this col*,n

!oolean(...) integer(...) #ate(...) #atetime(...) time(...) char(string,si"e,translate#$alse,..) te't (string, translate#$alse, %)

para,eters (/or relational /ields+ change_default ;r*e i/ /ield sho*ld be *sable as condition /or de/a*lt val*es in clients states dyna,ic changes to this /ield=s co,,on attrib*tes based on the state /ield

Functional field simulating a real field! computed rather than stored

Simple fields
8active8: fields boolean(8Fctive8)5 8priorit18: fields integer(8*riorit18)5 8start6date8: fields date(8+tart 2ate8)5

Text-based fields

translate True i/ /ield val*es can be translated by *sers- /or char/te!t /ields si"e optional ,a? si@e /or char /ields (0"1-"#+

fnct /*nction to co,p*te the /ield val*e (required) def fnct(self, cr, uid, ids, field_name, arg, conte!t) ret*rns a dictionary * ids+values , 5ith val*es o/ type type fnct_inv /*nction *sed to 5rite a val*e in the /ield instead def fnct_inv(ob', cr, uid, id, name, value, fnct_inv_arg, conte!t) type type o/ si,*lated /ield (can be any other type e?cept =/*nction=+ fnct_search /*nction *sed to search on this /ield def fnct_search(ob', cr, uid, ob', name, args) ret*rns a list o/ t*ples arg*,ents /or search()- e g -('id','in',-(,.,/0)0 ob'2 ,odel _name o/ si,*lated /ield i/ it is a relational /ield store, multi 2 opti,i@ation ,echanis,s (see *sage in Per/or,ance Section+

float(string, digits#&one, ...)

Decimal value
selection(values, string, ...)

digits t*ple (precision- scale+ (0#&+

Field allowing selection among a set of predefined values

values list o/ val*es (7ey-label t*ples+ or /*nction ret*rning s*ch a list (required) (0"2+ filters optional /ilena,e /ilters /or selection

relate# (f(, f), %, type#'float', %) 'hortcut field e(uivalent to browsing chained fields f(,f),... chained /ields to reach target (f1 required) (0#1+ type2 type o/ target /ield propert (ob', type#'float', vie1_load#&one, group_name#&one, %)

!inar (string, filters#&one, ...)

Field for storing a file or binary content.

reference(string, selection, si"e,..)

8picture8: fields binar1(8*icture85 filtersB8H png5H gif8)

Dynamic attribute with specific access rights ob' object (required) type2 type o/ e)*ivalent /ield
one/many 0 many/one are symmetric

Field with dynamic relationship to any other ob ect! associated with an assistant widget

selection ,odel _name o/ allo5ed objects types and corresponding label (sa,e /or,at as values /or selection /ields+ (required) si"e si@e o/ te?t col*,n *sed to store it (storage /or,at is =model_name,ob'ect_id' +
8contact8: fields reference(8Dontact85< (8res partner858*artner8)5 (8res partner contact858Dontact8)=)

Tip: relational fields symmetry

many/many 0 many/many are symmetric when in"ersed 'swap field( and field) i% e1plicit( one/many 0 many/one 2 many/one 0 one/many 3 many/many

Special 2 Reser/e# fiel# names

Relational fields

A fe% field names are reser$ed for pre+defined #eha$ior in -penERP! Some of them are created automaticall' #' the s'stem, and in that case an' field %ih that name %ill #e ignored! id name active sequence state parent_id

Common attributes supported by relational fields

man 1one(ob', ondelete#'set null', %) (0#0+

domain optional /ilter in the /or, o/ arg*,ents /or search (see search(++ ob' _name o/ destination object (required) ondelete deletion handling- e g =set null ==cascade=- see PostgreS89 doc*,entation ob' _name o/ destination object (required) field_id /ield na,e o/ inverse ,any2one- i e

*ni)*e syste, identi/ier /or the object /ield 5hose val*e is *sed to display the record in lists- etc i/ ,issing- set _rec_name to speci/y another /ield to *se toggle visibility2 records 5ith active set to False are hidden by de/a*lt de/ines order and allo5s dragAdrop reordering i/ visible in list vie5s li/ecycle stages /or the object- *sed by the states attrib*te de/ines tree str*ct*re on records- and enables child_of operator

"elationship towards a parent ob ect (using a foreign #ey)

one1man (ob', field_id, %) (0##+

$irtual relationship towards multiple ob ects (inverse of many%one)

corresponding /oreign 7ey (required)

ob' _name o/ destination object (required) rel2 optional na,e o/ relationship table to *se

man 1man (ob', rel, field(, field), %) (0#$+

&idirectional multiple relationship between ob ects

parent_left - *sed in conj*nction 5ith _parent_store /lag on object- allo5s /aster parent_right access to tree str*ct*res (see also )erformance *ptimi+ation section+ create_date - *sed to log creator- last *pdater- date o/ creation and last *pdate date o/ create_uid - the record disabled i/ _log_access /lag is set to False 1rite_date- (created by O34- do not add the,+ 1rite_uid

(de/a*lt2 a*to-assigned based on ,odel na,es+ field( na,e o/ /ield in rel table storing the id o/ the c*rrent object (de/a*lt2 based on ,odel+ field) na,e o/ /ield in rel table storing the id o/ the target object (de/a*lt2 based on ,odel+
Functional fields

3orking with the OR.

"nheriting from the osv.Model 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 %ithin the P'thon class itself 2see e(amples in the ta#le #elo%3, or from outside the class #' first o#taining an instance $ia the -RM pool s'stem!
%2 class ideaG(osv Aodel): ideaG %3 6in!erit B 8idea idea8 %" def 6score6calc(self5cr5uid5ids5field5arg5conte>tBIone): %# res B ;@ %$ # 0!is loop generates onl1 G 7ueries t!anks to browse()? %% for idea in self browse(cr5uid5ids5conte>tBconte>t): %& su$6vote B su$(<v vote for v in idea vote6ids=)

OR. usage sample

Copyright 2013 Open Object Press - All rights reserved See license on page 12

p 3!12

%' &0 &1 &2 &3 &" &#

avg6vote B su$6vote/len(idea vote6ids) res<idea id= B avg6vote return res 6colu$ns B ; # )eplace static score wit! average of votes 8score8:fields function(6score6calc5t1peB8float8) @

OR. .etho#s on os/..o#el o!-ects

unlink(cr, uid, ids, conte!t#&one)
self unlink(cr5 uid5 <CG5CN=)

Deletes records with the given ids "eturns, True

!rowse(cr, uid, ids, conte!t#&one)

OR. .etho#s on os/..o#el o!-ects *'$ generic accessor self.pool.get('ob'ect_name') ,ay be *sed to
obtain a ,odel /ro, any other Common parameters! used by multiple methods

cr database connection (c*rsor+ uid id o/ *ser per/or,ing the operation ids record ids to per/or, the operation on conte!t optional dictionary o/ conte?t*al
; 8lang8: 8en6J+85 @

Fetches records as ob ects! allowing to use dot-notation to browse fields and relations "eturns, ob ect or list of ob ects re(uested
#efault,get (cr, uid, fields, conte!t#&one)

idea B self browse(cr5 uid5 CG) print 8Idea description:85 idea description print 8Inventor countr1 code:85 idea inventor6id address<&= countr16id code for vote in idea vote6ids: print 84ote PG Gf8 P vote vote

fields list of field names

para,eters- e g
search(cr, uid, domain, offset#2, limit#&one, order#&one, conte!t#&one, count#$alse)

domain /ilter speci/ying search criteria offset2 optional n*,ber o/ records to s7ip limit2 optional ,a? n*,ber o/ records to

"eturns, a dictionary of the default values for fields (set on the ob ect class! by the user preferences! or via the context)
perm,rea# (cr, uid, ids, details#3rue)

defs B self default6get(cr5uid5 <8na$e858active8=) # active s!ould be 0rue b1 default assert defs<8active8=

"eturns, list of ids of records matching the given criteria

order 2 optional col*,ns to sort by (de/a*lt2 self._order + count2 i/ True- ret*rns only the n*,ber o/

records ,atching the criteria- not their ids

"eturns, a list of ownership dictionaries for each re(uested record

#Operators: B5 ?B5 K5 KB5 L5 LB5 like5 ilike5 #in5 not in5 c!ild6of5 parent6left5 parent6rig!t #Prefix operators: 8:8 (default)5 8"85 8?8 #Eetc! non-spa$ partner s!ops M partner NC ids B self searc!(cr5 uid5 < '|'5 (8partner6id85 '!='5 NC)5 '!'5 (8na$e85 'ilike'5 8spa$8)5=5 orderB8partner6id8 )

details 2 i/ True- 4_uid /ields val*es are replaced 5ith pairs (id, name_of_user) ret*rned dictionaries contain2 object id (id+creator *ser id (create_uid+- creation date (create_date+- *pdater *ser id (1rite_uid +*pdate date (1rite_date+
per$s B self per$6read(cr5uid5<CG5CN=) print 8creator:85 per$s<&= get(8create6uid85 8n/a8)

fiel#s,get (cr, uid, fields#&one, conte!t#&one)


list o/ /ield na,es

create(cr, uid, values, conte!t#&one)

values dictionary o/ /ield val*es

Creates a new record with the specified value "eturns, id of the new record
rea#(cr, uid, ids, fields#&one, conte!t#&one)

idea6id B self create(cr5 uid5 ; 8na$e8: 8+pa$ recipe85 8description8 : 8spa$ : eggs85 8inventor6id8: CO5 @)

"eturns a dictionary of field dictionaries! each one describing a field of the business ob ect
fiel#s,/iew,get(cr, uid, vie1_id#&one, vie1_type#'form', conte!t#&one, toolbar#$alse)

class idea(osv osv): idea ( ) 6colu$ns B ; 8na$e8 : fields c!ar(8Ia$e85sizeB.C) ( ) def test6fields6get(self5cr5uid): assert(self fields6get(8na$e8)<8size8= BB .C)

fields optional list o/ /ield na,es to ret*rn (de/a*lt2 all /ields+

results B self read(cr5 uid5 <CG5CN=5 <8na$e85 8inventor6id8=) print 8Inventor:85 results<&=<8inventor6id8=

"eturns, list of dictionaries with re(uested field values

rea#,group(cr, uid, domain, fields, groupby, offset#2, limit#&one, orderby#&one, conte!t#&one)

"eturns a dictionary describing the composition of the re(uested view (including inherited views)
name,get (cr, uid, ids, conte!t#&one)

vie1_id id o/ the vie5 or &one vie1_type2 type o/ vie5 to ret*rn i/ vie56id is &one (=/or,=-=tree=- B+ toolbar True to also ret*rn conte?t actions
def test6fields6view6get(self5cr5uid): idea6ob9 B self pool get(8idea idea8) for$6view B idea6ob9 fields6view6get(cr5uid) # Ideas s!ould be s!own wit! invention date def na$e6get(self5cr5uid5ids): res B <= for r in self read(cr5uid5ids<8na$e858create6date8=) res append((r<8id8=5 8Ps (Ps)8 (r<8na$e8=51ear)) return res

"eturns, list of dictionaries with re(uested field values! grouped by given groupby field(s).

domain2 search /ilter (see search()+ fields list o/ /ield na,es to read groupby 2 /ield or list o/ /ields to gro*p by offset, limit2 see search() orderby2 optional ordering /or the res*lts

"eturns tuples with the text representation of re(uested ob ects for to-many relationships
name,search(cr, uid, name#'', domain#&one, operator#'ili5e', conte!t#&one, limit#62)

K print self read6group(cr5uid5<=5 <8score8=5 <8inventor6id8=) <;8inventor6id8: (35 8Fd$inistrator8)5 8score8: GN5 # aggregated score 8inventor6id6count8: 3G5 # group count @5 ;8inventor6id8: (N5 82e$o8)5 8score8: 3N5 8inventor6id6count8: %5 @=

name object na,e to search /or operator 2 operator /or na,e criterion domain, limit 2 sa,e as /or search()+

"eturns list of ob ect names matching the criteria! used to provide completion for to-many relationships. .(uivalent of search() on name / name_get()

write(cr, uid, ids, values, conte!t#&one)

values dictionary o/ /ield val*es to *pdate

-pdates records with given ids with the given values. "eturns, True
cop (cr, uid, id, defaults,conte!t#&one)

self write(cr5 uid5 <CG5CN=5 ; 8na$e8: 8spa$ : eggs85 8partner6id8: GC5 @)

# Dountries can be searc!ed b1 code or na$e def na$e6searc!(self5cr5uid5na$eB885 do$ainB<=5operatorB8ilike85 conte>tBIone5li$itB-&): ids B <= if na$e and len(na$e) BB G: ids B self searc!(cr5 user5 <(8code85 8B85 na$e)= M args5 li$itBli$it5 conte>tBconte>t) if not ids: ids B self searc!(cr5 user5 <(8na$e85 operator5 na$e)= M args5 li$itBli$it5 conte>tBconte>t) return self na$e6get(cr5uid5ids)

Duplicates record with given id updating it with de/a*lts values. "eturns, True

defaults dictionary o/ /ield val*es to ,odi/y in the copied val*es 5hen creating the d*plicated object

Copyright 2013 Open Object Press - All rights reserved See license on page 12

p "!12

OR. .etho#s on os/..o#el o!-ects e'port,#ata (cr, uid, ids, fields, fields list o/ /ield na,es conte!t#&one) conte!t ,ay contain import_comp (de/a*lt2
.xports fields for selected ob ects! returning a dictionary with a datas matrix. -sed when exporting data via client menu.
import,#ata(cr, uid, fields, data, mode#'init', current_module#'', noupdate#$alse, conte!t#&one, filename#&one)

many)many_field id many)

reconnect %. o# ect>s !ml_id, multiple $alues %. commas reconnect %. o# ect>s database id, multiple $alues %. commas

False+ to ,a7e e?ported data co,patible 5ith import_data() (,ay prevent e?porting so,e /ields+

101 RidR5Rna$eR5R$odel6id:idR5Rgroup6id:idR5Rper$6readR5Rper$6writeR5Rper$6createR5Rper$6unlinkR 102 Raccess6idea6ideaR5Ridea ideaR5R$odel6idea6ideaR5Rbase group6userR535&5&5& 103 Raccess6idea6voteR5Ridea voteR5R$odel6idea6voteR5Rbase group6userR535&5&5&

one)many_field/field creates one)many destination record and sets field $alue

0mports given data in the given module -sed when exporting data via client menu

fields list o/ /ield na,es data data to i,port (see e!port_data()+ mode =init= or =*pdate= /or record creation current_module 2 ,od*le na,e noupdate /lag /or record creation filename2 optional /ile to store partial i,port

.enus an# actions

Actions are declared as regular records and can #e triggered in ? %a's* #' clic&ing on menu items lin&ed to a specific action #' clic&ing on #uttons in $ie%s, if these are connected to actions as conte(tual actions on an o# ect 2$isi#le in the side #ar3 Action declaration

state /or recovery

Tip: use read() throu!h webser"ice calls, but pre%er bro1se() internally

)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, $ie%s, actions, roles, access rights, etc!

10" Lrecord $odelBRir actions act6windowR idBRaction6idRK 10# Lfield na$eBRna$eRKaction na$eL/fieldK 10$ Lfield na$eBRview6idR refBRview6idR/K 10% Lfield na$eBRdo$ainRK<list of N-tuples ($a> GO& c!aracters)=L/fieldK 10& Lfield na$eBRconte>tRK;conte>t dictionar1 ($a> GO& c!aracters)@L/fieldK 10' Lfield na$eBRres6$odelRKob9ect $odel na$eL/fieldK 110 Lfield na$eBRview6t1peRKfor$"treeL/fieldK 111 Lfield na$eBRview6$odeRKfor$5tree5calendar5grap!L/fieldK 112 Lfield na$eBRtargetRKnewL/fieldK 113 Lfield na$eBRsearc!6view6idR refBRsearc!6view6idR/K 11" L/recordK

+ommon 4.& structure

4ML files declared in a module>s data section contain record declarations in the follo%ing form*
&% LQ>$l versionBR3 &R encodingBRutf--RQK && LopenerpK &' LdataK '0 Lrecord $odelBRob9ect6$odel6na$eR idBRob9ect6>$l6idRK '1 Lfield na$eBRfield3RKvalue3L/fieldK '2 Lfield na$eBRfieldGRKvalueGL/fieldK '3 L/recordK '" '# Lrecord $odelBRob9ect6$odel6na$eGR idBRob9ect6>$l6idGRK '$ Lfield na$eBRfield3R refBR$odule ob9ect6>$l6idR/K '% Lfield na$eBRfieldGR evalBRref(8$odule ob9ect6>$l6id8)R/K '& L/recordK '' L/dataK 100 L/openerpK

id name view1id domain context res1model view1type view1mode target search1view1id

identi/ier o/ the action in table ir.actions.act_1indo1- ,*st be *ni)*e action na,e (required) speci/ic vie5 to open (i/ ,issing- highest priority vie5 o/ given type is *sed+ t*ple (see search() arg*,ents+ /or /iltering the content o/ the vie5 conte?t dictionary to pass to the vie5 object ,odel on 5hich the vie5 to open is de/ined set to form to open records in edit ,ode- set to tree /or a hierarchy vie5 only i/ view1type is form- list allo5ed ,odes /or vie5ing records (form! tree! + set to new to open the vie5 in a ne5 5indo5!pop*p identi/ier o/ the search vie5 to replace de/a*lt search /or, (new in version 2.3+

11# L$enuite$ idBR$enu6idR parentBRparent6$enu6idR na$eBRlabelR 11$ actionBRaction6idR groupsBRgroupna$e35groupna$eGR se7uenceBR3&R/K

Menu declaration 1he menuitem element is a shortcut for declaring an record and connect it %ith a corresponding action $ia an record!
id parent name action groups se(uence identi/ier o/ the ,en*ite,- ,*st be *ni)*e e?ternal :C (?,l6id+ o/ the parent ,en* in the hierarchy optional ,en* label (de/a*lt2 action na,e+ identi/ier o/ action to e?ec*te- i/ any list o/ gro*ps that can see this ,en* ite, (i/ ,issing- all gro*ps can see it+ integer inde? /or ordering sibling ,en*ite,s (10-20-30 +

Each t'pe of record 2$ie%, menu, action3 supports a specific set of child entities and attri#utes, #ut all share the follo%ing special attri#utes*
id ref the uni)ue 2per module3 e(ternal identifier of this record 2(mlBid3 ma' #e used instead of normal element content to reference another record 2%or&s cross+module #' prepending the module name3

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 (mlBid Tip: XML Rela N! validation OpenERP "alidates the synta1 and structure o% 4M# %iles, accordin! to a Rela156 !rammar, %ound in server/bin/import_!ml.rng . For manual chec& use 1mllint: !mllint 7rela!ng /path/to/import_!ml.rng 8file9

5iews an# inheritance

6ie%s form a hierarch'! Se$eral $ie%s of the same t'pe can #e declared on the same o# ect, and %ill #e used depending on their priorities! B' declaring an inherited $ie% it is possi#le to add.remo$e features in a $ie%!
11% Lrecord $odelBRir ui viewR idBRview6idRK 11& Lfield na$eBRna$eRKview na$eL/fieldK 11' Lfield na$eBR$odelRKob9ect6na$eL/fieldK 120 L?-- t1pes: tree5for$5calendar5searc!5grap!5gantt5kanban --K 121 Lfield na$eBRt1peRKfor$L/fieldK 122 Lfield na$eBRpriorit1R evalBR3.R/K 123 Lfield na$eBRarc!R t1peBR>$lRK 12" L?-- view content: Lfor$K5 LtreeK5 Lgrap!K5 S --K 12# L/fieldK 12$ L/recordK

6eneric /iew #eclaration

Common CSV syntax CS6 files can also #e added in the data section and the records %ill #e inserted #' the -S6>s import_data() method, using the CS6 filename to determine the target o# ect model! 1he -RM automaticall' reconnects relationships #ased on the follo%ing special column names*
id (!ml_id) many)one_field many)one_field id many) many)many_field column containing identifiers for relationships reconnect man'@one using name_search() reconnect man'@one #ased on o# ect>s !ml_id reconnect man'@one #ased on o# ect>s database id reconnect $ia name_search(), multiple $alues %. commas

id name model type priority arch

*ni)*e vie5 identi/ier vie5 na,e object ,odel on 5hich the vie5 is de/ined (sa,e as res1model in actions+ vie5 type2 form- tree- graph- calendar- search! gantt! #anban vie5 priority- s,aller is higher (de/a*lt2 1$+ architect*re o/ the vie5- see vario*s vie5 types belo5

Copyright 2013 Open Object Press - All rights reserved See license on page 12

p #!12


$to /iew2e#it recor#s( =orms allo% creation.edition or resources, and correspond to 8form9 elements!


Allo5ed ele,ents

all (see #orm elements below)

12% Lfor$ stringBRIdea for$RK 12& Lgroup colBR.R colspanBRCRK 12' Lgroup colspanBROR colBR.RK 130 Lfield na$eBRna$eR colspanBR.R/K 131 Lfield na$eBRinventor6idR/K 132 Lfield na$eBRinventor6countr16idR /K 133 Lfield na$eBRscoreR/K 13" L/groupK 13# Lgroup colspanBR3R colBRGRK 13$ Lfield na$eBRactiveR/KLfield na$eBRinvent6dateR/K 13% L/groupK 13& L/groupK 13' Lnotebook colspanBRCRK 1"0 Lpage stringBR#eneralRK 1"1 Lseparator stringBR2escriptionR/K 1"2 Lfield colspanBRCR na$eBRdescriptionR nolabelBR3R/K 1"3 L/pageK 1"" Lpage stringBR4otesRK 1"# Lfield colspanBRCR na$eBRvote6idsR nolabelBR3RK 1"$ LtreeK 1"% Lfield na$eBRpartner6idR/K 1"& Lfield na$eBRvoteR/K 1"' L/treeK 1#0 L/fieldK 1#1 L/pageK 1#2 Lpage stringBR+ponsorsRK 1#3 Lfield colspanBRCR na$eBRsponsor6idsR nolabelBR3R/K 1#" L/pageK 1## L/notebookK 1#$ Lfield na$eBRstateR/K 1#% Lbutton na$eBRdo6confir$R stringBRDonfir$R t1peBRob9ectR/K 1#& L/for$K

separator newline label group noteboo#! page

clic7able 5idget associated 5ith actions Speci/ic attrib*tes2 type2 type o/ b*tton2 wor#flow (de/a*lt+- ob ect- or action name2 5or7/lo5 signal- /*nction na,e (5itho*t parentheses+ or action to call (depending on type+ confirm2 te?t o/ con/ir,ation ,essage 5hen clic7ed states2 co,,a-separated list o/ states in 5hich this b*tton is sho5n hori@ontal separator line /or str*ct*ring vie5s- 5ith optional label place-holder /or co,pleting the c*rrent line o/ the vie5 /ree-te?t caption or legend in the /or, *sed to organise /ields in gro*ps 5ith optional label (adds /ra,e+ noteboo# ele,ents are tab containers /or page ele,ents Attrib*tes2 name2 label /or the tab!page position2 tabs position in noteboo7 (inside! top! bottom! left! right+

D namic /iews
"n addition to %hat can #e done %ith states and attrs attri#utes, functions ma' #e called #' $ie% elements 2$ia #uttons of t'pe ob'ect, or on_change triggers on fields3 to o#tain d'namic #eha$ior! 1hese functions ma' alter the $ie% interface #' returning a P'thon map %ith the follo%ing entries*

value domain

a dictionary o/ /ield na,es and their ne5 val*es a dictionary o/ /ield na,es and their *pdated do,ains o/ val*e

warning a dictionary 5ith a title and message to sho5 a 5arning dialog

&ists an# 8ierarchical Tree &ists

Ne": t#e v$%& form '(I 7s o% OpenERP *.+ a new %orm "iew 7P has been introduced. t can be turned on by addin! versionBT% &T to the Lfor$K element. $his new %orm 7P allows mi1in! arbitrary 48$M# code with re!ular OpenERP %orm elements. t also introduces a %ew speci%ic elements to produce better,loo&in! %orms, such as Ls!eetK, L!eaderK, LfooterK, and a set o% !eneral purpose C)) classes to customi9e the appearance and beha"ior o% %orm elements. :est practices and e1amples %or the new %orm 7P are a"ailable in the technical documentation: !ttp://doc openerp co$/trunk/developers/server/for$-view-guidelines

List $ie%s include #ield elements, are created %ith t'pe tree, and ha$e a 8tree9 parent element! 1he' are used to define flat lists 2edita#le or not3 and hierarchical lists!


7orm Elements

colors2 list o/ colors or D;49 color codes ,apped to Python conditions editable top or bottom to allo5 in-place edit toolbar2 set to True to display the top level o/ object hierarchies as a side toolbar (only /or hierarchical lists- i e opened 5ith actions that set the view6t1pe to UtreeT instead o/ U$odeT+

Co,,on attrib*tes /or all ele,ents2 string label o/ the ele,ent nolabel2 1 to hide the /ield label colspan2 n*,ber o/ col*,n on 5hich the /ield ,*st span ro1span2 n*,ber o/ ro5s on 5hich the /ield ,*st span col2 n*,ber o/ col*,n this ele,ent ,*st allocate to its child ele,ents invisible 2 4 to hide this ele,ent co,pletely eval2 eval*ate this Python code as ele,ent content (content is string by de/a*lt+ attrs2 Python ,ap de/ining dyna,ic conditions on these attrib*tes2 readonlyinvisible - required based on search t*ples on other /ield val*es field a*to,atic 5idgets depending on the corresponding /ield type Attrib*tes2 string label o/ the /ield /or this partic*lar vie5 nolabel 2 4 to hide the /ield label required2 override required /ield attrib*te /ro, 4odel /or this vie5 readonly2 override readonly /ield attrib*te /ro, 4odel /or this vie5 pass1ord2 True to hide characters typed in this /ield conte!t Python code declaring a conte?t dictionary domain2 Python code declaring list o/ t*ples /or restricting val*es on_change2 Python ,ethod to call 5hen /ield val*e is changed groups2 co,,a-separated list o/ gro*p (id+ allo5ed to see this /ield 1idget2 select alternative /ield 5idget (url! email! image! float1time! reference! html! progressbar! statusbar! handle! etc. + properties dyna,ic 5idget sho5ing all available properties (no attrib*te+

Allo5ed ele,ents #ield, gro"p, separator, tree, b"tton, #ilter, newline

1#' Ltree stringBRIdea DategoriesR toolbarBR3R colorsBRblue:stateBBdraftRK 1$0 Lfield na$eBRna$eR/K 1$1 Lfield na$eBRstateR/K 1$2 L/treeK

Copyright 2013 Open Object Press - All rights reserved See license on page 12

p $!12

9an!an )oar#s

As of -penERP C!D a ne% t'pe $ersatile #oard $ie%, in %hich each record is rendered as a small E&an#an cardF! "t supports dragGdrop to manage the lifec'cle of the &an#an cards #ased on configura#le dimensions! <an#an $ie%s are introduced in the -penERP C!D release notes and defined using the 8We# templating language, documented in the technical documentation* see http*..#it!l'.DHus54t and http*..doc!openerp!com.trun&.de$elopers.%e#.)%e#

1&$ L/groupK 1&% L/searc!K

5iew Inheritance
E(isting $ie%s should #e modif'ing through inherited $ie%s, ne$er directl'! An inherited $ie% references its parent $ie% using the inherit_id field, and ma' add or modif' e(isting elements in the $ie% #' referencing them through 4Path e(pressions, and specif'ing the appropriate position!
Tip: 4Path re%erence can be %ound at www.w;.or!/$R/1path position inside2 p*t inside ,atch (de/a*lt+

6ie%s used to displa' date fields as calendar e$ents 2 8calendar9 parent3

replace2 replace ,atch

before2 p*t be/ore ,atch after2 p*t a/ter ,atch


color2 na,e o/ /ield /or color seg,entation date_start na,e o/ /ield containing event start date!ti,e day_length length o/ a E5or7ingF day in ho*rs (de/a*lt2 &+ date_stop na,e o/ /ield containing event stop date!ti,e

date_delay na,e o/ /ield containing event d*ration

Allo5ed ele,ents

#ield (to de#ine the label #or each calendar event)

1&& L?-- i$proved idea categories list --K 1&' Lrecord idBRidea6categor16listGR $odelBRir ui viewRK 1'0 Lfield na$eBRna$eRKid categor1 listGL/fieldK 1'1 Lfield na$eBR$odelRKir ui viewL/fieldK 1'2 Lfield na$eBRin!erit6idR refBRid6categor16listR/K 1'3 Lfield na$eBRarc!R t1peBR>$lRK 1'" L>pat! e>prBR/tree/field<Vna$eB8description8=R positionBRafterRK 1'# Lfield na$eBRidea6idsR stringBRIu$ber of ideasR/K 1'$ L/>pat!K 1'% L/fieldK 1'& L/recordK

1$3 Lcalendar stringBRIdeasR date6startBRinvent6dateR colorBRinventor6idRK 1$" Lfield na$eBRna$eR/K 1$# L/calendarK

1here are se$eral report engines in -penERP, to produce reports from different sources and in man' formats!

6antt +harts
Bar chart t'picall' used to sho% pro ect schedule 28gantt9 parent element3

Attrib*tes Allo5ed ele,ents

same as 8calendar9 #ield, level

level ele,ents are *sed to de/ine the Gantt chart levels- 5ith the enclosed /ield *sed as label /or that drill-do5n level
1$$ Lgantt stringBRIdeasR date6startBRinvent6dateR colorBRinventor6idRK 1$% Llevel ob9ectBRidea ideaR linkBRidR do$ainBR<=RK 1$& Lfield na$eBRinventor6idR/K 1$' L/levelK 1%0 L/ganttK

+harts $6raphs(
6ie%s used to displa' statistics charts 28graph9 parent element3
Tip: charts are most use%ul with custom "iews e1tractin! ready,to,use statistics

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 %ritten to support additional e(pressions!


type type o/ chart2 bar- pie (de/a*lt+ orientation 2 hori+ontal! vertical

Alternati/e Report 7ormats (see

s(%@rml rml (ml,(sl*rml odt@odt -pen-ffice D!I templates 2!s(%3 con$erted to RML %ith s(%@rml tool, and the RML rendered in H1ML or P5= RML templates rendered directl' as H1ML or P5= 4ML data J 4SL*RML st'lesheets to generate RML -pen-ffice templates 2!odt3 -pen-ffice documents 2!odt3 used to produce directl'

Allo5ed ele,ents #ield, %ith specific #eha$ior* /irst /ield in vie5 is H a?is- 2nd one is I- 3rd one is J 2 /ields re)*ired- 3rd one is optional group attrib*te de/ines the G3OKP LI /ield (set to 1+ operator attrib*te sets the aggregation operator to *se /or other /ields 5hen one /ield is gro*ped (:,4,44,min,ma!+
1%1 Lgrap! stringBR0otal idea score b1 InventorR t1peBRbarRK 1%2 Lfield na$eBRinventor6idR /K 1%3 Lfield na$eBRscoreR operatorBRMR/K 1%" L/grap!K

E'pressions use# in OpenERP report templates

-- 8content9 00

dou#le #rac&ets content is e$aluated as a P'thon e(pression #ased on the follo%ing e(pressions

Search /iews
Search $ie%s customi,e the search panel on top of other $ie%s!

;redefined e!pressions ob'ects contains the list of records to print

Allo5ed ele,ents

#ield, gro"p, separator, label, search, #ilter, newline, properties

filter ele,ents allo5 de/ining b*tton /or do,ain /ilters adding a conte!t attrib*te to /ields ,a7es 5idgets that alter the

search conte?t (*se/*l /or conte?t-sensitive /ields- e g pricelist-dependent prices+

1%# Lsearc! stringBR+earc! IdeasRK 1%$ Lgroup colBR.R colspanBRCRK 1%% Lfilter stringBRA1 IdeasR 1%& do$ainBR<(8inventor6id858B85uid)=R 1%' !elpBRA1 own ideasR/K 1&0 Lfield na$eBRna$eR/K 1&1 Lfield na$eBRdescriptionR/K 1&2 Lfield na$eBRinventor6idR/K 1&3 L?-- following conte>t field is for illustration onl1 --K 1&" Lfield na$eBRinventor6countr16idR widgetBRselectionR 1&# conte>tBR;8inventor6countr18: self@R/K

data comes from the %i,ard launching the report user contains the current user 2bro1se_record, as returned bro1se() 3 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 set3ag('tag(','tag)') replaces the parent RML tag( %ith tag) remove;arent&ode('tag') remo$es parent RML element tag

format=ang(value, digits#), date#$alse, date_time#$alse, grouping#3rue, 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
p %!12

Copyright 2013 Open Object Press - All rights reserved See license on page 12

1'' L?-- 0!e following creates records in ir actions report >$l $odel --K 200 Lreport idBRidea6reportR stringBR*rint IdeasR $odelBRidea ideaR 201 na$eBRidea reportR r$lBRidea/report/idea r$lR K 202 L?-- Jse addons/base_report_designer/wizard/tiny_sxw2rml/tiny_sxw2rml py 203 to generate t!e )AW te$plate file fro$ a s>w te$plate --K


id name string model rml! sxw! xml! xsl auto header groups menu #eywords

*ni)*e report identi/ier na,e /or the report (required) report title (required) object ,odel on 5hich the report is de/ined (required) path to report te,plate so*rces (starting /ro, addons+- depending on report set to False to *se a c*sto, parser- by s*bclassing report_s!1.rml_parse and declaring the report as /ollo5s2
report_s!1.report_s!1(report_name, ob'ect_model,rml_path,parser#custom>lass)



set to False to s*ppress report header (de/a*lt2 True+ co,,a-separated list o/ gro*ps allo5ed to vie5 this report set to True to display this report in the Print ,en* (de/a*lt2 True+ speci/y report type 7ey5ord (de/a*lt2 client1print1multi+

20" Lstor1K 20# Lblock0able st1leBR0ableRK 20$ LtrK 20% LtdKLpara st1leBR0itleRKIdea na$eL/paraK L/tdK 20& LtdKLpara st1leBR0itleRK+coreL/paraK L/tdK 20' L/trK 210 LtrK 211 LtdKLparaK<< repeatIn(ob9ects58o858tr8) == << o na$e ==L/paraKL/tdK 212 LtdKLparaK<< o score ==L/paraKL/tdK 213 L/trK 21" L/block0ableK 21# L/stor1K

Tip: RM# <ser 6uide:,user!uide.pd% ?!ample @M= report e!tract

subflow1id action

logical behavior o/ this node regarding inco,ing transitions2 5*"2 activate on the /irst inco,ing transition (de/a*lt+ 67D2 5aits /or all inco,ing transitions to beco,e valid logical behavior o/ this node regarding o*tgoing transitions2 5*"2 one valid transition necessary- send 5or7ite, on it (de/a*lt+ *"2 send 5or7ite,s on all valid transitions (0 or ,ore+- se)*entially 67D2 send a 5or7ite, on all valid transitions at once (/or7+ type o/ action to per/or, 5hen node is activated by a transition2 dummy to per/or, no operation 5hen activated (de/a*lt+ function to invo7e a /*nction deter,ined by action subflow to e?ec*te the s*b/lo5 5ith subflow1id- invo7ing action to deter,ine the record id o/ the record /or 5hich the s*b/lo5 sho*ld be instantiated :/ action ret*rns no res*lt- the 5or7ite, is deleted stopall to ter,inate the 5or7/lo5 *pon activation i/ 7ind subflow- id o/ the s*b/lo5 to e?ec*te (*se ref attrib*te or search 5ith a t*ple+ object ,ethod call- *sed i/ 7ind is function or subflow. ;his /*nction sho*ld also *pdate the state /ield o/ the object- e g /or a function 7ind2
def action6confir$ed(self5 cr5 uid5 ids): self write(cr5 uid5 ids5 ; 8state8 : 8confir$ed8 @) # S perfor$ ot!er tasks return 0rue

3orkflow Transitions $e#ges(

22% Lrecord idBRtrans6idea6draft6confir$edR $odelBRworkflow transitionRK 22& Lfield na$eBRact6fro$R refBRact6draftR/K 22' Lfield na$eBRact6toR refBRact6confir$edR/K 230 Lfield na$eBRsignalRKbutton6confir$L/fieldK 231 Lfield na$eBRrole6idR refBRidea6$anagerR/K 232 Lfield na$eBRconditionRK3 BB 3L/fieldK 233 L/recordK

Conditions are e$aluated in this order* roleBid, signal, condition e(pression

Wor&flo%s ma' #e associated %ith an' o# ect in -penERP, and are entirel' customi,a#le! Wor&flo%s are used to structure and manage the life+c'cles of #usiness o# ects and documents, and define transitions, triggers, etc! %ith graphical tools! Wor&flo%s, acti$ities 2nodes or actions3 and transitions 2conditions3 are declared as 4ML records, as usual! 1he to&ens that na$igate in %or&flo%s are called wor$items!

act1from! act1to signal role1id condition

identi/iers o/ the so*rce and destination activities na,e o/ a b*tton o/ type 5or7/lo5 that triggers this transition re/erence to the role that *ser ,*st have to trigger the transition (see "oles+ Python e?pression that ,*st eval*ate to True /or transition to be triggered

Tip: OpenERP %eatures a !raphical wor&%low editor, a"ailable by switchin! to the =ia!ram "iew while "iewin! a wor&%low in the )ettin!s>$echnical>?or&%lows

Access control mechanisms must #e com#ined to achie$e a coherent securit' polic'!

3orkflow #eclaration
21$ Lrecord idBRwkf6ideaR $odelBRworkflowRK 21% Lfield na$eBRna$eRKidea basicL/fieldK 21& Lfield na$eBRosvRKidea ideaL/fieldK 21' Lfield na$eBRon6createR evalBR3R/K 220 L/recordK

Wor&flo%s are declared on o# ects that possess a state field 2see the e(ample idea class in the -RM section3

6roup%!ase# access control mechanisms

Groups are created as normal records on the res.groups model, and granted menu access $ia menu definitions! Ho%e$er e$en %ithout a menu, o# ects ma' still #e accessi#le indirectl', so actual object%le"el permissions 2create,read,write,"nlin$3 must #e defined for groups! 1he' are usuall' inserted $ia CS6 files inside modules! "t is also possi#le to restrict access to speci!ic !ields on a $ie% or o# ect using the field>s groups attri#ute!
23" RidR5Rna$eR5R$odel6id:idR5Rgroup6id:idR5Rper$6readR5Rper$6writeR5Rper$6createR5Rper$6unlinkR 23# Raccess6idea6ideaR5Ridea ideaR5R$odel6idea6ideaR5Rbase group6userR5353535& 23$ Raccess6idea6voteR5Ridea voteR5R$odel6idea6voteR5Rbase group6userR5353535&

id name osv on1create

*ni)*e 5or7/lo5 record identi/ier na,e /or the 5or7/lo5 (required) object ,odel on 5hich the 5or7/lo5 is de/ined (required) i/ True- a 5or7ite, is instantiated a*to,atically /or each ne5 osv record

221 Lrecord idBRact6confir$edR $odelBRworkflow activit1RK 222 Lfield na$eBRna$eRKconfir$edL/fieldK 223 Lfield na$eBRwkf6idR refBRwkf6ideaR/K 22" Lfield na$eBRkindRKfunctionL/fieldK 22# Lfield na$eBRactionRKaction6confir$ed()L/fieldK 22$ L/recordK

Wor !low Acti"ities #nodes$

Roles are created as normal records on the res.roles model and used onl' to condition %or&flo% transitions through transitions> role_id attri#ute!

Wi,ards descri#e stateful interacti$e sessions %ith the user through d'namic forms! 1he' are constructed #ased on the osv 0ransientAodel class and automaticall' gar#age+collected after use! 1he'>re defined using the same AP" and $ie%s as regular osv Aodel o# ects!
23% fro$ osv i$port fields5osv

id w#f1id name flow1start flow1stop

*ni)*e activity identi/ier parent 5or7/lo5 identi/ier activity node label True to ,a7e it a =begin= node- receiving a 5or7ite, /or each 5or7/lo5 instance True to ,a7e it an =end= node- ter,inating the 5or7/lo5 5hen all ite,s reach it

3i"ar# mo#els $Transient.o#el(

p &!12

Copyright 2013 Open Object Press - All rights reserved See license on page 12

23& i$port dateti$e 23' class cleanup6wizard(osv 0ransientAodel): cleanup6wizard 2"0 6na$e B 8idea cleanup wizard8 2"1 6colu$ns B ; 2"2 8idea6age8: fields integer(8Fge (in da1s)8)5 2"3 @ 2"" def cleanup(self5cr5uid5ids5conte>tBIone): 2"# idea6ob9 B self pool get(8idea idea8) 2"$ for wiz in self browse(cr5uid5ids): 2"% if wiz idea6age LB N: 2"& raise osv e>cept6osv(8Jser(rror858*lease select a larger age8) 2"' li$it B dateti$e date toda1()-dateti$e ti$edelta(da1sBwiz idea6age) 2#0 ids6to6del B idea6ob9 searc!(cr5uid5 <(8create6date85 8L8 5 2#1 li$it strfti$e(8PX-P$-Pd &&:&&:&&8))=5conte>tBconte>t) 2#2 idea6ob9 unlink(cr5uid5ids6to6del) 2#3 return ;@

30' 8inventor6id8BKnew >$lrpcval($uid5 RintR)5 310 )Z

3i"ar# /iews
2#" Lrecord idBRwizard6idea6cleanupR $odelBRir ui viewRK 2## Lfield na$eBRna$eRKidea cleanup wizard for$L/fieldK 2#$ Lfield na$eBR$odelRKidea cleanup wizardL/fieldK 2#% Lfield na$eBRt1peRKfor$L/fieldK 2#& Lfield na$eBRarc!R t1peBR>$lRK 2#' Lfor$ stringBRIdea Dleanup ,izardRK 2$0 Llabel colspanBRCR stringBR+elect t!e age of ideas to cleanupR/K 2$1 Lfield na$eBRidea6ageR stringBRFge (da1s)R/K 2$2 Lgroup colspanBRCRK 2$3 Lbutton stringBRDancelR specialBRcancelR/K 2$" Lbutton stringBRDleanupR na$eBRcleanupR t1peBRob9ectR/K 2$# L/groupK 2$$ L/for$K 2$% L/fieldK 2$& L/recordK

Wi,ards use regular $ie%s and their #uttons ma' use a special cancel attri#ute to close the %i,ard %indo% %hen clic&ed!

3i"ar# e'ecution
2$' Lrecord idBRaction6idea6cleanup6wizardR $odelBRir actions act6windowRK 2%0 Lfield na$eBRna$eRKDleanupL/fieldK 2%1 Lfield na$eBRt1peRKir actions act6windowL/fieldK 2%2 Lfield na$eBRres6$odelRKidea cleanup wizardL/fieldK 2%3 Lfield na$eBRview6t1peRKfor$L/fieldK 2%" Lfield na$eBRview6$odeRKfor$L/fieldK 2%# Lfield na$eBRtargetRKnewL/fieldK 2%$ L/recordK

Such %i,ards are launched $ia regular action records, %ith a special target field used to open the %i,ard $ie% in a ne% %indo%!

3e!Ser/ices 0 4.&%RP+
-penERP is accessi#le through 4ML+RPC interfaces, for %hich li#raries e(ist in man' languages!
2%% 2%& 2%' 2&0 2&1 2&2 2&" 2&3 2&# 2&$ 2&% 2&& 2&' 2'0 2'1 2'2

P thon e'ample
i$port >$lrpclib # define Y'+05 *')05 2B5 J+()5 *F++ url B 8!ttp://Ps:Pd/>$lrpc/co$$on8 P (Y'+05*')0) sock B >$lrpclib +erver*ro>1(url) uid B sock login(2B5J+()5*F++) print RWogged in as Ps (uid:Pd)R P (J+()5uid) # Dreate a new idea url B 8!ttp://Ps:Pd/>$lrpc/ob9ect8 P (Y'+05*')0) sock B >$lrpclib +erver*ro>1(url) args B ; 8na$e8 : 8Fnot!er idea85 8description8 : 80!is is anot!er idea of $ine85 8inventor6id8: uid5 @ idea6id B sock e>ecute(2B5uid5*F++58idea idea858create85args)

2'3 2'" 2'# 2'$ 2'% 2'& 2'' 300 301 302 303

P8P e'ample
LQ include(8>$lrpc inc8)Z // Jse p!p>$lrpc librar15 available on sourceforge // define $Y'+05 $*')05 $2B5 $J+()5 $*F++ $client B new >$lrpc6client(R!ttp://$Y'+0:$*')0/>$lrpc/co$$onR)Z $$sg B new >$lrpc$sg(RloginR)Z $$sg-Kadd*ara$(new >$lrpcval($2B5 RstringR))Z $$sg-Kadd*ara$(new >$lrpcval($J+()5 RstringR))Z $$sg-Kadd*ara$(new >$lrpcval($*F++5 RstringR))Z resp B $client-Ksend($$sg)Z uid B $resp-Kvalue()-Kscalarval() ec!o RWogged in as $J+() (uid:$uid)R

30# // Dreate a new idea 30" 30$ $arra14al B arra1( 30% 8na$e8BKnew >$lrpcval(RFnot!er IdeaR5 RstringR) 5 30& 8description8BKnew >$lrpcval(R0!is is anot!er idea of $ineR 5 RstringR)5

Copyright 2013 Open Object Press - All rights reserved See license on page 12

p '!12

Copyright 2013 Open Object Press - All rights reserved See license on page 12

p 10!12

Performance Optimi"ation
As Enterprise Management Soft%are t'picall' has to deal %ith large amounts of records, 'ou ma' %ant to pa' attention to the follo%ing anti-patterns, to o#tain consistent performance* 5o not place bro1se() calls inside loops, put them #efore and access onl' the #ro%sed o# ects inside the loop! 1he -RM %ill optimi,e the num#er of data#ase )ueries #ased on the browsed attri#utes! A$oid recursion on o# ect hierarchies 2o# ects %ith a parent_id relationship3, #' adding parent_left and parent_right integer fields on 'our o# ect, and setting _parent_store to 3rue in 'our o# ect class! 1he -RM %ill use a modi#ied preorder tree traversal to #e a#le to perform recursi$e operations 2e!g! child_of 3 %ith data#ase )ueries in O(%) instead of O(n) 5o not use function fields lightl', especiall' if 'ou include them in tree $ie%s! 1o optimi,e function fields, t%o mechanisms are a$aila#le* multi* all fields sharing the same multi attri#ute $alue %ill #e computed %ith one single call to the function, %hich should then return a dictionar' of $alues in its values map store* function fields %ith a store attri#ute %ill #e stored in the data#ase, and recomputed on demand %hen the rele$ant trigger o# ects are modified! 1he format for the trigger specification is as follo%s* store
B ;8$odel8: (6ref6fnct5 fields5 priorit1)@ 2see e(ample #elo%3
311 312 313 31" 31# 31$ 31% 31& 31' 320 321 322 323 32" 32# 32$ 32% 32& 32' 330 331 332 333

def 6get6idea6fro$6vote(self5cr5uid5ids5conte>tBIone): res B ;@ vote6ids B self pool get(8idea vote8) browse(cr5uid5ids5conte>tBconte>t) for v in vote6ids: res<v idea6id id= B 0rue # +tore t!e idea identifiers in a set return res ke1s() def 6co$pute(self5cr5uid5ids5field6na$e5arg5conte>tBIone): res B ;@ for idea in self browse(cr5uid5ids5conte>tBconte>t): vote6nu$ B len(idea vote6ids) vote6su$ B su$(<v vote for v in idea vote6ids=) res<idea id= B ; 8vote6su$8: vote6su$5 8vote6avg8: (vote6su$/vote6nu$) if vote6nu$ else & &5 @ return res 6colu$ns B ; # 0!ese fields are reco$puted w!enever one of t!e votes c!anges 8vote6avg8: fields function(6co$pute5 stringB84otes Fverage85 store B ;8idea vote8: (6get6idea6fro$6vote5<8vote8=53&)@5$ultiB8votes8)5 8vote6su$8: fields function(6co$pute5 stringB84otes +u$85 store B ;8idea vote8: (6get6idea6fro$6vote5<8vote8=53&)@5$ultiB8votes8)5 @

+ommunit 2 +ontri!uting
-penERP pro ects are hosted on Launchpad 2LP3, %here all pro ect resources ma' #e found* Ba,aar #ranches, #ug trac&ing, #lueprints, =A8s, etc! Create a free account on launchpad!net to #e a#le to contri#ute!

&aunchpa# groups
Group* *pen.") 8uality Team (9openerp) *pen.") Drivers (9openerp-drivers) *pen.") Community (9openerp-community) Members OpenM3P Core ;ea, Selected active co,,*nity ,e,bers Open gro*p- anyone can join Bazaar/LP restrictions Can ,erge and co,,it on o//icial branches Can con/ir, b*gs and set ,ilestones on b*gs Can create co,,*nity branches 5here everyone can contrib*te

:;embers of upper groups are also members of lower groups

Copyright 2013 Open Object Press - All rights reserved See license on page 12

p 11!12

Cop'right K @IDI+@ID? -pen -# ect Press! All rights reser$ed! 7ou ma' ta&e electronic cop' of this %or& and distri#ute it if 'ou don>t change the content! 7ou can also print a cop' to #e read #' 'ourself onl'! We ha$e contracts %ith different pu#lishers in different countries to sell and distri#ute paper or electronic #ased $ersions of this %or& 2translated or not3 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 %ith the ro'alties! 5ue to this, grants to translate, modif' or sell this %or& are strictl' for#idden, unless -penERP s!a! 2representing -pen -# ect Press3 gi$es 'ou a %ritten authori,ation for this! While e$er' precaution has #een ta&en in the preparation of this %or&, 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 RosiLre, Belgium

Copyright 2013 Open Object Press - All rights reserved See license on page 12

p 12!12