doc review part1
[odoo/odoo.git] / doc / 03_module_dev_01.rst
1 Module structure
2 ================
3
4 A module can contain the following elements:
5
6  - **Business object** : declared as Python classes extending the class
7    osv.Model, the persistence of these resource is completly managed by
8    OpenERP's ORM.
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
14    reports.
15
16 .. figure:: _static/03_module_gen_view.png
17    :width: 75%
18    :alt: Module composition
19    :align: center
20    
21    Module composition
22
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
26 steps are required:
27
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 
33    or demo data
34  - optionally create **reports** or **workflows**
35
36 Python import file __init__.py
37 ++++++++++++++++++++++++++++++
38
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
41 file or submodules.
42
43 For example, if a module contains a single python file named ``openacademy.py``,
44 the file should look like:
45
46     import openacademy
47
48 Manifest file __openerp__.py
49 +++++++++++++++++++++++++++++++
50
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
53
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
58
59 This file must contain a Python dictionary with the following values:
60
61 ::
62
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 
76                    or not.
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.
80
81 For the ``openacademy`` module, here is an example of ``__openerp__.py``
82 declaration file:
83
84 .. code-block:: python
85
86     {
87         'name' : "OpenAcademy",
88         'version' : "1.0",
89         'author' : "OpenERP SA",
90         'category' : "Tools",
91         'depends' : ['mail'],
92         'data' : [
93             'openacademy_view.xml',
94             'openacademy_data.xml',
95             'report/module_report.xml',
96             'wizard/module_wizard.xml',
97         ],
98         'demo' : [
99             'openacademy_demo.xml'
100         ],
101         'installable': True,
102     }
103
104 Objects
105 +++++++
106
107 All OpenERP resources are objects: invoices, partners. Metadata are also object
108 too: menus, actions, reports...  Object names are hierarchical, as in the
109 following examples:
110
111     * account.transfer : a money transfer
112     * account.invoice : an invoice
113     * account.invoice.line : an invoice line
114
115 Generally, the first word is the name of the module: account, stock, sale.
116
117 Those object are declared in python be subclassing osv.Model
118
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.
122
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
125 modification.
126
127 .. figure::  images/pom_3_0_3.png
128    :scale: 50
129    :align: center
130
131    *The Physical Objects Model of [OpenERP version 3.0.3]*
132
133
134 XML Files
135 +++++++++
136
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 :
140
141     * initialization and demonstration data declaration,
142     * views declaration,
143     * reports declaration,
144     * workflows declaration.
145
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.
151
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
154 is as follows:
155
156 .. code-block:: xml
157
158    <?xml version="1.0"?>
159    <openerp>
160      <data>
161        <record model="model.name_1" id="id_name_1">
162          <field name="field1"> "field1 content" </field>
163          <field name="field2"> "field2 content" </field>
164          (...)
165        </record>
166        <record model="model.name_2" id="id_name_2">
167            (...)
168        </record>
169        (...)
170      </data>
171    </openerp>
172
173 Record Tag
174 //////////
175
176 **Description**
177
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.
183
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.
186
187 The Record Field tag
188 ////////////////////
189
190 The attributes for the field tag are the following:
191
192 name : mandatory
193   the field name
194
195 eval : optional
196   python expression that indicating the value to add
197   
198 ref
199   reference to an id defined in this file
200
201 model
202   model to be looked up in the search
203
204 search
205   a query
206
207
208 **Example**
209
210 .. code-block:: xml
211
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>
218     </record>
219
220 Let's review an example taken from the OpenERP source (base_demo.xml in the base module):
221
222 .. code-block:: xml
223
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"/>
228        </record>
229
230 .. code-block:: xml
231
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"/>
242        </record>
243
244 This last record defines the admin user :
245
246     * The fields login, password, etc are straightforward.
247     * The ref attribute allows to fill relations between the records :
248
249 .. code-block:: xml
250
251        <field name="company_id" ref="main_company"/>
252
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.
254
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).
256
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):
258
259 .. code-block:: xml
260
261        <field name="partner_id" search="[]" model="res.partner"/>
262
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.
264
265 Function tag
266 ////////////
267
268 A function tag can contain other function tags.
269
270 model : mandatory
271   The model to be used
272
273 name : mandatory
274   the function given name
275
276 eval
277   should evaluate to the list of parameters of the method to be called, excluding cr and uid
278
279 **Example**
280
281 .. code-block:: xml
282
283     <function model="ir.ui.menu" name="search" eval="[[('name','=','Operations')]]"/>
284
285
286 Views
287 +++++
288
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.
290
291 There are two types of views:
292
293     * form views
294     * tree views
295
296 Lists are simply a particular case of tree views.
297
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.
299
300 Views are described in XML.
301
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.
303
304
305 Usage example
306 /////////////
307
308 When you open an invoice, here is the chain of operations followed by the client:
309
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
313
314 .. figure::  images/arch_view_use.png
315    :scale: 50
316    :align: center
317
318 To develop new objects
319 //////////////////////
320
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).
322
323 Reports
324 """""""
325
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.
327
328 Reports are described more in details in the `Reporting <http://openobject.com/wiki/index.php/Developers:Developper%27s_Book/Reports>`_ chapter.
329
330
331 Workflow
332 """"""""
333
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.
335
336 A few examples:
337
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
340
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.
342
343 Below is an example workflow used for sale orders. It must generate invoices and shipments according to certain conditions.
344
345 .. figure::  images/arch_workflow_sale.png
346    :scale: 85
347    :align: center
348
349
350 In this graph, the nodes represent the actions to be done:
351
352     * create an invoice,
353     * cancel the sale order,
354     * generate the shipping order, ...
355
356 The arrows are the conditions;
357
358     * waiting for the order validation,
359     * invoice paid,
360     * click on the cancel button, ...
361
362 The squared nodes represent other Workflows;
363
364     * the invoice
365     * the shipping
366
367
368 i18n
369 ----
370
371 .. versionchanged:: 5.0
372
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
376 module.
377
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.
381
382 Please read the `FAQ <https://answers.launchpad.net/rosetta/+faqs>`_ before asking questions.
383
384
385 .. [#f_po] http://www.gnu.org/software/autoconf/manual/gettext/PO-Files.html#PO-Files
386
387