10.3.1 La famille de Workflow

La famille de workflow permet de spécifier :

  • le graphe du cycle ainsi que les attributs spécifiques au cycle,
  • les paramètres de familles qui seront utilisables lors des traitements spécifiques liés aux cycles.

10.3.1.1 Définition de la famille

Au même titre que les autres familles, une famille de workflow est caractérisée par :

  • son code dans un fichier php

  • sa définition dans un fichier csv.

Cette famille doit :

  • Hériter de la famille WDOC,
  • être liée à une classe définissant les états et transitions du cycle.

La propriété USEFOR est SW par défaut, cela indique que la famille est :

  • Système (S),
  • utilisable comme workflow (W).

10.3.1.1.1 Exemple

Famille parente Libellé / / Nom logique
BEGIN WDOC Cycle Demo WFL_DEMO
CLASS Demo\WflDemo
END

10.3.1.2 La classe de workflow

La classe correspondante à un workflow doit définir la structure de ce workflow. Cette structure s'exprime sous la forme d'un graphe, exprimé notamment au moyen des propriétés de classe $cycle et $transitions.

10.3.1.2.1 $cycle

La propriété $cycle définit le graphe à proprement parler. C'est une liste d'éléments de la forme :

array(
    "e1" => "<état de départ>",
    "e2" => "<état d'arrivée>",
    "t"  => "<transition à utiliser>"
)

  • e1 est l'identifiant de l'état de départ,
  • e2 est l'identifiant de l'état d'arrivée,
  • t est l'identifiant de la transition à utiliser pour passer de l'état de départ à l'état d'arrivée.

Exemple :

public $cycle = array(
    array(
        "e1" => "<état de départ 1>",
        "e2" => "<état d'arrivée 1>",
        "t"  => "<transition à utiliser 1>"
    ),,
    array(
        "e1" => "<état de départ N>",
        "e2" => "<état d'arrivée N>",
        "t"  => "<transition à utiliser N>"
    )
);

10.3.1.2.2 $transitions

La propriété $transitions définit l'ensemble des types de transitions utilisables. C'est un tableau associatif dont la clé est le nom de la transition, et la valeur est un élément de la forme :

array(
    "nr"  => true,
    "m0"  => "myFirstCondition",
    "m1"  => "mySecondCondition",
    "m2"  => "myFirstProcess",
    "m3"  => "myLastProcess",
    "ask" => array("askId1",)
)

  • nr est un booléen indiquant qu'il ne faut pas demander de raison au passage de transition (nr pour No Reason).
    La valeur par défaut est à false ; dans ce cas, une popup demande à l'utilisateur de préciser la raison du passage de transition.
  • m0, m1, m2, m3 sont chacune le nom d'une méthode de la classe de workflow.
  • ask est un tableau d'identifiants de paramètres ou d'attributs du workflow, qui seront utilisés pour générer la demande des paramètres de transition.

Exemple :

public $transitions = array(
    "<transition à utiliser 1>" => array(
        "nr" => true,
        "m0" => "myFirstCondition_1",),,
    "<transition à utiliser N>" => array(
        "nr" => true,
        "m0" => "myFirstCondition_N",)
);

10.3.1.2.3 $firstState

La propriété $firstState définit l'état initial des documents liés à ce cycle de vie. Elle désigne l'identifiant d'un état.

10.3.1.2.4 $attrPrefix

Lors de la génération d'un cycle de vie, Dynacase génère un grand nombre d'attributs pour paramétrer finement chaque état et chaque transition. ces attributs sont préfixés par $attrPrefix pour éviter les éventuelles collisions en base de données.

10.3.1.2.5 $stateactivity

La propriété $stateactivity définit l'ensemble des activités. C'est un tableau associatif ; la clé est l'identifiant de l'état et la valeur est le libellé de l'activité.

10.3.1.2.6 Les méthodes de transition

Les méthodes appelées lors des transitions en m0, m1, m2, m3 sont des méthodes de la famille de workflow.

  • Les méthodes appelées en m0 doivent être en visibilité public ;
  • les méthodes appelées en m1, m2, et m3 peuvent être en visibilité protected ou public mais elles ne peuvent pas être private.

10.3.1.2.6.1 Définition méthode m0

La méthode appelée en m0 est de la forme :

m0 ( $nextStep, $currentStep, $confirmationMessage)

