refactor(lodeom): déplace la question sur la zone dans modele-social

feat/2909-4-zone-switch
Alice Dahan 2024-12-27 11:13:11 +01:00
parent fe82f98fbc
commit 85d74de033
15 changed files with 114 additions and 118 deletions

View File

@ -437,6 +437,7 @@ exports[`e2e test mon-entreprise api > Test evaluate brut => net + super brut 2`
"salarié . cotisations . exonérations . lodeom . zone deux",
"salarié . cotisations . exonérations . lodeom . zone un",
"salarié . cotisations . exonérations . réduction générale . caisse de congés payés",
"salarié . cotisations . exonérations . zones lodeom",
"salarié . cotisations . maladie . employeur . taux réduit",
"salarié . cotisations . prévoyances . santé . montant",
"salarié . cotisations . prévoyances . santé . taux employeur",

View File

@ -143,6 +143,22 @@ salarié . cotisations . exonérations . heures supplémentaires:
- 1 / assiette
plafond: 11.31%
salarié . cotisations . exonérations . zones lodeom:
question: Quelle est votre localisation ?
formule:
une possibilité:
choix obligatoire: oui
possibilités:
- zone un
- zone deux
avec:
zone un:
valeur: zones lodeom = 'zone un'
titre: Guadeloupe, Guyane, Martinique, La Réunion
zone deux:
valeur: zones lodeom = 'zone deux'
titre: Saint-Barthélémy, Saint-Martin
salarié . cotisations . exonérations . lodeom:
experimental: oui
applicable si:
@ -190,6 +206,7 @@ salarié . cotisations . exonérations . lodeom . zone un:
titre: Guadeloupe, Guyane, Martinique, La Réunion
par défaut: non
une de ces conditions:
- zones lodeom = 'zone un'
- établissement . commune . département = 'Guadeloupe'
- établissement . commune . département = 'La Réunion'
- établissement . commune . département = 'Martinique'
@ -405,6 +422,7 @@ salarié . cotisations . exonérations . lodeom . zone deux:
titre: Saint-Barthélémy, Saint-Martin
par défaut: non
une de ces conditions:
- zones lodeom = 'zone deux'
- établissement . commune . département = 'Saint-Barthélemy'
- établissement . commune . département = 'Saint-Martin'
références:

View File

@ -62,17 +62,13 @@ describe('Simulateur lodeom', { testIsolation: false }, function () {
})
it('should allow to select a scale', function () {
cy.get('#salarié___cotisations___exonérations___lodeom___zone_un___barèmes')
.contains('Barème de compétitivité renforcée')
.click()
cy.contains('Barème de compétitivité renforcée').click()
cy.get(
'p[id="salarié___cotisations___exonérations___lodeom___montant-value"]'
).should('include.text', '1117,90 €')
cy.get('#salarié___cotisations___exonérations___lodeom___zone_un___barèmes')
.contains("Barème d'innovation et croissance")
.click()
cy.contains("Barème d'innovation et croissance").click()
cy.get(
'p[id="salarié___cotisations___exonérations___lodeom___montant-value"]'
@ -81,31 +77,19 @@ describe('Simulateur lodeom', { testIsolation: false }, function () {
it('should allow to select a zone', function () {
cy.contains('Saint-Barthélémy, Saint-Martin').click()
cy.get(
'#salarié___cotisations___exonérations___lodeom___zone_deux___barèmes'
)
.contains('Barème pour les employeurs de moins de 11 salariés')
.click()
cy.contains('Barème pour les employeurs de moins de 11 salariés').click()
cy.get(
'p[id="salarié___cotisations___exonérations___lodeom___montant-value"]'
).should('include.text', '530,25 €')
cy.get(
'#salarié___cotisations___exonérations___lodeom___zone_deux___barèmes'
)
.contains("Barème d'exonération sectorielle")
.click()
cy.contains("Barème d'exonération sectorielle").click()
cy.get(
'p[id="salarié___cotisations___exonérations___lodeom___montant-value"]'
).should('include.text', '350,35 €')
cy.get(
'#salarié___cotisations___exonérations___lodeom___zone_deux___barèmes'
)
.contains("Barème d'exonération renforcée")
.click()
cy.contains("Barème d'exonération renforcée").click()
cy.get(
'p[id="salarié___cotisations___exonérations___lodeom___montant-value"]'

View File

@ -26,7 +26,7 @@ export default function EffectifSwitch() {
return (
<Container>
<StyledBody id="effectif-switch-label">
<Strong>{t("Effectif de l'entreprise")} :</Strong>
<Strong>{t('Effectif de lentreprise')} :</Strong>
</StyledBody>
<StyledToggleGroup
value={currentEffectif}
@ -50,9 +50,11 @@ const Container = styled.div`
flex-wrap: wrap;
column-gap: ${({ theme }) => theme.spacings.sm};
width: 100%;
margin-bottom: ${({ theme }) => theme.spacings.sm};
`
const StyledBody = styled(Body)`
margin: ${({ theme }) => theme.spacings.xxs} 0;
margin: 0;
margin-bottom: ${({ theme }) => theme.spacings.sm};
`
const StyledToggleGroup = styled(ToggleGroup)`
display: flex;

View File

@ -60,9 +60,11 @@ const Container = styled.div`
flex-wrap: wrap;
column-gap: ${({ theme }) => theme.spacings.sm};
width: 100%;
margin-bottom: ${({ theme }) => theme.spacings.sm};
`
const StyledBody = styled(Body)`
margin: ${({ theme }) => theme.spacings.xxs} 0;
margin: 0;
margin-bottom: ${({ theme }) => theme.spacings.sm};
`
const StyledToggleGroup = styled(ToggleGroup)`
display: flex;

View File

@ -0,0 +1,29 @@
import { DottedName } from 'modele-social'
import { useEngine } from '@/components/utils/EngineContext'
import { useZoneLodeom, ZoneLodeom } from './useZoneLodeom'
const barèmes = [
'barème compétitivité',
'barème compétitivité renforcée',
'barème innovation et croissance',
'barème moins de 11 salariés',
'barème sectoriel',
'barème renforcé',
]
export type BarèmeLodeom = (typeof barèmes)[number]
export const barèmeLodeomDottedName = (zone: ZoneLodeom) =>
`salarié . cotisations . exonérations . lodeom . ${zone} . barèmes` as DottedName
export const useBarèmeLodeom = (): BarèmeLodeom | undefined => {
const zone = useZoneLodeom()
const engine = useEngine()
return (
zone &&
(engine.evaluate(barèmeLodeomDottedName(zone)).nodeValue as BarèmeLodeom)
)
}

View File

@ -1,38 +1,16 @@
import { useDispatch } from 'react-redux'
import { DottedName } from 'modele-social'
import { useEngine } from '@/components/utils/EngineContext'
import { toOuiNon } from '@/domaine/engine/toOuiNon'
import { batchUpdateSituation } from '@/store/actions/actions'
const zones = ['zone un', 'zone deux']
export type ZoneLodeom = (typeof zones)[number]
type ReturnType = {
currentZone?: ZoneLodeom
updateZone: (zone: ZoneLodeom) => void
}
export const zonesLodeomDottedName =
'salarié . cotisations . exonérations . zones lodeom' as DottedName
export const useZoneLodeom = (): ReturnType => {
export const useZoneLodeom = (): ZoneLodeom | undefined => {
const engine = useEngine()
const dispatch = useDispatch()
const dottedName = 'salarié . cotisations . exonérations . lodeom'
const currentZone = zones.find((zone) => {
const zoneValue = engine.evaluate(`${dottedName} . ${zone}`).nodeValue
return !!zoneValue
})
const updateZone = (newZone: ZoneLodeom): void => {
const newSituation = zones.reduce((situation, zone) => {
return {
...situation,
[`${dottedName} . ${zone}`]: toOuiNon(zone === newZone),
}
}, {})
dispatch(batchUpdateSituation(newSituation))
}
return { currentZone, updateZone }
return engine.evaluate(zonesLodeomDottedName).nodeValue as ZoneLodeom
}

View File

@ -10380,6 +10380,18 @@ salarié . cotisations . exonérations . réduction générale . régularisation
- ou au titre du dernier trimestre de lannée pour les employeurs « trimestriels ».
titre.en: '[automatic] regularization'
titre.fr: régularisation
salarié . cotisations . exonérations . zones lodeom:
avec:
zone deux:
titre.en: '[automatic] Saint-Barthélémy, Saint-Martin'
titre.fr: Saint-Barthélémy, Saint-Martin
zone un:
titre.en: '[automatic] Guadeloupe, French Guiana, Martinique, Reunion Island'
titre.fr: Guadeloupe, Guyane, Martinique, La Réunion
question.en: '[automatic] Where are you located?'
question.fr: Quelle est votre localisation ?
titre.en: '[automatic] lodeom zones'
titre.fr: zones lodeom
salarié . cotisations . forfait social:
description.en: >
[automatic] The social security contribution is a contribution paid by the

View File

@ -92,7 +92,7 @@ Décès: Deaths
Déplier: Unfold
"Détail du montant :": "Amount in detail :"
Effacer mes réponses: Delete my answers
Effectif de l'entreprise: Number of employees
Effectif de lentreprise: Number of employees
"En cas d<1>accident de travail</1>, de <4>maladie professionnelle</4> ou dun <7>accident sur le trajet domicile-travail</7>, vous serez indemnisé(e) à hauteur de :":
"In the event of an<1>accident at work</1>, <4>occupational illness</4> or an
<7>accident on the way to or from work</7>, you will receive compensation of:"
@ -137,7 +137,6 @@ Graphique statistiques détaillés de la satisfaction, présence dune alterna
Graphique statistiques détaillés du nombre visites par jour, présence dune alternative accessible après limage:
Graph showing detailed statistics on the number of visits per day, with an
alternative accessible after the image
Guadeloupe, Guyane, Martinique, La Réunion: Guadeloupe, French Guiana, Martinique, Reunion Island
Habituellement: Usually
Impôt: Tax
Impôt au barème: Tax scale
@ -279,7 +278,6 @@ Répartition du chiffre d'affaires: Sales breakdown
Répondez à quelques questions additionnelles afin de préciser votre résultat.: Answer a few additional questions to clarify your result.
Résultat fiscal: Taxable income
Réussite: Success
Saint-Barthélémy, Saint-Martin: Saint-Barthélémy, Saint-Martin
Saisissez votre domaine d'activité: Enter your field of activity
Salaire brut: Gross salary
Salaire brut mensuel: Gross monthly salary
@ -1490,7 +1488,7 @@ pages:
salaries below 3.5 SMIC. This means, for 2024, a total
remuneration not exceeding <2>€6,306.30</2> gross per month.
stage: The Lodeom exemption does not apply to internship bonuses.
zone-switch-label: Company location
zone-switch-label: "Company location :"
médecin:
meta:
description: Calculation of net income after deduction of contributions, based

View File

@ -98,7 +98,7 @@ Décès: Décès
Déplier: Déplier
"Détail du montant :": "Détail du montant :"
Effacer mes réponses: Effacer mes réponses
Effectif de l'entreprise: Effectif de l'entreprise
Effectif de lentreprise: Effectif de lentreprise
"En cas d<1>accident de travail</1>, de <4>maladie professionnelle</4> ou dun <7>accident sur le trajet domicile-travail</7>, vous serez indemnisé(e) à hauteur de :":
"En cas d<1>accident de travail</1>, de <4>maladie professionnelle</4> ou
dun <7>accident sur le trajet domicile-travail</7>, vous serez indemnisé(e) à
@ -146,7 +146,6 @@ Graphique statistiques détaillés de la satisfaction, présence dune alterna
Graphique statistiques détaillés du nombre visites par jour, présence dune alternative accessible après limage:
Graphique statistiques détaillés du nombre visites par jour, présence dune
alternative accessible après limage
Guadeloupe, Guyane, Martinique, La Réunion: Guadeloupe, Guyane, Martinique, La Réunion
Habituellement: Habituellement
Impôt: Impôt
Impôt au barème: Impôt au barème
@ -294,7 +293,6 @@ Répartition du chiffre d'affaires: Répartition du chiffre d'affaires
Répondez à quelques questions additionnelles afin de préciser votre résultat.: Répondez à quelques questions additionnelles afin de préciser votre résultat.
Résultat fiscal: Résultat fiscal
Réussite: Réussite
Saint-Barthélémy, Saint-Martin: Saint-Barthélémy, Saint-Martin
Saisissez votre domaine d'activité: Saisissez votre domaine d'activité
Salaire brut: Salaire brut
Salaire brut mensuel: Salaire brut mensuel
@ -1587,7 +1585,7 @@ pages:
2024, une rémunération totale qui ne dépasse pas <2>6 306,30 €</2>
bruts par mois.
stage: L'exonération Lodeom ne s'applique pas sur les gratifications de stage.
zone-switch-label: Localisation de l'entreprise
zone-switch-label: "Localisation de lentreprise :"
médecin:
meta:
description: Calcul du revenu net après déduction des cotisations à partir du

View File

@ -15,8 +15,9 @@ import ZoneSwitch from './components/ZoneSwitch'
import LodeomSimulationGoals from './Goals'
export default function LodeomSimulation() {
const { t } = useTranslation()
const currentZone = useZoneLodeom()
const [monthByMonth, setMonthByMonth] = useState(false)
const { t } = useTranslation()
const periods = [
{
label: t('pages.simulateurs.lodeom.tab.month', 'Exonération mensuelle'),
@ -41,8 +42,6 @@ export default function LodeomSimulation() {
const [régularisationMethod, setRégularisationMethod] =
useState<RégularisationMethod>('progressive')
const { currentZone } = useZoneLodeom()
return (
<>
<Simulation afterQuestionsSlot={<SelectSimulationYear />}>

View File

@ -1,23 +1,21 @@
import { DottedName } from 'modele-social'
import { renderToString } from 'react-dom/server'
import { useTranslation } from 'react-i18next'
import { styled } from 'styled-components'
import { Body } from '@/design-system/typography/paragraphs'
import { barèmeLodeomDottedName } from '@/hooks/useBarèmeLodeom'
import { useZoneLodeom } from '@/hooks/useZoneLodeom'
import { SimpleField } from '@/pages/assistants/components/Fields'
export default function BarèmeSwitch() {
const { currentZone } = useZoneLodeom()
const currentZone = useZoneLodeom()
const { t } = useTranslation()
return (
currentZone && (
<Container>
<SimpleField
dottedName={
`salarié . cotisations . exonérations . lodeom . ${currentZone} . barèmes` as DottedName
}
dottedName={barèmeLodeomDottedName(currentZone)}
label={renderToString(
<p>
<strong>
@ -42,8 +40,9 @@ const Container = styled.div`
flex-wrap: wrap;
column-gap: ${({ theme }) => theme.spacings.sm};
width: 100%;
margin-bottom: -${({ theme }) => theme.spacings.xl};
margin-bottom: -${({ theme }) => theme.spacings.lg};
`
const StyledBody = styled(Body)`
margin: ${({ theme }) => theme.spacings.xxs} 0;
margin: 0;
margin-bottom: ${({ theme }) => theme.spacings.md};
`

View File

@ -1,16 +1,9 @@
import { Trans } from 'react-i18next'
import { useEngine } from '@/components/utils/EngineContext'
import { useZoneLodeom } from '@/hooks/useZoneLodeom'
import { useBarèmeLodeom } from '@/hooks/useBarèmeLodeom'
export default function WarningSalaireTrans() {
const { currentZone } = useZoneLodeom()
const engine = useEngine()
const currentBarème =
currentZone &&
engine.evaluate(
`salarié . cotisations . exonérations . lodeom . ${currentZone} . barèmes`
).nodeValue
const currentBarème = useBarèmeLodeom()
return (
currentBarème && (

View File

@ -1,38 +1,30 @@
import { renderToString } from 'react-dom/server'
import { useTranslation } from 'react-i18next'
import { styled } from 'styled-components'
import { Radio, ToggleGroup } from '@/design-system'
import { Strong } from '@/design-system/typography'
import { Body } from '@/design-system/typography/paragraphs'
import { useZoneLodeom } from '@/hooks/useZoneLodeom'
import { zonesLodeomDottedName } from '@/hooks/useZoneLodeom'
import { SimpleField } from '@/pages/assistants/components/Fields'
export default function ZoneSwitch() {
const { currentZone, updateZone } = useZoneLodeom()
const { t } = useTranslation()
return (
<Container>
<StyledBody id="zone-switch-label">
<Strong>
{t(
'pages.simulateurs.lodeom.zone-switch-label',
"Localisation de l'entreprise"
)}{' '}
:
</Strong>
</StyledBody>
<StyledToggleGroup
value={currentZone}
onChange={updateZone}
aria-labelledby="zone-switch-label"
>
<StyledRadio value="zone un">
{t('Guadeloupe, Guyane, Martinique, La Réunion')}
</StyledRadio>
<StyledRadio value="zone deux">
{t('Saint-Barthélémy, Saint-Martin')}
</StyledRadio>
</StyledToggleGroup>
<SimpleField
dottedName={zonesLodeomDottedName}
label={renderToString(
<p>
<strong>
{t(
'pages.simulateurs.lodeom.zone-switch-label',
'Localisation de lentreprise :'
)}
</strong>
</p>
)}
labelStyle={StyledBody}
/>
</Container>
)
}
@ -44,20 +36,9 @@ const Container = styled.div`
flex-wrap: wrap;
column-gap: ${({ theme }) => theme.spacings.sm};
width: 100%;
margin-bottom: -${({ theme }) => theme.spacings.lg};
`
const StyledBody = styled(Body)`
margin: ${({ theme }) => theme.spacings.xxs} 0;
`
const StyledToggleGroup = styled(ToggleGroup)`
display: flex;
> * {
display: flex;
flex-direction: column;
}
`
const StyledRadio = styled(Radio)`
white-space: nowrap;
> span {
width: 100%;
}
margin: 0;
margin-bottom: ${({ theme }) => theme.spacings.md};
`

View File

@ -54,9 +54,11 @@ const Container = styled.div`
flex-wrap: wrap;
column-gap: ${({ theme }) => theme.spacings.sm};
width: 100%;
margin-bottom: ${({ theme }) => theme.spacings.sm};
`
const StyledBody = styled(Body)`
margin: ${({ theme }) => theme.spacings.xxs} 0;
margin: 0;
margin-bottom: ${({ theme }) => theme.spacings.sm};
`
const StyledToggleGroup = styled(ToggleGroup)`
display: flex;