You are on page 1of 56

Tryton Technical Training

N. Évrard

B2 CK

September 18, 2015

N. Évrard (B2 CK ) Tryton Technical Training September 18, 2015 1 / 56


Overview and Installation

Outline

1 Overview and Installation


Tryton Overview
Prerequisites
Initializing tryton

2 A basic module

3 Some more advanced features

4 Additional topics

N. Évrard (B2 CK ) Tryton Technical Training September 18, 2015 2 / 56


Overview and Installation Tryton Overview

Global overview

A general purpose application platform


Web shop
Insurance software
GNU Health
Traditional ERP
Covers lot of fields
Accounting
Sales Management
Stock Management
...
Free Software
GPL-3
Tryton foundation
TU*

N. Évrard (B2 CK ) Tryton Technical Training September 18, 2015 3 / 56


Overview and Installation Tryton Overview

Technical Overview

Written in Python
Three tiers architecture
PyGTK client (tryton) and a JavaScript client (sao) in its infancy
Application Server (trytond)
dbms, usually PostgreSQL but you can use SQLite or even MySQL
Modularity of business functionalities

N. Évrard (B2 CK ) Tryton Technical Training September 18, 2015 4 / 56


Overview and Installation Prerequisites

Python good practices (pip & virtualenv)

pip is THE tool for installing and managing Python packages.


virtualenv is THE tool used to create isolated Python environment.
create isolated Python environments
Do not mix different version of your libraries / applications
Installation of packages in the user $HOME
pip install virtualenv (or your distro package manager)
virtualenv --system-site-packages .venv/trytond
source .venv/trytond/bin/activate
hgnested is a mercurial extension. The tryton project use it to easily apply the same
command on nested repositories.

N. Évrard (B2 CK ) Tryton Technical Training September 18, 2015 5 / 56


Overview and Installation Prerequisites

Configuring mercurial

In order to activate both the hgnested and MQ extensions of Mercurial we will need to
add those lines to your .hgrc
Example

[extensions]
hgext.mq =
hgnested =

N. Évrard (B2 CK ) Tryton Technical Training September 18, 2015 6 / 56


Overview and Installation Initializing tryton

Installing trytond

Example

$ hg nclone http://hg.tryton.org/3.4/trytond -b 3.4


$ cd trytond
$ pip install -e .
$ pip install vobject

N. Évrard (B2 CK ) Tryton Technical Training September 18, 2015 7 / 56


Overview and Installation Initializing tryton

Setting up a trytond config file

Here is a minimal example of a configuration file. You should save it in


$HOME/.trytond.conf
Example

[database]
path = /home/training/databases

We will set the TRYTOND_CONFIG environment variable


Example

$ export TRYTOND_CONFIG=$HOME/.trytond.conf

N. Évrard (B2 CK ) Tryton Technical Training September 18, 2015 8 / 56


Overview and Installation Initializing tryton

Initializing a minimal trytond database

Example

$ touch ~/databases/test.sqlite
$ ./bin/trytond -d test -u ir res

trytond will ask you for the admin password at the end of the installation process.

N. Évrard (B2 CK ) Tryton Technical Training September 18, 2015 9 / 56


Overview and Installation Initializing tryton

Adding a new modules

In this tutorial we will use a MQ repository in order to progress step by step.


Example

$ cd trytond/modules
$ hg init training
$ cd training/.hg
$ hg clone http://hg.tryton.org/training -b 3.4 patches

N. Évrard (B2 CK ) Tryton Technical Training September 18, 2015 10 / 56


A basic module

Outline

1 Overview and Installation

2 A basic module
A minimal module
Defining some object / tables
Different fields
Defining a tree and a form view
Default values and on_change calls

3 Some more advanced features

4 Additional topics

N. Évrard (B2 CK ) Tryton Technical Training September 18, 2015 11 / 56


A basic module A minimal module

A minimal trytond modules

A minimal trytond modules needs two files:


__init__.py the usual file needed by all python modules
tryton.cfg the file that helps tryton glue together model and view definitions

N. Évrard (B2 CK ) Tryton Technical Training September 18, 2015 12 / 56


A basic module A minimal module

The content of tryton.cfg

Example

[tryton]
version=0.0.1
depends:
ir
res

N. Évrard (B2 CK ) Tryton Technical Training September 18, 2015 13 / 56


