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 ObjectRelationship 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 openerp-server and openerp-client pac&ages are a!aila%le !ia corresponding pac&age manager Linu' 0e$g$ S"naptic on 6%untu4 loo& online for pac&age installers for the G12 client, as well as tutorials for installing the ser!er 0e$g$ Mac 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
1 2 !

Typical ba aar 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


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$
C,;1E<1

Copyright 2010 Open Object Press - All rights reserved See license on p. 18.

1 18

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$
" # $ % 8 & 10 11 12 1! 1" 1# 1$ 1% 18 1&

addons/ |- idea/ |- test/ |- i"#n/ |- report/ |- security/ |- &izard/ |- __init__.py |- __openerp__.py |- idea.py |- installer.py |- idea_installer.1ml |- idea_vie&.1ml |- idea_&or)flo&.1ml |- idea_demo.1ml |- idea_data.1ml

# # # # # # # # # # # # # # #

he module directory !nit testing data ranslation files $eport definitions %eclaration of groups and access rights 'izards definitions (ython pac)age initialization *re+uired, module declaration *re+uired, (ython classes- the module.s ob/ects 0nstaller python declaration 0nstaller 234 declaration 5ie&s *forms-lists,- menus and actions 'or)flo& definitions %emo data (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( 20 # 0mport all files & directories containing python code 21 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( 22 6 2! .name. : .0dea.2" .version. : .".7.2# .author. : .8pen9$(.2$ .description. : .0deas management module.2% .category.: .9nterprise 0nnovation.28 .&ebsite.: .http://&&&.openerp.com.2& .depends. : :.base.;- # list of dependencies- conditioning startup order !0 .data. : : # data files to load at module init !1 .security/groups.1ml.# al&ays load groups first< !2 .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.!% ;!8 .demo.: :.idea_demo/demo.1ml.;# demo data !& .test.: :.test/test.1ml.;# unit test data "0 .e1ternal_dependencies.: 6.python.::.ma)o.-.simple/son.;"1 .bin.::.&hich.;= # e1ternal dependencies "2 .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.

2 18

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)
"$ "% "8 "& #0 #1 #2 #! #" ## #$ #% #8 #& $0 $1 $2 $! $" $# $$ $% $8 $& %0 %1 %2 %! %" %# %$ %% %8 %& 80

i!ea+py( from osv import osv- fields class idea*osv.osv,: idea _name G .idea.idea. _columns G 6 .name.: fields.char*. itle.- sizeGDB- re+uiredG rue- translateG rue,.state.: fields.selection*:*.draft.-.%raft.,*.confirmed.-.Honfirmed.,;-.Itate.-re+uiredG rue-readonlyG rue,# %escription is read-only &hen not draft< .description.: fields.te1t*.%escription.- readonlyG ruestatesG6.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.readonlyG rue- 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* _columns 're()ired* _defaults _auto _inherit _inherits _constraints _sql_constraints _log_access _order _rec_name _sql _table b)siness object n+,e- in dot-not+tion 'in ,od)le n+,esp+ce* diction+ry ./ield n+,es 0 object /ields decl+r+tions 1 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. 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+ble vie5 5ithin the init() ,ethod _name o/ the p+rent b)siness object '/or prototype inherit+nce* /or ,)ltiple instance inherit+nce ,ech+nis,2 diction+ry ,+pping the 6 name o/ the p+rent b)siness objects to the n+,es o/ the corresponding /oreign 7ey /ields to )se 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* list o/ t)ples de/ining the S89 constr+ints- in the /or, (name, sql_def, message). 'message ,+y be c+ll+ble* '0$&* :/ ;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 =+,e o/ the /ield )sed to sort the records in lists 'de/+)lt2 <id<* Altern+tive /ield to )se +s n+,e- )sed by osv<s name_get() 'de/+)lt2 <name'* S89 code to cre+te the t+ble vie5 /or this object 'i/ _auto is >+lse* c+n be repl+ced by S89 e?ec)tion in the init() ,ethod 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

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) conte t: diction+ry 5ith conte?t)+l p+r+,eters '/or rel+tion+l /ields* required: True i/ ,+nd+tory change_default: ;r)e i/ /ield sho)ld be )s+ble +s condition /or de/+)lt v+l)es in clients readonly: True i/ not edit+ble states: dyn+,ic ch+nges to this /ield<s co,,on +ttrib)tes b+sed on the state help: help tooltip /ield '0"2-"$* select: True to opti,i@e /or list /iltering '5ith d+t+b+se inde?*- to incl)de in se+rch vie5s "imple fields .active.: fields.boolean*.Jctive.,boolean(...) integer(...) !ate(...) !atetime(...) time(...) .priority.: fields.integer*.(riority.,.start_date.: fields.date*.Itart %ate.,char(string,si!e,translate"#alse,..) te%t(string, translate"#alse, $) Text-based fields float(string, digits"%one, ...) Floating-point value with arbitrary precision and scale selection(values, string, ...) Field allowing selection among a set of predefined values binary(string, filters"%one, ...) Field for storing a file or binary content. reference(string, selection, si!e,..) Field with dynamic relationship to any other object associated with an assistant widget 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-"#* digits: t)ple 'precision- sc+le* '0#8* . :/ digits is not provided- it<s + /lo+t- not + deci,+l type. values: list o/ v+l)es '7ey-l+bel t)ples* or /)nction ret)rning s)ch + list (required) '0"2* filters: option+l /ilen+,e /ilters .picture.: fields.binary*.(icture.filtersG.K.png-K.gif., 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 domain: option+l restriction in the /or, o/ +rg),ents /or se+rch 'see search'** many/one(ob&, ondelete"'set null', $) '0#0* ob&: _name o/ destin+tion object (required) !elationship towards a parent object (using a foreign "ey) ondelete: deletion h+ndling- e.g. <set null<- <cascade<- see PostgreS89 doc),ent+tion one/many(ob&, field_id, $) '0##* ob&: _name o/ destin+tion object (required) #irtual relationship towards multiple objects (inverse of field_id: /ield n+,e o/ inverse ,+ny2one- i.e. corresponding /oreign 7ey many$one) (required) many/many(ob&, rel, field', field(, $) '0#$* ob&: _name o/ destin+tion object (required) %idirectional multiple relationship between objects 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) Common attributes supported by relational fields
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, conte t) 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, conte t) 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$ )ni()e syste, identi/ier /or the object 'cre+ted by O34- do not +dd it* id name active sequence state parent_id parent_leftparent_right create_datecreate_uid0rite_date0rite_uid 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 de/ines visibility2 records 5ith active set to False +re hidden by de/+)lt de/ines order +nd +llo5s dr+gAdrop reordering i/ incl)ded in list vie5s de/ines li/e-cycle st+ges /or the object- )sed /or 5or7/lo5s de/ines tree str)ct)re on records- +nd en+bles child_of oper+tor )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* )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 81 class idea@*osv.osv,: idea@ 82 _name G .idea.idea. 8! _inherit G .idea.idea. 8" def _score_calc*self-cr-uid-ids-field-arg-conte1tGLone,: 8# res G 6= 8$ # his loop generates only @ +ueries than)s to bro&se*,< 8% for idea in self.bro&se*cr-uid-ids-conte1tGconte1t,: 88 sum_vote G sum*:v.vote for v in idea.vote_ids;, 8& avg_vote G sum_vote/len*idea.vote_ids, &0 res:idea.id; G avg_vote &1 return res &2 _columns G 6 &! # $eplace static score &ith average of votes &" .score.:fields.function*_score_calc-typeG.float.-methodG rue, &# = &$ idea@*,

