def create_and_apply_structural_reform_ag(
tax_benefit_system, dict_params, period="2000-01-01"
):
"""
Creates and applies a structural reform to add a new exemption.
Depending on the type of general exemption to add, this function modifies the parameters of the tax-benefit system
and adds a new variable to calculate. The type of exemption can be 'fillon', 'convexe_fillon', 'allocations_familiales',
or 'maladie'.
Args:
tax_benefit_system (TaxBenefitSystem):
The initial tax-benefit system.
dict_params (dict):
A dictionary containing the parameters of the reform. The 'TYPE' key indicates the type of exemption to add.
period (str, optional):
The period for which the parameters are defined. Default is '2000-01-01'.
Returns:
(TaxBenefitSystem): The reformed tax-benefit system.
Raises:
ValueError: If the type of exemption is not 'fillon', 'convexe_fillon', 'allocations_familiales', or 'maladie'.
"""
# Distinction suivant le type d'allègement général à ajouter
if dict_params["TYPE"] == "fillon":
# Définition de la fonction de modification des paramètres
def modify_new_fillon_parameters(parameters):
# Définition des paramètres à ajouter
reform_parameters_subtree = ParameterNode(
name="new_fillon",
data={
"ensemble_des_entreprises": {
"plafond": {
"values": {
period: {"value": dict_params["PARAMS"]["PLAFOND"]}
}
},
"entreprises_de_50_salaries_et_plus": {
"values": {
period: {
"value": dict_params["PARAMS"][
"TAUX_50_SALARIES_ET_PLUS"
]
}
}
},
"entreprises_de_moins_de_50_salaries": {
"values": {
period: {
"value": dict_params["PARAMS"][
"TAUX_MOINS_DE_50_SALARIES"
]
}
}
},
}
},
)
# Ajout des paramètres au noeud d'intéret
parameters.prelevements_sociaux.reductions_cotisations_sociales.add_child(
"new_fillon", reform_parameters_subtree
)
return parameters
# Définition de la classe de réforme
class StructuralReformFillon(Reform):
name = "Ajout d'un nouvel allègement général de type 'Allègement Fillon'"
# Application de la réforme
def apply(self):
# Ajout des paramètres des allègements de cotisation
self.modify_parameters(modifier_function=modify_new_fillon_parameters)
# Ajout de la variable à calculer
self.add_variable(new_allegement_fillon)
# Application de la réforme au système socio-fiscal
reformed_tax_benefit_system = StructuralReformFillon(tax_benefit_system)
return reformed_tax_benefit_system
elif dict_params["TYPE"] == "convexe_fillon":
# Définition de la fonction de modification des paramètres
def modify_convexe_fillon_parameters(parameters):
# Définition des paramètres à ajouter
reform_parameters_subtree = ParameterNode(
name="convexe_fillon",
data={
"ensemble_des_entreprises": {
"plafond": {
"values": {
period: {"value": dict_params["PARAMS"]["PLAFOND"]}
}
},
"entreprises_de_50_salaries_et_plus": {
"values": {
period: {
"value": dict_params["PARAMS"][
"TAUX_50_SALARIES_ET_PLUS"
]
}
}
},
"entreprises_de_moins_de_50_salaries": {
"values": {
period: {
"value": dict_params["PARAMS"][
"TAUX_MOINS_DE_50_SALARIES"
]
}
}
},
"exposant": {
"values": {
period: {"value": dict_params["PARAMS"]["EXPOSANT"]}
}
},
}
},
)
# Ajout des paramètres au noeud d'intéret
parameters.prelevements_sociaux.reductions_cotisations_sociales.add_child(
"convexe_fillon", reform_parameters_subtree
)
return parameters
# Définition de la classe de réforme
class StructuralReformConvexeFillon(Reform):
name = "Ajout d'un nouvel allègement général de type 'Allègement Fillon' dont la convexité est modifiée"
# Application de la réforme
def apply(self):
# Ajout des paramètres des allègements de cotisation
self.modify_parameters(
modifier_function=modify_convexe_fillon_parameters
)
# Ajout de la variable à calculer
self.add_variable(new_allegement_convexe_fillon)
# Application de la réforme au système socio-fiscal
reformed_tax_benefit_system = StructuralReformConvexeFillon(tax_benefit_system)
return reformed_tax_benefit_system
elif dict_params["TYPE"] == "allocations_familiales":
# Définition de la fonction de modification des paramètres
def modify_new_allocations_familiales_parameters(parameters):
# Définition des paramètres à ajouter
reform_parameters_subtree = ParameterNode(
name="new_allegement_cotisation_allocations_familiales",
data={
"plafond_smic": {
"values": {period: {"value": dict_params["PARAMS"]["PLAFOND"]}}
},
"reduction": {
"values": {period: {"value": dict_params["PARAMS"]["TAUX"]}}
},
},
)
# Ajout des paramètres au noeud d'intéret
parameters.prelevements_sociaux.reductions_cotisations_sociales.add_child(
"new_allegement_cotisation_allocations_familiales",
reform_parameters_subtree,
)
return parameters
# Définition de la classe de réforme
class StructuralReformAllocationsFamiliales(Reform):
name = "Ajout d'un nouvel allègement général de type 'Allègement cotisations allocations familiales'"
# Application de la réforme
def apply(self):
# Ajout des paramètres des allègements de cotisation
self.modify_parameters(
modifier_function=modify_new_allocations_familiales_parameters
)
# Ajout de la variable à calculer
self.add_variable(new_allegement_allocations_familiales)
# Application de la réforme du système socio-fiscal
reformed_tax_benefit_system = StructuralReformAllocationsFamiliales(
tax_benefit_system
)
return reformed_tax_benefit_system
elif dict_params["TYPE"] == "maladie":
# Définition de la fonction de modification des paramètres
def modify_new_maladie_parameters(parameters):
# Définition des paramètres à ajouter
reform_parameters_subtree = ParameterNode(
name="new_mmid",
data={
"plafond": {
"values": {period: {"value": dict_params["PARAMS"]["PLAFOND"]}}
},
"taux": {
"values": {period: {"value": dict_params["PARAMS"]["TAUX"]}}
},
},
)
# Ajout des paramètres au noeud d'intéret
parameters.prelevements_sociaux.reductions_cotisations_sociales.add_child(
"new_mmid", reform_parameters_subtree
)
return parameters
# Définition de la classe de réforme
class StructuralReformMaladie(Reform):
name = "Ajout d'un nouvel allègement général de type 'Allègement cotisations maladie'"
# Application de la réforme
def apply(self):
# Ajout des paramètres des allègements de cotisation
self.modify_parameters(modifier_function=modify_new_maladie_parameters)
# Ajout de la variable à calculer
self.add_variable(new_allegement_cotisation_maladie)
# Application de la réforme du système socio-fiscal
reformed_tax_benefit_system = StructuralReformMaladie(tax_benefit_system)
return reformed_tax_benefit_system
else:
raise ValueError(
"Unknown allegement type : should be in ['fillon', 'allocations_familiales', 'maladie']"
)