Monday, 6 October 2014

ORM methods

Keeping the context in ORM methods

In OpenObject, the context holds very important data such as the language in which a document must be written, whether function field needs updating or not, etc.
When calling an ORM method, you will probably already have a context - for example the framework will provide you with one as a parameter of almost every method. If you do have a context, it is very important that you always pass it through to every single method you call.
This rule also applies to writing ORM methods. You should expect to receive a context as parameter, and always pass it through to every other method you call..

ORM methods

class osv.osv.osv(pool, cr)
Bases: osv.osv.osv_base, osv.orm.orm
browse(cr, uid, select, context=None, list_class=None, fields_process=None)
Fetch records as objects allowing to use dot notation to browse fields and relations
Parameters:
  • cr -- database cursor
  • user -- current user id
  • select -- id or list of ids
  • context -- context arguments, like lang, time zone
Return type:
object or list of objects requested
check_access_rule(cr, uid, ids, operation, context=None)
Verifies that the operation given by operation is allowed for the user according to ir.rules.
Parameters:
operation -- one of write, unlink
Raises except_orm:
  • if current ir.rules do not permit this operation.
Returns:
None if the operation is allowed
copy(cr, uid, id, default=None, context=None)
Duplicate record with given id updating it with default values
Parameters:
  • cr -- database cursor
  • uid -- current user id
  • id -- id of the record to copy
  • default (dictionary) -- dictionary of field values to override in the original values of the copied record, e.g: {'field_name': overriden_value, ...}
  • context (dictionary) -- context arguments, like lang, time zone
Returns:
True
copy_data(cr, uid, id, default=None, context=None)
Copy given record's data with all its fields values
Parameters:
  • cr -- database cursor
  • user -- current user id
  • id -- id of the record to copy
  • default (dictionary) -- field values to override in the original values of the copied record
  • context (dictionary) -- context arguments, like lang, time zone
Returns:
dictionary containing all the field values
create(cr, user, vals, context=None)
Create new record with specified value
Parameters:
  • cr -- database cursor
  • user (integer) -- current user id
  • vals (dictionary) -- field values for new record, e.g {'field_name': field_value, ...}
  • context (dictionary) -- optional context arguments, e.g. {'lang': 'en_us', 'tz': 'UTC', ...}
Returns:
id of new record created
Raises:
  • AccessError --
    • if user has no create rights on the requested object
    • if user tries to bypass access rules for create on the requested object
  • ValidateError -- if user tries to enter invalid value for a field that is not in selection
  • UserError -- if a loop would be created in a hierarchy of objects a result of the operation (such as setting an object as its own parent)
Note: The type of field values to pass in vals for relationship fields is specific. Please see the description of the write() method for details about the possible values and how to specify them.
default_get(cr, uid, fields_list, context=None)
Returns default values for the fields in fields_list.
Parameters:
  • fields_list (list) -- list of fields to get the default values for (example ['field1', 'field2',])
  • context -- optional context dictionary - it may contains keys for specifying certain options like context_lang (language) or context_tz (timezone) to alter the results of the call. It may contain keys in the form default_XXX (where XXX is a field name), to set or override a default value for a field. A special bin_size boolean flag may also be passed in the context to request the value of all fields.binary columns to be returned as the size of the binary instead of its contents. This can also be selectively overriden by passing a field-specific flag in the form bin_size_XXX: True/False where XXX is the name of the field. Note: The bin_size_XXX form is new in OpenERP v6.0.
Returns:
dictionary of the default values (set on the object model class, through user preferences, or in the context)
export_data(cr, uid, ids, fields_to_export, context=None)
Export fields for selected objects
Parameters:
  • cr -- database cursor
  • uid -- current user id
  • ids -- list of ids
  • fields_to_export -- list of fields
  • context -- context arguments, like lang, time zone
Return type:
dictionary with a datas matrix
This method is used when exporting data via client menu
fields_get(cr, user, fields=None, context=None)
Get the description of list of fields
Parameters:
  • cr -- database cursor
  • user -- current user id
  • fields -- list of fields
  • context -- context arguments, like lang, time zone
