Refonte conceptuelle de l'écriture des règles

Changements majeurs : espaces de noms, variantes imbriquées.
Des notes en .md expliquent les changements, ou les changements à venir
même si l'implémentation est en retard.
Un peu plus d'ordre dans le dossier /règles : les 'entités' et règles
calculatoires se rapprochent...
pull/6/head
mama 2017-04-24 20:03:38 +02:00
parent 15141d5539
commit e030ed1e44
85 changed files with 1174 additions and 1430 deletions

15
brouillon Normal file
View File

@ -0,0 +1,15 @@
Séparer la définition de cotisation des entités.
https://cs.stackexchange.com/questions/45383/which-research-languages-have-a-stronger-typesystem-than-haskell-and-why
https://news.ycombinator.com/item?id=3117776
http://stackoverflow.com/questions/19081904/scala-difference-between-a-typeclass-and-an-adt
Learn you a Haskell define your own...
Ce que je fais c'est je définis des types qui sont des Records, mais de façon éclatée, ou des ADT (motif).
Et pour les listes ? Plusieurs contrat par individu ? Comment ils font en Haskell ?
Les cotisations sont des listes ?
Les namespaces ?
Et polymorphisme des record ?
Faudrait que je teste de coder ça en Haskell...

View File

@ -27,7 +27,7 @@
"react-router-dom": "^4.1.1",
"reduce-reducers": "^0.1.2",
"redux": "^3.6.0",
"redux-form": "^6.4.3",
"redux-form": "^6.6.3",
"redux-saga": "^0.14.3",
"reselect": "^2.5.2",
"whatwg-fetch": "^2.0.2"

View File

@ -0,0 +1,55 @@
Supposons qu'il y ait deux variables dans notre système.
```yaml
Variable: motif CDD
valeur:
une possibilité:
- motif B
- motif Z
- motif H
```
```yaml
Variable: CIF CDD
valeur:
multiplication:
assiette: salaire brut
taux: 29%
```
Si tu n'as pas à disposition la valeur de cette variable, le moteur peut utiliser la formule de la propriété `valeur` pour la calculer, _et_ s'il lui manque la valeur des dépendances (ex. pour 1. motif B, Z = `non` mais H = `null` donc inconnue; pour 2. salaire brut est `null`), il proposera un formulaire pour la récupérer.
### Demander les valeurs manquantes
Ajoutons un mécanisme à la formule 2.
```yaml
Variable: CIF CDD
formule:
non applicable si: motif H
multiplication:
assiette: salaire brut
taux: 29%
```
Pour la calculer, il nous faut maintenant la valeur de motif H, car elle n'est pas renseignée et donc cette variable n'est pas calculable : sa valeur est `null`. Comme dit précédemment, cela nous permet de proposer un formulaire de saisie à l'utilisateur :
```
Motif H est-il vrai pour vous ?
[Oui] [Non]
```
C'est une première étape, mais elle n'est pas parfaite : étant donné que `motif H` appartient à une liste de possibilités exclusives dans la variable `Motif CDD`, peut-être qu'il serait préférable de poser cette question :
```
Quel est votre motif ?
[Motif B] [Motif Z] [Motif H]
```
Le moteur doit pour cela vérifier si motif H intervient dans un mécanisme de type `une possibilité` pour construire son formulaire de saisie.
> la note "éclatement des variables et espaces de noms" continue en complexifiant de modèle.

View File

@ -0,0 +1,43 @@
Supposons que dans notre système, il y ait deux variables. C'est notre point de départ.
C'est un peu abstrait tout ça, mais ça permet de justifier certains choix de conception.
La première :
```yaml
Variable: motif CDD
contrainte:
une possibilité:
- motif B
- motif Z
- motif H
```
La deuxième :
```yaml
Variable: CIF CDD
formule de calcul:
multiplication:
assiette: salaire brut
taux: 29%
```
# Contrainte ou formule de calcul ?
Si tu veux renseigner directement la valeur de cette variable, la propriété `contrainte` cette propriété me permet de contraindre la saisie à 3 possibilités.
A l'opposé, la variable CIF CDD a une propriété `formule de calcul` qui nous donne un algorithme de calcul utile quand tu ne peux renseigner directement la valeur de la variable.
Mais en y regardant de plus près, le fait que cette formule soit exprimée sous forme de _donnée_ (facile à _parser_, déclaratif) nous permettraient potentiellement aussi de _contraindre_ la saisie de la valeur de la variable.
> implicitement, je contraint ton entrée à une valeur compatible avec le mécanisme multiplication. On pourrait même pousser jusqu'à vérifier que la valeur est compatible avec le domaine qu'autorise la multiplication (par exemple si on sait que l'assiette est toujours positive).
Et de même, le mécanisme `une possibilité` (et une seule) nous donne l'information suivant : si l'utilisateur a saisi `motif Z = oui`, alors motif CDD = motif Z. On retrouve donc une notion d'algorithme de calcul.
La frontière est floue entre `contrainte/type` et `formule de calcul`. On va donc pour l'instant utiliser une unique propriété, `valeur`, qui rassemble ces deux usages.
> Voir la note "des règles au formulaire"

View File

@ -0,0 +1,101 @@
> On atteint dans cette note le bout actuel de la réfléxion...
Pour l'instant, on n'avait considéré seulement des versions simplifiées des variables :
```yaml
Variable: CIF CDD
valeur:
multiplication:
assiette: salaire brut
taux: 29%
```
Or il y a pas mal de variables du système qui se ressembleront, et donc partageront des propriétés en commun.
Par exemples les cotisations, qui sont des obligations de verser une fraction du salaire à des organismes de protection sociale.
```yaml
activité . contrat salarié : AGIRC
description: AGIRC
références: article B-vingt-douze
dû par: salarié
branche: retraite
applicable si: Contrat . statut cadre
valeur:
multiplication:
assiette: ...
taux: ...
```
On peut remarquer que certaines des propriétés de cet objet sont relativement génériques, alors que d'autres dépendent directement du fait que notre objet est une cotisation. On pourrait la réécrire ainsi :
```yaml
activité . contrat salarié : AGIRC
meta:
description: AGIRC
références: article B-vingt-douze
cotisation:
dû par: salarié
branche: retraite
valeur:
applicable si: Contrat . statut cadre
multiplication:
assiette: ...
taux: ...
```
Finalement ici, on _renseigne_ les données d'une entité de type `Cotisation`. Tout comme quand on va fournir une situation au système, en renseignant les données d'un `Salarié` (âge, expérience...) et de son `Contrat` (appelé pour l'instant `Salariat`, qui a un salaire, ...) qui le lie à son `Entreprise` (effectif, ...).
Il faudra donc dans (TODO dans le futur) définir le _schéma_ de notre entité `Cotisation`. Pourquoi ne pas réutiliser ce que l'on a fait jusqu'à présent par exemple en définissant le schéma de `CDD . mofif` ?
```yaml
- entité: cotisation
# Ici on ajoute des propriétés à l'espace de nom `cotisation`.
# Comme si on créait et peuplait un _record_ en Haskell/Ocaml, ou encore d'un type produit en maths.
- cotisation: dû par
valeur:
# Ici, ce serait l'équivalent des _variant types_ des ADTs d'Haskell/Ocaml, ou d'une type somme en maths.
une possibilité:
- salarié
- entreprise
- cotisation . dû par: salarié
meta:
description: Les salariés ont l'obligation de verser des cotisations, mais c'est normalement l'employeur qui s'en charge.
# ...
- cotisation : branche
valeur:
une possibilité:
- maladie
- retraite
- ...
```
Il est très intéressant de noter qu'ici on définit le `schéma cotisation` pour pouvoir en faire des instance avec des données respectant ce schéma (cotisation.branche=maladie, etc.)... tout comme nous avons précédemment défini le `schéma contrat salarié` pour pouvoir par la suite en faire une instance avec des données (contrat salarié . type de contrat = CDD).
<!-- TODO est-ce clair ? -->
De la même façon que le schéma cotisation, on définirait le schéma de `meta`, qui ferait lui souvent appel à des types plus élémentaires (et "terminaux"), des _strings_ (chaines de caractères).
Pour être parfait, le modèle définirait aussi le schéma de `valeur`.
```yaml
- valeur : applicable si
type: # mécanisme ou variable de type booléen
- valeur : formule
type:
une possibilité: # mécanismes de type numérique
- multiplication
- barème
- ...
```
A ce stade, on aurait finalement besoin d'un langage de programmation complet (par exemple introduisant un certain polymorphisme : une cotisation et une indemnité partagent des propriété !), ce qui est un but non souhaitable pour le moment. `meta` et `valeur` peuvent dans un premier temps rester dynamiques (sans type bien défini) et types par leur implémentation en Javascript.

View File

@ -0,0 +1,119 @@
Supposons qu'il y ait deux variables dans notre système.
```yaml
Variable: motif CDD
valeur:
une possibilité:
- motif B
- motif Z
- motif H
```
```yaml
Variable: CIF CDD
valeur:
multiplication:
assiette: salaire brut
taux: 29%
```
Rapprochons-nous encore de la réalité. La formule de `motif CDD` est en fait une imbrication de possibilités :
```yaml
motif CDD:
- motif classique
- motif remplacement
- motif accroissement d'activité
- motif saisonnier
- motif contrat aidé
- motif complément formation
- motif issue d'apprentissage
```
Les formules d'autres variables, par exemple `indemnité fin de contrat` ou `CID CDD` peuvent alors dépendre des éléments de cette liste de possibilités imbriquées :
```yaml
formule:
non applicable si:
une de ces conditions:
- motif saisonnier
- motif contrat aidé # on cite une catégorie de motifs, mais qui est une variable utilisable en soi
```
Alors on pourrait représenter la variable `motif CDD` ainsi :
```yaml
Variable: motif CDD
formule:
une possibilité parmi:
- Variable: classique
formule:
une possibilité parmi:
- Variable: remplacement
titre: Contrat de remplacement
- Variable: usage
titre: Contrat d'usage
# formule...
- Variable: accroissement d'activité
titre: Motif accroissement temporaire d'activité
- Variable: contrat aidé
formule:
une possibilité parmi:
- A
- B
- Variable: complément formation
description: le motif complément formation c'est...
- Variable: issue d'apprentissage
description: le motif d'issue d'apprentissage c'est ...
```
- L'avantage de cette modélisation, c'est que tout est au même endroit; on évite, pour chaque descente de niveau de l'imbrication, de répéter le _chemin_ de la variable : on factorise de l'information.
- Le problème, c'est que cela nuit vraiment à la lisibilité de la formule `motif` : on perd complètement la vue très synthétique de notre pseudo modèle de départ :
```yaml
Variable: motif
une possibilité parmi:
- classique
- contrat aidé
- complément formation
- issue d'apprentissage
```
Et finalement, contrairement au mécanisme de `composantes` utilisé dans le corps des `Cotisations`, l'information factorisée n'est pas très conséquent : ce n'est que le chemin.
Une autre modélisation, que l'on retient, consiste donc à éclater les variables en utilisant un système d'**espace de nom**:
```yaml
Salariat . CDD . motif: classique
# espace de nom : nom de la variable
formule:
une possibilité:
- remplacement
- accroissement d'activité
- saisonnier
```
```yaml
Salariat . CDD . motif : issue d'apprentissage
description: |
A l'issue d'un contrat d'apprentissage, un contrat de travail à durée déterminée peut être conclu lorsque l'apprenti doit satisfaire aux obligations du service national dans un délai de moins d'un an après l'expiration du contrat d'apprentissage.
```
On pourrait même définir l'espace de nom commun `Salariat . CDD . motif` en en-tête du fichier où est stocké la variable... mais cela nous rendrait trop dépendant du système de fichiers, qui deviendront superflus quand l'édition se fera dans une interface Web.
Pour beaucoup de variables au nom spécifique, il n'est pas souhaitable d'utiliser des espaces de nom, pour ne pas alourdir le code.
> Par exemple, on pourrait définir la variable CDD comme `activité . contrat salarié . CDD`. Mais CDD est un terme non ambigue dans le contexte français.
> À l'inverse, `motif` ou `effectif` sont trop spécifiques pour être laissés dans l'espace de nom global. Quand une variable contiendra `motif` dans son sous-espace de nom, c'est celle-ci qui sera utilisée plutôt que celle d'un autre espace, si elle existe.
Pas de panique, une variable globale pourra quand même être rattachée à quelque chose ! Même si elle n'est pas définie dans un espace de noms, `CDD` sera quand même utilisée dans `contrat salarié` commune une des valeurs de `type de contrat` (ou mieux à l'avenir !). Le moteur se chargera de retrouver son attache.
Quand on créée par exemple la variable `CDD: motif`, donc la variable motif dans l'espace de nom CDD, et qu'on continue avec une variable `CDD . motif . classique` on fait deux choses :
- si la variable `motif` a une propriété `valeur`, on créée un espace pour pour stocker la valeur de cette variable
- on créée aussi un espace de nom associé à cette variable, qui va héberger des variables qui y sont liées et vont souvent intervenir dans la formule de la valeur de `motif`
> la note "typer les variables" peut être lue à la suite de celle-ci.

View File

@ -1,21 +0,0 @@
# Individu est le concept représentant une personne.
# C'est un 'record', une collection de champs nommés
Individu
# Ce concept a des propriétés non calculables.
# On peut parler de variables d'entrée, à saisir par l'utilisateur de la simulation.
date de naissance: YYYY-MM-JJ
# Et d'autres calculables. Mais toujours saisissables.
# On parle alors simplement de variables.
age = calc(date de naissance): nombre positif
# A ce concept est associée une liste d'un autre concept, l'Activité.
# La liste dénote le fait qu'elles peuvent se cumuler.
activités: liste Activité
# Lors de l'éxecution du simulateur, ce concept sera instancié avec des données,
# potentiellement plusieurs fois pour construire une population :
# {
# date de naissance: 1989-08-01,
# activités: [a1, a2]
# }
# -------> allez voir le concept Activité

View File

@ -1,18 +0,0 @@
Activité
# L'activité d'un individu, souvent rémunérée.
durée déterminée: Booléen (Non) # peut être un calcul allant chercher les propriétés des types : CDD pour le salariat, durée du stage, etc.
type:
| Salariat
| Indépendant
| Fonction publique
| Stage
| Demandeur Emploi
# Cette syntaxe indique que l'activité est une alternative entre plusieurs autres concepts incompatibles : c'est ce que l'on appelle une variante.
# Ce qui ne veux pas dire que le cumul de plusieurs activités est impossible (etc. Salariat et Indépendant), mais celui-ci est défini en amont dans le concept d'Individu.
# C'est aux TODO fonctions de contrôle que revient la tâche de vérifier la cohérence des données
# Par exemple, un on peut cumuler un emploi dans la fonction publique et une activité d'indépendant que sous certaines conditions.

View File

@ -1,28 +0,0 @@
# Le nom de ce fichier n'est qu'un guide : plusieurs concepts sont ici définis
Établissement
Entreprise
effectif: nombre positif
SIRET: entier à
code commune: entier à 5 chiffres
code Postal = calc(code commune) : entier à 5 chiffres
compte AT/MP: Compte AT/MP
salariés: liste Salariat
Compte AT/MP
code risque: caractères
appréciation du risque: très élevé | élevé | moyen | bureau
taux de risque: calc(code risque) nombre positif
Entreprise
# l'effectif est par défaut automatiquement rempli de cette façon
effectif: (sum(Établissements.effectif) | count(Individus)): nombre positif
employés: join(établissements.salariés)
établissements: liste Établissements
nombre apprenti: nombre positif
masse salariale: sum(employés.salaire brut)
taxe sur les salaires(Cotisation, Impôt) = sum(Employés.Taxe sur les salaires)
calcule la taxe sur les salaires de mes employés
si resultat < franchise (2000) : 0
si résultat < abattement (20 000): lissage

View File

@ -1,28 +0,0 @@
- Variable: Régime Alsace Moselle
# Il aurait été possible d'attacher ces propriétés directement au concept Salariat, mais la définition de sous-concepts nous donne de l'ordre. C'est en quelque sorte un espace de nom.
attache: Salariat . régime alsace moselle
description: Appartenance au régime local de sécurité sociale Alsace-Moselle
référence: http://regime-local.fr/salaries/
logique:
- affiliation 2012 conservée
- département activité salarié ⊂ [57 67 68]
- itinérance en Alsace Moselle:
- departement établissement ⊂ [57 67 68]
- itinérance en Alsace Moselle contractualisée
- Variable: affiliation 2012 conservée
type: booléen
- Variable: département activité salarié
attache: Salariat
description: Département d'activité du salarié
type: numerique
- Variable: itinérance en Alsace Moselle
description: Le salarié effectue une itinérance en Alsace-Moselle
type: booléen
- Variable: itinérance en Alsace Moselle contractualisée
description: Le salarié effectue une itinérance en Alsace-Moselle, et celle-ci est définie explicitement dans le contrat de travail
type: booléen

View File

@ -1,202 +0,0 @@
Prenons deux variables, simplifiées, du système.
La première
```yaml
Variable: motif CDD
formule:
une possibilité:
- motif B
- motif Z
- motif H
```
La deuxième
```yaml
Variable: CIF CDD
formule:
multiplication:
assiette: salaire brut
taux: 29%
```
Voilà ce qu'on peut faire avec ces informations.
### Contraindre la saisie
Si tu veux renseigner directement la valeur de cette variable,
1. je contraint ton entrée à 3 possibilités (et tu ne peux en choisir qu'une, mais c'est un autre sujet).
2. implicitement, je contraint ton entrée à une valeur compatible avec le mécanisme multiplication. On pourrait même pousser jusqu'à vérifier que la valeur est compatible avec le domaine qu'autorise la multiplication (par exemple si on sait que l'assiette est toujours positive).
### Calculer la valeur
Si tu n'as pas à disposition la valeur de cette variable,
1 et 2. le moteur peut utiliser la formule pour la calculer, _et_ s'il lui manque la valeur des dépendances (ex. pour 1. motif B, Z = `non` mais H = `null` donc inconnue; pour 2. salaire brut est `null`), il proposera un formulaire pour la récupérer.
### Demander les valleurs manquantes
Ajoutons un mécanisme à la formule 2.
```yaml
Variable: CIF CDD
formule:
non applicable si: motif H
multiplication:
assiette: salaire brut
taux: 29%
```
Pour la calculer, il nous faut maintenant la valeur de motif H, car elle n'est pas renseignée et donc cette variable n'est pas calculable : sa valeur est `null`. Comme dit précédemment, cela nous permet de proposer un formulaire de saisie à l'utilisateur :
```
Motif H est-il vrai pour vous ?
[Oui] [Non]
```
C'est une première étape, mais elle n'est pas parfaite : étant donné que `motif H` appartient à une liste de possibilités exclusives dans la variable `Motif CDD`, peut-être qu'il serait préféreable de poser cette question :
```
Quel est votre motif ?
[Motif B] [Motif Z] [Motif H]
```
Le moteur doit pour cela vérifier si motif H intervient dans un mécanisme de type `une possibilité` pour construire son formulaire de saisie.
### Et si `motif CDD` est une liste de possibilités mais avec des catégories ?
Rapprochons-nous encore de la réalité. La formule de `motif CDD` ressemble en fait plutôt à cela :
```yaml
Variable: motif CDD
formule:
une possibilité:
- motif classique
- motif contrat aidé
- motif complément formation
- motif issue d'apprentissage
```
Chaque élément peut alors être lui-même une liste de possibilités,
```yaml
Variable: motif classique
formule:
une possibilité:
- motif remplacement
- motif accroissement d'activité
- motif saisonnier
```
ou une variable sans formule, booléenne, avec une description permetant d'indiquer à l'utilisateur comment y répondre (parce que c'est une feuille, ou parce qu'on n'a pas eu le temps de définir sa formule...) :
```yaml
Variable: motif issue d'apprentissage
description: |
A l'issue d'un contrat d'apprentissage, un contrat de travail à durée déterminée peut être conclu lorsque l'apprenti doit satisfaire aux obligations du service national dans un délai de moins d'un an après l'expiration du contrat d'apprentissage.
```
Les formules d'autres variables, par exemple `indemnité fin de contrat` ou `CID CDD` peuvent alors dépendre des éléments de cette liste de possibilités imbriquée :
```yaml
formule:
non applicable si:
une de ces conditions:
- motif saisonnier
- motif contrat aidé # on cite une catégorie de motifs, mais qui est une variable intéressante en soi
```
```yaml
Variable: motif
attache: Salariat . CDD
formule:
une possibilité parmi:
- Variable: classique
formule:
une possibilité parmi:
- Variable: remplacement
titre: Contrat de remplacement
- Variable: usage
titre: Contrat d'usage
# formule...
- Variable: accroissement d'activité
titre: Motif accroissement temporaire d'activité
- Variable: contrat aidé
formule:
une possibilité parmi:
- A
- B
- Variable: complément formation
description: le motif complément formation c'est...
- Variable: issue d'apprentissage
description: le motif d'issue d'apprentissage c'est ...
```
On peut alors utiliser ces variables dans les formules ainsi:
```yaml
Variable: CIF
attache: Salariat . CDD
formule:
non applicable si:
une de ces conditions:
- motif . usage
- motif . contrat aidé # on cite une catégorie de motifs, qui est quand même une variable exploitable
```
- L'avantage de cette modélisation, c'est que l'on évite, pour chaque descente de niveau de l'imbrication, de répéter le _chemin_ de la variable : on factorise de l'information.
- Le désavantage, c'est que cela nuit à la lisibilité de la formule `motif` : on perd complètement la vue très synthétique de départ :
```yaml
Variable: motif
une possibilité parmi:
- classique
- contrat aidé
- complément formation
- issue d'apprentissage
```
Et finalement, contrairement au mécanisme de `composantes` utilisé dans le corps des `Cotisations`, l'information factorisée n'est pas très conséquent : ce n'est que le chemin.
Une autre modélisation consiste donc à éclater les variables. Par exemple :
```yaml
Salariat . CDD . motif : issue d'apprentissage
description: |
A l'issue d'un contrat d'apprentissage, un contrat de travail à durée déterminée peut être conclu lorsque l'apprenti doit satisfaire aux obligations du service national dans un délai de moins d'un an après l'expiration du contrat d'apprentissage.
```
> On pourrait même définir le chemin commun en en-tête du fichier où est stocké la variable... mais cela nous rendrait trop dépendant des fichiers, superflus quand l'édition se fera dans une interface Web.
# TODO sauf que ça remet en cause notre format :
```yaml
Cotisation: CIF
attributs:
dû par: employeur
branche: yayaya lorde
```
`Cotisation` / `Variable` / `Indemnité` ?
Si le CIF est une Cotisation rattachée à Salariat . CDD,
si l'indemnité de fin de contrat est une Indemnité rattachée à Salariat . CDD,
fillon est une Réduction attachée à Salariat,
alors qu'est-ce que issue d'apprentissage ?
Voir le fichier 'la cotisation est une entité'
Mais ne faudrait-il pas réserver les qualifications de type Cotisation aux règles ?
#TODO Cas où motif H appartient à plusieurs variables de possibilités.
Par exemple, si on considère que parmi les motifs du CDD, il y a des contrats aidés, et que ces contrats aidés peuvent être utilisés à d'autre endroits. C'est flou pour l'instant.

View File

@ -1,3 +1,5 @@
# Voilà un brouillon de la définition des "types de variables". Reste à coder ça d'une façon ou d'une autre.
Variable
| Cotisation
| Réduction de Cotisation

View File

Before

Width:  |  Height:  |  Size: 21 KiB

After

Width:  |  Height:  |  Size: 21 KiB

View File

Before

Width:  |  Height:  |  Size: 7.5 KiB

After

Width:  |  Height:  |  Size: 7.5 KiB

View File

Before

Width:  |  Height:  |  Size: 17 KiB

After

Width:  |  Height:  |  Size: 17 KiB

View File

Before

Width:  |  Height:  |  Size: 22 KiB

After

Width:  |  Height:  |  Size: 22 KiB

View File

Before

Width:  |  Height:  |  Size: 3.4 KiB

After

Width:  |  Height:  |  Size: 3.4 KiB

View File

Before

Width:  |  Height:  |  Size: 7.8 KiB

After

Width:  |  Height:  |  Size: 7.8 KiB

View File

@ -0,0 +1,4 @@
#TODO
Il faudra migrer les éléments des dossiers destinataires et références dans une définition de type des propriétés `cotisation` et `meta`.
Lire la note `typer les variables`.

View File

@ -58,15 +58,15 @@
toutes ces conditions:
- effectif entreprise <= 200
- chiffre d'affaires < 50 000 000
- et l'une de ces conditions:
- et une de ces conditions:
- entreprise . région = Alsace
- établissement . secteur = éducation
# On peut imaginer que 'toutes ces conditions' devienne en fonction du contexte:
toutes ces situations:
# On peut aussi légèrement adapter par exemple:
l'une de ces conditions: # devient :
et l'une de ces conditions:
une de ces conditions: # devient :
et une de ces conditions:
# OPTIONS ABANDONNÉES

View File

@ -1,13 +1,10 @@
- Cotisation: CIF CDD
attache: Salariat . CDD
- espace: contrat salarié . CDD
nom: CIF
description: Contribution au financement du congé individuel de formation spécifique aux CDD.
attributs:
cotisation:
destinataire: OPCA
dû par: employeur
références:
Code du travail - Article L6322-37 : https://www.legifrance.gouv.fr/affichCodeArticle.do?idArticle=LEGIARTI000022234996&cidTexte=LEGITEXT000006072050
non applicable si:
une de ces conditions:
- événement . CDD poursuivi en CDI
@ -19,3 +16,6 @@
multiplication:
assiette: assiette cotisations sociales
taux: 1%
références:
Code du travail - Article L6322-37 : https://www.legifrance.gouv.fr/affichCodeArticle.do?idArticle=LEGIARTI000022234996&cidTexte=LEGITEXT000006072050

View File

@ -1,6 +1,6 @@
- Cotisation: AGIRC
attache: Salariat
attributs:
- espace: contrat salarié
nom: AGIRC
cotisation:
branche: retraite
type de retraite: complémentaire
destinataire: AGIRC

View File

@ -1,6 +1,6 @@
- Cotisation: APEC
attache: Salariat
attributs:
- espace: contrat salarié
nom: APEC
cotisation:
branche: retraite
type de retraite: complémentaire
destinataire: APEC

View File

@ -1,6 +1,6 @@
- Indemnité: compensation des congés payés
attache: Salariat . CDD
attributs:
- espace: contrat salarié . CDD
nom: compensation des congés payés
indemnité:
destinataire: salarié
dû par: employeur
description: |
@ -8,14 +8,9 @@
Il est cependant courant que le salarié ne puisse pas prendre tous ses congés avant le terme de son contrat, il bénéficie d'une indemnité compensatrice de congés payés.
references:
Fiche service-public.gouv.fr: https://www.service-public.fr/particuliers/vosdroits/F2931
Code du travail - Article L3141-24: https://www.legifrance.gouv.fr/affichCodeArticle.do?cidTexte=LEGITEXT000006072050&idArticle=LEGIARTI000006902661&dateTexte=&categorieLien=cid
Congés payés et contrat CDD: https://www.easycdd.com/LEGISLATION-CDD/L-embauche-le-suivi-du-contrat-CDD-les-incidents-frequents/Conges-payes-et-contrat-CDD
non applicable si:
l'une de ces conditions:
- événements . CDD poursuivi en CDI
une de ces conditions:
- événement . CDD poursuivi en CDI
# TODO Y a-t-il d'autres conditions ? Sinon supprimer la liste
# TODO aspect temporel
@ -55,3 +50,9 @@
À noter, la loi El Khomri modifie l'article L3141-12:
- avant : Les congés peuvent être pris dès l'ouverture des droits [...]
- maintenant : Les congés peuvent être pris dès lembauche [...]
references:
Fiche service-public.gouv.fr: https://www.service-public.fr/particuliers/vosdroits/F2931
Code du travail - Article L3141-24: https://www.legifrance.gouv.fr/affichCodeArticle.do?cidTexte=LEGITEXT000006072050&idArticle=LEGIARTI000006902661&dateTexte=&categorieLien=cid
Congés payés et contrat CDD: https://www.easycdd.com/LEGISLATION-CDD/L-embauche-le-suivi-du-contrat-CDD-les-incidents-frequents/Conges-payes-et-contrat-CDD

View File

@ -1,40 +1,34 @@
- Indemnité: prime de fin de contrat
attache: Salariat . CDD
attributs:
type: indemnité
- espace: contrat salarié . CDD
nom: prime de fin de contrat
indemnité:
destinataire: salarié
alias: prime de précarité
description: Somme versée en fin de CDD comme compensation de précarité.
notes: Attention, les exceptions sont légion. Conventions collectives.
notes: |
Attention, les exceptions sont légion. Conventions collectives...
- Dans les faits, les CDD Senior perçoivent une indemnité dun montant équivalent à lindemnité de précarité : [line](https://www.easycdd.com/LEGISLATION-CDD/Fin-ou-rupture-du-contrat-CDD/La-prime-de-precarite/La-prime-de-precarite-n-est-pas-due-si)
non applicable si:
l'une de ces conditions:
une de ces conditions:
# Evènements particuliers
- événements . CDD poursuivi en CDI
- événements . refus CDI avantageux
- événement . CDD poursuivi en CDI
- événement . refus CDI avantageux
# Rupture
- événements . rupture anticipée salarié
- événements . rupture pour faute grave ou force majeure
- événements . rupture pendant période essai
# Rupture TODO regrouper celà dans une nouvelle variante
- événement . rupture anticipée salarié
- événement . rupture pour faute grave ou force majeure
- événement . rupture pendant période essai
- engagement employeur complément formation
- motif . classique . usage
- motif . classique . saisonnier
- motif . complément formation
- motif . contrat aidé
# types de contrat
- contrat aidé
- motif . usage
- motif . jeune vacances
- motif . saisonnier
# https://www.easycdd.com/LEGISLATION-CDD/Fin-ou-rupture-du-contrat-CDD/La-prime-de-precarite/La-prime-de-precarite-n-est-pas-due-si Dans les faits, les CDD Senior perçoivent une indemnité dun montant équivalent à lindemnité de précarité.
- contrat jeune vacances
# - CDD . type = vendanges
# cas du contrat vendanges !! différent du saisonnier ?
# du Code rural et de la pêche maritime : https://www.easycdd.com/LEGISLATION-CDD/Avant-de-rediger-un-contrat-CDD/Les-cas-de-recours-au-contrat-CDD/Cas-de-recours-Detaille/Le-contrat-CDD-vendanges
# Les contrats d'extras dans l'hôtellerie restauration
# - CDD . type = extras restauration
# TODO Il faudrait pouvoir afficher les indemnités comme une somme de fin de contrat.
# Ici elle est étalée sur un mois moyen

View File

@ -1,27 +1,31 @@
- Cotisation: majoration chômage CDD
attache: Salariat . CDD
attributs:
- espace: contrat salarié . CDD
nom: majoration chômage
cotisation:
dû par: employeur
type: majoration
destinataire: URSSAF
description: Majoration des contributions patronales dassurance chômage pour les contrats à durée déterminée courts (CDD)
non applicable si:
l'une de ces conditions:
une de ces conditions:
- durée contrat > 3 #cette information est déjà contenue dans la formule, mais ça ne fait pas de mal de l'expliciter ici
- événements . CDD poursuivi en CDI
- événement . CDD poursuivi en CDI
formule:
multiplication:
assiette: assiette cotisations sociales
plafond: 4 * plafond sécurité sociale
taux:
logique numérique:
motif . accroissement temporaire activité:
motif . classique . accroissement activité:
durée contrat <= 1: 3% # TODO 1 mois, pas 1 rien, évidemment
durée contrat <= 3: 1.5%
motif . usage:
motif . classique . usage:
durée contrat <= 3: 0.5%
références:
La mojoration de la contribution chômage: https://www.urssaf.fr/portail/home/employeur/calculer-les-cotisations/les-taux-de-cotisations/lassurance-chomage-et-lags/la-majoration-de-la-contribution.html
Circulaire Unédic: http://www.unedic.org/sites/default/files/ci201317_1.pdf

View File

@ -1,6 +1,5 @@
- Cotisation: AGIRC
attache: Salariat
attributs:
- contrat salarié: AGIRC
cotisation:
branche: retraite
type de retraite: complémentaire
destinataire: AGIRC

View File

@ -1,96 +0,0 @@
- variable: AGFF
description: |
Cotisation de retraite complémentaire
(Cotisation pour l'Association pour la Gestion du Fonds de Financement de lAGIRC et de lARRCO)
tags:
branche: retraite
type de retraite: complémentaire
destinataire: AGFF
référence: http://www.agirc-arrco.fr/l-agirc-et-larrco/chiffres-cles
notes: |
Attention: les tranches du barème sont différentes pour les cadres et non-cadres, en valeur et en nombres.
marginalRateTaxScale:
assiette: assiette cotisations sociales
- variable: AGFF
tags:
dû par: employeur
concerne:
- categorie salarié = privé non cadre
marginalRateTaxScale:
- threshold: 0
rate:
historique:
2001-04-01: .008
- threshold: 1
rate:
historique:
2001-04-01: .009
- threshold: 3
rate: 0
- variable: AGFF
tags:
dû par: salarié
concerne:
- categorie salarié = privé non cadre
marginalRateTaxScale:
- threshold: 0
rate:
historique:
2001-04-01: .008
- threshold: 1
rate:
historique:
2001-04-01: .009
- threshold: 3
rate: 0
- variable: AGFF
tags:
dû par: salarié
concerne:
- categorie salarié = privé cadre
marginalRateTaxScale:
- threshold: 0
rate:
historique:
2001-04-01: .008
- threshold: 1
rate:
historique:
2001-04-01: .009
- threshold: 4
rate:
historique:
2016-01-01: .009
2001-04-01: 0
- threshold: 8
rate: 0
- variable: AGFF
tags:
dû par: employeur
concerne:
- categorie salarié = privé cadre
marginalRateTaxScale:
- threshold: 0
rate:
historique:
2001-04-01: .012
- threshold: 1
rate:
historique:
2001-04-01: .013
- threshold: 4
rate:
historique:
2016-01-01: .013
2001-04-01: 0
- threshold: 8
rate: 0

View File

@ -1,62 +0,0 @@
- variable: AGIRC
description: |
Cotisation de retraite complémentaire cadre, complémentant le régime ARRCO
(pour l'Association Générale des Institutions de Retraite des Cadres)
tags:
branche: retraite
type de retraite: complémentaire
destinataire: AGIRC
référence: http://www.agirc-arrco.fr/l-agirc-et-larrco/chiffres-cles
concerne:
- categorie salarié = privé cadre
notes: |
Il éxiste une tranche C, de 4 à 8 fois la base, sur laquelle la répartition des cotisations est décidée au sein de lentreprise jusquà 20 %. De 20 % à 20,30 %, la répartition est la suivante : 66,67 % à la charge du salarié et 33,33 % pour lemployeur.
marginalRateTaxScale:
assiette: assiette cotisations sociales
- variable: AGIRC
tags:
dû par: employeur
marginalRateTaxScale:
- threshold: 0
rate: 0
- threshold: 1
rate:
historique:
2016-01-01: .1275
2015-01-01: .1275
2014-01-01: .1268
2006-01-01: .126
1999-01-01: .125
1998-01-01: .11875
1997-01-01: .1125
1996-01-01: .10625
1995-01-01: .10
1994-01-01: .0847
1993-01-01: .0702
- threshold: 8
rate: 0
- variable: AGIRC
tags:
dû par: salarié
marginalRateTaxScale:
- threshold: 0
rate: 0
- threshold: 1
rate:
historique:
2016-01-01: .078
2015-01-01: .078
2014-01-01: .0775
2006-01-01: .077
1999-01-01: .075
1998-01-01: .06875
1997-01-01: .0625
1996-01-01: .05625
1995-01-01: .05
1994-01-01: .0363
1993-07-01: .0234
- threshold: 8
rate: 0

View File

@ -1,35 +0,0 @@
- variable: AGS
description: Cotisation au Régime de Garantie des Salaires
tags:
- plafonnée
- dû par: employeur
ne concerne pas:
- assimilé salarié
reference: https://www.service-public.fr/professionnels-entreprises/vosdroits/F31409
linear:
assiette: assiette cotisations sociales
limit: 4 * plafond sécurité sociale
historique:
2017-01-01: 0.0025
2016-01-01: 0.0025
2011-04-01: 0.003
2009-11-01: 0.004
2009-08-01: 0.003
2006-07-01: 0.0015
2006-01-01: 0.0025
2005-04-01: 0.0035
2003-09-01: 0.0045
2003-01-01: 0.0035
2002-07-01: 0.003
2002-01-01: 0.002
2001-01-01: 0.001
2000-07-01: 0.0015
1999-07-01: 0.002
1995-07-01: 0.0025
1993-07-01: 0.0035
notes: |
- taux différent pour le personnel intérimaire des entreprises de travail temporaire
- Ne sont pas assujetties :
- les personnes morales de droit public,
- les syndicats de copropriété,
- les particuliers employeurs.

View File

@ -1,48 +0,0 @@
- variable: APEC
description: |
Cotisation de retraite complémentaire cadre, pour le fonctionnement de l'APEC
(Association Pour lEmploi des Cadres)
tags:
branche: retraite
type de retraite: complémentaire
destinataire: APEC
référence: http://www.agirc-arrco.fr/l-agirc-et-larrco/chiffres-cles
avertissements: |
Avant 2011, il y avait une cotisation forfaitaire au lieu de la tranche A
- variable: APEC
tags:
dû par: employeur
marginalRateTaxScale:
- threshold: 0
rate:
historique:
2016-01-01: 0.00036
2011-01-01: 0.00036
1993-07-01: 0
- threshold: 0
rate:
historique:
2016-01-01: 0.00036
1993-07-01: 0.00036
- threshold: 4
rate: 0
- variable: APEC
tags:
dû par: salarié
marginalRateTaxScale:
- threshold: 0
rate:
historique:
2016-01-01: 0.00024
2011-01-01: 0.00024
1993-07-01: 0
- threshold: 0
rate:
historique:
2016-01-01: 0.00024
1993-07-01: 0.00024
- threshold: 4
rate: 0

View File

@ -1,113 +0,0 @@
- variable: ARRCO
description: >
Cotisation de retraite complémentaire pour tous les salariés du secteur prive,
(pour l'Association pour le Régime de Retraite Complémentaire des salariés)
référence: http://www.agirc-arrco.fr/l-agirc-et-larrco/chiffres-cles
tags:
branche: retraite
type de retraite: complémentaire
destinataire: ARRCO
marginalRateTaxScale:
assiette: assiette cotisations sociales
- variable: ARRCO
tags:
dû par: employeur
concerne:
- categorie salarié = privé cadre
marginalRateTaxScale:
- threshold: 0
rate:
historique:
2016-01-01: .0465
2015-01-01: .0465
2014-01-01: .0458
1999-01-01: .045
1998-01-01: .04125
1997-01-01: .0375
1996-01-01: .03375
1993-01-01: .02952
- threshold: 1
rate: 0
- variable: ARRCO
tags:
dû par: salarié
concerne:
- categorie salarié = privé cadre
marginalRateTaxScale:
- threshold: 0
rate:
historique:
2016-01-01: .031
2015-01-01: .031
2014-01-01: .0305
1999-01-01: .03
1998-01-01: .0275
1997-01-01: .025
1996-01-01: .0225
1993-01-01: .01968
- threshold: 1
rate: 0
- variable: ARRCO
tags:
dû par: employeur
concerne:
- categorie salarié = privé non cadre
marginalRateTaxScale:
- threshold: 0
rate:
historique:
2016-01-01: .0465
2015-01-01: .0465
2014-01-01: .0458
1999-01-01: .045
1998-01-01: .04125
1997-01-01: .0375
1996-01-01: .03375
1993-07-01: .02952
- threshold: 1
rate:
historique:
2016-01-01: .1215
2015-01-01: .1215
2014-01-01: .1208
2005-01-01: .12
2004-01-01: .105
2002-01-01: .09
2000-01-01: .075
- threshold: 3
rate: 0
- variable: ARRCO
tags:
dû par: salarié
concerne:
- categorie salarié = privé non cadre
marginalRateTaxScale:
- threshold: 0
rate:
historique:
2016-01-01: .031
2015-01-01: .031
2014-01-01: .0305
1999-01-01: .03
1998-01-01: .0275
1997-01-01: .025
1996-01-01: .0225
1993-01-01: .01968
- threshold: 1
rate:
historique:
2016-01-01: .081
2015-01-01: .081
2014-01-01: .0805
2005-01-01: .08
2004-01-01: .07
2002-01-01: .06
1993-01-01: .05
- threshold: 3
rate: 0

View File

@ -1,71 +0,0 @@
- variable: chomage
description: Cotisation dassurance chômage
tags:
- plafonnée
- branche: chomage
collecteur: URSSAF
destinataire: Pôle emploi
ne concerne pas:
- assimilé salarié
linear:
assiette: assiette cotisations sociales
limit: 4 * plafond sécurité sociale
- variable: chomage
tags:
dû par: employeur
linear:
historique:
2015-01-01: 0.04
2007-01-01: 0.04
2006-01-01: 0.0404
2003-01-01: 0.04
2002-07-01: 0.037
2002-01-01: 0.036
2001-04-01: 0.037
2001-01-01: 0.0499
1997-01-01: 0.0526
1994-01-01: 0.0547
1993-08-01: 0.0538
1993-07-01: 0.0483
- variable: chomage
tags:
dû par: salarié
linear:
historique:
2015-01-01: .024
2007-01-01: .024
2006-01-01: .0244
2003-01-01: .024
2002-07-01: .021
2002-01-01: .02
2001-07-01: .021
2001-04-01: .026
2001-01-01: .0349
1997-01-01: .036
1994-01-01: .0386
1993-07-01: .03770
- variable: chomage
description: Majoration des contributions patronales dassurance chômage
complément: oui
tags:
dû par: employeur
références:
- circulaire Unédic du 29 juillet 2013 précise les modalités dapplication du dispositif
- https://www.urssaf.fr/portail/home/employeur/calculer-les-cotisations/les-taux-de-cotisations/lassurance-chomage-et-lags/la-majoration-de-la-contribution.html
notes: |
- L'URSSAF liste à la fois des conditions pour "Les CDD concernés par lapplication de la majoration" et pour "Les contrats de travail exclus de la majoration". Un doute persiste : difficile de savoir si les premières suffisent au calcul (donc que les deuxièmes sont là pour enlever les doutes) ou si les deuxièmes peuvent faire exception...
- Depuis le 1er juillet 2013
- l'URSSAF explique longuement la notion de durée du CDD : "Comment déterminer la durée du CDD ?"
concerne:
- catégorie salarié = CDD
logique numérique: # première valeur trouvée, sinon 0
contrat de travail durée = CDD:
- embauche en CDI suivant le CDD: 0
- CDD type accroissement temporaire d'activité:
contrat de travail durée ≤ 1 mois: 0.03
contrat de travail durée ≤ 3 mois: 0.015
- CDD type usage # faire le calcul !!
contrat de travail durée ≤ 3 mois: 0.005

View File

@ -1,34 +0,0 @@
- variable: cotisation exceptionnelle temporaire
tags:
branche: retraite
type de retraite: complémentaire
destinataire: AGIRC
concerne:
- categorie salarié = privé cadre
linear:
assiette: assiette cotisations sociales
limit: 8 * plafond sécurité sociale
- variable: cotisation exceptionnelle temporaire
tags:
dû par: employeur
linear:
historique:
2016-01-01: .0022
2001-01-01: .0022
2000-01-01: .0017
1999-01-01: .0013
1998-01-01: .0009
1997-01-01: .00044
- variable: cotisation exceptionnelle temporaire
tags:
dû par: salarié
linear:
historique:
2016-01-01: .0013
2001-01-01: .0013
2000-01-01: .0011
1999-01-01: .0008
1998-01-01: .0005
1997-01-01: .00026

View File

@ -1,34 +0,0 @@
- variable: contribution formation professionnelle
tags:
dû par: employeur
collecteur: OPCA
notes: |
- Le seuil supérieur disparaît en 2016 et se confond avec le seuil des TPE
- A faire : majoration pour les entreprises de travail temporaire
local:
seuil:
historique:
2016-01-01: 11
passé: 10
concerne:
effectif entreprise >= 20:
historique:
2016-01-01: 0.01
2015-01-01: 0.01
2004-01-01: 0.016
1993-01-01: 0.015
1992-01-01: 0.014
effectif entreprise >= seuil:
historique:
2016-01-01: 0.01
2015-01-01: 0.01
2005-01-01: 0.0105
2004-01-01: 0.016
1993-01-01: 0.015
1992-01-01: 0.014
effectif entreprise < seuil::
historique:
2016-01-01: 0.0055
2005-01-01: 0.0055
2004-01-01: 0.004
1993-01-01: 0.0015

View File

@ -1,78 +0,0 @@
- variable: maladie
tags:
branche: maladie
linear:
assiette: assiette cotisations sociales
- variable: maladie
tags:
dû par: employeur
linear:
historique:
2016-01-01: 0.04
2007-01-01: 0.04
2006-01-01: 0.0404
2003-01-01: 0.04
2002-07-01: 0.037
2002-01-01: 0.036
2001-04-01: 0.037
2001-01-01: 0.0499
1997-01-01: 0.0526
1994-01-01: 0.0547
1993-08-01: 0.0538
1993-07-01: 0.0483
- variable: maladie
tags:
dû par: salarié
linear:
historique:
2016-01-01: .024
2007-01-01: .024
2006-01-01: .0244
2003-01-01: .024
2002-07-01: .021
2002-01-01: .02
2001-07-01: .021
2001-04-01: .026
2001-01-01: .0349
1997-01-01: .036
1994-01-01: .0386
1993-07-01: .03770
# TODO pourquoi pas "s'ajoute à : maladie" ?
- variable: maladie
complément: oui
# Ceci signifie que cette spécification ne remplace pas
# la variable de base du même nom, mais s'y ajoute !
# Pourrait aussi être exprimé comme
# règle: +
# par opposition au défaut d'écrasement par spécificité de tags
# description: Complément de cotisation maladie spécifique au régime de sécurité sociale d'Alsace-Moselle
# référence: https://baseircantec.retraites.fr/cotisations-assurance-maladie-alsace-moselle.html
tags:
dû par: salarié
concerne:
- régime géographique = Alsace Moselle
linear:
# base: selon cette source, la base est l'assiette de la CSG : https://baseircantec.retraites.fr/cotisations-assurance-maladie-alsace-moselle.html
# information non retrouvée ailleurs
historique:
2012-01-01: 1.5
2008-01-01: 1.6
2007-07-01: 1.7
2006-01-01: 1.8
2003-01-01: 1.7
1999-07-01: 1.5
1998-01-07: 1.25
1994-01-01: 1
1989-09-01: 0.75
#
# exception:
# si: régime = agricole
# historique:
# 2014-01-01: 1.1
# 2011-07-01: 1.2
# 2008-07-01: 1.3
# 2007-01-01: 1.4
# 2003-01-01: 1.5

View File

@ -1,25 +0,0 @@
- variable: participation effort construction
description:
- Participation des employeurs à l'effort de construction
- Dispositif du 1 % logement
référence: https://www.service-public.fr/professionnels-entreprises/vosdroits/F22583
# TODO c'est une cotisation à versement particulier : plusieurs possibilités
tags:
branche: aucune idée
dû par: employeur
concerne:
- régime = général:
- effectif entreprise >= 20
- régime = agricole:
- effectif entreprise >= 50
# Cette syntaxe (retour à la ligne pour un OU et indentation pour un ET) permet d'exprimer :
# l'une des concerne:
# - "régime = général et effectif_entreprise >= 20"
# - "régime = agricole et effectif_entreprise >= 50"
linear:
assiette: assiette cotisations sociales
historique:
2015-01: 0.0045
1992-01: 0.0045

View File

@ -1,76 +0,0 @@
- variable: apprentissage
description: Taxes d'apprentissage
référence: https://www.service-public.fr/professionnels-entreprises/vosdroits/F22574
tags:
branche: aucune idée
ne concerne pas:
- entreprise_est_association_non_lucrative
linear:
assiette: assiette cotisations sociales
- variable: apprentissage
tags:
apprentissage: taxe de base
# TODO introduire la répartition entre part régionale, quota d'app., hors quota
# https://www.service-public.fr/professionnels-entreprises/vosdroits/F22574
linear:
historique:
2017-01-01: 0.0068
2014-01-01: 0.0068
1993-07-01: 0.005
- variable: apprentissage
tags:
- régime géographique = Alsace Moselle
linear:
historique:
2017-01-01: 0.0044
- variable: apprentissage
description: Contribution supplémentaire à l'apprentissage
abbreviation: CSA
tags:
apprentissage: contribution supplémentaire
linear:
var:
- condition: "(ratio_alternants < .01) & (effectif_entreprise < 2000)"
historique:
2016-01-01: .005
2013-01-01: .004
- condition: "(ratio_alternants < .01) & (effectif_entreprise >= 2000)"
historique:
2016-01-01: .006
2014-01-01: .006
2013-01-01: .005
- condition: "ratio_alternants < .02"
historique:
2016-01-01: .002
2015-01-01: .002
2013-01-01: .001
- condition: "ratio_alternants < .03"
historique:
2016-01-01: .002
2015-01-01: .002
2013-01-01: .001
- condition: "ratio_alternants < .04"
historique:
2016-01-01: .0005
2015-01-01: .0005
- condition: "ratio_alternants < .05"
historique:
2016-01-01: .0005
2015-01-01: 0
- variable: apprentissage
description: Contribution additionnelle au développement de l'apprentissage
tags:
- obsolète
- apprentissage: contribution additionnelle
linear:
historique:
2017-01-01: 0
2014-01-01: 0
2006-01-01: 0.0018
2005-01-01: 0.0012
2004-01-01: 0.0006

View File

@ -1,70 +0,0 @@
- Cotisation: vieillesse
description: Cotisation au régime de retraite de base des salariés.
tags:
branche: retraite
type de retraite: de base
collecteur: URSSAF
destinataire: CNAV
# CTP: 100
linear:
assiette: assiette cotisations sociales
- variable: vieillesse
tags:
dû par: salarié
plafonnée: non
linear:
historique:
2018-01-01: .004
2017-01-01: .004
2016-01-01: .0035
2015-01-01: .003
2014-01-01: .0025
2004-07-01: .001
- variable: vieillesse
tags:
dû par: employeur
plafonnée: non
linear:
historique:
2018-01-01: 0.019
2017-01-01: 0.019
2016-01-01: 0.0185
2015-01-01: 0.018
2014-01-01: 0.0175
1991-02-01: 0.016
- variable: vieillesse
tags:
- plafonnée
linear:
limit: 4 * plafond sécurité sociale
- variable: vieillesse
tags:
- plafonnée
- dû par: salarié
linear:
historique:
2017-01-01: .0690
2016-01-01: .0690
2015-01-01: .0685
2014-01-01: .0680
2012-11-01: .0675
2006-01-01: .0665
1993-07-01: .0655
- variable: vieillesse
tags:
- plafonnée
- dû par: employeur
linear:
historique:
2017-01-01: .0855
2016-01-01: .0855
2015-01-01: .085
2014-01-01: .0845
2012-11-01: .084
2006-01-01: .083
1979-01-01: .082

View File

@ -1,10 +1,9 @@
- Cotisation: ARRCO
attache: Salariat
attributs:
- contrat salarié: ARRCO
cotisation:
branche: retraite
type de retraite: complémentaire
destinataire: ARRCO
description: >
description: |
Cotisation de retraite complémentaire pour tous les salariés du secteur privé, gérée par l'Association pour le Régime de Retraite Complémentaire des salariés
références:
calcul des cotisations: http://www.agirc-arrco.fr/entreprises/gerer-les-salaries/calcul-des-cotisations/

View File

@ -1,7 +1,7 @@
- Cotisation: ATMP
- contrat salarié: ATMP
nom: Cotisation d'Accidents du Travail et Maladies Professionnelles
description: Cotisation due au titre des Accidents du Travail et Maladies Professionnelles
attributs:
cotisation:
branche: maladie
collecteur: URSSAF
responsable: CARSAT
@ -48,8 +48,7 @@
Il est accessible en ligne sur [net-entreprise](http://www.net-entreprises.fr/html/compte-accident-travail.htm) ou reçu par courrier.
taux: Établissement . taux collectif ATMP
- Variable: taux collectif ATMP
attache: Établissement
- contrat salarié . ATMP : taux collectif ATMP
saisie:
selection: # affichera une saisie utilisateur de type <select> avec champ de recherche par mots clefs
données: https://raw.githubusercontent.com/sgmap/taux-collectifs-cotisation-atmp/master/taux-2016.csv

View File

@ -6,7 +6,7 @@
collecteur: URSSAF
branche: logement
note: Il y avait une cotisation supplémentaire pour les entreprises de >= 20 employés avant 2015, mais le résultat était le même.
explication: >
explication: |
Si l'entreprise a un effectif supérieur ou égal à 20 salariés, elle doit verser 0,50 % sur la totalité des salaires. Pour les entreprises de moins de 20 salariés et pour les employeurs occupés aux activités mentionnées aux 1° à 4° de l'article L. 722-1 du code rural et de la pêche maritime et les coopératives mentionnées à l'article L. 521-1 du même code, la cotisation est de 0,10 % des salaires limités au plafond de sécurité sociale (tranche A). Intégrée aux cotisations de sécurité sociale, elle est recouvrée par les Urssaf pour le financement des allocations logement versées par les caisses d'allocations familiales. Les employeurs qui ont atteint ou dépassé pour la première fois, au titre des années 2008 à 2012, le seuil de 20 salariés ont été dispensés de lancien Fnal supplémentaire pendant 3 ans. La contribution était ensuite progressivement appelée sur les 3 années suivantes. Un dispositif est mis en place pour 2016, 2017 et 2018. Les employeurs qui atteignent ou dépassent au titre de ces années l'effectif de 20 salariés continuent d'appliquer le taux de 0,10 % pendant trois ans (suite au franchissement de seuil). Cette modalité n'implique pas d'adaptation du calcul du coefficient de la réduction générale. Le seuil de 20 salariés s'apprécie au 31 décembre et la modification de la cotisation est effective au 1er avril suivant.
formule:
multiplication:

View File

@ -1,4 +1,4 @@
- Cotisation: Versement transport
- contrat salarié: versement transport
applicable si:
# TODO variations sur la période
@ -14,9 +14,7 @@
assiette: assiette cotisations sociales
taux: Établissement . taux versement transport
- Variable: Taux versement transport
attache: Établissement
- contrat salarié . versement transport: taux
saisie:
sélection:
# On est ici sur l'option d'une recherche par mots clefs dans toutes les colonnes du tableau (ville par nom, par code postal, par code INSEE). On peut imaginer restreindre la recherche à l'une de ces clefs.

View File

@ -1,13 +1,13 @@
# Réflection sur la notion de haut niveau permettant d'implémenter les cotisations sociales
Malheureusement Contrat n'est pas adapté à toutes les situations: il est possible d'employer quelqu'un sans emploi:
Malheureusement Contrat n'est pas adapté à toutes les situations: il est possible d'employer quelqu'un sans contrat:
- particuliers employeurs : plus de 8 heures par semaine ou de plus de 4 semaines consécutives dans l'année.
- La signature dun contrat de travail nest pas obligatoire dans certains cas. Cest le cas du Contrat de travail à Durée Indéterminée, considéré comme la forme normale et générale de la relation de travail entre un salarié et un employeur (Art. L1221-2 du Code du travail).
- un assimilé salarié peut sûrement ne pas avoir de contrat
Cela dit, un contrat pourrait être noté "virtuel" pour ces cas là.
> Cela dit, un contrat pourrait être noté "virtuel" pour ces cas là.
On pourrait alors se tourner vers le concept de "Salarié" (en y incluant tout ce qui y est assimilé).
On peut alors se tourner vers le concept de "Salarié" (en y incluant tout ce qui y est assimilé).
Ce qui nous donnerait deux autres catégories : TNS (travailleur non salarié) et Fonction publique.
Mais !
- c'est étrange de se dire qu'un agent de la fonction publique, notamment contractuel, n'est pas salarié

View File

@ -0,0 +1,28 @@
- entité : activité
description: Une activité est une occupation d'un individu, souvent rémunérée.
valeur:
# Cette syntaxe indique que l'activité est une alternative entre plusieurs autres concepts incompatibles : c'est ce que l'on appelle une variante.
# Ce qui ne veux pas dire que le cumul de plusieurs activités est impossible (etc. salariat et indépendant), mais celui-ci est défini en amont dans le concept d'individu.
une possibilité:
- contrat salarié
- indépendant
- fonction publique
- stage
- inactif # (demandeur d'emploi, etc.)
# TODO ...
- activité: département
description: Département où l'activité est exercée
type: numerique
- activité: individu
description: l'individu qui exerce cette activité
# on ne spécifie pas d'information de valeur -> une activité a une propriété individu, qui ne créée pas d'entité, c'est simplement une attache à l'entité individu existante
# TODO C'est aux fonctions de contrôle que revient la tâche de vérifier la cohérence des données
# Par exemple, un on peut cumuler un emploi dans la fonction publique et une activité d'indépendant que sous certaines conditions.
# TODO durée déterminée: Booléen (Non)
# peut être un calcul allant chercher les propriétés des types : CDD pour le salariat, durée du stage, etc.

View File

@ -0,0 +1,36 @@
- entité : entreprise
- entreprise: établissements
valeur:
liste: établissement
- entreprise: employés
valeur:
union: établissements . employés
- entreprise: effectif
valeur:
décompte: employés
- entreprise: nombre apprenti
valeur: numérique
- entreprise: salaire brut
valeur:
somme: employés . salaire brut # les employés sont des `contrat salariés`, donc ont un salaire brut
# TODO formule intéressante :
# taxe sur les salaires(Cotisation, Impôt) = sum(Employés.Taxe sur les salaires)
# calcule la taxe sur les salaires de mes employés
# si resultat < franchise (2000) : 0
# si résultat < abattement (20 000): lissage
#TODO A refaire
# Compte AT/MP
# code risque: caractères
# appréciation du risque: très élevé | élevé | moyen | bureau
# taux de risque: calc(code risque) nombre positif

View File

@ -0,0 +1,11 @@
# Pourquoi ne pas simplement définir l'espace de nom en en-tête du fichier, par ex:
# ```espace: individu . sexe```
# pour ne pas avoir à le répéter ci-dessous ?
# -> pour pouvoir dans un futur, que l'on espère proche, éditer ou parcourir ce code source directement dans un navigateur _par espace de nom_ avec une barre de recherche avancée. La notion de fichier serait alors embêtante.
- individu . sexe : masculin
image: fa-male
- individu . sexe : masculin
image: fa-female

View File

@ -0,0 +1,47 @@
# Un des concepts de base du système, l'individu.
# C'est une collection de champs (un _record_)
- entité : individu
# individu n'est une proriété d'aucun autre objet
description: C'est le concept représentant une personne
- individu: sexe
valeur:
une possibilité:
- masculin
- féminin
# Voir ./individu.sexe.yaml, ces termes y sont définis.
# Ils sont attachés à l'espace de nom `individu . sexe`.
#
# Pourquoi les propriétés de l'objet individu sont-elles éclatées dans une liste plate ? Concrêtement, pourquoi `sexe` n'est pas une propriété écrite directement au sein de l'objet `individu` ?
# -> Pour plus de lisibilité : sexe, masculin, féminin peuvent s'étendre sur plusieurs lignes et rendraient l'objet individu illisible si elles y étaient toutes imbriquées.
# Des objets à proriété pourront être reconstitués dans le navigateur.
# Cette propriété est non calculable.
# On peut parler de variables d'entrée, à saisir par l'utilisateur de la simulation.
- individu: date de naissance
valeur:
date: JJ-MM-AAAA
# Celle-ci est calculable, mais toujours saisissable
- individu: age
valeur:
différence temporelle:
échelle: année
entre: date de naissance
et: aujourd'hui
# A ce concept est associée une liste d'un autre concept, l'Activité.
# La liste dénote le fait qu'elles peuvent se cumuler.
- individu: activités
valeur:
liste: activité
# Lors de l'éxecution du simulateur, ce concept sera instancié avec des données,
# potentiellement plusieurs fois pour construire une population :
# {
# date de naissance: 1989-08-01,
# activités: [a1, a2]
# }

View File

@ -0,0 +1,60 @@
# TODO Aujourd'hui, nous n'avons besoin des contrats aidés que dans le contexte du motif de recours au CDD.
# Il faudra par la suite, par exemple pour un simulateur CUI, les en extraire, par exemple dans `contrat salarié`, mais toujours pouvoir les utiliser ici.
- espace: contrat salarié . CDD . motif
nom: contrat aidé
# Voir le TODO de contrat salarié . CDD . événement . CDD poursuivi en CDI
# formule:
# une possibilité:
# - contrat unique d'insertion
# - emplois d'avenir
# - CDD sénior
# - alternance
# # CDD d'insertion (CDDI) https://www.service-public.fr/particuliers/vosdroits/F14100
références:
Code du travail - Article L1242-3: https://www.legifrance.gouv.fr/affichCodeArticle.do;jsessionid=714D2E2B814371F4F1D5AA88472CD621.tpdila20v_1?idArticle=LEGIARTI000006901196&cidTexte=LEGITEXT000006072050&dateTexte=20170420
- espace: contrat salarié . CDD . motif . contrat aidé
nom: contrat unique d'insertion
# Voir le TODO de contrat salarié . CDD . événement . CDD poursuivi en CDI
# formule:
# une possibilité:
# - CUI-CAE
# - CUI-CIE
références:
CUI - dispositions générales: http://travail-emploi.gouv.fr/emploi/insertion-dans-l-emploi/contrats-aides/article/le-contrat-unique-d-insertion-cui-dispositions-generales
- espace: contrat salarié . CDD . motif . contrat aidé
nom: CDD sénior
titre: Contrat CDD sénior
- espace: contrat salarié . CDD . motif . contrat aidé
nom: emploi d'avenir
description: Contrat de travail aidé créé pour faciliter l'insertion professionnelle et laccès à une qualification pour les jeunes en difficulté
références:
Emploi d'avenir: https://www.service-public.fr/particuliers/vosdroits/F24438
- espace: contrat salarié . CDD . motif . contrat aidé
nom: alternance
# Voir le TODO de contrat salarié . CDD . événement . CDD poursuivi en CDI
# formule:
# une possibilité:
# - apprentissage
# - professionnalisation
- espace: contrat salarié . CDD . motif . contrat aidé . alternance
nom: apprentissage
description: Contrat de travail aidé destiné au jeune professionnel qui suit une formation en alternance entre une entreprise et un centre de formation.
référence: https://fr.wikipedia.org/wiki/Contrat_d'apprentissage#En_France
# cette variable peut se calculer ! Au boulot !
# y intégrer l'Étudiant apprenti professeur https://www.service-public.fr/particuliers/vosdroits/F24439
# attention ! Le contrat d'apprentissage n'est pas soumis aux dispositions légales du CDD:
# Article L1241-1
# Les dispositions du présent titre ne s'appliquent ni au contrat d'apprentissage [...]
- espace: contrat salarié . CDD . motif . contrat aidé . alternance
nom: professionnalisation
description: Contrat de travail aidé consistant en l'alternance de périodes dacquisition de savoir-faire en entreprise et de périodes de formation théorique dispensées en centres de formation ou par lentreprise elle-même si elle dispose dun service de formation agréé.
référence: https://fr.wikipedia.org/wiki/Contrat_de_professionnalisation
# cette variable peut se calculer ! Au boulot !

View File

@ -1,43 +1,46 @@
- Variable: motif # alias utilisé dans l'article L. 1242-1
- espace: contrat salarié . CDD
nom: motif
nom complet: motif de recours
attache: Salariat . CDD
question: Quel est le motif de recours au CDD ?
description: |
Le CDD est un contrat d'exception: son recours doit être autorisé par l'un des motifs spécifiés dans la loi.
une possibilité:
- motif classique
- motif contrat aidé
- motif complément formation
- motif issue d'apprentissage
formule:
une possibilité:
- classique
- contrat aidé
- complément formation
- issue d'apprentissage
références:
Code du travail - Articles L1242-1 à 4: https://www.legifrance.gouv.fr/affichCode.do;jsessionid=E318966AA9DEB9E32465297F15B04D86.tpdila20v_1?idSectionTA=LEGISCTA000006195639&cidTexte=LEGITEXT000006072050&dateTexte=20170420
le recours au CDD: http://www.entreprises.cci-paris-idf.fr/web/reglementation/developpement-entreprise/droit-social/le-recours-au-cdd
embaucher en CDD: https://www.service-public.fr/particuliers/vosdroits/F34
les cas de recours au CDD: https://www.easycdd.com/LEGISLATION-CDD/Avant-de-rediger-un-contrat-CDD/Les-cas-de-recours-au-contrat-CDD
# C'est vraiment pas génial ça... Variable: classique, ça n'a aucun sens.
- Salariat . CDD . motif: classique
une possibilité:
- motif remplacement
- motif accroissement d'activité
- motif saisonnier
- motif usage
- motif mission
- espace: contrat salarié . CDD . motif
nom: classique
titre: motifs classiques
formule:
une possibilité:
- remplacement
- accroissement activité
- saisonnier
- usage
- mission
références:
Code du travail - Article L1242-2: https://www.legifrance.gouv.fr/affichCodeArticle.do;jsessionid=714D2E2B814371F4F1D5AA88472CD621.tpdila20v_1?idArticle=LEGIARTI000033024658&cidTexte=LEGITEXT000006072050&dateTexte=20170420
- Variable: motif saisonnier
attache: Salariat . CDD
- espace: contrat salarié . CDD . motif . classique
nom: saisonnier
titre: Saisonnier
description: Emplois à caractère saisonnier, dont les tâches sont appelées à se répéter chaque année selon une périodicité à peu près fixe, en fonction du rythme des saisons ou des modes de vie collectifs.
- Variable: motif accroissement d'activité
attache: Salariat . CDD
- espace: contrat salarié . CDD . motif . classique
nom: accroissement activité
titre: Accroissement temporaire d'activité
description: Accroissement temporaire de l'activité de l'entreprise
- Variable: motif remplacement
attache: Salariat . CDD
- espace: contrat salarié . CDD . motif . classique
nom: remplacement
titre: Contrat de remplacement
description: |
Nous regroupons dans cette catégorie les cas suivants.
@ -53,8 +56,8 @@
- Remplacement du chef d'une exploitation agricole ou d'une entreprise mentionnée aux 1° à 4° de l'article L. 722-1 du code rural et de la pêche maritime, d'un aide familial, d'un associé d'exploitation, ou de leur conjoint mentionné à l'article L. 722-10 du même code dès lors qu'il participe effectivement à l'activité de l'exploitation agricole ou de l'entreprise ;
- Variable: motif mission
attache: Salariat . CDD
- espace: contrat salarié . CDD . motif . classique
nom: mission
titre: Contrat de mission
description: |
> Aussi appelé contrat à objet défini.
@ -65,8 +68,8 @@
b) Les conditions dans lesquelles les salariés sous contrat à durée déterminée à objet défini bénéficient de garanties relatives à l'aide au reclassement, à la validation des acquis de l'expérience, à la priorité de réembauche et à l'accès à la formation professionnelle continue et peuvent, au cours du délai de prévenance, mobiliser les moyens disponibles pour organiser la suite de leur parcours professionnel ;
c) Les conditions dans lesquelles les salariés sous contrat à durée déterminée à objet défini ont priorité d'accès aux emplois en contrat à durée indéterminée dans l'entreprise.
- Variable: motif usage
attache: Salariat . CDD
- espace: contrat salarié . CDD . motif . classique
nom: usage
titre: Contrat d'usage
alias: motif extra
description: Emplois pour lesquels, dans certains secteurs d'activité définis par décret ou par convention ou accord collectif de travail étendu, il est d'usage constant de ne pas recourir au contrat de travail à durée indéterminée en raison de la nature de l'activité exercée et du caractère par nature temporaire de ces emplois ;
@ -98,16 +101,16 @@
- Assistance technique ou logistique dans les institutions internationales ou dans l'Union européenne prévu par les traités
- Variable: motif complément formation
attache: Salariat . CDD
- espace: contrat salarié . CDD . motif
nom: complément formation
titre: Complément de formation professionnelle assuré par l'employeur
description: l'employeur s'engage, pour une durée et dans des conditions déterminées par décret, à assurer un complément de formation professionnelle au salarié.
références:
Code du travail - Article L1242-3 : https://www.legifrance.gouv.fr/affichCodeArticle.do;jsessionid=714D2E2B814371F4F1D5AA88472CD621.tpdila20v_1?idArticle=LEGIARTI000006901196&cidTexte=LEGITEXT000006072050&dateTexte=20170420
- Variable: motif issue d'apprentissage
attache: Salariat . CDD
- espace: contrat salarié . CDD . motif
nom: issue d'apprentissage
titre: À l'issue d'un contrat d'apprentissage
description: |
A l'issue d'un contrat d'apprentissage, un contrat de travail à durée déterminée peut être conclu lorsque l'apprenti doit satisfaire aux obligations du service national dans un délai de moins d'un an après l'expiration du contrat d'apprentissage.

View File

@ -1,8 +1,8 @@
# TODO Attention, il faudrait peut-être prendre en compte les interdictions du CDD.
# https://www.legifrance.gouv.fr/affichCode.do;jsessionid=B74AE5D2E73ACE3A108B9ADF3BDC8C51.tpdila20v_1?idSectionTA=LEGISCTA000006195640&cidTexte=LEGITEXT000006072050&dateTexte=20170701
- Variable: CDD
attache: Salariat
- espace: contrat salarié
nom: CDD
nom complet: CDD
description: Contrat de travail pour lequel un employeur peut recruter un salarié pour une durée déterminée, car la cause de cette détermination, de la date ou échéance de fin de contrat est prévue explicitement par le Code du travail.
référence: https://fr.wikipedia.org/wiki/Contrat_de_travail_%C3%A0_dur%C3%A9e_d%C3%A9termin%C3%A9e_en_France
@ -12,14 +12,13 @@
# - motif de recours
# - Variable: emploi temporaire
# attache: Salariat . CDD
# description: Le contrat n'a ni pour objet ni pour effet de pourvoir durablement un emploi lié à l'activité normale et permanente de l'entreprise.
# références:
# Code du travail - Article L1242-1
- Variable: durée contrat
attache: Salariat . CDD
- espace: contrat salarié . CDD
nom: durée contrat
titre: durée du contrat
question: Quelle est la durée du contrat ?
sous-question: |
@ -33,9 +32,32 @@
6 mois: 6
3 mois: 3
- espace: contrat salarié . CDD
nom: congés non pris
question: Combien de jours de congés ne seront pas pris ?
description: Combien de jours de congés ne pourront être pris par l'employé, du fait de la durée de son CDD. En jours ouvrés, par rapport aux 25 jours de congés légaux annuels.
format: nombre positif
suggestions:
3 / 25: 3
10 / 25: 10
- Variable: contrat jeune vacances
attache: Salariat . CDD
- espace: contrat salarié . CDD
nom: contrat jeune vacances
titre: Contrat jeune vacances
question: Est-ce un contrat jeune vacances ?
description: Aussi appelé CDD vendages. Contrat conclu avec un jeune pendant ses vacances scolaires ou universitaires.
notes: Ce n'est pas un motif de CDD.
# Cette variable est le point de départ du simulateur "surcout CDD" :-D
- espace: contrat salarié . CDD
nom: surcoût CDD
description: |
En France, le contrat à durée déterminée _est un contrat d'exception au CDI_ qui apporte à l'employeur plus de souplesse dans un cadre législatif précis, comportant en particulier des contreparties financières.
formule:
somme: #TODO à l'avenir, exprimer une somme par requête de type : obligation applicable au CDD
- CIF #cotisation
- majoration chômage #cotisation
- prime de fin de contrat #indemnité
- compensation des congés payés #indemnité

View File

@ -1,14 +1,13 @@
- Variable: événements
attache: Salariat . CDD
- espace: contrat salarié . CDD
nom: événement
titre: Événement de contrat
question: Pensez-vous être confronté à l'un de ces événements au cours du contrat ?
description: |
Certains de ces événements impactent fortement les résultats de la simulation, et peuvent donc la racourcir.
Par exemple, dans l'hypothèse d'un CDD poursuivi en CDI, aucune majoration ou indemnité ne sera à verser !
# au lieu de lister tous les cas, l'alternative est de simplement indiquer qu'ils sont exclusifs,
# et les identifier dynamiquement par leur attribut "attache" :
langue au chat possible: oui
une possibilité:
formule:
une possibilité:
- CDD poursuivi en CDI
- refus CDI avantageux
- rupture anticipée salarié
@ -16,31 +15,36 @@
- rupture pendant période essai
- Variable: CDD poursuivi en CDI
attache: Salariat . CDD . événements
- espace: contrat salarié . CDD . événement
nom: CDD poursuivi en CDI
titre: Le CDD est poursuivi en CDI
une possibilité:
- embauche en CDI suivant le CDD
- CDD requalifié en CDI # quand ça arrive ?
# TODO quand cette variable est appelée par une autre variable,
# on devrait pouvoir poser la question, puis proposer un bouton qui permette d'aider l'utilisateur à
# y répondre, en lui expliquant la formule suivante :
#
# formule:
# une possibilité:
# - embauche en CDI suivant le CDD
# - CDD requalifié en CDI # quand ça arrive ?
- Variable: refus CDI avantageux
attache: Salariat . CDD . événements
- espace: contrat salarié . CDD . événement
nom: refus CDI avantageux
titre: Refus d'un CDI avantageux
description: Le salarié, au terme du CDD, refuse une reconduction en CDI pour un emploi similaire, et une rémunération au moins aussi avantageuse.
- Variable: rupture anticipée salarié
- espace: contrat salarié . CDD . événement
nom: rupture anticipée salarié
titre: Rupture anticipée du salarié
attache: Salariat . CDD . événements
description: Rupture anticipée du contrat à l'initiative du salarié.
# ces variables peuvent être attachées à un groupe ruptures pour plus de clarté
- Variable: rupture pour faute grave ou force majeure
- espace: contrat salarié . CDD . événement
nom: rupture pour faute grave ou force majeure
titre: Rupture pour faute grave ou force majeure
attache: Salariat . CDD . événements
# ces variables peuvent être attachées à un groupe ruptures pour plus de clarté
- Variable: rupture pendant période essai
- espace: contrat salarié . CDD . événement
nom: rupture pendant période essai
titre: Rupture pendant la période d'essai
attache: Salariat . CDD . événements
# ces variables peuvent être attachées à un groupe ruptures pour plus de clarté

View File

@ -1,47 +1,28 @@
- Entité: Salariat
- nom: contrat salarié
description: |
Activité encadrée par un contrat de travail de droit privé.
# Sur ce concept de Salariat sont définies une liste de propriétés.
# Le salarié est embauché dans un établissement, lui même rattaché à une entreprise
Le contrat n'est en fait pas nécessaire dans le droit français, il est possible d'employer quelqu'un sans contrat par exemple dans ces cas:
- particuliers employeurs : plus de 8 heures par semaine ou de plus de 4 semaines consécutives dans l'année.
- cdi: La signature dun contrat de travail nest pas obligatoire dans certains cas. Cest le cas du Contrat de travail à Durée Indéterminée, considéré comme la forme normale et générale de la relation de travail entre un salarié et un employeur (Art. L1221-2 du Code du travail).
individu: Individu
# le contrat salarié est rattaché à l'activité, elle-même rattachée à un individu.
établissement: Établissement
- Variable: congés non pris
attache: Salariat
question: Combien de jours de congés ne seront pas pris ?
description: Combien de jours de congés ne pourront être pris par l'employé, du fait de la durée de son CDD. En jours ouvrés, par rapport aux 25 jours de congés légaux annuels.
format: nombre positif
suggestions:
3 / 25: 3
10 / 25: 10
# Cette variable est le point de départ du simulateur "surcout CDD" :-D
- Variable: surcoût CDD
attache: Salariat
description: >
En France, le contrat à durée déterminée <span className="insist">est un contrat d'exception au CDI</span>
qui apporte à l'employeur plus de souplesse dans un cadre législatif précis, comportant en particulier des contreparties financières.
formule:
somme: #TODO à l'avenir, exprimer une somme par requête de type : obligation applicable au CDD
- CDD . CIF CDD #cotisation
- CDD . majoration chômage CDD #cotisation
- CDD . prime de fin de contrat #indemnité
- CDD . compensation des congés payés #indemnité
- Variable: assiette cotisations sociales
attache: Salariat
description: >
- espace: contrat salarié
nom: assiette cotisations sociales
description: |
L'assiette des cotisations sociales est la base de calcul d'un grand nombre de cotisations sur le travail salarié. Elle comprend les rémunérations en espèces (salaire de base, indemnité, primes...) et les avantages en nature (logement, véhicule...).
référence: https://www.urssaf.fr/portail/home/employeur/calculer-les-cotisations/la-base-de-calcul.html
formule:
somme:
- salaire brut
- CDD . prime de fin de contrat #indemnité
- CDD . compensation des congés payés #indemnité
# - CDD . prime de fin de contrat #indemnité
# - CDD . compensation des congés payés #indemnité
- Variable: salaire de base
attache: Salariat
- espace: contrat salarié
nom: salaire de base
question: Quel est le salaire de base ?
description: Le salaire de base est le salaire brut régulier inscrit dans le contrat. C'est le salaire de négociation entre le salarié et l'employeur. Des primes viendront éventuellement le compléter, on parlera alors de salaire brut.
format: nombre positif
@ -49,8 +30,8 @@
salaire médian: 2300
SMIC: 1480
- Variable: salaire brut
attache: Salariat
- espace: contrat salarié
nom: salaire brut
question: Quel est le salaire brut ?
description: Le salaire brut peut être vu comme la somme du salaire net et des cotisations sociales salariales retenues sur le bulletin de paie d'un salarié, ou comme les sommes perçues par le salarié au titre de son contrat de travail, avant retenues sociales et fiscales.
format: nombre positif
@ -65,34 +46,30 @@
salaire médian: 2300
SMIC: 1480
- Variable: statut cadre
attache: Salariat
- espace: contrat salarié
nom: statut cadre
description: Notion mal définie mais reconnue par les conventions collectives et déterminant l'appartenance à une caise de retraite de base spécifique
choix:
- oui
- non (défaut)
- Variable: plafond sécurité sociale
attache: Salariat
type de période: mensuel
- espace: contrat salarié
nom: plafond sécurité sociale
#TODO peut-être à déplacer ? Doit être accessible par d'autres types d'activité que contrat salarié
# type de période: mensuel
formule: 3269
# TODO
# Cette variable est le point de départ du simulateur "surcout CDD" :-D
- Variable: salaire net
attache: Salariat
description: >
- espace: contrat salarié
nom: salaire net
description: |
C'est, en gros, le salaire brut moins les cotisations sociales. Ce salaire est plus important que le brut car c'est ce que le salrié reçoit sur son compte bancaire, et pourtant, le brut est très utilisé lors des négociations salariales.
formule:
somme: #TODO à l'avenir, exprimer une somme sous forme de requête
- APEC
- AGIRC
- espace: contrat salarié
nom: régime alsace moselle
#TODO peut-être est-ce à définir au niveau de l'activité ?
# - Variable: salaire super brut
# formule:

View File

@ -0,0 +1,21 @@
- entité: régime alsace moselle
description: Appartenance au régime local de sécurité sociale Alsace-Moselle
référence: http://regime-local.fr/salaries/
valeur:
une de ces conditions:
- affiliation 2012 conservée
- activité . département ⊂ [57 67 68] #TODO peut-être trop complexe pour être une expression infixe
- itinérance en Alsace Moselle:
- departement établissement ⊂ [57 67 68]
- itinérance en Alsace Moselle contractualisée
- régime alsace moselle: affiliation 2012 conservée
type: booléen
- régime alsace moselle: itinérance en Alsace Moselle
description: Le salarié effectue une itinérance en Alsace-Moselle
type: booléen
- régime alsace moselle: itinérance en Alsace Moselle contractualisée
description: Le salarié effectue une itinérance en Alsace-Moselle, et celle-ci est définie explicitement dans le contrat de travail
type: booléen

View File

@ -0,0 +1,2 @@
Dans ce dossier `entités`, on définit l'individu, l'entreprise, l'établissement, le contrat etc.
Ce sont principalement des variables sans formule compliquée.

View File

@ -0,0 +1,37 @@
- entité : établissement
- établissement: entreprise
- établissement: employés
valeur:
liste: contrat salarié #TODO stagiaires, etc. ??
- établissement: effectif
valeur:
décompte: employés
- établissement: SIRET
valeur: entier à 14 chiffres
- établissement: code commune
valeur: entier à 5 chiffres
- établissement: code postal
valeur: entier à 5 chiffres
- établissement: compte AT/MP
- établissement . compte AT/MP: code risque
valeur: ?
- établissement . compte AT/MP: appréciation du risque
valeur:
une possibilité:
- très élevé
- élevé
- moyen
- faible
- établissement . compte AT/MP: taux risque
# TODO faire référence à la règle de atmp.yaml

View File

@ -0,0 +1,22 @@
http://travail-emploi.gouv.fr/droit-du-travail/temps-de-travail-et-conges/conges-et-absences/article/les-conges-payes
> Est appelée indemnité de congés payés la rémunération à laquelle le salarié a droit pendant son congé annuel.
-> le salarié n'est pas payé pendant ses jours de congés, mais reçoit une indemnité.
Son mode de calcul fait qu'elle est forcément plus elevée que le salaire qui serait reçu s'il avait travaillé !
> calcul : https://www.cogilog.com/Logiciel/exemple-bulletin-paie-conges-payes-4.html
-> QUESTIONS
- Faut-il en intégrer une estimation dans le prix d'embauche ?
Oui je pense
- Si un salarié a négocié un salaire de 40 000 euros annuels sur son contrat de travail
Il prend 25 jours de congés.
Soit :
- il reçoit donc plus d'argent pendant ses congés que pendant ses jours de travail, donc il reçoit au total plus que 40k, par exemple 40 300€
- l'employeur abaisse son taux horaire pour prendre en compte la différence et le paie bien 40k par an

View File

@ -1,22 +0,0 @@
# http://travail-emploi.gouv.fr/droit-du-travail/temps-de-travail-et-conges/conges-et-absences/article/les-conges-payes
#
# > Est appelée indemnité de congés payés la rémunération à laquelle le salarié a droit pendant son congé annuel.
#
# -> le salarié n'est pas payé pendant ses jours de congés, mais reçoit une indemnité.
#
# Son mode de calcul fait qu'elle est forcément plus elevée que le salaire qui serait reçu s'il avait travaillé !
# > calcul : https://www.cogilog.com/Logiciel/exemple-bulletin-paie-conges-payes-4.html
#
#
# -> QUESTIONS
#
# - Faut-il en intégrer une estimation dans le prix d'embauche ?
# Oui je pense
#
# - Si un salarié a négocié un salaire de 40 000 euros annuels sur son contrat de travail
#
# Il prend 25 jours de congés.
#
# Soit :
# - il reçoit donc plus d'argent pendant ses congés que pendant ses jours de travail, donc il reçoit au total plus que 40k, par exemple 40 300€
# - l'employeur abaisse son taux horaire pour prendre en compte la différence et le paie bien 40k par an

View File

@ -1,5 +1,6 @@
# Les simulateurs sont définis ici. Ils ont une variable comme objectif de calcul. Le moteur va analyser cette variable et son arbre pour produire un formulaire. Il sera exposé sur /simulateurs/:id
#TODO pourquoi ne pas définir les simulateurs directement dans leurs variables d'objectif ?
- titre: Simulateur CDD
sous-titre: Découvrir le surcoût employeur du CDD par rapport au CDI
id: cdd

View File

@ -1,5 +1,5 @@
import React from 'react'
import references from '../../règles/références/références.yaml'
import references from '../../règles/ressources/références/références.yaml'
import './References.css'
import R from 'ramda'
@ -18,7 +18,7 @@ export default ({refs}) => (
<span className="url">
{domain}
{refData.image &&
<img src={require('../../règles/références/' + refData.image)}/> }
<img src={require('../../règles/ressources/références/' + refData.image)}/> }
</span>
</span>
<a href={link} target="_blank">

View File

@ -9,7 +9,7 @@ import {connect} from 'react-redux'
import mockSituation from '../engine/mockSituation.yaml'
import {START_CONVERSATION} from '../actions'
import classNames from 'classnames'
import possiblesDestinataires from '../../règles/destinataires/destinataires.yaml'
import possiblesDestinataires from '../../règles/ressources/destinataires/destinataires.yaml'
import {capitalise0} from '../utils'
import knownMecanisms from '../engine/known-mecanisms.yaml'
import marked from '../engine/marked'
@ -78,7 +78,7 @@ export default class Rule extends Component {
: <div>
<a href={destinataireData.lien} target="_blank">
{destinataireData.image &&
<img src={require('../../règles/destinataires/' + destinataireData.image)} /> }
<img src={require('../../règles/ressources/destinataires/' + destinataireData.image)} /> }
{!destinataireData.image &&
<div id="calligraphy">{destinataire}</div>
}

View File

@ -8,12 +8,13 @@ import Aide from './Aide'
import PageTypeIcon from './PageTypeIcon'
import simulateurs from '../../règles/simulateurs.yaml'
import R from 'ramda'
import {Redirect, Link} from 'react-router-dom'
import {Redirect, Link, withRouter} from 'react-router-dom'
import {createMarkdownDiv} from '../engine/marked'
import './Simulateur.css'
import classNames from 'classnames'
let situationSelector = formValueSelector('conversation')
@withRouter
@reduxForm({form: 'conversation', destroyOnUnmount: false})
@connect(
state => ({
@ -37,24 +38,21 @@ export default class extends React.Component {
}
} = this.props
this.simulateurId = simulateurId
this.simulateur = R.find(R.propEq('id', simulateurId))(simulateurs)
// C'est ici que la génération du formulaire, et donc la traversée des variables commence
if (this.simulateur)
this.props.startConversation(this.simulateur.objectif)
}
state = {
started: null
}
render(){
if (!this.simulateur) return <Redirect to="/404"/>
let
started = !this.props.match.params.intro,
{foldedSteps, unfoldedSteps, situation} = this.props,
sim = path =>
R.path(R.unless(R.is(Array), R.of)(path))(this.simulateur)
,
{started} = this.state
return (
<div id="sim" className={classNames({started})}>
@ -73,11 +71,11 @@ export default class extends React.Component {
</div>
{
// Tant que le bouton 'C'est parti' n'est pas cliqué, on affiche l'intro
!this.state.started ?
!started ?
<div>
<div className="action centered">
<p>{sim(['action', 'texte'])}</p>
<button onClick={() => this.setState({started: true})}>
<button onClick={() => this.props.history.push(`/simulateurs/${this.simulateurId}`) }>
{sim(['action', 'bouton'])}
</button>
</div>
@ -109,11 +107,11 @@ export default class extends React.Component {
}
<div id="unfoldedSteps">
{ !R.isEmpty(unfoldedSteps) && do {
let step = R.head(unfoldedSteps)
let step = R.head(unfoldedSteps),
pureStep = R.dissoc('component', step)
;<step.component
key={step.name}
{...step}
step={step}
step={pureStep}
unfolded={true}
answer={situation(step.name)}
/>

View File

@ -119,7 +119,7 @@ export var FormDecorator = formType => RenderField =>
// color: this.props.themeColours.textColourOnWhite,
maxWidth: wideQuestion ? '95%' : ''
}}
>{this.props.question}</h1>
>{this.props.step.question}</h1>
<div className="step-subquestion" dangerouslySetInnerHTML={{__html: subquestion}}></div>
</div>

View File

@ -55,7 +55,7 @@ export default class Input extends Component {
<ul>
{R.toPairs(suggestions).map(([text, value]) =>
<li key={value}
onClick={() => setFormValue(value) && submit()}
onClick={e => setFormValue(value) && submit() && e.preventDefault()}
onMouseOver={() => setFormValue(value) && this.setState({suggestedInput: true})}
onMouseOut={() => setFormValue('') && this.setState({suggestedInput: false})}>
<a href="#" title="cliquer pour valider">{text}</a>

View File

@ -5,6 +5,88 @@ import HoverDecorator from '../HoverDecorator'
import Explicable from './Explicable'
import R from 'ramda'
/* Ceci est une saisie de type "radio" : l'utilisateur choisit une réponse dans une liste, ou une liste de listes.
Les données @choices sont un arbre de type:
- nom: motif CDD # La racine, unique, qui formera la Question. Ses enfants sont les choix possibles
enfants:
- nom: motif classique
enfants:
- nom: motif saisonnier
- nom: motif remplacement
- nom: motif contrat aidé
- nom: motif complément de formation
A chaque nom est associé une propriété 'données' contenant l'entité complète (et donc le titre, le texte d'aide etc.) : ce n'est pas à
ce composant (une vue) d'aller les chercher.
*/
let dottedNameToObject = R.pipe(
R.split(' . '),
R.reverse,
R.reduce((memo, next) => (
{[next]: memo}
), 'oui')
)
// FormDecorator permet de factoriser du code partagé par les différents types de saisie,
// dont Question est un example
@FormDecorator('question')
export default class Question extends Component {
render() {
let {
stepProps: {choices},
} = this.props
if (R.is(Array)(choices))
return this.renderBinaryQuestion()
else
return this.renderChildren(choices.children)
}
renderBinaryQuestion(){
let {
input, // vient de redux-form
stepProps: {submit, choices},
themeColours
} = this.props
return (
<ul>
{ choices.map(({value, label}) =>
<RadioLabel key={value} {...{value, label, input, submit, themeColours}}/>
)}
</ul>
)
}
renderChildren(children) {
let {
input, // vient de redux-form
stepProps,
themeColours
} = this.props,
{name} = input,
{submit} = stepProps,
// seront stockées ainsi dans le state :
// [parent object path]: dotted name relative to parent
relativeDottedName = radioDottedName =>
radioDottedName.split(name + ' . ')[1]
return (<ul>
{ children.map( ({name, titre, dottedName, children: nextChildren}) =>
nextChildren ?
<li key={name} className="variant">
<div>{titre || name}</div>
{this.renderChildren(nextChildren)}
</li>
: <li key={name} className="variantLeaf">
<RadioLabel key={name} {...{value: relativeDottedName(dottedName), label: titre || name, input, submit, themeColours}}/>
</li>
)}
</ul>)
}
}
@HoverDecorator
class RadioLabel extends Component {
@ -29,27 +111,3 @@ class RadioLabel extends Component {
)
}
}
/* Ceci est une saisie de type "radio" : l'utilisateur choisit une réponse dans une liste.
FormDecorator permet de factoriser du code partagé par les différents types de saisie,
dont Question est un example */
@FormDecorator('question')
export default class Question extends Component {
render() {
let {
input,
stepProps: {submit, choices},
themeColours
} = this.props
return (
<div>
{ choices.map((choice) => do {
let {value, label} = R.is(String)(choice) ? {value: choice, label: null} : choice;
<RadioLabel key={value} {...{value, label, input, submit, themeColours}}/>
}
)}
</div>
)
}
}

View File

@ -141,10 +141,30 @@
margin: .8em 0;
}
.step fieldset ul {
list-style-type: none;
}
#foldedSteps {
margin: 2em 0 4em;
}
.step.question .variant {
margin-bottom: 1em;
}
.step.question .variant > ul {
border-left: 1px dashed #ccc;
margin-top: .6em;
padding-left: .6em;
margin-left: 1em;
}
.step.question .variant > div {
padding-left: .6em;
font-weight: 600;
font-style: italic;
}
.step.question fieldset > div {
display: flex;
justify-content: flex-end;
@ -152,7 +172,13 @@
}
.step.question fieldset span {
margin-bottom: .6em;
white-space: nowrap
}
.step.question .variantLeaf {
margin-bottom: .6em;
}
.step.question .variant .variantLeaf {
display: inline-block;
}
.step label.radio,

View File

@ -30,7 +30,7 @@ export default class Layout extends Component {
<Route exact path="/" component={Home}/>
<Route path="/contact" component={Contact} />
<Route path="/regle/:name" component={Rule} />
<Route path="/simulateurs/:simulateurId" component={Simulateur} />
<Route path="/simulateurs/:simulateurId/:intro?" component={Simulateur} />
<Route component={Route404} />
</Switch>
</div>

View File

@ -1,20 +0,0 @@
import React from 'react'
import Explicable from '../components/conversation/Explicable'
export let constructStepMeta = ({titre, question, subquestion, dottedName, name}) => ({
// name: dottedName.split(' . ').join('.'),
name: dottedName,
// question: question || name,
question: <Explicable
label={question || name}
name={name}
lightBackground={true}
/>,
title: titre || name,
subquestion,
// Legacy properties :
visible: true,
// helpText: 'Voila un peu d\'aide poto'
})

View File

@ -0,0 +1,141 @@
import { findRuleByDottedName } from './rules'
import React from 'react'
import Explicable from '../components/conversation/Explicable'
import R from 'ramda'
import Question from '../components/conversation/Question'
import Input from '../components/conversation/Input'
import {euro, months} from '../components/conversation/formValueTypes'
export let constructStepMeta = ({
titre,
question,
subquestion,
dottedName,
name,
}) => ({
// name: dottedName.split(' . ').join('.'),
name: dottedName,
// question: question || name,
question: (
<Explicable label={question || name} name={name} lightBackground={true} />
),
title: titre || name,
subquestion,
// Legacy properties :
visible: true,
// helpText: 'Voila un peu d\'aide poto'
})
let isVariant = R.path(['formule', 'une possibilité'])
let buildVariantTree = relevantPaths => path => {
let rec = path => {
let node = findRuleByDottedName(path),
variants = isVariant(node),
shouldBeExpanded = variants && variants.find( v => relevantPaths.find(rp => R.contains(path + ' . ' + v)(rp) ))
return Object.assign(
node,
shouldBeExpanded ?
{children: variants.map(v => rec(path + ' . ' + v))}
: null
)
}
return rec(path)
}
export let generateGridQuestions = R.pipe(
R.toPairs,
R.map( ([variantRoot, relevantVariants]) =>
({
...constructStepMeta(findRuleByDottedName(variantRoot)),
component: Question,
choices: buildVariantTree(relevantVariants)(variantRoot),
objectives: []
})
),
// R.map( R.pipe(
// R.flatten,
// R.map(findRuleByDottedName),
// ([variant, ...variants]) =>
// Object.assign(
// constructStepMeta(variant),
// //TODO reintroduce langue au chat !
// {
// component: Question,
// choices: variants,
// },
// {objectives: []}
//TODO reintroduce objectives
// {
// objectives: R.pipe(
// R.chain(v => missingVariables[variant.dottedName + ' . ' + v]),
// R.uniq()
// )(variant['une possibilité'])
// }
)
export let generateSimpleQuestions = R.pipe(
R.values, //TODO exploiter ici les groupes de questions de type 'record' (R.keys): elles pourraient potentiellement êtres regroupées visuellement dans le formulaire
R.unnest,
R.map(dottedName => {
let rule = findRuleByDottedName(dottedName)
if (rule == null) console.log(dottedName)
return Object.assign(
constructStepMeta(rule),
rule.format == 'nombre positif' || rule.format == 'période'
? {
component: Input,
valueType: rule.format == 'nombre positif' ? euro : months,
attributes: {
inputMode: 'numeric',
placeholder: 'votre réponse',
},
suggestions: rule.suggestions,
}
: {
component: Question,
choices: [
{ value: 'non', label: 'Non' },
{ value: 'oui', label: 'Oui' },
],
},
{
objectives: [] //missingVariables[dottedName],
}
)
})
)
/*
// Pas de groupe trouvé : ce sont des variables individuelles
[R.isNil, () => variables.map(dottedName => {
let rule = findRuleByDottedName(dottedName)
return Object.assign(constructStepMeta(rule),
rule.format == 'nombre positif' ||
rule.format == 'période' ?
{
component: Input,
valueType: rule.format == 'nombre positif' ? euro : months,
attributes: {
inputMode: 'numeric',
placeholder: 'votre réponse'
},
suggestions: rule.suggestions
} : {
component: Question,
choices: [
{value: 'non', label: 'Non'},
{value: 'oui', label: 'Oui'}
]
},
{
objectives: missingVariables[dottedName]
}
)})],
*/

View File

@ -1,7 +1,7 @@
# Liste et description des différents mécanismes compris par le moteur.
# La description peut être rédigée en markdown :-)
l'une de ces conditions:
une de ces conditions:
description: |
C'est un `ou` logique.

View File

@ -1,19 +1,17 @@
import R from 'ramda'
/* TODO Ce fichier n'est pas propre.
C'est temporaire (séparation artificielle entre les règles d'entités et les règles d'objectif)
Elles seront à termes toutes dans le même fichier, ou toutes dans leur fichier respectif
/*
TODO sélection temporaire de dossier, tant que toute la base de règles n'est pas vérifiée
*/
let objectivesContext = require.context(
'../../règles/rémunération-travail/cdd', true,
/([a-zA-Z]|-|_)+.yaml$/)
// /([a-zA-Z]|-|_)+.yaml$/)
/(CIF|indemnité_fin_contrat|indemnité_compensatrice_congés_payés|majoration-chomage).yaml/)
let entityContext = require.context(
'../../règles/entités/salariat', true,
/([a-zA-Z]|-|_)+.yaml$/)
'../../règles/rémunération-travail/entités/ok', true)
let objectives = R.pipe(

View File

@ -4,6 +4,7 @@ import R from 'ramda'
import possibleVariableTypes from './possibleVariableTypes.yaml'
import marked from './marked'
// console.log('rawRules', rawRules.map(({espace, nom}) => espace + nom))
/***********************************
Méthodes agissant sur une règle */
@ -11,20 +12,21 @@ import marked from './marked'
export let enrichRule = rule => {
let
type = possibleVariableTypes.find(t => rule[t]),
name = rule[type],
dottedName = rule.attache && [
rule.attache,
name = rule['nom'],
ns = rule['espace'],
dottedName = ns ? [
ns,
name
].join(' . '),
].join(' . ') : name,
subquestionMarkdown = rule['sous-question'],
subquestion = subquestionMarkdown && marked(subquestionMarkdown)
return {...rule, type, name, dottedName, subquestion}
return {...rule, type, name, ns, dottedName, subquestion}
}
export let hasKnownRuleType = rule => rule && enrichRule(rule).type
let
export let
splitName = R.split(' . '),
joinName = R.join(' . ')
@ -38,29 +40,24 @@ export let nameLeaf = R.pipe(
R.last
)
/* Les variables peuvent être exprimées dans une règle relativement à son contexte, son 'attache', pour une plus grande lisibilité. Cette fonction résoud cette ambiguité.
/* Les variables peuvent être exprimées dans la formule d'une règle relativement à son propre espace de nom, pour une plus grande lisibilité. Cette fonction résoud cette ambiguité.
*/
export let completeRuleName = ({attache, name}, partialName) => {
export let disambiguateRuleReference = ({ns, name}, partialName) => {
let
fragments = attache.split(' . '),
pathPossibilities = R.pipe(
R.length,
R.inc,
R.range(1),
R.map(R.take(R.__, fragments)),
R.reverse
)(fragments),
fragments = ns.split(' . '), // ex. [CDD . événements . rupture]
pathPossibilities = // -> [ [CDD . événements . rupture], [CDD . événements], [CDD] ]
R.range(0, fragments.length + 1)
.map(nbEl => R.take(nbEl)(fragments))
.reverse(),
found = R.reduce((res, path) =>
R.when(
R.is(Object), R.reduced
)(findRuleByDottedName([...path, partialName].join(' . ')))
, null, pathPossibilities)
return found && found.dottedName || do {throw `OUUUUPS la référence ${partialName} dans la règle : ${name} est introuvable dans la base`}
return found && found.dottedName || do {throw `OUUUUPS la référence '${partialName}' dans la règle '${name}' est introuvable dans la base`}
}
// On enrichit la base de règles avec des propriétés dérivées de celles du YAML
export let rules = rawRules.map(enrichRule)
@ -82,7 +79,7 @@ export let searchRules = searchInput =>
JSON.stringify(rule).toLowerCase().indexOf(searchInput) > -1)
.map(enrichRule)
export let findRuleByDottedName = dottedName => // console.log('dottedName', rules, dottedName) ||
export let findRuleByDottedName = dottedName => // console.log('dottedName', dottedName) ||
rules.find(rule => rule.dottedName == dottedName)
export let findGroup = R.pipe(
@ -140,3 +137,28 @@ export let collectMissingVariables = (groupMethod='groupByMissingVariable') => a
// below is a hand implementation of above... function composition can be nice sometimes :')
// R.reduce( (memo, [mv, dependencyOf]) => ({...memo, [mv]: [...(memo[mv] || []), dependencyOf] }), {})
)(analysedSituation)
let isVariant = R.path(['formule', 'une possibilité'])
export let recrecrecrec =
({variantGroups, recordGroups}, dottedName, childDottedName) => {
let child = findRuleByDottedName(dottedName),
parentDottedName = parentName(dottedName),
parent = findRuleByDottedName(parentDottedName)
if (isVariant(parent)) {
let grandParentDottedName = parentName(parentDottedName),
grandParent = findRuleByDottedName(grandParentDottedName)
if (isVariant(grandParent))
return recrecrecrec({variantGroups, recordGroups}, parentDottedName, childDottedName || dottedName)
else
return {
variantGroups: R.mergeWith(R.concat, variantGroups, {[parentDottedName]: [childDottedName || dottedName]}),
recordGroups
}
} else
return {
variantGroups,
recordGroups: R.mergeWith(R.concat, recordGroups, {[parentDottedName]: [dottedName]})
}
}

View File

@ -1,6 +1,6 @@
import React from 'react'
import {findRuleByDottedName, completeRuleName, findRuleByName} from './rules'
import {evaluateVariable, knownVariable} from './variables'
import {findRuleByDottedName, disambiguateRuleReference, findRuleByName} from './rules'
import {evaluateVariable} from './variables'
import R from 'ramda'
import knownMecanisms from './known-mecanisms.yaml'
import { Parser } from 'nearley'
@ -36,7 +36,7 @@ par exemple ainsi : https://github.com/Engelberg/instaparse#transforming-the-tre
- faire le calcul (déterminer les valeurs de chaque noeud)
- trouver les branches complètes pour déterminer les autres branches courtcircuitées
- ex. rule.formule est courtcircuitée si rule.non applicable est vrai
- les feuilles de "l'une de ces conditions" sont courtcircuitées si l'une d'elle est vraie
- les feuilles de 'une de ces conditions' sont courtcircuitées si l'une d'elle est vraie
- les feuilles de "toutes ces conditions" sont courtcircuitées si l'une d'elle est fausse
- ...
(- bonus : utiliser ces informations pour l'ordre de priorité des variables inconnues)
@ -58,7 +58,7 @@ let fillVariableNode = (rule, situationGate) => (parseResult) => {
let
{fragments} = parseResult,
variablePartialName = fragments.join(' . '),
variableName = completeRuleName(rule, variablePartialName),
variableName = disambiguateRuleReference(rule, variablePartialName),
// y = console.log('variableName', variableName),
variable = findRuleByDottedName(variableName),
variableIsRule = variable.formule != null,
@ -70,8 +70,8 @@ let fillVariableNode = (rule, situationGate) => (parseResult) => {
variable
),
known = !variableIsRule && knownVariable(situationGate, variableName),
nodeValue = variableIsRule ? parsedRule.nodeValue : !known ? null : evaluateVariable(situationGate, variableName)
nodeValue = variableIsRule ? parsedRule.nodeValue : evaluateVariable(situationGate, variableName, variable.format),
missingVariables = variableIsRule ? [] : (nodeValue == null ? [variableName] : [])
return {
nodeValue,
@ -81,7 +81,7 @@ let fillVariableNode = (rule, situationGate) => (parseResult) => {
name: variableName,
type: 'boolean | numeric',
explanation: parsedRule,
missingVariables: (variableIsRule || known) ? [] : [variableName],
missingVariables,
jsx: <Leaf
classes="variable"
name={fragments.join(' . ')}
@ -95,8 +95,8 @@ let treat = (situationGate, rule) => rawNode => {
if (R.is(String)(rawNode)) {
/* On a à faire à un string, donc à une expression infixe.
Elle sera traité avec le parser obtenu grâce ) NearleyJs et notre grammaire.
On obtient un objet de type Variable (avec potentiellement un 'modifier'), CalcExpression ou Comparison.
Elle sera traité avec le parser obtenu grâce à NearleyJs et notre grammaire.
On obtient un objet de type Variable (avec potentiellement un 'modifier', par exemple temporel (TODO)), CalcExpression ou Comparison.
Cet objet est alors rebalancé à 'treat'.
*/
@ -220,11 +220,16 @@ let treat = (situationGate, rule) => rawNode => {
}
let mecanisms = R.intersection(R.keys(rawNode), R.keys(knownMecanisms))
if (mecanisms.length != 1) throw 'OUPS !'
if (mecanisms.length != 1) {
console.log('Erreur : On ne devrait reconnaître que un et un seul mécanisme dans cet objet', rawNode)
throw 'OUPS !'
}
let k = R.head(mecanisms),
v = rawNode[k]
if (k === "l'une de ces conditions") {
if (k === 'une de ces conditions') {
let result = R.pipe(
R.unless(R.is(Array), () => {throw 'should be array'}),
R.reduce( (memo, next) => {
@ -241,7 +246,7 @@ let treat = (situationGate, rule) => rawNode => {
}, {
nodeValue: false,
category: 'mecanism',
name: "l'une de ces conditions",
name: 'une de ces conditions',
type: 'boolean',
explanation: []
}) // Reduce but don't use R.reduced to set the nodeValue : we need to treat all the nodes
@ -826,7 +831,7 @@ Variable:
(boolean logic):
toutes ces conditions: ([expression | boolean logic])
l'une de ces conditions: ([expression | boolean logic])
une de ces conditions: ([expression | boolean logic])
conditions exclusives: ([expression | boolean logic])
"If you write a regular expression, walk away for a cup of coffee, come back, and can't easily understand what you just wrote, then you should look for a clearer way to express what you're doing."

View File

@ -1,16 +1,30 @@
import R from 'ramda'
import {parentName, nameLeaf, findRuleByDottedName} from './rules'
import {parentName, nameLeaf, findRuleByDottedName, splitName, joinName} from './rules'
export let knownVariable = (situationGate, variableName) =>
situationGate(variableName) != null
|| situationGate(parentName(variableName)) != null
// pour 'usage', 'motif' ( le parent de 'usage') = 'usage'
export let evaluateVariable = (situationGate, variableName) => {
let evaluateBottomUp = situationGate => startingFragments => {
let rec = (parentFragments, childFragments=[]) =>
parentFragments.length == 0 ? null
: ( do {
let query = joinName(parentFragments),
expectedResult = ( R.isEmpty(childFragments) ? 'oui' : joinName(childFragments) )
situationGate(query) == null ?
rec(
R.dropLast(1)(parentFragments),
[ R.last(parentFragments), ...childFragments]
)
: situationGate(query) == expectedResult
})
return rec(startingFragments)
}
export let evaluateVariable = (situationGate, variableName, format) => {
// test rec
let value = situationGate(variableName)
return isNaN(value)
? value == 'oui' ||
situationGate(parentName(variableName)) == nameLeaf(variableName)
: value
return R.contains(format)(['nombre positif', 'période'])
? value
: evaluateBottomUp(situationGate)(splitName(variableName))
}

View File

@ -5,14 +5,12 @@ import {reducer as formReducer, formValueSelector} from 'redux-form'
import {analyseSituation} from './engine/traverse'
import { euro, months } from './components/conversation/formValueTypes.js'
import Question from './components/conversation/Question'
import Input from './components/conversation/Input'
import { STEP_ACTION, START_CONVERSATION, EXPLAIN_VARIABLE, POINT_OUT_OBJECTIVES} from './actions'
import R from 'ramda'
import {findGroup, findRuleByDottedName, parentName, collectMissingVariables} from './engine/rules'
import {constructStepMeta} from './engine/conversation'
import {findGroup, findRuleByDottedName, parentName, collectMissingVariables, recrecrecrec} from './engine/rules'
import {generateGridQuestions, generateSimpleQuestions} from './engine/generateQuestions'
import computeThemeColours from './components/themeColours'
@ -112,13 +110,15 @@ let buildNextSteps = R.pipe(
missingVariables = collectMissingVariables('groupByMissingVariable')(analysedSituation)
return missingVariables
},
// mv => console.log('l', mv),
R.keys,
/*
Certaines variables manquantes peuvent être factorisées dans des groupes.
Parmi les variables manquantes, certaines sont citées dans une règle de type 'une possibilité'.
**On appelle ça des groupes de type 'variante'.**
Il est alors plus intéressant de demander leur valeur dans un grille de possibilité plutôt que de façon indépendante.
Par exemple, au lieu de :
q1: "Pensez vous porlonger le CDD en CDI",
q1: "Pensez vous prolonger le CDD en CDI",
r1: Oui | Non
q2: "Pensez-vous qu'une rupture pour faute grave est susceptible d'arriver"
r2: Oui | Non
@ -126,67 +126,27 @@ let buildNextSteps = R.pipe(
on préfère :
q: "Pensez-vous être confronté à l'un de ces événements ?"
r: Prolongation du CDD en CDI | Rupture pour faute grave
*/
R.groupBy(parentName),
// on va maintenant construire la liste des composants React qui afficheront les questions à l'utilisateur pour que l'on obtienne les variables manquantes
R.pipe(
R.mapObjIndexed((variables, group) =>
R.pipe(
findGroup,
R.cond([
// Pas de groupe trouvé : ce sont des variables individuelles
[R.isNil, () => variables.map(dottedName => {
let rule = findRuleByDottedName(dottedName)
return Object.assign(constructStepMeta(rule),
rule.format == 'nombre positif' ||
rule.format == 'période' ?
{
component: Input,
valueType: rule.format == 'nombre positif' ? euro : months,
attributes: {
inputMode: 'numeric',
placeholder: 'votre réponse'
},
suggestions: rule.suggestions
} : {
component: Question,
choices: [
{value: 'non', label: 'Non'},
{value: 'oui', label: 'Oui'}
]
},
{
objectives: missingVariables[dottedName]
}
)})],
[R.T, group => do {
let possibilities = group['une possibilité']
Object.assign(
constructStepMeta(group),
{
component: Question,
choices:
possibilities.concat(
group['langue au chat possible'] === 'oui' ?
[{value: '_', label: 'Aucun'}] : []
)
},
{
objectives: R.pipe(
R.chain(v => missingVariables[group.dottedName + ' . ' + v]),
R.uniq()
)(possibilities)
}
)}]
])
)(group)
),
R.values,
R.unnest
)
)
r: Prolongation du CDD en CDI | Rupture pour faute grave.
Ceci est possible car ce sont tous les deux des événements et qu'ils sont incompatibles entre eux.
Pour l'instant, cela n'est possible que si les variables ont comme parent (ou grand-parent),
au sens de leur espace de nom, une règle de type 'une possibilité'.
#TODO pouvoir faire des variantes sans cette contrainte d'espace de nom
D'autres variables pourront être regroupées aussi, car elles partagent un parent, mais sans fusionner leurs questions dans l'interface. Ce sont des **groupes de type _record_ **
*/
R.reduce(
recrecrecrec //TODO reorganize
, {variantGroups: {}, recordGroups: {}}
),
// on va maintenant construire la liste des composants React qui afficheront les questions à l'utilisateur pour que l'on obtienne les variables manquantes
R.evolve({
variantGroups: generateGridQuestions,
recordGroups: generateSimpleQuestions,
}),
R.values,
R.unnest,
)
export default reduceReducers(
combineReducers({
@ -195,9 +155,8 @@ export default reduceReducers(
/* Have forms been filled or ignored ?
false means the user is reconsidering its previous input */
foldedSteps: (steps=[]) => steps,
unfoldedSteps: (steps=[]) => steps,
foldedSteps: (steps = []) => steps,
unfoldedSteps: (steps = []) => steps,
analysedSituation: (state = []) => state,
@ -205,7 +164,7 @@ export default reduceReducers(
explainedVariable,
pointedOutObjectives
pointedOutObjectives,
}),
// cross-cutting concerns because here `state` is the whole state tree
handleSteps