diff --git a/.editorconfig b/.editorconfig index 2b86cdb02..c6c8a0f85 100644 --- a/.editorconfig +++ b/.editorconfig @@ -26,3 +26,5 @@ trim_trailing_whitespace = false [*.md] trim_trailing_whitespace = false +indent_style = space +indent_size = 4 diff --git a/publicodes/README.md b/publicodes/README.md index faa8b6ba7..69a6b0961 100644 --- a/publicodes/README.md +++ b/publicodes/README.md @@ -20,19 +20,23 @@ progressivement le résultat affiché, et d'exposer une documentation du calcul - **[futur.eco](https://futur.eco/)** utilise publicodes pour calculer les bilans carbone d'un grand nombre d'activités, plats, transports ou biens. -## Principe de base +## Syntaxe + +### Principe de base La syntaxe de Publicode est basée sur le langage -[Yaml](https://en.wikipedia.org/wiki/YAML). Un fichier Publicode contient une -liste de règles identifiées par leur nom et possédant une formule de calcul : +[Yaml](https://en.wikipedia.org/wiki/YAML). + +Un fichier Publicode contient une liste de _règles_ identifiées par leur _nom_ et +possédant une _formule de calcul_ : ```yaml prix d'un repas: formule: 10 € ``` -Une formule de calcul peut référencer d'autres variables. Dans l'exemple suivant -la règle `prix total` aura pour valeur 50 (= 5 \* 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) ```yaml prix d'un repas: @@ -42,10 +46,11 @@ prix total: formule: 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 +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 +### Unités Pour fiabiliser les calculs et faciliter leur compréhension, on peut préciser l'unité des valeurs littérales : @@ -112,7 +117,8 @@ prime faible salaire: formule: 300€ ``` -On peut forcer la conversion des unités via la propriété `unité`, ou la notation suffixé `[...]` +On peut forcer la conversion des unités via la propriété `unité`, ou la notation +suffixée `[...]`. ```yaml salaire: @@ -123,24 +129,29 @@ salaire annuel: formule: salaire [k€/an] ``` -**Conversions disponibles :** +**Types de base disponibles pour la conversion :** - `jour` / `mois` / `an` - `€` / `k€` -## Titre, description et références +### Pages d'explications -Plusieurs propriétés permettent de documenter les règles et sont utilisées dans -les pages d'explications générées automatiquement : +L'explication des règles est un des objectifs fondamentaux de Publicodes. -- le **titre**, qui s'affiche en haut de la page de documentation. Par défaut on - utilise le nom de la règle, mais l'attribut `titre` permet de choisir un titre - plus approprié ; +Chaque règle se voit générer automatiquement une page explicatives +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** qui peut être rédigée en Markdown et est généralement - affichée comme paragraphe d'introduction sur la page. On utilise le caractère `>` - pour indiquer au parseur Yaml que la description utilise du Markdown ; -- les **références** généralement affichées en bas de page et qui sont - constituées d'une liste de liens avec une description. + affichée comme paragraphe d'introduction sur la page. On utilise le caractère + `>` pour indiquer au parseur Yaml que la description utilise du Markdown ; +- les **références** externes (documentation utile) affichées en + bas de page et qui sont constituées d'une liste de liens avec une description. ```yaml ticket resto: @@ -156,24 +167,64 @@ ticket resto: Fiche Urssaf: https://www.urssaf.fr/portail/home/taux-et-baremes/frais-professionnels/les-titres-restaurant.html ``` -## Espaces de noms +Voir aussi la rubrique sur les mécanismes. + +### Espaces de noms Les espaces de noms sont utiles pour organiser un grand nombre de règles. On -utilise le `.` pour définir la hiérarchie des noms. +utilise le `.` pour exprimer la hiérarchie des noms. ```yaml prime de vacances: - formule: taux * 1000€ + formule: taux * 1000 € prime de vacances . taux: formule: 6% ``` -Ici la variable `taux` est dans l'espace de nom `prime de vacances` et c'est -elle qui est référencée dans la formule de calcul. On peut avoir une autre -variable `taux` dans un autre espace de nom. +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`. -## Mécanismes +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: + +```yaml +# Ceci n'entre pas dans le calcul de `prime de vacances` définie plus haut +autre prime . taux: + formule: 19% +``` + +On dit que la formule de 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: + +```yaml +prime de vacances v2: + formule: 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. + +```yaml +contrat salarié . rémunération . primes . prime de vacances: + formule: taux générique * 1000 € + +contrat salarié . rémunération . taux générique: + formule: 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 €`. + +### Mécanismes Les règles de calcul élémentaires sont extraites dans des "mécanismes" qui permettent de partager la logique de calcul et de générer une page d'explication @@ -221,7 +272,7 @@ prime: > **[Aller à la liste des mécanismes existants](./mécanismes)** -## Applicabilité +### Applicabilité On peut définir des conditions d'applicabilité des règles : @@ -241,11 +292,20 @@ prime de vacances: ``` Ici si l'ancienneté est inférieure à un an la prime de vacances ne sera pas -applicable. Les variables non applicables sont ignorées au niveau des mécanismes -(par exemple le mécanisme `somme` comptera une prime non applicable comme valant -zéro). +_applicable_. Les variables _non applicables_ sont ignorées au niveau des +mécanismes (par exemple le mécanisme `somme` comptera une prime non applicable +comme valant zéro, voir la page spécifique aux mécanismes). -## Remplacement +La syntaxe suivante est également valable: + +```yaml +dirigeant . assimilé salarié: + formule: dirigeant = 'assimilé salarié' + rend non applicable: + - contrat salarié . convention collective +``` + +### 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 @@ -294,7 +354,7 @@ somme avec remplacements: formule: a + b ``` -## Références de paramètres +### 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 @@ -327,7 +387,7 @@ 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**. +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]` : @@ -362,6 +422,22 @@ 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. +La syntaxe suivante est équivalente : + +```yaml +prime: + formule: + multiplication: + assiette: 1000€ + taux: + définition: taux bonus + formule: 5% + +super-prime: + remplace: prime . taux bonus + formule: 10% +``` + ## Évaluation Le ticket diff --git a/publicodes/docs/api.md b/publicodes/docs/api.md index 34d1fe0ea..cd60513aa 100644 --- a/publicodes/docs/api.md +++ b/publicodes/docs/api.md @@ -49,6 +49,8 @@ dépenses primeur: const engine = new Engine(rules) ``` +(Attention, sous node vous devrez faire `const Engine = require('publicodes').default`) + La variable `engine` permet en ensuite de calculer la valeur d'une règle avec la méthode `evaluate`. @@ -56,18 +58,19 @@ méthode `evaluate`. console.log(engine.evaluate('dépenses primeur')) ``` -La valeur du nœud est disponible dans l'attribut `nodeValue`, son -unité est disponible dans l'attribut `unit`. Mais pour un formattage sans +La valeur du nœud est disponible dans la propriété `nodeValue`, son +unité est disponible dans la propriété `unit`. Mais pour un formattage sans effort, on préfèrera utiliser la fonction `formatValue` ```js import Engine, { formatValue } from 'publicodes' +// ... const dépenses = engine.evaluate('dépenses primeur') -console.log(`j'ai dépensé ${formatValue(dépenses)} chez le primeur`) +console.log(`J'ai dépensé ${formatValue(dépenses)} chez le primeur.`) ``` -La méthode `setSituation` permet de forcer la valeur d'une liste de règle. Elle est -utile pour préciser les paramètres spécifiques à une simulation. +La méthode `setSituation` permet de forcer la valeur d'une liste de règles. Elle +est utile pour préciser les paramètres spécifiques à une simulation. ```js // Ici on change le prix des avocats @@ -81,7 +84,7 @@ La valeur de `dépenses primeur` se base maintenant sur un avocat à 3€ : ```js // On ré-évalue la règle dans la nouvelle situation console.log( - `Nouveau prix ! ${formatValue(engine.evaluate('dépenses primeur'))}` + `Nouveau prix ! Dépenses mises à jour: ${formatValue(engine.evaluate('dépenses primeur'))}.` ) ``` @@ -91,7 +94,10 @@ La fonction `evaluate` permet d'évaluer des expressions publicode complètes ```js // On va au marché une fois par semaine, amortissons la dépense sur 7 jours -engine.evaluate('dépenses primeur / 7 jours') +const depensesParJour = engine.evaluate('dépenses primeur / 7 jours') +console.log( + `J'ai dépensé ${formatValue(depensesParJour)}.` +) ``` ### Conversion d'unité @@ -101,7 +107,10 @@ indiquer l'unité désirée comme paramètre à la méthode `evaluate` : ```js // on va au marché une fois par semaine en moyenne, combien dépense-t-on par mois ? -engine.evaluate('dépenses primeurs / 7 jours', { unit: '€/mois' }) +const depensesParMois = engine.evaluate('dépenses primeur / 7 jours', { unit: '€/mois' }) +console.log( + `J'ai dépensé ${formatValue(depensesParMois)}.` +) ``` [➡ en savoir plus sur les unités](https://publi.codes/#unités) @@ -110,16 +119,16 @@ engine.evaluate('dépenses primeurs / 7 jours', { unit: '€/mois' }) Publicode calcule automatiquement les dépendances de chaque règle. Si une la valeur d'une dépendance est manquante et ne permet pas de faire le calcul elle -apparaîtra dans l'attribut `missingVariables` +apparaîtra dans la propriété `missingVariables` ```js -const engine = new Engine(` +const missingYEngine = new Engine(` x: y + 5 y: `) -console.log(engine.evaluate('x').missingVariables) +console.log(missingYEngine.evaluate('x').missingVariables) ``` Cette information est utile pour intégrer publicode à votre application. @@ -139,7 +148,7 @@ portion non active de l'évaluation (par exemple dans un bloc condition non actif, ou la tranche d'un barème non actif) elle sera filtrée et n'apparaîtra pas dans les `missingVariables`. -### Documentation intéractive +### Documentation interactive Publicodes génère également pour vous une documentation interactive, très facilement intégrable dans une app react. Pour cela, il vous suffit d'importer @@ -211,8 +220,8 @@ C'est le point d'entrée principal pour adapter les calculs de règles général une situation particulière. La situation est gardée en mémoire, et chaque appel à `setSituation` remplace la situation précédente. Le moteur contient donc un _état interne_. Cela permet d'obtenir de meilleure performance, -avec une gestion plus fine du cache de calcul. En revanche, cela peut-être une -source de bug si l'état interne est modifié lors d'effet de bord non prévus. +avec une gestion plus fine du cache de calcul. En revanche, il faut prêter une +grande attention à la bonne gestion de cet état interne. **Arguments** @@ -225,14 +234,14 @@ source de bug si l'état interne est modifié lors d'effet de bord non prévus. **Retourne** L'objet engine (`this`) sur lequel la fonction a été appelée, afin de pouvoir -utiliser une écriture chaînée (`engine.setSituation(situation).evaluate()`) +utiliser une écriture chaînée (`engine.setSituation(situation).evaluate()`). #### _method_ engine.evaluate(expression, \[options]) Évalue l'expression dans le contexte du moteur (règle et situation). Pour des raisons de performance, les résultats intermédiaires sont enregistrés -dans un cache. Par conséquent, les prochains appels seront plus rapides. +dans un cache. Par conséquent, les appels suivants seront plus rapides. **Arguments** @@ -240,9 +249,11 @@ dans un cache. Par conséquent, les prochains appels seront plus rapides. référence vers une règle, une expression arithmétique, tout ce que la grammaire publicode permet. - `options`: un objet de configuration pour l'évaluation - - - `unit`: spécifie l'unité dans laquelle le résultat doit être retourné. - Si la valeur retournée par le calcul est un nombre, ce dernier sera converti dans l'unité demandée. Ainsi `evaluate('prix', {unit: '€'})` équivaut à `evaluate('prix [€]')`. Une erreur est levée si l'unité n'est pas compatible avec la formule. + - `unit`: spécifie l'unité dans laquelle le résultat doit être retourné. Si la + valeur retournée par le calcul est un nombre, ce dernier sera converti dans + l'unité demandée. Ainsi `evaluate('prix', {unit: '€'})` équivaut à + `evaluate('prix [€]')`. Une erreur est levée si l'unité n'est pas compatible + avec la formule. **Retourne** Un objet javascript de type `EvaluatedNode` contenant la valeur calculée. @@ -267,10 +278,13 @@ Formate la valeur evaluée. - `evaluatedNode` : l'objet retourné lors de l'appel à la fonction d'évaluation du moteur `evaluate(expression)` - `options` : configuration pour le formatage - - - `language`: le langage utilisé pour le formatage (par défaut `fr`) - - `precision`: le nombre de chiffre après la virgule pour le formatage des nombres (par défaut `2`) - - `displayedUnit`: l'unité à afficher pour le formatage des nombres. Outrepasse l'unité définie dans le calcul (on peut donc forcer l'unité affichée à une autre que celle retournée par le calcul, même si elle ne sont pas compatibles) + - `language`: le langage utilisé pour le formatage (par défaut `fr`) + - `precision`: le nombre de chiffre après la virgule pour le formatage des + nombres (par défaut `2`) + - `displayedUnit`: l'unité à afficher pour le formatage des nombres. + Outrepasse l'unité définie dans le calcul (on peut donc forcer l'unité + affichée à une autre que celle retournée par le calcul, même si elle ne sont + pas compatibles) **Retourne** @@ -288,8 +302,8 @@ intermédiaires qui permettent d'aboutir au résultat affiché. #### -Composant react permettant d'afficher une documentation explorable d'une base de règles -publicodes. Se base sur react-router pour créer une arborescence de pages +Composant react permettant d'afficher une documentation explorable d'une base de +règles publicodes. Se base sur react-router pour créer une arborescence de pages correspondant aux espaces de noms existants dans les règles. Voir le [bac à sable](https://publi.codes/studio) pour voir le composant en @@ -299,10 +313,10 @@ action (il est affiché sur l'écran de droite). - `engine`: l'objet moteur dont on veut afficher les calculs. - `documentationPath` : (`string`) le chemin de base sur lequel la documentation sera - montée. Par exemple, si c'est `/documentation` l'url de la règle 'rémunération - . primes' sera `/documentation/rémunération/primes` + montée. Par exemple, si c'est `/documentation` l'url de la règle `rémunération + . primes` sera `/documentation/rémunération/primes` - `language`: le language dans lequel afficher la documentation (pour l'instant, - seul `fr` et `en` sont supportés) + seuls `fr` et `en` sont supportés). #### @@ -316,4 +330,5 @@ Par défaut, le texte affiché est le nom de la règle. montée. Doit correspondre à celui précisé pour le composant `` - `dottedName`: le nom de la règle à afficher - `displayIcon`: affiche l'icône de la règle dans le lien (par défaut à `false`) -- `children`: N'importe quel noeud react. Par défaut, c'est le nom de la règle qui est utilisé. +- `children`: un noeud react quelconque. Par défaut, c'est le nom de la règle + qui est utilisé. diff --git a/publicodes/docs/mecanisms.yaml b/publicodes/docs/mecanisms.yaml index 1509a7ee6..5787955d8 100644 --- a/publicodes/docs/mecanisms.yaml +++ b/publicodes/docs/mecanisms.yaml @@ -1,8 +1,9 @@ une de ces conditions: description: >- - C'est un `ou` logique. - Contient une liste de conditions. - Renvoie `oui` si l'une des conditions est applicable. + Renvoie `oui` si l'une des règles listées est _applicable_. + + + Equivaut à un `ou` logique. retourne: Booléen exemples: base: >- @@ -20,9 +21,10 @@ une de ces conditions: toutes ces conditions: description: >- - C'est un `et` logique. - Contient une liste de conditions. - Renvoie `oui` si toutes les conditions sont applicables. + Renvoie `oui` si toutes toutes les règles listées sont _applicables_. + + + Equivaut à un `et` logique. argument: - '*' - ... @@ -42,12 +44,13 @@ toutes ces conditions: produit: description: >- - C'est une multiplication un peu améliorée, très utile pour exprimer les - cotisations. + C'est une multiplication adaptée pour exprimer au mieux les cotisations. + - Sa propriété `assiette` est multipliée par un pourcentage, `taux`, ou par un + Sa propriété `assiette` est multipliée par un pourcentage `taux`, ou par un `facteur` quand ce nom est plus approprié. + La multiplication peut être plafonnée : ce plafond sépare l'assiette en deux, et la partie au-dessus du plafond est tout simplement ignorée. Dans ce cas, elle se comporte comme une barème en taux marginaux à deux tranches, la @@ -83,15 +86,19 @@ produit: variations: description: >- Contient une liste de conditions (`si`) et leurs conséquences associées - (`alors`). + (`alors`), ainsi qu'un cas par défaut (`sinon`). + Pour la première condition vraie dans la liste, on retient la valeur qui lui est associée. - Si aucune condition n'est vraie, alors ce mécanisme renvoie implicitement - `non applicable` - Ce mécanisme peut aussi être utilisé au sein d'un mécanisme compatible, tel qu'un produit ou un barème. + Si aucune condition n'est vraie, alors ce mécanisme renvoie implicitement + `non applicable`. + + + Ce mécanisme peut aussi être utilisé au sein d'un autre mécanisme + compatible, tel que `produit` ou `barème`. arguments: - si: condition à vérifier alors: consequence évaluée si la condition est vrai @@ -129,10 +136,13 @@ variations: somme: description: >- - C'est tout simplement la somme de chaque terme de la liste. Si un des terme - n'est pas applicable, il vaut zéro. + Somme de chaque terme de la liste. - On peut aussi retrancher des valeurs avec l'opérateur unaire `-` + + Si un des terme n'est pas applicable, il vaut zéro. + + + On peut retrancher des valeurs grâce à l'opérateur unaire `-` arguments: - '*' - ... @@ -165,6 +175,7 @@ le maximum de: Renvoie la valeur numérique de la liste de propositions fournie qui est la plus grande. + Pour ajouter un plancher à une valeur, préférer l'utilisation du mécanisme `encadrement`. exemples: @@ -180,6 +191,7 @@ le minimum de: Renvoie la valeur numérique de la liste de propositions fournie qui est la plus petite. + Pour plafonner une valeur, préférer l'utilisation du mécanisme `encadrement`. exemples: base: >- @@ -343,17 +355,17 @@ recalcul: brut: 1500 € barème: - description: C'est un barème en taux marginaux, mécanisme de calcul connu son utilisation - dans le calcul de l'impôt sur le revenu. + description: C'est un barème en taux marginaux, mécanisme de calcul connu de + par son utilisation dans le calcul de l'impôt sur le revenu. L'assiette est décomposée en plusieurs tranches, qui sont multipliées par un - taux spécifique. + taux spécifique et enfin additionnées pour donner le résultat. Les tranches sont souvent exprimées sous forme de facteurs d'une variable - que l'on appelle `multiplicateur`, par exemple `1 x le plafond de la - sécurité sociale`. + que l'on appelle `multiplicateur`, par exemple une fois le plafond de la + sécurité sociale. exemples: - base: >- + sans multiplicateur: >- revenu imposable: formule: 54126 € @@ -372,10 +384,24 @@ barème: plafond: 153783 € - taux: 45% + avec multiplicateur: >- + retraite de base: + formule: + barème: + assiette: assiette retraite + multiplicateur: plafond sécurité sociale temps plein + tranches: + - taux: 17.75% + plafond: 1 + - taux: 0.6% + arrondi: oui + + grille: description: >- - C'est un barème sous la forme d'une grille de correspondance. C'est le - mécanisme de calcul de l'impôt neutre, aussi appelé impôt non personnalisé. + C'est un barème sous la forme d'une grille de correspondance simple. C'est + le mécanisme de calcul de l'impôt neutre, aussi appelé impôt non + personnalisé. Il est composé de tranches qui se suivent. Il suffit de trouver l'assiette qui correspond à la tranche, et de selectionner le montant associé à @@ -411,15 +437,19 @@ taux progressif: Ce mécanisme permet de calculer un taux progressif. On spécifie pour chaque tranche le plafond et le taux associé. Le taux effectif renvoyé est calculé en lissant la différence de taux entre la borne inférieure et supérieure de - l'assiette + l'assiette. + + + Par exemple, si nous nous avons les tranches suivantes : - > Par exemple, si nous nous avons les tranches suivantes : - taux: 50% / plafond: 0 + - taux: 100% / plafond: 1000 - > Pour une assiette de 500, le taux retourné sera 75%, car il correspond au - > taux situé à la moitié de la tranche correspondante. + + Pour une assiette de 500, le taux retourné sera 75%, car il correspond au + taux situé à la moitié de la tranche correspondante. exemples: base: >- chiffre d'affaires: @@ -438,26 +468,58 @@ taux progressif: plafond: 75% - taux: 0% plafond: 100% + composantes: description: >- Beaucoup de cotisations sont composées de deux parties qui partagent la - méthode de calcul mais diffèrent par des paramètres différents. + méthode de calcul mais diffèrent selons certains paramètres. Pour ne pas + définir deux variables quasi-redondantes, on utilise ce mécanisme. - Pour ne pas définir deux variables presque redondantes, on utilise le - mécanisme de composante. Il se comportera comme une somme dans les calculs, - mais son affichage sur les pages /règle sera adapté. - Il est même possible, pour les mécanismes `barème` et `produit` de garder en + Dans les calculs, `composantes` se comporte **exactement comme une somme**. + La documentation, elle, sera adaptée pour montrer chaque composantes. + + + Chaque composante peut contenir un champs `nom` (de type texte) ou un champs + `attributs` (de type objet avec des champs libres) qui remonteront dans la + documentation pour aider à l'explicabilité. + + + Il est possible, pour les mécanismes `barème` et `produit` de garder en commun un paramètre comme l'assiette, puis de déclarer des composantes pour le taux. - > L'exemple le plus courant de composantes, c'est la distinction part - employeur, part salarié (ex. retraite AGIRC). + + > L'exemple le plus courant de composantes est la distinction part + employeur / part salarié (ex. retraite AGIRC). + + exemples: + base: >- + CSG . base: + formule: + multiplication: + assiette: assiette de base + composantes: + - attributs: + impôt sur le revenu: déductible + taux: taux déductible + - attributs: + impôt sur le revenu: non déductible + taux: taux non déductible allègement: description: >- Permet de réduire le montant d'une variable. + Très utilisé dans le contexte des impôts. + exemples: + base: >- + impôt . revenu abattu: + formule: + allègement: + assiette: base des cotisations + abattement: abattement + encadrement: description: Permet d'ajouter un plafond et/ou un plancher à une valeur. @@ -485,30 +547,41 @@ durée: jusqu'à: 31/12/2020 synchronisation: - description: Pour éviter trop de saisies à l'utilisateur, certaines informations sont - récupérées à partir de ce que l'on appelle des API. Ce sont des services - auxquels ont fait appel pour obtenir des informations sur un sujet précis. - Par exemple, l'État français fournit gratuitement l'API commune, qui permet à - partir du nom d'une ville, d'obtenir son code postal, son département, la - population etc. + description: Permet de récupérer certaines informations, tels que les les + codes postaux des villes, à partir d'APIs externes, telles que l'[API + commune](https://geo.api.gouv.fr/decoupage-administratif/communes). - Ce mécanismes `synchronisation` permet de faire le lien entre les règles de - notre système et les réponses de ces API. + + Attention, ce mécanisme est encore en cours de développement, et sa syntaxe + n'est pas stable. Se référer aux exemples existants. inversion numérique: description: >- - La formule de calcul de cette variable n'est pas connue, souvent elle n'a - même pas de sens. Mais le mécanisme `inversion` indique qu'elle peut être - _estimée_ à partir de l'un des _objectifs_ listés sous l'attribut `avec`. Il - faut alors renseigner une valeur cible pour cet objectif. + Il est souhaitable de rédiger les règles de calcul + en publicodes de la même façon qu'elles sont décrites dans la loi ou les + interprétations administratives ou juridiques existantes. En conséquence, + certaines variables n'auront donc pas de méthode de calcul clairement + explicitée, il s'agira donc de la déduire des autres valeurs renseignées. - Voilà comment ça marche : on va donner à la variable une valeur au hasard, - calculer _l'objectif_, puis grâce à des calculs savants améliorer notre - choix jusqu'à ce que l'écart entre le calcul et la valeur cible devienne - satisfaisant. - Concrètement, si l'on demande au moteur (même indirectement) la valeur d'une - variable qui a pour formule une inversion, il va vérifier qu'une des - possibilités d'inversion a bien une valeur calculée ou saisie, et procéder à - l'inversion décrite plus haut à partir de celle-ci. Sinon, ces possibilités - d'inversions seront listées comme manquantes. + De façon simplifiée, il s'agira donc, à partir d'une règle existante + explicitant `y = ƒ(x)` de calculer `x` à partir de `y`. + + + L'inversion numérique permet d'estimer la valeur de la variable en question + au plus près à partir d'un des _objectifs_, listés dans la propriété `avec`. + Il faut alors renseigner une valeur cible pour ces objectifs. + + + L'algorithme utilisé est la [méthode de + Brent](https://fr.wikipedia.org/wiki/M%C3%A9thode_de_Brent). L'idée générale + est de prendre une valeur au hasard pour la variable en question, et + d'améliorer mathématiquement le choix jusqu'à ce que les valeurs cibles + soient toutes suffisamment proches des objectifs + + + Si on demande au moteur la valeur d'une variable qui a pour formule une + inversion, il va vérifier qu'une des variables `avec` a bien une valeur + (calculée ou saisie), et procéder à l'inversion décrite plus haut à partir + de celle-ci. Sinon, ces possibilités d'inversions seront listées comme + manquantes.