Returns:
dictionary of field dictionaries, each one describing a field of the business object
Raises AccessError:
  • if user has no create/write rights on the requested object
fields_view_get(cr, user, view_id=None, view_type='form', context=None, toolbar=False, submenu=False)
Get the detailed composition of the requested view like fields, model, view architecture
Parameters:
  • cr -- database cursor
  • user -- current user id
  • view_id -- id of the view or None
  • view_type -- type of the view to return if view_id is None ('form', tree', ...)
  • context -- context arguments, like lang, time zone
  • toolbar -- true to include contextual actions
  • submenu -- example (portal_project module)
Returns:
dictionary describing the composition of the requested view (including inherited views and extensions)
Raises:
  • AttributeError --
    • if the inherited view has unknown position to work with other than 'before', 'after', 'inside', 'replace'
    • if some tag other than 'position' is found in parent view
  • Invalid ArchitectureError -- if there is view type other than form, tree, calendar, search etc defined on the structure
get_xml_id(cr, uid, ids, *args, **kwargs)
Find out the XML ID of any database record, if there is one. This method works as a possible implementation for a function field, to be able to add it to any model object easily, referencing it as osv.osv.get_xml_id.
When multiple XML IDs exist for a record, only one of them is returned (randomly).
Synopsis: get_xml_id(cr, uid, ids) -> { 'id': 'module.xml_id' }
Returns:
map of ids to their fully qualified XML ID, defaulting to an empty string when there's none (to be usable as a function field).
import_data(cr, uid, fields, datas, mode='init', current_module='', noupdate=False, context=None, filename=None)
Import given data in given module
Parameters:
  • cr -- database cursor
  • uid -- current user id
  • fields -- list of fields
  • data -- data to import
  • mode -- 'init' or 'update' for record creation
  • current_module -- module name
  • noupdate -- flag for record creation
  • context -- context arguments, like lang, time zone,
  • filename -- optional file to store partial import state for recovery
Return type:
tuple
This method is used when importing data via client menu.
Example of fields to import for a sale.order:
.id,                         (=database_id)
partner_id,                  (=name_search)
order_line/.id,              (=database_id)
order_line/name,
order_line/product_id/id,    (=xml id)
order_line/price_unit,
order_line/product_uom_qty,
order_line/product_uom/id    (=xml_id)
name_get(cr, user, ids, context=None)
Parameters:
  • cr -- database cursor
  • user (integer) -- current user id
  • ids -- list of ids
  • context (dictionary) -- context arguments, like lang, time zone
Returns:
tuples with the text representation of requested objects for to-many relationships
Search for records and their display names according to a search domain.
Parameters:
  • cr -- database cursor
  • user -- current user id
  • name -- object name to search
  • args -- list of tuples specifying search criteria [('field_name', 'operator', 'value'), ...]
  • operator -- operator for search criterion
  • context (dictionary) -- context arguments, like lang, time zone
  • limit -- optional max number of records to return
Returns:
list of object names matching the search criteria, used to provide completion for to-many relationships
This method is equivalent of search() on name + name_get() on the result. See search() for an explanation of the possible values for the search domain specified in args.
perm_read(cr, user, ids, context=None, details=True)
Returns some metadata about the given records.
Parameters:
details -- if True, *_uid fields are replaced with the name of the user
Returns:
list of ownership dictionaries for each requested record
Return type:
list of dictionaries with the following keys:
  • id: object id
  • create_uid: user who created the record
  • create_date: date when the record was created
  • write_uid: last user who changed the record
  • write_date: date of the last change to the record
  • xmlid: XML ID to use to refer to this record (if there is one), in format module.name
read_group(cr, uid, domain, fields, groupby, offset=0, limit=None, context=None, orderby=False)
Get the list of records in list view grouped by the given groupby fields
Parameters:
  • cr -- database cursor
  • uid -- current user id
  • domain -- list specifying search criteria [['field_name', 'operator', 'value'], ...]
  • fields -- list of fields present in the list view specified on the object
  • groupby -- list of fields on which to groupby the records
  • offset -- optional number of records to skip
  • limit -- optional max number of records to return
  • context -- context arguments, like lang, time zone
  • order -- optional order by specification, for overriding the natural sort ordering of the groups, see also search() (supported only for many2one fields currently)
Returns:
list of dictionaries(one dictionary for each record) containing:
  • the values of fields grouped by the fields in groupby argument
  • __domain: list of tuples specifying the search criteria
  • __context: dictionary with argument like groupby
Return type:
[{'field_name_1': value, ...]
Raises AccessError:
  • if user has no read rights on the requested object
  • if user tries to bypass access rules for read on the requested object
search(cr, user, args, offset=0, limit=None, order=None, context=None, count=False)
Search for records based on a search domain.
Parameters:
  • cr -- database cursor
  • user -- current user id
  • args -- list of tuples specifying the search domain [('field_name', 'operator', value), ...]. Pass an empty list to match all records.
  • offset -- optional number of results to skip in the returned values (default: 0)
  • limit -- optional max number of records to return (default: None)
  • order -- optional columns to sort by (default: self._order=id )
  • context (dictionary) -- optional context arguments, like lang, time zone
  • count -- optional (default: False), if True, returns only the number of records matching the criteria, not their ids
Returns:
id or list of ids of records matching the criteria
Return type:
integer or list of integers
Raises AccessError:
  • if user tries to bypass access rules for read on the requested object.
Expressing a search domain (args)
Each tuple in the search domain needs to have 3 elements, in the form: ('field_name', 'operator', value), where:
  • field_name must be a valid name of field of the object model, possibly following many-to-one relationships using dot-notation, e.g 'street' or 'partner_id.country' are valid values.
  • operator must be a string with a valid comparison operator from this list: =, !=, >, >=, <, <=, like, ilike, in, not in, child_of, parent_left, parent_right The semantics of most of these operators are obvious. The child_of operator will look for records who are children or grand-children of a given record, according to the semantics of this model (i.e following the relationship field named by self._parent_name, by default parent_id.
  • value must be a valid value to compare with the values of field_name, depending on its type.
Domain criteria can be combined using 3 logical operators than can be added between tuples: '&' (logical AND, default), '|' (logical OR), '!' (logical NOT). These are prefix operators and the arity of the '&' and '|' operator is 2, while the arity of the '!' is just 1. Be very careful about this when you combine them the first time.
Here is an example of searching for Partners named ABC from Belgium and Germany whose language is not english
[('name','=','ABC'),'!',('language.code','=','en_US'),'|',
('country_id.code','=','be'),('country_id.code','=','de'))
The '&' is omitted as it is the default, and of course we could have used '!=' for the language, but what this domain really represents is:
(name is 'ABC' AND (language is NOT english) AND (country is Belgium 
OR Germany))
Delete records with given ids
Parameters:
  • cr -- database cursor
  • uid -- current user id
  • ids -- id or list of ids
  • context -- (optional) context arguments, like lang, time zone
Returns:
True
Raises:
  • AccessError --
    • if user has no unlink rights on the requested object
    • if user tries to bypass access rules for unlink on the requested object
  • UserError -- if the record is default property for other records
view_init(cr, uid, fields_list, context=None)
Override this method to do specific things when a view on the object is opened.
write(cr, user, ids, vals, context=None)
Update records with given ids with the given field values
Parameters:
  • cr -- database cursor
  • user (integer) -- current user id
  • ids -- object id or list of object ids to update according to vals
  • vals (dictionary) -- field values to update, e.g {'field_name': new_field_value, ...}
  • context (dictionary) -- (optional) context arguments, e.g. {'lang': 'en_us', 'tz': 'UTC', ...}
Returns:
True
Raises:
  • AccessError --
    • if user has no write rights on the requested object
    • if user tries to bypass access rules for write on the requested object
  • ValidateError -- if user tries to enter invalid value for a field that is not in selection
  • UserError -- if a loop would be created in a hierarchy of objects a result of the operation (such as setting an object as its own parent)
Note: The type of field values to pass in vals for relationship fields is specific:
  • For a many2many field, a list of tuples is expected. Here is the list of tuple that are accepted, with the corresponding semantics
    (0, 0,  { values })    link to a new record that needs to    be created with the given values dictionary
    (1, ID, { values })    update the linked record with id = ID (write *values* on it)
    (2, ID)                remove and delete the linked record with id = ID(calls unlink on ID, that will delete the object completely, and the link to it as well)
    (3, ID) cut the link to the linked record with id = ID (delete the relationship between the two objects but does not delete the  target object itself)
    (4, ID) link to existing record with id = ID (adds a relationship)
    (5) unlink all (like using (3,ID) for all linked records)
    (6, 0, [IDs])  replace the list of linked IDs (like using (5) then (4,ID)
      for each ID in the list of IDs)

    Example:
       [(6, 0, [8, 5, 6, 4])] sets the many2many to ids [8, 5, 6, 4]

    For a one2many field, a lits of tuples is expected. Here is the list of tuple that are accepted, with the corresponding semantics
  • (0, 0,  { values })    link to a new record that needs to 
                           be created with the given values 
                           dictionary
    (1, ID, { values })    update the linked record with id = ID 
                           (write *values* on it)
    (2, ID)                remove and delete the linked record wit
             h id = ID 
             (calls unlink on ID, that will delete the object 
    completely,and the link to it as well)
    
    Example:
       [(0, 0, {'field_name':field_value_record1, ...}), 
        (0, 0, {'field_name':field_value_record2, ...})]
    
    
  • For a many2one field, simply use the ID of target record, which must already exist, or False to remove the link.
  • For a reference field, use a string with the model name, a comma, and the target object id (example: 'product.product, 5')

Sunday, 5 October 2014

OpenERP 6.1 Complete guide for Module Development

Module is an independent and self-contained unit of any system. OpenERP modules are written in Python. The usage of module in OpenERP will extend the functionality of OpenERP. It uses OpenERP ORM to persist it’s data in a relational database called Postgresql. Modules are simple way to structure a complex application. One can add his own module in his OpenERP system or customize any existing module. Modules could also be known as plug-ins. Our demo module is called Student_info. This module provides an interface to collect following information about students.
  • Name
  • Age
  • Gender
  • Percentage
  • Details
  • Active
It also displays list of student information in tabular format. You can search student by name, gender and age.

Following are the standard Applications available in OpenERP.


  • CRM
  • Sales and Distribution
  • Accounting
  • Marketing
  • Human Resource
  • Purchase
  • Manufacturing
  • Project Management
  • Point of Sale
  • Warehouse Management
  • Invoicing
  • Payroll

Apart from modules given above, there are around 700+ modules available for use.



  • Following are steps to install module in OpenERP :

For sake of simplicity here we will use module name “Student_info

  • Copy your module directory into addons directory located under your Openerp directory
  • Launch an OpenERP server using following command:
python openerp-server.py --addons=<path of your addons directory>

Here in above command openerp-server.py file is located at <your-openerp- directory>/server/bin/ directory. You also have to supply path of addons directory which is generally located right under your openerp directory.

If you see the message like “OpenERP server is running, waiting for connections...”. you have successfully started the server, Bingo!

  • After starting server, start your either GTK client using following command:
python openerp-client.py

Here in above command openerp-client.py is located at <your-openerp- directory>/client/bin/ directory. After launching the client successfully you will see following screen.




Our database is test_demo but you have to select your own database.
Enter correct username and password and click on OK button.


  1. After clicking on button you will see following screen. Here you will see“Administration” menu item. Click on it.


  1. After selecting Administration module expand “Module” items. 


    3   Select “Update Modules List”. As your module is not a part of the certified addons yet, you will need to update the repository which is identified by
OpenERP Server.






  1. Now you can see one wizard “Update Module List”. Click on “Update”. This process will update modules




  1. After updating module you need to add new module as well as updated module. So after updating modules one wizard will open as “Update Module List”. Click on “Open Modules”.




  1. Now you can see all modules are loaded in the module list.






    7.   You can search any module by Name, Description, Dependencies or State. Here      

         



  1. Now you can see the filtered results containing name “student” which is showing “Not installed”. Just click “Student_info” and go to Form View or just double click on that.



  1. Now you can see all the information about Student_info containing Name, Quality Certificate, Category, Information about Author and Dependencies. For installing “Student_info” click on “Schedule for Installation”.





  1. For applying updates click on “Apply scheduled Upgrades”.








  1. Now one wizard will open to start update “Student_info”. Click on “Start update”.








  1. Now next step is to start configuration after updating module. Click “Start configuration”.




  1. Click ctrl+R to reload the Modules. Now you can see the “Student” Module is loaded in Menu. Click on that.



    14.Now expand the tree of Student Management. Click on “Student Information”.





    15.   After Clicking Student Information you can see the List View in which all the     fields of Student will be shown and records of which are shown in list .



  1. You can create a New record by clicking “New”.



  1. After clicking new record you will take to another wizard i.e. a Form View in which u can edit, create a new record and save it.


  1. After clicking that you can see that Document is saved and it is showing in centre bottom that “Document Saved”.



  1. Now you can search any record by its Name, Gender or Age. Here we have searched a “abc” name and it is showing record name containing student name “abc”.



  1. Another example of search, we have searched by “Gender” and we can see record containing Gender “Female”.



Module structure of OpenERP module :

Module structure considers the following things : 

1. OpenERP addons (openobject-addons) OpenERP business modules : 
 

OpenERP addons host the functional business modules of openerp covering: accounting, sales, crm,
 purchases, warehouse, manufacturing, project, human resources, marketing, knowledge, point-of-sale, 
and much more.

  • Addons contain the list of modules. 
  • The modules : 
  • When you create any module there are minimum four files required. which are given below : 
            
   1. __init__.py 

    2. __openerp__.py 

   3. filename.py (Your model file ) 
   
   4. filename_view.xml :
  • Views
  • Actions
  • Menu entries
  • Report
  • Wizard     
   
  • Now we shall see how to create a module in OpenERP: 
      
       Step 1:   Create the __init__.py file in the new folder you have created for the module, in the   addons
                     directory. The  __init__.py file must have a line to import the main  python(.py)  file you 
      intend create for the module.Having the __init__.py file in your module makes the code a package.
          
        
        Step 2:   Create a module description file (i.e __openerp__.py). The __openerp__.py 
                         file provides a description of the  module you want to create. 
  • It essentially contains a python dictionary. 
        Step 3:  Create your python file that contains objects (Infact thats your model) .
                 This file you have to import in your __init__.py file. 

       Step 4 :  Create your view.xml file . 
             This XML file is a VIEW component of MVC architecture, which is responsible for the GUI.

  •  They are used for many purpose : 
  • Initialization and demonstration data declaration.
2. Views declaration :
  • Views are a way to represent the objects on the client-side. 
  • They indicate to the client how to layout the data coming from the objects on the screen. 
  • There are two basic types of view(there are more, but let's focus on basic ones):
  • Form view
  • Tree view  
    
    
    List view  is simply a particular case of tree view.
          
      
            3. Report declaration : 
  • OpenERP uses a flexible and powerful reporting system.
  • Reports are generated either in PDF or HTML format.
  • Reports are designed on the principle of separation between the data layer and presentation 
    layer. 
    
    
           4. Wizard declaration :  
  • A wizard is declared using wizard tag.        
   

      5. Workflow declaration. 
  • The workflow describes these interaction with graphs.
    
  • One or several workflows may be associated with the objects.
    
  • Workflows are not mendatory.
  • Screen short of the module is given below : 



  In above figure you can see the list of modules in the addons. 


The four file described above are :

(1)__init__.py
(2)__openerp__.py
(3)Student_info.py
(4)Student_info_view.xml
Now we see content of these above file:


(1)__init_.py

This file contains the import statements for importing python(.py) files.
The screenshot of this file is shown below.




(2) __openerp__.py

This file contains the directory which gives introduction about module. In which there are various field described below.


Key

Value
name
It shows field contains the name of the module.
version
It shows the version of the module.
author
It shows author of the module.
website
It contains website of the author.
depends
It is a list of modules on which this module depends.
category
It shows the category of the module (i.e. sales,finance,etc.)
description
The detailed description about the module which describe the functionality of the module.
init_xml
It contains list of xml files which will get executed when the module gets installed.

update_xml
It contains list of xml files which will get executed when the module goes under update mode.
demo_xml
It is a file same as other xml files, but this one contains the demostration data of the models created in the module.
active
It describes that if this module is installed by default or not.
installable
It describes this module is installable or not.
certificate
The certificate no. Assigned by Editor, OpenERP SA.

The example of the __openerp__.py file is shown in the screenshot below.








(3)Student_info.py

It contains the class which is inherits osv class by importing osv and fields class from osv file. The class contains _name which contains name of table, _columns which contains fields of table and _defaults is to give default value.

    • _name:
It define the table name of module. If (.) is used then it will be replaced by (_) in table name.
    • _columns:
It contains fields of the table. Fields contains various data type which shown below.

Data type

Description
char
It stores character data. Size is necessary for this data type.
integer
It stores the Integer value.
boolean
It store Boolean value which contains True or False.
text
It stores large amount of character data without defining the size.
float
It stores the floating(decimal) value.
selection
It contains list of tuple to store data in list. Can be said as a combo-box.






The _columns field contains dictionary to store fields of table.






In above screenshot the _columns contains dictionary which contains various keys and values. Key describe fields of table and value describe data type, label name and constraints of the field.

Various constraints are shown below.


Constraint

Description

required
It is used for mandatory field. If value of required is True then it consider as mandatory field.
readonly
If value of read only is True then user can not modify in field.
translate
If value of translate is True then the field can be translated into installed language.

    • _defaults:
It is use for give default value in table's field. The example shown in below screenshot.







The _defaults variable contains the dictionary, in above screenshot the name field contains default value “Atul” and it is Active.
The student_student() calls the parent class osv.osv's constructor.


View the XML File


There are two type of architectures
A. Client-Server Architecture
B. MVC Architecture

As per MVC architecture there are Model,View, and Controller. So this is view of
the system.
For the view of the module a file is created which is formatted as XML.
There are three categories of XML file in module.
    1) View
    • Search View
    • Tree View
    • Form View
         This portion contains presentation of your module. As per the requirement,
there are three types of view.
  • Search View:






Search View used in module to provide the search panels in form , and from those fields user can search the data. It creates a customized search panel, and is declared quite similarly to a form view, except that the view type and root element change to search instead of form.

Here, in above example Name, Gender and Age fields are provided so by using these fields user can search the particular record.




  • Tree view








Tree view is also called a list view. We can specify columns which we want to add in the list with some details of list display.

In above example we can see the Student Name, Student Age, Student Percentage , Gender and Active Status.


  • Form view



Form view is used when the User wants to Edit or Add the information. The field disposition in a form view always follows the same principle.By default, each field is preceded by a label, with its name. In above example code displays the form view of module and fields like name,age,gender etc.




2) Action :





The action defines the behavior of the system in response to the action of the users. Action portion shows an action or behaviour of module. It shows the priority of the views. By this action we will open next view.
In above code you can see that when we open the module the default view of module is form view.


    3) Menu :




In OpenERP, this element represents a menu structure as shown in the screenshot. You would be able to reach the Forms of the model only by clicking on this menu and it will trigger an action you created in (2).