A basic module Defining some object / tables

Creating a model

A trytond model is a python class inheriting from Model. To enable the SQL
persistence the model must inherit of ModelSQL.
Example
from t r y t o n d . model import ModelSQL

__all__ = [ ’ Opportunity ’ ]

c l a s s O p p o r t u n i t y ( ModelSQL ) :
’ Opportunity ’
__name__ = ’ t r a i n i n g . o p p o r t u n i t y ’

N. Évrard (B2 CK ) Tryton Technical Training September 18, 2015 14 / 56


A basic module Defining some object / tables

Register the model

In order for your object to be "known" by trytond they must be registered into the pool.
Example
from t r y t o n d . p o o l import P o o l
from . o p p o r t u n i t y import ∗

def r e g i s t e r ( ) :
Pool . r e g i s t e r (
Opportunity ,
module = ’ t r a i n i n g ’ , t y p e _ = ’ model ’ )

N. Évrard (B2 CK ) Tryton Technical Training September 18, 2015 15 / 56


A basic module Defining some object / tables

Adding fields to a model

Example
c l a s s O p p o r t u n i t y ( ModelSQL ) :
’ Opportunity ’
__name__ = ’ t r a i n i n g . o p p o r t u n i t y ’
_rec_name = ’ d e s c r i p t i o n ’
d e s c r i p t i o n = f i e l d s . Char ( ’ D e s c r i p t i o n ’ ,
r e q u i r e d =True )
s t a r t _ d a t e = f i e l d s . Date ( ’ S t a r t Date ’ ,
r e q u i r e d =True )
e n d _ d a t e = f i e l d s . D a t e ( ’ End D a t e ’ )
p a r t y = f i e l d s . Many2One ( ’ p a r t y . p a r t y ’ ,
’ P a r t y ’ , r e q u i r e d =True )
comment = f i e l d s . T e x t ( ’ Comment ’ )

N. Évrard (B2 CK ) Tryton Technical Training September 18, 2015 16 / 56


A basic module Defining some object / tables

fields arguments

string A string for label of the field.


required A boolean if True the field is required.
readonly A boolean if True the field is not editable in the user interface.
domain A list that defines a domain constraint.
states A dictionary. Possible keys are required, readonly and invisible.
Values are pyson expressions that will be evaluated with record
values. This allows to change dynamically the attributes of the field.
The whole list in trytond/model/fields/field.py

N. Évrard (B2 CK ) Tryton Technical Training September 18, 2015 17 / 56


A basic module Different fields

fields.Char

In a tryton module:
Example
d e s c r i p t i o n = f i e l d s . Char ( ’ D e s c r i p t i o n ’ , r e q u i r e d = T r u e )

In the interface:
Example

In SQL:
Example
d e s c r i p t i o n VARCHAR NOT NULL

N. Évrard (B2 CK ) Tryton Technical Training September 18, 2015 18 / 56


A basic module Different fields

fields.Date

In a tryton module:
Example
s t a r t _ d a t e = f i e l d s . Date ( ’ S t a r t Date ’ , r e q u i r e d =True )

In the interface:
Example

In SQL:
Example
s t a r t _ d a t e DATE NOT NULL

N. Évrard (B2 CK ) Tryton Technical Training September 18, 2015 19 / 56


A basic module Different fields

fields.Text

In a tryton module:
Example
comment = f i e l d s . T e x t ( ’ Comment ’ )

In the interface:
Example

In SQL:
Example
comment TEXT

N. Évrard (B2 CK ) Tryton Technical Training September 18, 2015 20 / 56


A basic module Different fields

fields.Many2One

In a tryton module:
Example
p a r t y = f i e l d s . Many2One ( ’ p a r t y . p a r t y ’ , ’ P a r t y ’ , r e q u i r e d = T r u e )

In the interface:
Example

In SQL:
Example
p a r t y i n t e g e r NOT NULL,
FOREIGN KEY( p a r t y ) REFERENCES p a r t y _ p a r t y ( i d )

N. Évrard (B2 CK ) Tryton Technical Training September 18, 2015 21 / 56


A basic module Different fields

Other relation fields

fields.One2Many
fields.Many2Many
fields.One2One

N. Évrard (B2 CK ) Tryton Technical Training September 18, 2015 22 / 56


