feat: ajout de la régularisation annuelle dans le simulateur RGCP mois par mois
parent
65d4e4dd89
commit
227936935a
|
@ -112,12 +112,12 @@ describe(
|
|||
cy.contains('Réduction mois par mois').click()
|
||||
|
||||
cy.get(inputSelector).first().type('{selectall}1900')
|
||||
cy.get(inputSelector).last().type('{selectall}2000')
|
||||
cy.get(inputSelector).eq(1).type('{selectall}2000')
|
||||
cy.get(
|
||||
'td[id="salarié___cotisations___exonérations___réduction_générale-janvier"]'
|
||||
).should('include.text', '523,26 €')
|
||||
cy.get(
|
||||
'td[id="salarié___cotisations___exonérations___réduction_générale-décembre"]'
|
||||
'td[id="salarié___cotisations___exonérations___réduction_générale-février"]'
|
||||
).should('include.text', '470 €')
|
||||
})
|
||||
|
||||
|
@ -127,7 +127,7 @@ describe(
|
|||
cy.get(inputSelector).first().type('{selectall}1900')
|
||||
cy.contains('Réduction mois par mois').click()
|
||||
cy.get(inputSelector).first().type('{selectall}2000')
|
||||
cy.get(inputSelector).last().type('{selectall}2000')
|
||||
cy.get(inputSelector).eq(1).type('{selectall}2000')
|
||||
|
||||
cy.contains('Réduction mensuelle').click()
|
||||
cy.get(inputSelector).first().should('have.value', '1 916,67 €')
|
||||
|
@ -136,13 +136,25 @@ describe(
|
|||
cy.contains('Réduction mois par mois').click()
|
||||
cy.get(inputSelector).each(($input, index) => {
|
||||
let expectedValue = '1 900 €'
|
||||
if (index === 0 || index === 11) {
|
||||
if (index < 2) {
|
||||
expectedValue = '2 000 €'
|
||||
}
|
||||
cy.wrap($input).should('have.value', expectedValue)
|
||||
})
|
||||
})
|
||||
|
||||
it('should include annual regularisation', function () {
|
||||
cy.contains('Moins de 50 salariés').click()
|
||||
cy.contains('Réduction mensuelle').click()
|
||||
cy.get(inputSelector).first().type('{selectall}1900')
|
||||
cy.contains('Réduction mois par mois').click()
|
||||
cy.get(inputSelector).eq(1).type('{selectall}3000')
|
||||
|
||||
cy.get(
|
||||
'td[id="salarié___cotisations___exonérations___réduction_générale-décembre"]'
|
||||
).should('include.text', '460,38 €')
|
||||
})
|
||||
|
||||
it('should be RGAA compliant', function () {
|
||||
cy.contains('Réduction mensuelle').click()
|
||||
checkA11Y()
|
||||
|
|
|
@ -206,8 +206,8 @@ export default function SimulateurWarning({
|
|||
<abbr title="Réduction Générale des Cotisations Patronales">
|
||||
RGCP
|
||||
</abbr>{' '}
|
||||
à partir d'une rémunération mensuelle ou annuelle, sans intégrer
|
||||
la régularisation. Pour une version complète, utilisez{' '}
|
||||
à partir d'une rémunération mensuelle ou annuelle. Pour une
|
||||
version complète, utilisez{' '}
|
||||
<Link
|
||||
aria-label="Simulateur de calcul de la réduction générale des cotisations sur urssaf.fr, nouvelle fenêtre"
|
||||
href="https://www.declaration.urssaf.fr/calcul/"
|
||||
|
|
|
@ -46,6 +46,7 @@ Aller directement au pied de page: Go directly to footer
|
|||
Annuler: Cancel
|
||||
Arrêt maladie: Sick leave
|
||||
Assistants à la déclaration de revenu 2023 des indépendants: Assistants for the 2023 self-employed tax return
|
||||
Attention: Warning
|
||||
Attention, information importante: Important information
|
||||
Attention, vos données sauvegardées seront supprimées de manière définitive.: Please note that your saved data will be permanently deleted.
|
||||
Aucun: No
|
||||
|
@ -1786,9 +1787,8 @@ simulateurs:
|
|||
specific rates and/or distribution of supplementary pension
|
||||
contributions applied in certain companies.
|
||||
beta: <0>This simulator is currently under development.</0> It only calculates
|
||||
the <3>RGCP</3> on the basis of monthly or annual remuneration, without
|
||||
including regularization. For a full version, use <7>the urssaf.fr
|
||||
simulator.</7>
|
||||
<3>RGCP</3> on the basis of monthly or annual remuneration. For a full
|
||||
version, use <7>the urssaf.fr simulator.</7>
|
||||
salarié: The simulator does not currently take into account collective
|
||||
agreements, nor the myriad of company subsidies. Find your collective
|
||||
bargaining agreement <2>here</2>, and explore the range of assistance
|
||||
|
|
|
@ -49,6 +49,7 @@ Aller directement au pied de page: Aller directement au pied de page
|
|||
Annuler: Annuler
|
||||
Arrêt maladie: Arrêt maladie
|
||||
Assistants à la déclaration de revenu 2023 des indépendants: Assistants à la déclaration de revenu 2023 des indépendants
|
||||
Attention: Attention
|
||||
Attention, information importante: Attention, information importante
|
||||
Attention, vos données sauvegardées seront supprimées de manière définitive.: Attention, vos données sauvegardées seront supprimées de manière définitive.
|
||||
Aucun: Aucun
|
||||
|
@ -1904,8 +1905,8 @@ simulateurs:
|
|||
complémentaire appliqués dans certaines entreprises.
|
||||
beta: <0>Ce simulateur est en cours de développement.</0> Il propose uniquement
|
||||
le calcul de la <3>RGCP</3> à partir d'une rémunération mensuelle ou
|
||||
annuelle, sans intégrer la régularisation. Pour une version complète,
|
||||
utilisez <7>le simulateur d'urssaf.fr.</7>
|
||||
annuelle. Pour une version complète, utilisez <7>le simulateur
|
||||
d'urssaf.fr.</7>
|
||||
salarié: Le simulateur ne prend pour l'instant pas en compte les accords et
|
||||
conventions collectives, ni la myriade d'aides aux entreprises. Trouvez
|
||||
votre convention collective <2>ici</2>, et explorez les aides sur
|
||||
|
|
|
@ -1,13 +1,17 @@
|
|||
import { ReactNode } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { styled } from 'styled-components'
|
||||
|
||||
import { WarningIcon } from '@/design-system/icons'
|
||||
import { Tooltip } from '@/design-system/tooltip'
|
||||
|
||||
const WarningTooltip = ({ tooltip }: { tooltip: ReactNode }) => {
|
||||
const { t } = useTranslation()
|
||||
|
||||
return (
|
||||
<Tooltip tooltip={tooltip}>
|
||||
<StyledWarningIcon aria-label="Attention" />
|
||||
<span className="sr-only">{t('Attention')}</span>
|
||||
<StyledWarningIcon aria-label={t('Attention')} />
|
||||
</Tooltip>
|
||||
)
|
||||
}
|
||||
|
|
|
@ -142,6 +142,7 @@ function RéductionGénéraleSimulationGoals({
|
|||
engine,
|
||||
rémunérationBrute
|
||||
),
|
||||
régularisation: 0,
|
||||
}
|
||||
|
||||
updateRémunérationBruteAnnuelle(updatedData)
|
||||
|
|
|
@ -7,7 +7,6 @@ import NumberInput from '@/components/conversation/NumberInput'
|
|||
import { Condition } from '@/components/EngineValue/Condition'
|
||||
import { useEngine } from '@/components/utils/EngineContext'
|
||||
import { SearchIcon, WarningIcon } from '@/design-system/icons'
|
||||
import { Spacing } from '@/design-system/layout'
|
||||
import { Tooltip } from '@/design-system/tooltip'
|
||||
|
||||
import Répartition from './components/Répartition'
|
||||
|
@ -101,6 +100,9 @@ export default function RéductionGénéraleMoisParMois({
|
|||
contexte={{
|
||||
[rémunérationBruteDottedName]:
|
||||
data[monthIndex].rémunérationBrute,
|
||||
[réductionGénéraleDottedName]:
|
||||
data[monthIndex].réductionGénérale +
|
||||
data[monthIndex].régularisation,
|
||||
}}
|
||||
/>
|
||||
)
|
||||
|
@ -135,11 +137,16 @@ export default function RéductionGénéraleMoisParMois({
|
|||
'_'
|
||||
)}-${monthName}`}
|
||||
>
|
||||
{data[monthIndex].réductionGénérale ? (
|
||||
{data[monthIndex].réductionGénérale ||
|
||||
data[monthIndex].régularisation ? (
|
||||
<Tooltip tooltip={tooltip} hasArrow={true}>
|
||||
<StyledDiv>
|
||||
{formatValue(
|
||||
{ nodeValue: data[monthIndex].réductionGénérale },
|
||||
{
|
||||
nodeValue:
|
||||
data[monthIndex].réductionGénérale +
|
||||
data[monthIndex].régularisation,
|
||||
},
|
||||
{
|
||||
displayedUnit,
|
||||
language,
|
||||
|
@ -163,8 +170,8 @@ export default function RéductionGénéraleMoisParMois({
|
|||
tooltip={<WarningSalaireTrans />}
|
||||
hasArrow={true}
|
||||
>
|
||||
<Spacing xxs />
|
||||
<WarningIcon />
|
||||
<span className="sr-only">{t('Attention')}</span>
|
||||
<StyledWarningIcon aria-label={t('Attention')} />
|
||||
</Tooltip>
|
||||
</Condition>
|
||||
</StyledDiv>
|
||||
|
@ -208,3 +215,7 @@ const StyledDiv = styled.div`
|
|||
align-items: center;
|
||||
gap: ${({ theme }) => theme.spacings.sm};
|
||||
`
|
||||
|
||||
const StyledWarningIcon = styled(WarningIcon)`
|
||||
margin-top: ${({ theme }) => theme.spacings.xxs};
|
||||
`
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
import { sumAll } from 'effect/Number'
|
||||
import { DottedName } from 'modele-social'
|
||||
import Engine from 'publicodes'
|
||||
|
||||
|
@ -10,6 +11,7 @@ export const réductionGénéraleDottedName =
|
|||
export type MonthState = {
|
||||
rémunérationBrute: number
|
||||
réductionGénérale: number
|
||||
régularisation: number
|
||||
}
|
||||
|
||||
export const getRéductionGénéraleFromRémunération = (
|
||||
|
@ -44,6 +46,7 @@ export const getInitialRéductionGénéraleMoisParMois = (
|
|||
return Array(12).fill({
|
||||
rémunérationBrute,
|
||||
réductionGénérale,
|
||||
régularisation: 0,
|
||||
}) as MonthState[]
|
||||
}
|
||||
|
||||
|
@ -51,11 +54,33 @@ export const reevaluateRéductionGénéraleMoisParMois = (
|
|||
data: MonthState[],
|
||||
engine: Engine<DottedName>
|
||||
): MonthState[] => {
|
||||
return data.map((item) => ({
|
||||
const reevaluatedData = data.map((item) => ({
|
||||
...item,
|
||||
réductionGénérale: getRéductionGénéraleFromRémunération(
|
||||
engine,
|
||||
item.rémunérationBrute
|
||||
),
|
||||
régularisation: 0,
|
||||
}))
|
||||
|
||||
reevaluatedData[reevaluatedData.length - 1].régularisation =
|
||||
getRégularisationAnnuelle(data, engine)
|
||||
|
||||
return reevaluatedData
|
||||
}
|
||||
|
||||
const getRégularisationAnnuelle = (
|
||||
data: MonthState[],
|
||||
engine: Engine<DottedName>
|
||||
): number => {
|
||||
const currentRéductionGénéraleAnnuelle = sumAll(
|
||||
data.map((monthData) => monthData.réductionGénérale)
|
||||
)
|
||||
const realRéductionGénéraleAnnuelle = engine.evaluate({
|
||||
valeur: réductionGénéraleDottedName,
|
||||
arrondi: 'non',
|
||||
unité: '€/an',
|
||||
}).nodeValue as number
|
||||
|
||||
return realRéductionGénéraleAnnuelle - currentRéductionGénéraleAnnuelle
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue