🖋️ Améliore la page de documentation de publicode
- Ajoute le tuto - Rend tous les exemples executablespull/945/head
parent
815ff255ee
commit
0f1ca13b7f
|
@ -1,5 +1,5 @@
|
|||
// Page listing the engine's currently implemented mecanisms and their tests
|
||||
import knownMecanims from 'Engine/known-mecanisms.yaml'
|
||||
import mécanismes from 'Engine/mecanisms.yaml'
|
||||
import { fromPairs, has, toPairs } from 'ramda'
|
||||
import React from 'react'
|
||||
import './Mecanisms.css'
|
||||
|
@ -24,7 +24,7 @@ export default function Mecanisms() {
|
|||
partageant le code de mecanisms.test.js
|
||||
</p>
|
||||
<ul id="mecanisms">
|
||||
{toPairs(knownMecanims).map(([name, data]) => (
|
||||
{toPairs(mécanismes).map(([name, data]) => (
|
||||
<li key={name}>
|
||||
{name}
|
||||
{suites[name] == null ? (
|
||||
|
|
|
@ -1,11 +0,0 @@
|
|||
import React from 'react'
|
||||
import { Light as SyntaxHighlighter } from 'react-syntax-highlighter'
|
||||
import yaml from 'react-syntax-highlighter/dist/cjs/languages/hljs/yaml'
|
||||
import style from 'react-syntax-highlighter/dist/cjs/styles/hljs/tomorrow'
|
||||
SyntaxHighlighter.registerLanguage('yaml', yaml)
|
||||
|
||||
export default ({ source }) => (
|
||||
<SyntaxHighlighter language="yaml" style={style}>
|
||||
{source}
|
||||
</SyntaxHighlighter>
|
||||
)
|
|
@ -1,7 +1,7 @@
|
|||
import { ThemeColorsContext } from 'Components/utils/colors'
|
||||
import { SitePathsContext } from 'Components/utils/withSitePaths'
|
||||
import Value from 'Components/Value'
|
||||
import knownMecanisms from 'Engine/known-mecanisms.yaml'
|
||||
import mecanisms from 'Engine/mecanisms.yaml'
|
||||
import { findRuleByDottedName, findRuleByNamespace } from 'Engine/rules'
|
||||
import { isEmpty } from 'ramda'
|
||||
import React, { Suspense, useContext, useState } from 'react'
|
||||
|
@ -28,7 +28,7 @@ import './Rule.css'
|
|||
|
||||
let LazySource = React.lazy(() => import('./RuleSource'))
|
||||
|
||||
export default AttachDictionary(knownMecanisms)(function Rule({ dottedName }) {
|
||||
export default AttachDictionary(mecanisms)(function Rule({ dottedName }) {
|
||||
const currentExample = useSelector(state => state.currentExample)
|
||||
const flatRules = useSelector(flatRulesSelector)
|
||||
const valuesToShow = !useSelector(noUserInputSelector)
|
||||
|
|
|
@ -3,7 +3,7 @@ import rules from 'Publicode/rules'
|
|||
import React from 'react'
|
||||
import emoji from 'react-easy-emoji'
|
||||
import { Rule } from 'Types/rule'
|
||||
import ColoredYaml from './ColoredYaml'
|
||||
import PublicodeHighlighter from '../ui/PublicodeHighlighter'
|
||||
|
||||
type RuleSourceProps = Pick<Rule, 'dottedName'>
|
||||
|
||||
|
@ -17,7 +17,7 @@ export default function RuleSource({ dottedName }: RuleSourceProps) {
|
|||
Code source <br />
|
||||
<code>{dottedName}</code>
|
||||
</h2>
|
||||
<ColoredYaml source={safeDump(source)} />
|
||||
<PublicodeHighlighter source={safeDump(source)} />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
|
|
@ -0,0 +1,21 @@
|
|||
import React from 'react'
|
||||
import emoji from 'react-easy-emoji'
|
||||
import { PrismLight as SyntaxHighlighter } from 'react-syntax-highlighter'
|
||||
import yaml from 'react-syntax-highlighter/dist/esm/languages/prism/yaml'
|
||||
import style from 'react-syntax-highlighter/dist/esm/styles/prism/atom-dark'
|
||||
|
||||
SyntaxHighlighter.registerLanguage('yaml', yaml)
|
||||
|
||||
export default ({ source }) => (
|
||||
<div css="position: relative; margin-bottom: 1rem">
|
||||
<SyntaxHighlighter language="yaml" style={style}>
|
||||
{source}
|
||||
</SyntaxHighlighter>
|
||||
<a
|
||||
href={`https://publi.codes/studio?code=${encodeURIComponent(source)}`}
|
||||
css="position: absolute; bottom: 5px; right: 10px; color: white !important;"
|
||||
>
|
||||
{emoji('⚡')} Lancer le calcul
|
||||
</a>
|
||||
</div>
|
||||
)
|
|
@ -31,10 +31,11 @@ button {
|
|||
|
||||
blockquote {
|
||||
background: var(--lighterColor);
|
||||
border-radius: 0.6em;
|
||||
padding: 1.2em 1em 0.4em;
|
||||
margin: 0.6em;
|
||||
color: #333;
|
||||
border-radius: 0.3rem;
|
||||
padding: 1rem;
|
||||
padding-bottom: 0.6rem;
|
||||
margin: 1rem 0;
|
||||
color: var(--darkerColor);
|
||||
}
|
||||
|
||||
.ui__.answer-group {
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
import PublicodeHighlighter from 'Components/ui/PublicodeHighlighter'
|
||||
import React from 'react'
|
||||
import emoji from 'react-easy-emoji'
|
||||
import ReactMarkdown, { ReactMarkdownProps } from 'react-markdown'
|
||||
|
@ -31,6 +32,15 @@ type MarkdownProps = ReactMarkdownProps & {
|
|||
className?: string
|
||||
}
|
||||
|
||||
const CodeBlock = ({ value, language }) =>
|
||||
language === 'yaml' ? (
|
||||
<PublicodeHighlighter source={value} />
|
||||
) : (
|
||||
<pre>
|
||||
<code>{value}</code>
|
||||
</pre>
|
||||
)
|
||||
|
||||
export const Markdown = ({
|
||||
source,
|
||||
className = '',
|
||||
|
@ -40,7 +50,12 @@ export const Markdown = ({
|
|||
<ReactMarkdown
|
||||
source={source}
|
||||
className={`markdown ${className}`}
|
||||
renderers={{ link: LinkRenderer, text: TextRenderer, ...renderers }}
|
||||
renderers={{
|
||||
link: LinkRenderer,
|
||||
text: TextRenderer,
|
||||
code: CodeBlock,
|
||||
...renderers
|
||||
}}
|
||||
{...otherProps}
|
||||
/>
|
||||
)
|
||||
|
|
|
@ -1,16 +1,29 @@
|
|||
# Publicode
|
||||
|
||||
Publicode est un langage déclaratif pour encoder les algorithmes d'intérêt
|
||||
public. Il permet de réaliser des calculs généraux tout en fournissant une
|
||||
explication permettant de comprendre et de documenter ces calculs.
|
||||
|
||||
Publicode est adapté pour modéliser des domaines métiers complexes pouvant être
|
||||
décomposés en règles élémentaires simples (comme la législation socio-fiscale,
|
||||
un bilan carbone, un estimateur de rendement locatif, etc.). Il permet de
|
||||
décomposés en règles élémentaires simples (comme la [législation socio-fiscale](https://github.com/betagouv/mon-entreprise/tree/master/publicode),
|
||||
[un bilan carbone](https://github.com/laem/futureco-data/blob/master/co2.yaml),
|
||||
un estimateur de rendement locatif, etc.).
|
||||
|
||||
Il permet de
|
||||
générer facilement des simulateurs web interactifs où l'on peut affiner
|
||||
progressivement le résultat affiché, et explorer une documentation du calcul.
|
||||
|
||||
## Formule basiques
|
||||
## Projets phares
|
||||
|
||||
- [mon-entreprise.fr](https://mon-entreprise.fr/simulateurs) : utilise publicode
|
||||
pour spécifier l'ensemble des calculs relatifs à la législation socio-fiscale
|
||||
en France. Le site permet entre autre de simuler une fiche de paie complète,
|
||||
de calculer les cotisations sociales pour un indépendant ou encore connaître
|
||||
le montant du chômage partiel. Les règles sont publiées sous la forme d'une
|
||||
[bibliothèque de calcul autonome](https://mon-entreprise.fr/intégration/bibliothèque-de-calcul), libre de droit.
|
||||
|
||||
- [futur.eco](https://futur.eco/) utilise publicode pour calculer les bilans
|
||||
carbone d'un grand nombre d'activité, plats, transport ou biens.
|
||||
|
||||
## 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
|
||||
|
@ -32,8 +45,6 @@ prix total:
|
|||
formule: 5 * prix d'un repas
|
||||
```
|
||||
|
||||
> [Lancer le calcul](https://publi.codes/studio?code=prix%20d'un%20repas%3A%0A%20%20formule%3A%2010%0A%0Aprix%20total%3A%0A%20%20formule%3A%205%20*%20prix%20d'un%20repas)
|
||||
|
||||
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.
|
||||
|
||||
|
@ -53,12 +64,12 @@ prix total:
|
|||
formule: nombre de repas * prix d'un repas
|
||||
```
|
||||
|
||||
> [Lancer le calcul](https://publi.codes/studio?code=prix%20d'un%20repas%3A%0A%20%20formule%3A%2010%20%E2%82%AC%2Frepas%0A%0Anombre%20de%20repas%3A%0A%20%20formule%3A%205%20repas%0A%0Aprix%20total%3A%0A%20%20formule%3A%20nombre%20de%20repas%20*%20prix%20d'un%20repas)
|
||||
|
||||
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
|
||||
`€`)
|
||||
|
||||
Ce système d'unité permet de typer les formules de calcul et de rejeter
|
||||
automatiquement des formules incohérentes :
|
||||
|
||||
```yaml
|
||||
|
@ -77,8 +88,6 @@ prix total:
|
|||
# La formule de "prix total" est invalide.
|
||||
```
|
||||
|
||||
> [Lancer le calcul](https://publi.codes/studio?code=prix%20d'un%20repas%3A%0A%20%20formule%3A%2010%20%E2%82%AC%2Frepas%0A%0Anombre%20de%20repas%3A%0A%20%20formule%3A%205%20repas%0A%0Afrais%20de%20r%C3%A9servation%3A%0A%20%20formule%3A%201%20%E2%82%AC%2Frepas%0A%0Aprix%20total%3A%0A%20%20formule%3A%20nombre%20de%20repas%20*%20prix%20d'un%20repas%20%2B%20frais%20de%20r%C3%A9servation)
|
||||
|
||||
Dans l'exemple ci-dessus Publicode 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`. Comme dans les formules de Physique, cette incohérence d'unité
|
||||
|
@ -90,10 +99,37 @@ prix total:
|
|||
formule: nombre de repas * (prix d'un repas + frais de réservation)
|
||||
```
|
||||
|
||||
> [Lancer le calcul](<https://publi.codes/studio?code=prix%20d'un%20repas%3A%0A%20%20formule%3A%2010%20%E2%82%AC%2Frepas%0A%0Anombre%20de%20repas%3A%0A%20%20formule%3A%205%20repas%0A%0Afrais%20de%20r%C3%A9servation%3A%0A%20%20formule%3A%201%20%E2%82%AC%2Frepas%0A%0Aprix%20total%3A%0A%20%20formule%3A%20nombre%20de%20repas%20*%20(prix%20d'un%20repas%20%2B%20frais%20de%20r%C3%A9servation)>)
|
||||
> **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`
|
||||
|
||||
> **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`
|
||||
### Conversion
|
||||
|
||||
Publicode converti automatiquement les unités si besoin.
|
||||
|
||||
```yaml
|
||||
salaire:
|
||||
formule: 1500 €/mois
|
||||
|
||||
prime faible salaire:
|
||||
applicable si: salaire < 20 k€/an
|
||||
formule: 300€
|
||||
```
|
||||
|
||||
On peut forcer la conversion des unités via la propriété `unité`, ou la notation suffixé `[...]`
|
||||
|
||||
```yaml
|
||||
salaire:
|
||||
unité: €/mois
|
||||
formule: 3200
|
||||
|
||||
salaire annuel:
|
||||
formule: salaire [k€/an]
|
||||
```
|
||||
|
||||
**Conversions disponibles :**
|
||||
|
||||
- `mois` / `année` / `jour`
|
||||
- `€` / `k€`
|
||||
|
||||
## Titre, description et références
|
||||
|
||||
|
@ -149,25 +185,34 @@ spécifique par mécanisme.
|
|||
Par exemple on a un mécanisme `barème`:
|
||||
|
||||
```yaml
|
||||
revenu imposable:
|
||||
formule: 54126 €
|
||||
|
||||
impôt sur le revenu:
|
||||
formule:
|
||||
barème:
|
||||
assiette: revenu imposable
|
||||
tranches:
|
||||
- taux: 0%
|
||||
plafond: 9807
|
||||
plafond: 9807 €
|
||||
- taux: 14%
|
||||
plafond: 27086
|
||||
plafond: 27086 €
|
||||
- taux: 30%
|
||||
plafond: 72617
|
||||
plafond: 72617 €
|
||||
- taux: 41%
|
||||
plafond: 153783
|
||||
plafond: 153783 €
|
||||
- taux: 45%
|
||||
```
|
||||
|
||||
La syntaxe hiérarchique de Yaml permet d'imbriquer les mécanismes :
|
||||
|
||||
```yaml
|
||||
prime . fixe:
|
||||
formule: 1000€
|
||||
|
||||
prime . taux du bonus:
|
||||
formule: 20%
|
||||
|
||||
prime:
|
||||
formule:
|
||||
somme:
|
||||
|
@ -175,15 +220,9 @@ prime:
|
|||
- produit:
|
||||
assiette: fixe
|
||||
taux: taux du bonus
|
||||
|
||||
prime . fixe:
|
||||
formule: 1000€
|
||||
|
||||
prime . taux du bonus:
|
||||
formule: 20%
|
||||
```
|
||||
|
||||
**[Voir la liste des mécanismes](https://github.com/betagouv/mon-entreprise/blob/master/publicode/mecanism.md)**
|
||||
**[Voir la liste des mécanismes existants](/mécanismes)**
|
||||
|
||||
## Applicabilité
|
||||
|
||||
|
@ -204,8 +243,6 @@ prime de vacances:
|
|||
formule: 200€
|
||||
```
|
||||
|
||||
> [Lancer le calcul](https://publi.codes/studio?code=date%20de%20d%C3%A9but%3A%20%0A%20%20formule%3A%2012%2F02%2F2020%0A%20%20%0Aanciennet%C3%A9%20en%20fin%20d'ann%C3%A9e%3A%0A%20%20formule%3A%20%0A%20%20%20%20dur%C3%A9e%3A%0A%20%20%20%20%20%20%20depuis%3A%20date%20de%20d%C3%A9but%0A%20%20%20%20%20%20%20jusqu'%C3%A0%3A%2031%2F12%2F2020%0A%0Aprime%20de%20vacances%3A%0A%20%20applicable%20si%3A%20anciennet%C3%A9%20en%20fin%20d'ann%C3%A9e%20%3E%201%20an%0A%20%20formule%3A%20200%E2%82%AC)
|
||||
|
||||
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
|
|
@ -1,219 +0,0 @@
|
|||
# Liste et description des différents mécanismes compris par le moteur.
|
||||
# La description peut être rédigée en markdown :-)
|
||||
|
||||
une possibilité:
|
||||
type: enum
|
||||
|
||||
inversion numérique:
|
||||
type: numeric
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
une de ces conditions:
|
||||
type: boolean
|
||||
description: |
|
||||
C'est un `ou` logique.
|
||||
|
||||
Contient une liste de conditions.
|
||||
|
||||
Renvoie vrai si l'une des conditions est vraie.
|
||||
toutes ces conditions:
|
||||
type: boolean
|
||||
description: |
|
||||
C'est un `et` logique.
|
||||
|
||||
Contient une liste de conditions.
|
||||
|
||||
Renvoie vrai si toutes les conditions vraies.
|
||||
|
||||
variations:
|
||||
type: numeric
|
||||
description: |
|
||||
Contient une liste de conditions (`si`) et leurs conséquences associées (`alors`).
|
||||
|
||||
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`
|
||||
|
||||
|
||||
Exemple:
|
||||
```
|
||||
- si: age < 18 ans
|
||||
alors: 'mineur'
|
||||
- sinon: 'majeur'
|
||||
```
|
||||
|
||||
Ce mécanisme peut aussi être utilisé au sein d'un mécanisme compatible, tel que la produit ou le barème.
|
||||
|
||||
Exemple (TVA):
|
||||
```
|
||||
produit:
|
||||
assiette: total hors taxe
|
||||
variations:
|
||||
- si: restauration
|
||||
alors:
|
||||
taux: 10%
|
||||
- sinon:
|
||||
taux: 20%
|
||||
```
|
||||
|
||||
produit:
|
||||
type: numeric
|
||||
description: |
|
||||
C'est une multiplication un peu améliorée, très utile pour exprimer les cotisations.
|
||||
|
||||
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 deuxième au taux nul et allant de `plafond` à l'infini.
|
||||
|
||||
le maximum de:
|
||||
type: numeric
|
||||
description: |
|
||||
Renvoie la valeur numérique de la liste de propositions fournie qui est la plus grande.
|
||||
|
||||
Il est conseillé de renseigner une description de chaque proposition par exemple quand elles représentent des méthodes de calcul alternatives.
|
||||
|
||||
le minimum de:
|
||||
type: numeric
|
||||
description: |
|
||||
Renvoie l'élément de la liste de propositions fournie qui a la plus petite valeur.
|
||||
|
||||
Ces propositions doivent avoir un mécanisme de calcul ou être une valeur numérique.
|
||||
|
||||
Il est conseillé de renseigner une description de chaque proposition par exemple quand elles représentent des méthodes de calcul alternatives parmi lesquelles il faut en choisir une.
|
||||
|
||||
somme:
|
||||
type: numeric
|
||||
description: |
|
||||
C'est tout simplement la somme de chaque terme de la liste.
|
||||
|
||||
arrondi:
|
||||
type: numeric
|
||||
description: |
|
||||
On arrondi à l'euro le plus proche
|
||||
|
||||
recalcul:
|
||||
type: numeric
|
||||
description: >-
|
||||
Relance le calcul d'une règle dans une situation différente de la situation
|
||||
courante. Permet par exemple de calculer le montant des cotisations au
|
||||
niveau du SMIC, même si le salaire est plus élevé dans la situation
|
||||
actuelle.
|
||||
|
||||
##########################################
|
||||
# Ce qu'on appelle aujourd'hui des RuleProp
|
||||
# Et qui deviendront des mécanismes classiques normalement par la suite #TODO
|
||||
|
||||
formule:
|
||||
description: |
|
||||
C'est la formule de calcul d'une variable. Elle renvoie une valeur numérique ou un 'non', exprimant le fait que la variable n'est pas applicable, ce qui vaut implicitement 0.
|
||||
|
||||
Cette doit faire appel à fera appel à des mécanismes de calcul : par exemple `produit`, le plus commun pour les variables de type `Cotisation`.
|
||||
|
||||
applicable si:
|
||||
description: |
|
||||
Décide si la règle est applicable pour la situation saisie.
|
||||
|
||||
> Une cotisation sociale peut ne concerner que les salariés au statut cadre. Elle ne sera pas à verser pour un non cadre
|
||||
|
||||
La formule de calcul peut donc être ignorée, quel que soit son montant.
|
||||
|
||||
Peut être accompagnée du mécanisme 'non applicable si'.
|
||||
|
||||
non applicable si:
|
||||
description: |
|
||||
Décide si la règle n'est applicable pour la situation saisie.
|
||||
|
||||
> Un contrat CDD peut entraîner une majoration spécifique. Cette majoration est 'non applicable si' le contrat est un CDI.
|
||||
|
||||
La formule de calcul peut donc être ignorée, quel que soit son montant.
|
||||
|
||||
Peut être accompagnée du mécanisme 'applicable si'.
|
||||
|
||||
rend non applicable:
|
||||
description: |
|
||||
Permet de désactiver l'application de certaines règles pour la situation saisie.
|
||||
|
||||
> Ce mécanisme est utile pour encoder les régimes d'exceptions (par exemple le [régime des impatriés](/documentation/contrat-salarié/régime-des-impatriés)) sans avoir à modifier la définition des règles de base.
|
||||
|
||||
barème:
|
||||
type: numeric
|
||||
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.
|
||||
|
||||
L'assiette est décomposée en plusieurs tranches, qui sont multipliées par un
|
||||
taux spécifique.
|
||||
|
||||
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`.
|
||||
|
||||
grille:
|
||||
type: numeric
|
||||
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é.
|
||||
|
||||
Il est composé de tranches qui se suivent. Il suffit de trouver l'assiette
|
||||
qui correspond à la tranche, et de selectionner le montant associé à
|
||||
l'assiette.
|
||||
|
||||
taux progressif:
|
||||
type: numeric
|
||||
description: >-
|
||||
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
|
||||
|
||||
> 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.
|
||||
|
||||
composantes:
|
||||
type: numeric
|
||||
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.
|
||||
|
||||
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 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).
|
||||
|
||||
allègement:
|
||||
type: numeric
|
||||
description: |
|
||||
Permet de réduire le montant d'une variable.
|
||||
Très utilisé dans le contexte des impôts.
|
||||
|
||||
encadrement:
|
||||
type: numeric
|
||||
description: |
|
||||
Permet d'ajouter un plafond et/ou un plancher à une valeur.
|
||||
|
||||
durée:
|
||||
type: numeric
|
||||
description: |
|
||||
Permet d'obtenir le nombre de jours entre deux dates
|
||||
|
||||
synchronisation:
|
||||
type: object
|
||||
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 géo, qui permet à
|
||||
partir du nom d'une ville, d'obtenir son code postal, son département, la
|
||||
population etc.
|
||||
|
||||
Ce mécanismes `synchronisation` permet de faire le lien entre les règles de
|
||||
notre système et les réponses de ces API.
|
|
@ -2,33 +2,11 @@ import { decompose } from 'Engine/mecanisms/utils'
|
|||
import variations from 'Engine/mecanisms/variations'
|
||||
import { convertNodeToUnit } from 'Engine/nodeUnits'
|
||||
import { inferUnit, isPercentUnit } from 'Engine/units'
|
||||
import {
|
||||
any,
|
||||
equals,
|
||||
evolve,
|
||||
is,
|
||||
map,
|
||||
max,
|
||||
mergeWith,
|
||||
min,
|
||||
path,
|
||||
pluck,
|
||||
reduce,
|
||||
toPairs
|
||||
} from 'ramda'
|
||||
import { any, equals, evolve, is, map, max, mergeWith, min, path, pluck, reduce, toPairs } from 'ramda'
|
||||
import React from 'react'
|
||||
import 'react-virtualized/styles.css'
|
||||
import { typeWarning } from './error'
|
||||
import {
|
||||
collectNodeMissing,
|
||||
defaultNode,
|
||||
evaluateArray,
|
||||
evaluateNode,
|
||||
evaluateObject,
|
||||
makeJsx,
|
||||
mergeAllMissing,
|
||||
parseObject
|
||||
} from './evaluation'
|
||||
import { collectNodeMissing, defaultNode, evaluateArray, evaluateNode, evaluateObject, makeJsx, mergeAllMissing, parseObject } from './evaluation'
|
||||
import Allègement from './mecanismViews/Allègement'
|
||||
import { Node, SimpleRuleLink } from './mecanismViews/common'
|
||||
import InversionNumérique from './mecanismViews/InversionNumérique'
|
||||
|
@ -463,7 +441,7 @@ export let mecanismReduction = (recurse, k, v) => {
|
|||
|
||||
export let mecanismProduct = (recurse, k, v) => {
|
||||
if (v.composantes) {
|
||||
//mécanisme de composantes. Voir known-mecanisms.md/composantes
|
||||
//mécanisme de composantes. Voir mécanismes.md/composantes
|
||||
return decompose(recurse, k, v)
|
||||
}
|
||||
if (v.variations) {
|
||||
|
|
|
@ -0,0 +1,308 @@
|
|||
une de ces conditions:
|
||||
description: >-
|
||||
C'est un `ou` logique.
|
||||
Contient une liste de conditions.
|
||||
Renvoie vrai si l'une des conditions est applicable.
|
||||
retourne: Booléen
|
||||
exemples:
|
||||
base:
|
||||
age:
|
||||
formule: 17 ans
|
||||
mineur émancipé:
|
||||
formule: oui
|
||||
peut voter:
|
||||
formule:
|
||||
une de ces conditions:
|
||||
- age > 18 ans
|
||||
- mineur émancipé
|
||||
|
||||
toutes ces conditions:
|
||||
description: >-
|
||||
C'est un `et` logique.
|
||||
Contient une liste de conditions.
|
||||
Renvoie vrai si toutes les conditions sont applicables.
|
||||
argument:
|
||||
- '*'
|
||||
- ...
|
||||
|
||||
produit:
|
||||
description: >-
|
||||
C'est une multiplication un peu améliorée, très utile pour exprimer les
|
||||
cotisations.
|
||||
|
||||
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
|
||||
deuxième au taux nul et allant de `plafond` à l'infini.
|
||||
argument:
|
||||
assiette: Valeur à multiplier
|
||||
taux: Taux à appliquer
|
||||
facteur: Facteur multiplicatif
|
||||
plafond: Plafond au dessus duquel le taux appliqué est nul
|
||||
|
||||
exemples:
|
||||
base:
|
||||
cotisation:
|
||||
formule:
|
||||
produit:
|
||||
assiette: 2000 €/mois
|
||||
taux: 5%
|
||||
|
||||
assiette plafonnée:
|
||||
plafond sécurité sociale:
|
||||
formule: 3000 €/mois
|
||||
assiette cotisation:
|
||||
formule: 15000 €/mois
|
||||
chômage:
|
||||
formule:
|
||||
produit:
|
||||
assiette: assiette cotisation
|
||||
plafond: 400% * plafond sécurité sociale
|
||||
taux: 4%
|
||||
|
||||
variations:
|
||||
description: >-
|
||||
Contient une liste de conditions (`si`) et leurs conséquences associées
|
||||
(`alors`).
|
||||
|
||||
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.
|
||||
arguments:
|
||||
- si: condition à vérifier
|
||||
alors: consequence évaluée si la condition est vrai
|
||||
- ...
|
||||
- sinon: consequence évaluée si aucune des conditions précédente n'était applicable
|
||||
exemples:
|
||||
base:
|
||||
taux réduit:
|
||||
formule: oui
|
||||
|
||||
taux allocation familiales:
|
||||
formule:
|
||||
variations:
|
||||
- si: taux réduit
|
||||
alors: 3.45%
|
||||
- sinon: 5.25%
|
||||
|
||||
dans un produit:
|
||||
assiette cotisation:
|
||||
formule: 2300 €/mois
|
||||
|
||||
taux réduit:
|
||||
formule: oui
|
||||
|
||||
allocation familiales:
|
||||
formule:
|
||||
produit:
|
||||
assiette: assiette cotisation
|
||||
variations:
|
||||
- si: taux réduit
|
||||
alors:
|
||||
taux: 3.45%
|
||||
- sinon:
|
||||
taux: 5.25%
|
||||
|
||||
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.
|
||||
|
||||
On peut aussi retrancher des valeurs avec l'opérateur unaire `-`
|
||||
arguments:
|
||||
- '*'
|
||||
- ...
|
||||
|
||||
exemples:
|
||||
base:
|
||||
somme:
|
||||
- 15.89 €
|
||||
- 12% * 14 €
|
||||
- (-30 €)
|
||||
terme non applicable:
|
||||
a:
|
||||
formule: 50 €
|
||||
b:
|
||||
applicable si: non
|
||||
formule: 20 €
|
||||
somme:
|
||||
formule:
|
||||
somme:
|
||||
- a
|
||||
- b
|
||||
- 40 €
|
||||
|
||||
le maximum de:
|
||||
description: >-
|
||||
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`.
|
||||
|
||||
le minimum de:
|
||||
description: >-
|
||||
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`.
|
||||
|
||||
arrondi:
|
||||
description: >-
|
||||
Arrondi à l'entier le plus proche, ou à une précision donnée.
|
||||
exemples:
|
||||
base:
|
||||
arrondi:
|
||||
formule:
|
||||
arrondi:
|
||||
valeur: 12.45
|
||||
décimales: 1
|
||||
|
||||
régularisation:
|
||||
description: >-
|
||||
Permet de régulariser progressivement un calcul de cotisation en fonction de
|
||||
variables numérique mensuelle cumulée.
|
||||
|
||||
Ce mécanisme spécifique est utilisé pour le calcul des cotisations
|
||||
mensuelles.
|
||||
|
||||
arguments:
|
||||
règle: règle à régulariser
|
||||
valeurs cumulées:
|
||||
- liste de variables cumulée mensuellement pour calculer la régularisation. Doit être
|
||||
numérique, et avoir une unité `/mois`
|
||||
|
||||
exemples:
|
||||
base:
|
||||
brut:
|
||||
formule:
|
||||
somme:
|
||||
- 2000 €/mois | du 01/01/2020 | au 31/05/2020
|
||||
- 4000 €/mois | du 01/06/2020 | au 31/12/2020
|
||||
plafond:
|
||||
formule: 3000 €/mois
|
||||
|
||||
cotisation:
|
||||
formule:
|
||||
régularisation:
|
||||
règle:
|
||||
produit:
|
||||
assiette: brut
|
||||
plafond: plafond
|
||||
taux: 10%
|
||||
valeurs cumulées:
|
||||
- brut
|
||||
- plafond
|
||||
|
||||
cotisation en mai:
|
||||
formule: cotisation | du 01/05/2020 | au 31/05/2020
|
||||
|
||||
cotisation en juin:
|
||||
formule: cotisation | du 01/06/2020 | au 30/06/2020
|
||||
|
||||
cotisation en novembre:
|
||||
formule: cotisation | du 01/11/2020 | au 30/11/2020
|
||||
|
||||
recalcul:
|
||||
description: >-
|
||||
Relance le calcul d'une règle dans une situation différente de la situation
|
||||
courante. Permet par exemple de calculer le montant des cotisations au niveau du
|
||||
SMIC, même si le salaire est plus élevé dans la situation actuelle.
|
||||
|
||||
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.
|
||||
|
||||
L'assiette est décomposée en plusieurs tranches, qui sont multipliées par un
|
||||
taux spécifique.
|
||||
|
||||
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`.
|
||||
|
||||
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é.
|
||||
|
||||
Il est composé de tranches qui se suivent. Il suffit de trouver l'assiette
|
||||
qui correspond à la tranche, et de selectionner le montant associé à
|
||||
l'assiette.
|
||||
|
||||
taux progressif:
|
||||
description: >-
|
||||
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
|
||||
|
||||
> 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.
|
||||
|
||||
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.
|
||||
|
||||
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
|
||||
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).
|
||||
|
||||
allègement:
|
||||
description: >-
|
||||
Permet de réduire le montant d'une variable.
|
||||
Très utilisé dans le contexte des impôts.
|
||||
|
||||
encadrement:
|
||||
description: Permet d'ajouter un plafond et/ou un plancher à une valeur.
|
||||
|
||||
durée:
|
||||
description: Permet d'obtenir le nombre de jours entre deux dates
|
||||
|
||||
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 géo, qui permet à
|
||||
partir du nom d'une ville, d'obtenir son code postal, son département, la
|
||||
population etc.
|
||||
|
||||
Ce mécanismes `synchronisation` permet de faire le lien entre les règles de
|
||||
notre système et les réponses de ces API.
|
||||
|
||||
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.
|
||||
|
||||
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.
|
|
@ -20,7 +20,7 @@ export default function parse(parse, k, v) {
|
|||
// Barème en taux marginaux.
|
||||
|
||||
if (v.composantes) {
|
||||
//mécanisme de composantes. Voir known-mecanisms.md/composantes
|
||||
//mécanisme de composantes. Voir mécanismes.md/composantes
|
||||
return decompose(parse, k, v)
|
||||
}
|
||||
if (v.variations) {
|
||||
|
|
|
@ -17,7 +17,7 @@ import {
|
|||
|
||||
export default function parse(parse, k, v) {
|
||||
if (v.composantes) {
|
||||
//mécanisme de composantes. Voir known-mecanisms.md/composantes
|
||||
//mécanisme de composantes. Voir mécanismes.md/composantes
|
||||
return decompose(parse, k, v)
|
||||
}
|
||||
if (v.variations) {
|
||||
|
|
|
@ -11,7 +11,7 @@ import {
|
|||
|
||||
export default function parse(parse, k, v) {
|
||||
if (v.composantes) {
|
||||
//mécanisme de composantes. Voir known-mecanisms.md/composantes
|
||||
//mécanisme de composantes. Voir mécanismes.md/composantes
|
||||
return decompose(parse, k, v)
|
||||
}
|
||||
if (v.variations) {
|
||||
|
|
|
@ -19,7 +19,7 @@ export const Header = ({ noSubtitle, sectionName = '' }) => (
|
|||
</Link>
|
||||
{!noSubtitle && (
|
||||
<p css="max-width: 28rem; margin: 0 auto; font-size: 120%">
|
||||
Un nouveau langage pour les algorithmes d'intérêt public.
|
||||
Le langage pour les algorithmes d'intérêt public.
|
||||
</p>
|
||||
)}
|
||||
</header>
|
||||
|
|
|
@ -1,9 +1,6 @@
|
|||
import exemple1 from '!!raw-loader!./exemples/bareme-ir.yaml'
|
||||
import exemple2 from '!!raw-loader!./exemples/douche.yaml'
|
||||
import ColoredYaml from 'Components/rule/ColoredYaml'
|
||||
import { Markdown } from 'Components/utils/markdown'
|
||||
import publicodeReadme from 'Engine/README.md'
|
||||
import React, { useEffect } from 'react'
|
||||
import emoji from 'react-easy-emoji'
|
||||
import { Link } from 'react-router-dom'
|
||||
import { Header } from './Header'
|
||||
|
||||
export default function Landing() {
|
||||
|
@ -21,67 +18,11 @@ export default function Landing() {
|
|||
document.body.appendChild(css)
|
||||
})
|
||||
return (
|
||||
<div className="app-content ui__ container" css="margin-bottom: 2rem">
|
||||
<div className="app-content ui__ container" css="margin: 2rem 0">
|
||||
<Header />
|
||||
<h2>Pourquoi ?</h2>
|
||||
<p>
|
||||
Certains algorithmes sont bien trop importants pour être maintenus dans
|
||||
une boîte noire, souvent privée, que seuls les développeurs expérimentés
|
||||
peuvent comprendre.
|
||||
</p>
|
||||
<p>
|
||||
{' '}
|
||||
C'est notamment le cas d'une bonne partie de la loi, qui spécifie en
|
||||
français des règles... et charge à d'autres de les implémenter
|
||||
librement.
|
||||
</p>
|
||||
<p>
|
||||
La plateforme <em>publicodes</em> fusionne documentation et
|
||||
implémentation en partant d'un code simple. Ajouter une règle de calcul,
|
||||
c'est déployer sans effort sur le Web la page de documentation
|
||||
correspondante, lisible par tout citoyen.
|
||||
</p>
|
||||
<br />
|
||||
<p>Pour aller plus loin:</p>
|
||||
<ul>
|
||||
<li>
|
||||
<a href="https://github.com/betagouv/publicodes/wiki">
|
||||
{emoji('📖 ')} Lire la documentation
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<Link to="/studio">⚡ Essayer le langage </Link>
|
||||
</li>
|
||||
</ul>
|
||||
<h2>Projets phares</h2>
|
||||
<h3>
|
||||
La sécurité sociale et les impôts -{' '}
|
||||
<a href="https://mon-entreprise.fr">mon-entreprise.fr</a>
|
||||
</h3>
|
||||
<div className="ui__ card">
|
||||
<ColoredYaml source={exemple1} />
|
||||
</div>
|
||||
<Link to="/studio?exemple=bareme-ir" className="ui__ button small">
|
||||
Lancer le calcul ⚡
|
||||
</Link>
|
||||
<p>
|
||||
En plus du site Web, Mon-entreprise est disponible comme une{' '}
|
||||
<a href="https://mon-entreprise.fr/intégration/bibliothèque-de-calcul">
|
||||
bibliothèque de calcul autonome
|
||||
</a>
|
||||
.
|
||||
</p>
|
||||
<h3>
|
||||
L'impact climatique de nos gestes du quotidien -
|
||||
<a href="https://futur.eco">futur.eco</a>
|
||||
</h3>
|
||||
<div className="ui__ card">
|
||||
<ColoredYaml source={exemple2} />
|
||||
</div>
|
||||
<Link to="/studio?exemple=douche" className="ui__ button small">
|
||||
Lancer le calcul ⚡
|
||||
</Link>
|
||||
<br />
|
||||
<Markdown source={publicodeReadme} />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
|
|
@ -134,6 +134,10 @@ module.exports.commonLoaders = ({ legacy = false } = {}) => {
|
|||
{
|
||||
test: /\.ne$/,
|
||||
use: [babelLoader, 'nearley-loader']
|
||||
},
|
||||
{
|
||||
test: /\.md$/,
|
||||
use: ['raw-loader']
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue