Merge pull request #894 from betagouv/better-barèmes
⚙️ 🔥 grosse modification des barèmesbranche-desactivée
commit
8e98c998b9
|
@ -144,19 +144,15 @@ impôt sur le revenu:
|
|||
barème:
|
||||
assiette: revenu imposable
|
||||
tranches:
|
||||
- en-dessous de: 9807
|
||||
taux: 0%
|
||||
- de: 9807
|
||||
à: 27086
|
||||
taux: 14%
|
||||
- de: 27086
|
||||
à: 72617
|
||||
taux: 30%
|
||||
- de: 72617
|
||||
à: 153783
|
||||
taux: 41%
|
||||
- au-dessus de: 153783
|
||||
taux: 45%
|
||||
- taux: 0%
|
||||
plafond: 9807
|
||||
- taux: 14%
|
||||
plafond: 27086
|
||||
- taux: 30%
|
||||
plafond: 72617
|
||||
- taux: 41%
|
||||
plafond: 153783
|
||||
- taux: 45%
|
||||
```
|
||||
|
||||
La syntaxe hiérarchique de Yaml permet d'imbriquer les mécanismes :
|
||||
|
|
|
@ -95,8 +95,8 @@ artiste-auteur . cotisations . vieillesse:
|
|||
assiette: assiette
|
||||
composantes:
|
||||
- nom: plafonnée
|
||||
plafond: contrat salarié . plafond sécurité sociale
|
||||
taux: contrat salarié . vieillesse . taux salarié plafonné - 0.75%
|
||||
plafond: contrat salarié . plafond sécurité sociale
|
||||
- nom: non plafonnée
|
||||
taux: contrat salarié . vieillesse . taux salarié non plafonné - 0.4%
|
||||
|
||||
|
@ -116,8 +116,8 @@ artiste-auteur . cotisations . CSG-CRDS . abattement:
|
|||
formule:
|
||||
multiplication:
|
||||
assiette: revenus . traitements et salaires
|
||||
plafond: 4 * contrat salarié . plafond sécurité sociale
|
||||
taux: 1.75%
|
||||
plafond: 4 * contrat salarié . plafond sécurité sociale
|
||||
|
||||
artiste-auteur . cotisations . CSG-CRDS . CSG:
|
||||
formule:
|
||||
|
|
|
@ -39,15 +39,13 @@ contrat salarié . convention collective . HCR . majoration heures supplémentai
|
|||
formule:
|
||||
barème:
|
||||
assiette: temps de travail . heures supplémentaires
|
||||
multiplicateur: 1 heure/semaine * période . semaines par mois
|
||||
multiplicateur: période . semaines par mois
|
||||
tranches:
|
||||
- en-dessous de: 4
|
||||
taux: 10%
|
||||
- de: 4
|
||||
à: 8
|
||||
taux: 20%
|
||||
- au-dessus de: 8
|
||||
taux: 50%
|
||||
- taux: 10%
|
||||
plafond: 4 heures/semaine
|
||||
- taux: 20%
|
||||
plafond: 8 heures/semaine
|
||||
- taux: 50%
|
||||
|
||||
contrat salarié . convention collective . SVP:
|
||||
titre: Spectacle vivant privé (beta)
|
||||
|
@ -298,28 +296,21 @@ contrat salarié . convention collective . sport . cotisations . assiette forfai
|
|||
applicable si: assiette franchisée < SMIC horaire * 115 heures/mois
|
||||
remplace: contrat salarié . cotisations . assiette forfaitaire
|
||||
formule:
|
||||
multiplication:
|
||||
assiette: SMIC horaire
|
||||
facteur:
|
||||
barème linéaire:
|
||||
assiette: assiette franchisée [€/mois]
|
||||
multiplicateur: SMIC horaire
|
||||
unité: heures/mois
|
||||
tranches:
|
||||
- en-dessous de: 45
|
||||
montant: 5
|
||||
- de: 45
|
||||
à: 60
|
||||
montant: 15
|
||||
- de: 60
|
||||
à: 80
|
||||
montant: 25
|
||||
- de: 80
|
||||
à: 100
|
||||
montant: 35
|
||||
- de: 100
|
||||
à: 115
|
||||
montant: 50
|
||||
grille:
|
||||
assiette: assiette franchisée [€/mois]
|
||||
multiplicateur: SMIC horaire / 1 mois
|
||||
unité: €/mois
|
||||
tranches:
|
||||
- montant: 5 * SMIC horaire
|
||||
plafond: 45 heures
|
||||
- montant: 15 * SMIC horaire
|
||||
plafond: 60 heures
|
||||
- montant: 25 * SMIC horaire
|
||||
plafond: 80 heures
|
||||
- montant: 35 * SMIC horaire
|
||||
plafond: 100 heures
|
||||
- montant: 50 * SMIC horaire
|
||||
plafond: 115 heures
|
||||
|
||||
contrat salarié . convention collective . sport . primes . nombre de manifestations:
|
||||
question: Combien de manifestations rémunérées le joueur a-t'il effectué ?
|
||||
|
|
|
@ -182,10 +182,9 @@ dirigeant . auto-entrepreneur . cotisations et contributions . cotisations:
|
|||
assiette: base des cotisations
|
||||
multiplicateur: plafond ACRE
|
||||
tranches:
|
||||
- en-dessous de: 1
|
||||
taux: taux de cotisation * (100% - taux ACRE)
|
||||
- au-dessus de: 1
|
||||
taux: taux de cotisation
|
||||
- taux: taux de cotisation * (100% - taux ACRE)
|
||||
plafond: 1
|
||||
- taux: taux de cotisation
|
||||
|
||||
références:
|
||||
La protection sociale du micro-entrepreneur: https://bpifrance-creation.fr/encyclopedie/micro-entreprise-regime-auto-entrepreneur/fiscal-social-comptable/protection-sociale
|
||||
|
@ -409,14 +408,14 @@ dirigeant . indépendant . cotisations et contributions . exonérations . ACRE .
|
|||
|
||||
dirigeant . indépendant . cotisations et contributions . exonérations . ACRE . taux:
|
||||
formule:
|
||||
barème continu:
|
||||
assiette: revenu professionnel
|
||||
taux progressif:
|
||||
assiette: assiette des cotisations
|
||||
multiplicateur: PSS proratisé
|
||||
points:
|
||||
0: 100%
|
||||
0.75: 100%
|
||||
1: 0%
|
||||
retourne seulement le taux: oui
|
||||
tranches:
|
||||
- taux: 100%
|
||||
plafond: 75%
|
||||
- taux: 0%
|
||||
plafond: 100%
|
||||
|
||||
dirigeant . indépendant . revenu net de cotisations:
|
||||
formule:
|
||||
|
@ -430,16 +429,7 @@ dirigeant . indépendant . revenu net de cotisations:
|
|||
unité par défaut: €/an
|
||||
|
||||
dirigeant . indépendant . revenu professionnel:
|
||||
titre: revenu professionnel (net imposable)
|
||||
unité par défaut: €/an
|
||||
description: |
|
||||
C'est le revenu net de cotisations déductibles du travailleur indépendant, qui sert de base au calcul des cotisations et de l'impôt pour les indépendants.
|
||||
|
||||
Attention, **notre calcul est fait au régime de croisière**:
|
||||
l'indépendant qui se lance paiera pendant ses 2 premières années un forfait relativement réduit de cotisations sociales. Il devra ensuite régulariser cette situation par rapport au revenu qu'il a vraiment perçu.
|
||||
|
||||
Il faut donc voir ce calcul comme *le montant qui devra de toute façon être payé* à court terme après 2 ans d'exercice.
|
||||
|
||||
formule:
|
||||
inversion numérique:
|
||||
avec:
|
||||
|
@ -449,6 +439,13 @@ dirigeant . indépendant . revenu professionnel:
|
|||
- entreprise . chiffre d'affaires
|
||||
- entreprise . chiffre d'affaires minimum
|
||||
|
||||
dirigeant . indépendant . assiette des cotisations:
|
||||
unité par défaut: €/an
|
||||
formule:
|
||||
encadrement:
|
||||
plancher: 0
|
||||
valeur: revenu professionnel
|
||||
|
||||
dirigeant . indépendant . conjoint collaborateur:
|
||||
question: Avez-vous un conjoint collaborateur ?
|
||||
description: |
|
||||
|
@ -488,14 +485,14 @@ dirigeant . indépendant . conjoint collaborateur . assiette . revenu avec parta
|
|||
**Cette option baisse le montant des cotisations à payer pour le gérant, mais elle diminue également ses contreparties sociales (pension de retraite, indemnité décès, etc)**
|
||||
formule: assiette = 'revenu avec partage'
|
||||
remplace:
|
||||
règle: revenu professionnel
|
||||
par: revenu professionnel - cotisations . assiette
|
||||
règle: assiette des cotisations
|
||||
par: assiette des cotisations - cotisations . assiette
|
||||
dans:
|
||||
- cotisations et contributions . cotisations . retraite de base
|
||||
- cotisations et contributions . cotisations . retraite complémentaire
|
||||
- cotisations et contributions . cotisations . invalidité et décès
|
||||
dirigeant . indépendant . conjoint collaborateur . assiette . revenu sans partage:
|
||||
description: Le conjoint collaborateur paiera des cotisations sociales calculées sur une base d'un pourcentage du revenu professionnel du gérant de l'entreprise (un tiers ou la moitié).
|
||||
description: Le conjoint collaborateur paiera des cotisations sociales calculées sur une base d'un pourcentage du assiette des cotisations du gérant de l'entreprise (un tiers ou la moitié).
|
||||
formule: assiette = 'revenu sans partage'
|
||||
|
||||
dirigeant . indépendant . conjoint collaborateur . assiette . pourcentage:
|
||||
|
@ -520,7 +517,7 @@ dirigeant . indépendant . conjoint collaborateur . cotisations . assiette:
|
|||
titre: assiette conjoint collaborateur
|
||||
formule:
|
||||
multiplication:
|
||||
assiette: revenu professionnel
|
||||
assiette: assiette des cotisations
|
||||
taux: 1 / 3
|
||||
variations:
|
||||
- si: assiette . forfaitaire
|
||||
|
@ -553,21 +550,19 @@ dirigeant . indépendant . conjoint collaborateur . cotisations . retraite de ba
|
|||
assiette: assiette retraite
|
||||
multiplicateur: plafond sécurité sociale temps plein
|
||||
tranches:
|
||||
- en-dessous de: 1
|
||||
taux: 17.75%
|
||||
- au-dessus de: 1
|
||||
taux: 0.6%
|
||||
- taux: 17.75%
|
||||
plafond: 1
|
||||
- taux: 0.6%
|
||||
|
||||
dirigeant . indépendant . conjoint collaborateur . cotisations . retraite complémentaire:
|
||||
formule:
|
||||
barème:
|
||||
assiette: retraite complémentaire . assiette [€/an]
|
||||
assiette: retraite complémentaire . assiette
|
||||
tranches:
|
||||
- en-dessous de: 37960
|
||||
taux: 7%
|
||||
- de: 37960
|
||||
à: 162096
|
||||
taux: 8%
|
||||
- taux: 7%
|
||||
plafond: cotisations et contributions . cotisations . retraite complémentaire . plafond
|
||||
- taux: 8%
|
||||
plafond: 4 * plafond sécurité sociale temps plein
|
||||
|
||||
dirigeant . indépendant . conjoint collaborateur . cotisations . retraite complémentaire . assiette:
|
||||
titre: assiette retraite complémentaire
|
||||
|
@ -589,8 +584,8 @@ dirigeant . indépendant . conjoint collaborateur . cotisations . invalidité et
|
|||
formule:
|
||||
multiplication:
|
||||
assiette: assiette
|
||||
plafond: plafond sécurité sociale temps plein
|
||||
taux: 1.3%
|
||||
plafond: plafond sécurité sociale temps plein
|
||||
|
||||
dirigeant . indépendant . conjoint collaborateur . cotisations . indemnités journalières maladie:
|
||||
formule:
|
||||
|
@ -634,16 +629,19 @@ dirigeant . indépendant . cotisations et contributions . cotisations . déducti
|
|||
par défaut: 0
|
||||
|
||||
dirigeant . indépendant . cotisations et contributions . cotisations . déduction tabac . revenus déduits:
|
||||
titre: revenu professionnel (avec déduction tabac)
|
||||
titre: assiette des cotisations (avec déduction tabac)
|
||||
applicable si: déduction tabac
|
||||
remplace:
|
||||
règle: revenu professionnel
|
||||
règle: assiette des cotisations
|
||||
dans:
|
||||
- retraite de base
|
||||
- retraite complémentaire
|
||||
- invalidité et décès
|
||||
- conjoint collaborateur
|
||||
formule: revenu professionnel - déduction tabac
|
||||
formule:
|
||||
allègement:
|
||||
assiette: assiette des cotisations
|
||||
abattement: déduction tabac
|
||||
|
||||
dirigeant . rattachement CIPAV:
|
||||
description: |
|
||||
|
@ -686,12 +684,17 @@ dirigeant . indépendant . cotisations et contributions . cotisations . maladie
|
|||
remplace: maladie
|
||||
rend non applicable: indemnités journalières maladie
|
||||
formule:
|
||||
barème continu:
|
||||
assiette: indépendant . revenu professionnel
|
||||
multiplicateur: plafond sécurité sociale temps plein
|
||||
points:
|
||||
0: 1.5%
|
||||
1.1: 6.5%
|
||||
multiplication:
|
||||
assiette: indépendant . assiette des cotisations
|
||||
taux:
|
||||
taux progressif:
|
||||
assiette: indépendant . assiette des cotisations
|
||||
multiplicateur: plafond sécurité sociale temps plein
|
||||
tranches:
|
||||
- plafond: 0%
|
||||
taux: 1.5%
|
||||
- plafond: 110%
|
||||
taux: 6.5%
|
||||
références:
|
||||
secu-independants.fr: https://www.secu-independants.fr/cotisations/calcul-des-cotisations/taux-de-cotisations
|
||||
guide urssaf (pdf): https://www.urssaf.fr/portail/files/live/sites/urssaf/files/documents/Guide-Professions-liberales.pdf
|
||||
|
@ -702,11 +705,11 @@ dirigeant . indépendant . cotisations et contributions . cotisations . maladie
|
|||
formule:
|
||||
variations:
|
||||
- si: situation personnelle . RSA
|
||||
alors: revenu professionnel
|
||||
alors: assiette des cotisations
|
||||
- sinon:
|
||||
encadrement:
|
||||
plancher: 40% * plafond sécurité sociale temps plein
|
||||
valeur: revenu professionnel
|
||||
valeur: assiette des cotisations
|
||||
références:
|
||||
secu-independants.fr: https://www.secu-independants.fr/cotisations/calcul-des-cotisations/cotisations-minimales/
|
||||
|
||||
|
@ -725,10 +728,9 @@ dirigeant . indépendant . cotisations et contributions . cotisations . maladie:
|
|||
assiette: assiette
|
||||
multiplicateur: plafond sécurité sociale temps plein
|
||||
tranches:
|
||||
- en-dessous de: 5
|
||||
taux: taux variable
|
||||
- au-dessus de: 5
|
||||
taux: 6.5%
|
||||
- taux: taux variable
|
||||
plafond: 5
|
||||
- taux: 6.5%
|
||||
références:
|
||||
décret formule de calcul: https://www.legifrance.gouv.fr/affichTexte.do?cidTexte=JORFTEXT000036342439&categorieLien=id
|
||||
note: |
|
||||
|
@ -757,7 +759,7 @@ dirigeant . indépendant . cotisations et contributions . cotisations . maladie
|
|||
formule:
|
||||
multiplication:
|
||||
assiette: 5%
|
||||
taux: revenu professionnel / seuil supérieur de réduction
|
||||
taux: assiette des cotisations / seuil supérieur de réduction
|
||||
|
||||
dirigeant . indépendant . cotisations et contributions . cotisations . maladie . seuil supérieur de réduction:
|
||||
formule:
|
||||
|
@ -767,14 +769,16 @@ dirigeant . indépendant . cotisations et contributions . cotisations . maladie
|
|||
|
||||
dirigeant . indépendant . cotisations et contributions . cotisations . maladie . taux:
|
||||
formule:
|
||||
barème continu:
|
||||
retourne seulement le taux: oui
|
||||
assiette: revenu professionnel
|
||||
taux progressif:
|
||||
assiette: assiette des cotisations
|
||||
multiplicateur: plafond sécurité sociale temps plein
|
||||
points:
|
||||
0: 0%
|
||||
0.4: 3.168%
|
||||
1.1: 6.35%
|
||||
tranches:
|
||||
- plafond: 0%
|
||||
taux: 0%
|
||||
- plafond: 40%
|
||||
taux: 3.168%
|
||||
- plafond: 110%
|
||||
taux: 6.35%
|
||||
note: |
|
||||
Cette cotisation est à la base très simple : la cotisation maladie est de 7.2% jusqu'à 5 fois le plafond de la sécurité sociale, puis 6.5% au-delà. Cependant :
|
||||
- pour son recouvrement, cette cotisation est séparée en 2 : maladie et maladie 2, cette deuxième au taux de 0.85%. Ainsi le montant de 7.2% cité dans le décret est rabaissé à 6.35% dans nos calculs.
|
||||
|
@ -791,11 +795,11 @@ dirigeant . rattachement CIPAV . retraite de base:
|
|||
multiplicateur:
|
||||
composantes:
|
||||
- nom: tranche 1
|
||||
plafond: plafond sécurité sociale temps plein
|
||||
taux: 8.23%
|
||||
plafond: plafond sécurité sociale temps plein
|
||||
- nom: tranche 2
|
||||
plafond: 5 * plafond sécurité sociale temps plein
|
||||
taux: 1.87%
|
||||
plafond: 5 * plafond sécurité sociale temps plein
|
||||
|
||||
dirigeant . indépendant . cotisations et contributions . cotisations . retraite de base:
|
||||
formule:
|
||||
|
@ -803,21 +807,20 @@ dirigeant . indépendant . cotisations et contributions . cotisations . retraite
|
|||
assiette: assiette
|
||||
multiplicateur: plafond sécurité sociale temps plein
|
||||
tranches:
|
||||
- en-dessous de: 1
|
||||
taux: 17.75%
|
||||
- au-dessus de: 1
|
||||
taux: 0.6%
|
||||
- taux: 17.75%
|
||||
plafond: 1
|
||||
- taux: 0.6%
|
||||
|
||||
dirigeant . indépendant . cotisations et contributions . cotisations . retraite de base . assiette:
|
||||
titre: assiette retraite de base
|
||||
formule:
|
||||
variations:
|
||||
- si: situation personnelle . RSA
|
||||
alors: revenu professionnel
|
||||
alors: assiette des cotisations
|
||||
- sinon:
|
||||
encadrement:
|
||||
plancher: 11.5% * plafond sécurité sociale temps plein
|
||||
valeur: revenu professionnel
|
||||
valeur: assiette des cotisations
|
||||
|
||||
références:
|
||||
secu-independants.fr: https://www.secu-independants.fr/cotisations/calcul-des-cotisations/cotisations-minimales/
|
||||
|
@ -825,31 +828,25 @@ dirigeant . indépendant . cotisations et contributions . cotisations . retraite
|
|||
dirigeant . rattachement CIPAV . retraite complémentaire:
|
||||
remplace: indépendant . cotisations et contributions . cotisations . retraite complémentaire
|
||||
formule:
|
||||
barème linéaire:
|
||||
assiette: indépendant . revenu professionnel [€/an]
|
||||
grille:
|
||||
assiette: indépendant . assiette des cotisations
|
||||
unité: €/an
|
||||
tranches:
|
||||
- en-dessous de: 26580
|
||||
montant: 1315
|
||||
- de: 26581
|
||||
à: 49280
|
||||
montant: 2630
|
||||
- de: 49281
|
||||
à: 57850
|
||||
montant: 3945
|
||||
- de: 57851
|
||||
à: 66400
|
||||
montant: 6575
|
||||
- de: 66401
|
||||
à: 83060
|
||||
montant: 9205
|
||||
- de: 83061
|
||||
à: 103180
|
||||
montant: 14465
|
||||
- de: 103181
|
||||
à: 123300
|
||||
montant: 15780
|
||||
- au-dessus de: 123300
|
||||
montant: 17095
|
||||
- montant: 1315
|
||||
plafond: 26581 €/an
|
||||
- montant: 2630
|
||||
plafond: 49281 €/an
|
||||
- montant: 3945
|
||||
plafond: 57851 €/an
|
||||
- montant: 6575
|
||||
plafond: 66401 €/an
|
||||
- montant: 9205
|
||||
plafond: 83061 €/an
|
||||
- montant: 14465
|
||||
plafond: 103181 €/an
|
||||
- montant: 15780
|
||||
plafond: 123301 €/an
|
||||
- montant: 17095
|
||||
|
||||
dirigeant . indépendant . cotisations et contributions . cotisations . retraite complémentaire . taux spécifique PLNR:
|
||||
applicable si:
|
||||
|
@ -869,30 +866,35 @@ dirigeant . indépendant . cotisations et contributions . cotisations . retraite
|
|||
remplace: retraite complémentaire
|
||||
formule:
|
||||
barème:
|
||||
assiette: revenu professionnel
|
||||
assiette: assiette des cotisations
|
||||
multiplicateur: plafond sécurité sociale temps plein
|
||||
tranches:
|
||||
- de: 1
|
||||
à: 4
|
||||
taux: 14%
|
||||
- taux: 0%
|
||||
plafond: 1
|
||||
- taux: 14%
|
||||
plafond: 4
|
||||
|
||||
dirigeant . indépendant . cotisations et contributions . cotisations . retraite complémentaire:
|
||||
formule:
|
||||
barème:
|
||||
assiette: revenu professionnel [€/an]
|
||||
assiette: assiette des cotisations
|
||||
tranches:
|
||||
- en-dessous de: 37960
|
||||
taux: 7%
|
||||
- de: 37960
|
||||
à: 162096
|
||||
taux: 8%
|
||||
- taux: 7%
|
||||
plafond: plafond
|
||||
- taux: 8%
|
||||
plafond: 4 * plafond sécurité sociale temps plein
|
||||
|
||||
dirigeant . indépendant . cotisations et contributions . cotisations . retraite complémentaire . plafond:
|
||||
acronyme: PRCI
|
||||
titre: plafond retraite complémentaire des indépendants
|
||||
formule: 38340 €/an
|
||||
|
||||
dirigeant . indépendant . cotisations et contributions . cotisations . invalidité et décès:
|
||||
formule:
|
||||
multiplication:
|
||||
assiette: assiette
|
||||
plafond: plafond sécurité sociale temps plein
|
||||
taux: 1.3%
|
||||
plafond: plafond sécurité sociale temps plein
|
||||
|
||||
# TODO invalidité décès pour les libéraux
|
||||
# 3 classes, 76, 228, 380€
|
||||
|
@ -901,10 +903,10 @@ dirigeant . indépendant . cotisations et contributions . cotisations . invalidi
|
|||
formule:
|
||||
variations:
|
||||
- si: situation personnelle . RSA
|
||||
alors: revenu professionnel
|
||||
alors: assiette des cotisations
|
||||
- sinon:
|
||||
encadrement:
|
||||
valeur: revenu professionnel
|
||||
valeur: assiette des cotisations
|
||||
plancher: 11.5% * plafond sécurité sociale temps plein
|
||||
références:
|
||||
secu-independants.fr: https://www.secu-independants.fr/cotisations/calcul-des-cotisations/cotisations-minimales/
|
||||
|
@ -980,13 +982,17 @@ dirigeant . indépendant . cotisations et contributions . formation professionne
|
|||
|
||||
dirigeant . indépendant . cotisations et contributions . cotisations . allocations familiales:
|
||||
formule:
|
||||
barème continu:
|
||||
assiette: revenu professionnel
|
||||
multiplicateur: plafond sécurité sociale temps plein
|
||||
points:
|
||||
0: 0%
|
||||
1.1: 0%
|
||||
1.4: 3.1%
|
||||
multiplication:
|
||||
assiette: assiette des cotisations
|
||||
taux:
|
||||
taux progressif:
|
||||
assiette: assiette des cotisations
|
||||
multiplicateur: plafond sécurité sociale temps plein
|
||||
tranches:
|
||||
- plafond: 110%
|
||||
taux: 0%
|
||||
- plafond: 140%
|
||||
taux: 3.1%
|
||||
|
||||
dirigeant . indépendant . cotisations et contributions . exonérations:
|
||||
période: flexible
|
||||
|
@ -1001,8 +1007,8 @@ dirigeant . indépendant . cotisations et contributions . exonérations . ZFU:
|
|||
multiplication:
|
||||
assiette: cotisations . maladie
|
||||
# TODO : ceci n'est pas bon (le plafond est sur le revenu exonéré, et est proratisé en début / fin d'éxo)
|
||||
plafond: 3042 heures/an * SMIC horaire
|
||||
taux: taux
|
||||
plafond: 3042 heures/an * SMIC horaire
|
||||
|
||||
dirigeant . indépendant . cotisations et contributions . exonérations . âge:
|
||||
question: Bénéficiez-vous du dispositif d'exonération "âge"
|
||||
|
@ -1024,30 +1030,41 @@ dirigeant . indépendant . cotisations et contributions . exonérations . invali
|
|||
dirigeant . indépendant . cotisations et contributions . exonérations . ZFU . taux:
|
||||
titre: taux exonération ZFU
|
||||
formule:
|
||||
barème continu:
|
||||
taux progressif:
|
||||
assiette: établissement . ZFU . durée d'implantation en fin d'année [an]
|
||||
retourne seulement le taux: oui
|
||||
variations:
|
||||
- si: entreprise . effectif < 5
|
||||
alors:
|
||||
points:
|
||||
0: 100%
|
||||
5: 100%
|
||||
6: 60%
|
||||
10: 60%
|
||||
11: 40%
|
||||
12: 40%
|
||||
13: 20%
|
||||
14: 20%
|
||||
15: 0%
|
||||
tranches:
|
||||
- plafond: 5 ans
|
||||
taux: 100%
|
||||
- plafond: 6 ans
|
||||
taux: 60%
|
||||
- plafond: 10 ans
|
||||
taux: 60%
|
||||
- plafond: 11 ans
|
||||
taux: 40%
|
||||
- plafond: 12 ans
|
||||
taux: 40%
|
||||
- plafond: 13 ans
|
||||
taux: 20%
|
||||
- plafond: 14 ans
|
||||
taux: 20%
|
||||
- plafond: 15 ans
|
||||
taux: 0%
|
||||
- sinon:
|
||||
points:
|
||||
0: 100%
|
||||
5: 100%
|
||||
6: 60%
|
||||
7: 40%
|
||||
8: 20%
|
||||
9: 0%
|
||||
tranches:
|
||||
- plafond: 5 ans
|
||||
taux: 100%
|
||||
- plafond: 6 ans
|
||||
taux: 60%
|
||||
- plafond: 7 ans
|
||||
taux: 40%
|
||||
- plafond: 8 ans
|
||||
taux: 20%
|
||||
- plafond: 9 ans
|
||||
taux: 0%
|
||||
|
||||
dirigeant . indépendant . cotisations et contributions . cotisations . maladie domiciliation fiscale étranger:
|
||||
applicable si: situation personnelle . domiciliation fiscale à l'étranger
|
||||
|
|
|
@ -83,15 +83,13 @@ entreprise . impôt sur les sociétés:
|
|||
unité: €/an
|
||||
formule:
|
||||
barème:
|
||||
assiette: bénéfice [€/an]
|
||||
assiette: bénéfice
|
||||
tranches:
|
||||
- en-dessous de: 38120
|
||||
taux: 15%
|
||||
- de: 38120
|
||||
à: 500000
|
||||
taux: 28%
|
||||
- au-dessus de: 500000
|
||||
taux: 33.3%
|
||||
- taux: 15%
|
||||
plafond: 38120 €/an
|
||||
- taux: 28%
|
||||
plafond: 500000 €/an
|
||||
- taux: 33.3%
|
||||
références:
|
||||
fiche service-public.fr: https://www.service-public.fr/professionnels-entreprises/vosdroits/F23575
|
||||
|
||||
|
@ -279,8 +277,8 @@ entreprise . taxe sur les salaires:
|
|||
assiette: barème
|
||||
franchise: 1200 €/an
|
||||
décote:
|
||||
plafond: 2040 €/an
|
||||
taux: 75%
|
||||
plafond: 2040 €/an
|
||||
abattement: abattement associations
|
||||
|
||||
entreprise . catégorie d'activité:
|
||||
|
|
|
@ -128,21 +128,17 @@ impôt . impôt sur le revenu:
|
|||
unité par défaut: €/an
|
||||
formule:
|
||||
barème:
|
||||
assiette: revenu abattu [€/an]
|
||||
assiette: revenu abattu
|
||||
tranches:
|
||||
- en-dessous de: 10064
|
||||
taux: 0%
|
||||
- de: 10064
|
||||
à: 25659
|
||||
taux: 11%
|
||||
- de: 25659
|
||||
à: 73369
|
||||
taux: 30%
|
||||
- de: 73369
|
||||
à: 157806
|
||||
taux: 41%
|
||||
- au-dessus de: 157806
|
||||
taux: 45%
|
||||
- taux: 0%
|
||||
plafond: 10064 €/an
|
||||
- taux: 11%
|
||||
plafond: 25659 €/an
|
||||
- taux: 30%
|
||||
plafond: 73369 €/an
|
||||
- taux: 41%
|
||||
plafond: 157806 €/an
|
||||
- taux: 45%
|
||||
exemples:
|
||||
- nom: Haut salaire de ~ 10 000€ mensuels
|
||||
situation:
|
||||
|
@ -158,8 +154,8 @@ impôt . impôt sur le revenu à payer:
|
|||
allègement:
|
||||
assiette: impôt sur le revenu
|
||||
décote:
|
||||
plafond: 1717 €/an
|
||||
taux: 45.25%
|
||||
plafond: 1717 €/an
|
||||
exemples:
|
||||
- nom: Salaire d'un cadre
|
||||
situation:
|
||||
|
@ -185,15 +181,13 @@ impôt . CEHR:
|
|||
note: Attention, ce barème concerne les foyers célibataires. Pour les couples, le barème est adapté pour ne pas leur appliquer la même imposition alors qu'ils sont individuellement deux fois moins riches.
|
||||
formule:
|
||||
barème:
|
||||
assiette: revenu fiscal de référence [€/an]
|
||||
assiette: revenu fiscal de référence
|
||||
tranches:
|
||||
- en-dessous de: 250000
|
||||
taux: 0%
|
||||
- de: 250000
|
||||
à: 500000
|
||||
taux: 3%
|
||||
- au-dessus de: 500000
|
||||
taux: 4%
|
||||
- taux: 0%
|
||||
plafond: 250000 €/an
|
||||
- taux: 3%
|
||||
plafond: 500000 €/an
|
||||
- taux: 4%
|
||||
références:
|
||||
contribution exceptionnelle sur les hauts revenus: https://www.service-public.fr/particuliers/vosdroits/F31130
|
||||
Article 223 sexies du Code général des impôts: https://www.legifrance.gouv.fr/affichCode.do?idSectionTA=LEGISCTA000025049019&cidTexte=LEGITEXT000006069577
|
||||
|
@ -202,174 +196,94 @@ impôt . CEHR:
|
|||
impôt . taux neutre d'impôt sur le revenu . barème Guadeloupe Réunion Martinique:
|
||||
icônes: 🇬🇵🇷🇪 🇲🇶
|
||||
formule:
|
||||
barème linéaire:
|
||||
assiette: revenu imposable [€/mois]
|
||||
retourne seulement le taux: oui
|
||||
grille:
|
||||
assiette: revenu imposable
|
||||
tranches:
|
||||
- de: 0
|
||||
à: 1625
|
||||
taux: 0%
|
||||
|
||||
- de: 1626
|
||||
à: 1723
|
||||
taux: 0.5%
|
||||
|
||||
- de: 1724
|
||||
à: 1899
|
||||
taux: 1.3%
|
||||
|
||||
- de: 1900
|
||||
à: 2074
|
||||
taux: 2.1%
|
||||
|
||||
- de: 2075
|
||||
à: 2291
|
||||
taux: 2.9%
|
||||
|
||||
- de: 2292
|
||||
à: 2416
|
||||
taux: 3.5%
|
||||
|
||||
- de: 2417
|
||||
à: 2499
|
||||
taux: 4.1%
|
||||
|
||||
- de: 2500
|
||||
à: 2749
|
||||
taux: 5.3%
|
||||
|
||||
- de: 2750
|
||||
à: 3399
|
||||
taux: 7.5%
|
||||
|
||||
- de: 3400
|
||||
à: 4349
|
||||
taux: 9.9%
|
||||
|
||||
- de: 4350
|
||||
à: 4941
|
||||
taux: 11.9%
|
||||
|
||||
- de: 4942
|
||||
à: 5724
|
||||
taux: 13.8%
|
||||
|
||||
- de: 5725
|
||||
à: 6857
|
||||
taux: 15.8%
|
||||
|
||||
- de: 6858
|
||||
à: 7624
|
||||
taux: 17.9%
|
||||
|
||||
- de: 7625
|
||||
à: 8666
|
||||
taux: 20%
|
||||
|
||||
- de: 8667
|
||||
à: 11916
|
||||
taux: 24%
|
||||
|
||||
- de: 11917
|
||||
à: 15832
|
||||
taux: 28%
|
||||
|
||||
- de: 15833
|
||||
à: 24166
|
||||
taux: 33%
|
||||
|
||||
- de: 24167
|
||||
à: 52824
|
||||
taux: 38%
|
||||
|
||||
- au-dessus de: 52825
|
||||
taux: 43%
|
||||
- montant: 0%
|
||||
plafond: 1626 €/mois
|
||||
- montant: 0.5%
|
||||
plafond: 1724 €/mois
|
||||
- montant: 1.3%
|
||||
plafond: 1900 €/mois
|
||||
- montant: 2.1%
|
||||
plafond: 2075 €/mois
|
||||
- montant: 2.9%
|
||||
plafond: 2292 €/mois
|
||||
- montant: 3.5%
|
||||
plafond: 2417 €/mois
|
||||
- montant: 4.1%
|
||||
plafond: 2500 €/mois
|
||||
- montant: 5.3%
|
||||
plafond: 2750 €/mois
|
||||
- montant: 7.5%
|
||||
plafond: 3400 €/mois
|
||||
- montant: 9.9%
|
||||
plafond: 4350 €/mois
|
||||
- montant: 11.9%
|
||||
plafond: 4942 €/mois
|
||||
- montant: 13.8%
|
||||
plafond: 5725 €/mois
|
||||
- montant: 15.8%
|
||||
plafond: 6858 €/mois
|
||||
- montant: 17.9%
|
||||
plafond: 7625 €/mois
|
||||
- montant: 20%
|
||||
plafond: 8667 €/mois
|
||||
- montant: 24%
|
||||
plafond: 11917 €/mois
|
||||
- montant: 28%
|
||||
plafond: 15833 €/mois
|
||||
- montant: 33%
|
||||
plafond: 24167 €/mois
|
||||
- montant: 38%
|
||||
plafond: 52825 €/mois
|
||||
- montant: 43%
|
||||
|
||||
impôt . taux neutre d'impôt sur le revenu . barème Guyane Mayotte:
|
||||
icônes: 🇬🇾 🇾🇹
|
||||
formule:
|
||||
barème linéaire:
|
||||
assiette: revenu imposable [€/mois]
|
||||
retourne seulement le taux: oui
|
||||
grille:
|
||||
assiette: revenu imposable
|
||||
tranches:
|
||||
- de: 0
|
||||
à: 1740
|
||||
taux: 0%
|
||||
|
||||
- de: 1741
|
||||
à: 1882
|
||||
taux: 0.5%
|
||||
|
||||
- de: 1883
|
||||
à: 2099
|
||||
taux: 1.3%
|
||||
|
||||
- de: 2100
|
||||
à: 2366
|
||||
taux: 2.1%
|
||||
|
||||
- de: 2367
|
||||
à: 2457
|
||||
taux: 2.9%
|
||||
|
||||
- de: 2458
|
||||
à: 2541
|
||||
taux: 3.5%
|
||||
|
||||
- de: 2542
|
||||
à: 2624
|
||||
taux: 4.1%
|
||||
|
||||
- de: 2625
|
||||
à: 2916
|
||||
taux: 5.3%
|
||||
|
||||
- de: 2917
|
||||
à: 4024
|
||||
taux: 7.5%
|
||||
|
||||
- de: 4025
|
||||
à: 5207
|
||||
taux: 9.9%
|
||||
|
||||
- de: 5208
|
||||
à: 5874
|
||||
taux: 11.9%
|
||||
|
||||
- de: 5875
|
||||
à: 6816
|
||||
taux: 13.8%
|
||||
|
||||
- de: 6817
|
||||
à: 7499
|
||||
taux: 15.8%
|
||||
|
||||
- de: 7500
|
||||
à: 8307
|
||||
taux: 17.9%
|
||||
|
||||
- de: 8308
|
||||
à: 9641
|
||||
taux: 20%
|
||||
|
||||
- de: 9642
|
||||
à: 12970
|
||||
taux: 24%
|
||||
|
||||
- de: 12971
|
||||
à: 16499
|
||||
taux: 28%
|
||||
|
||||
- de: 16500
|
||||
à: 26442
|
||||
taux: 33%
|
||||
|
||||
- de: 26443
|
||||
à: 55814
|
||||
taux: 38%
|
||||
|
||||
- au-dessus de: 55815
|
||||
taux: 43%
|
||||
- montant: 0%
|
||||
plafond: 1740 €/mois
|
||||
- montant: 0.5%
|
||||
plafond: 1883 €/mois
|
||||
- montant: 1.3%
|
||||
plafond: 2100 €/mois
|
||||
- montant: 2.1%
|
||||
plafond: 2367 €/mois
|
||||
- montant: 2.9%
|
||||
plafond: 2458 €/mois
|
||||
- montant: 3.5%
|
||||
plafond: 2542 €/mois
|
||||
- montant: 4.1%
|
||||
plafond: 2625 €/mois
|
||||
- montant: 5.3%
|
||||
plafond: 2917 €/mois
|
||||
- montant: 7.5%
|
||||
plafond: 4025 €/mois
|
||||
- montant: 9.9%
|
||||
plafond: 5208 €/mois
|
||||
- montant: 11.9%
|
||||
plafond: 5875 €/mois
|
||||
- montant: 13.8%
|
||||
plafond: 6817 €/mois
|
||||
- montant: 15.8%
|
||||
plafond: 7500 €/mois
|
||||
- montant: 17.9%
|
||||
plafond: 8308 €/mois
|
||||
- montant: 20%
|
||||
plafond: 9642 €/mois
|
||||
- montant: 24%
|
||||
plafond: 12971 €/mois
|
||||
- montant: 28%
|
||||
plafond: 16500 €/mois
|
||||
- montant: 33%
|
||||
plafond: 26443 €/mois
|
||||
- montant: 38%
|
||||
plafond: 55815 €/mois
|
||||
- montant: 43%
|
||||
|
||||
impôt . taux neutre d'impôt sur le revenu:
|
||||
description: >
|
||||
|
@ -386,89 +300,48 @@ impôt . taux neutre d'impôt sur le revenu:
|
|||
- établissement . localisation . département = 'Mayotte'
|
||||
alors: barème Guyane Mayotte
|
||||
- sinon:
|
||||
barème linéaire:
|
||||
assiette: revenu imposable [€/mois]
|
||||
retourne seulement le taux: oui
|
||||
grille:
|
||||
assiette: revenu imposable
|
||||
tranches:
|
||||
- de: 0
|
||||
à: 1417
|
||||
taux: 0%
|
||||
|
||||
- de: 1418
|
||||
à: 1471
|
||||
taux: 0.5%
|
||||
|
||||
- de: 1472
|
||||
à: 1566
|
||||
taux: 1.3%
|
||||
|
||||
- de: 1567
|
||||
à: 1672
|
||||
taux: 2.1%
|
||||
|
||||
- de: 1673
|
||||
à: 1786
|
||||
taux: 2.9%
|
||||
|
||||
- de: 1787
|
||||
à: 1882
|
||||
taux: 3.5%
|
||||
|
||||
- de: 1883
|
||||
à: 2007
|
||||
taux: 4.1%
|
||||
|
||||
- de: 2008
|
||||
à: 2375
|
||||
taux: 5.3%
|
||||
|
||||
- de: 2376
|
||||
à: 2719
|
||||
taux: 7.5%
|
||||
|
||||
- de: 2720
|
||||
à: 3097
|
||||
taux: 9.9%
|
||||
|
||||
- de: 3098
|
||||
à: 3486
|
||||
taux: 11.9%
|
||||
|
||||
- de: 3487
|
||||
à: 4068
|
||||
taux: 13.8%
|
||||
|
||||
- de: 4069
|
||||
à: 4877
|
||||
taux: 15.8%
|
||||
|
||||
- de: 4878
|
||||
à: 6103
|
||||
taux: 17.9%
|
||||
|
||||
- de: 6104
|
||||
à: 7624
|
||||
taux: 20%
|
||||
|
||||
- de: 7625
|
||||
à: 10582
|
||||
taux: 24%
|
||||
|
||||
- de: 10583
|
||||
à: 14332
|
||||
taux: 28%
|
||||
|
||||
- de: 14333
|
||||
à: 22499
|
||||
taux: 33%
|
||||
|
||||
- de: 22500
|
||||
à: 48195
|
||||
taux: 38%
|
||||
|
||||
- au-dessus de: 48196
|
||||
taux: 43%
|
||||
|
||||
- montant: 0%
|
||||
plafond: 1418 €/mois
|
||||
- montant: 0.5%
|
||||
plafond: 1472 €/mois
|
||||
- montant: 1.3%
|
||||
plafond: 1567 €/mois
|
||||
- montant: 2.1%
|
||||
plafond: 1673 €/mois
|
||||
- montant: 2.9%
|
||||
plafond: 1787 €/mois
|
||||
- montant: 3.5%
|
||||
plafond: 1883 €/mois
|
||||
- montant: 4.1%
|
||||
plafond: 2008 €/mois
|
||||
- montant: 5.3%
|
||||
plafond: 2376 €/mois
|
||||
- montant: 7.5%
|
||||
plafond: 2720 €/mois
|
||||
- montant: 9.9%
|
||||
plafond: 3098 €/mois
|
||||
- montant: 11.9%
|
||||
plafond: 3487 €/mois
|
||||
- montant: 13.8%
|
||||
plafond: 4069 €/mois
|
||||
- montant: 15.8%
|
||||
plafond: 4878 €/mois
|
||||
- montant: 17.9%
|
||||
plafond: 6104 €/mois
|
||||
- montant: 20%
|
||||
plafond: 7625 €/mois
|
||||
- montant: 24%
|
||||
plafond: 10583 €/mois
|
||||
- montant: 28%
|
||||
plafond: 14333 €/mois
|
||||
- montant: 33%
|
||||
plafond: 22500 €/mois
|
||||
- montant: 38%
|
||||
plafond: 48196 €/mois
|
||||
- montant: 43%
|
||||
références:
|
||||
Explication de l'impôt neutre: https://www.economie.gouv.fr/prelevement-a-la-source/taux-prelevement#taux-non-personnalise
|
||||
BOFIP: http://bofip.impots.gouv.fr/bofip/11255-PGP.html
|
||||
|
|
|
@ -49,8 +49,8 @@ protection sociale . retraite . base:
|
|||
titre: pension de retraite de base
|
||||
formule:
|
||||
multiplication:
|
||||
plafond: plafond sécurité sociale temps plein
|
||||
taux: taux de la pension
|
||||
plafond: plafond sécurité sociale temps plein
|
||||
assiette: revenu moyen
|
||||
note: Les impatriés bénéficient d'une exonération de cotisation vieillesse. En contrepartie, ils n'acquièrent aucun droit pendant la durée d'exonération.
|
||||
références:
|
||||
|
@ -98,24 +98,20 @@ protection sociale . retraite . trimestres validés par an . trimestres indépen
|
|||
protection sociale . retraite . trimestres validés par an . barème trimestres générique:
|
||||
unité: trimestres validés/an
|
||||
formule:
|
||||
barème linéaire:
|
||||
grille:
|
||||
unité: trimestres validés/an
|
||||
assiette: revenu moyen [€/an]
|
||||
assiette: revenu moyen
|
||||
multiplicateur: SMIC horaire
|
||||
tranches:
|
||||
- en-dessous de: 150
|
||||
montant: 0
|
||||
- de: 150
|
||||
à: 300
|
||||
montant: 1
|
||||
- de: 300
|
||||
à: 450
|
||||
montant: 2
|
||||
- de: 450
|
||||
à: 600
|
||||
montant: 3
|
||||
- au-dessus de: 600
|
||||
montant: 4
|
||||
- montant: 0
|
||||
plafond: 150 heures/an
|
||||
- montant: 1
|
||||
plafond: 300 heures/an
|
||||
- montant: 2
|
||||
plafond: 450 heures/an
|
||||
- montant: 3
|
||||
plafond: 600 heures/an
|
||||
- montant: 4
|
||||
références:
|
||||
cnav.fr: https://www.legislation.cnav.fr/Pages/bareme.aspx?Nom=salaire_validant_un_trimestre_montant_bar
|
||||
|
||||
|
@ -127,63 +123,51 @@ protection sociale . retraite . trimestres validés par an . trimestres auto-ent
|
|||
variations:
|
||||
- si: entreprise . catégorie d'activité = 'libérale'
|
||||
alors:
|
||||
barème linéaire:
|
||||
grille:
|
||||
unité: trimestres validés/an
|
||||
assiette: entreprise . chiffre d'affaires [€/an]
|
||||
assiette: entreprise . chiffre d'affaires
|
||||
tranches:
|
||||
- en-dessous de: 2880
|
||||
montant: 0
|
||||
- de: 2880
|
||||
à: 5062
|
||||
montant: 1
|
||||
- de: 5062
|
||||
à: 7266
|
||||
montant: 2
|
||||
- de: 7266
|
||||
à: 9675
|
||||
montant: 3
|
||||
- au-dessus de: 9675
|
||||
montant: 4
|
||||
- montant: 0
|
||||
plafond: 2880 €/an
|
||||
- montant: 1
|
||||
plafond: 5062 €/an
|
||||
- montant: 2
|
||||
plafond: 7266 €/an
|
||||
- montant: 3
|
||||
plafond: 9675 €/an
|
||||
- montant: 4
|
||||
- si:
|
||||
une de ces conditions:
|
||||
- entreprise . catégorie d'activité . service ou vente = 'vente'
|
||||
- entreprise . catégorie d'activité . restauration ou hébergement
|
||||
alors:
|
||||
barème linéaire:
|
||||
grille:
|
||||
unité: trimestres validés/an
|
||||
assiette: entreprise . chiffre d'affaires [€/an]
|
||||
assiette: entreprise . chiffre d'affaires
|
||||
tranches:
|
||||
- en-dessous de: 4137
|
||||
montant: 0
|
||||
- de: 4137
|
||||
à: 7286
|
||||
montant: 1
|
||||
- de: 7286
|
||||
à: 10426
|
||||
montant: 2
|
||||
- de: 10426
|
||||
à: 20740
|
||||
montant: 3
|
||||
- au-dessus de: 20740
|
||||
montant: 4
|
||||
- montant: 0
|
||||
plafond: 4137 €/an
|
||||
- montant: 1
|
||||
plafond: 7286 €/an
|
||||
- montant: 2
|
||||
plafond: 10426 €/an
|
||||
- montant: 3
|
||||
plafond: 20740 €/an
|
||||
- montant: 4
|
||||
- sinon:
|
||||
barème linéaire:
|
||||
grille:
|
||||
unité: trimestres validés/an
|
||||
assiette: entreprise . chiffre d'affaires [€/an]
|
||||
assiette: entreprise . chiffre d'affaires
|
||||
tranches:
|
||||
- en-dessous de: 2412
|
||||
montant: 0
|
||||
- de: 2412
|
||||
à: 4239
|
||||
montant: 1
|
||||
- de: 4239
|
||||
à: 6071
|
||||
montant: 2
|
||||
- de: 6071
|
||||
à: 12030
|
||||
montant: 3
|
||||
- au-dessus de: 12030
|
||||
montant: 4
|
||||
- montant: 0
|
||||
plafond: 2412 €/an
|
||||
- montant: 1
|
||||
plafond: 4239 €/an
|
||||
- montant: 2
|
||||
plafond: 6071 €/an
|
||||
- montant: 3
|
||||
plafond: 12030 €/an
|
||||
- montant: 4
|
||||
références:
|
||||
service-public.fr: https://www.service-public.fr/professionnels-entreprises/vosdroits/F23369
|
||||
|
||||
|
@ -334,8 +318,8 @@ protection sociale . santé . indemnités journalières . salarié:
|
|||
formule:
|
||||
multiplication:
|
||||
assiette: revenu moyen [€/jour]
|
||||
plafond: 1.8 * contrat salarié . SMIC temps plein [€/jour]
|
||||
taux: 50%
|
||||
plafond: 1.8 * contrat salarié . SMIC temps plein [€/jour]
|
||||
reférences:
|
||||
service-public.fr: https://www.service-public.fr/particuliers/vosdroits/F3053
|
||||
|
||||
|
|
|
@ -255,38 +255,46 @@ contrat salarié . CDD . CPF:
|
|||
valeur attendue: null
|
||||
|
||||
contrat salarié . CDD . compensation pour congés non pris:
|
||||
titre: indemnité de congés payés
|
||||
indemnité:
|
||||
destinataire: salarié
|
||||
dû par: employeur
|
||||
description: |
|
||||
Le salarié en CDD bénéficie des mêmes droits à congés payés que le salarié en CDI. Il acquiert et prend ses congés payés dans les mêmes conditions.
|
||||
description: >-
|
||||
Le salarié en CDD bénéficie des mêmes droits à congés payés que le salarié
|
||||
en CDI. Il acquiert et prend ses congés payés dans les mêmes conditions.
|
||||
|
||||
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 alors d'une indemnité
|
||||
compensatrice de congés payés versée par l'employeur.
|
||||
|
||||
Il existe deux méthodes pour calculer l'indemnité de congés non pris.
|
||||
|
||||
### Méthode "du dixième"
|
||||
|
||||
Ce mode de calcul sera le plus souvent favorable au salarié lorsque celui-ci
|
||||
a accompli des heures supplémentaires. Une indemnité égale au dixième de la
|
||||
rémunération brute totale perçue par le salarié au cours de la période de
|
||||
référence.
|
||||
|
||||
### Méthode "maintien du salaire"
|
||||
|
||||
Cette méthode sera le plus souvent favorable au salarié lorsque celui-ci a
|
||||
bénéficié d’une augmentation de salaire.
|
||||
|
||||
Pour effectuer le calcul, l'employeur peut tenir compte soit :
|
||||
- de l'horaire réel du mois,
|
||||
- du nombre moyen de jours ouvrables (ou ouvrés),
|
||||
- du nombre réel de jours ouvrables (ou ouvrés).
|
||||
|
||||
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 alors d'une indemnité compensatrice de congés payés versée par l'employeur.
|
||||
unité: €/mois
|
||||
|
||||
non applicable si:
|
||||
une de ces conditions:
|
||||
- événement . poursuite du CDD en CDI
|
||||
# TODO Y a-t-il d'autres conditions ? Sinon supprimer la liste
|
||||
non applicable si: événement . poursuite du CDD en CDI
|
||||
formule:
|
||||
le maximum de:
|
||||
- description: Méthode "du dixième"
|
||||
note: |
|
||||
Ce mode de calcul sera le plus souvent favorable au salarié lorsque celui-ci a accompli des heures supplémentaires.
|
||||
> Une indemnité égale au dixième de la rémunération brute totale perçue par le salarié au cours de la période de référence.
|
||||
multiplication:
|
||||
- multiplication:
|
||||
assiette: assiette mensuelle
|
||||
taux: 10%
|
||||
facteur: proportion congés non pris
|
||||
- description: Méthode "maintien du salaire"
|
||||
note: |
|
||||
Cette méthode sera le plus souvent favorable au salarié lorsque celui-ci a bénéficié d’une augmentation de salaire.
|
||||
> Pour effectuer le calcul, l'employeur peut tenir compte soit :
|
||||
- de l'horaire réel du mois,
|
||||
- du nombre moyen de jours ouvrables (ou ouvrés),
|
||||
- du nombre réel de jours ouvrables (ou ouvrés).
|
||||
référence: https://www.service-public.fr/particuliers/vosdroits/F33359
|
||||
multiplication:
|
||||
- multiplication:
|
||||
assiette: salaire journalier
|
||||
facteur: congés non pris / durée contrat
|
||||
exemples:
|
||||
|
@ -316,13 +324,14 @@ contrat salarié . CDD . compensation pour congés non pris:
|
|||
note: |
|
||||
L'indemnité est versée à la fin du contrat, sauf si le CDD se poursuit par un CDI.
|
||||
À 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 l’embauche [...]
|
||||
- avant : Les congés peuvent être pris dès l'ouverture des droits
|
||||
- maintenant : Les congés peuvent être pris dès l’embauche
|
||||
références:
|
||||
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
|
||||
assiette de l'indemnité, circulaire DRT 18 du 30 octobre 1990: http://conseillerdusalarie.free.fr/Docs/TextesFrance/19901030Circulaire_DRT_90_18_du_30_octobre_1990_CDD_Travail_temporaire.htm
|
||||
Méthode du maintien de salaire: https://www.service-public.fr/particuliers/vosdroits/F33359
|
||||
|
||||
contrat salarié . CDD . compensation pour congés non pris . proportion congés non pris:
|
||||
unité: '%'
|
||||
|
@ -1449,14 +1458,14 @@ contrat salarié . réduction ACRE:
|
|||
contrat salarié . réduction ACRE . taux:
|
||||
titre: taux ACRE
|
||||
formule:
|
||||
barème continu:
|
||||
taux progressif:
|
||||
assiette: cotisations . assiette
|
||||
multiplicateur: plafond sécurité sociale temps plein
|
||||
points:
|
||||
0: 100%
|
||||
0.75: 100%
|
||||
1: 0%
|
||||
retourne seulement le taux: oui
|
||||
tranches:
|
||||
- plafond: 75%
|
||||
taux: 100%
|
||||
- plafond: 100%
|
||||
taux: 0%
|
||||
|
||||
contrat salarié . cotisations . salariales . réduction heures supplémentaires:
|
||||
cotisation:
|
||||
|
@ -1639,12 +1648,11 @@ contrat salarié . temps de travail . heures supplémentaires . majoration:
|
|||
formule:
|
||||
barème:
|
||||
assiette: heures supplémentaires
|
||||
multiplicateur: 1 heure/semaine * période . semaines par mois
|
||||
multiplicateur: période . semaines par mois
|
||||
tranches:
|
||||
- en-dessous de: 8
|
||||
taux: 25%
|
||||
- au-dessus de: 8
|
||||
taux: 50%
|
||||
- taux: 25%
|
||||
plafond: 8 heures/semaine
|
||||
- taux: 50%
|
||||
|
||||
contrat salarié . temps de travail . heures complémentaires:
|
||||
description: >
|
||||
|
@ -1848,21 +1856,19 @@ contrat salarié . contribution d'équilibre général:
|
|||
- attributs:
|
||||
dû par: employeur
|
||||
tranches:
|
||||
- en-dessous de: 1
|
||||
taux: 1.29%
|
||||
- de: 1
|
||||
à: 8
|
||||
taux: 1.62%
|
||||
- taux: 1.29%
|
||||
plafond: 1
|
||||
- taux: 1.62%
|
||||
plafond: 8
|
||||
|
||||
- attributs:
|
||||
dû par: salarié
|
||||
assiette: cotisations . assiette . salariale
|
||||
tranches:
|
||||
- en-dessous de: 1
|
||||
taux: 0.86%
|
||||
- de: 1
|
||||
à: 8
|
||||
taux: 1.08%
|
||||
- taux: 0.86%
|
||||
plafond: 1
|
||||
- taux: 1.08%
|
||||
plafond: 8
|
||||
|
||||
références:
|
||||
calcul des cotisations: https://www.agirc-arrco.fr/ce-qui-change-au-1er-janvier-2019/vous-etes-une-entreprise-tiers-declarant/
|
||||
|
@ -1902,20 +1908,18 @@ contrat salarié . retraite complémentaire:
|
|||
- attributs:
|
||||
dû par: employeur
|
||||
tranches:
|
||||
- en-dessous de: 1
|
||||
taux: taux employeur tranche 1
|
||||
- de: 1
|
||||
à: 8
|
||||
taux: taux employeur tranche 2
|
||||
- taux: taux employeur tranche 1
|
||||
plafond: 1
|
||||
- taux: taux employeur tranche 2
|
||||
plafond: 8
|
||||
- attributs:
|
||||
dû par: salarié
|
||||
assiette: cotisations . assiette . salariale
|
||||
tranches:
|
||||
- en-dessous de: 1
|
||||
taux: taux salarié tranche 1
|
||||
- de: 1
|
||||
à: 8
|
||||
taux: taux salarié tranche 2
|
||||
- taux: taux salarié tranche 1
|
||||
plafond: 1
|
||||
- taux: taux salarié tranche 2
|
||||
plafond: 8
|
||||
|
||||
références:
|
||||
calcul des cotisations: https://www.agirc-arrco.fr/ce-qui-change-au-1er-janvier-2019/vous-etes-une-entreprise-tiers-declarant/
|
||||
|
@ -1941,8 +1945,8 @@ contrat salarié . AGS:
|
|||
formule:
|
||||
multiplication:
|
||||
assiette: cotisations . assiette
|
||||
plafond: 4 * plafond sécurité sociale
|
||||
taux: 0.15%
|
||||
plafond: 4 * plafond sécurité sociale
|
||||
|
||||
contrat salarié . allocations familiales:
|
||||
cotisation:
|
||||
|
@ -2170,14 +2174,13 @@ contrat salarié . assiette CSG et CRDS:
|
|||
contrat salarié . assiette CSG et CRDS . assiette abattue:
|
||||
formule:
|
||||
barème:
|
||||
assiette: cotisations . assiette [€/mois]
|
||||
assiette: cotisations . assiette
|
||||
multiplicateur: plafond sécurité sociale
|
||||
# c'est en fait un abattement de 1,75% sur la partie en-dessous de 4 fois le plafond
|
||||
tranches:
|
||||
- en-dessous de: 4
|
||||
taux: 98.25%
|
||||
- au-dessus de: 4
|
||||
taux: 100%
|
||||
- taux: 98.25%
|
||||
plafond: 4
|
||||
- taux: 100%
|
||||
|
||||
contrat salarié . CSG . assiette heures supplémentaires et complémentaires défiscalisées:
|
||||
formule:
|
||||
|
@ -2410,8 +2413,8 @@ contrat salarié . prévoyance obligatoire cadre:
|
|||
formule:
|
||||
multiplication:
|
||||
assiette: cotisations . assiette
|
||||
plafond: plafond sécurité sociale
|
||||
taux: 1.5%
|
||||
plafond: plafond sécurité sociale
|
||||
# TODO attention : il semblerait que ce 1.5% englobe aussi la complémentaire santé ! La confusion serait entretenue par les organismes de prévoyance...
|
||||
|
||||
contrat salarié . taxe d'apprentissage:
|
||||
|
@ -2528,15 +2531,13 @@ contrat salarié . taxe sur les salaires . barème:
|
|||
|
||||
formule:
|
||||
barème:
|
||||
assiette: assiette [€/an]
|
||||
assiette: assiette
|
||||
tranches:
|
||||
- en-dessous de: 7799
|
||||
taux: 4.25%
|
||||
- de: 7799
|
||||
à: 15572
|
||||
taux: 8.5%
|
||||
- au-dessus de: 15572
|
||||
taux: 13.6%
|
||||
- taux: 4.25%
|
||||
plafond: 7799 €/an
|
||||
- taux: 8.5%
|
||||
plafond: 15572 €/an
|
||||
- taux: 13.6%
|
||||
exemples:
|
||||
- nom: salaire médian
|
||||
situation:
|
||||
|
@ -2641,16 +2642,16 @@ contrat salarié . vieillesse:
|
|||
taux: taux salarié non plafonné
|
||||
|
||||
- nom: plafonnée
|
||||
plafond: plafond sécurité sociale
|
||||
taux: taux salarié plafonné
|
||||
plafond: plafond sécurité sociale
|
||||
- attributs:
|
||||
dû par: employeur
|
||||
composantes:
|
||||
- nom: non plafonnée
|
||||
taux: taux employeur non plafonné
|
||||
- nom: plafonnée
|
||||
plafond: plafond sécurité sociale
|
||||
taux: taux employeur plafonné
|
||||
plafond: plafond sécurité sociale
|
||||
|
||||
exemples:
|
||||
- nom: SMIC
|
||||
|
|
|
@ -89,7 +89,7 @@ export default function CurrencyInput({
|
|||
}
|
||||
onValueChange={({ value }) => {
|
||||
setCurrentValue(value)
|
||||
nextValue.current = value.toString().replace(/^-/, '')
|
||||
nextValue.current = value.toString().replace('-', '')
|
||||
}}
|
||||
onChange={handleChange}
|
||||
value={currentValue.toString().replace('.', decimalSeparator)}
|
||||
|
|
|
@ -62,11 +62,11 @@ function integerAndDecimalParts(value: number) {
|
|||
// returned values is always 100. For instance: [60, 30, 10].
|
||||
export function roundedPercentages(values: Array<number>) {
|
||||
const sum = (a: number = 0, b: number) => a + b
|
||||
const total = values.reduce(sum)
|
||||
const total = values.reduce(sum, 0)
|
||||
const percentages = values.map(value =>
|
||||
integerAndDecimalParts((value / total) * 100)
|
||||
)
|
||||
const totalRoundedPercentage = percentages.map(v => v.integer).reduce(sum)
|
||||
const totalRoundedPercentage = percentages.map(v => v.integer).reduce(sum, 0)
|
||||
const indexesToIncrement = percentages
|
||||
.map((percentage, index) => ({ ...percentage, index }))
|
||||
.sort((a, b) => b.decimal - a.decimal)
|
||||
|
|
|
@ -19,7 +19,7 @@ let Conditions = ({
|
|||
parentDependency.nodeValue === false && (
|
||||
<ShowIfDisabled
|
||||
dependency={parentDependency}
|
||||
key="parent dependency"
|
||||
key={parentDependency.dottedName}
|
||||
/>
|
||||
)
|
||||
),
|
||||
|
@ -63,7 +63,6 @@ export default function Algorithm({ rule, showValues }) {
|
|||
!!Object.keys(formula).length &&
|
||||
!path(['formule', 'explanation', 'une possibilité'], rule) &&
|
||||
formula.explanation?.category !== 'number'
|
||||
|
||||
return (
|
||||
<div id="algorithm">
|
||||
<section id="rule-rules" className={classNames({ showValues })}>
|
||||
|
|
|
@ -1,12 +1,26 @@
|
|||
import { coerceArray } from '../utils'
|
||||
export function syntaxError(
|
||||
dottedName: string,
|
||||
rules: string[] | string,
|
||||
message: string,
|
||||
originalError: Error
|
||||
) {
|
||||
throw new Error(
|
||||
`[ Erreur syntaxique ]
|
||||
➡️ Dans la règle \`${dottedName}\`,
|
||||
`\n[ Erreur syntaxique ]
|
||||
➡️ Dans la règle \`${coerceArray(rules).slice(-1)[0]}\`
|
||||
✖️ ${message}
|
||||
${originalError && originalError.message}
|
||||
`
|
||||
)
|
||||
}
|
||||
|
||||
export function evaluationError(
|
||||
rules: string[] | string,
|
||||
message: string,
|
||||
originalError?: Error
|
||||
) {
|
||||
throw new Error(
|
||||
`\n[ Erreur d'évaluation ]
|
||||
➡️ Dans la règle \`${coerceArray(rules).slice(-1)[0]}\`
|
||||
✖️ ${message}
|
||||
${originalError && originalError.message}
|
||||
`
|
||||
|
@ -19,18 +33,22 @@ export function typeWarning(
|
|||
originalError?: Error
|
||||
) {
|
||||
console.warn(
|
||||
`[ Erreur de type ]
|
||||
➡️ Dans la règle \`${coerceArray(rules).slice(-1)[0]}\`,
|
||||
`\n[ Erreur de type ]
|
||||
➡️ Dans la règle \`${coerceArray(rules).slice(-1)[0]}\`
|
||||
✖️ ${message}
|
||||
${originalError && originalError.message}
|
||||
`
|
||||
)
|
||||
}
|
||||
|
||||
export function warning(dottedName: string, message: string, solution: string) {
|
||||
export function warning(
|
||||
rules: string[] | string,
|
||||
message: string,
|
||||
solution: string
|
||||
) {
|
||||
console.warn(
|
||||
`[ Avertissement ]
|
||||
➡️ Dans la règle \`${dottedName}\`,
|
||||
`\n[ Avertissement ]
|
||||
➡️ Dans la règle \`${coerceArray(rules).slice(-1)[0]}\`
|
||||
⚠️ ${message}
|
||||
💡${solution}
|
||||
`
|
||||
|
|
|
@ -43,20 +43,25 @@ export let evaluateNode = (cache, situationGate, parsedRules, node) => {
|
|||
return evaluatedNode
|
||||
}
|
||||
const sameUnitValues = (explanation, contextRule, mecanismName) => {
|
||||
const unit = explanation.map(n => n.unit).find(Boolean)
|
||||
const firstNodeWithUnit = explanation.find(node => !!node.unit)
|
||||
if (!firstNodeWithUnit) {
|
||||
return [undefined, explanation.map(({ nodeValue }) => nodeValue)]
|
||||
}
|
||||
const values = explanation.map(node => {
|
||||
try {
|
||||
return convertNodeToUnit(unit, node).nodeValue
|
||||
return convertNodeToUnit(firstNodeWithUnit?.unit, node).nodeValue
|
||||
} catch (e) {
|
||||
typeWarning(
|
||||
contextRule,
|
||||
`'${node.name}' a une unité incompatible avec celle du mécanisme ${mecanismName}`,
|
||||
`Dans le mécanisme ${mecanismName}, les unités des éléments suivants sont incompatibles entre elles : \n\t\t${node?.name ||
|
||||
node?.rawNode}\n\t\t${firstNodeWithUnit?.name ||
|
||||
firstNodeWithUnit?.rawNode}'`,
|
||||
e
|
||||
)
|
||||
return node.nodeValue
|
||||
}
|
||||
})
|
||||
return [unit, values]
|
||||
return [firstNodeWithUnit.unit, values]
|
||||
}
|
||||
|
||||
export let evaluateArray = (reducer, start) => (
|
||||
|
@ -144,7 +149,12 @@ export let evaluateObject = (objectShape, effect) => (
|
|||
let transforms = map(k => [k, evaluateOne], keys(objectShape)),
|
||||
automaticExplanation = evolve(fromPairs(transforms))(node.explanation)
|
||||
// the result of effect can either be just a nodeValue, or an object {additionalExplanation, nodeValue}. The latter is useful for a richer JSX visualisation of the mecanism : the view should not duplicate code to recompute intermediate values (e.g. for a marginal 'barème', the marginal 'tranche')
|
||||
let evaluated = effect(automaticExplanation, cache, situationGate, parsedRules),
|
||||
let evaluated = effect(
|
||||
automaticExplanation,
|
||||
cache,
|
||||
situationGate,
|
||||
parsedRules
|
||||
),
|
||||
explanation = is(Object, evaluated)
|
||||
? { ...automaticExplanation, ...evaluated.additionalExplanation }
|
||||
: automaticExplanation,
|
||||
|
|
|
@ -24,6 +24,7 @@ const lexer = moo.compile({
|
|||
'[': '[',
|
||||
']': ']',
|
||||
comparison: ['>','<','>=','<=','=','!='],
|
||||
infinity: 'Infinity',
|
||||
words: new RegExp(words),
|
||||
number: new RegExp(numberRegExp),
|
||||
string: /'[ \t\.'a-zA-Z\-\u00C0-\u017F0-9 ]+'/,
|
||||
|
@ -106,6 +107,7 @@ boolean ->
|
|||
|
||||
number ->
|
||||
%number {% number %}
|
||||
| %infinity {% number %}
|
||||
| %number (%space):? Unit {% numberWithUnit %}
|
||||
|
||||
string -> %string {% string %}
|
|
@ -134,37 +134,41 @@ rend non applicable:
|
|||
|
||||
barème:
|
||||
type: numeric
|
||||
description: |
|
||||
C'est un barème en taux marginaux, mécanisme de calcul connu son utilisation dans le calcul de l'impôt sur le revenu.
|
||||
description: >-
|
||||
C'est un barème en taux marginaux, mécanisme de calcul connu son utilisation
|
||||
dans le calcul de l'impôt sur le revenu.
|
||||
|
||||
L'assiette est décomposée en plusieurs tranches, qui sont multipliées par un taux spécifique.
|
||||
L'assiette est décomposée en plusieurs tranches, qui sont multipliées par un
|
||||
taux spécifique.
|
||||
|
||||
Les tranches sont souvent exprimées sous forme de facteurs d'une variable que l'on appelle `multiplicateur`, par exemple `1 x le plafond de la sécurité sociale`.
|
||||
Les tranches sont souvent exprimées sous forme de facteurs d'une variable
|
||||
que l'on appelle `multiplicateur`, par exemple `1 x le plafond de la
|
||||
sécurité sociale`.
|
||||
|
||||
barème linéaire:
|
||||
grille:
|
||||
type: numeric
|
||||
description: |
|
||||
C'est un barème en taux non marginaux, très simple. C'est le mécanisme de calcul de l'impôt neutre, aussi appelé impôt non personnalisé.
|
||||
Il est composé de tranches qui se suivent. Il suffit de trouver l'assiette qui correspond à la tranche, et de multiplier le taux associé avec l'assiette.
|
||||
Un montant fixe pour chaque tranche peut aussi remplacer le taux, rendant le barème encore plus simple, mais moins "juste", car moins continu.
|
||||
description: >-
|
||||
C'est un barème sous la forme d'une grille de correspondance. C'est le
|
||||
mécanisme de calcul de l'impôt neutre, aussi appelé impôt non personnalisé.
|
||||
|
||||
barème continu:
|
||||
Il est composé de tranches qui se suivent. Il suffit de trouver l'assiette
|
||||
qui correspond à la tranche, et de selectionner le montant associé à
|
||||
l'assiette.
|
||||
|
||||
taux progressif:
|
||||
type: numeric
|
||||
description: |
|
||||
Désolé, ce mécanisme est quelque peu compliqué, accrochez-vous !
|
||||
description: >-
|
||||
Ce mécanisme permet de calculer un taux progressif. On spécifie pour chaque
|
||||
tranche le plafond et le taux associé. Le taux effectif renvoyé est calculé
|
||||
en lissant la différence de taux entre la borne inférieure et supérieure de
|
||||
l'assiette
|
||||
|
||||
> Par exemple, si nous nous avons les tranches suivantes :
|
||||
- taux: 50% / plafond: 0
|
||||
- taux: 100% / plafond: 1000
|
||||
|
||||
Le barème définit des points, constitués d'un seuil et d'un taux correspondant. Par exemple `1 : 6%` et `2 : 8%`. L'assiette du barème est placée au bon endroit entre ces seuils, et on en déduit le taux qui lui correspond.
|
||||
|
||||
Dans notre exemple, si l'assiette vaut 1, le taux est 6%. Si elle vaut 2, le taux est 8%. Et si elle est entre les deux, par exemple 1.5, alors le taux est 7%. Et ainsi de suite.
|
||||
|
||||
Dans ce type de barème, il y a souvent un multiplicateur de l'assiette, par exemple le plafond de la sécurité sociale : les seuils sont des petits nombres comme 1 ou 1.5, mais ils correspondent en réalité à `1 * 3311€` et `1.5 * 3311€`.
|
||||
|
||||
L'option `retourne seulement le taux: oui` permet d'obtenir un taux pour une assiette donnée, pour l'appliquer ensuite à une autre assiette.
|
||||
|
||||
complément:
|
||||
type: numeric
|
||||
description: |
|
||||
Complète une base pour atteindre un seuil minimal
|
||||
> Pour une assiette de 500, le taux retourné sera 75%, car il correspond au
|
||||
taux situé à la moitié de la tranche correspondante.
|
||||
|
||||
composantes:
|
||||
type: numeric
|
||||
|
@ -196,5 +200,12 @@ durée:
|
|||
synchronisation:
|
||||
type: object
|
||||
description: |
|
||||
Pour éviter trop de saisies à l'utilisateur, certaines informations sont récupérées à partir de ce que l'on appelle des API. Ce sont des services auxquels ont fait appel pour obtenir des informations sur un sujet précis. Par exemple, l'État français fournit gratuitement l'API géo, qui permet à partir du nom d'une ville, d'obtenir son code postal, son département, la population etc.
|
||||
Ce mécanismes `synchronisation` permet de faire le lien entre les règles de notre système et les réponses de ces API.
|
||||
Pour éviter trop de saisies à l'utilisateur, certaines informations sont
|
||||
récupérées à partir de ce que l'on appelle des API. Ce sont des services
|
||||
auxquels ont fait appel pour obtenir des informations sur un sujet précis.
|
||||
Par exemple, l'État français fournit gratuitement l'API géo, qui permet à
|
||||
partir du nom d'une ville, d'obtenir son code postal, son département, la
|
||||
population etc.
|
||||
|
||||
Ce mécanismes `synchronisation` permet de faire le lien entre les règles de
|
||||
notre système et les réponses de ces API.
|
||||
|
|
|
@ -1,238 +0,0 @@
|
|||
import classNames from 'classnames'
|
||||
import { ShowValuesContext } from 'Components/rule/ShowValuesContext'
|
||||
import RuleLink from 'Components/RuleLink'
|
||||
import { numberFormatter } from 'Engine/format'
|
||||
import { trancheValue } from 'Engine/mecanisms/barème'
|
||||
import { inferUnit, serializeUnit } from 'Engine/units'
|
||||
import { identity } from 'ramda'
|
||||
import React, { useContext } from 'react'
|
||||
import { Trans } from 'react-i18next'
|
||||
import { makeJsx } from '../evaluation'
|
||||
import './Barème.css'
|
||||
import { Node, NodeValuePointer } from './common'
|
||||
|
||||
export let BarèmeAttributes = ({ explanation, lazyEval = identity }) => {
|
||||
const multiplicateur = lazyEval(explanation['multiplicateur'])
|
||||
const multiplicateurAcronym = multiplicateur?.explanation?.acronyme
|
||||
|
||||
return (
|
||||
<>
|
||||
<li key="assiette">
|
||||
<span className="key">
|
||||
<Trans>assiette</Trans>:{' '}
|
||||
</span>
|
||||
<span className="value">{makeJsx(lazyEval(explanation.assiette))}</span>
|
||||
</li>
|
||||
{explanation['multiplicateur'] &&
|
||||
explanation['multiplicateur'].nodeValue !== 1 &&
|
||||
!multiplicateurAcronym && (
|
||||
<li key="multiplicateur">
|
||||
<span className="key">
|
||||
<Trans>multiplicateur</Trans>:{' '}
|
||||
</span>
|
||||
<span className="value">{makeJsx(multiplicateur)}</span>
|
||||
</li>
|
||||
)}
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
let Component = function Barème({
|
||||
language,
|
||||
nodeValue,
|
||||
explanation,
|
||||
barèmeType,
|
||||
lazyEval,
|
||||
unit
|
||||
}) {
|
||||
const showValues = useContext(ShowValuesContext)
|
||||
const multiplicateur = lazyEval(explanation?.multiplicateur)
|
||||
return (
|
||||
<Node
|
||||
classes="mecanism barème"
|
||||
name={barèmeType === 'marginal' ? 'barème' : 'barème linéaire'}
|
||||
value={nodeValue}
|
||||
unit={unit}
|
||||
child={
|
||||
<ul className="properties">
|
||||
<BarèmeAttributes explanation={explanation} lazyEval={lazyEval} />
|
||||
<table className="tranches">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>
|
||||
<Trans>Tranche de l'assiette</Trans>
|
||||
</th>
|
||||
<th>
|
||||
{typeof unit === 'string' ? (
|
||||
unit
|
||||
) : (
|
||||
<Trans>
|
||||
{explanation.tranches[0].taux != null
|
||||
? 'Taux'
|
||||
: 'Montant'}
|
||||
</Trans>
|
||||
)}
|
||||
</th>
|
||||
{showValues &&
|
||||
!explanation.returnRate &&
|
||||
explanation.tranches[0].taux != null && (
|
||||
<th>
|
||||
<Trans>Résultat</Trans>
|
||||
</th>
|
||||
)}
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{explanation.tranches.map(tranche => (
|
||||
<Tranche
|
||||
key={tranche['de'] + tranche['à']}
|
||||
{...{
|
||||
language,
|
||||
tranche,
|
||||
showValues,
|
||||
tranchesUnit: inferUnit('/', [
|
||||
explanation.assiette.unit,
|
||||
explanation.multiplicateur?.unit
|
||||
]),
|
||||
resultUnit: explanation.assiette.unit,
|
||||
returnRate: explanation.returnRate,
|
||||
multiplicateur,
|
||||
trancheValue:
|
||||
barèmeType === 'marginal'
|
||||
? tranche.value
|
||||
: trancheValue(
|
||||
explanation['assiette'],
|
||||
explanation['multiplicateur']
|
||||
)(tranche)
|
||||
}}
|
||||
/>
|
||||
))}
|
||||
</tbody>
|
||||
</table>
|
||||
{/* nous avons remarqué que la notion de taux moyen pour un barème à 2 tranches est moins pertinent pour les règles de calcul des indépendants. Règle empirique à faire évoluer ! */}
|
||||
{showValues &&
|
||||
!explanation.returnRate &&
|
||||
barèmeType === 'marginal' &&
|
||||
explanation.tranches.length > 2 && (
|
||||
<>
|
||||
<b>
|
||||
<Trans>Taux moyen</Trans> :{' '}
|
||||
</b>
|
||||
<NodeValuePointer
|
||||
data={
|
||||
(100 * nodeValue) /
|
||||
lazyEval(explanation['assiette']).nodeValue
|
||||
}
|
||||
unit="%"
|
||||
/>
|
||||
</>
|
||||
)}
|
||||
{explanation.returnRate && (
|
||||
<p>
|
||||
Ce barème <strong>ne retourne que le taux</strong>.
|
||||
</p>
|
||||
)}
|
||||
</ul>
|
||||
}
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
||||
let Tranche = ({
|
||||
tranche: {
|
||||
'en-dessous de': maxOnly,
|
||||
'au-dessus de': minOnly,
|
||||
de: min,
|
||||
à: max,
|
||||
taux,
|
||||
nodeValue,
|
||||
montant
|
||||
},
|
||||
multiplicateur,
|
||||
tranchesUnit,
|
||||
resultUnit,
|
||||
returnRate,
|
||||
trancheValue,
|
||||
showValues,
|
||||
language
|
||||
}) => {
|
||||
const trancheFormatter = value => (
|
||||
<TrancheFormatter
|
||||
{...{
|
||||
language,
|
||||
tranchesUnit,
|
||||
resultUnit,
|
||||
multiplicateur,
|
||||
value
|
||||
}}
|
||||
/>
|
||||
)
|
||||
|
||||
let activated = trancheValue > 0
|
||||
return (
|
||||
<tr className={classNames('tranche', { activated })}>
|
||||
<td key="tranche">
|
||||
{maxOnly ? (
|
||||
<>
|
||||
<Trans>En-dessous de</Trans> {trancheFormatter(maxOnly)}
|
||||
</>
|
||||
) : minOnly ? (
|
||||
<>
|
||||
<Trans>Au-dessus de</Trans> {trancheFormatter(minOnly)}
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
<Trans>De</Trans> {trancheFormatter(min)} <Trans>à</Trans>{' '}
|
||||
{trancheFormatter(max)}
|
||||
</>
|
||||
)}
|
||||
</td>
|
||||
<td key="taux"> {taux != null ? makeJsx(taux) : makeJsx(montant)}</td>
|
||||
{showValues && !returnRate && taux != null && (
|
||||
<td key="value">
|
||||
<NodeValuePointer data={nodeValue} unit={resultUnit} />
|
||||
</td>
|
||||
)}
|
||||
</tr>
|
||||
)
|
||||
}
|
||||
|
||||
function TrancheFormatter({
|
||||
language,
|
||||
tranchesUnit,
|
||||
resultUnit,
|
||||
multiplicateur,
|
||||
value
|
||||
}) {
|
||||
const multiplicateurAcronym = multiplicateur?.explanation?.acronyme
|
||||
if (!multiplicateurAcronym) {
|
||||
return numberFormatter({
|
||||
language,
|
||||
style: serializeUnit(tranchesUnit) === '€' ? 'currency' : undefined
|
||||
})(value)
|
||||
} else {
|
||||
return (
|
||||
<>
|
||||
{value}
|
||||
<RuleLink
|
||||
{...multiplicateur.explanation}
|
||||
title={multiplicateur.explanation.name}
|
||||
>
|
||||
{multiplicateurAcronym}
|
||||
</RuleLink>{' '}
|
||||
<NodeValuePointer
|
||||
data={value * multiplicateur.nodeValue}
|
||||
unit={resultUnit}
|
||||
/>
|
||||
</>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
//eslint-disable-next-line
|
||||
export default barèmeType => (
|
||||
nodeValue,
|
||||
explanation,
|
||||
lazyEval = identity,
|
||||
unit
|
||||
) => <Component {...{ nodeValue, explanation, barèmeType, lazyEval, unit }} />
|
|
@ -0,0 +1,123 @@
|
|||
import classNames from 'classnames'
|
||||
import React from 'react'
|
||||
import { Trans } from 'react-i18next'
|
||||
import { makeJsx } from '../evaluation'
|
||||
import './Barème.css'
|
||||
import { Node, NodeValuePointer } from './common'
|
||||
|
||||
export default function Barème(nodeValue, explanation, _, unit) {
|
||||
return (
|
||||
<Node
|
||||
classes="mecanism barème"
|
||||
name="barème"
|
||||
value={nodeValue}
|
||||
unit={unit}
|
||||
child={
|
||||
<ul className="properties">
|
||||
<BarèmeAttributes explanation={explanation} />
|
||||
<TrancheTable
|
||||
tranches={explanation.tranches}
|
||||
multiplicateur={explanation.multiplicateur}
|
||||
/>
|
||||
{/* nous avons remarqué que la notion de taux moyen pour un barème à 2 tranches est moins pertinent pour les règles de calcul des indépendants. Règle empirique à faire évoluer ! */}
|
||||
{nodeValue !== null && explanation.tranches.length > 2 && (
|
||||
<>
|
||||
<b>
|
||||
<Trans>Taux moyen</Trans> :{' '}
|
||||
</b>
|
||||
<NodeValuePointer
|
||||
data={(100 * nodeValue) / explanation.assiette.nodeValue}
|
||||
unit="%"
|
||||
/>
|
||||
</>
|
||||
)}
|
||||
</ul>
|
||||
}
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
||||
export let BarèmeAttributes = ({ explanation }) => {
|
||||
const multiplicateur = explanation.multiplicateur
|
||||
return (
|
||||
<>
|
||||
<li key="assiette">
|
||||
<span className="key">
|
||||
<Trans>assiette</Trans>:{' '}
|
||||
</span>
|
||||
<span className="value">{makeJsx(explanation.assiette)}</span>
|
||||
</li>
|
||||
{multiplicateur && !multiplicateur.isDefault && (
|
||||
<li key="multiplicateur">
|
||||
<span className="key">
|
||||
<Trans>multiplicateur</Trans>:{' '}
|
||||
</span>
|
||||
<span className="value">{makeJsx(multiplicateur)}</span>
|
||||
</li>
|
||||
)}
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
export const TrancheTable = ({ tranches, multiplicateur }) => {
|
||||
const activeTranche = tranches.find(({ isActive }) => isActive)
|
||||
return (
|
||||
<table className="tranches">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>
|
||||
<Trans>Plafonds des tranches</Trans>
|
||||
</th>
|
||||
{tranches[0].taux && (
|
||||
<th>
|
||||
<Trans>Taux</Trans>
|
||||
</th>
|
||||
)}
|
||||
{(tranches[0].montant || activeTranche?.nodeValue != null) && (
|
||||
<th>
|
||||
<Trans>Montant</Trans>
|
||||
</th>
|
||||
)}
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{tranches.map((tranche, i) => (
|
||||
<Tranche key={i} tranche={tranche} multiplicateur={multiplicateur} />
|
||||
))}
|
||||
</tbody>
|
||||
</table>
|
||||
)
|
||||
}
|
||||
|
||||
const Tranche = ({ tranche, multiplicateur }) => {
|
||||
const isHighlighted = tranche.isActive
|
||||
return (
|
||||
<tr className={classNames('tranche', { activated: isHighlighted })}>
|
||||
<td key="tranche">
|
||||
{tranche.plafond.nodeValue === Infinity ? (
|
||||
<Trans>Au-delà du dernier plafond</Trans>
|
||||
) : (
|
||||
<>
|
||||
{makeJsx(tranche.plafond)}
|
||||
{multiplicateur && !multiplicateur.isDefault && (
|
||||
<>
|
||||
{' × '}
|
||||
{makeJsx(multiplicateur)}
|
||||
</>
|
||||
)}
|
||||
</>
|
||||
)}
|
||||
</td>
|
||||
{tranche.taux && <td key="taux">{makeJsx(tranche.taux)}</td>}
|
||||
{(tranche.nodeValue != null || tranche.montant) && (
|
||||
<td key="value">
|
||||
{tranche.montant ? (
|
||||
makeJsx(tranche.montant)
|
||||
) : (
|
||||
<NodeValuePointer data={tranche.nodeValue} unit={tranche.unit} />
|
||||
)}
|
||||
</td>
|
||||
)}
|
||||
</tr>
|
||||
)
|
||||
}
|
|
@ -1,106 +0,0 @@
|
|||
import { ShowValuesConsumer } from 'Components/rule/ShowValuesContext'
|
||||
import RuleLink from 'Components/RuleLink'
|
||||
import { formatValue } from 'Engine/format'
|
||||
import { sortObjectByKeys } from 'Engine/mecanismViews/common'
|
||||
import { serializeUnit } from 'Engine/units'
|
||||
import React from 'react'
|
||||
import { Trans, useTranslation } from 'react-i18next'
|
||||
import { BarèmeAttributes } from './Barème'
|
||||
import './Barème.css'
|
||||
import { Node, NodeValuePointer } from './common'
|
||||
|
||||
let Comp = function Barème({ nodeValue, explanation, unit }) {
|
||||
return (
|
||||
<ShowValuesConsumer>
|
||||
{showValues => (
|
||||
<Node
|
||||
classes="mecanism barème"
|
||||
name="barème continu"
|
||||
value={nodeValue}
|
||||
unit={unit}
|
||||
child={
|
||||
<ul className="properties">
|
||||
<BarèmeAttributes explanation={explanation} />
|
||||
<table className="tranches">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>
|
||||
<Trans>Seuil</Trans>
|
||||
</th>
|
||||
<th>
|
||||
<Trans>Taux</Trans>
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{sortObjectByKeys(explanation.points).map(([seuil, taux]) => (
|
||||
<tr key={seuil} className="tranche">
|
||||
<td key="tranche">
|
||||
<SeuilFormatteur
|
||||
value={Number(seuil)}
|
||||
unit={explanation.assiette.unit}
|
||||
multiplicateur={
|
||||
explanation.multiplicateur?.explanation
|
||||
}
|
||||
/>
|
||||
</td>
|
||||
<td key="taux"> {taux}</td>
|
||||
</tr>
|
||||
))}
|
||||
</tbody>
|
||||
</table>
|
||||
{showValues && (
|
||||
<span style={{ background: 'yellow' }}>
|
||||
<b>
|
||||
<Trans>Votre taux </Trans> :{' '}
|
||||
</b>
|
||||
<NodeValuePointer data={100 * explanation.taux} unit="%" />
|
||||
</span>
|
||||
)}
|
||||
{explanation.returnRate && (
|
||||
<p>
|
||||
Ce barème <strong>ne retourne que le taux</strong>.
|
||||
</p>
|
||||
)}
|
||||
</ul>
|
||||
}
|
||||
/>
|
||||
)}
|
||||
</ShowValuesConsumer>
|
||||
)
|
||||
}
|
||||
|
||||
function SeuilFormatteur({ value, multiplicateur, unit }) {
|
||||
const { language } = useTranslation().i18n
|
||||
if (value === 0) {
|
||||
return '0'
|
||||
} else {
|
||||
return (
|
||||
<>
|
||||
{formatValue({
|
||||
value,
|
||||
language
|
||||
})}{' '}
|
||||
{multiplicateur ? (
|
||||
<>
|
||||
|
||||
<RuleLink {...multiplicateur} title={multiplicateur.name}>
|
||||
{multiplicateur.acronyme}
|
||||
</RuleLink>
|
||||
<NodeValuePointer
|
||||
data={value * multiplicateur.nodeValue}
|
||||
unit={multiplicateur.unit}
|
||||
/>
|
||||
</>
|
||||
) : (
|
||||
serializeUnit(unit)
|
||||
)}{' '}
|
||||
</>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
//eslint-disable-next-line
|
||||
export default (nodeValue, explanation, _, unit) => (
|
||||
<Comp {...{ nodeValue, explanation, unit }} />
|
||||
)
|
|
@ -0,0 +1,24 @@
|
|||
import React from 'react'
|
||||
import { BarèmeAttributes, TrancheTable } from './Barème'
|
||||
import './Barème.css'
|
||||
import { Node } from './common'
|
||||
|
||||
export default function Grille(nodeValue, explanation, _, unit) {
|
||||
return (
|
||||
<Node
|
||||
classes="mecanism barème"
|
||||
name="grille"
|
||||
value={nodeValue}
|
||||
unit={unit}
|
||||
child={
|
||||
<ul className="properties">
|
||||
<BarèmeAttributes explanation={explanation} />
|
||||
<TrancheTable
|
||||
tranches={explanation.tranches}
|
||||
multiplicateur={explanation.multiplicateur}
|
||||
/>
|
||||
</ul>
|
||||
}
|
||||
/>
|
||||
)
|
||||
}
|
|
@ -0,0 +1,33 @@
|
|||
import React from 'react'
|
||||
import { Trans } from 'react-i18next'
|
||||
import { BarèmeAttributes, TrancheTable } from './Barème'
|
||||
import './Barème.css'
|
||||
import { Node, NodeValuePointer } from './common'
|
||||
|
||||
export default function TauxProgressif(nodeValue, explanation, _, unit) {
|
||||
return (
|
||||
<Node
|
||||
classes="mecanism barème"
|
||||
name="taux progressif"
|
||||
value={nodeValue}
|
||||
unit={unit}
|
||||
child={
|
||||
<ul className="properties">
|
||||
<BarèmeAttributes explanation={explanation} />
|
||||
<TrancheTable
|
||||
tranches={explanation.tranches}
|
||||
multiplicateur={explanation.multiplicateur}
|
||||
/>
|
||||
{nodeValue != null && (
|
||||
<>
|
||||
<b>
|
||||
<Trans>Taux calculé</Trans> :{' '}
|
||||
</b>{' '}
|
||||
<NodeValuePointer data={nodeValue * 100} unit="%" />
|
||||
</>
|
||||
)}
|
||||
</ul>
|
||||
}
|
||||
/>
|
||||
)
|
||||
}
|
|
@ -7,9 +7,9 @@ const colors = {
|
|||
'toutes ces conditions': '#3498db',
|
||||
composantes: '#3498db',
|
||||
variations: '#FF9800',
|
||||
complément: '#795548',
|
||||
'taux progressif': '#795548',
|
||||
barème: '#607D8B',
|
||||
barèmeLinéaire: '#AD1457'
|
||||
grille: '#AD1457'
|
||||
}
|
||||
|
||||
export default (name: string) => colors[name] || '#34495e'
|
||||
|
|
|
@ -129,14 +129,19 @@ export function Leaf({
|
|||
const sitePaths = useContext(SitePathsContext)
|
||||
const flatRules = useSelector(flatRulesSelector)
|
||||
let rule = findRuleByDottedName(flatRules, dottedName)
|
||||
|
||||
const title = rule.title || capitalise0(name)
|
||||
return (
|
||||
<span className={classNames(classes, 'leaf')}>
|
||||
{dottedName && (
|
||||
<span className="nodeHead">
|
||||
<Link to={sitePaths.documentation.rule(dottedName)}>
|
||||
<span className="name">
|
||||
{rule.title || capitalise0(name)} {filter}
|
||||
{rule.acronyme ? (
|
||||
<abbr title={title}>{rule.acronyme}</abbr>
|
||||
) : (
|
||||
title
|
||||
)}{' '}
|
||||
{filter}
|
||||
</span>
|
||||
</Link>
|
||||
{!isNil(nodeValue) && (
|
||||
|
|
|
@ -54,8 +54,8 @@ export let mecanismOneOf = (recurse, k, v) => {
|
|||
value={nodeValue}
|
||||
child={
|
||||
<ul>
|
||||
{explanation.map(item => (
|
||||
<li key={item.name || item.text}>{makeJsx(item)}</li>
|
||||
{explanation.map((item, i) => (
|
||||
<li key={i}>{makeJsx(item)}</li>
|
||||
))}
|
||||
</ul>
|
||||
}
|
||||
|
@ -105,8 +105,8 @@ export let mecanismAllOf = (recurse, k, v) => {
|
|||
value={nodeValue}
|
||||
child={
|
||||
<ul>
|
||||
{explanation.map(item => (
|
||||
<li key={item.name || item.text}>{makeJsx(item)}</li>
|
||||
{explanation.map((item, i) => (
|
||||
<li key={i}>{makeJsx(item)}</li>
|
||||
))}
|
||||
</ul>
|
||||
}
|
||||
|
@ -623,9 +623,6 @@ export let mecanismSynchronisation = (recurse, k, v) => {
|
|||
}
|
||||
}
|
||||
|
||||
export let mecanismError = (recurse, k, v) => {
|
||||
throw new Error("Le mécanisme '" + k + "' est inconnu !" + v)
|
||||
}
|
||||
export let mecanismOnePossibility = dottedName => (recurse, k, v) => ({
|
||||
...v,
|
||||
'une possibilité': 'oui',
|
||||
|
|
|
@ -1,82 +0,0 @@
|
|||
import { defaultNode, evaluateObject, parseObject } from 'Engine/evaluation'
|
||||
import { decompose } from 'Engine/mecanisms/utils'
|
||||
import variations from 'Engine/mecanisms/variations'
|
||||
import BarèmeContinu from 'Engine/mecanismViews/BarèmeContinu'
|
||||
import { anyNull, val } from 'Engine/traverse-common-functions'
|
||||
import { parseUnit } from 'Engine/units'
|
||||
import {
|
||||
aperture,
|
||||
isEmpty,
|
||||
last,
|
||||
pipe,
|
||||
reduce,
|
||||
reduced,
|
||||
sort,
|
||||
toPairs
|
||||
} from 'ramda'
|
||||
export default (recurse, k, v) => {
|
||||
if (v.composantes) {
|
||||
return decompose(recurse, k, v)
|
||||
}
|
||||
if (v.variations) {
|
||||
return variations(recurse, k, v, true)
|
||||
}
|
||||
if (!v.points || typeof v.points !== 'object' || isEmpty(v.points)) {
|
||||
throw new Error(
|
||||
'Le mécanisme `barème linéaire` doit avoir un paramètre `points` valide'
|
||||
)
|
||||
}
|
||||
let objectShape = {
|
||||
assiette: false,
|
||||
multiplicateur: defaultNode(1)
|
||||
}
|
||||
let returnRate = v['retourne seulement le taux'] === 'oui'
|
||||
let effect = ({ assiette, multiplicateur, points }) => {
|
||||
if (anyNull([assiette, multiplicateur])) return null
|
||||
//We'll build a linear function given the two constraints that must be respected
|
||||
let result = pipe(
|
||||
toPairs,
|
||||
// we don't rely on the sorting of objects
|
||||
sort(([k1], [k2]) => k1 - k2),
|
||||
points => [...points, [Infinity, last(points)[1]]],
|
||||
aperture(2),
|
||||
reduce((_, [[lowerLimit, lowerRate], [upperLimit, upperRate]]) => {
|
||||
let x1 = val(multiplicateur) * lowerLimit,
|
||||
x2 = val(multiplicateur) * upperLimit,
|
||||
y1 = (val(assiette) * val(recurse(lowerRate))) / 100,
|
||||
y2 = (val(assiette) * val(recurse(upperRate))) / 100
|
||||
if (val(assiette) > x1 && val(assiette) <= x2) {
|
||||
// Outside of these 2 limits, it's a linear function a * x + b
|
||||
let a = (y2 - y1) / (x2 - x1),
|
||||
b = y1 - x1 * a,
|
||||
nodeValue = a * val(assiette) + b,
|
||||
taux = nodeValue / val(assiette)
|
||||
return reduced({
|
||||
nodeValue: returnRate ? taux * 100 : nodeValue,
|
||||
additionalExplanation: {
|
||||
seuil: val(assiette) / val(multiplicateur),
|
||||
taux,
|
||||
unit: returnRate ? parseUnit('%') : assiette.unit
|
||||
}
|
||||
})
|
||||
}
|
||||
}, 0)
|
||||
)(points)
|
||||
return result
|
||||
}
|
||||
let explanation = {
|
||||
...parseObject(recurse, objectShape, v),
|
||||
points: v.points,
|
||||
returnRate
|
||||
},
|
||||
evaluate = evaluateObject(objectShape, effect)
|
||||
return {
|
||||
evaluate,
|
||||
jsx: BarèmeContinu,
|
||||
explanation,
|
||||
category: 'mecanism',
|
||||
name: 'barème continu',
|
||||
type: 'numeric',
|
||||
unit: returnRate ? parseUnit('%') : explanation.assiette.unit
|
||||
}
|
||||
}
|
|
@ -1,87 +0,0 @@
|
|||
import { defaultNode, evaluateObject, parseObject } from 'Engine/evaluation'
|
||||
import { decompose } from 'Engine/mecanisms/utils'
|
||||
import variations from 'Engine/mecanisms/variations'
|
||||
import Barème from 'Engine/mecanismViews/Barème'
|
||||
import { evaluateNode } from 'Engine/evaluation'
|
||||
import { val } from 'Engine/traverse-common-functions'
|
||||
import { parseUnit } from 'Engine/units'
|
||||
import { desugarScale } from './barème'
|
||||
|
||||
/* on réécrit en une syntaxe plus bas niveau mais plus régulière les tranches :
|
||||
`en-dessous de: 1`
|
||||
devient
|
||||
```
|
||||
de: 0
|
||||
à: 1
|
||||
```
|
||||
*/
|
||||
|
||||
export default (recurse, k, v) => {
|
||||
if (v.composantes) {
|
||||
//mécanisme de composantes. Voir known-mecanisms.md/composantes
|
||||
return decompose(recurse, k, v)
|
||||
}
|
||||
if (v.variations) {
|
||||
return variations(recurse, k, v, true)
|
||||
}
|
||||
|
||||
let returnRate = v['retourne seulement le taux'] === 'oui'
|
||||
let tranches = desugarScale(recurse)(v['tranches']),
|
||||
objectShape = {
|
||||
assiette: false,
|
||||
multiplicateur: defaultNode(1)
|
||||
}
|
||||
|
||||
let effect = ({ assiette, multiplicateur, tranches }, cache, situationGate, parsedRules) => {
|
||||
if (val(assiette) === null) return null
|
||||
|
||||
let roundedAssiette = Math.round(val(assiette))
|
||||
|
||||
let matchedTranche = tranches.find(
|
||||
({ de: min, à: max }) =>
|
||||
roundedAssiette >= val(multiplicateur) * min &&
|
||||
roundedAssiette <= max * val(multiplicateur)
|
||||
)
|
||||
let nodeValue
|
||||
if (!matchedTranche) {
|
||||
nodeValue = 0
|
||||
} else if (matchedTranche.taux) {
|
||||
nodeValue = returnRate
|
||||
? matchedTranche.taux.nodeValue
|
||||
: (matchedTranche.taux.nodeValue / 100) * val(assiette)
|
||||
} else {
|
||||
matchedTranche.montant = evaluateNode(cache, situationGate, parsedRules, matchedTranche.montant)
|
||||
nodeValue = matchedTranche.montant.nodeValue
|
||||
}
|
||||
|
||||
return {
|
||||
nodeValue,
|
||||
additionalExplanation: {
|
||||
matchedTranche,
|
||||
unit: returnRate
|
||||
? parseUnit('%')
|
||||
: (v['unité'] && parseUnit(v['unité'])) || explanation.assiette.unit
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let explanation = {
|
||||
...parseObject(recurse, objectShape, v),
|
||||
returnRate,
|
||||
tranches
|
||||
},
|
||||
evaluate = evaluateObject(objectShape, effect),
|
||||
unit = returnRate
|
||||
? parseUnit('%')
|
||||
: (v['unité'] && parseUnit(v['unité'])) || explanation.assiette.unit
|
||||
return {
|
||||
evaluate,
|
||||
jsx: Barème('linéaire'),
|
||||
explanation,
|
||||
category: 'mecanism',
|
||||
name: 'barème linéaire',
|
||||
barème: 'en taux',
|
||||
type: 'numeric',
|
||||
unit
|
||||
}
|
||||
}
|
|
@ -1,138 +0,0 @@
|
|||
import { defaultNode, evaluateNode, mergeAllMissing } from 'Engine/evaluation'
|
||||
import { decompose } from 'Engine/mecanisms/utils'
|
||||
import variations from 'Engine/mecanisms/variations'
|
||||
import Barème from 'Engine/mecanismViews/Barème'
|
||||
import { evolve, has } from 'ramda'
|
||||
import { typeWarning } from '../error'
|
||||
import { convertNodeToUnit } from '../nodeUnits'
|
||||
import { parseUnit } from '../units'
|
||||
|
||||
export let desugarScale = recurse => tranches =>
|
||||
tranches
|
||||
.map(t =>
|
||||
has('en-dessous de')(t)
|
||||
? { ...t, de: 0, à: t['en-dessous de'] }
|
||||
: has('au-dessus de')(t)
|
||||
? { ...t, de: t['au-dessus de'], à: Infinity }
|
||||
: t
|
||||
)
|
||||
.map(evolve({ taux: recurse, montant: recurse }))
|
||||
|
||||
// This function was also used for marginal barèmes, but now only for linear ones
|
||||
export let trancheValue = (assiette, multiplicateur) => ({
|
||||
de: min,
|
||||
à: max,
|
||||
taux,
|
||||
montant
|
||||
}) =>
|
||||
Math.round(assiette.nodeValue) >= min * multiplicateur.nodeValue &&
|
||||
(!max || Math.round(assiette.nodeValue) <= max * multiplicateur.nodeValue)
|
||||
? taux != null
|
||||
? assiette.nodeValue * taux.nodeValue
|
||||
: montant
|
||||
: 0
|
||||
|
||||
export default (recurse, k, v) => {
|
||||
// Barème en taux marginaux.
|
||||
|
||||
if (v.composantes) {
|
||||
//mécanisme de composantes. Voir known-mecanisms.md/composantes
|
||||
return decompose(recurse, k, v)
|
||||
}
|
||||
if (v.variations) {
|
||||
return variations(recurse, k, v, true)
|
||||
}
|
||||
|
||||
let { assiette, multiplicateur } = v,
|
||||
tranches = desugarScale(recurse)(v['tranches'])
|
||||
|
||||
let explanation = {
|
||||
assiette: recurse(assiette),
|
||||
multiplicateur: multiplicateur ? recurse(multiplicateur) : defaultNode(1),
|
||||
tranches
|
||||
}
|
||||
|
||||
let evaluate = (cache, situationGate, parsedRules, node) => {
|
||||
let { assiette, multiplicateur } = node.explanation
|
||||
assiette = evaluateNode(cache, situationGate, parsedRules, assiette)
|
||||
multiplicateur = evaluateNode(
|
||||
cache,
|
||||
situationGate,
|
||||
parsedRules,
|
||||
multiplicateur
|
||||
)
|
||||
try {
|
||||
multiplicateur = convertNodeToUnit(assiette.unit, multiplicateur)
|
||||
} catch (e) {
|
||||
typeWarning(
|
||||
cache._meta.contextRule,
|
||||
`L'unité du multiplicateur du barème doit être compatible avec celle de son assiette`,
|
||||
e
|
||||
)
|
||||
}
|
||||
const tranches = node.explanation.tranches.map(tranche => {
|
||||
let { de: min, à: max, taux } = tranche
|
||||
if (
|
||||
[assiette, multiplicateur].every(
|
||||
({ nodeValue }) => nodeValue != null
|
||||
) &&
|
||||
assiette.nodeValue < min * multiplicateur.nodeValue
|
||||
) {
|
||||
return { ...tranche, nodeValue: 0 }
|
||||
}
|
||||
taux = convertNodeToUnit(
|
||||
parseUnit(''),
|
||||
evaluateNode(cache, situationGate, parsedRules, taux)
|
||||
)
|
||||
if (
|
||||
[assiette, multiplicateur, taux].some(
|
||||
({ nodeValue }) => nodeValue == null
|
||||
)
|
||||
) {
|
||||
return {
|
||||
...tranche,
|
||||
nodeValue: null,
|
||||
missingVariables: taux.missingVariables
|
||||
}
|
||||
}
|
||||
return {
|
||||
...tranche,
|
||||
nodeValue:
|
||||
(Math.min(assiette.nodeValue, max * multiplicateur.nodeValue) -
|
||||
min * multiplicateur.nodeValue) *
|
||||
taux.nodeValue
|
||||
}
|
||||
})
|
||||
|
||||
const nodeValue = tranches.reduce(
|
||||
(value, { nodeValue }) => (nodeValue == null ? null : value + nodeValue),
|
||||
0
|
||||
)
|
||||
const missingVariables = mergeAllMissing([
|
||||
assiette,
|
||||
multiplicateur,
|
||||
...tranches
|
||||
])
|
||||
return {
|
||||
...node,
|
||||
nodeValue,
|
||||
explanation: {
|
||||
...explanation,
|
||||
tranches
|
||||
},
|
||||
missingVariables,
|
||||
unit: assiette.unit,
|
||||
lazyEval: node => evaluateNode(cache, situationGate, parsedRules, node)
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
explanation,
|
||||
evaluate,
|
||||
jsx: Barème('marginal'),
|
||||
category: 'mecanism',
|
||||
name: 'barème',
|
||||
barème: 'marginal',
|
||||
unit: explanation.assiette.unit
|
||||
}
|
||||
}
|
|
@ -0,0 +1,91 @@
|
|||
import { defaultNode, evaluateNode, mergeAllMissing } from 'Engine/evaluation'
|
||||
import { decompose } from 'Engine/mecanisms/utils'
|
||||
import variations from 'Engine/mecanisms/variations'
|
||||
import Barème from 'Engine/mecanismViews/Barème'
|
||||
import { convertUnit, parseUnit } from '../units'
|
||||
import {
|
||||
evaluatePlafondUntilActiveTranche,
|
||||
parseTranches
|
||||
} from './trancheUtils'
|
||||
|
||||
export default function parse(parse, k, v) {
|
||||
// Barème en taux marginaux.
|
||||
|
||||
if (v.composantes) {
|
||||
//mécanisme de composantes. Voir known-mecanisms.md/composantes
|
||||
return decompose(parse, k, v)
|
||||
}
|
||||
if (v.variations) {
|
||||
return variations(parse, k, v, true)
|
||||
}
|
||||
const explanation = {
|
||||
assiette: parse(v.assiette),
|
||||
multiplicateur: v.multiplicateur ? parse(v.multiplicateur) : defaultNode(1),
|
||||
tranches: parseTranches(parse, v.tranches)
|
||||
}
|
||||
return {
|
||||
explanation,
|
||||
evaluate,
|
||||
jsx: Barème,
|
||||
category: 'mecanism',
|
||||
name: 'barème',
|
||||
type: 'numeric',
|
||||
unit: explanation.assiette.unit
|
||||
}
|
||||
}
|
||||
|
||||
const evaluate = (
|
||||
cache,
|
||||
situationGate,
|
||||
parsedRules,
|
||||
node: ReturnType<typeof parse>
|
||||
) => {
|
||||
const evaluate = evaluateNode.bind(null, cache, situationGate, parsedRules)
|
||||
const assiette = evaluate(node.explanation.assiette)
|
||||
const multiplicateur = evaluate(node.explanation.multiplicateur)
|
||||
const tranches = evaluatePlafondUntilActiveTranche(
|
||||
evaluate,
|
||||
{
|
||||
parsedTranches: node.explanation.tranches,
|
||||
assiette,
|
||||
multiplicateur
|
||||
},
|
||||
cache
|
||||
).map(tranche => {
|
||||
if (tranche.isAfterActive) {
|
||||
return { ...tranche, nodeValue: 0 }
|
||||
}
|
||||
const taux = evaluate(tranche.taux)
|
||||
if ([taux.nodeValue, tranche.nodeValue].some(value => value === null)) {
|
||||
return {
|
||||
...tranche,
|
||||
taux,
|
||||
nodeValue: null,
|
||||
missingVariables: mergeAllMissing([taux, tranche])
|
||||
}
|
||||
}
|
||||
return {
|
||||
...tranche,
|
||||
taux,
|
||||
unit: assiette.unit,
|
||||
nodeValue:
|
||||
(Math.min(assiette.nodeValue, tranche.plafondValue) -
|
||||
tranche.plancherValue) *
|
||||
convertUnit(taux.unit, parseUnit(''), taux.nodeValue)
|
||||
}
|
||||
})
|
||||
return {
|
||||
...node,
|
||||
nodeValue: tranches.reduce(
|
||||
(value, { nodeValue }) => (nodeValue == null ? null : value + nodeValue),
|
||||
0
|
||||
),
|
||||
missingVariables: mergeAllMissing(tranches),
|
||||
explanation: {
|
||||
assiette,
|
||||
multiplicateur,
|
||||
tranches
|
||||
},
|
||||
unit: assiette.unit
|
||||
}
|
||||
}
|
|
@ -0,0 +1,85 @@
|
|||
import { defaultNode, evaluateNode, mergeAllMissing } from 'Engine/evaluation'
|
||||
import { decompose } from 'Engine/mecanisms/utils'
|
||||
import variations from 'Engine/mecanisms/variations'
|
||||
import grille from 'Engine/mecanismViews/Grille'
|
||||
import { parseUnit } from 'Engine/units'
|
||||
import { lensPath, over } from 'ramda'
|
||||
import {
|
||||
evaluatePlafondUntilActiveTranche,
|
||||
parseTranches
|
||||
} from './trancheUtils'
|
||||
|
||||
export default function parse(parse, k, v) {
|
||||
if (v.composantes) {
|
||||
//mécanisme de composantes. Voir known-mecanisms.md/composantes
|
||||
return decompose(parse, k, v)
|
||||
}
|
||||
if (v.variations) {
|
||||
return variations(parse, k, v, true)
|
||||
}
|
||||
const defaultUnit = v['unité'] && parseUnit(v['unité'])
|
||||
let explanation = {
|
||||
assiette: parse(v.assiette),
|
||||
multiplicateur: v.multiplicateur ? parse(v.multiplicateur) : defaultNode(1),
|
||||
tranches: parseTranches(parse, v.tranches).map(
|
||||
over(lensPath(['montant', 'unit']), unit => unit ?? defaultUnit)
|
||||
)
|
||||
}
|
||||
return {
|
||||
explanation,
|
||||
evaluate,
|
||||
jsx: grille,
|
||||
category: 'mecanism',
|
||||
name: 'grille',
|
||||
type: 'numeric',
|
||||
unit: explanation.tranches[0].montant.unit
|
||||
}
|
||||
}
|
||||
|
||||
const evaluate = (
|
||||
cache,
|
||||
situationGate,
|
||||
parsedRules,
|
||||
node: ReturnType<typeof parse>
|
||||
) => {
|
||||
const evaluate = evaluateNode.bind(null, cache, situationGate, parsedRules)
|
||||
const assiette = evaluate(node.explanation.assiette)
|
||||
const multiplicateur = evaluate(node.explanation.multiplicateur)
|
||||
const tranches = evaluatePlafondUntilActiveTranche(
|
||||
evaluate,
|
||||
{
|
||||
parsedTranches: node.explanation.tranches,
|
||||
assiette,
|
||||
multiplicateur
|
||||
},
|
||||
cache
|
||||
).map(tranche => {
|
||||
if (tranche.isActive === false) {
|
||||
return tranche
|
||||
}
|
||||
const montant = evaluate(tranche.montant)
|
||||
return {
|
||||
...tranche,
|
||||
montant,
|
||||
nodeValue: montant.nodeValue,
|
||||
unit: montant.unit,
|
||||
missingVariables: mergeAllMissing([montant, tranche])
|
||||
}
|
||||
})
|
||||
|
||||
const activeTranches = tranches.filter(({ isActive }) => isActive != false)
|
||||
const missingVariables = mergeAllMissing(activeTranches)
|
||||
const nodeValue = activeTranches.length ? activeTranches[0].nodeValue : false
|
||||
|
||||
return {
|
||||
...node,
|
||||
explanation: {
|
||||
tranches,
|
||||
assiette,
|
||||
multiplicateur
|
||||
},
|
||||
missingVariables,
|
||||
nodeValue,
|
||||
unit: activeTranches[0]?.unit ?? node.unit
|
||||
}
|
||||
}
|
|
@ -0,0 +1,134 @@
|
|||
import { defaultNode, evaluateNode, mergeAllMissing } from 'Engine/evaluation'
|
||||
import { decompose } from 'Engine/mecanisms/utils'
|
||||
import variations from 'Engine/mecanisms/variations'
|
||||
import tauxProgressif from 'Engine/mecanismViews/TauxProgressif'
|
||||
import { convertNodeToUnit } from 'Engine/nodeUnits'
|
||||
import { anyNull } from 'Engine/traverse-common-functions'
|
||||
import { parseUnit } from 'Engine/units'
|
||||
import {
|
||||
evaluatePlafondUntilActiveTranche,
|
||||
parseTranches
|
||||
} from './trancheUtils'
|
||||
|
||||
export default function parse(parse, k, v) {
|
||||
if (v.composantes) {
|
||||
//mécanisme de composantes. Voir known-mecanisms.md/composantes
|
||||
return decompose(parse, k, v)
|
||||
}
|
||||
if (v.variations) {
|
||||
return variations(parse, k, v, true)
|
||||
}
|
||||
|
||||
let explanation = {
|
||||
assiette: parse(v.assiette),
|
||||
multiplicateur: v.multiplicateur ? parse(v.multiplicateur) : defaultNode(1),
|
||||
tranches: parseTranches(parse, v.tranches)
|
||||
}
|
||||
return {
|
||||
evaluate,
|
||||
jsx: tauxProgressif,
|
||||
explanation,
|
||||
category: 'mecanism',
|
||||
name: 'taux progressif',
|
||||
type: 'numeric',
|
||||
unit: parseUnit('%')
|
||||
}
|
||||
}
|
||||
|
||||
const evaluate = (
|
||||
cache,
|
||||
situationGate,
|
||||
parsedRules,
|
||||
node: ReturnType<typeof parse>
|
||||
) => {
|
||||
const evaluate = evaluateNode.bind(null, cache, situationGate, parsedRules)
|
||||
const assiette = evaluate(node.explanation.assiette)
|
||||
const multiplicateur = evaluate(node.explanation.multiplicateur)
|
||||
const tranches = evaluatePlafondUntilActiveTranche(
|
||||
evaluate,
|
||||
{
|
||||
parsedTranches: node.explanation.tranches,
|
||||
assiette,
|
||||
multiplicateur
|
||||
},
|
||||
cache
|
||||
)
|
||||
|
||||
const evaluatedNode = {
|
||||
...node,
|
||||
explanation: {
|
||||
tranches,
|
||||
assiette,
|
||||
multiplicateur
|
||||
},
|
||||
unit: parseUnit('%')
|
||||
}
|
||||
|
||||
const lastTranche = tranches[tranches.length - 1]
|
||||
if (
|
||||
tranches.every(({ isActive }) => isActive === false) ||
|
||||
(lastTranche.isActive && lastTranche.plafond.nodeValue === Infinity)
|
||||
) {
|
||||
const taux = convertNodeToUnit(parseUnit('%'), evaluate(lastTranche.taux))
|
||||
const { nodeValue, missingVariables } = taux
|
||||
lastTranche.taux = taux
|
||||
lastTranche.nodeValue = nodeValue
|
||||
lastTranche.missingVariables = missingVariables
|
||||
return {
|
||||
...evaluatedNode,
|
||||
nodeValue,
|
||||
missingVariables
|
||||
}
|
||||
}
|
||||
|
||||
if (tranches.every(({ isActive }) => isActive !== true)) {
|
||||
return {
|
||||
...evaluatedNode,
|
||||
nodeValue: null,
|
||||
missingVariables: mergeAllMissing(tranches)
|
||||
}
|
||||
}
|
||||
|
||||
const activeTrancheIndex = tranches.findIndex(
|
||||
({ isActive }) => isActive === true
|
||||
)
|
||||
const activeTranche = tranches[activeTrancheIndex]
|
||||
activeTranche.taux = convertNodeToUnit(
|
||||
parseUnit('%'),
|
||||
evaluate(activeTranche.taux)
|
||||
)
|
||||
|
||||
const previousTranche = tranches[activeTrancheIndex - 1]
|
||||
if (previousTranche) {
|
||||
previousTranche.taux = convertNodeToUnit(
|
||||
parseUnit('%'),
|
||||
evaluate(previousTranche.taux)
|
||||
)
|
||||
previousTranche.isActive = true
|
||||
}
|
||||
const previousTaux = previousTranche
|
||||
? previousTranche.taux
|
||||
: activeTranche.taux
|
||||
const calculationValues = [previousTaux, activeTranche.taux, activeTranche]
|
||||
if (anyNull(calculationValues)) {
|
||||
activeTranche.nodeValue = null
|
||||
activeTranche.missingVariables = mergeAllMissing(calculationValues)
|
||||
return {
|
||||
...evaluatedNode,
|
||||
nodeValue: null,
|
||||
activeTranche: activeTranche.missingVariables
|
||||
}
|
||||
}
|
||||
|
||||
const lowerTaux = previousTaux.nodeValue
|
||||
const upperTaux = activeTranche.taux.nodeValue
|
||||
const plancher = activeTranche.plancherValue
|
||||
const plafond = activeTranche.plafondValue
|
||||
const coeff = (upperTaux - lowerTaux) / (plafond - plancher)
|
||||
const nodeValue = lowerTaux + (assiette.nodeValue - plancher) * coeff
|
||||
activeTranche.nodeValue = nodeValue
|
||||
return {
|
||||
...evaluatedNode,
|
||||
nodeValue
|
||||
}
|
||||
}
|
|
@ -0,0 +1,97 @@
|
|||
import { mergeAllMissing } from 'Engine/evaluation'
|
||||
import { evolve } from 'ramda'
|
||||
import { evaluationError, typeWarning } from '../error'
|
||||
import { convertUnit, inferUnit } from '../units'
|
||||
|
||||
export const parseTranches = (parse, tranches) => {
|
||||
return tranches
|
||||
.map((t, i) => {
|
||||
if (!t.plafond && i > tranches.length) {
|
||||
console.log(t, i)
|
||||
throw new SyntaxError(
|
||||
`La tranche n°${i} du barème n'a pas de plafond précisé. Seule la dernière tranche peut ne pas être plafonnée`
|
||||
)
|
||||
}
|
||||
return { ...t, plafond: t.plafond ?? Infinity }
|
||||
})
|
||||
.map(evolve({ taux: parse, montant: parse, plafond: parse }))
|
||||
}
|
||||
|
||||
export function evaluatePlafondUntilActiveTranche(
|
||||
evaluate,
|
||||
{ multiplicateur, assiette, parsedTranches },
|
||||
cache
|
||||
) {
|
||||
return parsedTranches.reduce(
|
||||
([tranches, activeTrancheFound], parsedTranche, i: number) => {
|
||||
if (activeTrancheFound) {
|
||||
return [
|
||||
[...tranches, { ...parsedTranche, isAfterActive: true }],
|
||||
activeTrancheFound
|
||||
]
|
||||
}
|
||||
|
||||
const plafond = evaluate(parsedTranche.plafond)
|
||||
const plancher = tranches[i - 1]
|
||||
? tranches[i - 1].plafond
|
||||
: { nodeValue: 0 }
|
||||
const calculationValues = [plafond, assiette, multiplicateur, plancher]
|
||||
if (calculationValues.some(node => node.nodeValue === null)) {
|
||||
return [
|
||||
[
|
||||
...tranches,
|
||||
{
|
||||
...parsedTranche,
|
||||
plafond,
|
||||
nodeValue: null,
|
||||
isActive: null,
|
||||
isAfterActive: false,
|
||||
missingVariables: mergeAllMissing(calculationValues)
|
||||
}
|
||||
],
|
||||
false
|
||||
]
|
||||
}
|
||||
let plafondValue = plafond.nodeValue * multiplicateur.nodeValue
|
||||
try {
|
||||
plafondValue = [Infinity || 0].includes(plafondValue)
|
||||
? plafondValue
|
||||
: convertUnit(
|
||||
inferUnit('*', [plafond.unit, multiplicateur.unit]),
|
||||
assiette.unit,
|
||||
plafondValue
|
||||
)
|
||||
} catch (e) {
|
||||
typeWarning(
|
||||
cache._meta.contextRule,
|
||||
`L'unité du plafond de la tranche n°${i +
|
||||
1} n'est pas compatible avec celle l'assiette`,
|
||||
e
|
||||
)
|
||||
}
|
||||
|
||||
let plancherValue = tranches[i - 1] ? tranches[i - 1].plafondValue : 0
|
||||
if (!!tranches[i - 1] && plafondValue <= plancherValue) {
|
||||
evaluationError(
|
||||
cache._meta.contextRule,
|
||||
`Le plafond de la tranche n°${i +
|
||||
1} a une valeur inférieure à celui de la tranche précédente`
|
||||
)
|
||||
}
|
||||
|
||||
const tranche = {
|
||||
...parsedTranche,
|
||||
plafond,
|
||||
plancherValue,
|
||||
plafondValue,
|
||||
isAfterActive: false,
|
||||
isActive:
|
||||
assiette.nodeValue >= plancherValue &&
|
||||
assiette.nodeValue < plafondValue
|
||||
}
|
||||
|
||||
return [[...tranches, tranche], tranche.isActive]
|
||||
},
|
||||
[[], false]
|
||||
)[0]
|
||||
}
|
|
@ -5,38 +5,30 @@
|
|||
import { formatValue } from 'Engine/format'
|
||||
import mecanismRound from 'Engine/mecanisms/arrondi'
|
||||
import barème from 'Engine/mecanisms/barème'
|
||||
import barèmeContinu from 'Engine/mecanisms/barème-continu'
|
||||
import barèmeLinéaire from 'Engine/mecanisms/barème-linéaire'
|
||||
import durée from 'Engine/mecanisms/durée'
|
||||
import encadrement from 'Engine/mecanisms/encadrement'
|
||||
import grille from 'Engine/mecanisms/grille'
|
||||
import operation from 'Engine/mecanisms/operation'
|
||||
import tauxProgressif from 'Engine/mecanisms/tauxProgressif'
|
||||
import variations from 'Engine/mecanisms/variations'
|
||||
import { Grammar, Parser } from 'nearley'
|
||||
import {
|
||||
add,
|
||||
cond,
|
||||
divide,
|
||||
equals,
|
||||
fromPairs,
|
||||
gt,
|
||||
gte,
|
||||
is,
|
||||
keys,
|
||||
lt,
|
||||
lte,
|
||||
multiply,
|
||||
propOr,
|
||||
subtract,
|
||||
T,
|
||||
without
|
||||
subtract
|
||||
} from 'ramda'
|
||||
import React from 'react'
|
||||
import { syntaxError } from './error.ts'
|
||||
import grammar from './grammar.ne'
|
||||
import {
|
||||
mecanismAllOf,
|
||||
mecanismComplement,
|
||||
mecanismError,
|
||||
mecanismInversion,
|
||||
mecanismMax,
|
||||
mecanismMin,
|
||||
|
@ -49,154 +41,156 @@ import {
|
|||
} from './mecanisms'
|
||||
import { parseReferenceTransforms } from './parseReference'
|
||||
|
||||
export let parse = (rules, rule, parsedRules) => rawNode => {
|
||||
let onNodeType = cond([
|
||||
[is(String), parseString(rules, rule, parsedRules)],
|
||||
[is(Number), parseNumber],
|
||||
[is(Object), parseObject(rules, rule, parsedRules)],
|
||||
[T, parseOther]
|
||||
])
|
||||
export const parse = (rules, rule, parsedRules) => rawNode => {
|
||||
if (rawNode == null) {
|
||||
syntaxError(
|
||||
rule.dottedName,
|
||||
`
|
||||
Une des valeurs de la formule est vide.
|
||||
Vérifiez que tous les champs à droite des deux points sont remplis`
|
||||
)
|
||||
}
|
||||
if (typeof rawNode === 'boolean') {
|
||||
syntaxError(
|
||||
rule.dottedName,
|
||||
`
|
||||
Les valeure booléenes true / false ne sont acceptée.
|
||||
Utilisez leur contrepartie française : 'oui' / 'non'`
|
||||
)
|
||||
}
|
||||
const node =
|
||||
typeof rawNode === 'object' ? rawNode : parseExpression(rule, '' + rawNode)
|
||||
|
||||
let defaultEvaluate = (cache, situationGate, parsedRules, node) => node
|
||||
let parsedNode = onNodeType(rawNode)
|
||||
|
||||
return parsedNode.evaluate
|
||||
? parsedNode
|
||||
: { ...parsedNode, evaluate: defaultEvaluate }
|
||||
const parsedNode = parseMecanism(rules, rule, parsedRules)(node)
|
||||
parsedNode.evaluate = parsedNode.evaluate ?? ((_, __, ___, node) => node)
|
||||
return parsedNode
|
||||
}
|
||||
|
||||
const compiledGrammar = Grammar.fromCompiled(grammar)
|
||||
|
||||
export let parseString = (rules, rule, parsedRules) => rawNode => {
|
||||
const parseExpression = (rule, rawNode) => {
|
||||
/* Strings correspond to infix expressions.
|
||||
* Indeed, a subset of expressions like simple arithmetic operations `3 + (quantity * 2)` or like `salary [month]` are more explicit that their prefixed counterparts.
|
||||
* This function makes them prefixed operations. */
|
||||
try {
|
||||
let [parseResult] = new Parser(compiledGrammar).feed(rawNode).results
|
||||
return parseObject(rules, rule, parsedRules)(parseResult)
|
||||
return parseResult
|
||||
} catch (e) {
|
||||
syntaxError(
|
||||
rule.dottedName,
|
||||
`\`${rawNode}\` n'est pas une formule valide`,
|
||||
`\`${rawNode}\` n'est pas une expression valide`,
|
||||
e
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
export let parseNumber = rawNode => ({
|
||||
text: '' + rawNode,
|
||||
category: 'number',
|
||||
nodeValue: rawNode,
|
||||
type: 'numeric',
|
||||
jsx: <span className="number">{rawNode}</span>
|
||||
})
|
||||
|
||||
export let parseOther = rawNode => {
|
||||
throw new Error(
|
||||
'Cette donnée : ' + rawNode + ' doit être un Number, String ou Object'
|
||||
)
|
||||
}
|
||||
|
||||
export let parseObject = (rules, rule, parsedRules) => rawNode => {
|
||||
/* TODO instead of describing mecanisms in knownMecanisms.yaml, externalize the mecanisms themselves in an individual file and describe it
|
||||
let mecanisms = intersection(keys(rawNode), keys(knownMecanisms))
|
||||
|
||||
if (mecanisms.length != 1) {
|
||||
}
|
||||
*/
|
||||
|
||||
let attributes = keys(rawNode),
|
||||
descriptiveAttributes = ['description', 'note', 'référence'],
|
||||
relevantAttributes = without(descriptiveAttributes, attributes)
|
||||
if (relevantAttributes.length !== 1)
|
||||
throw new Error(`OUPS : On ne devrait reconnaître que un et un seul mécanisme dans cet objet (au-delà des attributs descriptifs tels que "description", "commentaire", etc.)
|
||||
Objet YAML : ${JSON.stringify(rawNode)}
|
||||
Cette liste doit avoir un et un seul élément.
|
||||
Si vous venez tout juste d'ajouter un nouveau mécanisme, vérifier qu'il est bien intégré dans le dispatch de parse.js
|
||||
`)
|
||||
let k = relevantAttributes[0],
|
||||
v = rawNode[k]
|
||||
|
||||
let knownOperations = {
|
||||
'*': [multiply, '×'],
|
||||
'/': [divide, '∕'],
|
||||
'+': [add],
|
||||
'-': [subtract, '−'],
|
||||
'<': [lt],
|
||||
'<=': [lte, '≤'],
|
||||
'>': [gt],
|
||||
'>=': [gte, '≥'],
|
||||
'=': [equals],
|
||||
'!=': [(a, b) => !equals(a, b), '≠']
|
||||
},
|
||||
operationDispatch = fromPairs(
|
||||
Object.entries(knownOperations).map(([k, [f, symbol]]) => [
|
||||
k,
|
||||
operation(k, f, symbol)
|
||||
])
|
||||
const parseMecanism = (rules, rule, parsedRules) => rawNode => {
|
||||
if (Object.keys(rawNode).length > 1) {
|
||||
syntaxError(
|
||||
rule.dottedName,
|
||||
`
|
||||
Les mécanismes suivants se situent au même niveau : ${Object.keys(rawNode)
|
||||
.map(x => `'${x}'`)
|
||||
.join(', ')}
|
||||
Cela vient probablement d'une erreur dans l'indentation
|
||||
`
|
||||
)
|
||||
}
|
||||
const mecanismName = Object.keys(rawNode)[0]
|
||||
const values = rawNode[mecanismName]
|
||||
|
||||
let dispatch = {
|
||||
'une de ces conditions': mecanismOneOf,
|
||||
'toutes ces conditions': mecanismAllOf,
|
||||
somme: mecanismSum,
|
||||
multiplication: mecanismProduct,
|
||||
arrondi: mecanismRound,
|
||||
barème,
|
||||
'barème linéaire': barèmeLinéaire,
|
||||
'barème continu': barèmeContinu,
|
||||
encadrement,
|
||||
durée,
|
||||
'le maximum de': mecanismMax,
|
||||
'le minimum de': mecanismMin,
|
||||
complément: mecanismComplement,
|
||||
'une possibilité': mecanismOnePossibility(rule.dottedName),
|
||||
'inversion numérique': mecanismInversion(rule.dottedName),
|
||||
allègement: mecanismReduction,
|
||||
variations,
|
||||
synchronisation: mecanismSynchronisation,
|
||||
...operationDispatch,
|
||||
filter: () =>
|
||||
parseReferenceTransforms(
|
||||
rules,
|
||||
rule,
|
||||
parsedRules
|
||||
)({
|
||||
filter: v.filter,
|
||||
variable: v.explanation
|
||||
}),
|
||||
variable: () =>
|
||||
parseReferenceTransforms(rules, rule, parsedRules)({ variable: v }),
|
||||
unitConversion: () =>
|
||||
parseReferenceTransforms(
|
||||
rules,
|
||||
rule,
|
||||
parsedRules
|
||||
)({
|
||||
variable: v.explanation,
|
||||
unit: v.unit
|
||||
}),
|
||||
constant: () => ({
|
||||
type: v.type,
|
||||
nodeValue: v.nodeValue,
|
||||
unit: v.unit,
|
||||
// eslint-disable-next-line
|
||||
jsx: () => (
|
||||
<span className={v.type}>
|
||||
{formatValue({
|
||||
unit: v.unit,
|
||||
value: v.nodeValue,
|
||||
// TODO : handle localization here
|
||||
language: 'fr',
|
||||
// We want to display constants with full precision,
|
||||
// espacilly for percentages like APEC 0,036 %
|
||||
maximumFractionDigits: 5
|
||||
})}
|
||||
</span>
|
||||
)
|
||||
const parseFunctions = {
|
||||
...statelessParseFunction,
|
||||
'une possibilité': mecanismOnePossibility(rule.dottedName),
|
||||
'inversion numérique': mecanismInversion(rule.dottedName),
|
||||
filter: () =>
|
||||
parseReferenceTransforms(
|
||||
rules,
|
||||
rule,
|
||||
parsedRules
|
||||
)({
|
||||
filter: values.filter,
|
||||
variable: values.explanation
|
||||
}),
|
||||
variable: () =>
|
||||
parseReferenceTransforms(rules, rule, parsedRules)({ variable: values }),
|
||||
unitConversion: () =>
|
||||
parseReferenceTransforms(
|
||||
rules,
|
||||
rule,
|
||||
parsedRules
|
||||
)({
|
||||
variable: values.explanation,
|
||||
unit: values.unit
|
||||
})
|
||||
},
|
||||
action = propOr(mecanismError, k, dispatch)
|
||||
}
|
||||
|
||||
return action(parse(rules, rule, parsedRules), k, v)
|
||||
const parseFn = parseFunctions[mecanismName]
|
||||
if (!parseFn) {
|
||||
syntaxError(
|
||||
rule.dottedName,
|
||||
`
|
||||
Le mécanisme ${mecanismName} est inconnu.
|
||||
Vérifiez qu'il n'y ait pas d'erreur dans l'orthographe du nom.`
|
||||
)
|
||||
}
|
||||
return parseFn(parse(rules, rule, parsedRules), mecanismName, values)
|
||||
}
|
||||
|
||||
const knownOperations = {
|
||||
'*': [multiply, '×'],
|
||||
'/': [divide, '∕'],
|
||||
'+': [add],
|
||||
'-': [subtract, '−'],
|
||||
'<': [lt],
|
||||
'<=': [lte, '≤'],
|
||||
'>': [gt],
|
||||
'>=': [gte, '≥'],
|
||||
'=': [equals],
|
||||
'!=': [(a, b) => !equals(a, b), '≠']
|
||||
}
|
||||
|
||||
const operationDispatch = fromPairs(
|
||||
Object.entries(knownOperations).map(([k, [f, symbol]]) => [
|
||||
k,
|
||||
operation(k, f, symbol)
|
||||
])
|
||||
)
|
||||
|
||||
const statelessParseFunction = {
|
||||
...operationDispatch,
|
||||
'une de ces conditions': mecanismOneOf,
|
||||
'toutes ces conditions': mecanismAllOf,
|
||||
somme: mecanismSum,
|
||||
multiplication: mecanismProduct,
|
||||
arrondi: mecanismRound,
|
||||
barème,
|
||||
grille,
|
||||
'taux progressif': tauxProgressif,
|
||||
encadrement,
|
||||
durée,
|
||||
'le maximum de': mecanismMax,
|
||||
'le minimum de': mecanismMin,
|
||||
allègement: mecanismReduction,
|
||||
variations,
|
||||
synchronisation: mecanismSynchronisation,
|
||||
constant: (_, __, v) => ({
|
||||
type: v.type,
|
||||
nodeValue: v.nodeValue,
|
||||
unit: v.unit,
|
||||
// eslint-disable-next-line
|
||||
jsx: (nodeValue, _, __, unit) => (
|
||||
<span className={v.type}>
|
||||
{formatValue({
|
||||
unit: unit,
|
||||
value: nodeValue,
|
||||
// TODO : handle localization here
|
||||
language: 'fr',
|
||||
// We want to display constants with full precision,
|
||||
// espacilly for percentages like APEC 0,036 %
|
||||
maximumFractionDigits: 5
|
||||
})}
|
||||
</span>
|
||||
)
|
||||
})
|
||||
}
|
||||
|
|
|
@ -50,7 +50,7 @@ let printUnits = (units: Array<string>, count: number, lng): string =>
|
|||
|
||||
const plural = 2
|
||||
export let serializeUnit = (
|
||||
rawUnit: Unit | null | string,
|
||||
rawUnit: Unit | undefined | string,
|
||||
count: number = plural,
|
||||
lng: string = 'fr'
|
||||
) => {
|
||||
|
@ -88,7 +88,7 @@ type SupportedOperators = '*' | '/' | '+' | '-'
|
|||
let noUnit = { numerators: [], denominators: [] }
|
||||
export let inferUnit = (
|
||||
operator: SupportedOperators,
|
||||
rawUnits: Array<Unit>
|
||||
rawUnits: Array<Unit | undefined>
|
||||
): Unit | undefined => {
|
||||
let units = rawUnits.map(u => u || noUnit)
|
||||
if (operator === '*')
|
||||
|
@ -182,7 +182,11 @@ function unitsConversionFactor(from: string[], to: string[]): number {
|
|||
return factor
|
||||
}
|
||||
|
||||
export function convertUnit(from: Unit, to: Unit, value: number) {
|
||||
export function convertUnit(
|
||||
from: Unit | undefined,
|
||||
to: Unit | undefined,
|
||||
value: number
|
||||
) {
|
||||
if (!areUnitConvertible(from, to)) {
|
||||
throw new Error(
|
||||
`Impossible de convertir l'unité '${serializeUnit(
|
||||
|
@ -193,8 +197,8 @@ export function convertUnit(from: Unit, to: Unit, value: number) {
|
|||
if (!value) {
|
||||
return value
|
||||
}
|
||||
const [fromSimplified, factorTo] = simplifyUnitWithValue(from)
|
||||
const [toSimplified, factorFrom] = simplifyUnitWithValue(to)
|
||||
const [fromSimplified, factorTo] = simplifyUnitWithValue(from || noUnit)
|
||||
const [toSimplified, factorFrom] = simplifyUnitWithValue(to || noUnit)
|
||||
return round(
|
||||
((value * factorTo) / factorFrom) *
|
||||
unitsConversionFactor(
|
||||
|
@ -239,7 +243,7 @@ export function simplifyUnitWithValue(
|
|||
value ? round(value * factor) : value
|
||||
]
|
||||
}
|
||||
export function areUnitConvertible(a: Unit, b: Unit) {
|
||||
export function areUnitConvertible(a: Unit | undefined, b: Unit | undefined) {
|
||||
if (a == null || b == null) {
|
||||
return true
|
||||
}
|
||||
|
|
|
@ -7,6 +7,7 @@ Accueil: Home
|
|||
Alors: Then
|
||||
Année d'activité: Years of activity
|
||||
Assimilé salarié: '"Assimilé-salarié"'
|
||||
Au-delà du dernier plafond: Beyond the last ceiling
|
||||
Au-dessus de: Above
|
||||
Aucun résultat: No result$
|
||||
Auto-entrepreneur: Auto-entrepreneur
|
||||
|
@ -62,6 +63,7 @@ Modifier: Modify
|
|||
Modifier mes réponses: Change my answers
|
||||
Mon entreprise: My company
|
||||
Mon revenu: My income
|
||||
Montant: Amount
|
||||
Montant des cotisations: Amount of contributions
|
||||
'Nom de l''entreprise ou SIREN ': Company name or SIREN code
|
||||
Non: 'No'
|
||||
|
@ -76,6 +78,7 @@ Pas en auto-entrepreneur: Not in auto-entrepreneur
|
|||
Pas implémenté: Not implemented
|
||||
Passer: Skip
|
||||
Personnalisez l'integration: Customize the integration
|
||||
Plafonds des tranches: Wafer ceilings
|
||||
Plein écran: Fullscreen
|
||||
Plus d'informations: More information (fr)
|
||||
Plusieurs associés: Several partners
|
||||
|
@ -115,6 +118,7 @@ Simulations personnalisées: Customized simulations
|
|||
Sinon: Else
|
||||
Suivant: Next
|
||||
Taux: Rate
|
||||
Taux calculé: Calculated rate
|
||||
Taux moyen: Average rate
|
||||
Total des retenues: Total withheld
|
||||
Tout effacer: Delete all
|
||||
|
|
|
@ -248,42 +248,76 @@ contrat salarié . CDD . CPF:
|
|||
titre.fr: CPF
|
||||
contrat salarié . CDD . compensation pour congés non pris:
|
||||
description.en: >-
|
||||
The employee on a fixed-term contract has the same rights for paid leave as
|
||||
the employee on a permanent contract. He acquires and takes his paid leave
|
||||
under the same conditions.
|
||||
[automatic] The employee with a fixed-term contract has the same paid
|
||||
vacation entitlements as the employee with a permanent contract. He acquires
|
||||
and takes his paid leave under the same conditions.
|
||||
|
||||
However, it is common that the employee may not take all of his or her leave
|
||||
before the end of the contract, in which case he or she will receive a
|
||||
compensatory allowance for paid leave paid by the employer.
|
||||
|
||||
It is however common that the employee can not take all his leave before the
|
||||
end of his contract. In that case, he receives a compensatory alowance paid
|
||||
by the employer.
|
||||
description.fr: >
|
||||
There are two methods of calculating the allowance for leave without pay.
|
||||
|
||||
### Tenths method
|
||||
|
||||
This method of calculation will most often be favourable to the employee
|
||||
when he or she has worked overtime. An allowance equal to one tenth of the
|
||||
total gross remuneration received by the employee during the reference
|
||||
period.
|
||||
|
||||
## Salary continuance method ##
|
||||
|
||||
This method will most often be favourable to the employee when he or she has
|
||||
received a salary increase.
|
||||
|
||||
In making the calculation, the employer may take into account either : - the
|
||||
actual time of the month, - the average number of working days (or working
|
||||
days), - the actual number of working days (or working days).
|
||||
description.fr: >-
|
||||
Le salarié en CDD bénéficie des mêmes droits à congés payés que le salarié
|
||||
en CDI. Il acquiert et prend ses congés payés dans les mêmes conditions.
|
||||
|
||||
|
||||
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 alors d'une indemnité
|
||||
compensatrice de congés payés versée par l'employeur.
|
||||
|
||||
Il existe deux méthodes pour calculer l'indemnité de congés non pris.
|
||||
|
||||
### Méthode "du dixième"
|
||||
|
||||
Ce mode de calcul sera le plus souvent favorable au salarié lorsque celui-ci
|
||||
a accompli des heures supplémentaires. Une indemnité égale au dixième de la
|
||||
rémunération brute totale perçue par le salarié au cours de la période de
|
||||
référence.
|
||||
|
||||
### Méthode "maintien du salaire"
|
||||
|
||||
Cette méthode sera le plus souvent favorable au salarié lorsque celui-ci a
|
||||
bénéficié d’une augmentation de salaire.
|
||||
|
||||
Pour effectuer le calcul, l'employeur peut tenir compte soit : - de
|
||||
l'horaire réel du mois, - du nombre moyen de jours ouvrables (ou ouvrés), -
|
||||
du nombre réel de jours ouvrables (ou ouvrés).
|
||||
note.en: >
|
||||
[automatic] The indemnity is paid at the end of the contract, unless the
|
||||
fixed-term contract is continued by a permanent contract.
|
||||
|
||||
Note that the El Khomri law modifies article L3141-12:
|
||||
|
||||
- before: Leave can be taken as soon as you become entitled....
|
||||
- before: Leave can be taken as soon as the entitlement arises.
|
||||
|
||||
- now: Leaves can be taken as soon as you are hired...
|
||||
- now: Leaves can be taken as soon as you are hired.
|
||||
note.fr: >
|
||||
L'indemnité est versée à la fin du contrat, sauf si le CDD se poursuit par
|
||||
un CDI.
|
||||
|
||||
À noter, la loi El Khomri modifie l'article L3141-12:
|
||||
|
||||
- avant : Les congés peuvent être pris dès l'ouverture des droits [...]
|
||||
- avant : Les congés peuvent être pris dès l'ouverture des droits
|
||||
|
||||
- maintenant : Les congés peuvent être pris dès l’embauche [...]
|
||||
titre.en: untaken vacation compensation
|
||||
titre.fr: compensation pour congés non pris
|
||||
- maintenant : Les congés peuvent être pris dès l’embauche
|
||||
titre.en: '[automatic] holiday pay'
|
||||
titre.fr: indemnité de congés payés
|
||||
contrat salarié . CDD . compensation pour congés non pris . assiette mensuelle:
|
||||
titre.en: monthly basis
|
||||
titre.fr: assiette mensuelle
|
||||
|
@ -3223,6 +3257,9 @@ dirigeant . indépendant . PLNR régime général:
|
|||
question.fr: Avez-vous opté pour le rattachement au régime général des indépendants ?
|
||||
titre.en: PLNR general scheme
|
||||
titre.fr: PLNR régime général
|
||||
dirigeant . indépendant . assiette des cotisations:
|
||||
titre.en: '[automatic] contribution base'
|
||||
titre.fr: assiette des cotisations
|
||||
dirigeant . indépendant . conjoint collaborateur:
|
||||
description.en: >
|
||||
[automatic] Allows the executive's spouse to be covered by social protection
|
||||
|
@ -3309,12 +3346,12 @@ dirigeant . indépendant . conjoint collaborateur . assiette . revenu avec parta
|
|||
dirigeant . indépendant . conjoint collaborateur . assiette . revenu sans partage:
|
||||
description.en: >-
|
||||
[automatic] The collaborating spouse will pay social security contributions
|
||||
calculated on the basis of a percentage of the professional income of the
|
||||
manager of the company (one third or one half).
|
||||
calculated on the basis of a percentage of the contribution base of the
|
||||
company manager (one third or one half).
|
||||
description.fr: >-
|
||||
Le conjoint collaborateur paiera des cotisations sociales calculées sur une
|
||||
base d'un pourcentage du revenu professionnel du gérant de l'entreprise (un
|
||||
tiers ou la moitié).
|
||||
base d'un pourcentage du assiette des cotisations du gérant de l'entreprise
|
||||
(un tiers ou la moitié).
|
||||
titre.en: undivided income
|
||||
titre.fr: revenu sans partage
|
||||
dirigeant . indépendant . conjoint collaborateur . cotisations:
|
||||
|
@ -3384,8 +3421,8 @@ dirigeant . indépendant . cotisations et contributions . cotisations . déducti
|
|||
titre.en: tobacco deduction
|
||||
titre.fr: déduction tabac
|
||||
dirigeant . indépendant . cotisations et contributions . cotisations . déduction tabac . revenus déduits:
|
||||
titre.en: professional income (with tobacco deduction)
|
||||
titre.fr: revenu professionnel (avec déduction tabac)
|
||||
titre.en: '[automatic] contribution base (with tobacco deduction)'
|
||||
titre.fr: assiette des cotisations (avec déduction tabac)
|
||||
dirigeant . indépendant . cotisations et contributions . cotisations . indemnités journalières maladie:
|
||||
description.en: >-
|
||||
Contributions for the daily allowances of self-employed people. If the state
|
||||
|
@ -3515,6 +3552,9 @@ dirigeant . indépendant . cotisations et contributions . cotisations . maladie
|
|||
dirigeant . indépendant . cotisations et contributions . cotisations . retraite complémentaire:
|
||||
titre.en: supplementary pension
|
||||
titre.fr: retraite complémentaire
|
||||
dirigeant . indépendant . cotisations et contributions . cotisations . retraite complémentaire . plafond:
|
||||
titre.en: '[automatic] supplementary pension ceiling for self-employed persons'
|
||||
titre.fr: plafond retraite complémentaire des indépendants
|
||||
dirigeant . indépendant . cotisations et contributions . cotisations . retraite complémentaire . taux spécifique PLNR:
|
||||
description.en: >
|
||||
Non-regulated liberal professions who started their activity as of 1 January
|
||||
|
@ -3634,36 +3674,8 @@ dirigeant . indépendant . revenu net de cotisations:
|
|||
titre.en: net contribution income
|
||||
titre.fr: revenu net de cotisations
|
||||
dirigeant . indépendant . revenu professionnel:
|
||||
description.en: >
|
||||
It is the net income of the self-employed person from deductible
|
||||
contributions that is used as the basis for calculating contributions and
|
||||
taxes for the self-employed.
|
||||
|
||||
Attention, **our calculation is valid for a standard scheme**:
|
||||
|
||||
The self-employed person who starts out will pay a fixed contributions
|
||||
during his first months. He will then have to regularize this situation in
|
||||
relation to the income he actually received.
|
||||
|
||||
This calculation should therefore be seen as *the amount that should in any
|
||||
case be paid* in the short term after several months of activity.
|
||||
description.fr: >
|
||||
C'est le revenu net de cotisations déductibles du travailleur indépendant,
|
||||
qui sert de base au calcul des cotisations et de l'impôt pour les
|
||||
indépendants.
|
||||
|
||||
|
||||
Attention, **notre calcul est fait au régime de croisière**:
|
||||
|
||||
l'indépendant qui se lance paiera pendant ses 2 premières années un forfait
|
||||
relativement réduit de cotisations sociales. Il devra ensuite régulariser
|
||||
cette situation par rapport au revenu qu'il a vraiment perçu.
|
||||
|
||||
|
||||
Il faut donc voir ce calcul comme *le montant qui devra de toute façon être
|
||||
payé* à court terme après 2 ans d'exercice.
|
||||
titre.en: Professional income
|
||||
titre.fr: revenu professionnel (net imposable)
|
||||
titre.en: '[automatic] occupational income'
|
||||
titre.fr: revenu professionnel
|
||||
dirigeant . indépendant . revenus étrangers:
|
||||
description.en: >
|
||||
[automatic] Foreign income is income declared by self-employed persons in
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
revenu imposable:
|
||||
format: euros
|
||||
unité: €
|
||||
|
||||
revenu abattu:
|
||||
formule:
|
||||
|
@ -12,25 +12,20 @@ impôt sur le revenu:
|
|||
barème:
|
||||
assiette: revenu abattu
|
||||
tranches:
|
||||
- en-dessous de: 9807
|
||||
taux: 0%
|
||||
- de: 9807
|
||||
à: 27086
|
||||
taux: 14%
|
||||
- de: 27086
|
||||
à: 72617
|
||||
taux: 30%
|
||||
- de: 72617
|
||||
à: 153783
|
||||
taux: 41%
|
||||
- au-dessus de: 153783
|
||||
taux: 45%
|
||||
|
||||
- taux: 0%
|
||||
plafond: 9807€
|
||||
- taux: 14%
|
||||
plafond: 27086€
|
||||
- taux: 30%
|
||||
plafond: 72617€
|
||||
- taux: 41%
|
||||
plafond: 153783€
|
||||
- taux: 45%
|
||||
|
||||
impôt final:
|
||||
formule:
|
||||
allègement:
|
||||
assiette: impôt sur le revenu
|
||||
décote:
|
||||
plafond: 1177
|
||||
taux: 75%
|
||||
|
||||
plafond: 1177€
|
||||
|
|
|
@ -18,8 +18,8 @@ describe('conversation', function() {
|
|||
{ nom: 'top . startHere', formule: { somme: ['a', 'b'] } },
|
||||
{ nom: 'top . a', formule: 'aa' },
|
||||
{ nom: 'top . b', formule: 'bb' },
|
||||
{ nom: 'top . aa', question: '?', titre: 'a' },
|
||||
{ nom: 'top . bb', question: '?', titre: 'b' }
|
||||
{ nom: 'top . aa', question: '?', titre: 'a', unité: '€' },
|
||||
{ nom: 'top . bb', question: '?', titre: 'b', unité: '€' }
|
||||
],
|
||||
rules = rawRules.map(enrichRule),
|
||||
state = merge(baseState, {
|
||||
|
@ -40,9 +40,9 @@ describe('conversation', function() {
|
|||
{ nom: 'top . a', formule: 'aa' },
|
||||
{ nom: 'top . b', formule: 'bb' },
|
||||
{ nom: 'top . c', formule: 'cc' },
|
||||
{ nom: 'top . aa', question: '?', titre: 'a' },
|
||||
{ nom: 'top . bb', question: '?', titre: 'b' },
|
||||
{ nom: 'top . cc', question: '?', titre: 'c' }
|
||||
{ nom: 'top . aa', question: '?', titre: 'a', unité: '€' },
|
||||
{ nom: 'top . bb', question: '?', titre: 'b', unité: '€' },
|
||||
{ nom: 'top . cc', question: '?', titre: 'c', unité: '€' }
|
||||
],
|
||||
rules = rawRules.map(enrichRule)
|
||||
|
||||
|
|
|
@ -159,9 +159,9 @@ describe('collectMissingVariables', function() {
|
|||
alors: {
|
||||
multiplicateur: 'deux',
|
||||
tranches: [
|
||||
{ 'en-dessous de': 1, taux: 0.1 },
|
||||
{ de: 1, à: 2, taux: 'trois' },
|
||||
{ 'au-dessus de': 2, taux: 10 }
|
||||
{ plafond: 1, taux: 0.1 },
|
||||
{ plafond: 2, taux: 'trois' },
|
||||
{ taux: 10 }
|
||||
]
|
||||
}
|
||||
},
|
||||
|
@ -170,8 +170,8 @@ describe('collectMissingVariables', function() {
|
|||
alors: {
|
||||
multiplicateur: 'quatre',
|
||||
tranches: [
|
||||
{ 'en-dessous de': 1, taux: 0.1 },
|
||||
{ de: 1, à: 2, taux: 1.8 },
|
||||
{ plafond: 1, taux: 0.1 },
|
||||
{ plafond: 2, taux: 1.8 },
|
||||
{ 'au-dessus de': 2, taux: 10 }
|
||||
]
|
||||
}
|
||||
|
|
|
@ -92,19 +92,15 @@ ya:
|
|||
barème:
|
||||
assiette: revenu abattu
|
||||
tranches:
|
||||
- en-dessous de: 9807
|
||||
taux: 0%
|
||||
- de: 9807
|
||||
à: 27086
|
||||
taux: 14%
|
||||
- de: 27086
|
||||
à: 72617
|
||||
taux: 30%
|
||||
- de: 72617
|
||||
à: 153783
|
||||
taux: 41%
|
||||
- au-dessus de: 153783
|
||||
taux: 45%
|
||||
- taux: 0%
|
||||
plafond: 9807
|
||||
- taux: 14%
|
||||
plafond: 27086
|
||||
- taux: 30%
|
||||
plafond: 72617
|
||||
- taux: 41%
|
||||
plafond: 153783
|
||||
- taux: 45%
|
||||
|
||||
|
||||
- nom: impôt sur le revenu à payer
|
||||
|
@ -112,8 +108,8 @@ ya:
|
|||
allègement:
|
||||
assiette: impôt sur le revenu
|
||||
décote:
|
||||
plafond: 1177
|
||||
taux: 75%
|
||||
plafond: 1177
|
||||
`
|
||||
|
||||
let target = 'impôt sur le revenu à payer'
|
||||
|
|
|
@ -6,10 +6,10 @@
|
|||
*/
|
||||
|
||||
import { expect } from 'chai'
|
||||
import { serializeUnit } from 'Engine/units'
|
||||
import { collectMissingVariables } from '../source/engine/generateQuestions'
|
||||
import { enrichRule } from '../source/engine/rules'
|
||||
import { analyse, parseAll } from '../source/engine/traverse'
|
||||
import { parseUnit } from '../source/engine/units'
|
||||
import testSuites from './load-mecanism-tests'
|
||||
|
||||
describe('Mécanismes', () =>
|
||||
|
@ -59,7 +59,7 @@ describe('Mécanismes', () =>
|
|||
|
||||
if (unit) {
|
||||
expect(target.unit).not.to.be.equal(undefined)
|
||||
expect(serializeUnit(target.unit)).to.eql(unit)
|
||||
expect(target.unit).to.deep.equal(parseUnit(unit))
|
||||
}
|
||||
})
|
||||
))
|
||||
|
|
|
@ -23,8 +23,8 @@ montant décoté:
|
|||
allègement:
|
||||
assiette: montant
|
||||
décote:
|
||||
plafond: 2040
|
||||
taux: 100%
|
||||
plafond: 2040
|
||||
exemples:
|
||||
- situation:
|
||||
montant: 1000
|
||||
|
@ -37,8 +37,8 @@ montant franchisé et décoté:
|
|||
assiette: montant
|
||||
franchise: 1200
|
||||
décote:
|
||||
plafond: 2040
|
||||
taux: 75%
|
||||
plafond: 2040
|
||||
exemples:
|
||||
- situation:
|
||||
montant: 100
|
||||
|
@ -103,8 +103,8 @@ montant franchisé, décote, abattu:
|
|||
assiette: montant
|
||||
franchise: 1200
|
||||
décote:
|
||||
plafond: 2040
|
||||
taux: 75%
|
||||
plafond: 2040
|
||||
abattement: 20507
|
||||
exemples:
|
||||
- situation:
|
||||
|
|
|
@ -1,79 +0,0 @@
|
|||
base:
|
||||
unité: £
|
||||
formule: 300
|
||||
|
||||
assiette:
|
||||
unité: £
|
||||
|
||||
Simple:
|
||||
formule:
|
||||
barème continu:
|
||||
assiette: assiette
|
||||
multiplicateur: base
|
||||
points:
|
||||
0: 0%
|
||||
0.4: 3.16%
|
||||
1.1: 6.35%
|
||||
unité attendue: £
|
||||
exemples:
|
||||
- nom: Premier point
|
||||
situation:
|
||||
assiette: 10
|
||||
valeur attendue: 0.026
|
||||
- nom: Deuxième point
|
||||
situation:
|
||||
assiette: 120
|
||||
valeur attendue: 3.792
|
||||
- nom: Premier point
|
||||
situation:
|
||||
assiette: 150
|
||||
valeur attendue: 5.423
|
||||
- nom: Troisième point
|
||||
situation:
|
||||
assiette: 330
|
||||
valeur attendue: 20.955
|
||||
- nom: Au-delà
|
||||
situation:
|
||||
assiette: 1000
|
||||
valeur attendue: 63.5
|
||||
|
||||
base deux:
|
||||
unité: µ
|
||||
formule: 300
|
||||
|
||||
assiette deux:
|
||||
unité: µ
|
||||
|
||||
Retour de taux, pas d'assiette:
|
||||
unité: '%'
|
||||
formule:
|
||||
barème continu:
|
||||
assiette: assiette deux
|
||||
multiplicateur: base deux
|
||||
points:
|
||||
0: 100%
|
||||
0.75: 100%
|
||||
1: 0%
|
||||
retourne seulement le taux: oui
|
||||
unité attendue: '%'
|
||||
exemples:
|
||||
- nom: Premier point
|
||||
situation:
|
||||
assiette deux: 200
|
||||
valeur attendue: 100
|
||||
- nom: Deuxième point
|
||||
situation:
|
||||
assiette deux: 225
|
||||
valeur attendue: 100
|
||||
- nom: Troisième point
|
||||
situation:
|
||||
assiette deux: 262.5
|
||||
valeur attendue: 50
|
||||
- nom: Quatrième point
|
||||
situation:
|
||||
assiette deux: 300
|
||||
valeur attendue: 0
|
||||
- nom: Cinquième point
|
||||
situation:
|
||||
assiette deux: 300
|
||||
valeur attendue: 0
|
|
@ -1,76 +0,0 @@
|
|||
assiette:
|
||||
unité: €
|
||||
|
||||
Barème linéaire en taux:
|
||||
formule:
|
||||
barème linéaire:
|
||||
assiette: assiette
|
||||
tranches:
|
||||
- de: 0
|
||||
à: 999
|
||||
taux: 5%
|
||||
- de: 1000
|
||||
à: 1999
|
||||
taux: 10%
|
||||
- au-dessus de: 2000
|
||||
taux: 15%
|
||||
unité attendue: €
|
||||
|
||||
exemples:
|
||||
- nom: 'petite assiette'
|
||||
situation:
|
||||
assiette: 200
|
||||
valeur attendue: 10
|
||||
- nom: 'moyenne assiette'
|
||||
situation:
|
||||
assiette: 1500
|
||||
valeur attendue: 150
|
||||
- nom: 'grande assiette'
|
||||
situation:
|
||||
assiette: 10000
|
||||
valeur attendue: 1500
|
||||
- nom: "pour choisir la tranche, l'assiette est arrondie au préalable"
|
||||
situation:
|
||||
assiette: 999.3
|
||||
valeur attendue: 49.965
|
||||
- nom: "pour choisir la tranche, l'assiette est arrondie au préalable (2)"
|
||||
situation:
|
||||
assiette: 999.6
|
||||
valeur attendue: 99.96
|
||||
|
||||
Barème linéaire en montant:
|
||||
formule:
|
||||
barème linéaire:
|
||||
assiette: assiette
|
||||
tranches:
|
||||
- de: 0
|
||||
à: 999
|
||||
montant: 50
|
||||
- de: 1000
|
||||
à: 1999
|
||||
montant: 170
|
||||
- au-dessus de: 2000
|
||||
montant: 400
|
||||
|
||||
unité attendue: €
|
||||
exemples:
|
||||
- nom: 'petite assiette'
|
||||
situation:
|
||||
assiette: 200
|
||||
valeur attendue: 50
|
||||
- nom: 'moyenne assiette'
|
||||
situation:
|
||||
assiette: 1500
|
||||
valeur attendue: 170
|
||||
- nom: 'grande assiette'
|
||||
situation:
|
||||
assiette: 10000
|
||||
valeur attendue: 400
|
||||
- nom: "pour choisir la tranche, l'assiette est arrondie au préalable"
|
||||
situation:
|
||||
assiette: 999.3
|
||||
valeur attendue: 50
|
||||
- nom: "pour choisir la tranche, l'assiette est arrondie au préalable (2)"
|
||||
situation:
|
||||
assiette: 999.6
|
||||
valeur attendue: 170
|
|
@ -1,8 +1,8 @@
|
|||
assiette:
|
||||
unité: €
|
||||
unité: €/mois
|
||||
|
||||
base:
|
||||
unité: €
|
||||
unité: €/mois
|
||||
|
||||
Barème en taux marginaux:
|
||||
formule:
|
||||
|
@ -10,14 +10,12 @@ Barème en taux marginaux:
|
|||
assiette: assiette
|
||||
multiplicateur: base
|
||||
tranches:
|
||||
- en-dessous de: 1
|
||||
taux: 4.65%
|
||||
- de: 1
|
||||
à: 3
|
||||
taux: 3%
|
||||
- au-dessus de: 3
|
||||
taux: 1%
|
||||
unité attendue: €
|
||||
- taux: 4.65%
|
||||
plafond: 1
|
||||
- taux: 3%
|
||||
plafond: 3
|
||||
- taux: 1%
|
||||
unité attendue: €/mois
|
||||
exemples:
|
||||
- nom: 'petite assiette'
|
||||
situation:
|
||||
|
@ -42,16 +40,14 @@ Barème à composantes:
|
|||
multiplicateur: base
|
||||
composantes:
|
||||
- tranches:
|
||||
- en-dessous de: 1
|
||||
taux: 2%
|
||||
- au-dessus de: 1
|
||||
taux: 0%
|
||||
- taux: 2%
|
||||
plafond: 1
|
||||
- taux: 0%
|
||||
- tranches:
|
||||
- en-dessous de: 2
|
||||
taux: 9%
|
||||
- au-dessus de: 2
|
||||
taux: 29%
|
||||
unité attendue: €
|
||||
- taux: 9%
|
||||
plafond: 2
|
||||
- taux: 29%
|
||||
unité attendue: €/mois
|
||||
|
||||
exemples:
|
||||
- nom:
|
||||
|
@ -78,11 +74,10 @@ deuxième barème:
|
|||
assiette: assiette
|
||||
multiplicateur: base
|
||||
tranches:
|
||||
- en-dessous de: 1
|
||||
taux: taux variable
|
||||
- au-dessus de: 1
|
||||
taux: 90%
|
||||
unité attendue: €
|
||||
- taux: taux variable
|
||||
plafond: 1
|
||||
- taux: 90%
|
||||
unité attendue: '€/mois'
|
||||
|
||||
exemples:
|
||||
- nom: taux faible
|
||||
|
@ -109,3 +104,37 @@ deuxième barème:
|
|||
base: 100
|
||||
variables manquantes:
|
||||
- ma condition
|
||||
|
||||
tranche 1:
|
||||
formule: 100 €/mois
|
||||
tranche 2:
|
||||
unité: €/an
|
||||
tranches variables:
|
||||
formule:
|
||||
barème:
|
||||
assiette: assiette
|
||||
tranches:
|
||||
- taux: 10%
|
||||
plafond: tranche 1
|
||||
- taux: 50%
|
||||
plafond: tranche 2
|
||||
exemples:
|
||||
- nom: tranche 2 manquante non active
|
||||
situation:
|
||||
assiette: 40
|
||||
valeur attendue: 4
|
||||
- nom: tranche 2 manquante active
|
||||
situation:
|
||||
assiette: 200
|
||||
variables manquantes:
|
||||
- tranche 2
|
||||
- nom: tranche 2 active
|
||||
situation:
|
||||
assiette: 200
|
||||
tranche 2: 12000
|
||||
valeur attendue: 60 # 10% * 100 + 50% * 100
|
||||
- nom: tranche 2 dépassée
|
||||
situation:
|
||||
assiette: 2000
|
||||
tranche 2: 12000
|
||||
valeur attendue: 460 # 10% * 100 + 50% * 900
|
||||
|
|
|
@ -1,35 +0,0 @@
|
|||
ma cotisation:
|
||||
unité: €
|
||||
|
||||
Complément:
|
||||
formule:
|
||||
complément:
|
||||
cible: ma cotisation
|
||||
montant: 100
|
||||
|
||||
exemples:
|
||||
- nom:
|
||||
situation:
|
||||
ma cotisation: 33
|
||||
valeur attendue: 67
|
||||
|
||||
autre cotisation:
|
||||
unité: €
|
||||
|
||||
Complément à composantes:
|
||||
formule:
|
||||
complément:
|
||||
composantes:
|
||||
- nom: A
|
||||
cible: ma cotisation
|
||||
montant: 100
|
||||
- nom: B
|
||||
cible: autre cotisation
|
||||
montant: 200
|
||||
|
||||
exemples:
|
||||
- nom:
|
||||
situation:
|
||||
ma cotisation: 33
|
||||
autre cotisation: 133
|
||||
valeur attendue: 134
|
|
@ -72,15 +72,13 @@ Conversion de mécanisme 1:
|
|||
unité: €/an
|
||||
formule:
|
||||
barème:
|
||||
assiette: assiette mensuelle [€/an]
|
||||
assiette: assiette mensuelle
|
||||
tranches:
|
||||
- en-dessous de: 30000
|
||||
taux: 4.65%
|
||||
- de: 30000
|
||||
à: 90000
|
||||
taux: 3%
|
||||
- au-dessus de: 90000
|
||||
taux: 1%
|
||||
- taux: 4.65%
|
||||
plafond: 30000 €/an
|
||||
- taux: 3%
|
||||
plafond: 90000 €/an
|
||||
- taux: 1%
|
||||
|
||||
exemples:
|
||||
- situation:
|
||||
|
@ -93,15 +91,13 @@ assiette annuelle:
|
|||
Conversion de mécanisme 2:
|
||||
formule:
|
||||
barème:
|
||||
assiette: assiette annuelle [€/mois]
|
||||
assiette: assiette annuelle
|
||||
tranches:
|
||||
- en-dessous de: 2500
|
||||
taux: 4.65%
|
||||
- de: 2500
|
||||
à: 7500
|
||||
taux: 3%
|
||||
- au-dessus de: 7500
|
||||
taux: 1%
|
||||
- taux: 4.65%
|
||||
plafond: 2500 €/mois
|
||||
- taux: 3%
|
||||
plafond: 7500 €/mois
|
||||
- taux: 1%
|
||||
exemples:
|
||||
- situation:
|
||||
assiette annuelle: 36000
|
||||
|
@ -126,8 +122,8 @@ retraite:
|
|||
formule:
|
||||
multiplication:
|
||||
assiette: assiette annuelle
|
||||
plafond: 12 k€/an
|
||||
taux: 10%
|
||||
plafond: 12 k€/an
|
||||
|
||||
Conversion dans une somme compliquée:
|
||||
formule:
|
||||
|
|
|
@ -98,7 +98,7 @@ nombre de personnes:
|
|||
|
||||
division trois:
|
||||
formule: salaire de base / nombre de personnes
|
||||
unité attendue: $ / personne
|
||||
unité attendue: $/personne
|
||||
exemples:
|
||||
- situation:
|
||||
salaire de base: 3000
|
||||
|
|
|
@ -0,0 +1,33 @@
|
|||
assiette:
|
||||
unité: €
|
||||
|
||||
Grille:
|
||||
formule:
|
||||
grille:
|
||||
assiette: assiette
|
||||
unité: €
|
||||
tranches:
|
||||
- montant: 50
|
||||
plafond: 1000 €
|
||||
- montant: 170
|
||||
plafond: 2000 €
|
||||
- montant: 400
|
||||
|
||||
unité attendue: €
|
||||
exemples:
|
||||
- nom: 'petite assiette'
|
||||
situation:
|
||||
assiette: 200
|
||||
valeur attendue: 50
|
||||
- nom: 'moyenne assiette'
|
||||
situation:
|
||||
assiette: 1500
|
||||
valeur attendue: 170
|
||||
- nom: 'grande assiette'
|
||||
situation:
|
||||
assiette: 10000
|
||||
valeur attendue: 400
|
||||
- nom: 'assiette limite'
|
||||
situation:
|
||||
assiette: 999.3
|
||||
valeur attendue: 50
|
|
@ -70,8 +70,8 @@ Multiplication complète:
|
|||
multiplication:
|
||||
assiette: mon assiette
|
||||
facteur: mon facteur
|
||||
plafond: mon plafond
|
||||
taux: 0.5%
|
||||
plafond: mon plafond
|
||||
|
||||
unité attendue: €.patates
|
||||
exemples:
|
||||
|
|
|
@ -0,0 +1,47 @@
|
|||
base:
|
||||
unité: £
|
||||
formule: 300
|
||||
|
||||
assiette:
|
||||
unité: £
|
||||
|
||||
base deux:
|
||||
unité: µ
|
||||
formule: 300
|
||||
|
||||
assiette deux:
|
||||
unité: µ
|
||||
|
||||
Simple:
|
||||
unité: '%'
|
||||
formule:
|
||||
taux progressif:
|
||||
assiette: assiette deux
|
||||
multiplicateur: base deux
|
||||
tranches:
|
||||
- plafond: 0.75
|
||||
taux: 100%
|
||||
- plafond: 1
|
||||
taux: 0%
|
||||
unité attendue: '%'
|
||||
exemples:
|
||||
- nom: Premier point
|
||||
situation:
|
||||
assiette deux: 200
|
||||
valeur attendue: 100
|
||||
- nom: Deuxième point
|
||||
situation:
|
||||
assiette deux: 225
|
||||
valeur attendue: 100
|
||||
- nom: Troisième point
|
||||
situation:
|
||||
assiette deux: 262.5
|
||||
valeur attendue: 50
|
||||
- nom: Quatrième point
|
||||
situation:
|
||||
assiette deux: 300
|
||||
valeur attendue: 0
|
||||
- nom: Cinquième point
|
||||
situation:
|
||||
assiette deux: 300
|
||||
valeur attendue: 0
|
|
@ -44,7 +44,7 @@ exports[`calculate simulations-auto-entrepreneur: échelle de revenus 9`] = `"[
|
|||
|
||||
exports[`calculate simulations-auto-entrepreneur: échelle de revenus 10`] = `"[1148303,148303,1000000,131979,868021]"`;
|
||||
|
||||
exports[`calculate simulations-indépendant: acre 1`] = `"[73028,23028,50000,51980,8052,41948,null,73028]"`;
|
||||
exports[`calculate simulations-indépendant: acre 1`] = `"[73024,23024,50000,51980,8052,41948,null,73024]"`;
|
||||
|
||||
exports[`calculate simulations-indépendant: activité 1`] = `"[28923,8923,20000,20783,604,19396,null,28923]"`;
|
||||
|
||||
|
@ -52,7 +52,7 @@ exports[`calculate simulations-indépendant: activité 2`] = `"[29101,9101,2000
|
|||
|
||||
exports[`calculate simulations-indépendant: impôt sur le revenu 1`] = `"[29085,9085,20000,20787,603,19397,null,29085]"`;
|
||||
|
||||
exports[`calculate simulations-indépendant: impôt sur le revenu 2`] = `"[73028,23028,50000,51980,8213,41787,null,73028]"`;
|
||||
exports[`calculate simulations-indépendant: impôt sur le revenu 2`] = `"[73024,23024,50000,51980,8213,41787,null,73024]"`;
|
||||
|
||||
exports[`calculate simulations-indépendant: impôt sur le revenu 3`] = `"[29085,9085,20000,20787,2079,17921,null,29085]"`;
|
||||
|
||||
|
@ -62,7 +62,7 @@ exports[`calculate simulations-indépendant: inversions 2`] = `"[50000,16003,33
|
|||
|
||||
exports[`calculate simulations-indépendant: inversions 3`] = `"[14596,4596,10000,10394,0,10000,null,14596]"`;
|
||||
|
||||
exports[`calculate simulations-indépendant: inversions 4`] = `"[88551,27364,61187,63588,11187,50000,null,88551]"`;
|
||||
exports[`calculate simulations-indépendant: inversions 4`] = `"[88547,27360,61187,63588,11187,50000,null,88547]"`;
|
||||
|
||||
exports[`calculate simulations-indépendant: inversions 5`] = `"[14596,4596,10000,10394,0,10000,null,15596]"`;
|
||||
|
||||
|
@ -82,9 +82,9 @@ exports[`calculate simulations-indépendant: échelle de revenus 5`] = `"[7427,
|
|||
|
||||
exports[`calculate simulations-indépendant: échelle de revenus 6`] = `"[14596,4596,10000,10394,0,10000,null,14596]"`;
|
||||
|
||||
exports[`calculate simulations-indépendant: échelle de revenus 7`] = `"[139598,39598,100000,103788,24245,75755,null,139598]"`;
|
||||
exports[`calculate simulations-indépendant: échelle de revenus 7`] = `"[139594,39594,100000,103788,24245,75755,null,139594]"`;
|
||||
|
||||
exports[`calculate simulations-indépendant: échelle de revenus 8`] = `"[1239743,239743,1000000,1033661,467503,532497,null,1239743]"`;
|
||||
exports[`calculate simulations-indépendant: échelle de revenus 8`] = `"[1239955,239955,1000000,1033666,467505,532495,null,1239955]"`;
|
||||
|
||||
exports[`calculate simulations-rémunération-dirigeant: Assimilé salarié - ACRE 1`] = `"[7257,7257,7184,4,13,16]"`;
|
||||
|
||||
|
@ -186,7 +186,7 @@ exports[`calculate simulations-rémunération-dirigeant: Indépendant - échell
|
|||
|
||||
exports[`calculate simulations-rémunération-dirigeant: Indépendant - échelle de rémunération 6`] = `"[30434,33997,24912,4,48,0]"`;
|
||||
|
||||
exports[`calculate simulations-rémunération-dirigeant: Indépendant - échelle de rémunération 7`] = `"[56271,69892,36442,4,56,0]"`;
|
||||
exports[`calculate simulations-rémunération-dirigeant: Indépendant - échelle de rémunération 7`] = `"[56273,69895,36431,4,56,0]"`;
|
||||
|
||||
exports[`calculate simulations-salarié: JEI 1`] = `"[3440,0,0,3000,2353,2187]"`;
|
||||
|
||||
|
|
|
@ -15,15 +15,13 @@ répartition salaire sur dividendes:
|
|||
impôt sur les sociétés:
|
||||
formule:
|
||||
barème:
|
||||
assiette: bénéfice [€/an]
|
||||
assiette: bénéfice
|
||||
tranches:
|
||||
- en-dessous de: 38120
|
||||
taux: 15%
|
||||
- de: 38120
|
||||
à: 500000
|
||||
taux: 28%
|
||||
- au-dessus de: 500000
|
||||
taux: 33.3%
|
||||
- taux: 15%
|
||||
plafond: 38120 €/an
|
||||
- taux: 28%
|
||||
plafond: 500000 €/an
|
||||
- taux: 33.3%
|
||||
références:
|
||||
fiche service-public.fr: https://www.service-public.fr/professionnels-entreprises/vosdroits/F23575
|
||||
|
||||
|
|
|
@ -196,9 +196,9 @@ describe('analyse with mecanisms', function() {
|
|||
assiette: 2008,
|
||||
multiplicateur: 1000,
|
||||
tranches: [
|
||||
{ 'en-dessous de': 1, taux: 0.1 },
|
||||
{ de: 1, à: 2, taux: 1.2 },
|
||||
{ 'au-dessus de': 2, taux: 10 }
|
||||
{ plafond: 1, taux: 0.1 },
|
||||
{ plafond: 2, taux: 1.2 },
|
||||
{ taux: 10 }
|
||||
]
|
||||
}
|
||||
}
|
||||
|
@ -221,16 +221,16 @@ describe('analyse with mecanisms', function() {
|
|||
composantes: [
|
||||
{
|
||||
tranches: [
|
||||
{ 'en-dessous de': 1, taux: 0.05 },
|
||||
{ de: 1, à: 2, taux: 0.4 },
|
||||
{ 'au-dessus de': 2, taux: 5 }
|
||||
{ plafond: 1, taux: 0.05 },
|
||||
{ plafond: 2, taux: 0.4 },
|
||||
{ taux: 5 }
|
||||
]
|
||||
},
|
||||
{
|
||||
tranches: [
|
||||
{ 'en-dessous de': 1, taux: 0.05 },
|
||||
{ de: 1, à: 2, taux: 0.8 },
|
||||
{ 'au-dessus de': 2, taux: 5 }
|
||||
{ plafond: 1, taux: 0.05 },
|
||||
{ plafond: 2, taux: 0.8 },
|
||||
{ taux: 5 }
|
||||
]
|
||||
}
|
||||
]
|
||||
|
@ -257,9 +257,9 @@ describe('analyse with mecanisms', function() {
|
|||
si: '3 > 4',
|
||||
alors: {
|
||||
tranches: [
|
||||
{ 'en-dessous de': 1, taux: 0.1 },
|
||||
{ de: 1, à: 2, taux: 1.2 },
|
||||
{ 'au-dessus de': 2, taux: 10 }
|
||||
{ plafond: 1, taux: 0.1 },
|
||||
{ plafond: 2, taux: 1.2 },
|
||||
{ taux: 10 }
|
||||
]
|
||||
}
|
||||
},
|
||||
|
@ -267,9 +267,9 @@ describe('analyse with mecanisms', function() {
|
|||
si: '3 > 2',
|
||||
alors: {
|
||||
tranches: [
|
||||
{ 'en-dessous de': 1, taux: 0.1 },
|
||||
{ de: 1, à: 2, taux: 1.8 },
|
||||
{ 'au-dessus de': 2, taux: 10 }
|
||||
{ plafond: 1, taux: 0.1 },
|
||||
{ plafond: 2, taux: 1.8 },
|
||||
{ taux: 10 }
|
||||
]
|
||||
}
|
||||
}
|
||||
|
@ -294,41 +294,6 @@ describe('analyse with mecanisms', function() {
|
|||
).to.have.property('nodeValue', 3200)
|
||||
})
|
||||
|
||||
it('should handle complements', function() {
|
||||
let rawRules = [
|
||||
{ nom: 'top' },
|
||||
{
|
||||
nom: 'top . startHere',
|
||||
formule: { complément: { cible: 'dix', montant: 93 } }
|
||||
},
|
||||
{ nom: 'top . dix', formule: 17 }
|
||||
],
|
||||
rules = parseAll(rawRules.map(enrichRule))
|
||||
expect(
|
||||
analyse(rules, 'startHere')(stateSelector).targets[0]
|
||||
).to.have.property('nodeValue', 93 - 17)
|
||||
})
|
||||
|
||||
it('should handle components in complements', function() {
|
||||
let rawRules = [
|
||||
{ nom: 'top' },
|
||||
{
|
||||
nom: 'top . startHere',
|
||||
formule: {
|
||||
complément: {
|
||||
cible: 'dix',
|
||||
composantes: [{ montant: 93 }, { montant: 93 }]
|
||||
}
|
||||
}
|
||||
},
|
||||
{ nom: 'top . dix', formule: 17 }
|
||||
],
|
||||
rules = parseAll(rawRules.map(enrichRule))
|
||||
expect(
|
||||
analyse(rules, 'startHere')(stateSelector).targets[0]
|
||||
).to.have.property('nodeValue', 2 * (93 - 17))
|
||||
})
|
||||
|
||||
it('should handle filtering on components', function() {
|
||||
let rawRules = [
|
||||
{ nom: 'top' },
|
||||
|
@ -342,17 +307,17 @@ describe('analyse with mecanisms', function() {
|
|||
composantes: [
|
||||
{
|
||||
tranches: [
|
||||
{ 'en-dessous de': 1, taux: 0.05 },
|
||||
{ de: 1, à: 2, taux: 0.4 },
|
||||
{ 'au-dessus de': 2, taux: 5 }
|
||||
{ plafond: 1, taux: 0.05 },
|
||||
{ plafond: 2, taux: 0.4 },
|
||||
{ taux: 5 }
|
||||
],
|
||||
attributs: { 'dû par': 'salarié' }
|
||||
},
|
||||
{
|
||||
tranches: [
|
||||
{ 'en-dessous de': 1, taux: 0.05 },
|
||||
{ de: 1, à: 2, taux: 0.8 },
|
||||
{ 'au-dessus de': 2, taux: 5 }
|
||||
{ plafond: 1, taux: 0.05 },
|
||||
{ plafond: 2, taux: 0.8 },
|
||||
{ taux: 5 }
|
||||
],
|
||||
attributs: { 'dû par': 'employeur' }
|
||||
}
|
||||
|
@ -384,17 +349,17 @@ describe('analyse with mecanisms', function() {
|
|||
composantes: [
|
||||
{
|
||||
tranches: [
|
||||
{ 'en-dessous de': 1, taux: 0.05 },
|
||||
{ de: 1, à: 2, taux: 0.4 },
|
||||
{ 'au-dessus de': 2, taux: 5 }
|
||||
{ plafond: 1, taux: 0.05 },
|
||||
{ plafond: 2, taux: 0.4 },
|
||||
{ taux: 5 }
|
||||
],
|
||||
attributs: { 'dû par': 'salarié' }
|
||||
},
|
||||
{
|
||||
tranches: [
|
||||
{ 'en-dessous de': 1, taux: 0.05 },
|
||||
{ de: 1, à: 2, taux: 0.8 },
|
||||
{ 'au-dessus de': 2, taux: 5 }
|
||||
{ plafond: 1, taux: 0.05 },
|
||||
{ plafond: 2, taux: 0.8 },
|
||||
{ taux: 5 }
|
||||
],
|
||||
attributs: { 'dû par': 'employeur' }
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue