Skip to main content

Principes de base

La syntaxe de Publicodes est basée sur le langage Yaml.

Un fichier Publicodes contient une liste de règles identifiées par leur nom et possédant une valeur :

prix d'un repas: 10

Une formule de calcul peut faire référence à d'autres règles. Dans l'exemple suivant la règle prix total aura pour valeur 50 (= 5 * 10)

prix d'un repas: 10
prix total: 5 * prix d'un repas

Il s'agit d'un langage déclaratif : comme dans une formule d'un tableur le prix total sera recalculé automatiquement si le prix d'un repas change. L'ordre de définition des règles n'a pas d'importance.

Unités

Pour fiabiliser les calculs et faciliter leur compréhension, on peut préciser l'unité des valeurs littérales :

prix d'un repas: 10 €/repas
nombre de repas: 5 repas

prix total: nombre de repas * prix d'un repas

Le calcul est inchangé mais on a indiqué que le "prix d'un repas" s'exprime en €/repas et que le "nombre de repas" est un nombre de repas. L'unité du prix total est inférée automatiquement comme étant en . (€/repas * repas = )

Ce système d'unité permet de typer les formules de calcul et de rejeter automatiquement des formules incohérentes :

prix d'un repas: 10 €/repas
nombre de repas: 5 repas
frais de réservation: 1 €/repas

prix total: nombre de repas * prix d'un repas + frais de réservation
# Erreur:
# La formule de "prix total" est invalide.

Dans l'exemple ci-dessus, Publicodes détecte une erreur car les termes de l'addition ont des unités incompatibles : d'un côté on a des et de l'autre des €/repas.

Cette incohérence d'unité témoigne d'une erreur de logique. Ici, une manière de corriger l'erreur peut être de factoriser la variable "nombre de repas" dans la formule du "prix total".

prix d'un repas: 10 €/repas
nombre de repas: 5 repas
frais de réservation: 1 €/repas