Copyright 2010 Open Object Press - All rights reserved See license on p. 18.

# 18

OR. .etho!s on os,+os, objects 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 conte t: option+l diction+ry o/ conte?t)+l p+r+,eters- s)ch +s )ser l+ng)+ge 6 .lang.: .en_!I.- ... = *&# generic accessor create(cr, uid, values, conte t"%one) Creates a new record with the specified value !eturns, id of the new record search(cr, uid, args, offset"1, limit"%one, order"%one, conte t"%one, count"#alse) !eturns, list of ids of records matching the given criteria values: diction+ry o/ /ield v+l)es /or the record idea_id G self.create*cr- uid6 .name.: .Ipam recipe..description. : .spam & eggs..inventor_id.: BC-=, 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., 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.; values: diction+ry o/ /ield v+l)es to )pd+te self.&rite*cr- uid- :B@-BA;6 .name.: .spam & eggs..partner_id.: @B-=, defaults: diction+ry o/ /ield v+l)es to ch+nge be/ore s+ving the d)plic+ted object self.unlin)*cr- uid- :B@-BA;,

rea!(cr, user, ids, fields"%one, conte t"%one) !eturns, list of dictionaries with re'uested field values write(cr, uid, ids, values, conte t"%one) -pdates records with given ids with the given values. !eturns, True copy(cr, uid, id, defaults,conte t"%one) (uplicates record with given id updating it with de/+)lts values. !eturns, True unlink(cr, uid, ids, conte t"%one) (eletes records with the given ids !eturns, True browse(cr, uid, ids, conte t"%one) Fetches records as objects allowing to use dot-notation to browse fields and relations !eturns, object or list of objects re'uested !efault*get(cr, uid, fields, conte t"%one) !eturns, a dictionary of the default values for fields (set on the object class by the user preferences or via the context) log(cr, uid, id, details"2rue) !eturns, id of the record created in res.log perm*rea!(cr, uid, ids, details"2rue) !eturns, a list of ownership dictionaries for each re'uested record

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 fields2 list o/ /ield n+,es defs G self.default_get*cr-uid:.name.-.active.;, # active should be rue by default assert defs:.active.; message2 ,ess+ge to 5rite conte t2 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-,, 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., 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

rea!*group(cr, uid, domain, fields, groupby, offset"1, limit"%one, conte t"%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..

Copyright 2010 Open Object Press - All rights reserved See license on p. 18.

$ 18

fiel!s*get(cr, uid, fields"%one, conte t"%one)

OR. .etho!s on os,+os, objects fields: list o/ /ield n+,es class idea*osv.osv,: idea *..., !eturns a dictionary of field dictionaries each one describing a _columns G 6 field of the business object .name. : fields.char*.Lame.-sizeGDB, *..., def test_fields_get*self-cr-uid,: assert*self.fields_get*.name.,:.size.; GG DB, 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, # 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

fiel!s*,iew*get(cr, uid, vie0_id"%one, vie0_type"'form', conte t"%one, toolbar"#alse) !eturns a dictionary describing the composition of the re'uested view (including inherited views and extensions) name*get(cr, uid, ids, conte t")+) !eturns tuples with the text representation of re'uested objects for to-many relationships

name*search(cr, uid, name"'', args"%one, operator"'ili4e', conte t"%one, limit"51)

name: object n+,e to se+rch /or operator2 oper+tor /or n+,e criterion args, limit2 s+,e +s /or search()* !eturns list of object names matching the criteria used to provide # Hountries can be searched by code or name completion for to-many relationships. /'uivalent of search() on def name_search*self-cr-uid-nameG..name 0 name_get() 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 argslimitGlimit- conte1tGconte1t, if not ids: ids G self.search*cr- user:*.name.- operator- name,; O argslimitGlimit- conte1tGconte1t, return self.name_get*cr-uid-ids, fields: list o/ /ield n+,es conte t ,+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* fields: list o/ /ield n+,es data: d+t+ to i,port 'see e port_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

e%port*!ata(cr, uid, ids, fields, conte t"%one) /xports fields for selected objects 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) 1mports given data in the given module -sed when exporting data via client menu

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 &8 NopenerpM && NdataM 100 Nrecord modelGRob/ect_model_nameR idGRob/ect_1ml_idRM 101 Nfield nameGRfield"RMvalue"N/fieldM 102 Nfield nameGRfield@RMvalue@N/fieldM 10! N/recordM 10" Nrecord modelGRob/ect_model_name@R idGRob/ect_1ml_id@RM 10# Nfield nameGRfield"R refGRmodule.ob/ect_1ml_idR/M 10$ Nfield nameGRfield@R evalGRref*.module.ob/ect_1ml_id.,R/M 10% N/recordM 108 N/dataM 10& 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

id ref eval

the uni(ue 0per module4 <ML identifier of this record 0'mlDid4 used instead of element content to reference another record 0wor&s cross*module %" prepending the module name4 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 6rela ng /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, 110 RidR-RnameR-Rmodel_id:idR-Rgroup_id:idR-Rperm_readR-Rperm_&riteR-Rperm_createR-Rperm_unlin)R 111 Raccess_idea_ideaR-Ridea.ideaR-Rmodel_idea_ideaR-Rbase.group_userR-"-7-7-7 112 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 11! Nrecord modelGRir.actions.act_&indo&R idGRaction_idRM 11" Nfield nameGRnameRMaction.nameN/fieldM 11# Nfield nameGRvie&_idR refGRvie&_idR/M 11$ Nfield nameGRdomainRM:list of A-tuples *ma1 @C7 characters,;N/fieldM 11% Nfield nameGRconte1tRM6conte1t dictionary *ma1 @C7 characters,=N/fieldM 118 Nfield nameGRres_modelRMob/ect.model.nameN/fieldM 11& Nfield nameGRvie&_typeRMform|treeN/fieldM 120 Nfield nameGRvie&_modeRMform-tree-calendar-graphN/fieldM 121 Nfield nameGRtargetRMne&N/fieldM 122 Nfield nameGRsearch_vie&_idR refGRsearch_vie&_idR/M 12! N/recordM id name view2id domain context res2model view2type view2mode target search2view2id identi/ier o/ the +ction in t+ble ir.actions.act_0indo0- ,)st be )ni()e +ction n+,e (required) speci/ic vie5 to open 'i/ ,issing- highest priority vie5 o/ given type is )sed* t)ple 'see search() +rg),ents* /or /iltering the content o/ the vie5 conte?t diction+ry to p+ss to the vie5. >or the se+rch vie52 'search_default_fieldname':'value' object ,odel on 5hich the vie5 to open is de/ined set to form to open records in edit ,ode- set to tree /or + tree vie5 only i/ view2type is form- list +llo5ed ,odes /or vie5ing records 'form tree ...* set to new to open the vie5 in + ne5 5indo5 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$ 12" Nmenuitem idGRmenu_idR parentGRparent_menu_idR 12# nameGRlabelR actionGRaction_idR iconGRicon-codeR 12$ groupsGRgroupname"-groupname@R se+uenceGR"7R/M id parent name action icon groups se'uence identi/ier o/ the ,en)ite,- ,)st be )ni()e id o/ the p+rent ,en) in the hier+rchy Option+l ,en) l+bel 'de/+)lt2 +ction n+,e* identi/ier o/ +ction to e?ec)te- i/ +ny icon to )se /or this ,en) 'e.g. terp-graph- &T*C42*)/5- see doc.opernerp.co,* list o/ gro)ps th+t c+n see this ,en) ite, 'i/ ,issing- +ll gro)ps c+n see it* integer inde? /or ordering sibling ,en)ite,s '10-20-!0..*
Copyright 2010 Open Object Press - All rights reserved See license on p. 18. 8 18

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$
12% 128 12& 1!0 1!1 1!2 1!! 1!" 1!#

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 name model type priority arch )ni()e vie5 identi/ier vie5 n+,e object ,odel on 5hich the vie5 is de/ined 's+,e +s res2model in +ctions* vie5 type2 form- tree- graph- calendar- search gantt 'search is ne5 in #.2* vie5 priority- s,+ller is higher 'de/+)lt2 1$* +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) 1!$ Nform stringGR0dea formRM 1!% Ngroup colGRDR colspanGRBRM 1!8 Ngroup colspanGRCR colGRDRM 1!& Nfield nameGRnameR selectGR"R colspanGRDR/M 1"0 Nfield nameGRinventor_idR selectGR"R/M 1"1 Nfield nameGRinventor_country_idR /M 1"2 Nfield nameGRscoreR selectGR@R/M 1"! N/groupM 1"" Ngroup colspanGR"R colGR@RM 1"# Nfield nameGRactiveR/MNfield nameGRinvent_dateR/M 1"$ N/groupM 1"% N/groupM 1"8 Nnoteboo) colspanGRBRM 1"& Npage stringGRTeneralRM 1#0 Nseparator stringGR%escriptionR/M 1#1 Nfield colspanGRBR nameGRdescriptionR nolabelGR"R/M 1#2 N/pageM 1#! Npage stringGR5otesRM 1#" Nfield colspanGRBR nameGRvote_idsR nolabelGR"R selectGR"RM 1## NtreeM 1#$ Nfield nameGRpartner_idR/M 1#% Nfield nameGRvoteR/M 1#8 N/treeM 1#& N/fieldM 1$0 N/pageM 1$1 Npage stringGRIponsorsRM 1$2 Nfield colspanGRBR nameGRsponsor_idsR nolabelGR"R selectGR"R/M 1$! N/pageM 1$" N/noteboo)M 1$# Nfield nameGRstateR/M 1$$ Nbutton nameGRdo_confirmR stringGRHonfirmR iconGRgt)-o)R typeGRob/ectR/M 1$% N/formM

Copyright 2010 Open Object Press - All rights reserved See license on p. 18.

& 18

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 conte t: 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+b p+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 1$8 Ntree stringGR0dea HategoriesR toolbarGR"R colorsGRblue:stateGGdraftRM 1$& Nfield nameGRnameR conte1tGR6.group_by.: :.inventor_id.;=R/M 1%0 Nfield nameGRstateR/M 1%1 N/treeM )alen!ars 7iews used to displa" date fields as calendar e!ents 0 7calendar8 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+te ti,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+te ti,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) 1%2 Ncalendar stringGR0deasR date_startGRinvent_dateR colorGRinventor_idRM 1%! Nfield nameGRnameR/M 1%" N/calendarM

Copyright 2010 Open Object Press - All rights reserved See license on p. 18.

10 18

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 drilldo5n level 1%# Ngantt stringGR0deasR date_startGRinvent_dateR colorGRinventor_idRM 1%$ Nlevel ob/ectGRidea.ideaR lin)GRidR domainGR:;RM 1%% Nfield nameGRinventor_idR/M 1%8 N/levelM 1%& 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 * 180 Ngraph stringGR otal idea score by 0nventorR typeGRbarRM 181 Nfield nameGRinventor_idR /M 182 Nfield nameGRscoreR operatorGROR/M 18! N/graphM Diagrams Edita%le wor&flow*li&e !iews 07diagram8 parent element4 Allo5ed node has the following attri%utes) ele,ents 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 + conte t +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* 18" Nsearch stringGRIearch 0deasRM 18# Ngroup colGRDR colspanGRBR e1pandGR7RM 18$ Nfilter stringGR3y 0deasR iconGRterp-partnerR 18% domainGR:*.inventor_id.-.G.-uid,;R 188 helpGR3y o&n ideasR/M 18& Nfield nameGRnameR selectGR rueR/M 1&0 Nfield nameGRdescriptionR selectGR rueR/M 1&1 Nfield nameGRinventor_idR selectGR rueR/M 1&2 Nseparator orientationGUverticalRM 1&! N<-- follo&ing conte1t field is for illustration only --M 1&" Nfield nameGRinventor_country_idR selectGR rueR &idgetGRselectionR 1&# conte1tGR6.inventor_country.: self=R/M 1&$ N/groupM 1&% N/searchM 1&8

Copyright 2010 Open Object Press - All rights reserved See license on p. 18.

11 18

)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 inside2 pl+ced inside ,+tch 'de/+)lt* before2 pl+ced be/ore ,+tch position attributes2 )sed 5ith 7attribute8 t+gs to +dd ne5 replace2 repl+ce ,+tch after2 pl+ced +/ter ,+tch +ttrib)tes 1&& N<-- improved idea categories list --M 200 Nrecord idGRidea_category_list@R modelGRir.ui.vie&RM 201 Nfield nameGRnameRMid.category.list@N/fieldM 202 Nfield nameGRmodelRMir.ui.vie&N/fieldM 20! Nfield nameGRinherit_idR refGRid_category_listR/M 20" Nfield nameGRarchR typeGR1mlRM 20# N1path e1prGR/tree/field:VnameG.description.;R positionGRafterRM 20$ Nfield nameGRidea_idsR stringGRLumber of ideasR/M 20% N/1pathM 208 N/fieldM 20& 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) ,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 e pressions: 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 210 N<-- he follo&ing creates records in ir.actions.report.1ml model --M 211 Nreport idGRidea_reportR stringGR(rint 0deasR modelGRidea.ideaR 212 nameGRidea.reportR rmlGRidea/report/idea.rmlR M 21! N<-- !se addons/base_report_designer/wizard/tiny_sxw2rml/tiny_sxw2rml py 21" to generate the $34 template file from a .s1& template --M id name string model rml sxw xml xsl auto )ni()e report identi/ier n+,e /or the report (required) report title (required) object ,odel on 5hich the report is de/ined (required) p+th to report te,pl+te so)rces 'st+rting /ro, addons*- depending on report set to False to )se + c)sto, p+rser- by s)bcl+ssing report_s 0.rml_parse +nd decl+ring the report +s /ollo5s2 report_s 0.report_s 0(report_name, ob&ect_model,rml_path,parser"custom>lass)
Copyright 2010 Open Object Press - All rights reserved See license on p. 18. 12 18

s'wArml

header groups menu "eywords

set to False to s)ppress report he+der 'de/+)lt2 True* co,,+-sep+r+ted list o/ gro)ps +llo5ed to vie5 this report set to True to lin7 the report 5ith the Print icon 'de/+)lt2 True* speci/y report type 7ey5ord 'de/+)lt2 client2print2multi *

Tip: RML 6ser Guide) www$reportla%$com/docs/rmlApdf*userguide$pdf ? ample @A= report e tract: 21# NstoryM 21$ Nbloc) able styleGR ableRM 21% NtrM 218 NtdMNpara styleGR itleRM0dea nameN/paraM N/tdM 21& NtdMNpara styleGR itleRMIcoreN/paraM N/tdM 220 N/trM 221 NtrM 222 NtdMNparaM:: repeat0n*ob/ects-.o.-.tr., ;; :: o.name ;;N/paraMN/tdM 22! NtdMNparaM:: o.score ;;N/paraMN/tdM 22" N/trM 22# N/bloc) ableM 22$ 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
22% 228 22& 2!0 2!1

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 name osv on2create )ni()e 5or7/lo5 record identi/ier n+,e /or the 5or7/lo5 (required) object ,odel on 5hich the 5or7/lo5 is de/ined (required) i/ True- + 5or7ite, is inst+nti+ted +)to,+tic+lly /or e+ch ne5 osv record

2!2 2!! 2!" 2!# 2!$ 2!%

,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 w"f2id name flow2start flow2stop join2mode split2mode )ni()e +ctivity identi/ier p+rent 5or7/lo5 identi/ier +ctivity node l+bel True to ,+7e it + <begin< node- receiving + 5or7ite, /or e+ch 5or7/lo5 inst+nce True to ,+7e it +n <end< node- ter,in+ting the 5or7/lo5 5hen +ll ite,s re+ch it 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 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* 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 i/ 7ind subflow- id o/ the s)b/lo5 to e?ec)te ')se ref +ttrib)te or search 5ith + t)ple* 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

