doc/book/fr/06-define-workflows.fr.txt
branchstable
changeset 3322 a522f86ab617
parent 1398 5fe84a5f7035
equal deleted inserted replaced
3291:24489cbbd697 3322:a522f86ab617
     1 .. -*- coding: utf-8 -*-
     1 .. -*- coding: utf-8 -*-
     2 
     2 
     3 Définition de workflow
     3 Définition de workflow
     4 ======================
     4 ======================
     5 On peut mettre une condition rql ou/et un groupe auquel doit appartenir l'utilisateur.
       
     6 
     5 
     7 Si on met à la fois un(ou plusieurs) groupe et une condition RQL, il faut que les deux soient respectés.
     6 Avant-propos
       
     7 ------------
     8 
     8 
     9 Si on met plusieurs groupes, il faut que l'utilisateur soit dans un des groupes.
     9 Un worflow décrit comment les entités vont être utilisés à travers différents états. Nous avons donc pour un workflow donné un ensemble d'états, un "graphe de transition" c'est-à-dire la liste des transitions possibles d'un état à un autre.
       
    10 
       
    11 Nous allons définir ici un simple workflow pour l'exemple du blog avec seulement deux états: `en attente` et `publié`. Il est nécessaire d'avoir préalablement créé une application simple *CubicWeb* en dix minutes (voir :ref:`BlogFiveMinutes`).
       
    12 
       
    13 Mise en place du workflow
       
    14 -------------------------
       
    15 
       
    16 Nous allons créer un workflow pour contrôler la qualité des BlogEntry soumis à l'instance. Lorsque un BlogEntry est créé par un utilisateur, son état doit être `en attente`. Pour être visible par tous, il doit être ensuite mis à l'état `publié`. Pour le changement d'état d'`en attente` à `publié`, nous avons besoin d'une transition que nous appellerons `approuve_blogentry`.
       
    17 
       
    18 Un état BlogEntry ne doit pas pouvoir être modifiable par les utilisateurs. Nous allons donc créé un groupe de modération `moderateurs` et ce groupe aura les permissions idoines pour publier un BlogEntry.
       
    19 
       
    20 Il existe deux manières de créer un workflow: depuis l'interface utilisateur ou en le définissant dans le fichier ``migration/postcreate.py``.
       
    21 Ce script est exécuté à chaque lancement de la commande ``cubicweb-ctl db-init``.
       
    22 Nous encourageons vivement la création dans ``migration/postcreate.py`` que nous allons vous montrer ici. Lire `Sous le capot`_ pour en comprendre les raisons.
       
    23 
       
    24 L'état d'une entité est sauvegardé par l'attribut `in_state` qui peut être ajouté à votre schéma d'entité par deux façons:
       
    25 
       
    26 * héritage direct en utilisant la classe `cubicweb.schema.WorkflowableEntityType`
       
    27 * par délégation en utilisant `cubicweb.schema.make_worflowable` (utilisable comme un décorateur également)
       
    28 
       
    29 Pour notre exemple de BlogEntry, nous devons avoir:
       
    30 
       
    31 .. sourcecode:: python
       
    32 
       
    33   from cubicweb.schema import WorkflowableEntityType
       
    34 
       
    35   class BlogEntry(EntityType, WorkflowableEntityType):
       
    36       ...
       
    37 
       
    38 
       
    39 Création des états, transitions et les permissions de groupe
       
    40 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
       
    41 
       
    42 Le script ``postcreate.py`` est exécuté dans un environnement spécial où plusieurs primitives *CubicWeb* peuvent être utilsées.
       
    43 Elles sont toutes définies dans ``class ServerMigrationHelper``.
       
    44 Nous allons maintenant voir dans le prochain example celles utilisées pour créer un workflow.
       
    45 
       
    46 Pour définir notre workflow pour BlogDemo, veuillez ajouter les lignes suivantes au script ``migration/postcreate.py``:
       
    47 
       
    48 .. sourcecode:: python
       
    49 
       
    50   _ = unicode
       
    51 
       
    52   moderators = add_entity('CWGroup', name=u"modérateurs")
       
    53 
       
    54 Cela va ajouter le groupe utilisateur `moderators`.
       
    55 
       
    56 .. sourcecode:: python
       
    57 
       
    58   wf = add_workflow(u'une description succincte de votre workflow', 'BlogEntry')
       
    59 
       
    60 Ceci va premièrement instancier un nouvel objet workflow avec une description sommaire mais pertinente et le type d'entité concerné (un tuple pour être utilisé pour des valeurs multiples).
       
    61 
       
    62 .. sourcecode:: python
       
    63 
       
    64   submitted = wf.add_state(_('submitted'), initial=True)
       
    65   published = wf.add_state(_('published'))
       
    66 
       
    67 ``add_state`` attend comme premier argument le nom de l'état que vous voulez créer et un argument optionnel pour signifier si c'est l'état initial supposé pour ce type d'entité.
       
    68 
       
    69 .. sourcecode:: python
       
    70 
       
    71   wf.add_transition(_('approuve_blogentry'), (submitted,), published, ('moderators', 'managers'),)
       
    72 
       
    73 ``add_transition`` attend:
       
    74 
       
    75   * comme premier argument le nom de la transition
       
    76   * ensuite la liste des états pour lesquels les transitions peuvent être tirées,
       
    77   * l'état attendu en fin de transition,
       
    78   * et les permissions
       
    79     (c'est-à-dire la liste des goupes utilisateurs qui peuvnet appliquer la transition; l'utilisateur devant appartenir à l'un des groupes listés pour être autoriser à exécuter l'action).
       
    80 
       
    81 .. sourcecode:: python
       
    82 
       
    83 
       
    84   checkpoint()
       
    85 
       
    86 .. note::
       
    87   Dans le script de création d'un workflow, penser à mettre `_()` autour des noms d'états et de transitions pour que ceux si soient pris en compte par les scripts de gestion des catalogues i18n.
       
    88 
       
    89 En complément de condition sur des groupes utilisateur dont l'utilisateur doit appartenir à l'in d'entre eux, vous pouvez utiliser une RQL condition.
       
    90 Dans ce cas, l'utilisateur peut seulement exécuter une action si les deux conditions sont satisfaites.
    10 
    91 
    11 Pour la condition RQL sur une transition, on peut y mettre les substitutions suivantes :
    92 Pour la condition RQL sur une transition, on peut y mettre les substitutions suivantes :
    12 
    93 
    13 * `%(eid)s`, eid de l'objet
    94 * `%(eid)s`, eid de l'objet
    14 * `%(ueid)s`, eid de l'utilisateur qui fait la requête
    95 * `%(ueid)s`, eid de l'utilisateur qui fait la requête
    15 * `%(seid)s`, eid de l'état courant de l'objet
    96 * `%(seid)s`, eid de l'état courant de l'objet
    16 
    97 
    17 Dans le script de création d'un workflow, penser à mettre `_()` autour des noms d'états et de transitions
    98 .. image:: ../../images/03-transitions-view.en.png
    18 pour que ceux si soient pris en compte par les scripts de gestion des catalogues i18n.
       
    19 
    99 
    20 General
   100 Vous pouvez remarqué que dans la boîte d'action d'un BlogEntry, l'état est maintenant listé ainsi que les possibles transitions définis pour l'état en cours dans le workflow. Les transitions ne sont seulement affichées pour les utilisateurs ayant les bonnes permissions.
    21 -------
   101 Dans notre exemple, la transition `approuve_blogentry` sera seulement affichée pour les utilisateurs appartenant au groupe `moderators` or `managers`.
    22 
       
    23 A workflow can be defined in a `LAX` application thanks to the system 
       
    24 entities ``State`` and ``Transition``. Those are defined within all 
       
    25 LAX application and can be set-up through the main administrator interface.
       
    26 
       
    27 Once your schema is defined, you can start creating the set of states and
       
    28 the required transitions for your applications entities.
       
    29 
       
    30 You first need to define the states and then the transitions between those
       
    31 to complete your workflow.
       
    32 
       
    33 A ``State`` defines the status of an entity. While creating a new state, 
       
    34 you will be first given the option to select the entity type the state
       
    35 can be applied to. By choosing ``Apply``, a new section will be displayed
       
    36 in the editing screen to enable you to add relation to the state you are
       
    37 creating.
       
    38 
       
    39 A ``Transition`` is also based on an entity type it can be applied to.
       
    40 By choosing ``Apply``, a new section will be displayed in the editing 
       
    41 screen to enable you to add relation to the transition you are
       
    42 creating.
       
    43 
       
    44 At the transition level you will also define the group of user which can
       
    45 aplly this transition to an object.
       
    46 
   102 
    47 
   103 
    48 Example of a simple workflow
   104 Sous le capot
    49 ----------------------------
   105 ~~~~~~~~~~~~~
    50 
   106 
    51 Please see the tutorial to view and example of a simple workflow.
   107 Un workflow est une collection d'entités de type `State`` et ``Transition`` qui sont des types d'entités standards de *CubicWeb*.
       
   108 
       
   109 Par exemple, les lignes précédentes:
       
   110 
       
   111 .. sourcecode:: python
       
   112 
       
   113   submitted = wf.add_state(_('en attente'), initial=True)
       
   114   published = wf.add_state(_('publié'))
       
   115 
       
   116 vont créé deux entités de type ``State``, l'une avec le nom 'submitted' et l'autre avec le nom 'published'. Tandis que:
       
   117 
       
   118 .. sourcecode:: python
       
   119 
       
   120   wf.add_transition(_('approuve_blogentry'), (submitted,), published, ('moderators', 'managers'),)
       
   121 
       
   122 va créé une entité de type ``Transition`` avec le nom `approuve_blogentry` qui sera relié aux entités ``State`` créées précédemment.
       
   123 
       
   124 Dès lors, nous pouvons utiliser l'interface d'administration pour ces opérations. Mais ce n'est pas recommandé à cause de la complexité superflue et du fait que ces changements ne seront locaux qu'à cette instance.
       
   125 
       
   126 En effet, si vous créez les états et les transitions à travers l'interface utilisateur, la prochaine initialisation de la base de données vous oblige à recréer toutes les entités.
       
   127 L'interface utilisateur devrait être seulement connu par vous pour la visualisation des états et transitions, mais ce n'est pas celle appropriée pour définir vos workflows applicatifs.
    52 
   128 
    53 
   129 
    54 [Create a simple workflow for BlogDemo, to have a moderator approve new blog 
       
    55 entry to be published. This implies, specify a dedicated group of blog
       
    56 moderator as well as hide the view of a blog entry to the user until
       
    57 it reaches the state published]
       
    58 
       
    59 Set-up a workflow
       
    60 -----------------
       
    61 
       
    62 Before starting, make sure you refresh your mind by reading [link to
       
    63 definition_workflow chapter].
       
    64 
       
    65 We want to create a workflow to control the quality of the BlogEntry 
       
    66 submitted on your application. When a BlogEntry is created by a user
       
    67 its state should be `submitted`. To be visible to all, it needs to
       
    68 be in the state `published`. To move from `submitted` to `published`
       
    69 we need a transition that we can name `approve_blogentry`.
       
    70 
       
    71 We do not want every user to be allowed to change the state of a 
       
    72 BlogEntry. We need to define a group of user, `moderators`, and 
       
    73 this group will have appropriate permissions to approve BlogEntry
       
    74 to be published and visible to all.
       
    75 
       
    76 There are two ways to create a workflow, form the user interface,
       
    77 and also by defining it in ``migration/postcreate.py``. This script
       
    78 is executed each time a new ``./bin/laxctl db-init`` is done. 
       
    79 If you create the states and transitions through the user interface
       
    80 this means that next time you will need to initialize the database
       
    81 you will have to re-create all the entities. 
       
    82 We strongly recommand you create the workflow in ``migration\postcreate.py``
       
    83 and we will now show you how.
       
    84 The user interface would only be a reference for you to view the states 
       
    85 and transitions but is not the appropriate interface to define your
       
    86 application workflow.
       
    87 
       
    88 Update the schema
       
    89 ~~~~~~~~~~~~~~~~~
       
    90 To enable a BlogEntry to have a State, we have to define a relation
       
    91 ``in_state`` in the schema of BlogEntry. Please do as follows, add
       
    92 the line ``in_state (...)``::
       
    93 
       
    94   class BlogEntry(EntityType):
       
    95       title = String(maxsize=100, required=True)
       
    96       publish_date = Date(default='TODAY')
       
    97       text_format = String(meta=True, internationalizable=True, maxsize=50,
       
    98                            default='text/rest', constraints=[format_constraint])
       
    99       text = String(fulltextindexed=True)
       
   100       category = String(vocabulary=('important','business'))
       
   101       entry_of = SubjectRelation('Blog', cardinality='?*')
       
   102       in_state = SubjectRelation('State', cardinality='1*')
       
   103 
       
   104 As you updated the schema, you will have re-execute ``./bin/laxctl db-init``
       
   105 to initialize the database and migrate your existing entities.
       
   106 [WRITE ABOUT MIGRATION]
       
   107 
       
   108 Create states, transitions and group permissions
       
   109 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
       
   110 
       
   111 At the time the ``postcreate.py`` script is executed, several methods
       
   112 can be used. They are all defined in the ``class ServerMigrationHelper``.
       
   113 We will only discuss the method we use to create a wrokflow here.
       
   114 
       
   115 To define our workflow for BlogDemo, please add the following lines
       
   116 to ``migration/postcreate.py``::
       
   117   
       
   118   _ = unicode
       
   119 
       
   120   moderators      = add_entity('CWGroup', name=u"moderators")
       
   121 
       
   122   submitted = add_state(_('submitted'), 'BlogEntry', initial=True)
       
   123   published = add_state(_('published'), 'BlogEntry')
       
   124 
       
   125   add_transition(_('approve_blogentry'), 'BlogEntry', (submitted,), published, ('moderators', 'managers'),)
       
   126 
       
   127   checkpoint()
       
   128 
       
   129 ``add_entity`` is used here to define the new group of users that we
       
   130 need to define the transitions, `moderators`.
       
   131 If this group required by the transition is not defined before the
       
   132 transition is created, it will not create the relation `transition 
       
   133 require the group moderator`.
       
   134 
       
   135 ``add_state`` expects as the first argument the name of the state you are
       
   136 willing to create, then the entity type on which the state can be applied, 
       
   137 and an optionnal argument to set if the state is the initial state
       
   138 of the entity type or not.
       
   139 
       
   140 ``add_transition`` expects as the first argument the name of the 
       
   141 transition, then the entity type on which we can apply the transition,
       
   142 then the list of possible initial states from which the transition
       
   143 can be applied, the target state of the transition, and the permissions
       
   144 (e.g. list of the groups of users who can apply the transition).
       
   145 
       
   146 .. image:: images/lax-book.03-transitions-view.fr.png
       
   147 
       
   148 You can now notice that in the actions box of a BlogEntry, the state
       
   149 is now listed as well as the possible transitions from this state
       
   150 defined by the workflow. This transition, as defined in the workflow,
       
   151 will only being displayed for the users belonging to the group
       
   152 moderators of managers.
       
   153 
       
   154