A basic module Defining a tree and a form view

Displaying data

To use the presentation layer your model must inherit from ModelView
Example
c l a s s O p p o r t u n i t y ( ModelSQL , ModelView ) :

You must also add the xml presentation file in the tryton.cfg configuration file
Example

xml:
opportunity.xml

N. Évrard (B2 CK ) Tryton Technical Training September 18, 2015 23 / 56


A basic module Defining a tree and a form view

Defining a view

View objects are normal tryton objects (trytond/ir/ui/view.py)


Two kind of view:
Tree view a list of record
Form view a view for editing/creating one record

N. Évrard (B2 CK ) Tryton Technical Training September 18, 2015 24 / 56


A basic module Defining a tree and a form view

A tree view

Example
< r e c o r d model = " i r . u i . view " i d = " o p p o r t u n i t y _ v i e w _ l i s t " >
< f i e l d name= " model " > t r a i n i n g . o p p o r t u n i t y < / f i e l d >
< f i e l d name= " t y p e " > t r e e < / f i e l d >
< f i e l d name= " name " > o p p o r t u n i t y _ l i s t < / f i e l d >
</ record>

Example
< t r e e s t r i n g =" O p p o r t u n i t i e s ">
< f i e l d name= " p a r t y " / >
< f i e l d name= " d e s c r i p t i o n " / >
< f i e l d name= " s t a r t _ d a t e " / >
< f i e l d name= " e n d _ d a t e " / >
</ tree>

N. Évrard (B2 CK ) Tryton Technical Training September 18, 2015 25 / 56


A basic module Defining a tree and a form view

A form view

Example
< r e c o r d model = " i r . u i . view " i d = " o p p o r t u n i t y _ v i e w _ f o r m " >
< f i e l d name= " model " > t r a i n i n g . o p p o r t u n i t y < / f i e l d >
< f i e l d name= " t y p e " > form < / f i e l d >
< f i e l d name= " name " > o p p o r t u n i t y _ f o r m < / f i e l d >
</ record>

Example
< form s t r i n g = " O p p o r t u n i t y " >
< l a b e l name= " p a r t y " / >
< f i e l d name= " p a r t y " / >
< l a b e l name= " d e s c r i p t i o n " / >
< f i e l d name= " d e s c r i p t i o n " / >
< l a b e l name= " s t a r t _ d a t e " / >
< f i e l d name= " s t a r t _ d a t e " / >
< l a b e l name= " e n d _ d a t e " / >
< f i e l d name= " e n d _ d a t e " / >
< s e p a r a t o r name= " comment " c o l s p a n = " 4 " / >
< f i e l d name= " comment " c o l s p a n = " 4 " / >
< / form >

N. Évrard (B2 CK ) Tryton Technical Training September 18, 2015 26 / 56


A basic module Defining a tree and a form view

Gluing them together

Example
< r e c o r d model = " i r . a c t i o n . a c t _ w i n d o w "
id =" a c t _ o p p o r t u n i t y _ f o r m ">
< f i e l d name= " name " > O p p o r t u n i t i e s < / f i e l d >
< f i e l d name= " r e s _ m o d e l " > t r a i n i n g . o p p o r t u n i t y < / f i e l d >
</ record>
< r e c o r d model = " i r . a c t i o n . a c t _ w i n d o w . view "
id =" act_opportunity_form_view1 ">
< f i e l d name= " s e q u e n c e " e v a l = " 10 " / >
< f i e l d name= " view " r e f = " o p p o r t u n i t y _ v i e w _ t r e e " / >
< f i e l d name= " a c t _ w i n d o w " r e f = " a c t _ o p p o r t u n i t y _ f o r m " / >
</ record>
< r e c o r d model = " i r . a c t i o n . a c t _ w i n d o w . view "
id =" act_opportunity_form_view2 ">
< f i e l d name= " s e q u e n c e " e v a l = " 20 " / >
< f i e l d name= " view " r e f = " o p p o r t u n i t y _ v i e w _ f o r m " / >
< f i e l d name= " a c t _ w i n d o w " r e f = " a c t _ o p p o r t u n i t y _ f o r m " / >
</ record>

N. Évrard (B2 CK ) Tryton Technical Training September 18, 2015 27 / 56


