Open ERP Introduction History Technical view Architecture Installing OpenERP Database Creation Install/uninstall and upgrade

of modules

Introduction
ERP What is ERP? ERP is the acronym of Enterprise Resource Planning. ERP is just not only a software. ERP definition refers to both; ERP software and business strategies that implement ERP systems.ERP is one of the most widely implemented business software systems in a wide variety of industries and organizations. Enterprise resource planning (ERP) is an integrated computer-based system used to manage internal and external resources including tangible assets, financial resources, materials, and human resources. It is a software architecture whose purpose is to facilitate the flow of information between all business functions inside the boundaries of the organization and manage the connections to outside stakeholders. Built on a centralized database and normally utilizing a common computing platform, ERP systems consolidate all business operations into a uniform and enterprise wide system environment. ERP Purpose The main value ERP systems provide is the opportunity to integrate an entire organization. End to end business processes that were traditionally disjointed, now share information through a common database. The information flow is much more efficient in that there are clear lines of business processes across the enterprise. For example, in a horizontally integrated ERP system, a purchasing department would process a purchase order in a central database with a common General Ledger (GL). Both Accounts Payable and Receiving have access to the same GL so the data would be immediately available to them. There is no time lag, re-entry of information, or dependency on paper documents. By having a single point of entry the risk of inaccuracy in the end-to-end transaction is reduced, resulting in fewer reconciliation points. Additionally, the ERP systems of today provide utilities for vertical integration with suppliers and distributors. When properly implemented as part of a comprehensive transformation effort, ERP solutions can yield the following results: Reduced reliance on programmers to make software changes Integrated processes and information systems Consolidation and/or elimination of current systems Reduced complexity of application and technology portfolios Authoritative data source Reduced data redundancy and duplicative data entry More effective and efficient business processes

Intro to Open ERP Open ERP is Enterprise Resource Planning software. It provides a complete, integrated ERP solution for small and medium sized businesses and organizations. Open ERP includes financial and analytic accounting, warehouse and inventory management, sales and purchase management, customer and supplier relations management, association management, tasks automation, human resource management, marketing campaign, document management, help desk, e-commerce integration, and point of sale functionality. More details about various features maybe be found on the Open ERP Features webpage. Open ERP has enjoyed robust development and growth in recent years, as shown in this screencast about global Open ERP deployments. OpenERP is a popular and powerful Open Source enterprise resource management (ERP) system that includes over 300 modules you can configure for your specific purposes. Combining CRM capabilities with financial management, product inventory, human resource control, purchase management, sales management, and point-of-sale capabilities, OpenERP provides you a complete solution for managing your business.

History of Open ERP Open ERP– a fully featured, free and open source ERP software suite. But before describing the features of OpenERP there are some background points to make about the use of ERPs by enteprises and the scope of the post needs to be clarified. 2005- Debuted as Developer 2006- Development of various Modules 2007- Adapted by many mid-level companies and proved to be significative 2008- Tiny erp to Open ERP 2009- Updating with new modules as well as maintaining the existing modules. Many organisations, in the late nineties commissioned bespoke software to match their business processes. They worked from these processes and „computerised‟ them. Often as not the result amounted to a collection of Visual Basic forms which were (and often still are) very popular. However the following systemic problems emerged:

Process Freeze: being „fleet of foot‟ is intrinsic to successful trading so having business processes effectively frozen in time by bespoke software (which cannot easily be modified) is a very bad thing indeed; Over Elaboration: operatives in the field have much less interest in ERP than do the managers in the office! So any excuse not to complete a form or navigate a menu will do just fine. Things like „more than you need‟ or over complex menus and mandatory fields which no longer exist on the new product just stop folk from using the software; Use Anywhere: even SMEs operate in multiple countries on different computing platforms and increasingly require access away from the office. Risks and integration costs are important barriers to all the advantages you gain from such systems. That‟s why, today, few small- and medium-sized companies use ERP. In addition, the larger ERP vendors such as SAP, Microsoft and Oracle haven‟t been able to reconcile the power and comprehensive cover of an ERP system with the simplicity and flexibility wanted by the users. But this is exactly what small and medium enterprises are looking for. The development processes of open source software, and the new business models adopted by their developers, provide a new way of resolving such problems of cost and quality for this kind of enterprise software. To make an ERP system fully available to small and medium enterprise, cost reduction is the first priority. Open source software makes it possible to greatly reduce development costs by aggressive reuse of open source software libraries; to eliminate intermediaries (the distributors), with all of their expensive sales overhead; to cut out selling costs by free publication of the software; and to considerably reduce the marketing overhead. Since there is open interaction among thousands of contributors and partners working on the same project, the quality of the resulting software benefits greatly from the scrutiny. And you can‟t be everything at once: accountant, software developer, salesperson, ISO 9001 quality professional, specialist in agricultural products, expert in the customs and habits of pharmaceutical vendors, just as a start. Faced with these wide-ranging requirements, what could be better than a world network of partners and contributors? Everyone adds their own contribution according to their professional competence. But the real challenge of development is to make this solution simple and flexible, as well as complete. And to reach this level of quality you need a leader and co-ordinator who can organize all of these activities. So the development team of Tiny ERP, today called Open ERP, is responsible for most of the organization, synchronization and coherence of the software.

Technical view OpenERP is free and open source software written in the popular Python programming language. It uses GTK to create an attractive user front end and enterprise-class database PostgreSQL at back end. It has three main packages: OpenERP server, OpenERP desktop client and OpenERP Web Client. This means... OpenERP is a Client/Server system that works over a IP Network. OpenERP programming language is Python. OpenERP uses Object-Oriented technologies. OpenERP records its data with a PostgreSQL relational database.

OpenERP business objects are modelled with an Object Relational Mapping (ORM) system. OpenERP offers three Human Machine Interfaces (HMI) a GTK client, a QT client and a web client (eTiny). OpenERP uses ReportLab for report generation in (PDF). OpenERP uses XML for several purpose: describing data, view, reports, data transport (XML-RPC) OpenERP installation is relatively easy to setup. It took our engineers less than an hour to have the system up and running with sample data for a 'services' company installed. OpenERP provides a good range of alternative sample data packs for differnet companies. The desktop client works on Mac, Linux and Windows. The web-based client worked on every browser we tested. The first thing to appreciate is that OpenERP is modular. It has 300 modules to chose from out-ofthe-box and, of course, you are free to write your own. It follows that you can assemble what is effectively a bespoke package to meet your company's processes. OpenERP is a modern Enterprise Management Software, released under the AGPL license, and featuring CRM, HR, Sales, Accounting, Manufacturing, Inventory, Project Management etc..It is based on OpenObject, a modular, scalable, and intuitive Rapid Application Development (RAD) framework written in Python. OpenObject features a complete and modular toolbox for quickly building applications: integrated Object-Relationship Mapping (ORM) support, template-based Model-View-Controller (MVC) interfaces, a report generation system, automated internationalization, and much more. Python is a high-level dynamic programming language, ideal for RAD, combining power with clear syntax, and a core kept small by design. PostgreSQL, is an object-relational database management system (ORDBMS). As with many other open source programs, PostgreSQL is not controlled by any single company, but has a global community of developers and companies to develop it. It contains all of the databases, each of which contains all data and most elements of the Open ERP system configuration. Extensible Markup Language (XML) provides a foundation for creating documents and document systems. XML operates on two main levels: first, it provides syntax for document markup; and second, it provides syntax for declaring the structures of documents. XML is clearly targeted at the Web, though it certainly has applications beyond it. Users who have worked with HTML before should be able to learn the basics of XML without too much difficulty. XML's simplicity is its key selling point, perhaps even its strongest feature.

and you can use both on the same server at the same time.Client software OpenERP provides a thick desktop client (GTK+) on all platforms. The web client is also easier to maintain. In this case the GTK client will be more responsive. each of which contains all data and most elements of the Open ERP system configuration. because it‟s generally already installed on users‟ computers. It‟s best to use the web browser if the Open ERP server is some distance away (such as on another continent) because it‟s more tolerant of time delays between the two than the GTK client is.Architecture OpenERP uses the well-known client-server paradigm. Open ERP Architecture To access Open ERP you can: use a web browser pointed at the Open ERP client-web server. so more satisfying to use. Conversely you‟d be better off with the application client (called the GTK client because of the technology it‟s built with) if you‟re using a local server (such as in the same building). and a web interface is also accessible using any modern browser. An Open ERP system is formed from three main components: the PostgreSQL database server. which contains all of the databases. or use an application client (the GTK client) installed on each computer. which contains all of the enterprise logic and ensures that . The two methods of access give very similar facilities. with different pieces of software acting as client and server depending on the desired configuration. the Open ERP application server.