où :

  • $nextStep est l'identifiant de la prochaine étape, (étape d'arrivée)
  • $currentStep est l'identifiant de l'étape actuelle, (étape de départ)
  • $confirmationMessage est le message de confirmation (si la méthode est exécuté pour l'affichage des menus, le message est vide)

Si elle retourne une chaîne vide, alors la transition peut être effectuée. dans le cas contraire, elle doit retourner un message localisé qui indiquera à l'utilisateur la raison pour laquelle la transition ne peut pas être effectuée.

Le message retourné par la méthode est présenté dans un "tooltip" lors du survol de l'entrée de l'étape dans le menu Étapes, ou dans un "popover" lors du clic sur l'entrée de l'étape.

Note : Cette méthode est aussi appelée lors de l'affichage de la liste des transitions accessibles. Cela permet notamment de signaler à l'utilisateur les transitions qu'il a le droit d'effectuer, mais pour lesquelles il doit faire des modifications sur le document. De fait, cette méthode ne doit pas modifier le document.

10.3.1.2.6.2 Définition méthode m1

La méthode appelée en m1 est de la forme :

m1 ( $nextStep, $currentStep, $confirmationMessage)

où :

  • $nextStep est l'identifiant de la prochaine étape, (étape d'arrivée)
  • $currentStep est l'identifiant de l'étape actuelle, (étape de départ)
  • $confirmationMessage est le message de confirmation

Si elle retourne une chaîne vide, alors la transition peut être effectuée. dans le cas contraire, elle doit retourner un message localisé qui indiquera à l'utilisateur la raison pour laquelle la transition ne peut pas être effectuée.

10.3.1.2.6.3 Définition méthode m2

La méthode appelée en m2 est de la forme :

m2 ( $currentStep, $previousStep, $confirmationMessage)

où :

  • $currentStep est l'identifiant de l'étape actuelle, (étape d'arrivée)
  • $previousStep est l'identifiant de l'ancienne étape, (étape de départ)
  • $confirmationMessage est le message de confirmation

Si elle retourne une chaîne non vide, cette chaîne est considérée comme un message d'erreur qui sera affiché à l'utilisateur à l'issue de la transition (Cette méthode n'est pas bloquante).

10.3.1.2.6.4 Définition méthode m3

La méthode appelée en m3 est de la forme :

m3 ( $currentStep, $previousStep, $confirmationMessage)

où :

  • $currentStep est l'identifiant de l'étape actuelle, (étape d'arrivée)
  • $previousStep est l'identifiant de l'ancienne étape, (étape de départ)
  • $confirmationMessage est le message de confirmation

Si elle retourne une chaîne non vide, cette chaîne est considérée comme un message d'erreur qui sera affiché à l'utilisateur à l'issue de la transition (Cette méthode n'est pas bloquante).

10.3.1.2.6.5 Utilisation des paramètres de transition ask

Les paramètres de transition sont envoyés lors de la requête de transition effectuée par l'interface web.

Les valeurs présentées sur l'interface sont les valeurs des paramètres ou des attributs référencés au moment de la demande de transition.

Les valeurs des paramètres de transition utilisées sont enregistrés dans l'historique du document.

Si le paramètre référencé est obligatoire, l'interface exigera que le paramètre soit complété. Cette contrainte n'est pas testée lorsqu'il s'agit de passer une transition par programmation. Elle est prise en compte que par l'interface web. De même, les valeurs des paramètres de transition ne sont remplies que lors d'une transition effectuée par l'interface.

Attention : Contrairement aux paramètres de famille ordinaires, les contraintes ne sont pas prises en compte dans les paramètres de transition.

Dans les méthodes m0, m1, m2, m3, la récupération des valeurs des paramètres de transition s'effectuent au moyen de la méthode WDoc::getValue() (bien que ces valeurs soient utilisées dans des paramètres, ce n'est pas la méthode getParameterValue qui est utilisée).

Lors de la recherche des transitions accessibles, La méthode m0 ne peut accèder aux paramètres de transition (ils ne sont pas encore demandés).

10.3.1.2.7 Exemple

Considérons le workflow de l'introduction. La classe le définissant contiendra :

 
namespace Demo;
 
class WflDemo extends \Dcp\Family\WDoc
{
    public $attrPrefix = "DEMO";
    public $firstState = self::etat_created;
    public $viewlist = "none";
 
    //region States
    const etat_created    = "myapp_demo_e1";
    const etat_redacted   = "myapp_demo_e2";
    const etat_verified   = "myapp_demo_e3";
    const etat_diffused   = "myapp_demo_e4";
    const etat_archived   = "myapp_demo_e5";
    const etat_abandonned = "myapp_demo_e6";
    //endregion
 
    //region Transitions
    const transition_created_redacted    = "myapp_demo_t1";
    const transition_redacted_created    = "myapp_demo_t2";
    const transition_redacted_verified   = "myapp_demo_t3";
    const transition_verified_created    = "myapp_demo_t4";
    const transition_verified_diffused   = "myapp_demo_t5";
    const transition_diffused_archived   = "myapp_demo_t6";
    const transition_created_abandonned  = "myapp_demo_t7";
    const transition_redacted_abandonned = "myapp_demo_t8";
    const transition_verified_abandonned = "myapp_demo_t9";
    //endregion
 