prix total: nombre de repas * (prix d'un repas + frais de réservation)
Attention

Il ne faut pas insérer d'espace autour de la barre oblique dans les unités, l'unité € / mois doit être notée €/mois.

Publicodes convertit automatiquement les unités si besoin.

salaire: 1500 €/mois
prime faible salaire applicable: salaire < 20 k€/an
info

On peut forcer la conversion des unités via le mécanisme unité.

Types de base disponibles pour la conversion :

  • jour / mois / an
  • / k€
  • g / kg / mg

Pourcentage %

Il est possible de spécifier un pourcentage comme unité. L'addition d'un nombre avec un pourcentage revient à ajouter le pourcentage à ce nombre. De même pour la soustraction.

prix TTC: 10€ + 20%

Le résultat de l'addition de deux pourcentages est bien la somme des deux nombres :

réduction: 2.4% + 5.0%

Mécanismes

Il existe une autre manière d'écrire des formules de calcul : les mécanismes. Au lieu de définir la formule sur une ligne, celle-ci prend la forme d'un objet sur plusieurs lignes.

Par exemple, la formule suivante :

prix total: 5 repas * 9 €/repas

peut également s'écrire en utilisant le mécanisme produit :

prix total:
produit:
assiette: 9 €/repas
facteur: 5 repas

Un des avantages de cette écriture est que la syntaxe hiérarchique de Yaml permet d'imbriquer les mécanismes :

table: 12 personnes
addition:
somme:
- 7 cafés * 1.5 €/cafés
- produit: # Menu unique dégressif pour les groupes
assiette: table
facteur:
variations:
- si: table > 10 personnes
alors: 12 €/personnes
- sinon: 15 €/personnes

Mécanismes chaînés

Certains mécanismes peuvent apparaître au même niveau d'indentation. Dans ce cas, le moteur appliquera les transformations dans un ordre préétabli.

nombre de repas: 12 repas
remboursement repas:
valeur: nombre de repas * 4.21 €/repas
plafond: 500
abattement: 25
arrondi: oui

Voir la liste des mécanismes existants

Pages d'explications

L'explication des règles est un des objectifs fondamentaux de Publicodes.

Chaque règle se voit générer automatiquement une page explicative correspondante dans le front-end, contenant une information facilement digeste mise en regard des calculs eux-mêmes.

Plusieurs propriétés sont reprises dans ces pages d'explications :

  • le titre, qui s'affiche en haut de la page. Par défaut on utilise le nom de la règle, mais la propriété titre permet de choisir un titre plus approprié ;
  • la description est affichée comme paragraphe d'introduction sur la page. On utilise le caractère | pour indiquer au parseur Yaml que la description est sur plusieurs lignes ;
  • une note de bas de page, affichée après la formule de calcul. Elle peut être sur plusieurs lignes également.
ticket resto:
titre: Prise en charge des titres-restaurants
formule: 4 €/repas
description: |-
L'employeur peut remettre des titres restaurants sous plusieurs formats: ticket papier, carte à puce
ou appli mobile
note: |-
La valeur a été revalorisée en 2022 pour faire face à l'inflation.

Conditions booléennes

Publicodes supporte des opérateurs booléens basiques.

âge: 17 ans
nationalité française: oui
citoyen européen:
domicilié en France:

droit de vote municipale:
toutes ces conditions:
- âge >= 18 ans
- une de ces conditions:
- nationalité française
- toutes ces conditions:
- citoyen européen
- domicilié en France

Il est possible de faire des branchements conditionnels via le mécanisme variations

Applicabilité

On peut définir des conditions d'applicabilité pour des valeurs :

date de début: 12/02/2020

ancienneté en fin d'année:
durée:
depuis: date de début
jusqu'à: 31/12/2020

prime de vacances:
applicable si: ancienneté en fin d'année > 1 an
valeur: 200

Ici, si l'ancienneté est inférieure à un an, alors la prime de vacances sera non applicable.

Les variables non applicable sont prise en compte différement au niveau des mécanismes numériques. Par exemple le mécanisme somme comptera une prime non applicable comme valant zéro. Un plafond non applicable n'aura pas d'incidence sur la valeur retournée (même chose pour un abattement ou un plancher par exemple).

La valeur non est applicable

Publicodes différencie désormais la valeur booléenne non d'une valeur non applicable. Cela permet par exemple de cacher les questions non applicable dans un formulaire tout en affichant les questions dont la réponse est non.

Tester l'applicabilité

On peut tester si une variable est applicable ou non applicable avec les mécanismes est applicable et est non applicable.

Rend non applicable

Il est également possible de rendre une règle non applicable depuis une autre règle :

nouveau salarié:
valeur: oui
rend non applicable: prime de vacances

prime de vacances: 200

primes:
somme:
- prime de vacances
- 150
Note

La syntaxe rend non applicable fonctionne de la même manière que le remplacement : elle rend non applicable toutes les références à la règle choisie.

En savoir plus sur le remplacement

Espaces de noms

Les espaces de noms sont utiles pour organiser un grand nombre de règles. On utilise le . pour exprimer la hiérarchie des noms.

prime de vacances: taux * 1000
prime de vacances . taux: 6%

Ici, prime de vacances est à la fois une règle et un espace de noms. La variable taux est définie dans cet espace de noms et c'est elle qui est référencée dans la formule de calcul de la règle prime de vacances.

La règle prime de vacances est elle-même définie dans l'espace de nom racine.

On pourrait avoir une autre variable taux dans un espace de nom différent, sans que cela entre en conflit :

prime de vacances: taux * 1000
prime de vacances . taux: 6%

# Ceci n'entre pas dans le calcul de `prime de vacances` définie plus haut
autre prime:
autre prime . taux: 19%

On dit que la règle prime de vacances fait référence à la règle prime de vacances . taux via le nom raccourci taux.

Pour faire référence à une règle hors de son espace de nom, on peut écrire le nom complet de cette règle:

autre prime:
autre prime . taux: 19%
prime de vacances v2: autre prime . taux * 1000

Dans le cas d'espaces de noms imbriqués (à plus qu'un étage), le nom inscrit dans une règle donnée est recherché de plus en plus haut dans la hiérarchie des espaces de nom jusqu'à la racine.

contrat salarié:
contrat salarié . rémunération:
contrat salarié . rémunération . primes:

contrat salarié . rémunération . primes . prime de vacances:
valeur: taux générique * 1000

contrat salarié . rémunération . taux générique:
valeur: 10%

Ici contrat salarié . rémunération . primes . prime de vacances va faire référence à contrat salarié . rémunération . taux générique trouvé deux espaces de noms plus haut, et va donc valoir 100 €.

Désactivation de branche

Il est possible de désactiver l'ensemble des règles définies dans un espace de nom.

