From 64027a405e114496c2bbac026e44e280d3f8bcc8 Mon Sep 17 00:00:00 2001 From: Alice Dahan Date: Fri, 15 Nov 2024 16:54:55 +0100 Subject: [PATCH] =?UTF-8?q?ajoute=20le=20calcul=20de=20la=20r=C3=A9duction?= =?UTF-8?q?=20g=C3=A9n=C3=A9rale=20selon=20la=20m=C3=A9thode=20de=20r?= =?UTF-8?q?=C3=A9gularisation?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../simulateurs/reduction-generale/utils.ts | 141 +++++++++++++----- 1 file changed, 103 insertions(+), 38 deletions(-) diff --git a/site/source/pages/simulateurs/reduction-generale/utils.ts b/site/source/pages/simulateurs/reduction-generale/utils.ts index 67e2f3119..95fb45948 100644 --- a/site/source/pages/simulateurs/reduction-generale/utils.ts +++ b/site/source/pages/simulateurs/reduction-generale/utils.ts @@ -14,6 +14,8 @@ export type MonthState = { régularisation: number } +export type RégularisationMethod = 'annuelle' | 'progressive' + export const getRéductionGénéraleFromRémunération = ( engine: Engine, rémunérationBrute: number @@ -38,10 +40,9 @@ export const getInitialRéductionGénéraleMoisParMois = ( arrondi: 'oui', unité: '€/mois', })?.nodeValue as number) || 0 - const réductionGénérale = getRéductionGénéraleFromRémunération( - engine, - rémunérationBrute - ) + const réductionGénérale = rémunérationBrute + ? getRéductionGénéraleFromRémunération(engine, rémunérationBrute) + : 0 return Array(12).fill({ rémunérationBrute, @@ -52,30 +53,90 @@ export const getInitialRéductionGénéraleMoisParMois = ( export const reevaluateRéductionGénéraleMoisParMois = ( data: MonthState[], - engine: Engine + engine: Engine, + régularisationMethod: RégularisationMethod ): MonthState[] => { - const reevaluatedData = data.map((item) => ({ - ...item, - réductionGénérale: getRéductionGénéraleFromRémunération( - engine, - item.rémunérationBrute - ), - régularisation: 0, - })) + const SMICMensuel = engine.evaluate({ + valeur: 'salarié . temps de travail . SMIC', + unité: 'heures/mois', + }).nodeValue as number + // Si on laisse l'engine calculer T dans le calcul de la réduction générale, + // le résultat ne sera pas bon à cause de l'assiette de cotisations du contexte + const coefT = engine.evaluate({ + valeur: 'salarié . cotisations . exonérations . T', + }).nodeValue as number - reevaluatedData[reevaluatedData.length - 1].régularisation = - getRégularisationAnnuelle(data, engine) + const reevaluatedData = data.reduce( + (reevaluatedData: MonthState[], monthState: MonthState, index) => { + const rémunérationBrute = monthState.rémunérationBrute + let réductionGénérale = 0 + let régularisation = 0 + + const partialData = [ + ...reevaluatedData, + { + rémunérationBrute, + réductionGénérale, + régularisation, + }, + ] + + if (régularisationMethod === 'progressive') { + régularisation = getRégularisationProgressive( + index, + partialData, + SMICMensuel, + coefT, + engine + ) + if (régularisation > 0) { + réductionGénérale += régularisation + régularisation = 0 + } + } else if (régularisationMethod === 'annuelle') { + réductionGénérale = getRéductionGénéraleFromRémunération( + engine, + rémunérationBrute + ) + if (index === data.length - 1) { + régularisation = getRégularisationAnnuelle( + partialData, + réductionGénérale, + engine + ) + if (réductionGénérale + régularisation > 0) { + réductionGénérale += régularisation + régularisation = 0 + } + } + } + + return [ + ...reevaluatedData, + { + rémunérationBrute, + réductionGénérale, + régularisation, + }, + ] + }, + [] + ) return reevaluatedData } +// La régularisation annuelle est la différence entre la réduction générale calculée +// pour la rémunération annuelle (comparée au SMIC annuel) et la somme des réductions +// générales déjà accordées. const getRégularisationAnnuelle = ( data: MonthState[], + réductionGénéraleDernierMois: number, engine: Engine ): number => { - const currentRéductionGénéraleAnnuelle = sumAll( - data.map((monthData) => monthData.réductionGénérale) - ) + const currentRéductionGénéraleAnnuelle = + réductionGénéraleDernierMois + + sumAll(data.map((monthData) => monthData.réductionGénérale)) const realRéductionGénéraleAnnuelle = engine.evaluate({ valeur: réductionGénéraleDottedName, arrondi: 'non', @@ -85,43 +146,47 @@ const getRégularisationAnnuelle = ( return realRéductionGénéraleAnnuelle - currentRéductionGénéraleAnnuelle } -export const getRégularisationProgressive = ( +// La régularisation progressive du mois N est la différence entre la réduction générale +// calculée pour la rémunération totale jusqu'à N (comparée au SMIC mensuel * N) et la +// somme des N-1 réductions générales déjà accordées (en incluant les régularisations). +const getRégularisationProgressive = ( monthIndex: number, data: MonthState[], + SMICMensuel: number, + coefT: number, engine: Engine ): number => { if (monthIndex > data.length - 1) { return 0 } - const nbOfMonths = monthIndex + 1 const partialData = data.slice(0, nbOfMonths) - const currentRéductionGénéraleTotale = sumAll( - partialData.map((monthData) => monthData.réductionGénérale) - ) - const rémunérationBruteTotale = sumAll( + + const rémunérationBruteCumulée = sumAll( partialData.map((monthData) => monthData.rémunérationBrute) ) - const SMICMensuel = engine.evaluate({ - valeur: 'salarié . temps de travail . SMIC', - unité: 'heures/mois', - }).nodeValue as number - // Si on laisse l'engine calculer T dans le calcul de la réduction générale, - // le résultat ne sera pas bon à cause de l'assiette de cotisations du contexte - const coefT = engine.evaluate({ - valeur: 'salarié . cotisations . exonérations . T' , - }).nodeValue as number + if (!rémunérationBruteCumulée) { + return 0 + } - const realRéductionGénéraleTotale = engine.evaluate({ + const SMICCumulé = nbOfMonths * SMICMensuel + + const réductionGénéraleTotale = engine.evaluate({ valeur: réductionGénéraleDottedName, arrondi: 'non', contexte: { - [rémunérationBruteDottedName]: rémunérationBruteTotale, - 'salarié . temps de travail . SMIC': nbOfMonths * SMICMensuel, + [rémunérationBruteDottedName]: rémunérationBruteCumulée, + 'salarié . temps de travail . SMIC': SMICCumulé, 'salarié . cotisations . exonérations . T': coefT, - } + }, }).nodeValue as number - return realRéductionGénéraleTotale - currentRéductionGénéraleTotale + const currentRéductionGénéraleCumulée = sumAll( + partialData.map( + (monthData) => monthData.réductionGénérale + monthData.régularisation + ) + ) + + return réductionGénéraleTotale - currentRéductionGénéraleCumulée }