diff --git a/README.md b/README.md index 690f38d43ba152bb0b81dae9b729518146ff7c0b..33e4e17dc7e2374e5726165598f581401dc16514 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,7 @@ LexImpact est un service de l'Assemblée nationale fournissant des outils de simulations fiscales, financières et sociales à destination des députés, administrateurs et collaborateurs. Ils sont accessibles via l'URL [https://leximpact.an.fr](https://leximpact.an.fr). -Ce dépôt contient le code du *front*. Les technologies principalement utilisées sont TypeScript, redux et React (Next.js). +Ce dépôt contient le code du *front*. Les technologies principalement utilisées sont TypeScript, [redux](https://redux.js.org), React ([Next.js](https://nextjs.org)) et [Sass](https://sass-lang.com) pour le style.  @@ -50,6 +50,17 @@ npm run start ## Structure des fichiers +Le code source comprend les codes des applications `ir` et `dotations` ainsi que du portail en place jusqu'en 2021 et désormais remplacé en production par [leximpact-portail](https://git.leximpact.dev/leximpact/leximpact-portail). + +Le point d'entrée est situé à la racine du dépôt : `server.js` + +Par ailleurs, les principaux répertoires sont : +* `components/` les composants graphiques (structure, logique, style et test) +* `pages/` les pages principales (où `/home` comprend les éléments de la page d'accueil de l'année 2020) +* `public/` les données statiques +* `redux/` les éléments de gestion des états Redux (pour en savoir plus, voici une documentation [Redux Fundamentals...: State, Actions, and Reducers](https://redux.js.org/tutorials/fundamentals/part-3-state-actions-reducers)) +* `styles/` les éléments de style paratagés + ### Organisation des composants ```bash @@ -64,6 +75,8 @@ npm run start - ... # Composants spécifiques à la page ... ``` +> Quelques utilitaires comme les requêtes à l'API Web et le suivi Matomo sont aussi présents dans `components/common/utils/`. + ### Organisation de l'état de l'application  diff --git a/README_PLF.md b/README_PLF.md new file mode 100644 index 0000000000000000000000000000000000000000..f03c8c488673ffe217eff2030e4aba9973bd6f36 --- /dev/null +++ b/README_PLF.md @@ -0,0 +1,126 @@ +# Activation & Désactivation du mode PLF + +Pour l'[application IR](http://leximpact.an.fr/ir) et l'[application dotations](http://leximpact.an.fr/dotations), il est possible d'activer un mode où, en plus de la loi en vigueur, un Projet de Loi de Finances (PLF) sert de base aux calculs d'amendements. + +Cette documentation présente les éléments à mettre à jour pour activer et désactiver le mode `PLF`. + +> ⚠️ Cette documentation n'est pas exhaustive et s'apparente à ce stade à une prise de notes. + +## Logique d'activation & désactivation du PLF + +`leximpact-client` échange par API Web avec `leximpact-server`. + +Les deux dépôts `leximpact-client` et `leximpact-server` disposent d'éléments de configuration qui déterminent l'état initial de ces applications. + +Néanmoins, pour le couple `leximpact-client`+`leximpact-server` la logique générale veut que ce soit le client qui sache si le PLF est activé. +> Aux débuts de ces applications (pré-PLF 2021), l'activation du PLF était décidée par `leximpact-server`. + +TODO Vérifier si le client détermine l'application du PLF d'après la première requête cas type ou si ce comportement est désactivé. + +## Contexte métier + +`leximpact-client` connaît potentiellement 3 lois : +* la loi en vigueur, dite `base` dans l'état de l'application, `avant` dans les requêtes à l'API Web, +* la loi réformée par un usager de l'application, dite `amendement` dans l'état de l'application, `apres` dans les requêtes à l'API Web, +* et, lorque le PLF est activé, la loi réformée par un PLF, dite `plf` dans l'état de l'application et les requêtes à l'API Web. + +Pour l'[application IR](http://leximpact.an.fr/ir), nous effectuons des calculs sur cas type et population. + +### Calcul sur cas types + +Au démarrage de l'application, une requête http://localhost:5000/metadata/description_cas_types est transmise (`onInitializeCasTypes` redux state ? => SIMULATE_CAS_TYPES_REQUEST => SIMULATE_CAS_TYPES_FAILURE) + +Un clic sue "ESTIMER CAS TYPES" produit une requête http://localhost:5000/calculate/compare +redux/actions/simulations/simulate-cas-types.ts + +Les cas types de l'usager sont sauvegardés sur son navigateur (cookies). + +🔥 CartesImpact props, extrait d'un print des props dans la console : +```js +{casTypes: Array(6), isInformationPanelVisible: true, isUserLogged: false, dispatch: ƒ} +casTypes: Array(6) +0: + declarants: Array(1) + 0: {ancienCombattant: false, invalide: false, parentIsole: false, retraite: false, veuf: false, …} + length: 1 + [[Prototype]]: Array(0) + name: "Foyer fiscal type" + personnesACharge: Array(0) + length: 0 + [[Prototype]]: Array(0) + residence: "metropole" + revenuImposable: 15584 +``` + +Et, du state aux properties d'une SimpleCard : components/ir/cartes-impact/simple-card/index.ts + +La zone impact d'une carte de cas type (bas de la carte) : components/ir/cartes-impact/simple-card/impact-impots.tsx - SimpleCardImpactImpots + +Reducers dédiés : redux/reducers/results +Calcul d'une requête : redux/actions/simulations/simulate-cas-types.ts + +### Calcul sur population + +Avant, cela était défini dans redux/reducers/results/total-pop.ts +Maintenant, c'est récupéré de la requête au serveur lorsque celui-ci a le PLF activé. + + +### Désactivation du PLF + +Pour désactiver le PLF, contrairement à `leximpact-server`, pour `lex-impact-client` le `.env` de l'application reste inchangé. + +Mais pour l'IR, il s'agit de : +* Mettre à jour l'état par défaut `BASE_IR_DEFAULT_STATE` défini dans `./redux/reducers/parameters/base/ir.ts` +* Vérifier la cohérence des montants sur les déciles de population définis dans `redux/reducers/results/total-pop.ts` +* S'assurer de la cohérence du message d'information sur la carte budget `components/ir/cartes-impact/carte-etat/CarteEtat.tsx` +* Mettre à jour le reducer en cas de `SIMULATE_CAS_TYPES_SUCCESS` défini dans `redux/reducers/results/plf/ir.ts` + +### Activation du PLF + +Pour activer le PLF, contrairement à `leximpact-server`, pour `lex-impact-client` le `.env` de l'application reste inchangé. + +Mais pour l'IR, il s'agit de : +* Mettre à jour l'état présentant le PLF `PLF_IR_DEFAULT_STATE` défini dans `redux/reducers/parameters/plf/ir.ts` et qui diffère désormais de `BASE_IR_DEFAULT_STATE` +* Vérifier la cohérence des montants sur les déciles de population définis dans `redux/reducers/results/total-pop.ts` +* S'assurer de la cohérence du message d'information sur la carte budget `components/ir/cartes-impact/carte-etat/CarteEtat.tsx` +* Mettre à jour le reducer en cas de `SIMULATE_CAS_TYPES_SUCCESS` défini dans `redux/reducers/results/plf/ir.ts` + +## Debug + +Un principe directeur de l'application est que l'interface graphique affichée dépend d'un état de l'application. Cet état est décrit dans [cette section du README](https://git.leximpact.dev/leximpact/leximpact-client/-/blob/master/README.md#organisation-de-létat-de-lapplication). + + +Le RootState est l'interface de l'état global redux. Elle est déduite des réduceurs. De cette manière, on peut déduire des bugs en amont en l'utilisant à chaque fois dans les mapStateToProps. ([src](https://github.com/leximpact/leximpact-client/pull/46)) + +Le root state est défini ici : redux/reducers/index.ts +L'état est construit ici : redux/make-application-state.ts + +Les interfaces des états redux se situent maintenant dans le dossier `./redux/reducers/` avec leur réduceur associé ([src](https://github.com/leximpact/leximpact-client/pull/46)). = Les interfaces d'action se situent maintenant conjointement avec leur fonction créatrice. + +Le format de ce state est défini ici (selon la partie gauche, la réforme paramétrique) : redux/reducers/parameters/interfaces/ir-state.ts +Interface total-pop : redux/reducers/results/total-pop.ts + +L'arborescence des états de l'application est contenue dans un store ([en savoir plus sur un Redux store](https://redux.js.org/api/store)) + +Des outils de développement facilitent grandement le debug de l'application comme : +* React via React Developer Tools [plugin chrome](https://chrome.google.com/webstore/detail/react-developer-tools/fmkadmapgofadopljbjfkapdkoienihi) +* Redux via Redux DevTools [plugin chrome](https://chrome.google.com/webstore/detail/redux-devtools/lmhkpmbekcpmknklioeibfkpmmfibljd?hl=fr) pour suivre l'évolution de l'état de l'application + +> Pour accéder aux calculs sur population, en local, prendre l'URL /connection/token et l'ajouter à [localhost](http://localhost:9001/) (sans `ir/`) + +### FAQ développement + +#### Bug des tirets - Sur les cas types, pourquoi les valeurs sont-elles remplacées par des tirets ? + +Au chargement de l'interface IR, l'impôt et le nombre de parts des cas types n'est pas représenté par un nombre mais par un `-`. +Ceci intervient dans le composant components/common/articles-inputs/values/Values.tsx + +Lorsque le PLF est désactivé du côté de leximpact-server seulement alors, on passe de : +`SimpleCardImpactImpots props {index: 5, amendement: 690, base: 756, isFetching: false, plf: 690, …}` +à `SimpleCardImpactImpots props {index: 5, amendement: undefined, base: undefined, isFetching: true, plf: undefined, …}`. + +Ceci serait lié à la présence du `PLF_PATH` seulement. Le client nécessiterait toujours la présence du PLF pour fonctionner (ou une modification de son code). Ceci est en partie apparu avec [cette PR](https://github.com/leximpact/leximpact-client/pull/104). + +#### Bug npm run dev - En mode dev ma modification n'est pas visible, que faire ? + +Si une modification du code source n'entraîne pas de changement dans l'interface en mode développement, il s'agit d'une situation déjà rencontrée. Relancer le `npm run dev`. diff --git a/components/common/simulation-page/SimulationPage.tsx b/components/common/simulation-page/SimulationPage.tsx index 2998f5580040b495c8db0c4b4a3c4c66a0f347c1..75cf6a0b611b0422c64cb64568db25ebb60beafe 100644 --- a/components/common/simulation-page/SimulationPage.tsx +++ b/components/common/simulation-page/SimulationPage.tsx @@ -63,6 +63,7 @@ export class SimulationPage extends PureComponent<Props, State> { <SimulationMenuBar primaryButtons={primaryButtons} secondaryButtons={secondaryButtons} + topic={topic} /> {results} </div> @@ -101,7 +102,9 @@ export class SimulationPage extends PureComponent<Props, State> { <div style={{ padding: 24 }}> <SimulationMenuBar primaryButtons={primaryButtons} - secondaryButtons={secondaryButtons} /> + secondaryButtons={secondaryButtons} + topic={topic} + /> {results} </div> </SwipeableViews> diff --git a/components/common/simulation-page/article-header/ArticleHeader.tsx b/components/common/simulation-page/article-header/ArticleHeader.tsx index 088775733ab3f8cc9e10263b75d3c7c51c99b349..99f55cd21dbb276a7154c63e74c62a7e322f914e 100644 --- a/components/common/simulation-page/article-header/ArticleHeader.tsx +++ b/components/common/simulation-page/article-header/ArticleHeader.tsx @@ -15,9 +15,20 @@ import styles from "./ArticleHeader.module.scss"; type Props = { topic: keyof ParametersState; + // "impot_revenu" | "dotations" + // Cf. redux/reducers/parameters/interfaces/index.ts } -const mapStateToProps = ({ parameters }: RootState) => ({ displayPLF: !!parameters.plf }); +// Met à jour les props d'après l'état de l'application IR ou dotations +const mapStateToProps = ({ parameters }: RootState, ownProps: Props) => ( + { displayPLF: ( + !!parameters.plf + && ( + JSON.stringify(parameters.plf[ownProps.topic]) !== JSON.stringify(parameters.base[ownProps.topic]) + ) + ) + } +); const mapDispatchToProps = (dispatch, ownProps: Props) => ({ resetAmendementToBase: () => dispatch(resetAmendementToBase(ownProps.topic)), diff --git a/components/common/simulation-page/simulation-menu/SimulationMenuBar.tsx b/components/common/simulation-page/simulation-menu/SimulationMenuBar.tsx index c4b5f363c1a5f0d4f3a89ad54cd8856ec20531fd..f937a251cea37d47de7a3cb27827ccf670d0caf8 100644 --- a/components/common/simulation-page/simulation-menu/SimulationMenuBar.tsx +++ b/components/common/simulation-page/simulation-menu/SimulationMenuBar.tsx @@ -9,9 +9,12 @@ import { Button } from "./button"; import { Legende } from "./legende"; import styles from "./SimulationMenuBar.module.scss"; -const mapStateToProps = ({ parameters }, { width }) => { +const mapStateToProps = ({ parameters }, { topic, width}) => { const isMobileView = width === "xs" || width === "sm" || width === "md"; - const montrerPLF = !!parameters.plf; + const montrerPLF = ( + !!parameters.plf + && ( JSON.stringify(parameters.plf[topic]) !== JSON.stringify(parameters.base[topic]) ) + ); return { isMobileView, montrerPLF, @@ -34,6 +37,9 @@ type Props = PropsFromRedux & { mobileCaption: string; mobileIcon?: JSX.Element; }[], + topic: string, + // topic = "impot_revenu" | "dotations" + // Cf. redux/reducers/parameters/interfaces/index.ts } class SimulationMenuBar extends PureComponent<Props> { @@ -43,6 +49,7 @@ class SimulationMenuBar extends PureComponent<Props> { montrerPLF, primaryButtons, secondaryButtons, + topic, } = this.props; return ( <Grid diff --git a/components/ir/cartes-impact/carte-etat/CarteEtat.tsx b/components/ir/cartes-impact/carte-etat/CarteEtat.tsx index 51344658e0b969d5df787c32fc5d2abc9075cab3..f3f20cc791dac45bcd4960b0fd508788075c1dc9 100644 --- a/components/ir/cartes-impact/carte-etat/CarteEtat.tsx +++ b/components/ir/cartes-impact/carte-etat/CarteEtat.tsx @@ -72,15 +72,16 @@ class CarteEtat extends PureComponent<PropsFromRedux> { <Card content1={( <Fragment> - <div className={styles.explicationPLF2022}> - <span className={styles.bold}>⚠️ Interpréter les résultats ci-dessous :</span> - <br /> - <ul> - <li>La réforme de l'IR du PLF 2022 se résume à une revalorisation par l'inflation, <span className={styles.bold}>sans changements du mécanisme de calcul</span>.</li> - <li>L'augmentation du montant total des recettes visible ci-dessous correspond à la <span className={styles.bold}>"dynamique économique" actuelle telle qu'évaluée par le PLF 2022 (p.15)</span>, traduite par une augmentation de la masse totale des revenus imposés.</li> - <li>En l'absence d'autres éléments nous traduisons cela par une augmentation de l'impôt sur les foyers déjà imposables.</li> - </ul> - </div> + {!isDisabledEtat && !isLoadingEtat && ( + <div className={styles.explicationPLF2022}> + <span className={styles.bold}>⚠️ Interpréter les résultats ci-dessous :</span> + <br /> + <ul> + <li>Les recettes présentées sont des estimations de recette d'impôt net sur le revenu.*</li> + <li>82.4 Md€ est la recette d'impôt net sur le revenu pour 2022 tel qu'évaluée par le <a href="https://www.economie.gouv.fr/files/2021-09/PLF_2022.PDF#page=13">PLF 2022</a>.</li> + </ul> + </div> + )} {isDisabledEtat && ( <div> <div className={`${styles.buttonPosition} ${styles.center}`}> diff --git a/redux/reducers/parameters/base/ir.ts b/redux/reducers/parameters/base/ir.ts index 3b3b9db3aeb7be74b6745c8b860f44d50390a7d3..ab13e77c00f706ab39b635e3cd216c79a439ab02 100644 --- a/redux/reducers/parameters/base/ir.ts +++ b/redux/reducers/parameters/base/ir.ts @@ -2,9 +2,9 @@ import { IRState } from "../interfaces"; export const BASE_IR_DEFAULT_STATE: IRState = { - // Base = 2021 + // Base = 2022 bareme: { - seuils: [10084, 25710, 73516, 158122], + seuils: [10225, 26070, 74545, 160336], taux: [11, 30, 41, 45], }, calculNombreParts: { @@ -44,8 +44,8 @@ export const BASE_IR_DEFAULT_STATE: IRState = { ], }, decote: { - seuil_celib: 779, - seuil_couple: 1289, + seuil_celib: 790, + seuil_couple: 1307, taux: 45.25, }, plafond_qf: { @@ -55,11 +55,11 @@ export const BASE_IR_DEFAULT_STATE: IRState = { taux_GuadMarReu: 30, taux_GuyMay: 40, }, - celib: 938, - celib_enf: 3704, - maries_ou_pacses: 1570, - reduc_postplafond: 1565, - reduc_postplafond_veuf: 1748, + celib: 951, + celib_enf: 3756, + maries_ou_pacses: 1592, + reduc_postplafond: 1587, + reduc_postplafond_veuf: 1772, }, }; diff --git a/redux/reducers/parameters/plf/ir.ts b/redux/reducers/parameters/plf/ir.ts index 86f8645eb9abbce0643d3ea53bbbf35bdcec28cb..e5dd4a09295f0bf080d136199072290cd3fc2fab 100644 --- a/redux/reducers/parameters/plf/ir.ts +++ b/redux/reducers/parameters/plf/ir.ts @@ -2,7 +2,8 @@ import { IRState } from "../interfaces"; export const PLF_IR_DEFAULT_STATE: IRState = { - // PLF = 2022 + // PLF 2022 désactivé tant que égal à la loi en vigueur + // dans : redux/reducers/parameters/base/ir.ts bareme: { seuils: [10225, 26070, 74545, 160336], taux: [11, 30, 41, 45], diff --git a/redux/reducers/results/plf/ir.ts b/redux/reducers/results/plf/ir.ts index d6337ba3c46c69c69ae162a94617b6737b831045..f5d56bcb454b2b3152e4830b78c00b413512d831 100644 --- a/redux/reducers/results/plf/ir.ts +++ b/redux/reducers/results/plf/ir.ts @@ -29,7 +29,10 @@ export function ir( return { isFetching: false, state: { - casTypes: convertCasTypes(action.data, "plf"), + //With PLF: + //casTypes: convertCasTypes(action.data, "plf"), + //Without PLF: + casTypes: convertCasTypes(action.data, "avant"), }, }; case "REMOVE_CAS_TYPE": diff --git a/redux/reducers/results/total-pop.ts b/redux/reducers/results/total-pop.ts index 32b7ca13f61946eabb5293dedf98bd9f96ffcfe7..f3a2b86542e7dfdbdd6aaa5c843d4858f34158e7 100644 --- a/redux/reducers/results/total-pop.ts +++ b/redux/reducers/results/total-pop.ts @@ -1,6 +1,13 @@ /* eslint-disable camelcase */ import { get } from "lodash"; -/* XXX Recopier le résultat de l'API */ +/** + To update the DEFAULT_STATE below, use leximpact-server Web API response + as its format should be identical to the State interface below: + * if the "base" (= "avant") law is updated, set the compulsory attributes of the State interface to Web API values, + * if the "plf" is activated, add all the "plf" optional attributes of the State interface + and set them to Web API values. + * and do not set any "apres" attribute as the DEFAULT_STATE should NOT include any "amendement". +*/ interface State { deciles: { sum_rfr: number; @@ -21,8 +28,6 @@ interface State { avg_irpp_apres?: number; irpp_on_rfr_apres?: number; avg_irpp_on_avg_rfr_apres?: number; - - }[]; foyersFiscauxTouches: { avant_to_plf?: { @@ -31,21 +36,21 @@ interface State { gagnant?: number; perdant?: number; perdant_zero?: number; - } + }; avant_to_apres?: { neutre?: number; neutre_zero?: number; gagnant?: number; perdant?: number; perdant_zero?: number; - } + }; plf_to_apres?: { neutre?: number; neutre_zero?: number; gagnant?: number; perdant?: number; perdant_zero?: number; - } + }; }; frontieresDeciles: number[]; total: { @@ -56,190 +61,131 @@ interface State { } const DEFAULT_STATE: State = { - deciles: [ { - "sum_rfr": 1248595294.3250895, - "avg_rfr": 325.6424932857625, - "poids": 3834251.733324631, - "avant": 0, - "sum_irpp_avant": 0, - "avg_irpp_avant": 0, - "irpp_on_rfr_avant": 0, - "avg_irpp_on_avg_rfr_avant": 0, - "apres": 0, - "sum_irpp_apres": 0, - "avg_irpp_apres": 0, - "irpp_on_rfr_apres": 0, - "avg_irpp_on_avg_rfr_apres": 0, + sum_rfr: 1248595294.3250895, + avg_rfr: 325.6424932857625, + poids: 3834251.733324631, + avant: 0, + sum_irpp_avant: 0, + avg_irpp_avant: 0, + irpp_on_rfr_avant: 0, + avg_irpp_on_avg_rfr_avant: 0, }, { - "sum_rfr": 23436330862.321556, - "avg_rfr": 6114.03411542516, - "poids": 3833202.5009795064, - "avant": 0, - "sum_irpp_avant": 0, - "avg_irpp_avant": 0, - "irpp_on_rfr_avant": 0, - "avg_irpp_on_avg_rfr_avant": 0, - "apres": 0, - "sum_irpp_apres": 0, - "avg_irpp_apres": 0, - "irpp_on_rfr_apres": 0, - "avg_irpp_on_avg_rfr_apres": 0, + sum_rfr: 23436330862.321556, + avg_rfr: 6114.03411542516, + poids: 3833202.5009795064, + avant: 0, + sum_irpp_avant: 0, + avg_irpp_avant: 0, + irpp_on_rfr_avant: 0, + avg_irpp_on_avg_rfr_avant: 0, }, { - "sum_rfr": 43302552094.83705, - "avg_rfr": 11298.140156590667, - "poids": 3832715.074753033, - "avant": 0, - "sum_irpp_avant": 0, - "avg_irpp_avant": 0, - "irpp_on_rfr_avant": 0, - "avg_irpp_on_avg_rfr_avant": 0, - "apres": 0, - "sum_irpp_apres": 0, - "avg_irpp_apres": 0, - "irpp_on_rfr_apres": 0, - "avg_irpp_on_avg_rfr_apres": 0, + sum_rfr: 43302552094.83705, + avg_rfr: 11298.140156590667, + poids: 3832715.074753033, + avant: 0, + sum_irpp_avant: 0, + avg_irpp_avant: 0, + irpp_on_rfr_avant: 0, + avg_irpp_on_avg_rfr_avant: 0, }, { - "sum_rfr": 59109327425.504074, - "avg_rfr": 15420.218819854104, - "poids": 3833235.320201719, - "avant": 185851978.16184786, - "sum_irpp_avant": 185851978.16184786, - "avg_irpp_avant": 48.48436441727962, - "irpp_on_rfr_avant": 0.003144207289383871, - "avg_irpp_on_avg_rfr_avant": 0.0031442072893838706, - "apres": 163391066.7322619, - "sum_irpp_apres": 163391066.7322619, - "avg_irpp_apres": 42.62484639833265, - "irpp_on_rfr_apres": 0.002764217998220076, - "avg_irpp_on_avg_rfr_apres": 0.002764217998220076, + sum_rfr: 59109327425.504074, + avg_rfr: 15420.218819854104, + poids: 3833235.320201719, + avant: 163391066.7322619, + sum_irpp_avant: 163391066.7322619, + avg_irpp_avant: 42.62484639833265, + irpp_on_rfr_avant: 0.002764217998220076, + avg_irpp_on_avg_rfr_avant: 0.002764217998220076, }, { - "sum_rfr": 72143223721.7203, - "avg_rfr": 18819.276995759777, - "poids": 3833474.7789712735, - "avant": 921462479.5895522, - "sum_irpp_avant": 921462479.5895522, - "avg_irpp_avant": 240.37264693751766, - "irpp_on_rfr_avant": 0.012772682340117351, - "avg_irpp_on_avg_rfr_avant": 0.012772682340117353, - "apres": 944751019.7222807, - "sum_irpp_apres": 944751019.7222807, - "avg_irpp_apres": 246.4476941141624, - "irpp_on_rfr_apres": 0.013095492147211086, - "avg_irpp_on_avg_rfr_apres": 0.013095492147211086, + sum_rfr: 72143223721.7203, + avg_rfr: 18819.276995759777, + poids: 3833474.7789712735, + avant: 944751019.7222807, + sum_irpp_avant: 944751019.7222807, + avg_irpp_avant: 246.4476941141624, + irpp_on_rfr_avant: 0.013095492147211086, + avg_irpp_on_avg_rfr_avant: 0.013095492147211086, }, { - "sum_rfr": 87683818162.51213, - "avg_rfr": 22873.391349911217, - "poids": 3833441.959749177, - "avant": 1617616912.5847774, - "sum_irpp_avant": 1617616912.5847774, - "avg_irpp_avant": 421.9750630294255, - "irpp_on_rfr_avant": 0.018448294639573128, - "avg_irpp_on_avg_rfr_avant": 0.018448294639573128, - "apres": 1703341992.9176059, - "sum_irpp_apres": 1703341992.9176059, - "avg_irpp_apres": 444.3374937725895, - "irpp_on_rfr_apres": 0.019425955992936488, - "avg_irpp_on_avg_rfr_apres": 0.01942595599293649, + sum_rfr: 87683818162.51213, + avg_rfr: 22873.391349911217, + poids: 3833441.959749177, + avant: 1703341992.9176059, + sum_irpp_avant: 1703341992.9176059, + avg_irpp_avant: 444.3374937725895, + irpp_on_rfr_avant: 0.019425955992936488, + avg_irpp_on_avg_rfr_avant: 0.01942595599293649, }, { - "sum_rfr": 110115965949.4268, - "avg_rfr": 28726.174096337054, - "poids": 3833297.3120660484, - "avant": 2923222966.9631305, - "sum_irpp_avant": 2923222966.9631305, - "avg_irpp_avant": 762.5870703432805, - "irpp_on_rfr_avant": 0.026546767689489145, - "avg_irpp_on_avg_rfr_avant": 0.026546767689489145, - "apres": 3031830109.6376085, - "sum_irpp_apres": 3031830109.6376085, - "avg_irpp_apres": 790.919634669199, - "irpp_on_rfr_apres": 0.02753306555953969, - "avg_irpp_on_avg_rfr_apres": 0.027533065559539695, + sum_rfr: 110115965949.4268, + avg_rfr: 28726.174096337054, + poids: 3833297.3120660484, + avant: 3031830109.6376085, + sum_irpp_avant: 3031830109.6376085, + avg_irpp_avant: 790.919634669199, + irpp_on_rfr_avant: 0.02753306555953969, + avg_irpp_on_avg_rfr_avant: 0.027533065559539695, }, { - "sum_rfr": 137184876883.36745, - "avg_rfr": 35787.99053345202, - "poids": 3833265.708370462, - "avant": 5622143411.826297, - "sum_irpp_avant": 5622143411.826297, - "avg_irpp_avant": 1466.6719814255537, - "irpp_on_rfr_avant": 0.04098223900150568, - "avg_irpp_on_avg_rfr_avant": 0.04098223900150568, - "apres": 5920010075.927875, - "sum_irpp_apres": 5920010075.927875, - "avg_irpp_apres": 1544.3776994119555, - "irpp_on_rfr_apres": 0.04315351816046735, - "avg_irpp_on_avg_rfr_apres": 0.04315351816046735, + sum_rfr: 137184876883.36745, + avg_rfr: 35787.99053345202, + poids: 3833265.708370462, + avant: 5920010075.927875, + sum_irpp_avant: 5920010075.927875, + avg_irpp_avant: 1544.3776994119555, + irpp_on_rfr_avant: 0.04315351816046735, + avg_irpp_on_avg_rfr_avant: 0.04315351816046735, }, { - "sum_rfr": 179011128573.3233, - "avg_rfr": 46701.02290233606, - "poids": 3833130.7849014252, - "avant": 10402662676.661081, - "sum_irpp_avant": 10402662676.661081, - "avg_irpp_avant": 2713.8814875916214, - "irpp_on_rfr_avant": 0.05811182108938066, - "avg_irpp_on_avg_rfr_avant": 0.05811182108938065, - "apres": 11081534982.670897, - "sum_irpp_apres": 11081534982.670897, - "avg_irpp_apres": 2890.98796897856, - "irpp_on_rfr_apres": 0.061904168031273424, - "avg_irpp_on_avg_rfr_apres": 0.061904168031273424, + sum_rfr: 179011128573.3233, + avg_rfr: 46701.02290233606, + poids: 3833130.7849014252, + avant: 11081534982.670897, + sum_irpp_avant: 11081534982.670897, + avg_irpp_avant: 2890.98796897856, + irpp_on_rfr_avant: 0.061904168031273424, + avg_irpp_on_avg_rfr_avant: 0.061904168031273424, }, { - "sum_rfr": 379094672499.9683, - "avg_rfr": 98903.84763576475, - "poids": 3832961.8266832978, - "avant": 55327039574.21336, - "sum_irpp_avant": 55327039574.21336, - "avg_irpp_avant": 14434.539678703562, - "irpp_on_rfr_avant": 0.14594517830956324, - "avg_irpp_on_avg_rfr_avant": 0.14594517830956327, - "apres": 59557996094.47585, - "sum_irpp_apres": 59557996094.47585, - "avg_irpp_apres": 15538.374444499754, - "irpp_on_rfr_apres": 0.15710586408855648, - "avg_irpp_on_avg_rfr_apres": 0.15710586408855648, - } + sum_rfr: 379094672499.9683, + avg_rfr: 98903.84763576475, + poids: 3832961.8266832978, + avant: 59557996094.47585, + sum_irpp_avant: 59557996094.47585, + avg_irpp_avant: 15538.374444499754, + irpp_on_rfr_avant: 0.15710586408855648, + avg_irpp_on_avg_rfr_avant: 0.15710586408855648, + }, ], - foyersFiscauxTouches: { - avant_to_apres: { - neutre_zero: 19925525, gagnant: 18407452, - }, - avant_to_plf: { - gagnant: 18407452, - neutre_zero: 19925525, - }, - }, + foyersFiscauxTouches: {}, frontieresDeciles: [ - 2350.426513671875, 8942.0009765625, 12885.66796875, 16710.77734375, 20210.9921875, 25134.4453125, 31086.5, 39143.7265625, 54232.7890625, 8527243 + 2350.426513671875, 8942.0009765625, 12885.66796875, 16710.77734375, + 20210.9921875, 25134.4453125, 31086.5, 39143.7265625, 54232.7890625, + 8527243, ], total: { - avant: 77000000000.00001, - plf: 82400000000.193146, + avant: 82400000000.00001, }, }; - const totalPop = (state: State = DEFAULT_STATE, action): State => { switch (action.type) { - case "onSimPopFetchResult": - return { - deciles: get(action, "data.deciles"), - foyersFiscauxTouches: get(action, "data.foyers_fiscaux_touches"), - frontieresDeciles: get(action, "data.frontieres_deciles"), - total: get(action, "data.total"), - }; - default: - return state; + case "onSimPopFetchResult": + return { + deciles: get(action, "data.deciles"), + foyersFiscauxTouches: get(action, "data.foyers_fiscaux_touches"), + frontieresDeciles: get(action, "data.frontieres_deciles"), + total: get(action, "data.total"), + }; + default: + return state; } };