Toutes les règles possèdent une dépendance implicite à leur parent. Si ce dernier vaut à non ou est non applicable alors toutes les règles enfants seront non applicables

CDD: non
CDD . indemnité de précarité: 10% * 1500€/mois * 6 mois

indemnités:
somme:
- 100
- CDD . indemnité de précarité
région: '"Centre"'

aides occitanie:
applicable si: région = 'Occitanie'
aides occitanie . subvention vélo : 500

Remplacement

Certaines règles ne s'appliquent parfois que dans quelques situations particulières et modifier la définition des règles générales pour prendre en compte ces particularités pose des problèmes de maintenabilité de la base de règles.

Publicodes dispose d'un mécanisme de remplacement qui permet d'amender n'importe quelle règle existante sans avoir besoin de la modifier :

frais de repas: 5 €/repas

convention hôtels cafés restaurants: oui
convention hôtels cafés restaurants . frais de repas restaurateur:
remplace: frais de repas
valeur: 6 €/repas

montant repas mensuels: 20 repas * frais de repas

On peut également choisir de remplacer dans un contexte donné :

temps de préparation: 20 min
temps de cuisson: 20 min

robot de cuisine:
remplace:
- règle: temps de préparation
sauf dans: temps original
par: 10 min
valeur: oui

temps original:
formule: temps de préparation + temps de cuisson

temps modifié:
formule: temps de préparation + temps de cuisson
Note

Les remplacement sont implémentés sous forme d'une substitution de variable. Quand une règle en remplace une autre, c'est toutes les références à la règle remplacée qui vont être changées par la valeur de remplacement.

Règle imbriquées

A l'intérieur des mécanismes : nom

Si le mécanisme de remplacement permet de faire des substitutions de règles complètes, il est parfois utile de ne modifier qu'un seul paramètre d'une règle existante, par exemple modifier le facteur d'une multiplication tout en conservant le reste de sa définition inchangée.

Une première manière de faire consiste à extraire le paramètre en question dans une règle indépendante, le rendant ainsi accessible et modifiable depuis l'extérieur :

prime:
multiplication:
assiette: 1000
taux: taux

prime . taux: 5%

super-prime:
remplace: prime . taux
valeur: 10%

Ce code fonctionne mais il nous oblige a créer une règle prime . taux qui n'est pas pertinente en tant qu'entité autonome, uniquement pour pouvoir la modifier avec un remplace.

On a aussi introduit une indirection dans la définition de la prime en remplaçant une ligne explicite taux: 5% par une référence vers une règle tierce taux: taux, qui est loin d'être aussi claire.

Pour ce cas d'usage il est possible de définir une règle imbriquée. On garde la définition de la prime inchangée et on annote la valeur à laquelle on veut accéder depuis l'extérieur avec le mot clé nom :

prime:
multiplication:
assiette: 1000
taux:
nom: taux
valeur: 5%

super-prime:
remplace: prime . taux
valeur: 10%

Directement sur la règle : avec

prix final:
valeur: 157 € * (100% - 20%)

Dans cet exemple, si l'on veut extraire le prix et la promotion dans des variables séparées, on est obligé de les définir à côté de la règle prix final :

prix final:
valeur: prix de base * (100% - promotion)
prix final . prix de base: 157
prix final . promotion: 20%

Pour alléger cette écriture, on peut utiliser la notation avec qui permet de définir des règles imbriquées directement depuis une règle parente :

prix final:
valeur: prix de base * (100% - réduction)
avec:
prix de base: 157
réduction: 20%
info

On peut tout à fait combiner les deux écritures nom et avec :

cotisation:
produit:
assiette: assiette
taux: 2.8%
plafond:
nom: plafond
le minimum de:
- 50 % * PFSS
- plafond forfaitaire
avec:
plafond forfaitaire: 2000

PFSS: 3400
assiette: 2000

Règles non définie

Il est possible de laisser certaines règles vide pour être saisie par l'utilisateur par exemple. Lors de l'évaluation, les variables dont les valeurs ne sont pas renseignées sont remontées.

salaire brut:
unité: €/mois

salaire net: salaire brut - 20 %

Il est possible de donner une valeur par défaut. Les variables manquantes seront quand même remontées, et le moteur utilisera la valeur par défaut pour le calcul.

durée:
par défaut: 2 mois

salaire brut:
par défaut: 1500 €/mois

indemnité de CDD: 10 % * salaire brut * durée