Some Links

Tutorials

License

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.

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()

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 :

<terp>

<data>

<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>

</record>

<menuitem name="LFY_Sample/Product" id="menu_lfy_sample_form"

action="action_lfy_sample_form" />

</data>

</terp>

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">

<notebook>

<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>

<page string="Descriptions">

<separator string="Description" />

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

</page>

<page string="Properties">

<properties/>

</page>

</notebook>

</form>

</field>

</record>

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.

Summary

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.