    public $stateactivity = array(
        self::etat_created    => "demo:activity:etat_created",
        self::etat_redacted   => "demo:activity:etat_redacted",
        self::etat_verified   => "demo:activity:etat_verified",
        self::etat_diffused   => "demo:activity:etat_diffused",
        self::etat_archived   => "demo:activity:etat_archived",
        self::etat_abandonned => "demo:activity:etat_abandonned"
    );
 
    public $transitions = array(
        self::transition_created_redacted    =>array(
            "m0" => "",
            "m1" => "",
            "m2" => "",
            "m3" => "",
            "ask" => array(\Dcp\Family\AttributeIdentifiers\MyDemo::wdemo_deadline_date),
            "nr" => true
        ),
        self::transition_redacted_created    =>array(
            "m0" => "",
            "m1" => "",
            "m2" => "",
            "m3" => "",
            "nr" => true
        ),
        self::transition_redacted_verified   =>array(
            "m0" => "",
            "m1" => "",
            "m2" => "",
            "m3" => "",
            "nr" => true
        ),
        self::transition_verified_created    =>array(
            "m0" => "",
            "m1" => "",
            "m2" => "",
            "m3" => "",
            "nr" => true
        ),
        self::transition_verified_diffused   =>array(
            "m0" => "",
            "m1" => "",
            "m2" => "",
            "m3" => "",
            "nr" => true
        ),
        self::transition_diffused_archived   =>array(
            "m0" => "",
            "m1" => "",
            "m2" => "",
            "m3" => "",
            "nr" => true
        ),
        self::transition_created_abandonned  =>array(
            "m0" => "",
            "m1" => "",
            "m2" => "",
            "m3" => "",
            "nr" => true
        ),
        self::transition_redacted_abandonned =>array(
            "m0" => "",
            "m1" => "",
            "m2" => "",
            "m3" => "",
            "nr" => true
        ),
        self::transition_verified_abandonned =>array(
            "m0" => "",
            "m1" => "",
            "m2" => "",
            "m3" => "",
            "nr" => true
        )
    );
 
    public $cycle = array(
 
        array(
            "e1" => self::etat_created,
            "e2" => self::etat_redacted,
            "t"  => self::transition_created_redacted
        ),
        array(
            "e1" => self::etat_redacted,
            "e2" => self::etat_created,
            "t"  => self::transition_redacted_created
        ),
        array(
            "e1" => self::etat_redacted,
            "e2" => self::etat_verified,
            "t"  => self::transition_redacted_verified
        ),
        array(
            "e1" => self::etat_verified,
            "e2" => self::etat_created,
            "t"  => self::transition_verified_created
        ),
        array(
            "e1" => self::etat_verified,
            "e2" => self::etat_diffused,
            "t"  => self::transition_verified_diffused
        ),
        array(
            "e1" => self::etat_diffused,
            "e2" => self::etat_archived,
            "t"  => self::transition_diffused_archived
        ),
        array(
            "e1" => self::etat_created,
            "e2" => self::etat_abandonned,
            "t"  => self::transition_created_abandonned
        ),
        array(
            "e1" => self::etat_redacted,
            "e2" => self::etat_abandonned,
            "t"  => self::transition_redacted_abandonned
        ),
        array(
            "e1" => self::etat_verified,
            "e2" => self::etat_abandonned,
            "t"  => self::transition_verified_abandonned
        )
    );
}

Quelques remarques sur ce code :

  • Toutes les activités et tous les états ont été définis au moyen de constantes.

    Cela n'est en aucun cas obligatoire, mais permet d'éviter les erreurs de copier-coller ; en effet, les identifiants des états, ainsi que les noms des transitions sont utilisés à de nombreux endroits.

  • Les noms des états et des transitions ont été anonymisés, et seules les constantes ont des labels intelligibles.

    Puisque les états et transitions vont générer des attributs, ils vont également générer des colonnes en base de données. Ces colonnes sont nommées à partir des identifiants de l'état ou de la transition. Aussi, si demain il est nécessaire de renommer l'état archivé en classé, il faudra soit accepter que le nom affiché et le nom stocké soient différents, soit renommer des colonnes en base de données et mettre à jour des fichiers de paramétrage. Aucun de ces 2 choix n'est pérenne ou dénué de risque.

    Avec des constantes anonymisées, il n'y a rien à changer en base de données, ni dans les fichiers de paramétrage, il suffit de changer la traduction de ce libellé. Accessoirement, on peut renommer la constante en bénéficiant de l'assistance d'outils de refactoring.

10.3.1.3 Internationalisation

Dans un workflow, les éléments qui peuvent être internationalisés sont :

  • le nom des états
  • le nom des activités
  • le nom des transitions

Pour être internationalisés, ces éléments doivent être ajoutés aux catalogues de traduction.

×