com). This database will contain the demonstration data provided with Open ERP and a large proportion of the core Open ERP functionality. Synaptic on Ubuntu) Mac look online for package installers for the GTK client. devteam.com. Installing OpenERP OpenERP is distributed as packages/installers for most platforms. openerp_ch01(Example) .taktik. or directly getting the source using Bazaar (distributed Source Version Control). visit the documentation section by following Product ‣ Documentation on http://www. You also need to install the required dependencies (PostgreSQL and a few Python libraries – see documentation on doc. and demo data can be included. and separate installers for server. .g./bzr_set. Database creation After installation.py # fetch code and perform setup For information about installation on other distributions. use File→Databases→New Database to create a new database (default super admin password is admin). Compilation tip: OpenERP being Python-based. a separate application called the Open Object client-web. You‟ll need to know your super administrator password for this – or you‟ll have to find somebody who does have it to create this seed database. Package installation Windows all-in-one installer. Each database has its own modules and config.be) Installing from source There are two alternatives: using a tarball provided on the website. and webserver are on the website Linux openerp-server and openerp-client packages are available via corresponding package manager (e. Use the technique outlined in this section to create a new database. Detailed instructions are given there for different distributions and releases. and you should also check if there are more up to date instructions for the Ubuntu distribution as well.Open ERP runs optimally. which enables you to connect to Open ERP from standard web browsers and is not needed when you connect using a GTK client. From the GTK client. but can of course be installed from the source on any platform.openerp. the web server. no compilation step is needed Typical bazaar checkout procedure (on Debian-based Linux) $ sudo apt-get install bzr # install bazaar version control $ bzr branch lp:openerp # retrieve source installer $ cd openerp && python . as well as tutorials for installing the server (e.openerp.g. client. run the server and the client.

