⚙️ Références de paramètres

pull/947/head
Maxime Quandalle 2020-03-25 18:06:07 +01:00
parent 18683f79de
commit f5512b9a9c
No known key found for this signature in database
GPG Key ID: 428641C03D29CA10
6 changed files with 200 additions and 133 deletions

View File

@ -297,6 +297,74 @@ somme avec remplacements:
formule: a + b
```
## Références de paramètres
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 :
```yaml
prime:
formule:
multiplication:
assiette: 1000€
taux: taux
prime . taux:
formule: 5%
super-prime:
remplace: prime . taux
formule: 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 (avec sa propre page de
documentation, etc.), 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 d'utiliser une **référence de paramètre**.
On garde la définition de la prime inchangée et on annote l'argument auquel on
veut accéder depuis l'extérieur avec le mot clé `[ref]` :
```yaml
prime:
formule:
multiplication:
assiette: 1000€
taux [ref]: 5%
super-prime:
remplace: prime . taux
formule: 10%
```
Par défaut le paramètre est référencé avec son nom dans l'espace de nom de la
règle, ici `prime . taux`. Il est possible de choisir un nom personnalisé :
```yaml
prime:
formule:
multiplication:
assiette: 1000€
taux [ref taux bonus]: 5%
super-prime:
remplace: prime . taux bonus
formule: 10%
```
Lors d'une relecture future de la règle `prime` le mot clé `[ref]` indique
explicitement que du code extérieur dépend du paramètre `taux`, ce a quoi il
faut être vigilant en cas de ré-écriture.
## Évaluation
Le ticket

View File