"ind

subflow2id action

1orkflow Transitions "e!ges& Conditions are e!aluated in this order) groupDid, signal, condition e'pression 2!8 Nrecord idGRtrans_idea_draft_confirmedR modelGR&or)flo&.transitionRM 2!& Nfield nameGRact_fromR refGRact_draftR/M 2"0 Nfield nameGRact_toR refGRact_confirmedR/M 2"1 Nfield nameGRsignalRMbutton_confirmN/fieldM 2"2 Nfield nameGRgroup_idR refGRidea_managerR/M 2"! Nfield nameGRconditionRM" GG "N/fieldM 2"" N/recordM act2from act2to signal group2id condition identi/iers o/ the so)rce +nd destin+tion +ctivities n+,e o/ + b)tton o/ type 5or7/lo5 th+t triggers this tr+nsition re/erence to the gro)p the )ser ,)st belong to in order to trigger the tr+nsition 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$
2"# 2"$ 2"%

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

1i ar!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$ 1i ar! objects "os,*memory& n*memor" o%#ects are created %" e'tending os!$os!Dmemor") 2"8 from osv import fields-osv 2"& import datetime 2#0 class cleanup_&izard*osv.osv_memory,: cleanup_&izard 2#1 _name G .idea.cleanup.&izard. 2#2 _columns G 6 2#! .idea_age.: fields.integer*.Jge *in days,.,2#" = 2## def cleanup*self-cr-uid-ids-conte1tG6=,: 2#$ idea_ob/ G self.pool.get*.idea.idea., 2#% for &iz in self.bro&se*cr-uid-ids,: 2#8 if &iz.idea_age NG A: 2#& raise osv.e1cept_osv*.!ser9rror.-.(lease select a larger age., 2$0 limit G datetime.date.today*,-datetime.timedelta*daysG&iz.idea_age, 2$1 ids_to_del G idea_ob/.search*cr-uid- :*.create_date.- .N. 2$2 limit.strftime*.PW-Pm-Pd 77:77:77.,,;-conte1tGconte1t, 2$! idea_ob/.unlin)*cr-uid-ids_to_del, 2$" return 6= 2$# 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$ 2$$ Nrecord idGR&izard_idea_cleanupR modelGRir.ui.vie&RM 2$% Nfield nameGRnameRMidea.cleanup.&izard.formN/fieldM 2$8 Nfield nameGRmodelRMidea.cleanup.&izardN/fieldM 2$& Nfield nameGRtypeRMformN/fieldM 2%0 Nfield nameGRarchR typeGR1mlRM 2%1 Nform stringGR0dea Hleanup 'izardRM 2%2 Nlabel colspanGRBR stringGRIelect the age of ideas to cleanupR/M 2%! Nfield nameGRidea_ageR stringGRJge *days,R/M 2%" Ngroup colspanGRBRM 2%# Nbutton stringGRHancelR specialGRcancelR iconGRgt)-cancelR/M 2%$ Nbutton stringGRHleanupR nameGRcleanupR typeGRob/ectR iconGRgt)-o)R/M 2%% N/groupM 2%8 N/formM 2%& N/fieldM 280 N/recordM
Copyright 2010 Open Object Press - All rights reserved See license on p. 18. 1" 18

1i ar! 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) 281 Nact_&indo& idGRaction_idea_cleanup_&izardR nameGRHleanup ideasR 282 res_modelGRidea.cleanup.&izardR src_modelGRidea.ideaR 28! vie&_typeGRformR vie&_modeGRformR 28" )ey@GRclient_action_multiR targetGRne&R 28# N<-- )ey@ can also be client_print_multi or client_action_relate --M 28$ multiGR rueR/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 28% import 1mlrpclib 288 # ... define X8I - (8$ - %?- !I9$- (JII 28& url G .http://Ps:Pd/1mlrpc/common. P *X8I -(8$ , 2&0 soc) G 1mlrpclib.Ierver(ro1y*url, 2&1 uid G soc).login*%?-!I9$-(JII, 2&2 print R4ogged in as Ps *uid:Pd,R P *!I9$-uid, 2&! 2&" # Hreate a ne& idea 2&# url G .http://Ps:Pd/1mlrpc/ob/ect. P *X8I -(8$ , 2&$ soc) G 1mlrpclib.Ierver(ro1y*url, 2&% args G 6 2&8 .name. : .Jnother idea.2&& .description. : . his is another idea of mine.!00 .inventor_id.: uid!01 = !02 idea_id G soc).e1ecute*%?-uid-(JII-.idea.idea.-.create.-args,
!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&

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*R his 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

Internationali ation
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

!!0 !!1 !!2 !!! !!" !!#

|- idea/ |- i"#n/ | - idea.pot | - fr.po | - pt_?$.po | *...,

# he module directory # ranslation files # ranslation emplate *e1ported from 8pen9$(, # >rench translation # ?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 !!8 Nfield nameGRdescriptionRMJ sample idea for performing testsN/fieldM !!& Nfield nameGRinvent_dateRM@7"77"7"N/fieldM !"0 N/recordM !"1 Nassert idGRidea_test_"R modelGRidea.ideaR severityGR&arningR !"2 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 !"8 stringGRHonfirm button does not &or)<RM !"& Ntest e1prGRstate GG .confirmed.R/M !#0 N/assertM !#1 Nfunction modelGRidea.ideaR nameGRunlin)RM !#2 Nvalue evalGRref*.idea_test_".,R/M !#! N/functionM !#" Nassert searchGR:*.name.-.G.-.!nit est 0dea.;R modelGRidea.ideaR countGR7R !## severityGR&arningR stringGR est 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* Per/or, test's* +nd /+il 5ith given string i/ tests do not p+ss. assert 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 e pr 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 Send + 5or7/lo5 sign+l on + given object 0or4flo0 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

Recurrent jobs
!#$ !#% !#8 !#& !$0 !$1 !$2 !$! !$" !$# !$$ !$%

