Tryton - Overview

europython_logo.png

Agenda

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
   try:
       Import the right environment
   except ImportError:
       raise Exception("Tryton is not for you!")
   try:
       Introduction to framework
       Instant hacking
       if time:
           Bonus features
   except (NoTime, NotInterested, UrMadAtMe):
       raise Exception("Lets stop here")
   finally:
       Questions

What is Tryton?

General architecture

arch.png

Tryton Client - Presentation layer

Tryton Server - Logic layer (1/3)

Tryton Server - Logic layer (2/3)

Tryton Server - Logic layer (3/3)

Persistence and transactional layer

Best open source RDBMS: PostgreSQL

Also Supports:

Next Release Goal:

Instant Hacking:

Fundamentals

Fundamentals - Module Structure (0A/8)

training/ (Folder Name)

__init__.py

__tryton__.py

opportunity.py (Models and Logic)

opportunity.xml (Views, Security etc Presentation)

fr_FR.csv (Translations)

setup.py (Python setup tools file)

docs/ (In module documentation)

tests/ (Unit Tests)

Fundamentals - __tryton__.py (0B/8)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
   {
       'name' : '<Name of Module>',
       'version' : '<Version>',
       'author' : '<Author>',
       'email': '<Valid email of Author>',
       'website': '<Author Website>',
       'description': '<Very descriptive description of module>',
       'depends' : [
           <str Name of Dependent Module>,
       ],
       'xml' : [
       ],
       'translation': [
       ],
   }

Fundamentals - Add New Models (1/8)

1
2
3
4
5
6
7
8
9
   from trytond.model import ModelSQL


   class Opportunity(ModelSQL):
       'Opportunity'
       _description = __doc__
       _name = 'training.opportunity'

   Opportunity()

Fundamentals - Fields API (2/8)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
   class Opportunity(ModelSQL):
       'Opportunity'
       _description = __doc__
       _name = 'training.opportunity'
       _rec_name = 'description'

       description = fields.Char('Description', required=True)
       start_date = fields.Date('Start Date', required=True)
       end_date = fields.Date('End Date')
       party = fields.Many2One('party.party', 'Party', required=True)
       comment = fields.Text('Comment')

   Opportunity()

Fundamentals - Presentation (3A/8)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
   <record model="ir.ui.view" id="opportunity_view_tree">
       <field name="model">training.opportunity</field>
       <field name="type">tree</field>
       <field name="arch" type="xml">
           <![CDATA[
           <tree string="Opportunities">
               <field name="party" select="1"/>
               <field name="description" select="1"/>
               <field name="start_date" select="1"/>
               <field name="end_date" select="2"/>
           </tree>
           ]]>
       </field>
   </record>

Fundamentals - Views and Actions (3B/8)

Views
  • Form, Tree, Graph
An action defines what the client (UI) must do
  • A window action (act_window) opens a new tab in the client and shows the first view which is related to it
  • A report fetches a report
  • A wizard opens a wizard etc.

contd....

Fundamentals - Views and Actions (Contd..) (3C/8)

Action Keyword

  • tree_open: after double click in a tree view
  • tree_action: when pressing action button in a tree view
  • form_print: click on print button

Fundamentals - Back to models (4/8)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
   def default_start_date(self, cursor, user, context=None):
       """
       Applies default value to a field
       syntax: def default_<field name>(...
       :param cursor: Database Cursor
       :param user: ID of current user
       :param context: Context from Tryton
       """
       date_obj = self.pool.get('ir.date')
       return date_obj.today(cursor, user, context=context)

Fundamentals - Workflows (5/8)

workflow.jpg
  • Design in XML
  • Inherit and modify by other modules
  • Applies to databases where installed
  • Changes specific to installation

Source : Flickr By : Philip Klinger

Fundamentals - States & Field properties (6A/8)

  • Dynamic property change to fields
  • Editable? Required? Visible? based on on screen vars or backend vars
  • Use of PYSON PYthon Statement and Object Notation
>>> from trytond.pyson import Equal
>>> Equal(1,2)
<trytond.pyson.Equal object at 0x7f7a4e178bd0>
>>> Equal(1,2).pyson()
{'s2': 2, 's1': 1, '__class__': 'Equal'}

Fundamentals - More about PYSON (6B/8)

1
2
3
Eval('active_id', -1)
#Python Equivalent
'active_id' in locals() and active_id or -1
1
2
3
4
If(In('company', Eval('context', {})), '=', '!=')
#Python Equivalent
'context' in locals() and isinstance(context, dict) \
       and 'company' in context and '=' or '!='
1
2
3
states={
       'readonly': Not(Equal(Eval('state'), 'opportunity')),
       }

Fundamentals - Extending existing objects (7A/8)

1
2
3
4
5
6
7
   class Party(ModelSQL, ModelView):
       _name = 'party.party'

       opportunities = fields.One2Many('training.opportunity', 'party',
               'Opportunities')

   Party()

Fundamentals - Extending existing views (7B/8)

Inheritance in views
  • Any levels of inheritance
1
2
3
4
  <xpath expr="/path/to/target[@id='id of target']"
                       position="after">
        ......
  </xpath>

Fundamentals - Wizards (8/8)

Wizards are magical people who defend themselves with magical things.

In the muddle world:
  • These are simple python classes with a view & Logic
  • Does not directly represent a data model (object)
  • Used for interactive prompts, feedbacks etc.

Real world example:

  • Do you have time to continue this presentation ?

Bonus Features

  • You are lucky to be here ;-)
  • Calendar & Caldav
  • Open Office Reports (Relatorio)
  • Email infrastructure
  • Web framework

The community

  • IRC:#tryton on irc.freenode.net
  • Google groups: tryton-dev and tryton (Mailing lists)
How to contribute:

Thanks for your attention

Any questions?

  • BTW, I am @sharoonthomas
  • and I work for @openlabsindia