Friday, January 28, 2011

Wizards and Links in openERP

    Wizard describe interaction sequences between the client and the server. Wizards provide a form for the client to complete it. Then client can sent the completed form back to the server and server executes some function and return another form to the user or will save the information provided by the client in the database.

To define a wizard, you have to create a class inheriting from wizard.interface and instantiate it. Each wizard must have a unique name. The wizard must define a dictionary named states which defines all its steps. 


 The ‘states’ dictionary define all the states of the wizard.In this example; init, test1, test2 and test3.
 A wizard always starts in the init state and ends in the end state. A state defines two things: a list of actions and a result.
  • List of actions: Each state of a wizard defines a list of actions which are executed when the wizard enters the state. This list can be empty.
  • Result : Specifies the next state/step. The wizard will continue to the next state and if the next state given is "end" then the wizard will stop.

    • The result have different types. They are form, action, choice, print etc.
    • If the type is form then the client will get a form view. 
    • If the type is action then a user_defined_function(action) will be executed and the resulting action will be performed.
    • If the type is choice then also a function will be executed. This function will return the name of the next state of the wizard.
    • If the type is print then we have to provide the name of the report to be printed.

  The type=form indicate that this step is a dialog to the client. We have to provide the fields and the xml view part inside our wizard.


Each step/state of a wizard can have several buttons.Those are located on the bottom right of the dialog box. The list of buttons for each step of the wizard is declared in the state key of its result dictionary.



  • the next step name (determine which state will be next)



  • the button string (to display for the client)



  • the gtk stock item without the stock prefix



  • Dynamic Forms and Fields in Wizard

    Here I create a function "_get_defaults" which returns a dictionary  self.states['test']['result']. Here I'm dynamically providing values to the dictionary "states". The function "_get_defaults" given below.

     The function gets the limit of fields and forms from the previous wizard state using its field name mainly I'm assuming that the data to be added to the field is a character field and I had created the fields according to this assumption. Try yourself and find out its output.


    The XML file

            After completing the code in the wizard we have to add the wizard to the view part. We have to add the following statement to the xml file for getting the wizard in the client interface

    --->id--> id is just a unique name.
    --->model-->model is the place where we want to display the wizard.
    --->name-->name given here is passed in the instance of the class test_wizard_college

    By adding the following statement inside our student view a new button will be created inside . 

     If we want the wizard as a menu item then


     here action is the wizard id, and parent is given as the root menu


     LINKS
            A link is different from wizard. A link creates a connection to a model from a model. To add a link from one model to another model we have to use act_window

    Here res_model is the resulting model in which the link will take us to this model, src_model is the source model in which where the link will be shown.

    Wednesday, January 5, 2011

    Reports In openERP

          This feature helps to create PDF reports. Data taken from our database can be used to create reports. To create a report we need a rml file. The rml file can be generated from sxw file. More about sxw file is explained later in this blog.

          First of all create a new directory called “report” inside our module. Then create an init file and import the file names of the files that we are going to use for report generation. We have to also update the init file of our module. That is we have to import the folder name "report" in the init file. 
    The python program is give below.

    We have to import report_sxw from report and osv from osv.

    class test_parser(report_sxw.rml_parse):-->we have to inherit the class report_sxw.rml_parse. 

    super(test_parser, self).__init__(cr, uid, name, context=context)--->here is the function overiding
     
    self.localcontext.update({})--> Inside braces if we are defining any functions for taking data from the database then we have to specify the function names here.
     
    report_sxw.report_sxw('report.test_report','student.class','addons/dec13/report/new_details.rml',parser=test_parser)-->The instance of the function is called here. Parameters passing here are name of the report, Which class is using this, its rml file location, then the parser(the class which create the report).

    Before reloading the server we have to generate the rml file from the sxw file. Open office helps to create the sxw file. Create the sxw file inside our module's report folder. Static information can be added by typing inside the sxw file.For dynamic information we have to use the following method.

    [[repeatIn(objects,'o')]] --> Inside 2 square brackets(tagging) add repeatIn(). This will help to take data from the database. RepeatIn works same like browse(). The first parameter can be objects, function name etc. Second parameter is the short_name used for calling the object. If no function is defined in report then the object of the class in which we are using the report is passed as the object and we can use each field using short_name.field_name. 

    Name:[[o.name]] --> Name is the text and o.name take the value from the database where fieldname= name
     If the field defined is one2many or many2many, then we have to first create a section in the sxw file and inside this define repeatIn() with the o.field_name as its first parameter.  

    To convert the *.sxw to *.rml first locate the directory “openerp_sxw2rml” copy  file openerp_sxw2rml.py, [normalized_odt2rml.xsl and normalized_oo2rml.xsl --sometimes these two files will be needed]  to our report folder. Then  
    ./openerp_sxw2rml.py file_name.sxw > file_name.rml  
    will convert the sxw file to rml file.


    Now we have completed 80% of our report creation. We have to add report feature to our view. Go to our xml file(or create a new xml file add this xml file name to the terp file).
     <openerp>
    <data>
       <report id="some_unique_id"
              string="Name_in_the_menu_that_calls_the_report"
              model="name_of_the_model_in_which_the_report_will_be_rendered"
              name="name_of_the_file"
              rml="PATH/filename.rml"    <!--PATH is relative to addons/ directory-->
              menu="True"    <!--whether the report will be able to be called directly via the client or not.  Setting menu to False is useful in case of reports called bywizards.-->
              auto="False"/>
     </data>
    </openerp> 
      

    This will create a menu inside the model we have specified. By clicking this field a pdf file will be opened with the values we have specified in the sxw file.

    Tuesday, December 28, 2010

    Python files in openERP

    All the necessary files needed for creating the module and connecting with the  view lies under the base module. Base module contain a folder called osv in which all the functions and classes needed for creating a model is defined here. So first of all Import fields and osv from osv.

    To define a new object, you have to define a new Python class then instantiate it. This class must inherit from the osv class in the osv module.The first line of the object definition will always be of the form:
    An object is defined by declaring some fields with predefined names in the class. Two of them are required (_name and _columns), the rest are optional. The predefined fields are:
    • _auto
    • _columns (required)
    • _constraints
    • _sql_constraints
    • _defaults
    • _inherit
    • _inherits
    • _log_access
    • _name (required)
    • _order
    • _rec_name
    • _sequence
    • _sql
    • _table
    In the database, tables will be created with the table name given in the _name field (all the dot"." will be replaced by underscore"_" in table creation)

    Fields for the database table is specified inside the "_columns". Columns is an associative array(dictionary) in which we specify the field name as the key and field type as the value.

    Types of fields
    Basic types
    boolean:
    A boolean (true, false).
    Syntax:
    fields.boolean('Field Name' [, Optional Parameters]),
     
    integer:
    An integer.
    Syntax:
    fields.integer('Field Name' [, Optional Parameters]),
     
    float:
    A floating point number.
    Syntax:
    fields.float('Field Name' [, Optional Parameters]),
    
    char:
    A string of limited length. The required size parameter determines its size.
    Syntax:
    fields.char(
            'Field Name',
            size=n [,
            Optional Parameters]), # where ''n'' is an integer.
    text:
    A text field with no limit in length.
    Syntax:
    fields.text('Field Name' [, Optional Parameters]),
     
    date:
    A date.
    Syntax:
    fields.date('Field Name' [, Optional Parameters]),
     
    datetime:
    Allows to store a date and the time of day in the same field.
    Syntax:
    fields.datetime('Field Name' [, Optional Parameters]),
     
    binary:
    A binary chain. We can import(upload) our files using binary.
    selection:
    A field which allows the user to make a selection between various predefined values.
    Syntax:
    fields.selection((('n','Unconfirmed'), ('c','Confirmed')),
                       'Field Name' [, Optional Parameters]),
     
    Relational fields

    • one2many and many2one
      • An example is relationship between employee and department. A department may have so many employees and employees will belong to only one department.
      • When defining a many2one relationship in open erp, at first there must have a one2many relationship. ie the constructor which have the one2many relation must be called before calling the constructor having many2one relation.

      • {"employee":fields.one2many("employee.class","department_id","Employees")}

    In class department we define the field as dictionary values, “employee” as the key, “fields.one2many()” as the value with 3parameters. First parameter is the other class name(here employee.class ), then the key name of the other class which has the many2one as its value(here employee_id), then the field name.
      • {"department_id":fields.many2one("department.class","Department"),}

                In class employee we define the field as dictionary values, “department_id” as the key, “field.many2one()” as the value with 2parameters. First parameter is the other class name(here is the department.class) then the field name.

    • many2many
      • Example is the relationship between user and group. Users may belong to so many groups and a group may have so many users.
      • For showing a many2many relationship, we have to create a new relationship table in the database with fields user_id and group_id.
      • If we want a many2many relation between two classes say class abc and class xyz then we have to first define both classes. Now add the many2many relationship in the class which secondly created( here class xyz). Now define a new class which inherit the properties of the class abc. Define the many2many relationship here in the inherited class.
      
      • { 'user_ids': fields.many2many('group.class','user_group_rel', 'user_id','group_id','Users')}
      • The parameters are
        • other class name
        • relationship table name
        • my_relation_id
        • other_relation_id
        • field name

    OpenERP(open Enterprise Resourse Planning)

            OpenERP is an open source comprehensive suite of business applications including Sales, CRM(Customer Relationship management), Project management, Warehouse management, Manufacturing, Accounting and Human Resources. OpenERP has separate client and server components. XML-RPC interfaces are available. It is based on a strong MVC architecture, flexible workflows, a dynamic GUI, an XML-RPC interface, and customizable reporting system with convenient OpenOffice.org integration.

    An OpenERP system has three main components :
    1. PostgreSQL dataserver which has all the databases
    2. OpenERP application server that has all of the enterprise logic
    3. web server, a distinct application called the Open Object client-web, which allows you to connect to OpenERP from any web browser. This is not needed if the user connect through a GTK client.
             The server part is written in Python. Business functionality is organized into "modules". A module is a folder with a pre-defined structure containing Python code and XML files. A module defines data structure, forms, reports, menus, procedures, workflows etc. The client is thin as it contains no business logic. 

    Working 
            I am using eclipse IDE for editing and using openERP version 5.0.14. We can download the server and client package from www.openerp.com , unzip the files and start the server. To start the server first go the openerp-server folder, then to the bin folder. There you can find the openerp-server.py 

         will run the server. Same process for running the client. We can find a file named openerp-client.py inside the bin folder present in the client. Provide the "-v" option to get the complete details of the module fields when mouse pointer pointed to it. Then a client interface with a pop-up window for login. If the database is not present or server is not yet started a error message will be shown. In openERP for the database creation postgresql is used. If there is no error then interface with all the functionalies will be shown.
    This is the login window.
            Open eclipse and select the work space. The server code must be inside the workspace folder found in the home folder. After opening the eclipse go to the folder /bin/addons inside our openerp-server-5.x.x. The addons folder contains all the modules created by the openerp team. We have to add our module in this folder. Create a new directory and inside this directory we have to create all supporting files needed for our module.

    Basic files needed for a module are
    1. __init__.py  -->In this file we have to specify the all the files needed for our module. That is we have to import all the needed *.py file names and folder names inside this init file.
    2. __terp__.py  -->This is the configuration file.Here we have to specify all the files and depending modules,demo files, author name, version etc.
    3. *.py file . --> In the .py file we define our model, and controller.
    4. *.xml file.--->The view part is defined in .xml files.
        ____________________________________________________________________________

    Saturday, November 20, 2010

    DRUPAL Installation guide

    Installation guide for Ubuntu 10.04 users.
    Requirements
            Drupal requires 3 things. A web server and we are using Apache web server, a database and we are using MySQL database and PHP5. Before installing drupal we have to install these three things. We can install apache2, php5, and mysql separately.


    Much more easier way is by installing LAMP(Linux Apache Mysql Php) server.

    If tasksel is not installed then you have to install it separately.

    In installing apache2 if you get an error like this apache2: Could not determine the server's fully qualified domain name, using 127.0.0.1 for ServerName then


    Apache2 has the concept of sites, which are separate configuration files that Apache2 will read. This file is available in /etc/apache2/sites-available/default. Edit this file and change the DocumentRoot and Directory specified here to the directory where you want to install drupal (I am installing drupal to /home/user/drupal/html. So i provide this path to this position).  Save this file and restart our apache web server.


            Create a new username and password in mysql and then create a database.  Complete privilege is given to this database. The user_name, password and database_name are needed in configuring drupal.

            After completing the installation of mysql, php and apache we can install drupal. Download the latest release of drupal from http://drupal.org/ then untar the file.




            Then move the contents from the directory drupal-x.x to the directory where you want to install drupal. I am installing drupal to /home/user/drupal/html

     

    Now change the current directory to drupal installed directory. Create the configuration file and give write permissions to the configuration file.



    Now open your browser and type http://localhost/. Here you have to provide the information such as language, site name, database name, username and password to complete the installation. After the successful completion of this installation a new welcome screen will be provided to you.

    A new installation of Drupal have only a very basic configuration with only a few active modules and minimal user access rights. Log in as admin to enable and configure services. For example:

    General Settings           Administer > Site configuration > Site information
    Enable Modules            Administer > Site building > Modules
    Configure Themes        Administer > Site building > Themes
    Set User Permissions   Administer > User management > Permissions

    By configuring the services you will be able to design a web server.

    Thursday, November 11, 2010

    How to develop a Game using python?

              Everyone like to play games. If we start to play a computer games sometimes we don't quit the game until we finish it. Game can be developed in  any language. I am using python for developing a game. Usual python language can be used for developing textual games. For developing graphical games we need a special module in python  called pygame.

           As the first phase of developing the graphical game we have to make a game plan and then import the pygame module and necessary modules needed for our game. 
     




    Then set up the pygame using pygame.init(). If we want to use sleep function or clock then we have to initiate them also.


    Next step is to set up our output window. For this we are using pygame.display.set_mode().  We can also provide a caption for our window using pygame.display.set_caption()


    Now set up the color variables. Each color can be created by a tuple with three elements. The three elements are red, blue and green each starting from 0 to 255. To create a black color we have to provide tuple as (0, 0, 0) and for white (255, 255, 255). And thus we can create any color.


    If we want to add a text, then first define the font. Then provide the text. TextRect will help to select a rectangle space where our text will be printed. 


    We can fill a background color using

    Then we can define all the geometrical figures needed for our game.


    Five arguments for drawing a line. First is window surface, second color, third coordinate (x1, y1), fourth coordinate (x2, y2) and finally the width of the line. Like this we can also draw circles, rectangles, ellipse etc.

    The keyword blit is used to print the text inside a rectangle which we had already created. pygame.display.update() function is needed to print every operations that have been done. Without this function nothing will be printed. This is because when we create a new object it take a small delay in drawing each object to the screen. So the update function helps to print at the end of definitions. If our game has a game loop - an infinite loop, then this update function will be inside this loop. A user can provide request using pygame.event.get(). On each loop each event is processed and produce a output according to the event.




    Monday, November 8, 2010

    MSP430 -Note on Timer_A

            Timers essential to almost all embedded applications. They generate a fixed period events. Timers replaces the delay loops which allows CPU to sleep.

             Watchdog timer can be found on all msp430 devices. If we enable the watchdog timer our program  keeps resetting itself. So we disable the watchdog timer and uses the Timer_A.

    Timer_A
            Timer is a Asynchronous 16-bit timer/counter. It has a 16-bit timer/counter register, TAR increments or decrements with each rising edge of the clock signal. The timer can generate an interrupt when it overflows. TAR can be cleared by setting TACLR bit. It also clears the clock divider and count direction for up/down mode. The timer clock can be sourced from ACLK, SMCLK, or externally via TACLK or INCLK. The clock source is selected with the TASSELx bits. The selected clock source may be passed directly to the timer or divided by 2, 4, or 8, using the IDx bits. The timer clock divider is reset when TACLR is set.

    TIMER_A Control Register

    TASSELx  :  
        They are 8th and 9th bits of the register.These two bits select the source of the clock for the timer. 

    IDx  :
         They are 6th and 7th bis of the register. These bits select the divider for the input clock.
    MCx  :


    TACLR  :
         Bit 2 of the register. This is Timer_A clear. Setting this bit resets TAR, the clock divider, and the count direction. The TACLR bit is automatically reset and is always read as zero.

    TAIE  :
        Bit 1 of the register. This is Timer_A interrupt enable. Setting this bit enables TAIFG interrupt request.

    TAIFG  :
        Bit 0 of the register. This is Timer_A interrupt flag. If this bit is set then interrupt is pending.