A basic module Defining a tree and a form view

Adding menu entries

Example
< menuitem name= " T r a i n i n g " i d = " m e n u _ t r a i n i n g " / >
< menuitem p a r e n t = " m e n u _ t r a i n i n g "
a c t i o n =" a c t _ o p p o r t u n i t y _ f o r m "
id =" menu_opportunity_form " / >

N. Évrard (B2 CK ) Tryton Technical Training September 18, 2015 28 / 56


A basic module Default values and on_change calls

Adding default values

Create a method in the object with the name default_<field_name>


Example
@staticmethod
def d e f a u l t _ s t a r t _ d a t e ( ) :
pool = Pool ( )
Date = pool . g e t ( ’ i r . d a t e ’ )
return Date . today ( )

N. Évrard (B2 CK ) Tryton Technical Training September 18, 2015 29 / 56


A basic module Default values and on_change calls

Reacting to user input: on_change

Tryton provides a way to react on the user input by changing the value of other fields.
This mechanism is call the on_changes.
They come in two flavours:
on_change_<field name> When a field is changed a list of value is sent to the server.
The server sends the new values of some fields
on_change_with_<field name> A field value is computed when any field in a list of
fields is modified. The computation occurs on the server.
In both case the list of fields sent to the server is specified thanks to the decorator
@fields.depends.

N. Évrard (B2 CK ) Tryton Technical Training September 18, 2015 30 / 56


A basic module Default values and on_change calls

on_change

Example
@fields . depends ( ’ p a r t y ’ )
def on_change_party ( s e l f ) :
a d d r e s s = None
if self . party :
a d d r e s s = s e l f . p a r t y . a d d r e s s _ g e t ( type= ’ i n v o i c e ’ )

return {
’ address ’ : address ,
}

N. Évrard (B2 CK ) Tryton Technical Training September 18, 2015 31 / 56


A basic module Default values and on_change calls

on_change_with

Example
@fields . depends ( ’ s t a r t _ d a t e ’ )
def on_change_with_end_date ( s e l f ) :
if self . start_date :
return s e l f . s t a r t _ d a t e + d a t e t i m e . t i m e d e l t a ( days =7)
r e t u r n None

N. Évrard (B2 CK ) Tryton Technical Training September 18, 2015 32 / 56


Some more advanced features

Outline

1 Overview and Installation

2 A basic module

3 Some more advanced features


Workflows
More beautiful views
Function fields
Wizards
Extending pre-existing tryton objects

4 Additional topics

N. Évrard (B2 CK ) Tryton Technical Training September 18, 2015 33 / 56


Some more advanced features Workflows

Adding workflow to object

Your object should inherit from Workflow


Example
c l a s s O p p o r t u n i t y ( Workflow , ModelSQL , ModelView ) :

It must have a state field:


Example
state = fields . Selection ([
( ’ opportunity ’ , ’ Opportunity ’ ) ,
( ’ converted ’ , ’ Converted ’ ) ,
( ’ l o s t ’ , ’ Lost ’ ) ,
] , ’ S t a t e ’ , r e q u i r e d = True ,
r e a d o n l y = True , s o r t = F a l s e )

N. Évrard (B2 CK ) Tryton Technical Training September 18, 2015 34 / 56


Some more advanced features Workflows

Defining a workflow

A workflow is composed of transitions:


Example
@classmethod
def __setup__ ( c l s ) :
super ( O pp o rt un i ty , c l s ) . __setup__ ( )
cls . _transitions \|= set ((
( ’ opportunity ’ , ’ converted ’ ) ,
( ’ opportunity ’ , ’ lost ’) ,
))

N. Évrard (B2 CK ) Tryton Technical Training September 18, 2015 35 / 56


Some more advanced features Workflows

Defining transition method

Each transition must be linked a class method:


Example
@classmethod
@Workflow . t r a n s i t i o n ( ’ c o n v e r t e d ’ )
def convert ( cls , o p p o r t u n i t i e s ) :
pool = Pool ( )
Date = pool . g e t ( ’ i r . d a t e ’ )
cls . write ( opportunities , {
’ en d_da te ’ : Date . today ( ) ,
})

N. Évrard (B2 CK ) Tryton Technical Training September 18, 2015 36 / 56


Some more advanced features Workflows

Adding buttons in view

Now we need to add buttons in the view


Example
< b u t t o n name= " c o n v e r t " s t r i n g = " C o n v e r t " i c o n = " t r y t o n−go−n e x t " / >

The method must be "button decorated" to be callable and defined.


Example
@classmethod
def __setup__ ( c l s ) :
...
c l s . _buttons . update ({
’ convert ’ : {} ,
’ l o s t ’ : {} ,
})

@classmethod
@ModelView . b u t t o n
@Workflow . t r a n s i t i o n ( ’ c o n v e r t e d ’ )
def convert ( cls , o p p o r t u n i t i e s ) :
...

N. Évrard (B2 CK ) Tryton Technical Training September 18, 2015 37 / 56


Some more advanced features More beautiful views

Making the view more beautiful

Let’s add the state and the buttons to the opportunity view. There is also a way of
grouping widgets
Example
<group co l =" 2 " colspan =" 2 " id =" s t a t e ">
< l a b e l name= " s t a t e " / >
< f i e l d name= " s t a t e " / >
< / group>
<group co l =" 2 " colspan =" 2 " id =" b u t t o n s ">
< b u t t o n name= " l o s t " s t r i n g = " L o s t " i c o n = " t r y t o n−c a n c e l " / >
< b u t t o n name= " c o n v e r t " s t r i n g = " C o n v e r t " i c o n = " t r y t o n−go−n e x t " / >
< / group>

N. Évrard (B2 CK ) Tryton Technical Training September 18, 2015 38 / 56


Some more advanced features More beautiful views

Adding dynamicity in the form

Of course sometimes you want to make fields readonly/invisible/required under certain


conditions. This behavior can be implemented using the states attribute of fields:
Example
s t a r t _ d a t e = f i e l d s . D a t e ( ’ S t a r t D a t e ’ , r e q u i r e d = True ,
s t a t e s ={
’ r e a d o n l y ’ : Eval ( ’ s t a t e ’ ) != ’ o p p o r t u n i t y ’ ,
} , depends =[ ’ s t a t e ’ ] )
e n d _ d a t e = f i e l d s . D a t e ( ’ End D a t e ’ , r e a d o n l y = True ,
s t a t e s ={
’ r e q u i r e d ’ : Eval ( ’ s t a t e ’ ) . in_ ( [ ’ converted ’ ,
’ lost ’ ]) ,
} , depends =[ ’ s t a t e ’ ] )

pyson is used to encode statements that can be evaluated.


http://doc.tryton.org/2.6/trytond/doc/topics/pyson.html

N. Évrard (B2 CK ) Tryton Technical Training September 18, 2015 39 / 56


Some more advanced features More beautiful views

Adding dynamicity to buttons

pyson expression can also be used on buttons to hide them.


Example
@classmethod
def __setup__ ( c l s ) :
...
c l s . _buttons . update ({
’ convert ’ : {
’ invisible ’ : ~Eval ( ’ s t a t e ’ ) \
. in_ ( [ ’ opportunity ’ ]) ,
},
’ lost ’ : {
’ invisible ’ : ~Eval ( ’ s t a t e ’ ) \
. in_ ( [ ’ opportunity ’ ]) ,
},
})

N. Évrard (B2 CK ) Tryton Technical Training September 18, 2015 40 / 56


Some more advanced features Function fields

Defining a simple function field

A function field is a field that is computed into python its data is not persistently store
into the database.
Example
duration = f i e l d s . Function ( f i e l d s . Integer ( ’ Duration ’ ) , ’ get_duration ’ )

d e f g e t _ d u r a t i o n ( s e l f , name=None ) :
i f n o t s e l f . s t a r t _ d a t e or n o t s e l f . e n d _ d a t e :
r e t u r n None
return ( s e l f . end_date − s e l f . s t a r t _ d a t e ) . days

Any tryton type can be used. Note also that since this signature is the same as the one
of an on_change_with then the same function can be used for both.
Of course a setter and a searcher can also be defined in order to modify or search
corresponding data.

N. Évrard (B2 CK ) Tryton Technical Training September 18, 2015 41 / 56


Some more advanced features Function fields

Defining a function field operating by batch

The previous example makes one call per record.


Tryton provides a way to compute the values by batch. In order to do so the getter must
be a classmethod and it must return a dictionary mapping the id to the function value.
Example
d e s c r i p t i o n _ l e n g t h = f i e l d s . Function ( f i e l d s . I n t e g e r ( ’ D e s c r i p t i o n Length ’ ) ,
’ get_description_length ’)

@classmethod
d e f g e t _ d e s c r i p t i o n _ l e n g t h ( c l s , o p p o r t u n i t i e s , name ) :
cursor = Transaction . cursor ()

opportunity = cls . __table__ ()


query = o p p o r t u n i t y . s e l e c t (
o p p o r t u n i t y . id , C h a r L e n g t h ( o p p o r t u n i t y . d e s c r i p t i o n ) )
c u r s o r . execute (∗ query )

return d i c t ( c u r s o r . f e t c h a l l ( ) )

N. Évrard (B2 CK ) Tryton Technical Training September 18, 2015 42 / 56


Some more advanced features Wizards

Adding actions to model

Sometime you want to add functionalities to a model that do not suite the use of a
button. For this kind of use case the wizard is your solution.
A wizard is composed of two things:
A set of views that represent the form to gather the user input
A "state machine" that define what should be done

N. Évrard (B2 CK ) Tryton Technical Training September 18, 2015 43 / 56


Some more advanced features Wizards

Wizard views

Those are standard ModelView, you can define on_change, on_change_with and
default values on them.
Example
c l a s s C o n v e r t O p p o r t u n i t i e s S t a r t ( ModelView ) :
’ Convert O p p o r t u n i t i e s ’
__name__ = ’ t r a i n i n g . o p p o r t u n i t y . c o n v e r t . s t a r t ’

N. Évrard (B2 CK ) Tryton Technical Training September 18, 2015 44 / 56


Some more advanced features Wizards

Wizard "state machine"

This is a class that inherits from Wizard. You’ll be able to define different states on it.
Example
from t r y t o n d . w i z a r d import Wizard , S t a t e V i e w , S t a t e T r a n s i t i o n , B u t t o n

c l a s s C o n v e r t O p p o r t u n i t i e s ( Wizard ) :
’ Convert O p p o r t u n i t i e s ’
__name__ = ’ t r a i n i n g . o p p o r t u n i t y . c o n v e r t ’

s t a r t = StateView ( ’ t r a i n i n g . o p p o r t u n i t y . convert . s t a r t ’ ,
’ training . opportunity_convert_start_view_form ’ , [
B u t t o n ( ’ C a n c e l ’ , ’ end ’ , ’ t r y t o n−c a n c e l ’ ) ,
B u t t o n ( ’ C o n v e r t ’ , ’ c o n v e r t ’ , ’ t r y t o n−ok ’ , d e f a u l t = T r u e ) ,
])
convert = StateTransition ()

def t r a n s i t i o n _ c o n v e r t ( s e l f ) :
pool = Pool ( )
Opportunity = pool . get ( ’ t r a i n i n g . opportuni ty ’ )
o p p o r t u n i t i e s = O p p o r t u n i t y . browse (
Transaction ( ) . context [ ’ active_ids ’ ])
Opportunity . convert ( opportunities )
r e t u r n ’ end ’

N. Évrard (B2 CK ) Tryton Technical Training September 18, 2015 45 / 56


Some more advanced features Wizards

Activating the wizard

Example
< r e c o r d model = " i r . a c t i o n . w i z a r d " i d = " a c t _ c o n v e r t _ o p p o r t u n i t i e s " >
< f i e l d name= " name " > C o n v e r t O p p o r t u n i t i e s < / f i e l d >
< f i e l d name= " wiz_name " > t r a i n i n g . o p p o r t u n i t y . c o n v e r t < / f i e l d >
< f i e l d name= " model " > t r a i n i n g . o p p o r t u n i t y < / f i e l d >
</ record>
< r e c o r d model = " i r . a c t i o n . keyword " i d = " a c t _ c o n v e r t _ o p p o r t u n i t i e s _ k e y w o r d " >
< f i e l d name= " keyword " > f o r m _ a c t i o n < / f i e l d >
< f i e l d name= " model " > t r a i n i n g . o p p o r t u n i t y ,−1< / f i e l d >
< f i e l d name= " a c t i o n " r e f = " a c t _ c o n v e r t _ o p p o r t u n i t i e s " / >
</ record>

N. Évrard (B2 CK ) Tryton Technical Training September 18, 2015 46 / 56


Some more advanced features Extending pre-existing tryton objects

Extending models

Sometimes you want to extend existing objects to add miscellaneous information.


Doing so is just a matter of (tryton) inheritance:
Example
from t r y t o n d . model import f i e l d s
from t r y t o n d . p o o l import P o o l M e t a

__all__ = [ ’ Party ’ ]
_ _ m e t a c l a s s _ _ = PoolMeta

class Party :
__name__ = ’ p a r t y . p a r t y ’
o p p o r t u n i t i e s = f i e l d s . One2Many (
’ training . opportunity ’ , ’ party ’ ,
’ Opportunities ’ )

N. Évrard (B2 CK ) Tryton Technical Training September 18, 2015 47 / 56


Some more advanced features Extending pre-existing tryton objects

Extending existing views

Modifing existing view is done by adding record in the XML files that specify an
xpath and what to do with the resulting node.
Example
< r e c o r d model = " i r . u i . view " i d = " p a r t y _ v i e w _ f o r m " >
< f i e l d name= " model " > p a r t y . p a r t y < / f i e l d >
< f i e l d name= " i n h e r i t " r e f = " p a r t y . p a r t y _ v i e w _ f o r m " / >
< f i e l d name= " name " > p a r t y _ f o r m < / f i e l d >
</ record>

Example
<data>
< x p a t h e x p r = " / form / n o t e b o o k / p a g e [ @id = ’ a c c o u n t i n g ’ ] "
p o s i t i o n =" a f t e r ">
< p a g e name= " o p p o r t u n i t i e s " c o l = " 1 " >
< s e p a r a t o r name= " o p p o r t u n i t i e s " / >
< f i e l d name= " o p p o r t u n i t i e s " / >
< / page>
< / xpath>
</ data>

N. Évrard (B2 CK ) Tryton Technical Training September 18, 2015 48 / 56


Additional topics

Outline

1 Overview and Installation

2 A basic module

3 Some more advanced features

4 Additional topics
Reporting
proteus
Table Queries

N. Évrard (B2 CK ) Tryton Technical Training September 18, 2015 49 / 56


Additional topics Reporting

Adding a report

To add a report you must create an odt template that is compatible with relatorio
(http://relatorio.openhex.org/)
This report engine allows you to create opendocument files from templates.

N. Évrard (B2 CK ) Tryton Technical Training September 18, 2015 50 / 56


Additional topics Reporting

Making trytond aware of the report

You must define a python class that will register a report object
Example
from t r y t o n d . r e p o r t import R e p o r t

c l a s s OpportunityReport ( Report ) :
pass

You might want to overload the parse method to define a specific behavior.

N. Évrard (B2 CK ) Tryton Technical Training September 18, 2015 51 / 56


Additional topics Reporting

Creating the report object

Example
< r e c o r d model = " i r . a c t i o n . r e p o r t " i d = " r e p o r t _ o p p o r t u n i t y " >
< f i e l d name= " name " > O p p o r t u n i t y < / f i e l d >
< f i e l d name= " model " > t r a i n i n g . o p p o r t u n i t y < / f i e l d >
< f i e l d name= " r e p o r t _ n a m e " > t r a i n i n g . o p p o r t u n i t y < / f i e l d >
< f i e l d name= " r e p o r t " > t r a i n i n g / o p p o r t u n i t y . o d t < / f i e l d >
</ record>
< r e c o r d model = " i r . a c t i o n . keyword "
id =" r e p o r t _ o p p o r t u n i t y _ k e y w o r d ">
< f i e l d name= " keyword " > f o r m _ p r i n t < / f i e l d >
< f i e l d name= " model " > t r a i n i n g . o p p o r t u n i t y ,−1< / f i e l d >
< f i e l d name= " a c t i o n " r e f = " r e p o r t _ o p p o r t u n i t y " / >
</ record>

N. Évrard (B2 CK ) Tryton Technical Training September 18, 2015 52 / 56


Additional topics proteus

Using proteus to script tryton

You might want to script your tryton server. For this there is the proteus library. It will
allow you to interact with it in a python way.
With models you will be able to use the find, edit, delete and create objects
You will also have the possiblity to use the wizards.

N. Évrard (B2 CK ) Tryton Technical Training September 18, 2015 53 / 56


Additional topics proteus

Setting up proteus

To set up proteus, you first need a connection to a Tryton server:


either through xml-rpc using the set_xmlrpc method
or on the same compute using the set_trytond method
The latter will use the possibility to import trytond to create and set up an internal
trytond server.

N. Évrard (B2 CK ) Tryton Technical Training September 18, 2015 54 / 56


Additional topics proteus

An example of proteus

Example
import csv
import datetime
import sys
from p r o t e u s i m p o r t c o n f i g , Model

d e f main ( a r g s ) :
P a r t y = Model . g e t ( ’ p a r t y . p a r t y ’ )
O p p o r t u n i t y = Model . g e t ( ’ t r a i n i n g . o p p o r t u n i t y ’ )
c s v _ f i l e = c s v . D i c t R e a d e r ( open ( a r g s [ 1 ] , ’ r ’ ) )
for line in c s v _ f i l e :
p a r t i e s = P a r t y . f i n d ( [ ( ’ name ’ , ’ = ’ , l i n e [ ’ P a r t y ’ ] ) ] )
i f not p a r t i e s :
p a r t y = P a r t y ( name= l i n e [ ’ P a r t y ’ ] )
party . save ( )
else:
party = parties [0]
l i n e _ d a t e = d a t e t i m e . d a t e t i m e . s t r p t i m e ( l i n e [ ’ Date ’ ] ,
’%d/%m/%y ’ ) . d a t e ( )
new_opportunity = Opportunity ( party =party ,
description=line [ ’ Description ’ ] , start_date =line_date )
new_opportunity . save ( )

i f __name__ == ’ __main__ ’ :
c o n f i g . s e t _ t r y t o n d ( p a s s w o r d = ’ admin ’ , d a t a b a s e _ n a m e = ’ t r a i n i n g ’ )
main ( s y s . a r g v )

N. Évrard (B2 CK ) Tryton Technical Training September 18, 2015 55 / 56


Additional topics Table Queries

Creating a ’view’ object

table_query allows you to define a sql-query to use as source of the records.


Example
c l a s s O p p o r t u n i t y B y P a r t y ( ModelSQL , ModelView ) :
’ O p p o r t u n i t i e s by P a r t y ’
__name__ = ’ t r a i n i n g . o p p o r t u n i t y _ b y _ p a r t y ’

p a r t y = f i e l d s . Many2One ( ’ p a r t y . p a r t y ’ , ’ P a r t y ’ , r e a d o n l y = T r u e )
o p p o r t u n i t y _ c o u n t = f i e l d s . I n t e g e r ( ’ O p p o r t u n i t y count ’ , r e a d o n l y =True )

@classmethod
def t a b l e _ q u e r y ( c l s ) :
pool = Pool ( )
o p p o r t u n i t y _ t a b l e = pool . get ( ’ t r a i n i n g . opportunit y ’ ) . __table__ ( )
columns = [
Min ( o p p o r t u n i t y _ t a b l e . i d ) . a s _ ( ’ i d ’ ) ,
Max ( o p p o r t u n i t y _ t a b l e . c r e a t e _ u i d ) . a s _ ( ’ c r e a t e _ u i d ’ ) ,
Max ( o p p o r t u n i t y _ t a b l e . c r e a t e _ d a t e ) . a s _ ( ’ c r e a t e _ d a t e ’ ) ,
Max ( o p p o r t u n i t y _ t a b l e . w r i t e _ u i d ) . a s _ ( ’ w r i t e _ u i d ’ ) ,
Max ( o p p o r t u n i t y _ t a b l e . w r i t e _ d a t e ) . a s _ ( ’ w r i t e _ d a t e ’ ) ,
opportunity_table . party ,
Count ( o p p o r t u n i t y _ t a b l e . i d ) . a s _ ( ’ o p p o r t u n i t y _ c o u n t ’ ) ,
]
group_by = [ o p p o r t u n i t y _ t a b l e . p a r t y ]

r e t u r n o p p o r t u n i t y _ t a b l e . s e l e c t ( ∗ columns , g r o u p _ b y = g r o u p _ b y )

N. Évrard (B2 CK ) Tryton Technical Training September 18, 2015 56 / 56

You might also like