along with the user accounts and passwords (admin/XXXX and demo/demo ). Super admin password : by default it‟s admin . if you or your system administrator haven‟t changed it. (In fact many people find it hard to resist admin as their password!) Wait for the message showing that the database has been successfully created. Enter the super-administrator password. Confirm password : admin . but obviously completely insecure). Failure to create a database . Default Language : English . Administrator password : admin (because it‟s easiest to remember at this stage. This makes your database quite secure because you can ensure that it is unique from the outset. Start the database creation process from the Welcome page by clicking Databases and then completing the following fields on the Create new database form: Enter the super-administrator password. If you‟re using the web client. and the name of the new database you‟re creating. The consequences of checking this box or not affect the whole use of this database. In both cases you‟ll also see that you can choose the Administrator password. then the name of the new database you‟re creating. Now you‟ve created this seed database you can extend it without having to know the super-administrator password. New database name : openerp_ch01 . Load Demonstration data checkbox: checked .Creating a New Database If you‟re using the GTK client. In both cases you‟ll see a checkbox that determines whether you load demonstration data or not. choose Files -> Databases -> New database in the menu at the top left.

In this test you should leave everything untouched for the moment and just click Next: you‟ll change them later.first screen 1. Select a profile : select Minimal Profile and click Next.first screen . . At the Summary page you can go back to change details if you need. click Start Configuration. and you can add more details on the second tab Report Information including a logo that would appear on reports. Click the Install button. 4.How do you know if you’ve successfully created your new database? You’re told if the database creation has been unsuccessful. 3. you’ll be alerted by the dialog box Error during database creation! After a short delay you are connected to the new openerp_ch03 database as user adminwith the password you gave it. at the Installation done page. If you have entered a database name using prohibited characters (or no name. starting with the menu layout Configuring a minimal database . Configuration consists of a set of wizards that help you through options for the installed modules. If you’ve entered the wrong super-administrator password or a name already in use (some names can be reserved without your knowledge). Finally. and address details on the first tab General Information. 2. Since you chose the minimal database hardly anything is installed so this is a very simple process at the moment. or too short a name) you will be alerted by the dialog box Bad database name! explaining how to correct the error. You‟ll have to go through the Setup wizard in steps: Setting up a blank database . At the Define Main Company step you could select your own Company Name and Currency.

Choose View Mode : Extended Interface so that you can see everything and then click Set to save it.Configuring a minimal database . Starting the minimal database .first screen 1. Click Skip Step to step over the next wizard. At the first screen click Continue to go into the first wizard. 3. which would enable you to add other users. 2. You‟ve now reached the end of the configuration so click Continue to start using the system as the Administrator as shown in the screenshot Starting the minimal database.

the Preferences toolbar to the top right. showing the user name. The Requests link sits just below this toolbar. All of the dates in the system are converted to the user‟s timezone automatically. Administration. This can be different from that of the server. The Signature field gives the user a place for the signature attached to messages sent from within Open ERP. information about copyright and the database you‟re logged into at the bottom of the page. You can click on that link to look at requests that have been sent to you at any time. a working language. This page also gives you access to the super-administrator functions for managing databases on this server. The next element in the Toolbar is a link to Preferences. Preferences. This takes you to either the dashboard or the available menus. The Timezone setting indicates the user‟s location to Open ERP. By clicking that link you reach a page where the current user can set their password. You should take steps (perhaps written policies) to prevent users making these too trivial. But in general each user of the system is presented with a dashboard that‟s designed to show performance indicators and urgent documents that are most useful to someone of the user‟s position in the company. just below you‟ll find information about the Request system. You‟ll see how to assign dashboards to different users in a later chapter. although might initially be set as blank.Once you‟re displaying the main menu you‟re able to see the following screen items. as shown in screenshot The Main Menu of the openerp_ch02 database: Two menus are available on the left: Partners. or to the same database as another user. and a signature: The Password field gives the user the opportunity to change their own password. links to the Home page. You‟ll find a link to the Home page to its right. a timezone. . Preferences toolbar When you‟re connected to Open ERP the Preferences toolbar indicates which user you‟re connected as. the main contents of the window with by the menu toolbar to the left: links generally line up on the right but there are none to show at the moment. If your database is new it will say No request. You can then login to another database. About and Logout. In the case of the openerp_ch02database so far the Home page is the Main Menu. links to the MAIN MENU and the SHORTCUTS. The Logout link enables you to logout and return to the original login page. So it should currently be showing Welcome Administrator (unless you logged in as another user and it‟s reflecting the name of that user instead). It is only visible if you‟re logged into a database. which is described in the next subsection of this chapter. But first the system must be loaded with other languages for the user to be able to choose an alternative. The About link gives information about the development of the Open ERP software and various links to other information. This is a mandatory field. The Language field enables the user‟s working language to be changed. depending on the user configuration.

4. then click Start Configuration on that form. are automatically loaded during the initial installation of the system and can be updated online later. It won‟t matter in this chapter if you can‟t download anything. sales management (the sale module). . and can then be installed in a separate step. Return to the Module tab and then click its Schedule for Installation button. and process modules along with the sale module. You‟ll start by checking if there are any updates available online that apply to your initial installation. as you did with product. to show it in form view. Update Modules List Click Administration ‣ Modules Management ‣ Update Modules List to start the updating tool. rather than the list view that a search displays. Click OK to return to the updated list. Click Apply Scheduled Upgrades in the Action toolbar to the right. The Scan for new modules window opens showing the addresses that Open ERP will look in for downloading new modules (known as the repositories). 7. and now includes all the modules you need. but some of the later chapters refer to modules that aren‟t part of the core installation and have to be obtained from a remote repository. When it‟s complete you‟ll see a New Modules window indicating how many new modules were downloaded and how many existing modules were updated. Click the Schedule for Installation button on the product module form. 5. mrp. Click the Search button at the top of the form to toggle back to the list view with search selection fields on it.com. 2. Enter product into the Name field and click Filter to list the product module. inventory control (the stock module). 9. stock. Click Check New Modules to start the download from the specified locations. Although they‟re mostly not installed in your database at the outset. purchase management (the purchase module). 6. Additional modules can also be loaded online from the official Open ERP site http://openerp. These modules are inactive when they‟re loaded into the system. When the System Upgrade form appears. too. Installing and configuring modules Open ERP contain many modules . wait for System upgrade done to be displayed. 8. Search for the sale module then select it. review the list of Modules to update – it may be longer than you had expected. 3. Use the menu Administration ‣ Modules Management ‣ Modules ‣ Uninstalled modules to show the list of all modules that are registered within Open ERP but as yet uninstalled. Click the Dependencies tab to see that you‟ll automatically be loading the product. the core modules. Click Start Upgrade.Installing New functionality All of Open ERP‟s functionality is contained in its many and various modules. Then you‟ll install a CRM module to complete your existing database. product and process are both already marked for installation as a result of the first steps. Many of these. Then: 1. because the dependencies themselves had their own dependencies. For example few modules are installed and explained below: product management (the product module). and updating existing ones. Click the name product in the list to display the product module in form view. accounting and finance (the account module). they‟re available on your computer for immediate installation.

You‟ve reached the end of this configuration stage so click Continue to continue using the system as the Administrator. 2. Each of the modules that were installed has its own new tab . Click Next and Previous to move between them. Accept the initial set by clicking Set default behaviour. 1. The sales defaults are shown in the screenshot The module form once a module is installed. 4.Configuration is required for both the accounts setup and the sales defaults. shown in the screenshot Continuing with the database after installing new modules. You first reach a new tab Features that lists the new menus and views as shown in the figure The Features tab once a module is installed. Click MAIN MENU to see this. Accept the defaults for the Fiscal Year and choose the Charts of Account to be None then click Continue. The module form once a module is installed . 3.it‟s not only the one you see displayed in front of you. The selections you make determine how Open ERP‟s processes work by setting its default behaviour (although you can override any of them for any sales order. so you are not strictly bound by these defaults). The main menu now displays all of the menu items that were loaded by the modules you installed.

journals and accounts etc. . categories. products . It may be configuring the partners.The Features tab once a module is installed Continuing with the database after installing new modules Data base is set by entering the necessary details required for the suitable module which is installed.

py create the Python file containing the objects create . They are used for many purposes. wizards and workflows declaration. It consist of a client “openerp-client” and a server “openerp-server” while the persistence is provided by Postgresql. wizards declaration. views declaration. Menu Entries 3. . menu entries. Reports 4. menu entries. Introduction 2. . Open ERP currently uses XML-RPC for communication over a network. Wizards 3. 1. General structure of Tiny ERP XML files is more detailed in the section Data Loading Files XML. __terp__. Profiles All the modules are located in the server/addons directory. XML Files 1. Files & Directories 1. reports declaration.Files And Directories .XML Files XML files located in the module directory are used to modify the structure of the database. __init__. The following section are only related to XML specific to actions.. reports. among which we can cite : initialization and demonstration data declaration.xml files that download the data (views. customers requirements will vary accordingly. Open ERP is a Python based client/server program for Enterprise Resource Planning.) optionally create reports. Look here if you are interested in learning more about initialization and demonstration data declaration XML files..py 3. It is necessary for the developer to customize the module according to client requirements. wizards or workflows. The Modules .File Structure Even though many modules exists. Once installed Open ERP has a modular structure that allows modules to be added as needed. The following steps are necessary to create a new module: create a subdirectory in the server/addons directory create a module description file: __terp__. workflows declaration.py 2. demo data. Actions 2.Module Development.

size=64.py__ module.py__ { "name" : "City Details".boolean('Status').xml(interface file) Note – Only __init. "active": False.py__ __terp. ].Basically four files are necessary to develop a module.osv class gp_website_country(osv. "author" : "Softapps".xml". Let us develop simple city module.py and custom_view. 2. "version" : "1. } _defaults={ 'active': lambda *a: True } gp_website_country() .xml files can be changed according to the module work.website. 3. "init_xml" : [].osv): _name = 'gp. 1. 'active':fields.py and __terp.py__ import module __terp. Sample programming lines are given below and its description of each files will be explained later.py(class file) custom_view. "update_xml" : [ "custom_view.1". "depends" : ["base"]. __init. 4.py from osv import fields. But module.py are default names used.required=True). "category" : "Intranet". "installable": True } module.country' _description = "Country Management" _columns = { 'name':fields.char('Country' . __init.

view"> <field name="name">view_city_tree</field> <field name="model">gp.city</field> <field name="type">form</field> .ui.actions.website.city</field> <field name="type">tree</field> <field name="arch" type="xml"> .form</field> </record> <menuitem action="action_city_form" id="menu_gp_city" name="City Management" parent="menu_group_website_root" sequence="1" /> </data> </opener> .website.<record id="action_city_form" model="ir.<form string="City Management"> <field name="country_id" required="1" select="1" /> <field name="state_id" required="1" select="1" /> <field name="name" required="1" /> <field name="active" select="1" /> </form> </field> </record> #####tree view .act_window"> <field name="name">Add City</field> <field name="type">ir.actions.city</field> <field name="view_type">form</field> <field name="view_mode">tree.<openerp> .0" encoding="utf-8" ?> .<field name="arch" type="xml"> .<record id="view_city_form" model="ir.act_window</field> <field name="res_model">gp.xml <?xml version="1.<data> <menuitem icon="terp-sale" id="menu_group_website_root" name="GPL Website" /> #####form view .<tree string="City Management"> <field name="country_id" /> <field name="state_id" /> <field name="name" required="1" /> <field name="active" select="1" /> </tree> </record> ##### action .<record id="view_city_tree" model="ir.custom_view .ui.view"> <field name="name">view_city_form</field> <field name="model">gp.website.

py: import module OpenERP Module Descriptor File __terp__.py” file. It needs to import the Python files that need to be loaded. This file must contain a Python dictionary with the following values: name The (Plain English) name of the module. author The author of the module. license The license of the module (default:GPL-2). and also to 2.py file The __init__. . This file. you must add a __terp__. determine the dependencies of the created module.py In the created module directory.Python Module Descriptor File __init__. So.py file is.py The __init__. website The website of the module. determine the XML files that will be parsed during the initialization of the server. containing the description of your objects. version The version of the module. description The module description (text). which must be in Python format. executed at the start of the program. you have to write one line in __init__.py file. is responsible to 1. if you create a “module. like any Python module.

. "account"].xml"]. "active": True } The files that must be placed in init_xml are the ones that relate to the workflow definition. .1". init_xml List of .xml". update_xml List of . reports and wizards. Determines the modules that are installed on the database creation. Open ERP XML File Format is detailed in this section. installable True or False.xml". Example Here is an example of __terp__. "author" : "Open". "version" : "1.xml files to load when the server is launched with the “–init=module” argument. Filepaths must be relative to the directory where the module is. data to load at the installation of the software and the data for the demonstrations.xml"]. "installable": True. Determines if the module is installable or not. The base module must almost always be in the dependencies because some necessary data for the views. .xml files to load when the server is launched with the “–update=module” launched.py file for the product module { "name" : "Products & Pricelists". reports.xml". "depends" : ["base".depends List of modules on which this module depends.. Filepaths must be relative to the directory where the module is. "pricelist_view. active True or False (default: False). "category" : "Generic Modules/Inventory Control". Open ERP XML File Format is detailed in this section.xml". "update_xml" : ["product_data. "init_xml" : []. "product_view. are in the base module. "product_report. "product_wizard. "demo_xml" : ["product_demo. The files in update_xml concern: views.

and not an object per resource. We have thus a res. As an example. etc. we will see how to define a new object. A Open ERP “resource” is usually called an object in OO programming.) We will see the exact syntax of object method calls further in this document. and has objects and instances .. if we have two partners with the identifiers 1 and 5. .partner object to manage all the partners and not a res.send_email(.. an Open ERP “resource” can be converted magically into a nice Python object using the “browse” class method (Open ERP object method).. For developers: Open ERP “objects” are usually called classes in object oriented programming. we could also say that there is an object per level. Precisely. and we want to call the res_partner method “send_email”. this parameter contains a list of resource ids on which the method must be applied. 5].. . If we talk in “object oriented” terms. Then. [1.partner object per partner. Please note that there is an object for every type of resource. . instance of a class. The direct consequences is that all the methods of objects have a common parameter: the “ids” parameter. and Python is a fully object oriented language.. we will write something like: res_partner... there is a res.OpenERP Objects All the ERP‟s pieces of data are accessible through “objects”. It‟s a bit confusing when you try to program inside Open ERP. because the language used is Python. For example.invoice object for the data concerning the invoices. In the following section. on which partner) the method must be applied. This specifies on which resources (for example. Luckily..partner object to access the data concerning the partners. we will check out the different methods of doing this. an account.

See the fields section for further details.. Setting _auto to False can be useful in case of Open ERP objects generated from PostgreSQL views.osv): _name = 'name.. _columns (required) The object fields. . Object Definition The first line of the object definition will always be of the form: class name_of_the_object(osv. you have to define a new Python class then instantiate it. the rest are optional. _sql_constraints The SQL Constraint on the object. See the constraints section for details.ORM ORM is for Object-Relational Mapping. OpenERP Object Attributes To define a new object. Two of them are required (_name and _columns). This class must inherit from the osv class in the osv module.object' _columns = { .Models. A Open-object is modeling by a static python description for his behavior and data. } . OpenERP modeling is based on “objects” but its data is stored in a classical relational database named Postgresql... The predefined fields are: _auto Determines whether a corresponding PostgreSQL table must be generated automatically from the object. See the SQL constraints section for further details. “ORM” is the python class ancestor of all Open-objects. Python is the programming langage giving the behavior and data description of Open-objects (This is not stored in the database). an a miror sql description for his data storage. _constraints The constraints on the object. name_of_the_object() An object is defined by declaring some fields with predefined names in the class.the.of. ORM job is to fill the gap between Open-objects and sql tables. See the “Reporting From PostgreSQL Views” section for more details.

