Other Articles‎ > ‎

Taking the Next Step with TinyERP

The concept of a business is fairly straightforward. Each business will deal with common business objects, e.g. products, orders, invoices, etc. However, the attributes of each of these persistent objects differ from one organization to another. Complexity gets added in the way these objects interact with each other. We customize a general ERP system to match the objects and the interactions between them to model the business processes being followed in an organization.

While conceptually simple, it can be difficult to know how to get started. This is especially frustrating in the case of Open Source ERP solutions. While we can download and explore the software, if we cannot get started, we may give up before we can make sense of the documentation and the discussion forums. In this article, we will discuss how to get started with TinyERP.

I have a strong bias towards Python and applications written in Python. TinyERP has been developing quite rapidly in the last year. The discussion forums are moderately active. Comparatively, TinyERP appears to be less complex and easier to manage. Very good J2EE alternatives are available in Compiere, Adempiere, OFBiz.

TinyERP makes it easy to add modules which extend or modify the capabilities of the existing system. The client application is only for display. It communicates with the server using xml-rpc calls. The customisation code will go in the server application. The server contains a directory 'addons' which, as the name suggests, contains the various modules, including ones we may wish to add. There are about 200 modules available on the Tinyerp web site.

This does bring up an interesting point – is finding the right modules and customising them easier or could it be easier to build the entire application by just defining the business processes? See www.thingamy.com for this alternate approach though there isn't very much concrete to play around with as yet.

A Small Task

We will create a simple module, lfy_sample. The module will define an additional persistent object by inheriting from the existing product object. The module will define a view for manipulating these objects through the client application.

The modules will consist of the following files:

  • Module initialisation and configuration files: __init__.py, __terp__.py

  • Object definition file : lfy_sample.py

  • View definition file : lfy_sample_view.xml

Minimum Code

If tinyerp-server is installed on the system, the code for the module will be in $PYTHON_HOME/site-packages/tinyerp-server/addons. While developing, it is easier to just untar the tinyerp-server-x.tgz in the home directory and work in its bin directory.

Create a directory lfy_sample in addons. Create the file __init__.py with just one line:

import lfy_sample

Now we create __terp__.py


"name" : "A Trivial Sample",

"version" : "0.1",

"author" : "Anil",

"depends" : ["base","product"],

"init_xml" : [],

"update_xml" : ["lfy_sample_view.xml"],

"category" : "Enterprise Specific Modules/Training Sample",

"active" : False,

"installable" : True


Since we will be inheriting from the product object, this module depends upon product in addition to the base. The update_xml entry defines the view file, which will be updated when we start the server with the update option. The module will not be active by default. We will need to install it if we need it.

The next step is to define the object. The system will map the object definition to the underlying relational database. The contents of the lfy_sample.py are as follows:

from osv import fields, osv

class lfy_sample_product(osv.osv):

_name = "lfy.sample.product"

_description = "Sample type"

_inherit = "product.product"

_columns = {

'shelf_life'=fields.integer('Shelf Life'),



lfy_sample_product object will contain all the fields of product.product and add a new column. The implementation of this object is with a join on the original table with a new table with the additional columns.

We now define the view in the file lfy_sample_view.xml :



<record model="ir.actions.act_window" id="action_lfy_sample_form">

<field name="name">lfy.sample</field>

<field name="res_model">lfy.sample.product</field>

<field name="domain">[('shelf_life','!=','')]</field>


<menuitem name="LFY_Sample/Product" id="menu_lfy_sample_form"
action="action_lfy_sample_form" />



The key fields above are the res_model which defines the objects with which we are dealing and the domain which restricts the objects to only those products which have a value for the shelf_life column.

We can now restart the tinyerp server and client. In the client, we choose Administration/Module Management/Update Module List. If the files are correct, we should find a new module lfy_sample. We install this module and refresh the menu. We should find LFY_Sample as one of the menu options. Clicking on it will give the option Product. Since no form has been defined, if we create a new entry, we will find a default form with all the fields. This is not very convenient if an object contains a lot of attributes.

Adding a Form View

We will add a form view, basing it on a view defined in the product addon. The following code is inserted after the menuitem tag in lfy_sample_view.xml:

<record model="ir.ui.view" id="lfy_sample_form_view`">

<field name="name">lfy.sample.form</field>

<field name="model">lfy.sample.product</field>

<field name="type">form</field>

<field name="priority" eval="7"/>

<field name="arch" type="xml">

<form string="Product">


<page string="Information">

<field name="name" select="1"/>

<field name="default_code" select="1"/>

<field name="shelf_life" select="1"/>

<field name="categ_id" select="1"/>


<page string="Descriptions">

<separator string="Description" />

<field name="description" colspan="4" nolabel="1" />


<page string="Properties">







The form is defined as a notebook with multiple pages, which are displayed in a tabbed view. It contains the column defined in lfy_sample and the attributes of interest from the product object. The option select='1' in a field includes the field in the search menu. After modifying the lfy_sample_view.xml, we restart the tinyerp server with the option --update=lfy_sample. If all has gone well, clicking on LFY_Sample/Product and creating a new entry should bring up a much simpler form with 3 tabbed pages. We can create products using this form. Note that these products will also be visible in Products/Products. However, the reverse is not true since we have restricted the domain of the products in the view associated with lfy_sample.

One can continue the exploration with information from http://tinyerp.org/wiki/.


Real life ERP customisations are complex. This is true no matter what the product as reflected in an interesting quotation in an article by Laurianne McLaughlin in CIO (http://www.cio.com):

“It's almost a miracle that SAP got as big as it did; they're just selling a skeleton."

Thousands of companies could benefit from erp systems if only they were far less expensive. In this article, we have explored the possibility of using an Open Source “skeleton” instead. It isn't hard to get started. The internal IT departments of companies can and should explore them for their own use. Possibilities are limitless.