Les variables
Les variables sont les éléments qui vont composer une collection.
Chaque variable peut être d'un type spécifique et porte une définition qui regroupe les règles de valorisation de la variable, mais aussi des contrôles sur ladite valeur.
Type
Plusieurs types de variables sont supportés :
Nombre
pour représenter un nombre entier comme décimalChaîne
pour représenter les chaînes de caractèresDate
pour représenter les dates (format ISO8601)Boolean
pour représenter une valeur booléenneComposite
il s'agit d'une structure de données, c'est-à-dire une variable qui n'a pas de valeur directe, mais contient des variables enfantsRecord
équivalent àComposite
ou les sous variables sont résolues à partir d'un service externe (RuleShake Referential)
Référence
Chaque variable est définie de façon unique par sa référence. La référence est composé par la référence du parent et le code de la variable séparés par un slash. Le code de la variable doit être unique parmi les sous-variables du parent.
PARENT_1/PARENT_2/CODE_VARIABLE
Au runtime, cette référence peut changer selon que la variable ou l'un de ses parents est multiple. Dans ce cas, un
index est ajouté au code de la variable multiple. La première occurrence d'une variable multiple porte l'index 0
.
PARENT_1[0]/PARENT_2/CODE_VARIABLE[1]
Dans cet exemple, la référence représente la 2ᵉ occurrence de CODE_VARIABLE
présente sous la variable PARENT_2
non multiple présente sous la première occurrence de PARENT_1
.
Valeur
Le type de la valeur assignée à la variable dépend du type de cette dernière. Ainsi :
- Une valeur de type
java.lang.String
est assignée à une variable de typeChaîne
- Une valeur d'un type qui implémente
java.lang.Number
est assignée ) une variable de typeNombre
. C'est essentiellement le typejava.math.BigDecimal
qui est utilisé. - Une valeur de type
java.lang.Boolean
est assignée à une variable de typeBooléen
- Une valeur de type
java.time.LocalDate
est assignée à une variable de typeDate
. - Dans le cas d'une variable de type
Composite
ouRecord
, la valeur de la variable est une liste contenant les valeurs des sous-variables.
Cette valeur peut être statique ou bien calculée à partir d'une formule de calcul.
Utilisation d'une formule de calcul
Une formule de calcul est une expression en langage MVEL ou chaque variable est accessible par son code.
QUANTITE.value + 10
est une expression dont le résultat est la valeur de la variable QUANTITE
à laquelle on va ajouter le chiffre 10
.
Dans le cas d'une variable composite, si on souhaite accéder à une sous variable, il faudra d'abord saisir le code de la
variable composite puis un point .
puis le code de la sous variable.
ARTICLE.QUANTITE.value * 10
ici, ARTICLE
est une variable composite qui contient la variable QUANTITE
.
Pour en savoir plus sur l'écriture des règles MVEL et les fonctions utilisables, veuillez vous référer aux pages suivantes :
Ordre
L'ordre de la définition d'une variable est important lors de la construction de la collection. En effet, dans une formule de calcul, il n'est possible d'utiliser que des variables définies précédemment. Cette limitation a pour but d'assurer une meilleure performance et une continuité dans le calcul.
Multiplicité
Une variable peut être unique, c'est-à-dire que lors de l'exécution, la variable ne peut avoir qu'une seule valeur. Elle peut également être multiple, autrement dit une liste ou un tableau de valeurs pour la variable.
Dans le cas où la variable est multiple, un index est ajouté à sa référence pour indiquer sa position dans le tableau de
valeurs.
L'index 0
représente le premier élément du tableau de valeurs.
Si une variable est multiple, il n'est pas possible de saisir dans une formule uniquement son code pour accéder à sa valeur. En effet, dans ce cas-là, l'objet représenté par le code de la variable est le tableau contenant les occurrences de cette variable. Il faut obligatoire indiquer l'index de l'occurrence souhaitée.
ARTICLE[0].QUANTITE.value * 10
ici, on accède à la première occurrence de la variable ARTICLE
puis à sa sous variable QUANTITE
.
On peut cependant utiliser le code de la variable si on souhaite interagir avec le tableau.
- Vérifier que le tableau (qui est en fait une liste dans java) est vide :
if (ARTICLE.isEmpty()) {
...
}
- Boucler sur les occurrences de la variable :
for (i : ARTICLE) {
...
}
Multiplicité et variable composite
Accès à l'occurrence du parent
Le fait qu'une variable composite soit multiple rajoute de la contrainte sur les formules de calcul utilisées dans les
sous variables. Rappelez-vous que les variables sont accessibles par leurs codes, mais que faire si dans une formule
dans une sous variable on souhaite accéder à la valeur d'une autre sous variable de la variable composite qui les
contient tous les deux ? Pour cela, le mot clé _parent
peut être utilisé afin d'accéder à l'occurrence parente puis
naviguer dans les sous variables.
Admettons que ARTICLE
est multiple, les valeurs pour QUANTITE
et PRIX
sont renseignées en entrée de l'évaluation.
On peut imaginer la formule de calcul pour la variable TOTAL
soit :
_parent.PRIX.value * _parent.QUANTITE.value
Le mot clé _parent
peut être chaîné si on veut remonter dans l'arbre des parents.
_parent._parent._VAR.value
Boucler sur les valeurs d'autres variables multiples
Cas particulier uniquement pour les variables multiples de type Composite
. Le nombre d'occurrences peut être calculé
au runtime en effectuant un produit cartésien sur les occurrences d'autres variables multiples choisies.
Un code doit être défini pour représenter la valeur sélectionnée pour chaque variable multiple utilisée. Ce code peut être utilisé dans les formules de calcul des sous variables afin d'accéder à la valeur de l'occurrence en cours de chacune des variables multiples utilisées.
Prenons pour exemple une variable composite multiple appelée TARIF
dont on souhaite que le nombre d'occurrences de
cette variable dépende des occurrences des variables chaînes de caractères FORMULE
et FRACTIONNEMENT
représentées
par les codes FORM
et FRAC
respectivement.
Ainsi, pour les valeurs :
[
{
"reference": "FORMULE[0]",
"value": "Mini"
},
{
"reference": "FORMULE[1]",
"value": "Maxi"
},
{
"reference": "FRACTIONNEMENT[0]",
"value": "Mensuel"
},
{
"reference": "FRACTIONNEMENT[1]",
"value": "Annuel"
}
]
Nous aurons 4 occurrences calculées de la variable TARIF
:
[
{
"reference": "TARIF[0]",
"loopStep": {
"FORM": "Mini",
"FRAC": "Mensuel"
},
...
},
{
"reference": "TARIF[1]",
"loopStep": {
"FORM": "Mini",
"FRAC": "Annuel"
},
...
},
{
"reference": "TARIF[2]",
"loopStep": {
"FORM": "Maxi",
"FRAC": "Mensuel"
},
...
},
{
"reference": "TARIF[3]",
"loopStep": {
"FORM": "Maxi",
"FRAC": "Annuel"
},
...
},
...
]
Admettons qu'on a défini une variable de type Nombre
appelée FRAIS_FRACTIONNEMENT
sous la variable TARIF
dont la
formule de calcul est :
if (FRAC == "Annuel") {
return 1;
} else {
return 1.1;
}
Concrètement, on définit ici un coefficient à appliquer au tarif selon le mode de fractionnement. Ainsi, la variable
FRAIS_FRACTIONNEMENT
sera évaluée comme suit :
[
...,
{
"reference": "TARIF[0]/FRAIS_FRACTIONNEMENT",
"value": 1.1
},
{
"reference": "TARIF[1]/FRAIS_FRACTIONNEMENT",
"value": 1
},
{
"reference": "TARIF[2]/FRAIS_FRACTIONNEMENT",
"value": 1.1
},
{
"reference": "TARIF[3]/FRAIS_FRACTIONNEMENT",
"value": 1
},
...
]
Propriétés
En plus de la valeur des attributs de contrôles, il est possible d'étendre le modèle de définition de la variable par une liste de propriétés.
Chaque propriété est de type Chaîne
et est définie par un code. Ce code doit être unique parmi les propriétés de la
variable.
La valeur de la propriété peut être statique ou calculée.
À titre d'exemple, on peut imaginer qu'on génère un formulaire web automatiquement à partir d'une collection de variables. On va donc définir plusieurs propriétés qui vont servir uniquement à l'affichage du formulaire, par exemple :
LIBELLE
: une propriété statique qui va contenir le libellé du champ à afficher dans le formulaireINFOBULLE
: une propriété statique renseignée pour les champs qui nécessitent plus de détail.AFFICHABLE
: une propriété calculée en fonction de la saisie ou non d'une autre variable.
Contrôles
Il est possible d'ajouter des contrôles sur les attributs ou la valeur de la variable. Ces contrôles sont exécutés après l'évaluation des valeurs, si au moins un contrôle n'est pas validé, une exception est levée contenant l'ensemble des erreurs de validation rencontrées.
Tous ces contrôles sont des attributs qui font partis de la définition de la variable. Certains sont communs et d'autres sont spécifiques au type de la variable.
Obligatoire
commun
Il s'agit d'un booléen statique ou calculé qui définit si la variable est obligatoire. Si c'est le cas et qu'après l'évaluation la variable n'a pas de valeur assignée, alors une erreur de validation est levée.
Nombre d'occurrences
commun
Dans le cas ou la variable est multiple, il est possible de définir un nombre min et/ou un max d'occurrences de la variable. Ces valeurs peuvent être statiques ou bien calculées à partir d'une formule.
Liste des valeurs valides
Nombre
et Chaîne
Permet de définir une liste des valeurs que l'on peut assigner aux occurrences de la variable. Si une valeur non présente dans cette liste est assignée à une occurrence de la variable, alors une erreur de validation est levée.
Cette liste ne peut contenir que des valeurs statiques.
Pour les variables de type Nombre
il est possible de faire calculer cette liste de valeurs. Pour cela, il ne faut pas
renseigner cette liste de valeurs statiques, mais utiliser les valeurs minimum/maximum
et le pas.
Longueur minimum et maximum
Chaîne
Permet de définir la longueur minimum et/ou maximum de la valeur assignée à la variable de type Chaîne
.
Les valeurs des longueurs minimum et maximum sont des entiers et peuvent être statiques ou calculées.
Date minimum et maximum
Date
Une date minimum ou maximum suivant l'échelle du temps que l'on peut assigner à une variable de type Date
.
Si la date assignée à la variable est antérieur ou supérieur (selon le cas) à la date minimum définie,
alors une erreur de validation est levée.
Les valeurs des dates minimum et maximum peuvent être statiques ou calculées.
Valeur minimum et maximum
Nombre
Même principe que pour les dates minimum et maximum, mais cette fois avec des valeurs numériques minimum et maximum.
Les valeurs minimum et maximum peuvent être statiques ou calculées.
Ces valeurs sont ignorées si la liste des valeurs valides est renseignée.
Pas
Nombre
N'a de sens que si la liste des valeurs valides est vide et que les valeurs minimum et maximum sont renseignées.
Le pas permet de reconstituer la liste des valeurs possibles en partant de la valeur minimum puis en ajoutant la valeur du pas jusqu'à arriver à la valeur maximum.
Si une valeur est inférieur à la valeur minimum ou supérieur à la valeur maximum ou ne faisant pas partis des valeurs respectant le pas défini, alors une erreur de validation est levée.
- Valeur minimum :
-5
- Valeur maximum :
5
- Pas :
1
Les valeurs possibles sont donc : -5
, -4
, -3
, -2
, -1
, 0
, 1
, 2
, 3
, 4
, 5
.
Une erreur de validation est levée si par exemple les valeurs suivantes sont assignées à la variable : -12
ou 3.14
ou 98
.
Modèle
Chaîne
Il est possible de définir un modèle, qui est une expression régulière, qui permet de valider la valeur de la variable. La valeur assignée doit correspondre pleinement à l'expression définie.
Modèle pour les plaques d'immatriculation : ^[A-Z]{2}[-][0-9]{3}[-][A-Z]{2}$
La valeur AA-123-BB
est valide.
La valeur xAA-123-BBx
n'est pas valide.
Variable Record
Les variables Record
sont transformés en variables Composite
dont les sous variables sont résolues à partir du
service RuleShake Referential.
La définition de la variable Record
contient le lien vers le dataset dans lequel la résolution des données sera faite.
On va également définir la liste des classiers qu'on souhaite inclure. Les valeurs des classiers seront ajoutées sous
forme de sous variable de la variable Record
.
Lors de l'évaluation, la variable Record
se verra assignée le code du record faisant partie du dataset sélectionné.
C'est la combinaison codeDataset
+ codeRecord
+ codesClassiers
qui va permettre le remplacement de la variable
Record
par une variable Composite
.
Soit le dataset REFERENTIEL_GEO
qui contient la liste des communes de France. En plus du CODE
, qui est le code INSEE
de la commune, il a comme propriétés :
PAYS
DEPARTEMENT
COMMUNE
CODE | PAYS | DEPARTEMENT | COMMUNE |
---|---|---|---|
69029 | FRANCE | RHONE | BRON |
69266 | FRANCE | RHONE | VILLEURBANE |
83061 | FRANCE | VAR | FREJUS |
A ce dataset, est lié le classier ZONIER
qui attribut un code de zone pour chaque commune selon les critères :
CODE | VALEUR | LIENS |
---|---|---|
ZONE1 | A | COMMUNE=BRON |
ZONE2 | B | DEPARTEMENT=RHONE |
ZONE3 | C | PAYS=FRANCE |
Dans la définition du classier ZONIER
il est indiqué que la résolution de sa valeur se fait dans l'ordre :
- COMMUNE
- DEPARTEMENT
- PAYS
Ainsi, pour la commune BRON
, la valeur du classier est A
car on a un lien direct vers cette commune. Pour la
commune VILLEURBANE
, la valeur du classier est B
car on n'a pas de lien direct vers la commune, mais on a lien avec
le département RHONE
. Enfin, pour la commune FREJUS
, n'ayant pas de lien ni avec la commune ni avec le départment,
la valeur du classier est C
.
Maintenant, prenons l'exemple d'une variable Record
appelée LIEU_STATIONNEMENT
qui est liée au dataset
REFERENTIEL_GEO
à laquelle on souhaite inclure le classier ZONIER
. Pour la valeur :
[
{
"reference": "LIEU_STATIONNEMENT",
"value": "69029"
}
]
On aura le résultat :
[
{
"reference": "LIEU_STATIONNEMENT",
"value": [
{
"reference": "LIEU_STATIONNEMENT/CODE",
"value": "69029"
},
{
"reference": "LIEU_STATIONNEMENT/PAYS",
"value": "FRANCE"
},
{
"reference": "LIEU_STATIONNEMENT/DEPARTEMENT",
"value": "RHONE"
},
{
"reference": "LIEU_STATIONNEMENT/COMMUNE",
"value": "BRON"
},
{
"reference": "LIEU_STATIONNEMENT/ZONIER",
"value": "A"
}
]
}
]
On pourra ensuite utiliser ces sous variables dans des formules de calcul.
if (LIEU_STATIONNEMENT.ZONIER.value == "A") {
return 0.9;
}
return 1;
Dans cet exemple, une réduction de 10% sera attribuée si le lieu de stationnement est BRON
(car c'est la seule commune qui est dans la zone A
)