From 227936935a27996f2596382d7f4d113d478dbb2d Mon Sep 17 00:00:00 2001 From: Alice Dahan Date: Mon, 28 Oct 2024 14:45:18 +0100 Subject: [PATCH] =?UTF-8?q?feat:=20ajout=20de=20la=20r=C3=A9gularisation?= =?UTF-8?q?=20annuelle=20dans=20le=20simulateur=20RGCP=20mois=20par=20mois?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../mon-entreprise/reduction-generale.ts | 20 +++++++++++--- site/source/components/SimulateurWarning.tsx | 4 +-- site/source/locales/ui-en.yaml | 6 ++--- site/source/locales/ui-fr.yaml | 5 ++-- .../components/WarningTooltip.tsx | 6 ++++- .../reduction-generale/RéductionGénérale.tsx | 1 + .../RéductionGénéraleMoisParMois.tsx | 21 +++++++++++---- .../simulateurs/reduction-generale/utils.ts | 27 ++++++++++++++++++- 8 files changed, 72 insertions(+), 18 deletions(-) diff --git a/site/cypress/integration/mon-entreprise/reduction-generale.ts b/site/cypress/integration/mon-entreprise/reduction-generale.ts index df6b87465..30d529656 100755 --- a/site/cypress/integration/mon-entreprise/reduction-generale.ts +++ b/site/cypress/integration/mon-entreprise/reduction-generale.ts @@ -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() diff --git a/site/source/components/SimulateurWarning.tsx b/site/source/components/SimulateurWarning.tsx index dd250923b..ee33929fc 100644 --- a/site/source/components/SimulateurWarning.tsx +++ b/site/source/components/SimulateurWarning.tsx @@ -206,8 +206,8 @@ export default function SimulateurWarning({ RGCP {' '} - à 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{' '} This simulator is currently under development. It only calculates - the <3>RGCP on the basis of monthly or annual remuneration, without - including regularization. For a full version, use <7>the urssaf.fr - simulator. + <3>RGCP on the basis of monthly or annual remuneration. For a full + version, use <7>the urssaf.fr simulator. salarié: The simulator does not currently take into account collective agreements, nor the myriad of company subsidies. Find your collective bargaining agreement <2>here, and explore the range of assistance diff --git a/site/source/locales/ui-fr.yaml b/site/source/locales/ui-fr.yaml index 19696a42f..4756c8943 100644 --- a/site/source/locales/ui-fr.yaml +++ b/site/source/locales/ui-fr.yaml @@ -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. Il propose uniquement le calcul de la <3>RGCP à 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. + annuelle. Pour une version complète, utilisez <7>le simulateur + d'urssaf.fr. 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, et explorez les aides sur diff --git a/site/source/pages/simulateurs/comparaison-statuts/components/WarningTooltip.tsx b/site/source/pages/simulateurs/comparaison-statuts/components/WarningTooltip.tsx index ee307b4fe..200124f10 100644 --- a/site/source/pages/simulateurs/comparaison-statuts/components/WarningTooltip.tsx +++ b/site/source/pages/simulateurs/comparaison-statuts/components/WarningTooltip.tsx @@ -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 ( - + {t('Attention')} + ) } diff --git a/site/source/pages/simulateurs/reduction-generale/RéductionGénérale.tsx b/site/source/pages/simulateurs/reduction-generale/RéductionGénérale.tsx index 4ebc951f5..ae65619c6 100644 --- a/site/source/pages/simulateurs/reduction-generale/RéductionGénérale.tsx +++ b/site/source/pages/simulateurs/reduction-generale/RéductionGénérale.tsx @@ -142,6 +142,7 @@ function RéductionGénéraleSimulationGoals({ engine, rémunérationBrute ), + régularisation: 0, } updateRémunérationBruteAnnuelle(updatedData) diff --git a/site/source/pages/simulateurs/reduction-generale/RéductionGénéraleMoisParMois.tsx b/site/source/pages/simulateurs/reduction-generale/RéductionGénéraleMoisParMois.tsx index 82e666061..f7dcfdce2 100644 --- a/site/source/pages/simulateurs/reduction-generale/RéductionGénéraleMoisParMois.tsx +++ b/site/source/pages/simulateurs/reduction-generale/RéductionGénéraleMoisParMois.tsx @@ -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 ? ( {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={} hasArrow={true} > - - + {t('Attention')} + @@ -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}; +` diff --git a/site/source/pages/simulateurs/reduction-generale/utils.ts b/site/source/pages/simulateurs/reduction-generale/utils.ts index 25ca99971..c75b2d426 100644 --- a/site/source/pages/simulateurs/reduction-generale/utils.ts +++ b/site/source/pages/simulateurs/reduction-generale/utils.ts @@ -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 ): 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 +): 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 }