Processus événementiel
Interruptif
Passons maintenant à l’exercice 2 : cette fois-ci l’utilisateur doit pouvoir appuyer sur annuler à tout moment et cela doit arrêter le processus.
Un des problèmes de l’exercice précédent est que l’utilisateur doit d’abord renseigner un fournisseur pour pouvoir annuler sa demande.
Pour résoudre l’exercice 2 nous allons introduire une nouvelle notion : les sous processus événementiels.
Pour insérer un sous processus événementiel, faite un glisser déposer de l’icône . Vous avez ainsi introduit un sous-processus. Pour le rendre événementiel, cliquer sur la clé à molette et sélectionner
Event Sub Process
.
Les sous processus événementiel contiennent un processus qui va se déclencher sous condition. Nous matérialisons cette condition par un événement de départ du processus. En fonction de l’événement de départ, le sous-processus événementiel peut être interruptif
(événement en traits plein) :
![event process](../_images/event_process.png)
ou non interruptif
(événement en traits pointillés) :
![event process](../_images/interruptif_event.png)
Ici on veut interrompre le processus principal dès lors que l’utilisateur clique sur Annuler, nous choisissons donc un processus interruptif. Comme point de départ nous utilisons un événement conditionnel (c’est celui sur l’image ci-dessus) en trait plein car l’on souhaite un processus interruptif.
Nous pouvons paramétrer cet événement conditionnel en lui indiquant une condition grâce à l’expressions builder (cliquez sur le crayon) :
![event process](../_images/add_expression.png)
Ici, dès lors que le sous-processus événementiel est déclenché, on termine le processus. Comme le sous processus est interruptif, il n’y a rien d’autre à faire :
![event process](../_images/process_event_bpm.png)
Déployez et testez ce processus. |
Non interruptif
Passons à l’exercice 3 : Nous allons partir sur un scénario sur les contrats (VehicleContract) du menu Parc automobile → Contrat
Le processus devra demander à l’utilisateur de renseigner le contractant puis le type, le coût d’activation, la fréquence de récurrence du coût et le fournisseur…
Pour la première partie de l’exercice, voici le modèle de processus :
![event process](../_images/non_interruptif_event.png)
Je vous laisse créer un nouveau modèle, le configurer et le paramétrer.
À tout moment si l’utilisateur renseigne la Date de facturation
on renseignera automatiquement la Date de début du contrat
un jour après…’
Nous avons une condition qui peut se déclencher à tout moment, nous allons donc à nouveau utiliser un sous-processus événementiel. Cette fois-ci, le processus principal ne doit pas être interrompu : le sous-processus événementiel sera donc non interruptif. Le modèle de processus est le suivant :
![event process](../_images/non_interruptif_event_bpm.png)
Nous allons maintenant paramétrer l’événement conditionnel et la tâche script. Vous devriez être capable de paramétrer l’événement conditionnel tout seul. Voici la correction :
![event process](../_images/add_expression_non_interruptif_event.png)
Pour la tâche script, nous allons utiliser la méthode plusDays(n)
qui permet d’ajouter n jour à une date :
![event process](../_images/script_non_interruptif_event.png)
Cette fois-ci nous utilisons la valeur Expression
pour Value from
afin d’indiquer que l’on renseigne une expression à évaluer.
Testons le processus et intéressons nous à son instance :
![event process](../_images/bpm_execution_event.png)
Normalement la mise à jour de la date à fonctionner mais il y a 8 jetons dans le sous processus… (il est possible que vous ayez un nombre différent du mien mais supérieur à 1).
Essayez de mettre à jour un champ quelconque sur le contrat et de sauvegarder : le nombre de jetons augmente encore.
Ce qui se passe, c’est qu’à chaque fois que l’on fait une mise à jour,
la condition est testée et comme elle est toujours vraie (la date de facturation est bien remplie)
, on repasse dans le sous processus événementiel. Ce n’est pas forcément gênant car le comportement attendu est le bon mais ce n’est pas très élégant. Il faudrait non pas vérifier si la date est nulle ou non mais tester s’il y a eu un changement. Dans la suite de l’exercice nous allons mettre cette solution en place, c’est un peu technique.
L’idée est la suivante :
![event process](../_images/bpm_non_interruptif_event.png)
On utilise un champ de test que l’on initialise avec la valeur de la date de facturation au début du processus principal.
Dès que l’on détecte une différence entre le champ de test et la date de facturation,
on entre dans le sous processus événementiel. La première tâche de ce sous processus consiste à mettre à jour le champ de test avec la valeur réelle.
Pour mettre en place cela, nous allons nous servir du champ attrs
de l’objet contrat. Le champ attrs
est un champ json présent sur tous les objets qui sert à stocker les valeurs du studio.
Sur la tâche script Initialiser champ de test
, vous pouvez renseigner le script suivant :
![event process](../_images/script_task_non_interruptif_event.png)
Le script :
def rec = __ctx__.find('VehicleContract',vehicleContractId) def slurped = rec?.attrs ? new groovy.json.JsonSlurper().parseText(rec.attrs) : [:] def builder = new groovy.json.JsonBuilder(slurped) def map = [invoiceDate : vehicleContract?.invoiceDate] builder.content = builder.content ?: [] << map rec.attrs = builder.toString() return __ctx__.save(rec)
Quelques explications :
__ctx__.find('VehicleContract',vehicleContractId)
permet de récupérer l’objet contrat sur lequel notre processus s’exécute.
Le code suivant :
‘def slurped = rec?.attrs ? new groovy.json.JsonSlurper().parseText(rec.attrs) : [:] def builder = new groovy.json.JsonBuilder(slurped)’
nous donne accès à l’objet builder qui permet de parser le champ attrs.
def map = [invoiceDate : vehicleContract?.invoiceDate]
Cela défini un dictionnaire dont la clé est invoiceDate et la valeur contient celle de la date de facturation actuelle. Nous stockons ensuite ce dictionnaire dans l’objet json attrs en le castant en string. Enfin, on renvoie et on sauvegarde l’objet contrat.
Sur l’événement conditionnel nous pouvons indiquer le script suivant :
def rec = __ctx__.find('VehicleContract',vehicleContractId) if (rec?.attrs==null){ false } else { def slurped = new groovy.json.JsonSlurper().parseText(rec?.attrs) def builder = new groovy.json.JsonBuilder(slurped) builder.content.invoiceDate[0]!=rec.invoiceDate }
Et sur la tâche script Mettre à jour champ de test
:
def rec = __ctx__.find('VehicleContract',vehicleContractId) def slurped = new groovy.json.JsonSlurper().parseText(rec.attrs) def builder = new groovy.json.JsonBuilder(slurped) def map = [invoiceDate : vehicleContract?.invoiceDate] builder.content = [] << map rec.attrs = builder.toString() return __ctx__.save(rec)
Vous pouvez tester le processus. Il se peut que l’on passe 2 fois dans le sous-processus événementiel lors du renseignement de la date mais, nous ne passons plus dans le sous processus lorsque l’on met à jour un autre champ du contrat . |