From 353c1ef6ba81d0d5957778e3c2c91abd7c990860 Mon Sep 17 00:00:00 2001
From: clallemand <=>
Date: Tue, 21 Jan 2025 10:26:57 +0100
Subject: [PATCH] initialise_leximpact_france

initialise_leximpact_france
---
 .../leximpact_france/__init__.py              |  86 +++
 .../leximpact_france/baremisation_csg_crds.py | 147 ++++
 .../parameters/deciles_niveau_de_vie.yaml     | 172 +++++
 .../refacto_super_brut_to_disponible.py       | 642 ++++++++++++++++++
 4 files changed, 1047 insertions(+)
 create mode 100644 openfisca_france_reforms/leximpact_france/__init__.py
 create mode 100644 openfisca_france_reforms/leximpact_france/baremisation_csg_crds.py
 create mode 100644 openfisca_france_reforms/leximpact_france/parameters/deciles_niveau_de_vie.yaml
 create mode 100644 openfisca_france_reforms/leximpact_france/refacto_super_brut_to_disponible.py

diff --git a/openfisca_france_reforms/leximpact_france/__init__.py b/openfisca_france_reforms/leximpact_france/__init__.py
new file mode 100644
index 00000000..1ecaa826
--- /dev/null
+++ b/openfisca_france_reforms/leximpact_france/__init__.py
@@ -0,0 +1,86 @@
+import os
+from openfisca_core.reforms import Reform
+from openfisca_core.parameters import ParameterNode
+from openfisca_france_reforms.leximpact_france.baremisation_csg_crds import (
+    csg_deductible_salaire,
+    csg_imposable_salaire,
+    crds_salaire,
+    csg_imposable_non_salarie,
+    csg_deductible_non_salarie,
+    crds_non_salarie
+    )
+from openfisca_france_reforms.leximpact_france.refacto_super_brut_to_disponible import (
+    autres_impositions_forfaitaires,
+    cotisations_allegement_general,
+    cotisations_employeur_assurance_chomage,
+    cotisations_employeur_autres,
+    cotisations_employeur_retraite_complementaire,
+    cotisations_employeur_securite_sociale,
+    cotisations_salariales_contributives,
+    csg,
+    csg_chomage,
+    csg_non_salarie,
+    csg_retraite,
+    csg_salaire,
+    irpp_economique,
+    minima_sociaux,
+    pensions_rentes_complementaires,
+    primes,
+    remuneration_brute,
+    revenu_disponible,
+    revenus_du_capital_avant_prelevements,
+    revenus_nets_apres_impot_menage,
+    revenus_nets_menage,
+    salaire_super_brut,
+    vieillesse_employeur,
+    vieillesse_salarie
+    )
+
+def modify_parameters(parameters):
+    deciles_niveau_vie = ParameterNode(
+        "deciles_niveau_de_vie",
+        directory_path=os.path.join(os.path.dirname(__file__), "parameters/deciles_niveau_de_vie"),
+    )
+    parameters.add_child("deciles_niveau_de_vie", deciles_niveau_vie)
+
+
+class LexImpactTaxBenefitSystem(Reform):
+    name = "PLF & PLFSS 2025"
+    tax_benefit_system_name = "openfisca_france_with_indirect_taxation"
+
+    def apply(self):
+        self.modify_parameters(modifier_function=modify_parameters)
+    
+        for variable in [
+            csg_deductible_salaire,
+            csg_imposable_salaire,
+            crds_salaire,
+            csg_imposable_non_salarie,
+            csg_deductible_non_salarie,
+            crds_non_salarie,
+            autres_impositions_forfaitaires,
+            cotisations_allegement_general,
+            cotisations_employeur_assurance_chomage,
+            cotisations_employeur_autres,
+            cotisations_employeur_retraite_complementaire,
+            cotisations_employeur_securite_sociale,
+            cotisations_salariales_contributives,
+            csg,
+            csg_chomage,
+            csg_non_salarie,
+            csg_retraite,
+            csg_salaire,
+            irpp_economique,
+            minima_sociaux,
+            pensions_rentes_complementaires,
+            primes,
+            remuneration_brute,
+            revenu_disponible,
+            revenus_du_capital_avant_prelevements,
+            revenus_nets_apres_impot_menage,
+            revenus_nets_menage,
+            salaire_super_brut,
+            vieillesse_employeur,
+            vieillesse_salarie
+            ]:
+            self.replace_variable(variable)
\ No newline at end of file
diff --git a/openfisca_france_reforms/leximpact_france/baremisation_csg_crds.py b/openfisca_france_reforms/leximpact_france/baremisation_csg_crds.py
new file mode 100644
index 00000000..cdb89e4d
--- /dev/null
+++ b/openfisca_france_reforms/leximpact_france/baremisation_csg_crds.py
@@ -0,0 +1,147 @@
+import logging
+
+from openfisca_france.model.base import *
+from openfisca_france.model.prelevements_obligatoires.prelevements_sociaux.contributions_sociales.base import montant_csg_crds_bareme
+
+
+log = logging.getLogger(__name__)
+
+# Dans ce fichier modification des variables de csg et de crds pour permettre la création d'un barème dans l'ui
+# Variables modifiees :
+## csg_deductible_salaire
+## csg_imposable_salaire
+## crds_salaire
+## csg_imposable_non_salarie
+## csg_deductible_non_salarie
+## crds_non_salarie
+
+
+class csg_deductible_salaire(Variable):
+    calculate_output = calculate_output_add
+    value_type = float
+    label = 'CSG déductible sur les salaires'
+    reference = 'https://www.legifrance.gouv.fr/codes/section_lc/LEGITEXT000006073189/LEGISCTA000006173055/#LEGIARTI000042340733'
+    entity = Individu
+    definition_period = MONTH
+    set_input = set_input_divide_by_period
+
+    def formula(individu, period, parameters):
+        assiette_csg_abattue = individu('assiette_csg_abattue', period)
+        assiette_csg_non_abattue = individu('assiette_csg_non_abattue', period)
+        plafond_securite_sociale = individu('plafond_securite_sociale', period)
+
+        csg = parameters(period).prelevements_sociaux.contributions_sociales.csg
+        montant_csg = montant_csg_crds_bareme(
+            base_avec_abattement = assiette_csg_abattue,
+            base_sans_abattement = assiette_csg_non_abattue,
+            abattement_parameter = csg.activite.abattement,
+            law_node = csg.activite.deductible,
+            plafond_securite_sociale = plafond_securite_sociale,
+            )
+        return montant_csg
+
+
+class csg_imposable_salaire(Variable):
+    calculate_output = calculate_output_add
+    value_type = float
+    label = 'CSG imposables sur les salaires'
+    entity = Individu
+    definition_period = MONTH
+    set_input = set_input_divide_by_period
+
+    def formula(individu, period, parameters):
+        assiette_csg_abattue = individu('assiette_csg_abattue', period)
+        assiette_csg_non_abattue = individu('assiette_csg_non_abattue', period)
+        plafond_securite_sociale = individu('plafond_securite_sociale', period)
+        csg_parameters = parameters(period).prelevements_sociaux.contributions_sociales.csg
+
+        montant_csg = montant_csg_crds_bareme(
+            base_avec_abattement = assiette_csg_abattue,
+            base_sans_abattement = assiette_csg_non_abattue,
+            abattement_parameter = csg_parameters.activite.abattement,
+            law_node = csg_parameters.activite.imposable,
+            plafond_securite_sociale = plafond_securite_sociale,
+            )
+
+        return montant_csg
+
+
+class crds_salaire(Variable):
+    calculate_output = calculate_output_add
+    value_type = float
+    label = 'CRDS sur les salaires'
+    entity = Individu
+    definition_period = MONTH
+    set_input = set_input_divide_by_period
+
+    def formula(individu, period, parameters):
+        assiette_csg_abattue = individu('assiette_csg_abattue', period)
+        assiette_csg_non_abattue = individu('assiette_csg_non_abattue', period)
+        plafond_securite_sociale = individu('plafond_securite_sociale', period)
+
+        parameters = parameters(period).prelevements_sociaux.contributions_sociales
+
+        montant_crds = montant_csg_crds_bareme(
+            law_node = parameters.crds,
+            base_avec_abattement = assiette_csg_abattue,
+            base_sans_abattement = assiette_csg_non_abattue,
+            abattement_parameter = parameters.csg.activite.abattement,
+            plafond_securite_sociale = plafond_securite_sociale,
+            )
+
+        return montant_crds
+
+
+class csg_imposable_non_salarie(Variable):
+    value_type = float
+    entity = Individu
+    label = 'CSG des personnes non salariées'
+    definition_period = YEAR
+
+    def formula(individu, period, parameters):
+        assiette_csg_crds_non_salarie = individu('assiette_csg_crds_non_salarie', period)
+        csg = parameters(period).prelevements_sociaux.contributions_sociales.csg.activite
+
+        montant_csg = montant_csg_crds_bareme(
+            base_sans_abattement = assiette_csg_crds_non_salarie,
+            law_node = csg.imposable,
+            )
+
+        return montant_csg
+
+
+class csg_deductible_non_salarie(Variable):
+    value_type = float
+    entity = Individu
+    label = 'CSG des personnes non salariées'
+    definition_period = YEAR
+
+    def formula(individu, period, parameters):
+        assiette_csg_crds_non_salarie = individu('assiette_csg_crds_non_salarie', period)
+        csg = parameters(period).prelevements_sociaux.contributions_sociales.csg.activite
+
+        montant_csg = montant_csg_crds_bareme(
+            base_sans_abattement = assiette_csg_crds_non_salarie,
+            law_node = csg.deductible,
+            )
+
+        return montant_csg
+
+
+class crds_non_salarie(Variable):
+    value_type = float
+    entity = Individu
+    label = 'CRDS des personnes non salariées'
+    definition_period = YEAR
+
+    def formula(individu, period, parameters):
+        assiette_csg_crds_non_salarie = individu('assiette_csg_crds_non_salarie', period)
+
+        law = parameters(period)
+
+        montant_crds = montant_csg_crds_bareme(
+            base_sans_abattement = assiette_csg_crds_non_salarie,
+            law_node = law.prelevements_sociaux.contributions_sociales.crds,
+            )
+
+        return montant_crds
diff --git a/openfisca_france_reforms/leximpact_france/parameters/deciles_niveau_de_vie.yaml b/openfisca_france_reforms/leximpact_france/parameters/deciles_niveau_de_vie.yaml
new file mode 100644
index 00000000..1d149811
--- /dev/null
+++ b/openfisca_france_reforms/leximpact_france/parameters/deciles_niveau_de_vie.yaml
@@ -0,0 +1,172 @@
+description: Déciles de niveau de vie, France métropolitaine, individus vivant dans un ménage ordinaire dont le revenu déclaré est positif ou null et dont la personne de référence n'est pas étudiante
+brackets:
+- threshold:
+    2017-01-01:
+      value: 11770
+    2018-01-01:
+      value: 11580
+    2019-01-01:
+      value: 11910
+    2020-01-01:
+      value: 12560
+    2021-01-01:
+      value: 12290
+    2024-01-01:
+      value: 13814
+  rate:
+    2017-01-01:
+      value: 1
+- threshold:
+    2017-01-01:
+      value: 14790
+    2018-01-01:
+      value: 14620
+    2019-01-01:
+      value: 15100
+    2020-01-01:
+      value: 15860
+    2021-01-01:
+      value: 15550
+    2024-01-01:
+      value: 17479
+  rate:
+    2017-01-01:
+      value: 2
+- threshold:
+    2017-01-01:
+      value: 17310
+    2018-01-01:
+      value: 17230
+    2019-01-01:
+      value: 17780
+    2020-01-01:
+      value: 18490
+    2021-01-01:
+      value: 18360
+    2024-01-01:
+      value: 20637
+  rate:
+    2017-01-01:
+      value: 3
+- threshold:
+    2017-01-01:
+      value: 19580
+    2018-01-01:
+      value: 19620
+    2019-01-01:
+      value: 20150
+    2020-01-01:
+      value: 20810
+    2021-01-01:
+      value: 20790
+    2024-01-01:
+      value: 23368
+  rate:
+    2017-01-01:
+      value: 4
+- threshold:
+    2017-01-01:
+      value: 21900
+    2018-01-01:
+      value: 21950
+    2019-01-01:
+      value: 22500
+    2020-01-01:
+      value: 23230
+    2021-01-01:
+      value: 23160
+    2024-01-01:
+      value: 26032
+  rate:
+    2017-01-01:
+      value: 5
+- threshold:
+    2017-01-01:
+      value: 24440
+    2018-01-01:
+      value: 24530
+    2019-01-01:
+      value: 25020
+    2020-01-01:
+      value: 25790
+    2021-01-01:
+      value: 25840
+    2024-01-01:
+      value: 29044
+  rate:
+    2017-01-01:
+      value: 6
+- threshold:
+    2017-01-01:
+      value: 27500
+    2018-01-01:
+      value: 27560
+    2019-01-01:
+      value: 28170
+    2020-01-01:
+      value: 28690
+    2021-01-01:
+      value: 28900
+    2024-01-01:
+      value: 32484
+  rate:
+    2017-01-01:
+      value: 7
+- threshold:
+    2017-01-01:
+      value: 31840
+    2018-01-01:
+      value: 31830
+    2019-01-01:
+      value: 32440
+    2020-01-01:
+      value: 32890
+    2021-01-01:
+      value: 33440
+    2024-01-01:
+      value: 37587
+  rate:
+    2017-01-01:
+      value: 8
+- threshold:
+    2017-01-01:
+      value: 40190
+    2018-01-01:
+      value: 40420
+    2019-01-01:
+      value: 40770
+    2020-01-01:
+      value: 41400
+    2021-01-01:
+      value: 41870
+    2024-01-01:
+      value: 47062
+  rate:
+    2017-01-01:
+      value: 9
+metadata:
+  short_label: déciles de niveau de vie
+  last_value_still_valid_on: "2024-04-22"
+  reference:
+    2017-01-01:
+      title: Distribution des niveaux de vie, données annuelles de 1996 à 2021, INSEE
+      href: https://www.insee.fr/fr/statistiques/2416808#tableau-figure1
+    2018-01-01:
+      title: Distribution des niveaux de vie, données annuelles de 1996 à 2021, INSEE
+      href: https://www.insee.fr/fr/statistiques/2416808#tableau-figure1
+    2019-01-01:
+      title: Distribution des niveaux de vie, données annuelles de 1996 à 2021, INSEE
+      href: https://www.insee.fr/fr/statistiques/2416808#tableau-figure1
+    2020-01-01:
+      title: Distribution des niveaux de vie, données annuelles de 1996 à 2021, INSEE
+      href: https://www.insee.fr/fr/statistiques/2416808#tableau-figure1
+    2021-01-01:
+      title: Distribution des niveaux de vie, données annuelles de 1996 à 2021, INSEE
+      href: https://www.insee.fr/fr/statistiques/2416808#tableau-figure1
+  notes:
+    2020-01-01: 
+    - title: données provisoires en date de avril 2024. Pour l'année 2020 deux séries sont présentées mais uniquement la deuxième est reportée ici.
+    2021-01-01: 
+    - title: données provisoires en date de avril 2024
+    2024-01-01:
+     - title: les valeurs 2024 sont des projections à partir des données 2021, dernière année connue. Les valeurs 2021 ont été augmentées de 12,4 % qui est l'évolution moyenne du SMPT économique cumulées pour les années 2022 (3,7%), 2023 (5.1%), 2024 (3.1%) telles que prévues dans le Rapport économique social et financier (RESF) attaché au PLF pour 2024, p54
\ No newline at end of file
diff --git a/openfisca_france_reforms/leximpact_france/refacto_super_brut_to_disponible.py b/openfisca_france_reforms/leximpact_france/refacto_super_brut_to_disponible.py
new file mode 100644
index 00000000..4a5ff4dd
--- /dev/null
+++ b/openfisca_france_reforms/leximpact_france/refacto_super_brut_to_disponible.py
@@ -0,0 +1,642 @@
+from openfisca_france.model.base import *
+
+
+# Dans ce fichier refactorisation de la décomposition du revenu disponible par rapport à openfisca france en fonction de ce qu'on veut afficher sur l'interface
+
+# Variables modifies :
+## autres_impositions_forfaitaires
+## cotisations_allegement_general
+## cotisations_employeur_assurance_chomage
+## cotisations_employeur_autres
+## cotisations_employeur_retraite_complementaire
+## cotisations_employeur_securite_sociale
+## cotisations_salariales_contributives
+## csg
+## csg_chomage
+## csg_non_salarie
+## csg_retraite
+## csg_salaire
+## irpp_economique
+## minima_sociaux
+## pensions_rentes_complementaires
+## primes
+## remuneration_brute
+## revenu_disponible
+## revenus_du_capital_avant_prelevements
+## revenus_nets_apres_impot_menage
+## revenus_nets_menage
+## salaire_super_brut
+## vieillesse_employeur
+## vieillesse_salarie
+
+class autres_impositions_forfaitaires(Variable):
+    value_type = float
+    entity = FoyerFiscal
+    label = 'Autres impositions forfaitaires'
+    definition_period = YEAR
+
+    def formula(foyer_fiscal, period, parameters):
+        # on déplace ici l'ir sur les plus values immo et le prelevement sur les micro pour plus de clarté sur la décomposition
+        ir_pv_immo = foyer_fiscal('ir_pv_immo', period)
+        prelevement_liberatoire_autoentrepreneur = foyer_fiscal('microsocial', period)
+        taxation_plus_values_hors_bareme = foyer_fiscal('taxation_plus_values_hors_bareme', period)
+        prelevement_forfaitaire_liberatoire = foyer_fiscal('prelevement_forfaitaire_liberatoire', period)
+        cont_rev_loc = foyer_fiscal('cont_rev_loc', period)
+        tax_rvcm_forfaitaire = foyer_fiscal('tax_rvcm_forfaitaire', period)
+        indemnite_compensatrice_agents_assurance = foyer_fiscal('indemnite_compensatrice_agents_assurance', period)
+
+        return (
+            ir_pv_immo
+            + prelevement_liberatoire_autoentrepreneur
+            + taxation_plus_values_hors_bareme
+            + prelevement_forfaitaire_liberatoire
+            + cont_rev_loc
+            + tax_rvcm_forfaitaire
+            + indemnite_compensatrice_agents_assurance
+            )
+
+
+class cotisations_allegement_general(Variable):
+    value_type = float
+    entity = Individu
+    label = 'Cotisations sociales employeur concernées par l allègement général'
+    set_input = set_input_divide_by_period
+    definition_period = MONTH
+    calculate_output = calculate_output_add
+
+    def formula_2019_01_01(individu, period, parameters):
+        agirc_arrco_employeur = individu('agirc_arrco_employeur', period)
+        chomage_employeur = individu('chomage_employeur', period)
+        contribution_equilibre_general_employeur = individu('contribution_equilibre_general_employeur', period)
+        vieillesse_deplafonnee_employeur = individu('vieillesse_deplafonnee_employeur', period, options = [ADD])
+        vieillesse_plafonnee_employeur = individu('vieillesse_plafonnee_employeur', period, options = [ADD])
+        accident_du_travail = individu('accident_du_travail', period, options = [ADD])
+        contribution_solidarite_autonomie = individu('contribution_solidarite_autonomie', period)
+        famille_net_allegement = individu('famille_net_allegement', period)
+        mmid_employeur_net_allegement = individu('mmid_employeur_net_allegement', period, options = [ADD])
+        fnal = individu('fnal', period, options = [ADD])
+
+        cotisations = (
+            agirc_arrco_employeur
+            + chomage_employeur
+            + contribution_equilibre_general_employeur
+            + vieillesse_deplafonnee_employeur
+            + vieillesse_plafonnee_employeur
+            + accident_du_travail
+            + contribution_solidarite_autonomie
+            + famille_net_allegement
+            + mmid_employeur_net_allegement
+            + fnal
+            )
+
+        return cotisations
+
+
+class cotisations_employeur_assurance_chomage(Variable):
+    value_type = float
+    entity = Individu
+    label = 'Cotisations employeur pour le chomage'
+    definition_period = MONTH
+    set_input = set_input_divide_by_period
+
+    def formula_2024_01_01(individu, period, parameters):
+        chomage_employeur = individu('chomage_employeur', period)
+        ags = individu('ags', period)
+
+        return (
+            chomage_employeur
+            + ags
+            )
+
+
+class cotisations_employeur_autres(Variable):
+    value_type = float
+    entity = Individu
+    label = 'Autres cotisations et contributions employeur'
+    definition_period = MONTH
+    set_input = set_input_divide_by_period
+
+    def formula_2024_01_01(individu, period, parameters):
+        conge_individuel_formation_cdd = individu('conge_individuel_formation_cdd', period)
+        contribution_supplementaire_apprentissage = individu('contribution_supplementaire_apprentissage', period)
+        financement_organisations_syndicales = individu('financement_organisations_syndicales', period)
+        taxe_salaires = individu('taxe_salaires', period)
+        forfait_social = individu('forfait_social', period)
+        participation_effort_construction = individu('participation_effort_construction', period)
+        prevoyance_obligatoire_cadre = individu('prevoyance_obligatoire_cadre', period)
+        complementaire_sante_employeur = individu('complementaire_sante_employeur', period)
+        versement_transport = individu('versement_transport', period)
+        contribution_unique_formation_professionnelle_alternance = individu('contribution_unique_formation_professionnelle_alternance', period)
+        fonds_emploi_hospitalier = individu('fonds_emploi_hospitalier', period)
+        ati_atiacl = individu('ati_atiacl', period)
+        fnal = individu('fnal', period)
+
+        return (
+            contribution_unique_formation_professionnelle_alternance
+            + conge_individuel_formation_cdd
+            + contribution_supplementaire_apprentissage
+            + versement_transport
+            + financement_organisations_syndicales
+            + fnal
+            + participation_effort_construction
+            + prevoyance_obligatoire_cadre
+            + complementaire_sante_employeur
+            + taxe_salaires
+            + forfait_social
+            + fonds_emploi_hospitalier
+            + ati_atiacl
+            )
+
+
+class cotisations_employeur_retraite_complementaire(Variable):
+    value_type = float
+    entity = Individu
+    label = 'Cotisations aux régimes complémentaires de retraite'
+    definition_period = MONTH
+    set_input = set_input_divide_by_period
+
+    def formula_2024_01_01(individu, period, parameters):
+        agirc_arrco_employeur = individu('agirc_arrco_employeur', period)
+        contribution_equilibre_general_employeur = individu('contribution_equilibre_general_employeur', period)
+        contribution_equilibre_technique_employeur = individu('contribution_equilibre_technique_employeur', period)
+        apec_employeur = individu('apec_employeur', period)
+        ircantec_employeur = individu('ircantec_employeur', period)
+
+        return (
+            agirc_arrco_employeur
+            + contribution_equilibre_general_employeur
+            + contribution_equilibre_technique_employeur
+            + apec_employeur
+            + ircantec_employeur
+            )
+
+
+class cotisations_employeur_securite_sociale(Variable):
+    value_type = float
+    entity = Individu
+    label = 'Cotisations et contributions du régime général de la sécurité sociale'
+    definition_period = MONTH
+    set_input = set_input_divide_by_period
+
+    def formula_2024_01_01(individu, period, parameters):
+        mmid_employeur_net_allegement = individu('mmid_employeur_net_allegement', period)
+        vieillesse_employeur = individu('vieillesse_employeur', period)
+        famille_net_allegement = individu('famille_net_allegement', period)
+        accident_du_travail = individu('accident_du_travail', period)
+        contribution_solidarite_autonomie = individu('contribution_solidarite_autonomie', period)
+
+        return (
+            mmid_employeur_net_allegement
+            + vieillesse_employeur
+            + famille_net_allegement
+            + accident_du_travail
+            + contribution_solidarite_autonomie
+            )
+
+
+class cotisations_salariales_contributives(Variable):
+    value_type = float
+    entity = Individu
+    label = 'Cotisations sociales salariales contributives'
+    set_input = set_input_divide_by_period
+    definition_period = MONTH
+
+    def formula(individu, period, parameters):
+        agff_salarie = individu('agff_salarie', period)
+        agirc_arrco_salarie = individu('agirc_arrco_salarie', period)
+        agirc_salarie = individu('agirc_salarie', period)
+        agirc_gmp_salarie = individu('agirc_gmp_salarie', period)
+        apec_salarie = individu('apec_salarie', period)
+        arrco_salarie = individu('arrco_salarie', period)
+        chomage_salarie = individu('chomage_salarie', period)
+        contribution_equilibre_general_salarie = individu('contribution_equilibre_general_salarie', period)
+        contribution_equilibre_technique_salarie = individu('contribution_equilibre_technique_salarie', period)
+        cotisation_exceptionnelle_temporaire_salarie = individu('cotisation_exceptionnelle_temporaire_salarie', period)
+        ircantec_salarie = individu('ircantec_salarie', period)
+        pension_salarie = individu('pension_salarie', period)
+        rafp_salarie = individu('rafp_salarie', period)
+        vieillesse_salarie = individu('vieillesse_salarie', period)
+
+        cotisations_salariales_contributives = (
+            # prive
+            agff_salarie
+            + agirc_arrco_salarie
+            + agirc_salarie
+            + agirc_gmp_salarie
+            + apec_salarie
+            + arrco_salarie
+            + chomage_salarie
+            + contribution_equilibre_general_salarie
+            + contribution_equilibre_technique_salarie
+            + cotisation_exceptionnelle_temporaire_salarie
+            + vieillesse_salarie
+            # public
+            + ircantec_salarie
+            + pension_salarie
+            + rafp_salarie
+            )
+
+        return cotisations_salariales_contributives
+
+
+class csg(Variable):
+    value_type = float
+    entity = Individu
+    label = 'Contribution sociale généralisée'
+    definition_period = YEAR
+
+    def formula(individu, period, parameters):
+        csg_salaire = individu('csg_salaire', period, options = [ADD])
+        csg_chomage = individu('csg_chomage', period, options = [ADD])
+        csg_retraite = individu('csg_retraite', period, options = [ADD])
+        csg_non_salarie = individu('csg_non_salarie', period)
+        csg_glo_assimile_salaire_ir_et_ps = individu('csg_glo_assimile_salaire_ir_et_ps', period)
+        # CSG sur revenus du capital, définie à l'échelle du foyer fiscal, mais projetée sur le déclarant principal
+        csg_revenus_capital = individu.foyer_fiscal('csg_revenus_capital', period)
+        csg_revenus_capital_projetee = csg_revenus_capital * individu.has_role(FoyerFiscal.DECLARANT_PRINCIPAL)
+
+        return (
+            csg_salaire
+            + csg_chomage
+            + csg_retraite
+            + csg_non_salarie
+            + csg_glo_assimile_salaire_ir_et_ps
+            + csg_revenus_capital_projetee
+            )
+
+
+class csg_chomage(Variable):
+    calculate_output = calculate_output_add
+    value_type = float
+    entity = Individu
+    label = 'CSG sur le chomage'
+    definition_period = MONTH
+    set_input = set_input_divide_by_period
+
+    def formula(individu, period):
+        return (
+            individu('csg_imposable_chomage', period)
+            + individu('csg_deductible_chomage', period)
+            )
+
+
+class csg_non_salarie(Variable):
+    value_type = float
+    entity = Individu
+    label = 'CSG non salarie'
+    definition_period = YEAR
+
+    def formula(individu, period, parameters):
+        return (
+            individu('csg_deductible_non_salarie', period)
+            + individu('csg_imposable_non_salarie', period)
+            )
+
+
+class csg_retraite(Variable):
+    calculate_output = calculate_output_add
+    value_type = float
+    entity = Individu
+    label = 'CSG sur les retraites'
+    definition_period = MONTH
+    set_input = set_input_divide_by_period
+
+    def formula(individu, period, parameters):
+        return (
+            individu('csg_imposable_retraite', period)
+            + individu('csg_deductible_retraite', period)
+            )
+
+
+class csg_salaire(Variable):
+    calculate_output = calculate_output_add
+    value_type = float
+    entity = Individu
+    label = 'CSG salaire'
+    definition_period = MONTH
+    set_input = set_input_divide_by_period
+
+    def formula(individu, period, parameters):
+        return (
+            individu('csg_deductible_salaire', period)
+            + individu('csg_imposable_salaire', period)
+            )
+
+
+class irpp_economique(Variable):
+    value_type = float
+    entity = FoyerFiscal
+    label = "Notion économique de l'impot sur le revenu"
+    definition_period = YEAR
+
+    def formula(foyer_fiscal, period, parameters):
+        '''
+        Voir la définition dans openfisca france
+        '''
+        iaidrdi = foyer_fiscal('iaidrdi', period)
+        cehr = foyer_fiscal('contribution_exceptionnelle_hauts_revenus', period)
+        pfu = foyer_fiscal('prelevement_forfaitaire_unique_ir', period)
+        credits_impot = foyer_fiscal('credits_impot', period)
+        acomptes_ir = foyer_fiscal('acomptes_ir', period)
+
+        autres_impositions_forfaitaires = foyer_fiscal('autres_impositions_forfaitaires', period)
+        correction_seuils_recouvrement = foyer_fiscal('correction_ir_seuils_recouvrement', period)
+
+        # prelevement_forfaitaire_liberatoire = foyer_fiscal('prelevement_forfaitaire_liberatoire', period) # déplacé dans autres_impositions_forfaitaires
+        acomptes_ir = foyer_fiscal('acomptes_ir', period)
+
+        return -(iaidrdi + cehr + pfu + autres_impositions_forfaitaires - credits_impot - acomptes_ir) - correction_seuils_recouvrement - acomptes_ir  # + prelevement_forfaitaire_liberatoire # Car par convention, impot_revenu_restant_a_payer et prelevement_forfaitaire_liberatoire sont des montants négatifs et acomptes_ir un montant positif
+
+
+class minima_sociaux(Variable):
+    value_type = float
+    entity = Famille
+    label = 'Minima sociaux'
+    reference = 'http://fr.wikipedia.org/wiki/Minima_sociaux'
+    definition_period = YEAR
+
+    def formula_2024_01_01(famille, period, parameters):
+        # Certaines réformes ayant des effets de bords nécessitent que le rsa soit calculé avant la ppa
+        rsa = famille('rsa', period, options = [ADD])
+        ppa_nette_crds = famille('ppa_nette_crds', period, options = [ADD])
+        aspa = famille('aspa', period, options = [ADD])
+        asi_i = famille.members('asi', period, options = [ADD])
+        asi = famille.sum(asi_i)
+        aah_i = famille.members('aah', period, options = [ADD])
+        aah = famille.sum(aah_i)
+        ass_i = famille.members('ass', period, options = [ADD])
+        ass = famille.sum(ass_i)
+        garantie_jeunes_i = famille.members('garantie_jeunes', period, options = [ADD])
+        garantie_jeunes = famille.sum(garantie_jeunes_i)
+        aefa = famille('aefa', period)
+
+        return rsa + ppa_nette_crds + aspa + asi + aah + ass + garantie_jeunes + aefa
+
+
+class pensions_rentes_complementaires(Variable):
+    value_type = float
+    entity = Menage
+    label = 'Pensions et revenus de remplacement  hors chomage et retraite'
+    reference = 'http://fr.wikipedia.org/wiki/Rente'
+    definition_period = YEAR
+
+    def formula(menage, period):
+        pensions_alimentaires_percues_i = menage.members('pensions_alimentaires_percues', period, options = [ADD])
+        pensions_alimentaires_percues = menage.sum(pensions_alimentaires_percues_i)
+        pensions_invalidite_i = menage.members('pensions_invalidite', period, options = [ADD])
+        pensions_invalidite = menage.sum(pensions_invalidite_i)
+
+        # Revenus du foyer fiscal, que l'on projette uniquement sur le 1er déclarant
+        pensions_alimentaires_versees_f = menage.members.foyer_fiscal('pensions_alimentaires_versees', period)
+        pensions_alimentaires_versees = menage.sum(pensions_alimentaires_versees_f * (menage.members.has_role(FoyerFiscal.DECLARANT_PRINCIPAL)))
+        rente_viagere_titre_onereux_f = menage.members.foyer_fiscal('rente_viagere_titre_onereux', period, options = [ADD])
+        rente_viagere_titre_onereux = menage.sum(rente_viagere_titre_onereux_f * (menage.members.has_role(FoyerFiscal.DECLARANT_PRINCIPAL)))
+
+        return (
+            pensions_alimentaires_percues
+            + pensions_invalidite
+            + pensions_alimentaires_versees
+            + rente_viagere_titre_onereux
+            )
+
+
+class primes(Variable):
+    value_type = float
+    entity = Individu
+    label = 'Primes'
+    definition_period = MONTH
+    set_input = set_input_divide_by_period
+
+    def formula_2024_01_01(individu, period, parameters):
+        primes_fonction_publique = individu('primes_fonction_publique', period)
+        primes_salaires = individu('primes_salaires', period)
+        prime_partage_valeur_exoneree = individu('prime_partage_valeur_exoneree', period, options=[DIVIDE])
+        prime_partage_valeur_non_exoneree = individu('prime_partage_valeur_non_exoneree', period, options=[DIVIDE])
+
+        return (
+            primes_fonction_publique
+            + primes_salaires
+            + prime_partage_valeur_exoneree
+            + prime_partage_valeur_non_exoneree
+            )
+
+
+class remuneration_brute(Variable):
+    value_type = float
+    entity = Individu
+    label = 'Rémunération brute'
+    definition_period = MONTH
+    set_input = set_input_divide_by_period
+
+    def formula_2024_01_01(individu, period, parameters):
+        salaire_de_base = individu('salaire_de_base', period)
+        remuneration_principale = individu('remuneration_principale', period)
+        indemnite_residence = individu('indemnite_residence', period)
+        supplement_familial_traitement = individu('supplement_familial_traitement', period)
+        remuneration_apprenti = individu('remuneration_apprenti', period)
+        primes = individu('primes', period)
+        indemnite_fin_contrat = individu('indemnite_fin_contrat', period)
+        depense_cantine_titre_restaurant_employeur = individu('depense_cantine_titre_restaurant_employeur', period)
+        reintegration_titre_restaurant_employeur = individu('reintegration_titre_restaurant_employeur', period)
+
+        return (
+            salaire_de_base
+            + remuneration_principale
+            + indemnite_residence
+            + supplement_familial_traitement
+            + remuneration_apprenti
+            + primes
+            + indemnite_fin_contrat
+            + depense_cantine_titre_restaurant_employeur
+            + reintegration_titre_restaurant_employeur
+            )
+
+
+class revenu_disponible(Variable):
+    value_type = float
+    entity = Menage
+    label = 'Revenu disponible du ménage'
+    reference = 'http://fr.wikipedia.org/wiki/Revenu_disponible'
+    definition_period = YEAR
+
+    def formula(menage, period, parameters):
+        revenus_nets_apres_impot_menage = menage('revenus_nets_apres_impot_menage', period)
+
+        # On prend en compte les prestations sociales touchées par une famille dont le demandeur est dans le ménage
+        prestations_sociales_i = menage.members.famille('prestations_sociales', period)  # PF de la famille auquel appartient chaque membre du ménage
+        prestations_sociales = menage.sum(prestations_sociales_i, role = Famille.DEMANDEUR)  # On somme seulement pour les demandeurs
+
+        return (
+            revenus_nets_apres_impot_menage
+            + prestations_sociales
+            )
+
+
+class revenus_du_capital_avant_prelevements(Variable):
+    value_type = float
+    entity = Menage
+    label = 'Revenus du capital avant prélèvements sociaux'
+    definition_period = YEAR
+
+    def formula_2024_01_01(menage, period):
+        assiette_csg_revenus_capital_f = menage.members.foyer_fiscal('assiette_csg_revenus_capital', period) * (menage.members.has_role(FoyerFiscal.DECLARANT_PRINCIPAL))
+        assiette_csg_revenus_capital = menage.sum(assiette_csg_revenus_capital_f)
+        assiette_csg_plus_values_f = menage.members.foyer_fiscal('assiette_csg_plus_values', period) * (menage.members.has_role(FoyerFiscal.DECLARANT_PRINCIPAL))
+        assiette_csg_plus_values = menage.sum(assiette_csg_plus_values_f)
+        plus_values_base_large_f = menage.members.foyer_fiscal('plus_values_base_large', period) * (menage.members.has_role(FoyerFiscal.DECLARANT_PRINCIPAL))
+        plus_values_base_large = menage.sum(plus_values_base_large_f)
+        rente_viagere_titre_onereux_net_f = menage.members.foyer_fiscal('rente_viagere_titre_onereux_net', period) * (menage.members.has_role(FoyerFiscal.DECLARANT_PRINCIPAL))
+        rente_viagere_titre_onereux_net = menage.sum(rente_viagere_titre_onereux_net_f)
+        # Ajoute les gains de levée d'options qui, pour les prélèvements sociaux, sont soumis aux mêmes taux que les salaires. Contrairement aux revenus ci-dessus, ces revenus sont individuels.
+        glo_assimiles_salaire_ir_et_ps_i = menage.members('f1tt', period)
+        glo_assimiles_salaire_ir_et_ps = menage.sum(glo_assimiles_salaire_ir_et_ps_i)
+
+        return (
+            assiette_csg_revenus_capital
+            - assiette_csg_plus_values
+            + plus_values_base_large
+            - rente_viagere_titre_onereux_net
+            + glo_assimiles_salaire_ir_et_ps
+            )
+
+
+class revenus_nets_apres_impot_menage(Variable):
+    value_type = float
+    entity = Menage
+    label = 'Revenus nets après impôts'
+    definition_period = YEAR
+
+    def formula(menage, period):
+        revenus_nets_menage = menage('revenus_nets_menage', period, options = [ADD])
+        irpp_economique_i = menage.members.foyer_fiscal('irpp_economique', period)
+        irpp_economique = menage.sum(irpp_economique_i, role = FoyerFiscal.DECLARANT_PRINCIPAL)
+
+        isf_ifi_i = menage.members.foyer_fiscal('isf_ifi', period)
+        isf_ifi = menage.sum(isf_ifi_i, role = FoyerFiscal.DECLARANT_PRINCIPAL)
+
+        return revenus_nets_menage + irpp_economique + isf_ifi
+
+
+class revenus_nets_menage(Variable):
+    value_type = float
+    entity = Menage
+    label = 'Revenus nets'
+    definition_period = YEAR
+
+    def formula(menage, period):
+        # revenus du travail nets
+        remuneration_brute_i = menage.members('remuneration_brute', period, options = [ADD])
+        remuneration_brute = menage.sum(remuneration_brute_i)
+        indemnite_compensatrice_csg_i = menage.members('indemnite_compensatrice_csg', period, options = [ADD])
+        indemnite_compensatrice_csg = menage.sum(indemnite_compensatrice_csg_i)
+        cotisations_salariales_i = menage.members('cotisations_salariales', period, options = [ADD])
+        cotisations_salariales = menage.sum(cotisations_salariales_i)
+        complementaire_sante_salarie_i = menage.members('complementaire_sante_salarie', period, options = [ADD])
+        complementaire_sante_salarie = menage.sum(complementaire_sante_salarie_i)
+        rpns_imposables_i = menage.members('rpns_imposables', period, options = [ADD])
+        rpns_imposables = menage.sum(rpns_imposables_i)
+        microentreprise_i = menage.members.foyer_fiscal('microentreprise', period, options = [ADD]) * menage.members.has_role(FoyerFiscal.DECLARANT_PRINCIPAL)
+        microentreprise = menage.sum(microentreprise_i)
+        # pensions nettes
+        chomage_brut_i = menage.members('chomage_brut', period, options = [ADD])
+        chomage_brut = menage.sum(chomage_brut_i)
+        retraite_brute_i = menage.members('retraite_brute', period, options = [ADD])
+        retraite_brute = menage.sum(retraite_brute_i)
+        casa_i = menage.members('casa', period, options = [ADD])
+        casa = menage.sum(casa_i)
+        pensions_rentes_complementaires = menage('pensions_rentes_complementaires', period)
+        # revenus nets du capital
+        revenus_du_capital_avant_prelevements = menage('revenus_du_capital_avant_prelevements', period)
+        prelevements_sociaux_revenus_capital_hors_csg_crds_f = menage.members.foyer_fiscal('prelevements_sociaux_revenus_capital_hors_csg_crds', period) * menage.members.has_role(FoyerFiscal.DECLARANT_PRINCIPAL)
+        prelevements_sociaux_revenus_capital_hors_csg_crds = menage.sum(prelevements_sociaux_revenus_capital_hors_csg_crds_f)
+
+        # CSG CRDS
+        csg_i = menage.members('csg', period)
+        csg = menage.sum(csg_i)
+        crds_hors_prestations_i = menage.members('crds_hors_prestations', period)
+        crds_hors_prestations = menage.sum(crds_hors_prestations_i)
+
+        return (
+            remuneration_brute
+            + indemnite_compensatrice_csg
+            + cotisations_salariales
+            - complementaire_sante_salarie
+            + rpns_imposables
+            + microentreprise
+            + retraite_brute
+            + casa
+            + chomage_brut
+            + pensions_rentes_complementaires
+            + revenus_du_capital_avant_prelevements
+            + prelevements_sociaux_revenus_capital_hors_csg_crds
+            + csg
+            + crds_hors_prestations
+            )
+
+
+class salaire_super_brut(Variable):
+    value_type = float
+    entity = Individu
+    label = 'Coût du travail à court terme. Inclut les exonérations et allègements de charges'
+    set_input = set_input_divide_by_period
+    definition_period = MONTH
+
+    def formula(individu, period, parameters):
+        remuneration_brute = individu('remuneration_brute', period)
+        cotisations_employeur_securite_sociale = individu('cotisations_employeur_securite_sociale', period)
+        cotisations_employeur_retraite_complementaire = individu('cotisations_employeur_retraite_complementaire', period)
+        pension_employeur = individu('pension_employeur', period)
+        rafp_employeur = individu('rafp_employeur', period)
+        cotisations_employeur_assurance_chomage = individu('cotisations_employeur_assurance_chomage', period)
+        cotisations_employeur_autres = individu('cotisations_employeur_autres', period)
+        allegement_general = individu('allegement_general', period)
+        exonerations = individu('exonerations', period)
+
+        return (
+            remuneration_brute
+            - cotisations_employeur_securite_sociale
+            - cotisations_employeur_retraite_complementaire
+            - pension_employeur
+            - rafp_employeur
+            - cotisations_employeur_assurance_chomage
+            - cotisations_employeur_autres
+            - allegement_general
+            - exonerations
+            )
+
+
+class vieillesse_employeur(Variable):
+    value_type = float
+    entity = Individu
+    label = 'Cotisation vieillesse plafonnée et déplafonnée (employeur)'
+    reference = [
+        'Article L. 242-1 du code de la sécurité sociale',
+        'https://www.legifrance.gouv.fr/codes/article_lc/LEGIARTI000044626664'
+        ]
+    definition_period = MONTH
+    set_input = set_input_divide_by_period
+
+    def formula(individu, period, parameters):
+        vieillesse_plafonnee_employeur = individu('vieillesse_plafonnee_employeur', period)
+        vieillesse_deplafonnee_employeur = individu('vieillesse_deplafonnee_employeur', period)
+
+        return vieillesse_plafonnee_employeur + vieillesse_deplafonnee_employeur
+
+
+
+class vieillesse_salarie(Variable):
+    value_type = float
+    entity = Individu
+    label = 'Cotisation vieillesse plafonnée et déplafonnée (salarié)'
+    reference = [
+        'Article L. 242-1 du code de la sécurité sociale',
+        'https://www.legifrance.gouv.fr/codes/article_lc/LEGIARTI000044626664'
+        ]
+    definition_period = MONTH
+    set_input = set_input_divide_by_period
+
+    def formula(individu, period, parameters):
+        vieillesse_plafonnee_salarie = individu('vieillesse_plafonnee_salarie', period)
+        vieillesse_deplafonnee_salarie = individu('vieillesse_deplafonnee_salarie', period)
+
+        return vieillesse_plafonnee_salarie + vieillesse_deplafonnee_salarie
-- 
GitLab