1he ir.cron model is used to setup recurrent tas&s$ Nrecord idGRtas)_idR modelGRir.cronRM Nfield nameGRnameRM as) 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 evalGR rue|>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 Optimi ation


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
!$8 !$& !%0 !%1 !%2 !%! !%" !%# !%$ !%% !%8 !%& !80 !81 !82 !8! !8" !8# !8$ !8% !88 !8& !&0

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- methodG rue- stringG.5otes Jverage.store G 6.idea.vote.: *_get_idea_from_vote-:.vote.;-"7,=-multiG.votes.,.vote_sum.: fields.function*_compute- methodG rue- 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 *pen/!) :uality Team OpenL3P Core ;e+, (;openerp) *pen/!) Commiters Selected +ctive co,,)nity ,e,bers (;openerp-commiter) *pen/!) (rivers Selected +ctive co,,)nity ,e,bers (;openerp-drivers) *pen/!) Community Open gro)p- +nyone c+n join (;openerp-community) 0Members of upper 1roups are also members of lo er Bazaar/LP restrictions C+n ,erge +nd co,,it on o//ici+l br+nches. C+n ,+r7 br+nches to be ,erged into o//ici+l br+nch. C+n co,,it on extra-addons br+nch C+n con/ir, b)gs +nd set ,ilestones on b)gs bl)eprints C+n cre+te co,,)nity br+nches 5here everyone c+n contrib)te 1roups

Copyright 2010 Open Object Press - All rights reserved See license on p. 18.

1% 18

$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.

18 18

You might also like