@ -15,6 +15,20 @@ export function syntaxError(
)
}
export function compilationError(
rules: string[] | string,
message: string,
originalError?: Error
) {
throw new Error(
`\n[ Erreur de compilation ]
Dans la règle \`${coerceArray(rules).slice(-1)[0]}\`
${message}
${originalError?.message}
`
)
}
export function evaluationError(
rules: string[] | string,
message: string,

View File

@ -1,23 +1,19 @@
import parseRule from 'Engine/parseRule'
import { safeLoad } from 'js-yaml'
import { lensPath, set } from 'ramda'
import { compilationError } from './error'
import { parseReference } from './parseReference'
import { ParsedRules, Rules } from './types'
/*
Dans ce fichier, les règles YAML sont parsées.
Elles expriment un langage orienté expression, les expressions étant
- préfixes quand elles sont des 'mécanismes' (des mot-clefs représentant des calculs courants dans la loi)
- infixes pour les feuilles : des tests d'égalité, d'inclusion, des comparaisons sur des variables ou tout simplement la variable elle-même, ou une opération effectuée sur la variable
*/
export default function parseRules<Names extends string>(
rawRules: Rules<Names> | string
): ParsedRules<Names> {
const rules =
typeof rawRules === 'string'
? (safeLoad(rawRules.replace(/\t/g, ' ')) as Rules<Names>)
: rawRules
: { ...rawRules }
extractInlinedNames(rules)
/* First we parse each rule one by one. When a mechanism is encountered, it is
recursively parsed. When a reference to a variable is encountered, a
@ -67,16 +63,60 @@ export default function parseRules<Names extends string>(
}))
})
/* Then we need to infer units. Since only references to variables have been created, we need to wait for the latter map to complete before starting this job. Consider this example :
A = B * C
B = D / E
C unité km
D unité
E unité km
*
* When parsing A's formula, we don't know the unit of B, since only the final nodes have units (it would be too cumbersome to specify a unit to each variable), and B hasn't been parsed yet.
*
* */
return parsedRules as ParsedRules<Names>
}
// We recursively traverse the YAML tree in order to extract named parameters
// into their own dedicated rules, and replace the inline definition with a
// reference to the newly created rule.
function extractInlinedNames(rules: Record<string, Object>) {
const extractNamesInRule = (dottedName: string) => {
rules[dottedName] !== null &&
Object.entries(rules[dottedName]).forEach(
extractNamesInObject(dottedName)
)
}
const extractNamesInObject = (
dottedName: string,
context: Array<string | number> = []
) => ([key, value]: [string, Object]) => {
const match = key.match(/\[ref( (.+))?\]$/)
if (match) {
const argumentType = key.replace(match[0], '').trim()
const argumentName = match[2]?.trim() || argumentType
const extractedReferenceName = `${dottedName} . ${argumentName}`
if (typeof rules[extractedReferenceName] !== 'undefined') {
compilationError(
dottedName,
`Le paramètre [ref] ${argumentName} entre en conflit avec la règle déjà existante ${extractedReferenceName}`
)
}
rules[extractedReferenceName] = {
formule: value,
// TODO: The `virtualRule` parameter should be used to avoid creating a
// dedicated documentation page.
virtualRule: true
}
rules[dottedName] = set(
lensPath([...context, argumentType]),
extractedReferenceName,
rules[dottedName]
)
extractNamesInRule(extractedReferenceName)
} else if (Array.isArray(value)) {
value.forEach((content: Object, i) =>
Object.entries(content).forEach(
extractNamesInObject(dottedName, [...context, key, i])
)
)
} else if (value && typeof value === 'object') {
Object.entries(value).forEach(
extractNamesInObject(dottedName, [...context, key])
)
}
}
Object.keys(rules).forEach(extractNamesInRule)
}

View File

@ -352,9 +352,6 @@ contrat salarié . ATMP:
Professionnelles.
titre.en: Contribution for work accidents and occupational diseases
titre.fr: Cotisation Accidents du Travail et Maladies Professionnelles
contrat salarié . ATMP . taux:
titre.en: rate
titre.fr: taux
contrat salarié . ATMP . taux collectif ATMP:
description.en: >-
Companies with fewer than 20 employees are subject to this collective rate.
@ -956,9 +953,6 @@ contrat salarié . FNAL:
le financement de lallocation logement.
titre.en: Contribution to the National Fund for Housing Assistance
titre.fr: Contribution au Fonds National dAide au Logement
contrat salarié . FNAL . taux:
titre.en: rate
titre.fr: taux
contrat salarié . FNAL . éligible taux réduit:
titre.en: '[automatic] eligible reduced rate'
titre.fr: éligible taux réduit
@ -1217,9 +1211,6 @@ contrat salarié . aides employeur . emploi franc . éligible:
contrat salarié . allocations familiales:
titre.en: Family allowances
titre.fr: allocations familiales
contrat salarié . allocations familiales . taux:
titre.en: rate
titre.fr: taux
contrat salarié . allocations familiales . taux réduit:
titre.en: reduced rate
titre.fr: taux réduit
@ -1315,12 +1306,6 @@ contrat salarié . chômage:
description.fr: Cotisation dassurance chômage
titre.en: unemployment
titre.fr: chômage
contrat salarié . chômage . taux employeur:
titre.en: employer rate
titre.fr: taux employeur
contrat salarié . chômage . taux salarié:
titre.en: employee rate
titre.fr: taux salarié
contrat salarié . complémentaire santé:
description.en: >
Health Insurance (Social Security) does not fully reimburse your health
@ -1455,15 +1440,9 @@ contrat salarié . contribution d'équilibre général:
cotisation de compensation pour les cadres.
titre.en: general equilibrium contribution
titre.fr: contribution d'équilibre général
contrat salarié . contribution d'équilibre général . taux employeur tranche 1:
titre.en: '[automatic] employer rate tranche 1'
titre.fr: taux employeur tranche 1
contrat salarié . contribution d'équilibre technique:
titre.en: technical equilibrium contribution
titre.fr: contribution d'équilibre technique
contrat salarié . contribution d'équilibre technique . taux employeur:
titre.en: '[automatic] employer rate'
titre.fr: taux employeur
contrat salarié . convention collective:
contrôles.0.en: |
[automatic] Caution, the implementation of collective agreements is still
@ -2653,18 +2632,6 @@ contrat salarié . retraite complémentaire:
Cotisations de retraite complémentaire.
titre.en: supplementary pension
titre.fr: retraite complémentaire
contrat salarié . retraite complémentaire . taux employeur tranche 1:
titre.en: employer rate tranche 1
titre.fr: taux employeur tranche 1
contrat salarié . retraite complémentaire . taux employeur tranche 2:
titre.en: employer rate tranche 2
titre.fr: taux employeur tranche 2
contrat salarié . retraite complémentaire . taux salarié tranche 1:
titre.en: employee rate tranche 1
titre.fr: taux salarié tranche 1
contrat salarié . retraite complémentaire . taux salarié tranche 2:
titre.en: employee rate tranche 2
titre.fr: taux salarié tranche 2
contrat salarié . retraite supplémentaire:
titre.en: '[automatic] additional pension'
titre.fr: retraite supplémentaire
@ -3704,18 +3671,6 @@ contrat salarié . vieillesse:
description.fr: Cotisation au régime de retraite de base des salariés.
titre.en: Basic pension contribution
titre.fr: vieillesse
contrat salarié . vieillesse . taux employeur déplafonné:
titre.en: not capped employer rate
titre.fr: taux employeur déplafonné
contrat salarié . vieillesse . taux employeur plafonné:
titre.en: capped employer rate
titre.fr: taux employeur plafonné
contrat salarié . vieillesse . taux salarié déplafonné:
titre.en: not capped employee rate
titre.fr: taux salarié déplafonné
contrat salarié . vieillesse . taux salarié plafonné:
titre.en: capped employee rate
titre.fr: taux salarié plafonné
dirigeant:
question.en: What is the director's social regime?
question.fr: Quel est le régime social du dirigeant ?

View File

@ -648,14 +648,11 @@ contrat salarié . ATMP:
formule:
produit:
assiette: cotisations . assiette
taux: taux
contrat salarié . ATMP . taux:
formule:
variations:
- si: taux réduit
alors: 1%
- sinon: ATMP . taux collectif ATMP
taux [ref]:
variations:
- si: taux réduit
alors: 1%
- sinon: ATMP . taux collectif ATMP
contrat salarié . ATMP . taux minimum:
description: >-
@ -2248,7 +2245,7 @@ contrat salarié . contribution d'équilibre général:
- attributs:
dû par: employeur
tranches:
- taux: taux employeur tranche 1
- taux [ref taux employeur tranche 1]: 1.29%
plafond: 1
- taux: 1.62%
plafond: 8
@ -2265,9 +2262,6 @@ contrat salarié . contribution d'équilibre général:
références:
calcul des cotisations: https://www.agirc-arrco.fr/ce-qui-change-au-1er-janvier-2019/vous-etes-une-entreprise-tiers-declarant/
contrat salarié . contribution d'équilibre général . taux employeur tranche 1:
formule: 1.29%
contrat salarié . contribution d'équilibre technique:
acronyme: CET
cotisation:
@ -2282,16 +2276,13 @@ contrat salarié . contribution d'équilibre technique:
composantes:
- attributs:
dû par: employeur
taux: taux employeur
taux [ref taux employeur]: 0.21%
- attributs:
dû par: salarié
taux: 0.14%
références:
calcul des cotisations: https://www.agirc-arrco.fr/ce-qui-change-au-1er-janvier-2019/vous-etes-une-entreprise-tiers-declarant/
contrat salarié . contribution d'équilibre technique . taux employeur:
formule: 0.21%
contrat salarié . retraite complémentaire:
cotisation:
branche: retraite
@ -2307,31 +2298,22 @@ contrat salarié . retraite complémentaire:
- attributs:
dû par: employeur
tranches:
- taux: taux employeur tranche 1
- taux [ref taux employeur tranche 1]: 4.72%
plafond: 1
- taux: taux employeur tranche 2
- taux [ref taux employeur tranche 2]: 12.95%
plafond: 8
- attributs:
dû par: salarié
assiette: cotisations . assiette . salariale
tranches:
- taux: taux salarié tranche 1
- taux [ref taux salarié tranche 1]: 3.15%
plafond: 1
- taux: taux salarié tranche 2
- taux [ref taux salarié tranche 2]: 8.64%
plafond: 8
références:
calcul des cotisations: https://www.agirc-arrco.fr/ce-qui-change-au-1er-janvier-2019/vous-etes-une-entreprise-tiers-declarant/
régime des impatriés: https://www.legifrance.gouv.fr/affichTexteArticle.do;jsessionid=D2C4F8F0A5E19693ADF9F440120B748A.tplgfr31s_2?idArticle=JORFARTI000038496272&cidTexte=JORFTEXT000038496102&dateTexte=29990101&categorieLien=id
contrat salarié . retraite complémentaire . taux employeur tranche 1:
formule: 4.72%
contrat salarié . retraite complémentaire . taux employeur tranche 2:
formule: 12.95%
contrat salarié . retraite complémentaire . taux salarié tranche 1:
formule: 3.15%
contrat salarié . retraite complémentaire . taux salarié tranche 2:
formule: 8.64%
contrat salarié . retraite supplémentaire:
formule:
somme:
@ -2395,16 +2377,11 @@ contrat salarié . allocations familiales:
formule:
produit:
assiette: cotisations . assiette
taux: taux
références:
calcul: https://www.urssaf.fr/portail/home/employeur/calculer-les-cotisations/les-taux-de-cotisations/la-cotisation-dallocations-famil.html
contrat salarié . allocations familiales . taux:
formule:
variations:
- si: taux réduit
alors: 3.45%
- sinon: 5.25%
taux [ref]:
variations:
- si: taux réduit
alors: 3.45%
- sinon: 5.25%
références:
calcul: https://www.urssaf.fr/portail/home/employeur/calculer-les-cotisations/les-taux-de-cotisations/la-cotisation-dallocations-famil.html
@ -2457,10 +2434,10 @@ contrat salarié . chômage:
composantes:
- attributs:
dû par: salarié
taux: taux salarié
taux [ref taux salarié]: 0%
- attributs:
dû par: employeur
taux: taux employeur
taux [ref taux employeur]: 4.05%
exemples:
- nom: SMIC
situation:
@ -2471,12 +2448,6 @@ contrat salarié . chômage:
cotisations . assiette: 20000
valeur attendue: 555.34
contrat salarié . chômage . taux salarié:
formule: 0%
contrat salarié . chômage . taux employeur:
formule: 4.05%
contrat salarié . complémentaire santé:
description: |
L'Assurance maladie (Sécurité sociale) ne rembourse pas complètement vos dépenses de santé.
@ -2825,7 +2796,11 @@ contrat salarié . FNAL:
formule:
produit:
assiette: cotisations . assiette
taux: taux
taux [ref]:
variations:
- si: éligible taux réduit
alors: 0.1%
- sinon: 0.5%
variations:
- si: éligible taux réduit
alors:
@ -2840,12 +2815,6 @@ contrat salarié . FNAL:
contrat salarié . FNAL . éligible taux réduit:
formule: entreprise . effectif < 50
contrat salarié . FNAL . taux:
formule:
variations:
- si: éligible taux réduit
alors: 0.1%
- sinon: 0.5%
contrat salarié . formation professionnelle:
cotisation:
@ -3325,18 +3294,17 @@ contrat salarié . vieillesse:
assiette: cotisations . assiette . salariale
composantes:
- nom: déplafonnée
taux: taux salarié déplafonné
taux [ref taux salarié déplafonné]: 0.4%
- nom: plafonnée
taux: taux salarié plafonné
taux [ref taux salarié plafonné]: 6.90%
plafond: plafond sécurité sociale
- attributs:
dû par: employeur
composantes:
- nom: déplafonnée
taux: taux employeur déplafonné
taux [ref taux employeur déplafonné]: 1.9%
- nom: plafonnée
taux: taux employeur plafonné
taux [ref taux employeur plafonné]: 8.55%
plafond: plafond sécurité sociale
exemples:
@ -3351,15 +3319,6 @@ contrat salarié . vieillesse:
références:
Article L727-2 du Code de la sécurité sociale: https://www.legifrance.gouv.fr/affichCode.do;jsessionid=F5CFB7C90D1D1F529A2CDC9FFD20BD6E.tplgfr34s_3?idSectionTA=LEGISCTA000038510929&cidTexte=LEGITEXT000006073189&dateTexte=20190626
contrat salarié . vieillesse . taux salarié plafonné:
formule: 6.90%
contrat salarié . vieillesse . taux salarié déplafonné:
formule: 0.4%
contrat salarié . vieillesse . taux employeur plafonné:
formule: 8.55%
contrat salarié . vieillesse . taux employeur déplafonné:
formule: 1.9%
contrat salarié . forfait social:
titre: Forfait social
description: |

View File

@ -0,0 +1,31 @@
cotisation:
formule:
multiplication:
assiette [ref]: 1000
taux [ref taux employeur]: 4%
exemples:
- valeur attendue: 40
- situation:
cotisation . assiette: 2000
valeur attendue: 80
- situation:
cotisation . assiette: 3000
cotisation . taux employeur: 3
valeur attendue: 90
paramètre nommés imbriqués:
formule:
multiplication:
assiette [ref]:
encadrement:
valeur: 1000
plafond [ref]: 100
taux: 5%
exemples:
- valeur attendue: 5
- situation:
paramètre nommés imbriqués . assiette . plafond: 200
valeur attendue: 10