_log_access Determines whether or not the write access to the resource must be logged. Default value: {}. Those fields represent respectively the id of the user who created the record. Default value: None. This list must be given in a python dictionary of the form: {„name_of_the_parent_object‟: „name_of_the_field‟. and the date of that last modification._defaults The default values for some of the object‟s fields. the id of the user who last modified the record. four fields will be created in the SQL table: create_uid. write_uid. Default value: None. _sql SQL code executed upon creation of the object (only if _auto is True). Default value: „name‟. _sequence Name of the SQL sequence that manages the ids for this object. ) replaced by underscores ( _ ). See the object inheritance section (second form) for further details. the creation date of record. _name (required) Name of the object. Default value: the value of the _name field above with the dots ( .. Examples: _order = "name" _order = "date_order desc" _rec_name Name of the field in which the name of every resource is stored. See the default value section for details.. _table Name of the SQL table. _inherits The list of osv objects the object inherits from. Note: by default. If true. _inherit The name of the osv object which the current object inherits from. the name_get method simply returns the content of this field. Default value: „id‟. This data may be obtained by using the perm_read method. create_date. . See the object inheritance section (first form) for further details. _order Name of the fields used to sort the results of the search and read methods. It means this code gets executed after the table is created. write_date. .}.

Syntax: fields. Syntax: fields.Types of fields boolean: A boolean (true. float: A floating point number. false). Syntax: fields. Example: 'rate' : fields. You should always use the digits parameter for monetary amounts. The scale being the number of digits after the decimal point whereas the precision is the total number of significant digits in the number (before and after the decimal point). the number will be a double precision floating point number. Optional Parameters]). digits=(12.float('Field Name' [. If the parameter digits is not present.char('Field Name'. size=n [. Optional Parameters]).boolean('Field Name' [.integer('Field Name' [. Optional Parameters]). . Optional Parameters]). Optional Parameters]). char: A string of limited length. integer: An integer. The required size parameter determines its size. # where ''n'' is an integer. Note The optional parameter digits defines the precision and scale of the number.float('Relative Change rate'. Syntax: fields. Warning: these floating-point numbers are inexact (not any value can be converted to its binary representation) and this can lead to rounding errors.6) [.

binary: A binary chain selection: A field which allows the user to make a selection between various predefined values. Syntax: fields. In fields definitions add: . Optional Parameters]). Optional Parameters]). Syntax: fields. ('c'. datetime: Allows to store a date and the time of day in the same field. Syntax: fields.char('City Name'.text('Field Name' [...datetime('Field Name' [. required=True).'Confirmed')). 'string_to_display').selection((('n'. text: A text field with no limit in length. Note Format of the selection parameter: tuple of tuples of strings of the form: (('key_or_value'. . ) Example Using relation fields many2one with selection. size=30. Syntax: fields. Optional Parameters]).date('Field Name' [. 'Field Name' [.'Unconfirmed').Example: 'city' : fields. date: A date. Optional Parameters]).

And then define the _sel_func like this (but before the fields definitions): def _sel_func(self.relation. 'id'].select: True .pool.object. ids. cr. . uid.name'. Use many2one instead.many2one('res.object.model') ids = obj. + Predefined value: "cascade". uid..readonly: True . r['name']) for r in res] return res Relational Types A one2one field expresses a one:to:one relation between two objects. 'my_field': fields. selection=_sel_func)..users'. ondelete='cascade').(creates an index on the Foreign Key field) Example 'commercial': fields. . 'Commercial'. optional parameter) many2one: * Optional parameters: .one2one('other.many2one('mymodule. 'Field Name'. "no action". For example Department an Employee belongs to would Many to one.e Many employees will belong to a Department Syntax: fields. 'Field Name') Associates this object to a parent object via this Field. "set null"... one2one: Syntax: fields. "set default" + Default value: "set null" .search(cr.ondelete: What should happen when the resource this field points to is deleted. ['name'. context=None): obj = self.required: True . 'Title'. i...many2one('other. context) res = [(r['id'].read(cr. "restrict".model'.relation. It is deprecated..get('mymodule. []) res = obj. uid.name'.

'relation object'.object. 'Categories'). 'Field Name') Where o o o other.id and other.states: ? .partner.object.invisible: True/False .name' _columns = { 'other_fields': fields.object. 'actual.osv): _inherit = 'other.name is the other object which belongs to the relation relation object is the table that makes the link actual. 'relation object'. 'partner_id'. To make it bidirectionnal (= create a field in the other object): class other_object_name2(osv.name'.id are the fields‟ names used in the relation table Example: 'category_ids': fields. 'other. optional parameter) * Optional parameters: .many2many('actual.partner. 'res_partner_category_rel'.object.many2many('other.one2many('res.readonly: True/False Example 'address': fields.name'.object.one2many('other.object. 'Contacts'). 'category_id'.category'.object.id'.one2many: Syntax: fields. 'other.id'.name'. 'Other Field Name').object.object. 'Fieldname'.address'.object. } other_object_name2() . 'actual. 'Field relation id'. 'partner_id'.many2many( 'res. many2many: Syntax: fields.id'.object.id'.

It can be any field type name except function. uid. and you need to refer Country in a City. If method is True. arg. the signature of the method must be: def fnct(self. id‟_2_‟: value‟_2_‟.}.osv): _inherit = 'res. Parameters: fnct. type="many2one". fnct_inv_arg=None. 'Partners'). fnct_search=None. method=False. method whether the field is computed by a method (of an object) or a global function fnct is the function or method that will compute the field value.. you can define a field as below in the City object: 'country_id': fields. ids. ids. store If you want to store field in database or not. context) Either way. . supposing you have objects: City <. Default is False.Example: class res_partner_category2(osv. context) otherwise (if it is a global function). its signature must be: def fnct(cr. store=False) Functional Field A functional field is a field whose value is calculated by a function (rather than being stored in the database). it must return a dictionary of values of the form {id‟_1_‟: value‟_1_‟. 'category_id'. relation="module. type="float". fnct_inv=None. For example..State <.partner'. arg=None. 'res_partner_category_rel'. 'partner_id'. table.related('state_id'. obj=None.partner. arg.many2many('res. It must have been declared before declaring the functional field. cr.Country. field_name.category' _columns = { 'partner_ids': fields. } res_partner_category2() Sometimes you need to refer the relation of a relation. field_name. 'country_id'.. string="Country". store=True where type is the field type name returned by the function.country".

osv): _name = "hr. If method is true. name. 'Employee'. context) fnct_search allows you to define the searching behaviour on that field. ids. required=True). fnct_inv is the function or method that will allow writing values in that field. } hr_contract() If we want to add a field that retrieves the function of an employee by looking its current contract. name. field_name. context) otherwise (if it is a global function). 'function' : fields.contract' _description = 'Contract' _columns = { 'name' : fields. the signature of the method must be: def fnct(self. field_value. 'Function'). args) otherwise (if it is a global function). cr.3.employee" _description = "Employee" _inherit = "hr. required=True). table. ids.employee'. The object hr_employee is inherited this way: class hr_employee(osv. uid. arg.employee" .function'.The values of the returned dictionary must be of the type specified by the type argument in the field declaration.partner.char('Contract Name'. the signature of the method must be: def fnct(self. field_value.many2one('hr. field_name.many2one('res. it should be: def fnct(cr. uid. arg.osv): _name = 'hr. cr. size=30. obj. it should be: def fnct(cr.5])] Example Of Functional Field: Suppose we create a contract object which is : class hr_contract(osv. obj. 'employee_id' : fields. uid. we use a functional field. args) The return value is a list countaining 3-part tuplets which are used in search funtion: return [('id'.[1.'in'. If method is true.

'Contracts')._columns = { 'contract_ids' : fields.execute(sql_req) sql_res = cr. We called our method _get_cur_function_id because its role is to return a dictionary whose keys are ids of employees.dictfetchone() if sql_res: #The employee has one associated contract res[i] = sql_res['func_id'] else: #res[i] must be set to False and not to None because of XML:RPC # "cannot marshal None unless allow_none is enabled" res[i] = False return res The id of the function is retrieved using a SQL query.partner. context): for i in ids: #get the id of the current function of the employee of identifier "i" sql_req= """ SELECT f. field_name. uid.) cr. We force the False value in this case value because XML:RPC (communication between the server and the client) doesn‟t allow to transmit this value.employee_id = %d) """ % (i. ids. obj =”res.function".id = c. . the value of sql_res[„func_id‟] will be None. method=True.function.one2many('hr. obj="res. 'employee_id'. and whose corresponding values are ids of the function of those employees. The code of this method is: def _get_cur_function_id(self. string='Contract Function').function” is used to specify that the object to use for the many2one field is res.partner. Note that if the query returns no result.function) WHERE (c.function(_get_cur_function_id.partner.id AS func_id FROM hr_contract c LEFT JOIN res_partner_function f ON (f.contract'. arg. cr. type='many2one'. function is declared as a many2one in hr_contract also. 'function' : fields. } hr_employee() Note three points type =‟many2one‟ is because the function field must create a many2one field.

[„field_name1‟. store={'account.function(_membership_state.store={.'='.property.['state']. 10)}).c={}:ids.‟field2‟] on object „object_name‟ and output of the function will send as a parameter for main function of the field. ('name'.} Enhancement: It will compute the field depends on other objects. store={„object_name‟:(function_name. relation='product. type='selection'.. 10). method=True. selection=STATE.property( 'product.. 'membership.invoice':(_get_invoice_partner.'res. } Then you have to create the default value in a . Example In membership module: 'membership_state': fields.property" id="property_product_pricelist"> <field name="name">property_product_pricelist</field> <field name="fields_id" search="[('model'. method=True.priority)} It will call function function_name when any changes will be applied on field list Syntax: [„field1‟.ids.'property_product_pricelist')]"/> <field name="value" eval="'product.pricelist'. view_load=True.cr. 'res.partner" _inherit = "res.membership_line':(_get_partner_id. string='Current membership state'.'='.pricelist'. 10).partner': (lambda self.'+str(list0)"/> . type='many2one'.XML file for this property: <record model="ir. group_name="Pricelists Properties").pricelist.partner').uid. string="Sale Pricelist".['state']. class res_partner(osv.‟field_name2‟]. ['free_member'].partner" _columns = { 'property_product_pricelist': fields. Property Fields¶ Declaring a property A property is a special field: fields.osv): _name = "res.

When you read a property.pricelist. the system will give you the default property. Use a normal field when you inherit from an object and want to extend this object.</record> Tip if the default value points to a resource from another module.data_id‟))”/> Putting properties in forms To add properties in forms. adding more features or data. Using properties or normal fields When you want to add a new feature.property class/table as a complete record. The stored value is a field of type reference (not many2one) because each property may point to a different object.fields class like any other fields. the program gives you the property attached to the instance of object you are reading. But the value of a property is stored in the ir. Properties are displayed by section. The type of this field is many2one. so in the form a property is represented like a many2one function. If you edit properties values (from the administration menu). If this object has no value. just put the <properties/> tag in your form.function and overrides the read and write method. depending on the group_name attribute. (some people will be able to change a specific property. How does this work ? The fields. This will automatically add all properties fields that are related to this object.‟+str(ref(„module. (It is rendered in the client like a separator tag). Use a property when the new feature is not related to the object but to an external concept. others won‟t). you can use the ref function like this: <field name=”value” eval=“„product. Here are a few tips to help you choose between a normal field or a property: Normal fields extend the object. The definition of a property is stored in the ir. you will have to choose to implement it as a property or as normal field.property class inherits from fields. . The system will add properties depending on your rights. you can add groups that are allowed to change to property. In the definition of the property.model. these are represented like a field of type reference.

It‟s much more difficult to maintain and code (for instance. Note One interesting thing is that properties avoid “spaghetti” code. there is one account chart per company. both objects will depend on each other. So you have specific rights just for this field of the partner form: only accountants may change the account receivable of a partner.osv): _inherit = 'product. The account module depends on the partner (base) module. 'alert_time': fields.product' _columns = { 'life_time': fields. try to remove a table when both tables are pointing to each others.product object and adds new fields to it: class product_product(osv. these are not the same rights that are applied to partner objects. so it is an account property that is visible on a partner form. 'use_time': fields.integer('Product removal time'). Rights have to be managed on this fields for accountants. This is a multi-company field: the same partner may have different account receivable values depending on the company the user belongs to. The account receivable of a partner depends on the company it placed the sale order.integer('Product usetime'). This module is very useful for food industries.integer('Product lifetime'). If you add a field that points to an account in the partner object. product usetime. This module inherits from the product.. } . 'removal_time': fields.) Example 2: Product Times The product expiry module implements all delays related to products: removal date..A property is a concept that is attached to an object and have special features: Different value for the same property depending on the company Rights management per field It‟s a link between resources (many2one) Example 1: Account Receivable The default “Account Receivable” for a specific partner is implemented as a property because: This is a concept related to the account chart and not to the partner.product' _name = 'product. The default account receivable is the same for all partners and is configured from the general property menu (in administration). . But you can install the partner (base) module without the accounting module.integer('Product alert time'). In a multi-company system.

context=None) Parameters: vals: a dictionary of values for every field. This dictionary must use this form: {„name_of_the_field‟: value.event'). highly recommended): the actual context dictionary. Example: id = pooler.dbname).. We did not use properties because: We extend a product. . }. the different delays are managed by the same people that manage all products. The available operators are: . This list must be of the form: [(„name_of_the_field‟. the life_time field is a concept related to a product. 'description': 'The Description for Partner Event'.id. order=None. context=None. limit=2000.. context=my_context) search Description: Search all the resources which satisfy certain criteria Signature: def search(self.. We do not need a right management per field.get('res. offset=0. uid. uid. vals. 'partner_id': partner. {'name': 'Email sent through mass mailing'. „operator‟. cr.product_product() This module adds simple fields to the product. not to another object.partner.. ORM methods create Description: Create a new resource Signature: def create(cr. uid.} context (optional.create(cr. . Returns: the id of the newly created resource. value).get_pool(cr. count=False) Parameters args: a list of tuples containing the search criteria. args.].product object.

The “relations” fields are also automatically evaluated to allow you to recover the values in the “neighbors” objects. context=my_context) browse Description: Return one or several resources with the objects form. If a value is not provided for this parameter.dbname).. Example: ids = pooler.get('res. >.}. highly recommended): the actual context dictionary. select.=. Signature: def read(self. the function will check all the fields. 'Customer')]. uid. offset=0.partner'). Signature: def browse(self. Returns: A list of dictionaries (a dictionary per resource asked) of the form [{„name_of_the_field‟: value.dbname). fields (optional): the list of the interested fields. [('category_id'. context=None) .. context (optional. >= IN (sql) LIKE. Returns: the list of ids of matching resources. <. ILIKE (sql) child_of offset (optional): do not return the “offset” first results.'category_id']. read Description: List of fields resources values. highly recommended): the actual context dictionary. cr. ['name'.get('res. These object fields can be reached directly with the pointed notation (“object. limit=2000.get_pool(cr.. fields=None. cr. context=None) Parameters: ids: list of the identifiers of the resources to read (list of integers). <=. ids.partner').search(cr. uid. limit (optional): maximum number of results to return.] Example: values = pooler. '='. .read(cr. uid.name_of_the_field”). uid. ids. context (optional. .. context=my_context) o o o o This example will return a list with all the partners that have the category „Customer‟.get_pool(cr.

contact_id) so. 'name': fields. Let‟s suppose that we know the identifier of a partner contact (name contact_id) and we want to recover his name and the account number of the company he works for.partner contains the field: 'bank':fields. if a list of integer (identifiers) has been passed. highly recommended): the actual context dictionary. uid. Knowing that the object res.many2one('res.pool.get('res. and the object res. context (optional. the most simple way to proceed is to use the browse method: addr_obj = self.partner.partner‟) and of a partner contact (object „res.partner'.address‟).name account_num = addr_obj. limit (optional): the maximum number of results to return.char('Bank account'. Example: Let‟s consider the case of a partner (object „res.bank Note This method is only useful locally (on the server itself) and not with the other interfaces !! write Description: . return an object having the properties described here above. return the object list.partner.size=64).address contains the fields: 'partner_id': fields.partner_id. 'Partner'. to recover the two fields that interest us. required=True). Returns: if an integer (identifier) has been passed as select parameter. you have to write: name = addr_obj. size=64).partner.Parameters select: this parameter accept data of several types: o an integer : identifier of a resource o a list of integers (list of identifiers) offset (optional): the number of results to pass.address').browse(cr.char('Contact Name'.

Returns: True Example: self..pool. form=None. context=my_context) Methods to manipulate the default values¶ default_get Description: Get back the value by default for one or several fields.get('sale.get('sale.. context=None) Parameters: ids: the identifiers resources list to delete. Returns: True Example: self. {'state':'cancel'}. vals. This dictionary must be with the form: {„name_of_the_field‟: value. highly recommended): the actual context dictionary.write(cr. vals: a dictionary with values to write. cr. highly recommended): the actual context dictionary.uid. uid.unlink(cr. uid. ids. fields. uid. ids. Signature: def default_get(self. form (optional): TODO .order'). context=my_context) unlink Description: Delete one or several resources Signature: def unlink(self. context (optional. context (optional. uid.Writes values in one or several fields of one or several resources Signature: def write(self. . cr.}. cr. context=None) Parameters: ids: the resources identifiers list to modify.order'). ids. ids.pool. reference=None) Parameters: fields: the fields list which we want to recover the value by default.

cr. value.timesheet').'product_uom_id']) default_set Description: Change the default value for one or several fields. for_user (optional): boolean that determines if the new default value must be available only for the current user or for all users.reference (optional): TODO Returns: dictionary of the default values of the form {„field_name‟: value. ['product_id'. Signature: def default_set(self. uid. field.pool.get('hr. Returns: True Example: TODO Methods to manipulate the permissions perm_read Signature: def perm_read(self. value: the value by default.analytic. ids) Parameters: ids: an integer list Returns: a list of dictionaries with the following keys Description: level : access level uid : user id gid : group id create_uid: user who created the resource create_date: date when the resource was created write_uid: last user who changed the resource write_date: date of the last change to the resource . uid. uid. } Example: self. cr.default_get(cr. ... for_user=False) Parameters: field: the name of the field that we want to change the value by default.

fields = None. uid. False)] return res . fields.partner'). context=my_context) Methods to generate the fields and the views fields_get Signature: def fields_get(self. cr.setdefault('states'.fields_get(cr. highly recommended): the actual context dictionary. {}) res['communication2']['states']['structured'] = [('readonly'. True)] res['communication2']['states']['normal'] = [('readonly'.line in account_payment module def fields_get(self.perm_read(cr. Result: Example: In payment. cr. user. context=None) Parameters: Description: context (optional. ids. cr. if None. context) if 'communication2' in res: res['communication2']. uid.pool.perm_write Signature: def perm_write(self. uid. highly recommended): the actual context dictionary. context=None) Parameters: Description: fields: a list of fields that interest us. uid. ids. self). fields=None.get('res. context=None): res = super(payment_line. fields. all the fields context (optional. Returns: Example: self.

uid.self). ['membership_products_form'.get('ir. view_id=None. view_id=None. highly recommended): the actual context dictionary. context. toolbar=False) Parameters: Description: context (optional.model. view_type=‟form‟. uid.ui. toolbar=False): if ('product' in context) and (context['product']=='membership_product'): model_data_ids_form = self.get('ir. view_type. user. ('name'. search(cr. Result: Example: In membership module [product. cr. 'in'.pool. offset=0. args=None.fields_view_get(cr.pool.'name']) dict_model={} for i in resource_id_form: dict_model[i['name']]=i['res_id'] if view_type=='form': view_id = dict_model['membership_products_form'] else: view_id = dict_model['membership_products_tree'] return super(Product. context=None. 'ir. 'membership_products_tree'])]) resource_id_form = self.user.view').data').fields=['res_id'.model_data_ids_form. user.product]: def fields_view_get(self. view_id. limit=2000) Description: Parameters: Result: Example: TODO . read(cr.model. field.fields_view_get Signature: def fields_view_get(self. value. toolbar) distinct_field_get Signature: def distinct_field_get(self. cr. '='. context=None. cr. [('model'. user.data'). view_type='form'.

cr. args=None. user. limit=80): if not args: args=[] if not context: context={} ids = False if len(name) == 2: ids = self. context={}): if not len(ids): return [] res = [] for r in self.. context=None) Description: „Parameters: Result: Example: In res. addr)) return res name_search Signature: def name_search(self. cr. name=‟„.. ids. operator=‟ilike‟.'zip'. ids. cr. context=None. args=None. ['name'. user. . '='.append((r['id']. ' addr += str(r['zip'] or '') + ' ' + str(r['city'] or '') res. user. user. operator='ilike'. uid. context=context) . uid. [('code'.'city']): addr = str(r['name'] or '') if r['name'] and (r['zip'] or r['city']): addr += '.partner.read(cr. context=None) Description: Parameters: Result: a list of tuples of the form [(id. ids. cr. limit=limit.country: def name_search(self.address: def name_get(self.search(cr. name=''. name).Methods concerning the name of the resources name_get Signature: def name_get(self. name)] + args.] Example: In res.

search(cr. user. Fields are placed on the screen from left to right.if not ids: ids = self. tree views Form views The field disposition in a form view always follows the same principle. There are two types of views: 1. with its name. They designate respectively the labels and their corresponding fields. As every edition field is preceded (by default) by a label with its name. or an “edition” field. user. limit=limit. for each object. form views 2. illustrate those 4 columns. [('name'. and from top to bottom. Every screen is divided into 4 columns. there will be two fields (and their respective labels) on each line of the screen. each field is preceded by a label. context) Views and Events Views describe how each object (type of resource) is displayed. . we can define one (or several) view(s) to describe which fields should be drawn and how.name_get(cr. operator. according to the order in which they are declared in the view. The green and red zones on the screen-shot below. More precisely. Fields are distributed on the screen following the rules below: By default. ids. name)] + args. each column being able to contain either a label. context=context) return self.

As we can see below in the purple zone of the screen. We can also make the opposite operation: take a columns group and divide it in as many columns as desired. there is also a way to distribute the fields of an object on different tabs. The surrounded green zones of the screen above are good examples. . but let‟s note that it uses the whole width of the screen and not only one column. the zone in the blue frame is.Views also support more advanced placement options: A view field can use several columns. We will come back later on this note. but contains 4 columns. Precisely. the green framework up and on the right side takes the place of two columns. For example. on the screen-shot below. the only field of a “one to many”. in fact.

.

Tree views These views are used when we work in list mode (in order to visualize several resources at once) and in the search screen. These views are simpler than the form views and thus have less options. .

.. New : You can now add shortcut using the shortcut tag.Design Elements The common structure to all the XML files of Tiny ERP is described in the DataLoadXML “Data Loading Using XML Files” section The files describing the views are also of the form: Example: <?xml version="1. which link actions to these views <menuitem> tags.. <record model="ir.view”.ui.0"?> <openerp> <data> [view definitions] </data> </openerp> The view definitions contain mainly three types of tags: <record> tags with the attribute model=”ir. which contain the view definitions themselves <record> tags with the attribute model=”ir.order</field> <field name="priority" eval="2"/> <field name="arch" type="xml"> <form string="Sale Order"> .act_window”. and link them with actions New : You can precise groups for whom the menu is accessible using the groups attribute in menuitem tag.. </form> </field> </record> Default value for the priority field : 16.actions.order.view" id="v"> <field name="name">sale. Example: <shortcut name="Draft Purchase Order (Proposals)" model="purchase.. . which create entries in the menu..order" logins="demo" menu="m"/> Note that you should add an id attribute on the menuitem which is refered by menu attribute..ui.. When not specified the system will use the view with the lower priority.form</field> <field name="model">sale.

right.. </page>: .. Notebook <notebook>: With notebooks you can distribute the view fields on different tabs (each one defined by a page tag).</notebook> Group <group>: groups several columns and split the group in as many columns as desired.. Example: <page string="Order Line"> .. the frame will be invisible.. Example: <notebook colspan="4">. left. You can use the tabpos properties to set tab at: up. a frame will be drawn around the group of fields. down. colspan: the number of columns to use rowspan: the number of rows to use expand: if we should expand the group or not col: the number of columns to provide (to its children) string: (optional) If set. Example: <group col="3" colspan="2"> <field name="invoiced" select="2"/> <button colspan="1" name="make_invoice" states="confirmed" string="Make Invoice" type="object"/> </group> Page Defines a new notebook page for the view. Otherwise.Grouping Elements Separator¶ Adds a separator line Example: <separator string="Links" colspan="4"/> The string attribute defines its label and the colspan attribute defines his horizontal size (in number of columns). with a label containing the string.

‟operator‟.‟value‟).]}” o where attribute will be readonly. (It can be use on page. invisible=”True”: hides both the label and the field.string: defines the name of the page. button and notebook tag also) o Format: “{„attribute‟:[(„field_name‟. o Example: mode=”tree. string=”“: change the field label. invisible. readonly=”1”: set the widget as read only required=”1”: the field is marked as required.partner_id)” o See ViewsSpecialProperties for details attrs: Permits to define attributes of a field depends on other fields of the same window.‟operator‟.product) . o Example: (in product.graph” on_change: define a function that is called when the content of the field changes. Data Elements Field attributes for the “field” tag select=”1”: mark this field as being one of the research criteria for this resource search view. nolabel=”1”: hides the label of the field (but the field is not hidden in the search view).‟operator‟.‟=‟. group. a user has to fill it the system won‟t save the resource if the field is not filled. ‟attribute2‟:[(„field_name‟. This attribute supersede the required field value defined in the object.partner_id)]” widget: can change the widget. “*”. If a field is marked as required.‟value‟)]. password=”True”: replace field entry by asterisk. colspan=”4”: the number of columns on which a field must extend. o Example: widget=”one2many_list”  one2one_list  one2many_list  many2one_list  many2many  url  email  image  float_time  reference mode: sequences of the views when switching. domain: can restrict the domain. o Example: on_change=”onchange_partner(type. o Example: domain=”[(„partner_id‟. required o Default value: {}.(„field_name‟.‟value‟). Note that this label is also used in the search view: see select attribute above).

partner. '='.ui.partner</field> <field name="type">form</field> <field name="arch" type="xml"> <form string="Partners"> <group colspan="4" col="6"> <field name="name" select="1"/> <field name="ref" select="1"/> <field name="customer" select="1"/> <field domain="[('domain'.<field digits="(14.'service')]}"/> eval: evaluate the attribute content as if it was Python code (see below for example) Example Here‟s the source code of the view of a sale order object.'='. 'partner')]" name="title"/> <field name="lang" select="2"/> <field name="supplier" select="2"/> </group> <notebook colspan="4"> <page string="General"> <field colspan="4" mode="form. '='.0"?> <openerp> <data> <record id="view_partner_form" model="ir.view"> <field name="name">res.form</field> <field name="model">res. 'contact')]" name="title"/> <field name="function"/> <field name="type" select="2"/> <field name="street" select="2"/> <field name="street2"/> <newline/> <field name="zip" select="2"/> <field name="city" select="2"/> <newline/> <field completion="1" name="country_id" select="2"/> <field name="state_id" select="2"/> <newline/> <field name="phone"/> <field name="fax"/> <newline/> <field name="mobile"/> <field name="email" select="2" widget="email"/> . This is the same object as the object shown on the screen shots of the presentation.tree" name="address" nolabel="1" select="1"> <form string="Partner Contacts"> <field name="name" select="2"/> <field domain="[('domain'. 3)" name="volume" attrs="{'readonly':[('type'. Example: <?xml version="1.

</form> <tree string="Partner Contacts"> <field name="name"/> <field name="zip"/> <field name="city"/> <field name="country_id"/> <field name="phone"/> <field name="email"/> </tree> </field> <separator colspan="4" string="Categories"/> <field colspan="4" name="category_id" nolabel="1" select="2"/> </page> <page string="Sales &amp.3' and not the float 2. This allows you to define values that are not strings. Purchases"> <separator string="General Information" colspan="4"/> <field name="user_id" select="2"/> <field name="active" select="2"/> <field name="website" widget="url"/> <field name="date" select="2"/> <field name="parent_id"/> <newline/> </page> <page string="History"> <field colspan="4" name="events" nolabel="1" widget="one2many_list"/> </page> <page string="Notes"> <field colspan="4" name="comment" nolabel="1"/> </page> </notebook> </form> </field> </record> <menuitem action="action_partner_form" id="menu_partner_form" parent="base.menu_base_partner" sequence="2"/> </data> </openerp> The eval attribute¶ The eval attribute evaluate its content as if it was Python code. Example 1: <field name="value">2. Normally. content inside <field> tags are always evaluated as strings.3</field> This will evaluate to the string '2.3 Example 2:<field name="value">False</field> .

wizards. Example: <newline/> . If the states attribute is not given. Eg: confirm=”Are you sure?” name: the name of the function to call when the button is pressed.. In the case it‟s an object function.This will evaluate to the string 'False' and not the boolean False If you want to evaluate the value to a float. except string. . o cr is a database cursor o uid is the userID of the user who clicked the button o ids is the record ID list o **args is a tuple of additional arguments states: a comma-separated list of states (from the state field or from the workflow) in which the button must appear.3" /> <field name="value" eval="False" /> Button <button/>: add a button using the string attribute as label.. ids. if needed. string: define the button‟s label confirm: the message for the confirmation window. a boolean or another type. the button is always visible. Example: <label string="Test"/> New Line Force a return to the line even if all the columns of the view are not filled in. type: this attribute can have 3 values o “workflow” (value by default): the function to call is a function of workflow o “object”: the function to call is a method of the object o “action”: call an action instead of a function Example: <button name="order_confirm" states="draft" string="Confirm Order" icon="gtkexecute"/> Label Adds a simple label using the string attribute as caption. you need to use the eval attribute: <field name="value" eval="2. it must take 4 arguments: cr. workflow transitions or actions (reports. When clicked. it can trigger methods on the object. uid.).

and must also be defined in the XML with fields defined this way: <field name="name_of_field" on_change="name_of_method(other_field'_1_'. . which are the three classical arguments and also the context dictionary. reference=None) Parameters: fields: the fields list which we want to recover the value by default.. form=None. uid. other_field'_n_')"/> Getting Defaults Description: Get back the value by default for one or several fields. } Example: self. ['product_id'... Signature: def default_get(self. This method takes at least arguments: cr. cr. .'product_uom_id']) default_set Description: Change the default value for one or several fields. fields. field. for_user=False) Parameters: field: the name of the field that we want to change the value by default.default_get(cr.Events On Change The on_change attribute defines a method that is called when the content of a view field has changed.. Signature: def default_set(self. ids.timesheet'). uid. cr. value.analytic. You can add parameters to the method. form (optional): TODO reference (optional): TODO Returns: dictionary of the default values of the form {„field_name‟: value.get('hr. They must correspond to other fields defined in the view. uid.. uid. .pool.

STOCK_CONVERT. This identifier must be unique. STOCK_CDROM. STOCK_BOLD. STOCK_DISCONNECT. STOCK_COLOR_PICKER. STOCK_DND. A menu item name with no slash in its text is a top level menu.value: the value by default. STOCK_DIALOG_INFO. Mandatory field. “Human Resources” in Open ERP are defined). STOCK_DIALOG_AUTHENTICATION. STOCK_CONNECT. STOCK_CLOSE. STOCK_FIND_AND_REPLACE. The default icon is STOCK_OPEN. STOCK_DELETE. STOCK_FILE. o The available icons are : STOCK_ABOUT. STOCK_DIRECTORY. STOCK_DIALOG_WARNING. icon specifies which icon will be displayed for the menu item using the menu item. Returns: True Example: TODO Menus Here‟s the template of a menu item : <menuitem id="menuitem_id" name="Position/Of/The/Menu/Item/In/The/Tree" action="action_id" icon="NAME_FROM_LIST" groups="groupname" sequence="<integer>"/> Where id specifies the identifier of the menu item in the menu items table. STOCK_APPLY. STOCK_GOTO_FIRST. STOCK_FIND. STOCK_GOTO_BOTTOM. STOCK_CLEAR.act_window).actions. STOCK_GOTO_LAST. STOCK_FLOPPY. Mandatory field. STOCK_CUT. STOCK_EDIT. STOCK_DIALOG_QUESTION. for_user (optional): boolean that determines if the new default value must be available only for the current user or for all users. STOCK_CANCEL. STOCK_COPY. STOCK_ADD. name defines the position of the menu item in the menu hierarchy. Elements are separated by slashes (“/”). STOCK_DND_MULTIPLE. . This is useful when defining custom icons for menu elements that will act as folders (for example this is how custom icons for “Projects”. STOCK_EXECUTE. Note that this field is not mandatory : you can define menu elements without associating actions to them. action specifies the identifier of the action that must have been defined in the action table (ir. STOCK_DIALOG_ERROR.

terp-hr. STOCK_JUSTIFY_LEFT. STOCK_SORT_ASCENDING. STOCK_ZOOM_IN. terp-report. STOCK_STOP. STOCK_SORT_DESCENDING. STOCK_YES. STOCK_GO_UP. STOCK_GO_FORWARD. STOCK_PRINT. STOCK_PREFERENCES. STOCK_ITALIC. terp-purchase. STOCK_UNDELETE. terp-tools. STOCK_NETWORK. STOCK_NO. STOCK_ZOOM_OUT. terp-account. STOCK_JUMP_TO. STOCK_UNDERLINE. STOCK_QUIT.. STOCK_UNINDENT. STOCK_UNDO. the menu item gets a default sequence number of 10.STOCK_REDO. the downer the menu item. STOCK_HOME.user”) sequence is an integer that is used to sort the menu item in the menu.id“). STOCK_INDEX. STOCK_REFRESH. STOCK_MEDIA_REWIND. STOCK_SELECT_COLOR. See section ” Management of Access Rights” for more information. STOCK_JUSTIFY_CENTER. STOCK_MEDIA_FORWARD. <menuitem name="Sales Management/Sales Order/Sales Order in Progress" id="menu_action_order_tree4" action="action_order_tree4"/> he actions define the behavior of the system in response to the actions of the users . STOCK_MEDIA_PLAY. STOCK_ZOOM_FIT. STOCK_OPEN. STOCK_SAVE_AS. login of a new user. STOCK_MEDIA_NEXT. terp-mrp. STOCK_MEDIA_STOP. STOCK_SELECT_FONT. STOCK_HELP. STOCK_HARDDISK. STOCK_JUSTIFY_RIGHT. terp-stock groups specifies which group of user can see the menu item (example : groups=”admin”). STOCK_PROPERTIES. This argument is not mandatory: if sequence is not specified. There are different types of simple actions: Window: Opening of a new window Report: The printing of a report o Custom Report: The personalized reports o RML Report: The XSL:RML reports . STOCK_REMOVE. double-click on an invoice. terp-project. The higher the sequence number. STOCK_NEW. STOCK_PRINT_PREVIEW. terpadministration.‟ (example: groups=”admin. STOCK_JUSTIFY_FILL.STOCK_GOTO_TOP. STOCK_SAVE. STOCK_MISSING_IMAGE. terp-partner. STOCK_STRIKETHROUGH. terp-crm. STOCK_MEDIA_PREVIOUS. . STOCK_SPELL_CHECK. STOCK_OK. STOCK_GO_BACK. STOCK_ZOOM_100. STOCK_REVERT_TO_SAVED. terp-product. terp-sale. STOCK_INDENT. STOCK_MEDIA_PAUSE.. Menu items with the same sequence numbers are sorted by order of creation (_order = “sequence. Multiple groups should be separated by a „. click on the action button. STOCK_GO_DOWN. STOCK_MEDIA_RECORD. STOCK_PASTE.

User connection. User connection When a new user is connected to the server. Reading of the action and execution of this one . Reading of a user file to obtain ACTION_ID 2. Two examples: Opening of a window when double-clicking in the menu User connection Opening of the menu When the user open the option of the menu “Operations > Partners > Partners Contact”. it indicates to the user that a new window must be opened for a selected object and it gives you the view (form or list) and the filed to use (only the pro-forma invoice). Generally. the client must search the action to use for the first screen of this user. The user double-clicks on the menu. 1. The user clicks on the icon „print‟ or „action‟. Search the action in the IR. If the action is the type Opening the Window. Execution of the action 1. 2. this action is: open the menu in the „Operations‟ section. 2. the next steps are done to give the user information on the action to undertake. The user asks the object and receives information necessary to trace a form.Wizard: The beginning of a Wizard Execute: The execution of a method on the server side Group: Gather some actions in one group The actions are used for the following events. all the actions are described and not configured. the fields description and the XML view. Example of events In Open ERP. The steps are: 1.

(restriction) For example. =. like) the tested value For example. The Domain This parameter allows you to regulate which resources are visible in a selected view. the domain define the resources which are the roots of the tree. Here‟s the template of an action XML record : . The form view is generally opened from the list mode (like if the user pushes on „switch view‟). [(„state‟. The views can be of „Form‟ or „Tree‟ type. The other resources. A form can be called by an action opening in „Tree‟ mode.The fields Action Name The action name Action Type Always „ir. The tuples have three elements.actions. according to whether they represent a form for the edition or a list/tree for global data viewing. if you want to obtain only „Draft‟ invoice. Actions are explained in more detail in section “Administration Modules . in the invoice case. >.‟=‟.Actions”.act_window‟ View Ref The view used for showing the object Model The model of the object to post Type of View The type of view (Tree/Form) Domain Value The domain that decreases the visible data with this view The view The view describes how the edition form or the data tree/list appear on screen. The domains are written in python. even if they are not from a part of the domain will be posted if the user develop the branches of the tree. you can define an action that opens a view that shows only invoices not paid. list of tuples.‟draft‟)] In the case of a simple view. the field on which the test must be done the operator used for the test (<. use the following domain.

context is the context dictionary which will be visible in the view that will be opened when the action is activated. Constraints of the list are linked together with an AND clause : a record of the table will be displayed in the view only if all the constraints are satisfied.form|form|tree</field> <field name="usage">menu</field> <field name="target">new</field> </record> Where id is the identifier of the action in the table “ir. Context dictionaries are declared with the same syntax as Python dictionaries in the XML file.act_window”. They indicate at the user that he has to open a new window in a new „tab‟. name is the name of the action (mandatory). view_mode is only considered if view_type is form. the view of a kind (list or form) associated to the object res_model with the highest priority field is used (if two views have the same priority. Administration > Custom > Low Level > Base > Action > Window Actions .act_window" id="action_id_1"> <field name="name">action.tree|tree. the list view can be displayed by clicking the “alternate view button” . o form : the view is displayed as a form and there is no way to switch to list view . the first defined view of a kind is used). o tree.name</field> <field name="view_id" ref="view_id_1"/> <field name="domain">["list of 3-tuples (max 250 characters)"]</field> <field name="context">{"context dictionary (max 250 characters)"}</field> <field name="res_model">Open. and ignored otherwise. domain is a list of constraints used to refine the results of a selection. (version 5 introduced graph and calendar views) usage is used [+ *TODO* +] target the view will open in new window like wizard. It must be unique. For more information about context dictionaries.form : the view is first displayed as a list.tree : the view is first displayed as a form. If this field is not defined. o tree : the view is displayed as a list and there is no way to switch to form view. view_type is set to form when the action must open a new form view.<record model="ir. see section ” The context Dictionary”. the form view can be displayed by clicking the “alternate view button” .actions.object</field> <field name="view_type">form|tree</field> <field name="view_mode">form. view_id is the name of the view to display when the action is activated. The four possibilities are : o form. and is set to tree when the action must open a new tree view.actions. and hence to get less records displayed in the view. res_model is the name of the object on which the action operates.

actions.picking</field> <field name="type">ir.actions.project</field> <field name="view_type">tree</field> <field name="domain">[('parent_id'. ('manager'.act_window</field> <field name="view_type">form</field> <field name="view_id" ref="view_picking_form"/> <field name="context">{'contact_display': 'partner'}</field> </record> .actions.picking</field> <field name="res_model">stock.act_window" id="open_view_my_project"> <field name="name">project.Examples of actions¶ This action is declared in server/bin/addons/project/project_view. '='. <record model="ir.act_window" id="action_picking_form"> <field name="name">stock. <record model="ir.'='. uid)]</field> <field name="view_id" ref="view_my_project" /> </record> This action is declared in server/bin/addons/stock/stock_view.False).xml.project</field> <field name="res_model">project.xml.

See “Add A New Wizard” for more information about wizard XML.employee" name="employee.wizard" id="wizard_employee_info"/> <menuitem name="Human Resource/Employee Info" action="wizard_employee_info" type="wizard" id="menu_wizard_employee_info"/> </data> </openerp> Report Action Reports in Open ERP are explained in chapter “Reports Reporting”.employee" name="employee.XML file that declares a wizard.print" rml="sale_category/report/sale_category_report. <?xml version="1. also you can add wizard in menu using following xml entry <?xml version="1.0"?> <openerp> <data> <wizard string="Employee Info" model="hr.info.0"?> <openerp> <data> <wizard string="Employee Info" model="hr.rml" menu="True" auto="False"/> .info.Url Action Here‟s an example of a .0"?> <openerp> <data> <report id="sale_category_print" string="Sales Orders By Categories" model="sale.wizard" id="wizard_employee_info"/> </data> </openerp> A wizard is declared using a wizard tag. Here‟s an example of a XML file that declares a RML report : <?xml version="1.order" name="sale_category.

RML file must be parsed using the default parser or not. string : the text of the menu that calls the report (if any. rml : the . menu : whether the report will be able to be called directly via the client or not.RML report model. Important Note : Path is relative to addons/ directory.</data> </openerp> A report is declared using a report tag inside a “data” block. model : the Open ERP object on which the report will be rendered. The different arguments of a report tag are : id : an identifier which must be unique. auto : determines if the . Using a custom parser allows you to define additional functions to your report. see below). Setting menu to False is useful in case of reports called by wizards. .

Sign up to vote on this title
UsefulNot useful