ajoute le calcul de la réduction générale selon la méthode de régularisation

pull/3230/head
Alice Dahan 2024-11-15 16:54:55 +01:00 committed by liliced
parent 4f2d6fc69e
commit 64027a405e
1 changed files with 103 additions and 38 deletions

View File

@ -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<DottedName>,
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<DottedName>
engine: Engine<DottedName>,
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<DottedName>
): 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<DottedName>
): 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
}