Professional Documents
Culture Documents
Open Source Rad With Openobject: Database Creation
Open Source Rad With Openobject: Database Creation
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 ;
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$
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
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
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.%)
: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, ...)
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
Floating-point value with arbitrary precision and scale Field allowing selection among a set of predefined values
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"
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
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
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)
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)
of the current object (required) field(: name of field in rel table storing the id of the target object (required)
#unctional fields
,%#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,#)
string: field label (required) required: True if mandatory readonly: True if not editable help: help tooltip select: 1 to include in search
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')
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
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
"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)
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 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)
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)
# ?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
/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
"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"
#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.)
<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
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
+opyright , -*.* pen bject (ress - /ll rights reserved $ 0ee license on page )1
p12%)
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
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
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
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)
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
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
/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
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
$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
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
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
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
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$
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$
Security
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
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
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
+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
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
+opyright , -*.* pen bject (ress - /ll rights reserved $ 0ee license on page )1
p14%)
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')
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
# 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
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.)( ;
)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
+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)%)