diff --git a/modele-social/règles/artiste-auteur.yaml b/modele-social/règles/artiste-auteur.yaml index b6e08798d..991d8e029 100644 --- a/modele-social/règles/artiste-auteur.yaml +++ b/modele-social/règles/artiste-auteur.yaml @@ -12,13 +12,12 @@ artiste-auteur . revenus . traitements et salaires: artiste-auteur . revenus . BNC: unité: €/an formule: - allègement: - assiette: recettes - abattement: - variations: - - si: micro-bnc - alors: charges forfaitaires - - sinon: frais réels + valeur: recettes + abattement: + variations: + - si: micro-bnc + alors: charges forfaitaires + - sinon: frais réels artiste-auteur . revenus . BNC . micro-bnc: non applicable si: contrôle micro-bnc diff --git a/modele-social/règles/conventions-collectives/sport.yaml b/modele-social/règles/conventions-collectives/sport.yaml index 2523243d3..f9f193a82 100644 --- a/modele-social/règles/conventions-collectives/sport.yaml +++ b/modele-social/règles/conventions-collectives/sport.yaml @@ -161,9 +161,8 @@ contrat salarié . convention collective . sport . cotisations . formation profe contrat salarié . convention collective . sport . cotisations . assiette franchisée: formule: - allègement: - assiette: cotisations . assiette - abattement: franchise + valeur: cotisations . assiette + abattement: franchise contrat salarié . convention collective . sport . joueur entraineur: question: Le joueur est-il aussi entraineur ? diff --git a/modele-social/règles/dirigeant.yaml b/modele-social/règles/dirigeant.yaml index 83f68b866..ca581e8a7 100644 --- a/modele-social/règles/dirigeant.yaml +++ b/modele-social/règles/dirigeant.yaml @@ -378,9 +378,8 @@ dirigeant . auto-entrepreneur . impôt . revenu imposable: dirigeant . auto-entrepreneur . impôt . revenu abattu: titre: revenu abattu auto-entrepreneur formule: - allègement: - assiette: base des cotisations - abattement: abattement + valeur: base des cotisations + abattement: abattement dirigeant . auto-entrepreneur . net après impôt: titre: revenu net après impôt @@ -829,9 +828,8 @@ dirigeant . indépendant . cotisations et contributions . déduction tabac . rev - invalidité et décès - conjoint collaborateur formule: - allègement: - assiette: assiette des cotisations - abattement: déduction tabac + valeur: assiette des cotisations + abattement: déduction tabac dirigeant . indépendant . contrats madelin: titre: Contrats Madelin @@ -1108,15 +1106,14 @@ dirigeant . indépendant . cotisations et contributions . CSG et CRDS . assiette puisque la partie non imposable a déjà été retranchée du revenu net fiscal fourni formule: - allègement: - assiette: - somme: - - revenu professionnel - - cotisations - abattement: - somme: - - revenus étrangers . montant - - dirigeant . indépendant . IJSS . imposable + valeur: + somme: + - revenu professionnel + - cotisations + abattement: + somme: + - revenus étrangers . montant + - dirigeant . indépendant . IJSS . imposable dirigeant . indépendant . cotisations et contributions . formation professionnelle: produit: diff --git a/modele-social/règles/déclaration-revenu-indépendant.yaml b/modele-social/règles/déclaration-revenu-indépendant.yaml index cb895050a..30aa1c19e 100644 --- a/modele-social/règles/déclaration-revenu-indépendant.yaml +++ b/modele-social/règles/déclaration-revenu-indépendant.yaml @@ -158,6 +158,5 @@ aide déclaration revenu indépendant 2019 . assiette sociale: titre: assiette sociale résumé: 'pour information [A - (B + C + D)]' formule: - allègement: - assiette: revenu net fiscal - abattement: total charges sociales déductible + valeur: revenu net fiscal + abattement: total charges sociales déductible diff --git a/modele-social/règles/entreprise-établissement.yaml b/modele-social/règles/entreprise-établissement.yaml index 91f77fd43..760d9d5e4 100644 --- a/modele-social/règles/entreprise-établissement.yaml +++ b/modele-social/règles/entreprise-établissement.yaml @@ -257,9 +257,8 @@ entreprise . impôt sur les sociétés . contribution sociale: produit: taux: 3.3% assiette: - allègement: - assiette: impôt sur les sociétés - abattement: 763000 €/an * prorata temporis + valeur: impôt sur les sociétés + abattement: 763000 €/an * prorata temporis références: Bofip: https://bofip.impots.gouv.fr/bofip/3492-PGP.html/identifiant%3DBOI-IS-AUT-10-20-20130318 @@ -469,9 +468,8 @@ entreprise . non assujettie à TVA: entreprise . taxe sur les salaires . montant avant décote: formule: - allègement: - assiette: contrat salarié . taxe sur les salaires . barème / 1 employé * effectif - abattement: abattement associations + valeur: contrat salarié . taxe sur les salaires . barème / 1 employé * effectif + abattement: abattement associations entreprise . taxe sur les salaires . abattement associations: applicable si: entreprise . association non lucrative diff --git a/modele-social/règles/impôt.yaml b/modele-social/règles/impôt.yaml index 909297f40..46bc0c17b 100644 --- a/modele-social/règles/impôt.yaml +++ b/modele-social/règles/impôt.yaml @@ -69,13 +69,12 @@ impôt . revenu imposable: description: | C'est le revenu à prendre en compte pour calculer l'impôt avec un taux moyen d'imposition (neutre ou personnalisé). formule: - allègement: - assiette: - somme: - - contrat salarié . rémunération . net imposable - - dirigeant . indépendant . résultat fiscal - - dirigeant . auto-entrepreneur . impôt . revenu imposable - abattement: abattement contrat court + valeur: + somme: + - contrat salarié . rémunération . net imposable + - dirigeant . indépendant . résultat fiscal + - dirigeant . auto-entrepreneur . impôt . revenu imposable + abattement: abattement contrat court impôt . revenu imposable . abattement contrat court: description: Lorsque la durée d'un contrat de travail est inférieure à 2 mois, il est possible d'appliquer un abattement pour diminuer le montant du prélèvement à la source. @@ -375,21 +374,20 @@ impôt . foyer fiscal . revenu imposable: impôt . foyer fiscal . revenu imposable . revenu d'activité abattu: description: Dans le cas général, l'impôt est calculé après l'application d'un abattement forfaitaire fixe. Chacun peut néanmoins opter pour la déclaration de ses *frais réels*, qui viendront remplacer ce forfait par défaut. formule: - allègement: - assiette [ref]: - somme: - - contrat salarié . rémunération . net imposable - - valeur: dirigeant . indépendant . résultat fiscal - applicable si: entreprise . imposition . IS - abattement: - valeur: 10% * assiette - # A VÉRIFIER: calculé à la main en revalorisant le taux 2020 - # HISTORIQUE 2020: 12627€ - # 12627€ × (1 + 0,2%) - plafond: 12652 €/an - # HISTORIQUE 2020: 441€ - # 441€ × (1 + 0,2%) - plancher: 442 €/an + valeur [ref assiette]: + somme: + - contrat salarié . rémunération . net imposable + - valeur: dirigeant . indépendant . résultat fiscal + applicable si: entreprise . imposition . IS + abattement: + valeur: 10% * assiette + # A VÉRIFIER: calculé à la main en revalorisant le taux 2020 + # HISTORIQUE 2020: 12627€ + # 12627€ × (1 + 0,2%) + plafond: 12652 €/an + # HISTORIQUE 2020: 441€ + # 441€ × (1 + 0,2%) + plancher: 442 €/an références: Frais professionnels - forfait ou frais réels: https://www.service-public.fr/particuliers/vosdroits/F1989 @@ -418,9 +416,8 @@ impôt . foyer fiscal . impôt à payer: impôt . foyer fiscal . impôt sur le revenu: unité: €/an formule: - allègement: - assiette: impôt brut - abattement: décote + valeur: impôt brut + abattement: décote exemples: - nom: Salaire d'un cadre situation: diff --git a/modele-social/règles/profession-libérale.yaml b/modele-social/règles/profession-libérale.yaml index f0a8743f9..9b0a053c7 100644 --- a/modele-social/règles/profession-libérale.yaml +++ b/modele-social/règles/profession-libérale.yaml @@ -540,9 +540,8 @@ dirigeant . indépendant . PL . PAMC . allocations familiales: règle: cotisations et contributions . allocations familiales sauf dans: participation CPAM formule: - allègement: - assiette: cotisations et contributions . allocations familiales - abattement: participation CPAM + valeur: cotisations et contributions . allocations familiales + abattement: participation CPAM références: Fiche Urssaf: https://www.urssaf.fr/portail/home/taux-et-baremes/taux-de-cotisations/les-praticiens-et-auxiliaires-me/taux-de-cotisations-medecin-sect.html @@ -728,9 +727,8 @@ dirigeant . indépendant . PL . CARMF . retraite CNAVPL: Pour compenser la hausse de la CSG, les médecins de secteur 1 bénéficient d'une participation de l'assurance maladie (avenant n°5 de la convention médicale) au financement de leurs cotisations du régime de base. remplace: cotisations et contributions . retraite de base formule: - allègement: - assiette: PL . retraite CNAVPL - abattement: participation CPAM + valeur: PL . retraite CNAVPL + abattement: participation CPAM références: Avenant 5 à la convention médical: https://www.ameli.fr/sites/default/files/Documents/434342/document/avis_relatif_a_lavenant_ndeg_5_a_la_convention_nationale_organisant_les_rapports_entre_les_medecins_liberaux_et_lassurance_maladie.pdf @@ -821,15 +819,14 @@ dirigeant . indépendant . PL . CARMF . ASV: par les Caisses maladie. non applicable si: métier . secteur médecin = 'non conventionné' formule: - allègement: - assiette [ref]: - somme: - - 5253 €/an - - produit: - assiette: PAMC . revenus activité conventionnée - plafond: 5 * plafond sécurité sociale temps plein - taux: 3.80% - abattement: participation CPAM + valeur [ref assiette]: + somme: + - 5253 €/an + - produit: + assiette: PAMC . revenus activité conventionnée + plafond: 5 * plafond sécurité sociale temps plein + taux: 3.80% + abattement: participation CPAM arrondi: oui références: Taux 2020: http://www.carmf.fr/page.php?page=chiffrescles/stats/2020/taux2020.htm @@ -1031,9 +1028,8 @@ dirigeant . indépendant . PL . CARCDSF . sage-femme . PCV: (CPAM). formule: - allègement: - assiette: 780 €/an - abattement [ref participation CPAM]: 520 €/an + valeur: 780 €/an + abattement [ref participation CPAM]: 520 €/an références: Site CARCDSF: http://www.carcdsf.fr/cotisations-du-praticien/montant-des-cotisations note: | diff --git a/modele-social/règles/salarié.yaml b/modele-social/règles/salarié.yaml index 48eb974f4..a989dafba 100644 --- a/modele-social/règles/salarié.yaml +++ b/modele-social/règles/salarié.yaml @@ -299,13 +299,12 @@ contrat salarié . activité partielle . indemnités . complémentaire: # La condition suivante assure que cette règle ne crée pas de boucle avec indemnités . conventionnelle . part soumise à cotisation non applicable si: rémunération . brut de base > 3.15 * SMIC formule: - allègement: - assiette: rémunération mensuelle minimale - abattement: - somme: - - rémunération . net de cotisations - - indemnités . base - - indemnités . conventionnelle + valeur: rémunération mensuelle minimale + abattement: + somme: + - rémunération . net de cotisations + - indemnités . base + - indemnités . conventionnelle contrat salarié . activité partielle . indemnités . conventionnelle: applicable si: convention syntec @@ -432,9 +431,9 @@ contrat salarié . déduction forfaitaire spécifique: # pour les journalistes. Nécessite probablement de faire un re-remplacement # inverse. formule: - allègement: - assiette: cotisations . assiette - abattement: taux + valeur: cotisations . assiette + abattement: + valeur: taux * cotisations . assiette plafond: 7600 €/an plancher: cotisations . assiette minimale références: @@ -1154,23 +1153,22 @@ contrat salarié . cotisations . assiette: références: Fiche Urssaf: https://www.urssaf.fr/portail/home/employeur/calculer-les-cotisations/la-base-de-calcul.html formule: - allègement: - assiette: rémunération . brut - abattement: - somme: - - frais professionnels . part déductible - - stage . gratification minimale - # TODO: La prévoyance et la retraite supplémentaire ne sont pour - # l'instant pas exposées sur les simulateurs. Je les désactive ici pour - # résoudre un problème de cycle avec la déduction forfaitaire - # spécifique. - # - # Il faudra soit supprimer complètement ces règles prévoyance / - # retraite supplémentaire (que j'avais ajoutées dans le cadre du POC - # Paie), soit les exposer dans un simulateur. - # - # - prévoyance . part déductible - # - retraite supplémentaire . part déductible + valeur: rémunération . brut + abattement: + somme: + - frais professionnels . part déductible + - stage . gratification minimale + # TODO: La prévoyance et la retraite supplémentaire ne sont pour + # l'instant pas exposées sur les simulateurs. Je les désactive ici pour + # résoudre un problème de cycle avec la déduction forfaitaire + # spécifique. + # + # Il faudra soit supprimer complètement ces règles prévoyance / + # retraite supplémentaire (que j'avais ajoutées dans le cadre du POC + # Paie), soit les exposer dans un simulateur. + # + # - prévoyance . part déductible + # - retraite supplémentaire . part déductible contrat salarié . cotisations . assiette . salariale: titre: Assiette des cotisations sociales @@ -1182,9 +1180,8 @@ contrat salarié . cotisations . assiette . salariale: variations: - si: apprentissage alors: - allègement: - assiette: cotisations . assiette - abattement: 79% * SMIC + valeur: cotisations . assiette + abattement: 79% * SMIC - sinon: cotisations . assiette contrat salarié . cotisations . assiette minimale: @@ -1383,19 +1380,18 @@ contrat salarié . rémunération . brut: # et de retraite complémentaire on ne ré-intègre ici que la part employeur # (car la part salarié est déjà comptabilisé dans `rémunération . brut de # base` dont elle vient en déduction). - allègement: - assiette: - somme: - - rémunération . brut de base - - avantages en nature . montant - - primes - - CDD . indemnités salarié - - heures supplémentaires - - heures complémentaires - - frais professionnels - - prévoyance . employeur - - retraite supplémentaire . employeur - abattement: activité partielle . retrait absence + valeur: + somme: + - rémunération . brut de base + - avantages en nature . montant + - primes + - CDD . indemnités salarié + - heures supplémentaires + - heures complémentaires + - frais professionnels + - prévoyance . employeur + - retraite supplémentaire . employeur + abattement: activité partielle . retrait absence contrat salarié . rémunération . heures supplémentaires: titre: rémunération heures supplémentaires @@ -2494,9 +2490,8 @@ contrat salarié . retraite supplémentaire: contrat salarié . retraite supplémentaire . part déductible: formule: - allègement: - assiette: retraite supplémentaire . employeur - abattement: plafond d'exonération sociale employeur + valeur: retraite supplémentaire . employeur + abattement: plafond d'exonération sociale employeur contrat salarié . retraite supplémentaire . plafond d'exonération sociale employeur: formule: @@ -3071,9 +3066,8 @@ contrat salarié . prévoyance: contrat salarié . prévoyance . part déductible: formule: - allègement: - assiette: prévoyance . employeur - abattement: plafond exonération sociale employeur + valeur: prévoyance . employeur + abattement: plafond exonération sociale employeur contrat salarié . prévoyance . plafond exonération sociale employeur: formule: @@ -3141,13 +3135,12 @@ contrat salarié . taxe d'apprentissage . assiette: variations: - si: apprentissage alors: - allègement: - assiette: cotisations . assiette - abattement: - variations: - - si: établissement . localisation . outre-mer - alors: 20% * SMIC - - sinon: 11% * SMIC + valeur: cotisations . assiette + abattement: + variations: + - si: établissement . localisation . outre-mer + alors: 20% * SMIC + - sinon: 11% * SMIC - sinon: cotisations . assiette contrat salarié . taxe d'apprentissage . base: @@ -3213,9 +3206,8 @@ contrat salarié . taxe sur les salaires . assiette de base: contrat salarié . taxe sur les salaires . assiette: formule: - allègement: - assiette: assiette de base - abattement: prime d'impatriation + valeur: assiette de base + abattement: prime d'impatriation références: bofig: http://bofip.impots.gouv.fr/bofip/6691-PGP.html impots.gouv.fr: https://www.impots.gouv.fr/portail/international-particulier/le-regime-des-impatries @@ -3288,9 +3280,8 @@ contrat salarié . profession spécifique . journaliste . abattement fiscal: remplace: rémunération . net imposable titre: net imposable journaliste formule: - allègement: - assiette: rémunération . net imposable - abattement: 7650€/an + valeur: rémunération . net imposable + abattement: 7650€/an contrat salarié . profession spécifique . ouvrier du bâtiment: icônes: 👷‍♂️ diff --git a/mon-entreprise/test/regressions/__snapshots__/simulations.jest.js.snap b/mon-entreprise/test/regressions/__snapshots__/simulations.jest.js.snap index 39d810180..38ac4f8f2 100644 --- a/mon-entreprise/test/regressions/__snapshots__/simulations.jest.js.snap +++ b/mon-entreprise/test/regressions/__snapshots__/simulations.jest.js.snap @@ -351,7 +351,7 @@ exports[`calculate simulations-rémunération-dirigeant (assimilé salarié): av exports[`calculate simulations-rémunération-dirigeant (assimilé salarié): avec charges 2`] = `"[917,0,0,10757,4,20]"`; -exports[`calculate simulations-rémunération-dirigeant (assimilé salarié): échelle de rémunération 1`] = `"[0,0,0,0,0,0]"`; +exports[`calculate simulations-rémunération-dirigeant (assimilé salarié): échelle de rémunération 1`] = `"[-22,0,0,0,0,0]"`; exports[`calculate simulations-rémunération-dirigeant (assimilé salarié): échelle de rémunération 2`] = `"[14,0,0,140,0,1]"`; diff --git a/publicodes/core/source/AST/index.ts b/publicodes/core/source/AST/index.ts index bb6ca5484..65a1d9736 100644 --- a/publicodes/core/source/AST/index.ts +++ b/publicodes/core/source/AST/index.ts @@ -128,8 +128,8 @@ const traverseASTNode: TraverseFunction = (fn, node) => { return traverseProductNode(fn, node) case 'recalcul': return traverseRecalculNode(fn, node) - case 'allègement': - return traverseReductionNode(fn, node) + case 'abattement': + return traverseAbattementNode(fn, node) case 'nom dans la situation': return traverseSituationNode(fn, node) case 'synchronisation': @@ -290,12 +290,11 @@ const traverseRecalculNode: TraverseFunction<'recalcul'> = (fn, node) => ({ }, }) -const traverseReductionNode: TraverseFunction<'allègement'> = (fn, node) => ({ +const traverseAbattementNode: TraverseFunction<'abattement'> = (fn, node) => ({ ...node, explanation: { assiette: fn(node.explanation.assiette), abattement: fn(node.explanation.abattement), - plafond: fn(node.explanation.plafond), }, }) diff --git a/publicodes/core/source/AST/types.ts b/publicodes/core/source/AST/types.ts index c1c99bc3f..5cfa47b27 100644 --- a/publicodes/core/source/AST/types.ts +++ b/publicodes/core/source/AST/types.ts @@ -1,3 +1,4 @@ +import { AbattementNode } from '../mecanisms/abattement' import { ApplicableSiNode } from '../mecanisms/applicable' import { ArrondiNode } from '../mecanisms/arrondi' import { OperationNode } from '../mecanisms/operation' @@ -17,7 +18,6 @@ import { ParDéfautNode } from '../mecanisms/parDéfaut' import { PlancherNode } from '../mecanisms/plancher' import { ProductNode } from '../mecanisms/product' import { RecalculNode } from '../mecanisms/recalcul' -import { ReductionNode } from '../mecanisms/reduction' import { PossibilityNode } from '../mecanisms/one-possibility' import { SituationNode } from '../mecanisms/situation' import { SommeNode } from '../mecanisms/sum' @@ -38,6 +38,7 @@ export type ConstantNode = { export type ASTNode = ( | RuleNode | ReferenceNode + | AbattementNode | ApplicableSiNode | ArrondiNode | BarèmeNode @@ -56,7 +57,6 @@ export type ASTNode = ( | PlancherNode | ProductNode | RecalculNode - | ReductionNode | SituationNode | SommeNode | SynchronisationNode diff --git a/publicodes/core/source/mecanisms/abattement.ts b/publicodes/core/source/mecanisms/abattement.ts new file mode 100644 index 000000000..aefef264a --- /dev/null +++ b/publicodes/core/source/mecanisms/abattement.ts @@ -0,0 +1,72 @@ +import { EvaluationFunction, serializeUnit } from '..' +import { ASTNode } from '../AST/types' +import { warning } from '../error' +import { mergeAllMissing } from '../evaluation' +import { registerEvaluationFunction } from '../evaluationFunctions' +import { convertNodeToUnit } from '../nodeUnits' +import parse from '../parse' +import { Context } from '../parsePublicodes' + +export type AbattementNode = { + explanation: { + assiette: ASTNode + abattement: ASTNode + } + nodeKind: 'abattement' +} + +const evaluateAbattement: EvaluationFunction<'abattement'> = function (node) { + const assiette = this.evaluate(node.explanation.assiette) + let abattement = this.evaluate(node.explanation.abattement) + const percentageAbattement = serializeUnit(abattement.unit) === '%' + if (assiette.unit && !percentageAbattement) { + try { + abattement = convertNodeToUnit(assiette.unit, abattement) + } catch (e) { + warning( + this.options.logger, + this.cache._meta.ruleStack[0], + "Impossible de convertir les unités de l'allègement entre elles", + e + ) + } + } + + const assietteValue = assiette.nodeValue as number + const abattementValue = abattement.nodeValue as number | null + const nodeValue = abattement + ? abattementValue == null + ? assietteValue === 0 + ? 0 + : null + : serializeUnit(abattement.unit) === '%' + ? Math.max(0, assietteValue - (abattementValue / 100) * assietteValue) + : Math.max(0, assietteValue - abattementValue) + : assietteValue + + return { + ...node, + nodeValue, + unit: assiette.unit, + missingVariables: mergeAllMissing([assiette, abattement]), + explanation: { + assiette, + abattement, + }, + } +} + +export default function parseAbattement(v, context: Context) { + const explanation = { + assiette: parse(v.valeur, context), + abattement: parse(v.abattement, context), + } + return { + explanation, + nodeKind: parseAbattement.nom, + } +} + +parseAbattement.nom = 'abattement' as const + +registerEvaluationFunction(parseAbattement.nom, evaluateAbattement) diff --git a/publicodes/core/source/mecanisms/reduction.ts b/publicodes/core/source/mecanisms/reduction.ts deleted file mode 100644 index b12fd5018..000000000 --- a/publicodes/core/source/mecanisms/reduction.ts +++ /dev/null @@ -1,83 +0,0 @@ -import { ASTNode } from '../AST/types' -import { warning } from '../error' -import { defaultNode, evaluateObject, parseObject } from '../evaluation' -import { registerEvaluationFunction } from '../evaluationFunctions' -import { convertNodeToUnit } from '../nodeUnits' -import { serializeUnit } from '../units' - -export type ReductionNode = { - explanation: { - assiette: ASTNode - abattement: ASTNode - plafond: ASTNode - } - nodeKind: 'allègement' -} - -const objectShape = { - assiette: false, - abattement: defaultNode(0), - plafond: defaultNode(Infinity), -} - -const evaluate = evaluateObject<'allègement'>(function ({ - assiette, - abattement, - plafond, -}) { - const assietteValue = assiette.nodeValue - if (assietteValue == null) return { nodeValue: null } - if (assiette.unit) { - try { - plafond = convertNodeToUnit(assiette.unit, plafond) - if (serializeUnit(abattement.unit) !== '%') { - abattement = convertNodeToUnit(assiette.unit, abattement) - } - } catch (e) { - warning( - this.options.logger, - this.cache._meta.ruleStack[0], - "Impossible de convertir les unités de l'allègement entre elles", - e - ) - } - } - const nodeValue = abattement - ? abattement.nodeValue == null - ? assietteValue === 0 - ? 0 - : null - : serializeUnit(abattement.unit) === '%' - ? Math.max( - 0, - assietteValue - - Math.min( - plafond.nodeValue, - (abattement.nodeValue / 100) * assietteValue - ) - ) - : Math.max( - 0, - assietteValue - Math.min(plafond.nodeValue, abattement.nodeValue) - ) - : assietteValue - return { - nodeValue, - ...('unit' in assiette && { unit: assiette.unit }), - explanation: { - plafond, - abattement, - }, - } -}) - -export const mecanismReduction = (v, context) => { - const explanation = parseObject(objectShape, v, context) - - return { - explanation, - nodeKind: 'allègement', - } as ReductionNode -} - -registerEvaluationFunction('allègement', evaluate) diff --git a/publicodes/core/source/parse.ts b/publicodes/core/source/parse.ts index 7a22964f3..16d6a3818 100644 --- a/publicodes/core/source/parse.ts +++ b/publicodes/core/source/parse.ts @@ -2,6 +2,7 @@ import { Grammar, Parser } from 'nearley' import { ASTNode } from './AST/types' import { EngineError, syntaxError } from './error' import grammar from './grammar.ne' +import abattement from './mecanisms/abattement' import applicable from './mecanisms/applicable' import arrondi from './mecanisms/arrondi' import barème from './mecanisms/barème' @@ -21,7 +22,6 @@ import plafond from './mecanisms/plafond' import plancher from './mecanisms/plancher' import { mecanismProduct } from './mecanisms/product' import { mecanismRecalcul } from './mecanisms/recalcul' -import { mecanismReduction } from './mecanisms/reduction' import situation from './mecanisms/situation' import { mecanismSum } from './mecanisms/sum' import { mecanismSynchronisation } from './mecanisms/synchronisation' @@ -155,6 +155,7 @@ const chainableMecanisms = [ unité, plancher, plafond, + abattement, situation, ] function parseChainedMecanisms(rawNode, context: Context): ASTNode { @@ -193,7 +194,6 @@ const parseFunctions = { durée, 'le maximum de': mecanismMax, 'le minimum de': mecanismMin, - allègement: mecanismReduction, variations, synchronisation: mecanismSynchronisation, valeur: parse, diff --git a/publicodes/core/test/library.test.js b/publicodes/core/test/library.test.js index f6b3bbc95..dba60a9a7 100644 --- a/publicodes/core/test/library.test.js +++ b/publicodes/core/test/library.test.js @@ -26,9 +26,8 @@ revenu imposable: revenu abattu: formule: - allègement: - assiette: revenu imposable - abattement: 10% + valeur: revenu imposable + abattement: 10% impôt sur le revenu: formule: @@ -47,11 +46,10 @@ impôt sur le revenu: impôt sur le revenu à payer: formule: - allègement: - assiette: impôt sur le revenu - abattement: - valeur: 1177 - (75% * impôt sur le revenu) - plancher: 0 + valeur: impôt sur le revenu + abattement: + valeur: 1177 - (75% * impôt sur le revenu) + plancher: 0 ` let engine = new Engine(rules) diff --git a/publicodes/core/test/mécanismes/abattement.yaml b/publicodes/core/test/mécanismes/abattement.yaml new file mode 100644 index 000000000..036f875c0 --- /dev/null +++ b/publicodes/core/test/mécanismes/abattement.yaml @@ -0,0 +1,28 @@ +montant: + unité: € + +montant abattu: + unité: € + formule: + valeur: montant + abattement: 20507 + exemples: + - situation: + montant: 10000 + valeur attendue: 0 + - situation: + montant: 80000 + valeur attendue: 59493 + +montant abattu en pourcentage: + unité: € + formule: + valeur: montant + abattement: 15% + exemples: + - situation: + montant: 10000 + valeur attendue: 8500 + - situation: + montant: 80000 + valeur attendue: 68000 diff --git a/publicodes/core/test/mécanismes/allègement.yaml b/publicodes/core/test/mécanismes/allègement.yaml deleted file mode 100644 index b0a31e057..000000000 --- a/publicodes/core/test/mécanismes/allègement.yaml +++ /dev/null @@ -1,45 +0,0 @@ -montant: - unité: € - -montant abattu: - unité: € - formule: - allègement: - assiette: montant - abattement: 20507 - exemples: - - situation: - montant: 10000 - valeur attendue: 0 - - situation: - montant: 80000 - valeur attendue: 59493 - -montant abattu en pourcentage: - unité: € - formule: - allègement: - assiette: montant - abattement: 15% - exemples: - - situation: - montant: 10000 - valeur attendue: 8500 - - situation: - montant: 80000 - valeur attendue: 68000 - -montant abattu avec plafond numérique: - unité: € - formule: - allègement: - assiette: montant - abattement: 15% - plafond: 12000 - exemples: - - situation: - montant: 10000 - valeur attendue: 8500 - - situation: - montant: 100000 - valeur attendue: 88000 # 85000 s'il n'y avait pas de plafond à la somme abattue diff --git a/publicodes/core/test/mécanismes/conversion-unité.yaml b/publicodes/core/test/mécanismes/conversion-unité.yaml index 50ee1e279..79f7c7068 100644 --- a/publicodes/core/test/mécanismes/conversion-unité.yaml +++ b/publicodes/core/test/mécanismes/conversion-unité.yaml @@ -152,11 +152,10 @@ Conversion avec composantes: assiette annuelle: 20000 valeur attendue: 180 -Conversion dans un allègement: +Conversion dans un abattement: formule: - allègement: - assiette: 1000€/an - abattement: 10€/mois + valeur: 1000€/an + abattement: 10€/mois unité: €/an exemples: valeur attendue: 880 @@ -164,17 +163,15 @@ Conversion dans un allègement: Conversion dans avec un abattement en %: unité: €/an formule: - allègement: - assiette: 1000€/an - abattement: 10% + valeur: 1000€/an + abattement: 10% exemples: - valeur attendue: 900 assiette cotisations: formule: - allègement: - assiette: assiette mensuelle - abattement: 1200 €/an + valeur: assiette mensuelle + abattement: 1200 €/an prévoyance cadre: formule: diff --git a/publicodes/core/test/mécanismes/paramètres-nommés.yaml b/publicodes/core/test/mécanismes/paramètres-nommés.yaml index b950e9b8a..6031479db 100644 --- a/publicodes/core/test/mécanismes/paramètres-nommés.yaml +++ b/publicodes/core/test/mécanismes/paramètres-nommés.yaml @@ -32,10 +32,9 @@ paramètre nommés imbriqués: paramètre nommé utilisé dans la règle: formule: - allègement: - assiette [ref] : 500€ - abattement: - valeur: assiette * 10% - plancher: 100€ + valeur [ref assiette] : 500€ + abattement: + valeur: assiette * 10% + plancher: 100€ exemples: - - valeur attendue: 400 \ No newline at end of file + - valeur attendue: 400 diff --git a/publicodes/docs/mecanisms.yaml b/publicodes/docs/mecanisms.yaml index 7757b0931..b0ce74a6d 100644 --- a/publicodes/docs/mecanisms.yaml +++ b/publicodes/docs/mecanisms.yaml @@ -399,7 +399,7 @@ composantes: vérification: prix = prix . HT + prix . TVA -allègement: +abattement: description: >- Permet de réduire le montant d'une variable. @@ -407,9 +407,8 @@ allègement: exemples: base: >- impôt . revenu abattu: - allègement: - assiette: base des cotisations - abattement: abattement + valeur: base des cotisations + abattement: abattement plancher: diff --git a/publicodes/ui-react/source/Explanation.tsx b/publicodes/ui-react/source/Explanation.tsx index 6c615b60f..76ce028a2 100644 --- a/publicodes/ui-react/source/Explanation.tsx +++ b/publicodes/ui-react/source/Explanation.tsx @@ -1,5 +1,5 @@ import { ConstantNode, Leaf } from './mecanisms/common' -import Allègement from './mecanisms/Allègement' +import Abattement from './mecanisms/Abattement' import ApplicableSi from './mecanisms/Applicable' import Arrondi from './mecanisms/Arrondi' import Barème from './mecanisms/Barème' @@ -33,7 +33,7 @@ import { EngineContext } from './contexts' const UIComponents = { constant: ConstantNode, - allègement: Allègement, + abattement: Abattement, 'applicable si': ApplicableSi, arrondi: Arrondi, barème: Barème, diff --git a/publicodes/ui-react/source/mecanisms/Allègement.js b/publicodes/ui-react/source/mecanisms/Abattement.tsx similarity index 56% rename from publicodes/ui-react/source/mecanisms/Allègement.js rename to publicodes/ui-react/source/mecanisms/Abattement.tsx index b32fc7745..218a22179 100644 --- a/publicodes/ui-react/source/mecanisms/Allègement.js +++ b/publicodes/ui-react/source/mecanisms/Abattement.tsx @@ -1,10 +1,10 @@ import Explanation from '../Explanation' import { Mecanism } from './common' -export default function Allègement({ nodeValue, explanation }) { +export default function Abattement({ nodeValue, unit, explanation }) { return (
- +
  • Assiette : @@ -12,7 +12,7 @@ export default function Allègement({ nodeValue, explanation }) {
  • - {!explanation.abattement?.isDefault && ( + {!explanation.abattement?.nodeValue && (
  • Abattement : @@ -20,14 +20,6 @@ export default function Allègement({ nodeValue, explanation }) {
  • )} - {!explanation.plafond?.isDefault && ( -
  • - Plafond : - - - -
  • - )}
diff --git a/publicodes/ui-react/source/mecanisms/colors.ts b/publicodes/ui-react/source/mecanisms/colors.ts index a452e8313..8f2ac2464 100644 --- a/publicodes/ui-react/source/mecanisms/colors.ts +++ b/publicodes/ui-react/source/mecanisms/colors.ts @@ -2,7 +2,7 @@ const colors = { 'applicable si': '#9b59b6', 'non applicable si': '#9b59b6', somme: '#18457B', - allègement: '#B73731', + abattement: '#B73731', produit: '#2ecc71', 'une de ces conditions': '#3498db', 'toutes ces conditions': '#3498db',