IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)

OpenERP et les workflows

Publié le 16 juillet 2012

Par ZyonghSite personnel

 

OpenERP a un système de workflows assez complexe à comprendre pour un néophyte. Néanmoins, une fois que l'on a cerné son fonctionnement, on peut se rendre compte à quel point ce concept est puissant. Bienvenu dans le monde des engrenages ;-)

       Version PDF   Version hors-ligne   Version eBooks
Viadeo Twitter Facebook Share on Google+        



I. Introduction
II. Créer l'objet
III. Créer les vues
IV. Créer le workflow
V. Comment tout cela fonctionne ?


I. Introduction

Un workflow (flux de travail) consiste en un changement d'état d'un objet, que ce soit une facture, un bon de commande, etc. Exemple : une facture d'achat passe d'abord par un bon d'achat confirmé par le founisseur qui, lui-même est précédée d'une demande de prix au fournisseur. Prérequis: je pars du principe que vous savez déjà coder des modules avec les champs de base (char, selection) et les vues (tree, form)


II. Créer l'objet

Créons un module tout simple de flotte de véhicule de tourisme de fonction (des voitures quoi^^). Nous avons un objet fleet_vehicle qui contient un champ name et un champ matricule (l'immatriculation du véhicule). Ajoutons à cet objet un champ state
L'objet fleet.vehicle

# -*- coding: utf-8 -*-
from osv import fields, osv

VEHICLE_STATES = [
    ('draft', 'Draft'),
    ('in_progress', 'In progress'),
    ('done', 'Done'),
]

class fleet_vehicle(osv.osv):
    _name = 'fleet.vehicle'
    
    _columns = {
        'name': fields.char("Name", size=128, required=True),
        'matricule': fields.char("Matricule", size=32, required=True),
        'state': fields.selection(VEHICLE_STATES, "State", readonly=True),
    }
    
    _defaults = {
        'state': 'draft',
    }
    
    # methods of workflows's activities
    def wkf_act_fleet_vehicle_draft(self, cr, uid, ids):
        self.write(cr, uid, ids, { 'state': 'draft' })
        return True
    
    def wkf_act_fleet_vehicle_active(self, cr, uid, ids):
        self.write(cr, uid, ids, { 'state': 'in_progress' })
        return True
    
    def wkf_act_fleet_vehicle_terminate(self, cr, uid, ids):
        self.write(cr, uid, ids, { 'state': 'done' })
        return True
fleet_vehicle()

III. Créer les vues

Pour l'exemple, je n'ai coller dans cet article que la vue formulaire. Notez bien le nom des deux boutons : "fleet_vehicle_active" et "fleet_vehicle_terminate"

<record model="ir.ui.view" id="view_fleet_vehicle_form">
    <field name="name">view.fleet.vehicle.form</field>
    <field name="model">fleet.vehicle</field>
    <field name="type">form</field>
    <field name="arch" type="xml">
        <form string="Vehicles">
            <field name="name"/>
            <field name="matricule"/>
            <group colspan="4" col="6">
                <field name="state"/>
                <button name="fleet_vehicle_active" string="Active vehicle" states="draft" icon="gtk-go-forward"/>
                <button name="fleet_vehicle_terminate" string="Terminate vehicle" states="in_progress" icon="gtk-jump-to"/>
            </group>
        </form>
    </field>
</record>

IV. Créer le workflow

Créons maintenant un fichier fleet_vehicle_workflow.xml dans lequel nous allons implémenter le workflow.
Le workflow

<?xml version="1.0" encoding="utf-8" ?>
<openerp>
    <data>
        <record model="workflow" id="wkf_fleet_vehicle">
            <field name="name">wkf.fleet.vehicle</field>
            <field name="osv">fleet.vehicle</field>
            <field name="on_create">True</field>
        </record>
        
        <!-- activities -->
        <record model="workflow.activity" id="wkf_act_fleet_vehicle_draft">
            <field name="wkf_id" ref="wkf_fleet_vehicle" />
            <field name="flow_start">True</field>
            <field name="name">draft</field>
            <field name="kind">function</field>
            <field name="action">wkf_act_fleet_vehicle_draft()</field>
        </record>

        <record model="workflow.activity" id="wkf_act_fleet_vehicle_active">
            <field name="wkf_id" ref="wkf_fleet_vehicle" />
            <field name="name">in_progress</field>
            <field name="kind">function</field>
            <field name="action">wkf_act_fleet_vehicle_active()</field>
        </record>

        <record model="workflow.activity" id="wkf_act_fleet_vehicle_terminate">
            <field name="wkf_id" ref="wkf_fleet_vehicle" />
            <field name="name">done</field>
            <field name="kind">function</field>
            <field name="action">wkf_act_fleet_vehicle_terminate()</field>
            <field name="flow_stop">True</field>
        </record>
        
        <!-- transitions -->
        <record model="workflow.transition" id="wkf_trans_fleet_vehicle_active">
            <field name="act_from" ref="wkf_act_fleet_vehicle_draft" />
            <field name="act_to" ref="wkf_act_fleet_vehicle_active" />
            <field name="signal">fleet_vehicle_active</field>
        </record>
        
        <record model="workflow.transition" id="wkf_trans_fleet_vehicle_terminate">
            <field name="act_from" ref="wkf_act_fleet_vehicle_active" />
            <field name="act_to" ref="wkf_act_fleet_vehicle_terminate" />
            <field name="signal">fleet_vehicle_terminate</field>
        </record>
        
    </data>
</openerp>
Le workflow contient trois paramètres: - name : le nom du workflow - osv : le nom de l'objet - on_create : instancie à la création

L'activité du workflow possède les paramètre suivants : - wkf_id : le workflow - flow_start : True signifie que l'activité démarre le workflow - flow_stop : True signifie que l'activité termine le worklow - kind : le type d'activité - dummy : ne fait rien - function : la méthode de l'objet qui sera exécutée à l'appel de l'activité - subflow : exécute un sous-worfklow


V. Comment tout cela fonctionne ?

Voici les explications du fonctionnement. Vous êtes prêt ? C'est partit! Comme je vous disais plus haut, avez vous retenu le nom des boutons ? Prenons le premier dans le name est fleet_vehicle_active. Cela va "activer" la transition dont la balise signal a pour valeur le nom du bouton.

<field name="signal">fleet_vehicle_active</field>
Cette transition contient deux autres balises :

<field name="act_from" ref="wkf_act_fleet_vehicle_draft" />
<field name="act_to" ref="wkf_act_fleet_vehicle_active" />
act_from est l'activité (worfklow.activity) source;

<record model="workflow.activity" id="wkf_act_fleet_vehicle_draft">
    <field name="wkf_id" ref="wkf_fleet_vehicle" />
    <field name="flow_start">True</field>
    <field name="name">draft</field>
    <field name="kind">function</field>
    <field name="action">wkf_act_fleet_vehicle_draft()</field>
</record>
act_to est l'activité (workflow.activity) destination

<record model="workflow.activity" id="wkf_act_fleet_vehicle_active">
    <field name="wkf_id" ref="wkf_fleet_vehicle" />
    <field name="name">in_progress</field>
    <field name="kind">function</field>
    <field name="action">wkf_act_fleet_vehicle_active()</field>
</record>


               Version PDF   Version hors-ligne   Version eBooks

Valid XHTML 1.0 TransitionalValid CSS!

Les sources présentées sur cette page sont libres de droits et vous pouvez les utiliser à votre convenance. Par contre, la page de présentation constitue une œuvre intellectuelle protégée par les droits d'auteur. Copyright © 2012 David DRAPEAU. Aucune reproduction, même partielle, ne peut être faite de ce site ni de l'ensemble de son contenu : textes, documents, images, etc. sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu'à trois ans de prison et jusqu'à 300 000 € de dommages et intérêts.