4 A module can contain the following elements:
6 - **Business object** : declared as Python classes extending the class
7 osv.Model, the persistence of these resource is completly managed by
9 - **Data** : XML/CSV files with meta-data (views and workflows declaration),
10 configuration data (modules parametrization) and demo data (optional but
11 recommended for testing),
12 - **Reports** : RML (XML format). HTML/MAKO or OpenOffice report templates, to
13 be merged with any kind of business data, and generate HTML, ODT or PDF
16 .. figure:: _static/03_module_gen_view.png
18 :alt: Module composition
23 Each module is contained in its own directory within either the server/bin/addons
24 directory or another directory of addons, configured in server installation.
25 To create a new module for example the 'OpenAcademy' module, the following
28 - create a ``openacademy`` subdirectory in the source/addons directory
29 - create the module import file ``__init__.py``
30 - create the module manifield file ``__openerp__.py``
31 - create **Python** files containing **objects**
32 - create **.xml files** holding module data such as views, menu entries
34 - optionally create **reports** or **workflows**
36 Python import file __init__.py
37 ++++++++++++++++++++++++++++++
39 The ``__init__.py`` file is the Python import file, because an OpenERP module
40 is also a regular Python module. The file should import all the other python
43 For example, if a module contains a single python file named ``openacademy.py``,
44 the file should look like:
48 Manifest file __openerp__.py
49 +++++++++++++++++++++++++++++++
51 In the created module directory, you must add a **__openerp__.py** file.
52 This file, which must be a Python dict literal, is responsible to
54 1. determine the *XML files that will be parsed* during the initialization
55 of the server, and also to
56 2. determine the *dependencies* of the created module.
57 3. declare additional meta data
59 This file must contain a Python dictionary with the following values:
63 name The name of the module in English.
64 version The version of the module.
65 summary Short description or keywords
66 description The module description (text).
67 category The categrory of the module
68 author The author of the module.
69 website URL of the website of the module.
70 license The license of the module (default: AGPL-3).
71 depends List of modules on which this module depends beside base.
72 data List of .xml files to load when the module is installed or updated.
73 demo List of additional .xml files to load when the module is
74 installed or updated and demo flag is active.
75 installable True or False. Determines whether the module is installable
77 auto_install True or False (default: False). If set to ``True``, the
78 module is a link module. It will be installed as soon
79 as all its dependencies are installed.
81 For the ``openacademy`` module, here is an example of ``__openerp__.py``
84 .. code-block:: python
87 'name' : "OpenAcademy",
89 'author' : "OpenERP SA",
93 'openacademy_view.xml',
94 'openacademy_data.xml',
95 'report/module_report.xml',
96 'wizard/module_wizard.xml',
99 'openacademy_demo.xml'
107 All OpenERP resources are objects: invoices, partners. Metadata are also object
108 too: menus, actions, reports... Object names are hierarchical, as in the
111 * account.transfer : a money transfer
112 * account.invoice : an invoice
113 * account.invoice.line : an invoice line
115 Generally, the first word is the name of the module: account, stock, sale.
117 Those object are declared in python be subclassing osv.Model
119 The ORM of OpenERP is constructed over PostgreSQL. It is thus possible to
120 query the object used by OpenERP using the object interface (ORM) or by
121 directly using SQL statements.
123 But it is dangerous to write or read directly in the PostgreSQL database, as
124 you will shortcut important steps like constraints checking or workflow
127 .. figure:: images/pom_3_0_3.png
131 *The Physical Objects Model of [OpenERP version 3.0.3]*
137 XML files located in the module directory are used to initialize or update the
138 the database when the module is installed or updated. They are used for many
139 purposes, among which we can cite :
141 * initialization and demonstration data declaration,
143 * reports declaration,
144 * workflows declaration.
146 General structure of OpenERP XML files is more detailed in the
147 :ref:`xml-serialization` section. Look here if you are interested in learning
148 more about *initialization* and *demonstration data declaration* XML files. The
149 following section are only related to XML specific to *actions, menu entries,
150 reports, wizards* and *workflows* declaration.
152 Data can be inserted or updated into the PostgreSQL tables corresponding to the
153 OpenERP objects using XML files. The general structure of an OpenERP XML file
158 <?xml version="1.0"?>
161 <record model="model.name_1" id="id_name_1">
162 <field name="field1"> "field1 content" </field>
163 <field name="field2"> "field2 content" </field>
166 <record model="model.name_2" id="id_name_2">
178 The addition of new data is made with the record tag. This one takes a
179 mandatory attribute : model. Model is the object name where the insertion has
180 to be done. The tag record can also take an optional attribute: id. If this
181 attribute is given, a variable of this name can be used later on, in the same
182 file, to make reference to the newly created resource ID.
184 A record tag may contain field tags. They indicate the record's fields value.
185 If a field is not specified the default value will be used.
190 The attributes for the field tag are the following:
196 python expression that indicating the value to add
199 reference to an id defined in this file
202 model to be looked up in the search
212 <record model="ir.actions.report.xml" id="l0">
213 <field name="model">account.invoice</field>
214 <field name="name">Invoices List</field>
215 <field name="report_name">account.invoice.list</field>
216 <field name="report_xsl">account/report/invoice.xsl</field>
217 <field name="report_xml">account/report/invoice.xml</field>
220 Let's review an example taken from the OpenERP source (base_demo.xml in the base module):
224 <record model="res.company" id="main_company">
225 <field name="name">Tiny sprl</field>
226 <field name="partner_id" ref="main_partner"/>
227 <field name="currency_id" ref="EUR"/>
232 <record model="res.users" id="user_admin">
233 <field name="login">admin</field>
234 <field name="password">admin</field>
235 <field name="name">Administrator</field>
236 <field name="signature">Administrator</field>
237 <field name="action_id" ref="action_menu_admin"/>
238 <field name="menu_id" ref="action_menu_admin"/>
239 <field name="address_id" ref="main_address"/>
240 <field name="groups_id" eval="[(6,0,[group_admin])]"/>
241 <field name="company_id" ref="main_company"/>
244 This last record defines the admin user :
246 * The fields login, password, etc are straightforward.
247 * The ref attribute allows to fill relations between the records :
251 <field name="company_id" ref="main_company"/>
253 The field **company_id** is a many-to-one relation from the user object to the company object, and **main_company** is the id of to associate.
255 * The **eval** attribute allows to put some python code in the xml: here the groups_id field is a many2many. For such a field, "[(6,0,[group_admin])]" means : Remove all the groups associated with the current user and use the list [group_admin] as the new associated groups (and group_admin is the id of another record).
257 * The **search** attribute allows to find the record to associate when you do not know its xml id. You can thus specify a search criteria to find the wanted record. The criteria is a list of tuples of the same form than for the predefined search method. If there are several results, an arbitrary one will be chosen (the first one):
261 <field name="partner_id" search="[]" model="res.partner"/>
263 This is a classical example of the use of **search** in demo data: here we do not really care about which partner we want to use for the test, so we give an empty list. Notice the **model** attribute is currently mandatory.
268 A function tag can contain other function tags.
274 the function given name
277 should evaluate to the list of parameters of the method to be called, excluding cr and uid
283 <function model="ir.ui.menu" name="search" eval="[[('name','=','Operations')]]"/>
289 Views are a way to represent the objects on the client side. They indicate to the client how to lay out the data coming from the objects on the screen.
291 There are two types of views:
296 Lists are simply a particular case of tree views.
298 A same object may have several views: the first defined view of a kind (*tree, form*, ...) will be used as the default view for this kind. That way you can have a default tree view (that will act as the view of a one2many) and a specialized view with more or less information that will appear when one double-clicks on a menu item. For example, the products have several views according to the product variants.
300 Views are described in XML.
302 If no view has been defined for an object, the object is able to generate a view to represent itself. This can limit the developer's work but results in less ergonomic views.
308 When you open an invoice, here is the chain of operations followed by the client:
310 * An action asks to open the invoice (it gives the object's data (account.invoice), the view, the domain (e.g. only unpaid invoices) ).
311 * The client asks (with XML-RPC) to the server what views are defined for the invoice object and what are the data it must show.
312 * The client displays the form according to the view
314 .. figure:: images/arch_view_use.png
318 To develop new objects
319 //////////////////////
321 The design of new objects is restricted to the minimum: create the objects and optionally create the views to represent them. The PostgreSQL tables do not have to be written by hand because the objects are able to automatically create them (or adapt them in case they already exist).
326 OpenERP uses a flexible and powerful reporting system. Reports are generated either in PDF or in HTML. Reports are designed on the principle of separation between the data layer and the presentation layer.
328 Reports are described more in details in the `Reporting <http://openobject.com/wiki/index.php/Developers:Developper%27s_Book/Reports>`_ chapter.
334 The objects and the views allow you to define new forms very simply, lists/trees and interactions between them. But that is not enough, you must define the dynamics of these objects.
338 * a confirmed sale order must generate an invoice, according to certain conditions
339 * a paid invoice must, only under certain conditions, start the shipping order
341 The workflows describe these interactions with graphs. One or several workflows may be associated to the objects. Workflows are not mandatory; some objects don't have workflows.
343 Below is an example workflow used for sale orders. It must generate invoices and shipments according to certain conditions.
345 .. figure:: images/arch_workflow_sale.png
350 In this graph, the nodes represent the actions to be done:
353 * cancel the sale order,
354 * generate the shipping order, ...
356 The arrows are the conditions;
358 * waiting for the order validation,
360 * click on the cancel button, ...
362 The squared nodes represent other Workflows;
371 .. versionchanged:: 5.0
373 Each module has its own ``i18n`` folder. In addition, OpenERP can now deal with
374 ``.po`` [#f_po]_ files as import/export format. The translation files of the
375 installed languages are automatically loaded when installing or updating a
378 Translations are managed by the `Launchpad Web interface
379 <https://translations.launchpad.net/openobject>`_. Here, you'll find the list
380 of translatable projects.
382 Please read the `FAQ <https://answers.launchpad.net/rosetta/+faqs>`_ before asking questions.
385 .. [#f_po] http://www.gnu.org/software/autoconf/manual/gettext/PO-Files.html#PO-Files