You are on page 1of 7

Open Source RAD with OpenObject

PREAMBLE OpenERP is a modern Enterprise Management Software, released

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

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$

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

OpenObject features a complete and modular tool%o' for (uic&l" %uilding applications) integrated Object-Relationship Mapping (ORM) support, template*%ased Model-View-Controller (MVC) interfaces, a report generation s"stem, automated internationali+ation, and much more$ Python is a high*le!el d"namic programming language, ideal for RAD, com%ining power with clear s"nta', and a core &ept small %" design$
Tip: Useful links Main we%site, with ,penERP downloads) www$openerp$com -unctional . technical documentation) doc$openerp$com Communit" resources) www$launchpad$net/open*o%#ect ntegration ser!er) test,openo%#ect$com Learning P"thon) doc$p"thon$org ,penERP E*Learning platform) edu$openerp$com

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$

-* -. --2 -3 -4 -5 -) -6 -7 2* 2. 222 23 24 25

.version. : .".2.( .author. : .3pen4$,.( .description. : .0deas management module.( .category.: .4nterprise 0nnovation.( .%ebsite.: .http://%%%.openerp.com.( .depends. : 5.base.6( # list of dependencies( conditioning startup order .update_7ml. : 5 # data files to load at module init .security/groups.7ml.( # al%ays load groups first8 .security/ir.model.access.csv.( # load access rights after groups .%or+flo%/%or+flo%.7ml.( .vie%/vie%s.7ml.( .%izard/%izard.7ml.( .report/report.7ml.( 6( .demo_7ml.: 5.demo/demo.7ml.6( # demo data 'for unit tests) .active.: 9alse( # %hether to install automatically at ne% !: creation ;

Object Ser,ice - OR.

'uil!ing an OpenERP mo!ule( i!ea


C,;1E<1

1he code samples used in this memento are ta&en from a h"pothetical idea module$ 1he purpose of this module would %e to help creati!e minds, who often come up with ideas that cannot %e pursued immediatel", and are too easil" forgotten if not logged somewhere$ t could %e used to record these ideas, sort them and rate them$
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$

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%#ectAs characteristics for the ,RM)
2) 26 27 3* 3. 332 33 34 35 3) 36 37 4* 4. 442 43 44 45 4) 46 47 5* 5. 552 53 54 55 5) 56 57 )* ).

i!ea+py(

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$

)omposition of a mo!ule

OpenERP Architecture

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


,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

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$
3 4 5 ) 6 7 .* .. ..2 .3 .4

Package installation
5indows Linu' Mac

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 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$ de!team$ta&ti&$%e4

addons/ |- idea/ |- demo/ |- i"#n/ |- report/ |- security/ |- vie%/ |- %izard/ |- %or+flo%/ |- __init__.py |- __terp__.py |- idea.py

# # # # # # # # # # #

he module directory !emo and unit test population data ranslation files $eport definitions !eclaration of groups and access rights &ie%s 'forms(lists)( menus and actions *izards definitions *or+flo% definitions ,ython pac+age initialization 're-uired) module declaration 're-uired) ,ython classes( the module.s ob/ects

from osv import osv( fields class idea'osv.osv): idea _name < .idea.idea. _columns < 1 .name.: fields.char'. itle.( size<=>( re-uired< rue( translate< rue)( .state.: fields.selection'5'.draft.(.!raft.)( '.confirmed.(.?onfirmed.)6(.@tate.(re-uired< rue(readonly< rue)( # !escription is read-only %hen not draft8 .description.: fields.te7t'.!escription.( readonly< rue( states<1.draft.: 5'.readonly.( 9alse)6; )( .active.: fields.boolean'.Active.)( .invent_date.: fields.date'.0nvent date.)( # by convention( manyBone fields end %ith ._id. .inventor_id.: fields.manyBone'.res.partner.(.0nventor.)( .inventor_country_id.: fields.related'.inventor_id.(.country.( readonly< rue( type<.manyBone.( relation<.res.country.( string<.?ountry.)( # by convention( CBmany fields end %ith ._ids. .vote_ids.: fields.oneBmany'.idea.vote.(.idea_id.(.&otes.)( .sponsor_ids.: fields.manyBmany'.res.partner.(.idea_sponsor_rel.( .idea_id.(.sponsor_id.(.@ponsors.)( .score.: fields.float'.@core.(digits<'B("))( .category_id. < manyBone'.idea.category.( .?ategory.)( ; _defaults < 1 .active.: lambda Ca: "( # ideas are active by default .state.: lambda Ca: .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 9alse # ?an.t create ideas %ith spam8 return rue _s-l_constraints < 5'.name_uni-.(.uni-ue'name).( .0dea must be uni-ue8.)6 _constraints < 5'_chec+_name(.,lease avoid spam in ideas 8.( 5.name.6)6 idea') # 0nstantiate the class

Pre!efine! os,+os, attributes for business objects


_name (required) _columns (required) _defaults _auto _inherit _inherits

business object name, in dot-notation (in module namespace) dictionary {field names object fields declarations } dictionary: { field names functions providing defaults }
_defaults5.name.6 < lambda self(cr(uid(conte7t: .eggs.

1he __init__.py file is the P"thon module descriptor, %ecause an ,penERP module is also a regular P"thon module$
.5 .)

**init**+py(

if True (default) the !" #ill create the database table $ set to False to create your o#n table%vie# #ithin the init() method
_name of the parent business object (for prototype inheritance)

# 0mport all files & directories containing python code import idea( %izard( report

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

1he __terp__.py 0or __openerp__.py as of !?$@4 is the ,penERP descriptor and contains a single P"thon dictionar" with the actual declaration of the module) its name, dependencies, description, and composition$
.6 .7

for multiple % instance inheritance mechanism: dictionary mapping the &name of the parent business objects to the names of the corresponding foreign 'ey fields to use list of tuples defining the (ython constraints, in the form
(func_name, message, fields). ()*)

**terp**+py(
1

_constraints

.name. : .0dea.(

+opyright , -*.* pen bject (ress - /ll rights reserved $ 0ee license on page )1

p1.%)

Pre!efine! os,+os, attributes for business objects


_sql_constraints _log_access

OR. fiel!s types


boolean(...) integer(...) !ate(...) !atetime(...) time(...) char(string,si e,translate!"alse,..) te%t (string, translate!"alse, #)
.active.: fields.boolean'.Active.)( .priority.: fields.integer'.,riority.)( .start_date.: fields.date'.@tart !ate.)(

OR. fiel!s types


property(ob%, type!&float&, vie0_load!$one, group_name!$one, #)

list of tuples defining the 089 constraints, in the form


(name, sql_def, message). (57)

:f ;rue (default), 3 fields (create&uid, create&date, #rite&uid, #rite&date) #ill be used to log record-level operations, made accessible via osv<s perm_read() function =ame of the field used to sort the records in lists (default: <id<) /lternative field to use as name, used by osv<s name_get() (default: _name) 089 code to create the table%vie# for this object (if _auto is >alse) $ can be replaced by 089 e?ecution in the init() method 089 table name to use (default: _name #ith dots <1< replaced by underscores <&<)

Text-based fields
float(string, digits!$one, ...)

_order _rec_name _sql _table

translate: True if field values can be translated by users si e: ma?imum si@e for char fields (3.,34) digits: tuple (precision, scale) (46) 1 :f digits

)ynamic attribute with specific access rights ob%: object (required) type: type of equivalent field
one@man" D man"@one are s"mmetric

Tip: relational fields s$mmetr$

Floating-point value with arbitrary precision and scale Field allowing selection among a set of predefined values

is not provided, it<s a float, not a decimal type1


values: list of values ('ey-label tuples) or function returning such a list (required) (3-) filters: optional filename filters

man"@man" D man"@man" are s"mmetric when in!ersed 0swap field' and field() one@man" D man"@one 3 man"@one D one@man" E man"@man"

selection(values, string, ...)

Special 0 Reser,e! fiel! names

binary(string, filters!$one, ...)

A few field names are reser!ed for pre*defined %eha!ior in ,pen,%#ect$ Some of them are created automaticall" %" the s"stem, and in that case an" field with that name will %e ignored$ id name active sequence state parent_id

Inheritance mechanisms

Field for storing a file or binary content.


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

.picture.: fields.binary'.,icture.( filters<.C.png(C.gif.)

unique system identifier for the object (created by !", do not add it) defines the value used by default to display the record in lists, etc1 if missing, set _rec_name to specify another field to use for this purpose defines visibility: records #ith active set to False are hidden by default defines order and allo#s dragAdrop reordering if included in list vie#s defines life-cycle stages for the object, used for #or'flo#s defines tree structure on records, and enables child_of operator

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

selection: model _name of allo#ed objects types and corresponding label (same format as values for selection fields) (required) si e: si@e of te?t column used to store it (as te?t: <model_name,ob%ect_id& ) (required)
.contact.: fields.reference'.?ontact.(5 '.res.partner.(.,artner.)( '.res.partner.contact.(.?ontact.)6( "B#)

Relational fields

Common attributes supported by relational fields


many/one(ob%, ondelete!&set null&, #) (4*)

domain: optional restriction in the form of arguments for search (see search()) ob%: _name of destination object (required) ondelete: deletion handling, e1g1 <set null <, <cascade<, see (ostgre089 documentation ob%: _name of destination object (required) field_id: field name of inverse many-one, i1e1

parent_left , used in conjunction #ith _parent_store flag on object, allo#s faster parent_right access to tree structures (see also *erformance +ptimi,ation section) create_date, used to log creator, last updater, date of creation and last update date of create_uid , the record1 disabled if _log_access flag is set to False 0rite_date, (created by !", do not add them) 0rite_uid

"elationship towards a parent ob ect (using a foreign #ey) $irtual relationship towards multiple ob ects (inverse of many%one)

one/many(ob%, field_id, #) (44)

1orking with the OR.

corresponding foreign 'ey (required)


ob%: _name of destination object (required) rel: relationship table to use (required) field': name of field in rel table storing the id

many/many(ob%, rel, field', field(, #) (45)

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$
))2 )3 )4 )5 )) )6 )7 6* 6. 662 63 64 65 6)

&idirectional multiple relationship between ob ects

OR. usage sample

of the current object (required) field(: name of field in rel table storing the id of the target object (required)
#unctional fields

OR. fiel! types

,%#ects ma" contain B 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 0one@man", man"@one, man"@man"4$ $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 with the corresponding line num%ers 0C<<,<<4

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

OR. fiel!s types


Common attributes supported by all fields (optional unless specified)

string: field label (required) required: True if mandatory readonly: True if not editable help: help tooltip select: 1 to include in search

vie#s and optimi@e for list filtering (#ith database inde?)

context: dictionary #ith conte?tual parameters (for relational fields) change_default: ;rue if field should be usable as condition for default values in clients states: dynamic changes to this field<s common attributes based on the state field (3-,35) "imple fields

fnct: function to compute the field value (required) def fnct(self, cr, uid, ids, field_name, arg, context) returns a dictionary ) ids*values + #ith values of type type fnct_inv: function used to #rite a value in the field instead def fnct_inv(ob%, cr, uid, id, name, value, fnct_inv_arg, context) type: type of simulated field (any other type besides <function<) fnct_search: function used to search on this field def fnct_search(ob%, cr, uid, ob%, name, args) returns a list of tuples arguments for search(), e1g1 ,(&id&,&in&,,',-,./)/ ob%: model _name of simulated field if it is a relational field store, multi: optimi@ation mechanisms (see usage in (erformance 0ection)

class ideaB'osv.osv): ideaB _name < .idea.idea. _inherit < .idea.idea. def _score_calc'self (cr(uid(ids(field(arg(conte7t<Done): res < 1; # his loop generates only B -ueries than+s to bro%se')8 for idea in self .bro%se'cr(uid(ids(conte7t<conte7t): sum_vote < sum'5v.vote for v in idea.vote_ids6) avg_vote < sum_vote/len'idea.vote_ids) res5idea.id6 < avg_vote return res _columns < 1 # $eplace static score %ith average of votes .score.:fields.function'_score_calc(type<.float.(method< rue) ; ideaB')

+'$ generic accessor

OR. .etho!s on os,+os, objects self.pool.get(&ob%ect_name&) may be used to


obtain a model class from any#here

Common parameters! used by multiple methods

relate! (f', f(, #, type!&float&, #) 'hortcut field e(uivalent to browsing chained fields f',f(,...: chained fields to reach target (f1 required) (4.) type: type of target field

cr: database connection (cursor) uid: id of user performing the operation ids: list of record ids, or single integer #hen

there is only one id context: optional dictionary of conte?tual parameters, such as user language e1g1 1 .lang.: .en_E@.( ... ;

+opyright , -*.* pen bject (ress - /ll rights reserved $ 0ee license on page )1

p1-%)

context!$one)

OR. .etho!s on os,+os, objects create(cr, uid, values, values: dictionary of field values for the
record Creates a new record with the specified value "eturns- id of the new record
search(cr, uid, args, offset!1, limit!$one, order!$one, context!$one, count!"alse)
idea_id < self.create'cr( uid( 1 .name.: .@pam recipe.( .description. : .spam & eggs.( .inventor_id.: >F( ;)

OR. .etho!s on os,+os, objects fiel!s*get (cr, uid, fields!$one, fields: list of field names
context!$one)

"eturns a dictionary of field dictionaries! each one describing a field of the business ob ect
fiel!s*,iew*get(cr, uid, vie0_id!$one, vie0_type!&form&, context!$one, toolbar!"alse)

class idea'osv.osv): idea '...) _columns < 1 .name. : fields.char'.Dame.(size<=>) '...) def test_fields_get'self(cr(uid): assert'self.fields_get'.name.)5.size.6 << =>)

75 7) 76 77 .** .*.

Hrecord model<Mob/ect_model_nameBM id<Mob/ect_7ml_idBMG Hfield name<Mfield"M ref<Mmodule.ob/ect_7ml_idM/G Hfield name<MfieldBM eval<Mref'.module.ob/ect_7ml_id.)M/G H/recordG H/dataG H/openerpG

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)
id ref the uni(ue 0per module4 <ML identifier of this record 0'mlFid4 used instead of element content to reference another record 0wor&s cross*module %" prepending the module name4

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

args: list of tuples specifying search criteria offset: optional number of records to s'ip limit : optional ma? number of records to

return
order: optional columns to sort by (default: self._order ) count: if True, returns only the number of

"eturns a dictionary describing the composition of the re(uested view (including inherited views and extensions)
name*get (cr, uid, ids, context!)+)

vie0_id: id of the vie# or $one vie0_type: type of vie# to return if vie#&id is $one (<form<,<tree<, 111) toolbar: True to include conte?tual actions
def test_fields_vie%_get'self(cr(uid): idea_ob/ < self.pool.get'.idea.idea.) form_vie% < idea_ob/.fields_vie%_get'cr(uid) # 0deas should be sho%n %ith invention date def name_get'self(cr(uid(ids): res < 56 for r in self.read'cr(uid(ids5.name.(.create_date.6) res.append''r5.id.6( .Ks 'Ks). 'r5.name.6(year)) return res

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 'mlFid 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_xml.rng$ -or manual chec& use 'mllint) xmllint 6relaxng /path/to/import_xml.rng 7file8

records matching the criteria, not their ids


#Operators: <( 8<( G( G<( H( H<( li+e( ili+e( #in( not in( child_of( parent_left( parent_right #Prefix operators: .&. 'default)( .|.( .8. #9etch non-spam partner shops I partner J> ids < self.search'cr( uid( 5 '|'( '.partner_id.( '!='( J>)( '!'( '.name.( 'ilike'( .spam.)(6( order<.partner_id. )

"eturns tuples with the text representation of re(uested ob ects for to-many relationships
name*search(cr, uid, name!&&, args!$one, operator!&ili4e&, context!$one, limit!51)

rea!(cr, user, ids, fields!$one, context!$one)

fields: optional list of field names to return (default: all fields)


results < self.read'cr( uid( 5>B(>J6( 5.name.( .inventor_id.6) print .0nventor:.( results5265.inventor_id.6

name: object name to search for operator : operator for name criterion args, limit: same as for search() )

Common C") s$nta' CS7 files can also %e added in update_xml, and the records will %e inserted %" the ,S7As importFdata04 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 (xml_id) many(one_field many(one_field:id many(one_field.id many(many_field many(many_field:id many(many_field.id column containing identifiers for relationships reconnect man"@one using name_search() reconnect man"@one %ased on o%#ectAs xml_id reconnect man"@one %ased on o%#ectAs database id reconnects !ia name_search(), repeat for multiple !alues reconnects with o%#ectAs xml_id, repeat for multiple !alues reconnects with o%#ectAs database id, repeat for multiple !alues

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


write(cr, uid, ids, values, context!$one)

values: dictionary of field values to update

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

.pdates records with given ids with the given values. "eturns- True
copy(cr, uid, id, defaults,context!$one)

self.%rite'cr( uid( 5>B(>J6( 1 .name.: .spam & eggs.( .partner_id.: B>( ;)

defaults: dictionary of field values to change e%port*!ata(cr, uid, ids, fields, context!$one)

)uplicates record with given id updating it with defaults values. "eturns- True
unlink(cr, uid, ids, context!$one)

before saving the duplicated object

# ?ountries can be searched by code or name def name_search'self(cr(uid(name<..( args<56(operator<.ili+e.(conte7t<1;( limit<#2): ids < 56 if name and len'name) << B: ids < self.search'cr( user( 5'.code.( .<.( name)6 I args( limit<limit( conte7t<conte7t) if not ids: ids < self.search'cr( user( 5'.name.( operator( name)6 I args( limit<limit( conte7t<conte7t) return self.name_get'cr(uid(ids)

.*.*2 .*3

one(many_field/field creates one(many destination record and sets field !alue ir+mo!el+access+cs,
MidM(MnameM(Mmodel_id:idM(Mgroup_id:idM(Mperm_readM(Mperm_%riteM(Mperm_createM(Mperm_unlin+M Maccess_idea_ideaM(Midea.ideaM(Mmodel_idea_ideaM(Mbase.group_userM("(2(2(2 Maccess_idea_voteM(Midea.voteM(Mmodel_idea_voteM(Mbase.group_userM("(2(2(2

fields: list of field names context may contain import_comp (default:

.enus an! actions

self.unlin+'cr( uid( 5>B(>J6)

)eletes records with the given ids "eturns- True


browse(cr, uid, ids, context!$one)

/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, context!$one, filename!$one)

False) to ma'e e?ported data compatible #ith import_data() (may prevent e?porting some fields)

Actions are declared as regular records and can %e triggered in B 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
.*4 .*5 .*) .*6 .*7 ..* ... ....2 ..3 ..4

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, context!$one)

idea < self.bro%se'cr( uid( >B) print .0dea description:.( idea.description print .0nventor country code:.( idea.inventor_id.address526.country_id.code for vote in idea.vote_ids: print .&ote KB.Bf. K vote.vote

1mports given data in the given module .sed when exporting data via client menu

fields: list of field names data: data to import (see export_data()) mode: <init< or <update< for record creation current_module : module name noupdate: flag for record creation filename: optional file to store partial import

*ction declaration
Hrecord model<Mir.actions.act_%indo%M id<Maction_idMG Hfield name<MnameMGaction.nameH/fieldG Hfield name<Mvie%_idM ref<Mvie%_idM/G Hfield name<MdomainMG5list of J-tuples 'ma7 BF2 characters)6H/fieldG Hfield name<Mconte7tMG1conte7t dictionary 'ma7 BF2 characters);H/fieldG Hfield name<Mres_modelMGob/ect.model.nameH/fieldG Hfield name<Mvie%_typeMGform|treeH/fieldG Hfield name<Mvie%_modeMGform(tree(calendar(graphH/fieldG Hfield name<MtargetMGne%H/fieldG Hfield name<Msearch_vie%_idM ref<Msearch_vie%_idM/G H/recordG

fields: list of field names

state for recovery

"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!2rue)

defs < self.default_get'cr(uid( 5.name.(.active.6) # active should be rue by default assert defs5.active.6

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, roles, access rights, etc$

details : if True, 3_uid fields are replaced

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

#ith the name of the user returned dictionaries contain: object id (id), creator user id (create_uid ), creation date (create_date), updater user id (0rite_uid ), update date (0rite_date)
perms < self.perm_read'cr(uid(5>B(>J6) print .creator:.( perms526.get'.create_uid.( .n/a.)

)ommon 2.$ structure


66 67 7* 7. 772 73 74

<ML files declared in a moduleAs updateF'ml attri%ute contain record declarations in the following form)
HL7ml version<M".2M encoding<Mutf-#MLG HopenerpG HdataG Hrecord model<Mob/ect_model_nameM id<Mob/ect_7ml_idMG Hfield name<Mfield"MGvalue"H/fieldG Hfield name<MfieldBMGvalueBH/fieldG H/recordG

id name view2id domain context res2model view2type view2mode target search2view2id

identifier of the action in table ir.actions.act_0indo0, must be unique action name (required) specific vie# to open (if missing, highest priority vie# of given type is used) tuple (see search() arguments) for filtering the content of the vie# conte?t dictionary to pass to the vie# object model on #hich the vie# to open is defined set to form to open records in edit mode, set to tree for a tree vie# only if view2type is form, list allo#ed modes for vie#ing records (form! tree! 111) set to new to open the vie# in a ne# #indo# identifier of the search vie# to replace default search form (new in version 3.%)

..5 ..)

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$
Hmenuitem id<Mmenu_idM parent<Mparent_menu_idM name<MlabelM icon<Micon-codeM action<Maction_idM groups<Mgroupname"(groupnameBM se-uence<M"2M/G

id

identifier of the menuitem, must be unique

+opyright , -*.* pen bject (ress - /ll rights reserved $ 0ee license on page )1

p12%)

parent name action icon groups se(uence

id of the parent menu in the hierarchy ptional menu label (default: action name) identifier of action to e?ecute, if any icon to use for this menu (e1g1 terp-graph, 'T+C42+*/5, see doc1opernerp1com) list of groups that can see this menu item (if missing, all groups can see it) integer inde? for ordering sibling menuitems (.*,-*,2*11)

5orm Elements

)alen!ars
/ttributes

3iews an! inheritance


4eneric ,iew !eclaration

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$
..6 ..7 .-* .-. .-.-2 .-3 .-4 .-5

Hrecord model<Mir.ui.vie%M id<Mvie%_idMG Hfield name<MnameMGvie%.nameH/fieldG Hfield name<MmodelMGob/ect_nameH/fieldG Hfield name<MtypeMGformH/fieldG # tree(form(calendar(search(graph(gantt Hfield name<MpriorityM eval<M"=M/G Hfield name<MarchM type<M7mlMG H8-- vie% content: HformG( HtreeG( HgraphG( N --G H/fieldG H/recordG

id name model type priority arch

unique vie# identifier vie# name object model on #hich the vie# is defined (same as res2model in actions) vie# type: form, tree, graph, calendar, search! gantt (search is ne# in 41-) vie# priority, smaller is higher (default: .5) architecture of the vie#, see various vie# types belo#

5orms
.-) .-6 .-7 .2* .2. .2.22 .23 .24 .25 .2) .26 .27 .3* .3. .3.32 .33 .34 .35 .3) .36 .37 .4* .4. .4.42 .43 .44 .45 .4) .46

"to ,iew0e!it recor!s& -orms allow creation/edition or resources, and correspond to 7form8 elements$

/llo#ed elements

all (see %orm elements below)

Hform string<M0dea formMG Hgroup col<M=M colspan<M>MG Hgroup colspan<MFM col<M=MG Hfield name<MnameM select<M"M colspan<M=M/G Hfield name<Minventor_idM select<M"M/G Hfield name<Minventor_country_idM /G Hfield name<MscoreM select<MBM/G H/groupG Hgroup colspan<M"M col<MBMG Hfield name<MactiveM/GHfield name<Minvent_dateM/G H/groupG H/groupG Hnoteboo+ colspan<M>MG Hpage string<MOeneralMG Hseparator string<M!escriptionM/G Hfield colspan<M>M name<MdescriptionM nolabel<M"M/G H/pageG Hpage string<M&otesMG Hfield colspan<M>M name<Mvote_idsM nolabel<M"M select<M"MG HtreeG Hfield name<Mpartner_idM/G Hfield name<MvoteM/G H/treeG H/fieldG H/pageG Hpage string<M@ponsorsMG Hfield colspan<M>M name<Msponsor_idsM nolabel<M"M select<M"M/G H/pageG H/noteboo+G Hfield name<MstateM/G Hbutton name<Mdo_confirmM string<M?onfirmM icon<Mgt+-o+M type<Mob/ectM/G H/formG

+ommon attributes for all elements: string: label of the element nolabel: . to hide the field label colspan: number of column on #hich the field must span ro0span: number of ro#s on #hich the field must span col: number of column this element must allocate to its child elements invisible: 1 to hide this element completely eval: evaluate this (ython code as element content (content is string by default) attrs: (ython map defining dynamic conditions on these attributes: readonly, invisible , required based on search tuples on other field values field automatic #idgets depending on the corresponding field type1 /ttributes: string: label of the field, also for search (overrides field name) select: 1 to sho# the field in normal search, % for advanced only nolabel: . to hide the field label required: override required field attribute readonly: override readonly field attribute pass0ord: True to hide characters typed in this field context: (ython code declaring a conte?t dictionary domain: (ython code declaring list of tuples for restricting values on_change: (ython method call to trigger #hen value is changed groups: comma-separated list of group (id) allo#ed to see this field 0idget: select alternative #idget (url! email! image! float2time! reference! text2wi#i! text2html! progressbar) properties dynamic #idget sho#ing all available properties (no attribute) button clic'able #idget associated #ith actions1 0pecific attributes: type: type of button: wor#flow (default), ob ect, or action name: #or'flo# signal, function name (#ithout parentheses) or action to call (depending on type) confirm: te?t of confirmation message #hen clic'ed states: comma-separated list of states in #hich this button is sho#n icon: optional icon (all B;C 0; +C icons e1g1 gt#-o#) separator hori@ontal separator line for structuring vie#s, #ith optional label newline place-holder for completing the current line of the vie# label free-te?t caption or legend in the form group used to organise fields in groups #ith optional label (adds frame) noteboo#! noteboo# elements are tab containers for page elements1 /ttributes: page name: label for the tab%page position : tabs position in noteboo' (inside! top! bottom! left! right)

7iews used to displa" date fields as calendar e!ents 07calendar8 parent4

color: name of field for color segmentation date_start: name of field containing event start date%time day_length: length of a calendar day in hours (default: 6) date_stop: name of field containing event stop date%time

or
date_delay: name of field containing event duration

/llo#ed elements
.52 .53 .54

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

Hcalendar string<M0deasM date_start<Minvent_dateM color<Minventor_idMG Hfield name<MnameM/G H/calendarG

4antt )harts

Bar chart t"picall" used to show pro#ect schedule 07gantt8 parent element4 same as 7calendar8 /ttributes

/llo#ed elements

%ield, level

level elements are used to define the Bantt chart levels, #ith the enclosed field used as label for that drill-do#n level
.55 .5) .56 .57 .)*

Hgantt string<M0deasM date_start<Minvent_dateM color<Minventor_idMG Hlevel ob/ect<Midea.ideaM lin+<MidM domain<M56MG Hfield name<Minventor_idM/G H/levelG H/ganttG

)harts "4raphs&
/ttributes

7iews used to displa" statistical charts 07graph8 parent element4


Tip: charts are most useful with custom !iews e'tracting read"*to*use statistics

type: type of chart: bar, pie (default) orientation : hori,ontal! vertical

/llo#ed elements %ield, with specific %eha!ior) first field in vie# is D a?is, -nd one is E, 2rd one is F - fields required, 2rd one is optional group attribute defines the B! G( HE field (set to .) operator attribute sets the aggregation operator to use for other fields #hen one field is grouped (9,3,33,min,max)
.). .).)2 .)3

Hgraph string<M otal idea score by 0nventorM type<MbarMG Hfield name<Minventor_idM /G Hfield name<MscoreM operator<MIM/G H/graphG

Search ,iews "new in ,6+/&

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)

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$ /llo#ed elements %ield, gro$p, separator, label, search, %ilter, newline, properties

value domain

a dictionary of field names and their updated values a dictionary of field names and their updated domains of value
.)4 .)5 .)) .)6 .)7 .6* .6. .6.62 .63 .64 .65 .6)

filter elements allo# defining button for domain filters adding a context attribute to fields ma'es #idgets that alter the

search conte?t (useful for conte?t-sensitive fields, e1g1 pricelistdependent prices)


Hsearch string<M@earch 0deasMG Hgroup col<M=M colspan<M>MG Hfilter string<MPy 0deasM icon<Mterp-partnerM domain<M5'.inventor_id.(.<.(uid)6M help<MPy o%n ideasM/G Hfield name<MnameM select<M"M/G Hfield name<MdescriptionM select<M"M/G Hfield name<Minventor_idM select<M"M/G H8-- follo%ing conte7t field is for illustration only --G Hfield name<Minventor_country_idM select<M"M %idget<MselectionM conte7t<M1.inventor_country.: self;M/G H/groupG H/searchG

warning a dictionary #ith a title and message to sho# a #arning dialog

$ists0Trees
/ttributes

Lists include %ield elements, are created with t"pe tree, and ha!e a 7tree8 parent element$

hierarchies as a side toolbar (e?ample: the menu) /llo#ed elements %ield, gro$p, separator, tree, b$tton, %ilter, newline
.47 .5* .5. .5-

colors: list of colors mapped to (ython conditions editable: top or bottom to allo# in-place edit toolbar : set to True to display the top level of object

Htree string<M0dea ?ategoriesM toolbar<M"M colors<Mblue:state<<draftMG Hfield name<MnameM/G Hfield name<MstateM/G H/treeG

+opyright , -*.* pen bject (ress - /ll rights reserved $ 0ee license on page )1

p13%)

3iew Inheritance

-*2

to generate the $PR template file from a .s7% template --G

split2mode

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$wB$org/1R/'path position inside: placed inside match (default) before: placed before match

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

.66 .67 .7* .7. .7.72 .73 .74 .75 .7) .76

replace: replace match

after: placed after match

unique report identifier name for the report (required) report title (required) object model on #hich the report is defined (required) path to report template sources (starting from addons), depending on report set to False to use a custom parser, by subclassing report_sx0.rml_parse and declaring the report as follo#s:
report_sx0.report_sx0(report_name, ob%ect_model,rml_path,parser!custom=lass)

#ind

H8-- improved idea categories list --G Hrecord id<Midea_category_listBM model<Mir.ui.vie%MG Hfield name<MnameMGid.category.listBH/fieldG Hfield name<MmodelMGir.ui.vie%H/fieldG Hfield name<Minherit_idM ref<Mid_category_listM/G Hfield name<MarchM type<M7mlMG H7path e7pr<M/tree/field5Qname<.description.6M position<MafterMG Hfield name<Midea_idsM string<MDumber of ideasM/G H/7pathG H/fieldG H/recordG

set to False to suppress report header (default: True) comma-separated list of groups allo#ed to vie# this report set to True to lin' the report #ith the (rint icon (default: True) specify report type 'ey#ord (default: client2print2multi)

Reports

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

-*3 -*4 -*5 -*) -*6 -*7 -.* -.. -.-.2 -.3 -.4

Tip: RML 6ser Guide) www$reportla%$com/docs/rml@pdf*userguide$pdf >xample ?@< report extract:


HstoryG Hbloc+ able style<M ableMG HtrG HtdGHpara style<M itleMG0dea nameH/paraG H/tdG HtdGHpara style<M itleMG@coreH/paraG H/tdG H/trG HtrG HtdGHparaG55 repeat0n'ob/ects(.o.(.tr.) 66 55 o.name 66H/paraGH/tdG HtdGHparaG55 o.score 66H/paraGH/tdG H/trG H/bloc+ ableG H/storyG

subflow2id action

logical behavior of this node regarding outgoing transitions: 6+": one valid transition necessary, send #or'item on it (default) +": send #or'items on all valid transitions (* or more), sequentially 75): send a #or'item on all valid transitions at once (for') type of action to perform #hen node is activated by a transition: dummy to perform no operation #hen activated (default) function to invo'e a function determined by action subflow to e?ecute the subflo# #ith subflow2id, invo'ing action to determine the record id of the record for #hich the subflo# should be instantiated1 :f action returns no result, the #or'item is deleted1 stopall to terminate the #or'flo# upon activation if 'ind subflow, id of the subflo# to e?ecute (use ref attribute or search #ith a tuple) object method call, used if 'ind is function or subflow. ;his function should also update the state field of the object, e1g1 for a function 'ind:
def action_confirmed'self( cr( uid( ids): self.%rite'cr( uid( ids( 1 .state. : .confirmed. ;) # N perform other tas+s return rue

1orkflow Transitions "e!ges&


--) --6 --7 -2* -2. -2-22

Conditions are e!aluated in this order) roleFid, signal, condition e'pression


Hrecord id<Mtrans_idea_draft_confirmedM model<M%or+flo%.transitionMG Hfield name<Mact_fromM ref<Mact_draftM/G Hfield name<Mact_toM ref<Mact_confirmedM/G Hfield name<MsignalMGbutton_confirmH/fieldG Hfield name<Mrole_idM ref<Midea_managerM/G Hfield name<MconditionMG" << "H/fieldG H/recordG

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$

act2from! act2to signal role2id condition

identifiers of the source and destination activities name of a button of type #or'flo# that triggers this transition reference to the role that user must have to trigger the transition (see "oles) (ython e?pression that must evaluate to True for transition to be triggered

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$

Tip: 1he 5e% client features a graphical wor&flow editor, !ia the C$stomise!Manage 'or&%lows lin& in lists and forms$

Alternati,e Report 5ormats (see doc.openerp.com)


s'w@rml rml 'ml,'sl)rml odt@odt ma&o ,pen,ffice G$H templates 0$s'w4 con!erted to RML with s'w@rml tool, and the RML rendered in H1ML or P>RML templates rendered directl" as H1ML or P><ML data 3 <SL)RML st"lesheets to generate RML ,pen,ffice templates 0$odt4 used to produce directl" ,pen,ffice documents 0$odt4 0As of ,penERP ?$@4 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 ?$@4 dou%le %rac&ets content is e!aluated as a P"thon e'pression %ased on the following e'pressions

Security

Access control mechanisms must %e com%ined to achie!e a coherent securit" polic"$

1orkflow !eclaration
-.5 -.) -.6 -.7 --*

5or&flows are declared on o%#ects that possess a state field 0see the e'ample idea class in the ,RM section4
Hrecord id<M%+f_ideaM model<M%or+flo%MG Hfield name<MnameMGidea.basicH/fieldG Hfield name<MosvMGidea.ideaH/fieldG Hfield name<Mon_createM eval<M"M/G H/recordG

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 fieldAs groups attri%ute$
-23 -24 -25

E%pressions use! in OpenERP report templates


,, 7content8 // :redefined expressions: 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

id name osv on2create

unique #or'flo# record identifier name for the #or'flo# (required) object model on #hich the #or'flo# is defined (required) if True, a #or'item is instantiated automatically for each ne# osv record

ir+mo!el+access+cs,
MidM(MnameM(Mmodel_id:idM(Mgroup_id:idM(Mperm_readM(Mperm_%riteM(Mperm_createM(Mperm_unlin+M Maccess_idea_ideaM(Midea.ideaM(Mmodel_idea_ideaM(Mbase.group_userM("("("(2 Maccess_idea_voteM(Midea.voteM(Mmodel_idea_voteM(Mbase.group_userM("("("(2

Roles

--. ----2 --3 --4 --5

+orkflo

*ctivities ,nodes-

Hrecord id<Mact_confirmedM model<M%or+flo%.activityMG Hfield name<MnameMGconfirmedH/fieldG Hfield name<M%+f_idM ref<M%+f_ideaM/G Hfield name<M+indMGfunctionH/fieldG Hfield name<MactionMGaction_confirmed')H/fieldG H/recordG

Roles are created as normal records on the res.roles model and used onl" to condition wor&flow transitions through transitionsA role_id attri%ute$

1i ar!s
5i+ards descri%e stateful interacti!e sessions with the user through d"namic forms$ As of ,penERP !?$H, wi+ards ma&e use of the osv(memor) in*memor" persistence to allow constructing wi+ards from regular %usiness o%#ects and !iews$

to the locale
set<ang(&lang_code&) sets the current language and locale for translations Report !eclaration
H8-- he follo%ing creates records in ir.actions.report.7ml model --G Hreport id<Midea_reportM string<M,rint 0deasM model<Midea.ideaM name<Midea.reportM rml<Midea/report/idea.rmlM G H8-- Ese addons/base_report_designer/wizard/tiny_sxw2rml/tiny_sxw2rml py

id w#f2id name flow2start flow2stop oin2mode

unique activity identifier parent #or'flo# identifier activity node label True to ma'e it a <begin< node, receiving a #or'item for each #or'flo# instance True to ma'e it an <end< node, terminating the #or'flo# #hen all items reach it logical behavior of this node regarding incoming transitions: 6+": activate on the first incoming transition (default) 75): #aits for all incoming transitions to become valid

1i ar! objects "os,*memory&


-2) -26 -27 -3* -3. -3-32 -33

n*memor" o%#ects are created %" e'tending os!$os!Fmemor")


from osv import fields(osv import datetime class cleanup_%izard'osv.osv_memory): cleanup_%izard _name < .idea.cleanup.%izard. _columns < 1 .idea_age.: fields.integer'.Age 'in days).)( ; def cleanup'self(cr(uid(ids(conte7t<1;):

.77 -** -*. -*-

+opyright , -*.* pen bject (ress - /ll rights reserved $ 0ee license on page )1

p14%)

-34 -35 -3) -36 -37 -4* -4. -4-42 -43

idea_ob/ < self.pool.get'.idea.idea.) for %iz in self.bro%se'cr(uid(ids): if %iz.idea_age H< J: raise osv.e7cept_osv'.Eser4rror.(.,lease select a larger age.) limit < datetime.date.today')-datetime.timedelta'days<%iz.idea_age) ids_to_del < idea_ob/.search'cr(uid( 5'.create_date.( .H. ( limit.strftime'.KS-Km-Kd 22:22:22.))6(conte7t<conte7t) idea_ob/.unlin+'cr(uid(ids_to_del) return 1; cleanup_%izard')

2.) 2.6 2.7 2-*

$msg-Gadd,aram'ne% 7mlrpcval'McreateM( MstringM))U $msg-Gadd,aram'ne% 7mlrpcval'$array&al( MstructM))U $resp < $client-Gsend'$msg)U LG

Performance Optimi ation

Internationali ation

3iews
-44 -45 -4) -46 -47 -5* -5. -5-52 -53 -54 -55 -5) -56 -57

5i+ards use regular !iews and their %uttons ma" use a special cancel attri%ute to close the wi+ard window when clic&ed$
Hrecord id<M%izard_idea_cleanupM model<Mir.ui.vie%MG Hfield name<MnameMGidea.cleanup.%izard.formH/fieldG Hfield name<MmodelMGidea.cleanup.%izardH/fieldG Hfield name<MtypeMGformH/fieldG Hfield name<MarchM type<M7mlMG Hform string<M0dea ?leanup *izardMG Hlabel colspan<M>M string<M@elect the age of ideas to cleanupM/G Hfield name<Midea_ageM string<MAge 'days)M/G Hgroup colspan<M>MG Hbutton string<M?ancelM special<McancelM icon<Mgt+-cancelM/G Hbutton string<M?leanupM name<McleanupM type<Mob/ectM icon<Mgt+-o+M/G H/groupG H/formG H/fieldG H/recordG

Each module can pro!ide its own translations within the i'5n director", %" ha!ing files named <A$B.po where <A$B is the locale code for the language, or the language and countr" com%ination when the" differ 0e$g$ pt.po or pt_C?.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 ,penERPAs gette't *O+ e'port feature 0Administration82ranslations8>xport 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" >EAs ha!e plugins or modes for editing and merging P,/P,1 files$
Tip: 1he G;6 gette7t format 0Porta%le ,%#ect4 used %" ,penERP is integrated into LaunchPad, ma&ing it an online colla%orati!e translation platform$
2-. 2-2-2 2-3 2-4 2-5

1i ar! e%ecution
-)* -). -)-)2 -)3 -)4 -)5 -))

Such wi+ards are launched !ia regular action records, with a special target field used to open the wi+ard !iew in a new window$
Hrecord id<Maction_idea_cleanup_%izardM model<Mir.actions.act_%indo%MG Hfield name<MnameMG?leanupH/fieldG Hfield name<MtypeMGir.actions.act_%indo%H/fieldG Hfield name<Mres_modelMGidea.cleanup.%izardH/fieldG Hfield name<Mvie%_typeMGformH/fieldG Hfield name<Mvie%_modeMGformH/fieldG Hfield name<MtargetMGne%H/fieldG H/recordG

|- idea/ |- i"#n/ | - idea.pot | - fr.po | - pt_:$.po | '...)

# he module directory # ranslation files # ranslation emplate 'e7ported from 3pen4$,) # 9rench translation # :razilian ,ortuguese translation

As Enterprise Management Software t"picall" has to deal with large amounts of records, "ou ma" want to pa" attention to the following antipatterns, 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_of 4 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 < 1.model.: '_ref_fnct( fields( priority); 0see e'ample %elow4
2-) 2-6 2-7 22* 22. 22222 223 224 225 22) 226 227 23* 23. 23232 233 234 235 23) 236 237

Tip: B" default ,penERPAs P,1 e'port onl" e'tracts la%els inside <ML files or inside field definitions in P"thon code, %ut an" P"thon string can %e translated this wa" %" surrounding it with the tools.translate._ method 0e$g$ _'.Rabel.) 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 @ 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$ $

1ebSer,ices - 2.$#RP)
,penERP is accessi%le through <ML*RPC interfaces, for which li%raries e'ist in man" languages$
-)6 -)7 -6* -6. -6-62 -64 -63 -65 -6) -66 -67 -7* -7. -7-72

Python e%ample
import 7mlrpclib # ... define T3@ ( ,3$ ( !:( E@4$( ,A@@ url < .http://Ks:Kd/7mlrpc/common. K 'T3@ (,3$ ) soc+ < 7mlrpclib.@erver,ro7y'url) uid < soc+.login'!:(E@4$(,A@@) print MRogged in as Ks 'uid:Kd)M K 'E@4$(uid) # ?reate a ne% idea url < .http://Ks:Kd/7mlrpc/ob/ect. K 'T3@ (,3$ ) soc+ < 7mlrpclib.@erver,ro7y'url) args < 1 .name. : .Another idea.( .description. : . his is another idea of mine.( .inventor_id.: uid( ; idea_id < soc+.e7ecute'!:(uid(,A@@(.idea.idea.(.create.(args)

def _get_idea_from_vote'self(cr(uid(ids(conte7t<1;): res < 1; vote_ids < self.pool.get'.idea.vote.).bro%se'cr(uid(ids(conte7t<conte7t) for v in vote_ids: res5v.idea_id.id6 < rue # @tore the idea identifiers in a set return res.+eys') def _compute'self(cr(uid(ids(field_name(arg(conte7t<1;): res < 1; for idea in self.bro%se'cr(uid(ids(conte7t<conte7t): vote_num < len'idea.vote_ids) vote_sum < sum'5v.vote for v in idea.vote_ids6) res5idea.id6 < 1 .vote_sum.: vote_sum( .vote_avg.: 'vote_sum/vote_num) if vote_num else 2.2( ; return res _columns < 1 # hese fields are recomputed %henever one of the votes changes .vote_avg.: fields.function'_compute( method< rue( string<.&otes Average.( store < 1.idea.vote.: '_get_idea_from_vote(5.vote.6("2);(multi<.votes.)( .vote_sum.: fields.function'_compute( method< rue( string<.&otes @um.( store < 1.idea.vote.: '_get_idea_from_vote(5.vote.6("2);(multi<.votes.)( ;

Report )reator ",iew& an! Report Designer "print& mo!ules

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

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$

$aunchpa! groups
Group* +pen/"* 8uality Team (9openerp) +pen/"* Commiters (9openerp-commiter) +pen/"* )rivers (9openerp-drivers) +pen/"* Community (9openerp-community) Members penI!( +ore ;eam 0elected active community members 0elected active community members pen group, anyone can join Bazaar/LP restrictions +an merge and commit on official branches1 +an mar' branches to be merged into official branch1 +an commit on extra-addons branch +an confirm bugs and set milestones on bugs % blueprints +an create community branches #here everyone can contribute

-73 -74 -75 -7) -76 -77 2** 2*. 2*2*2 2*3 2*5 2*4 2*) 2*6 2*7 2.* 2.. 2.2.2 2.3 2.4 2.5

P7P e%ample
HL include'.7mlrpc.inc.)U // Ese php7mlrpc library( available on sourceforge // ... define $T3@ ( $,3$ ( $!:( $E@4$( $,A@@ $client < ne% 7mlrpc_client'Mhttp://$T3@ :$,3$ /7mlrpc/commonM)U $msg < ne% 7mlrpcmsg'MloginM)U $msg-Gadd,aram'ne% 7mlrpcval'$!:( MstringM))U $msg-Gadd,aram'ne% 7mlrpcval'$E@4$( MstringM))U $msg-Gadd,aram'ne% 7mlrpcval'$,A@@( MstringM))U resp < $client-Gsend'$msg)U uid < $resp-Gvalue')-Gscalarval') echo MRogged in as $E@4$ 'uid:$uid)M // ?reate a ne% idea $array&al < array' .name.<Gne% 7mlrpcval'MAnother 0deaM( MstringM) ( .description.<Gne% 7mlrpcval'M his is another idea of mineM ( MstringM)( .inventor_id.<Gne% 7mlrpcval'$uid( MintM)( )U $msg < ne% 7mlrpcmsg'.e7ecute.)U $msg-Gadd,aram'ne% 7mlrpcval'$!:( MstringM))U $msg-Gadd,aram'ne% 7mlrpcval'$uid( MintM))U $msg-Gadd,aram'ne% 7mlrpcval'$,A@@( MstringM))U $msg-Gadd,aram'ne% 7mlrpcval'Midea.ideaM( MstringM))U

/Members of upper 0roups are also members of lo er 0roups

+opyright , -*.* pen bject (ress - /ll rights reserved $ 0ee license on page )1

p15%)

$icense
Cop"right I @HGH ,pen ,%#ect Press$ All rights reser!ed$ 8ou ma" ta&e electronic cop" of this wor& and distri%ute it if "ou donAt 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 RosiJre, Belgium

+opyright , -*.* pen bject (ress - /ll rights reserved $ 0ee license on page )1

p1)%)

You might also like