In [1]:
from openfisca_core import reforms
import openfisca_france
from openfisca_france.model.base import *
from numpy import maximum as max_, logical_not as not_, logical_or as or_
from datetime import date
import functools
#from openfisca_core.formulas import make_formula_decorator, neutralize_column
from openfisca_france.entities import entity_class_by_symbol
#reference_formula = make_formula_decorator(entity_class_by_symbol = entity_class_by_symbol, update = True)
#reference_input_variable = functools.partial(reference_input_variable, update = True)
In [2]:
tax_benefit_system = openfisca_france.init_country()()
In [32]:
Reform_individualisation = reforms.make_reform(
key = 'individualisation',
name = u'Individualisation du RSA et de l\'IRPP',
reference = tax_benefit_system,
)
In [33]:
Reform_individualisation.formula(neutralize_column(tax_benefit_system.column_by_name['af_base'])) # Suppression des allocations familiales
Reform_individualisation.formula(neutralize_column(tax_benefit_system.column_by_name['af'])) # Suppression des allocations familiales
Reform_individualisation.formula(neutralize_column(tax_benefit_system.column_by_name['cf'])) # Suppression du Complément familial
Reform_individualisation.formula(neutralize_column(tax_benefit_system.column_by_name['ars'])) # Suppression de l'allocation de rentrée scolaire
Reform_individualisation.formula(neutralize_column(tax_benefit_system.column_by_name['paje_base'])) # Suppression des allocations de base de la PAJE
Reform_individualisation.formula(neutralize_column(tax_benefit_system.column_by_name['ecpess'])) # Suppression de réduction d'impôts à titre des enfants à charge poursuivant leurs études secondaire ou supérieur.
Reform_individualisation.formula(neutralize_column(tax_benefit_system.column_by_name['nb_enfant_rsa'])) # Neutralisation des enfants dans les calculs liés au RSA
# Reform_individualisation.formula(neutralize_column(tax_benefit_system.column_by_name['rmi_nbp'])) # Neutralisation des enfants dans les calculs liés au RSA
In [34]:
# 8 - Suppression du Quotient familial (QF)
# Le nombre de parts fiscales est recalculé en supprimant l'impact des enfants
from numpy import logical_not as not_, minimum as min_, maximum as max_
class nbptr(Reform_individualisation):
reference = FoyersFiscaux.column_by_name['nbptr']
# On enlève les enfants du calcul du nbptr (quotient_familial.enf*)
def function(self, simulation, period):
'''
Nombre de parts du foyer
'foy'
note 1 enfants et résidence alternée (formulaire 2041 GV page 10)
quotient_familial.conj : nb part associées au conjoint d'un couple marié ou pacsé
quotient_familial.inv1 : nb part supp enfants invalides (I, G)
quotient_familial.inv2 : nb part supp adultes invalides (R)
quotient_familial.not31 : nb part supp note 3 : cases W ou G pour veuf, celib ou div
quotient_familial.not32 : nb part supp note 3 : personne seule ayant élevé des enfants
quotient_familial.not41 : nb part supp adultes invalides (vous et/ou conjoint) note 4
quotient_familial.not42 : nb part supp adultes anciens combattants (vous et/ou conjoint) note 4
quotient_familial.not6 : nb part supp note 6
quotient_familial.isol : demi-part parent isolé (T)
quotient_familial.edcd : enfant issu du mariage avec conjoint décédé;
'''
period = period.start.offset('first-of', 'month').period('year')
nb_pac = simulation.calculate('nb_pac', period)
marpac = simulation.calculate('marpac', period)
celdiv = simulation.calculate('celdiv', period)
veuf = simulation.calculate('veuf', period)
jveuf = simulation.calculate('jveuf', period)
nbF = simulation.calculate('nbF', period)
nbG = simulation.calculate('nbG', period)
nbH = simulation.calculate('nbH', period)
nbI = simulation.calculate('nbI', period)
nbR = simulation.calculate('nbR', period)
nbJ = simulation.calculate('nbJ', period)
caseP = simulation.calculate('caseP', period)
caseW = simulation.calculate('caseW', period)
caseG = simulation.calculate('caseG', period)
caseE = simulation.calculate('caseE', period)
caseK = simulation.calculate('caseK', period)
caseN = simulation.calculate('caseN', period)
caseF = simulation.calculate('caseF', period)
caseS = simulation.calculate('caseS', period)
caseL = simulation.calculate('caseL', period)
caseT = simulation.calculate('caseT', period)
quotient_familial = simulation.legislation_at(period.start).ir.quotient_familial
no_pac = nb_pac == 0 # Aucune personne à charge en garde exclusive
has_pac = not_(no_pac)
no_alt = nbH == 0 # Aucun enfant à charge en garde alternée
has_alt = not_(no_alt)
# # note 2 : nombre de parts liées aux invalides (enfant + adulte)
n2 = quotient_familial.inv1 * (nbG + nbI / 2) + quotient_familial.inv2 * nbR
# # note 3 : Pas de personne à charge
# - invalide
n31a = quotient_familial.not31a * (no_pac & no_alt & caseP)
# - ancien combatant
n31b = quotient_familial.not31b * (no_pac & no_alt & (caseW | caseG))
n31 = max_(n31a, n31b)
# - personne seule ayant élevé des enfants
n32 = quotient_familial.not32 * (no_pac & no_alt & ((caseE | caseK) & not_(caseN)))
n3 = max_(n31, n32)
# # note 4 Invalidité de la personne ou du conjoint pour les mariés ou
# # jeunes veuf(ve)s
n4 = max_(quotient_familial.not41 * (1 * caseP + 1 * caseF), quotient_familial.not42 * (caseW | caseS))
# # note 5
# - enfant du conjoint décédé
n51 = quotient_familial.cdcd * (caseL & ((nbF + nbJ) > 0))
# - enfant autre et parent isolé
n52 = quotient_familial.isol * caseT * (((no_pac & has_alt) * ((nbH == 1) * 0.5 + (nbH >= 2))) + 1 * has_pac)
n5 = max_(n51, n52)
# # note 6 invalide avec personne à charge
n6 = quotient_familial.not6 * (caseP & (has_pac | has_alt))
# # note 7 Parent isolé
n7 = quotient_familial.isol * caseT * ((no_pac & has_alt) * ((nbH == 1) * 0.5 + (nbH >= 2)) + 1 * has_pac)
# # Régime des mariés ou pacsés
m = 1 + quotient_familial.conj + n2 + n4
# # veufs hors jveuf
v = 1 + n2 + n3 + n5 + n6
# # celib div
c = 1 + n2 + n3 + n6 + n7
return period, (marpac | jveuf) * m + (veuf & not_(jveuf)) * v + celdiv * c
In [35]:
# A - Création d'un Revenu de Base Enfant
class rdb_enf(Reform_individualisation.Variable):
column = FloatCol
entity_class = Individus
label = u"Revenu de Base Enfant"
def function(self, simulation, period):
period = period.start.offset('first-of', 'month').period('month')
age = simulation.calculate('age')
P = simulation.legislation_at(period.start).fam.af
bmaf = P.bmaf
return period, (age < 14) * 0.41 * bmaf
In [36]:
# B - Création d'un Revenu de Base Jeune
class rdb_jeu(Reform_individualisation.Variable):
column = FloatCol
entity_class = Individus
label = u"Revenu de Base Jeune"
def function(self, simulation, period):
period = period.start.offset('first-of', 'month').period('month')
age = simulation.calculate('age')
P = simulation.legislation_at(period.start).fam.af
bmaf = P.bmaf
return period, (age >= 14) * (age < 25) * 0.57 * bmaf
In [37]:
# BILAN : calcul du revenu disponible en ajoutant RdB Enfant et RdB Jeune
class revdisp(Reform_individualisation.Variable):
reference = Menages.column_by_name['revdisp']
def function(self, simulation, period):
'''
Revenu disponible - ménage
'men'
'''
period = period.start.offset('first-of', 'month').period('year')
rev_trav_holder = simulation.compute('rev_trav', period)
pen_holder = simulation.compute('pen', period)
rev_cap_holder = simulation.compute('rev_cap', period)
psoc_holder = simulation.compute('psoc', period)
ppe_holder = simulation.compute('ppe', period)
impo = simulation.calculate('impo', period)
rdb_enfant_holder = simulation.compute_add('rdb_enf', period)
rdb_jeune_holder = simulation.compute_add('rdb_jeu', period)
pen = self.sum_by_entity(pen_holder)
ppe = self.cast_from_entity_to_role(ppe_holder, role = VOUS)
ppe = self.sum_by_entity(ppe)
psoc = self.cast_from_entity_to_role(psoc_holder, role = CHEF)
psoc = self.sum_by_entity(psoc)
rev_cap = self.sum_by_entity(rev_cap_holder)
rev_trav = self.sum_by_entity(rev_trav_holder)
rdb_enfant = self.sum_by_entity(rdb_enfant_holder)
rdb_jeune = self.sum_by_entity(rdb_jeune_holder)
return period, rev_trav + pen + rev_cap + psoc + ppe + impo + rdb_enfant + rdb_jeune
In [38]:
def modify_legislation_json(reference_legislation_json_copy):
#reference_legislation_json_copy['children']['xxx']['values'][0]['value'] = 0
return reference_legislation_json_copy
In [39]:
class nb_enfant_rsa_indiv(Reform_individualisation.Variable):
entity_class = Individus
label = u"Nombre d'enfants de la famille"
variable = Familles.column_by_name['nb_enfant_rsa']
In [40]:
class rsa_eligibilite_tns_indiv(Reform_individualisation.Variable):
# ATTENTION, on a fait le choix de se caler sur les célibataires dans le calcul du plafond,
# ce qui a pour effet de rendre inéligibles certains couples ou certaines familles avec enfants
column = BoolCol
entity_class = Individus
label = u"Eligibilité au RSA pour un travailleur non salarié"
def function(self, simulation, period):
period = period.start.offset('first-of', 'month').period('month')
#tns_benefice_exploitant_agricole_holder = simulation.compute('tns_benefice_exploitant_agricole', period)
#tns_benefice_exploitant_agricole = self.sum_by_entity(tns_benefice_exploitant_agricole_holder)
tns_benefice_exploitant_agricole = simulation.calculate('tns_benefice_exploitant_agricole', period) #new
#tns_employe_holder = simulation.compute('tns_employe', period)
#tns_employe = self.any_by_roles(tns_employe_holder)
tns_employe = simulation.calculate('tns_employe', period) #new
#tns_autres_revenus_chiffre_affaires_holder = simulation.compute('tns_autres_revenus_chiffre_affaires', period)
#tns_autres_revenus_chiffre_affaires = self.split_by_roles(tns_autres_revenus_chiffre_affaires_holder)
tns_autres_revenus_chiffre_affaires = simulation.calculate('tns_autres_revenus_chiffre_affaires', period) #new
#tns_autres_revenus_type_activite_holder = simulation.compute('tns_autres_revenus_type_activite', period)
#tns_autres_revenus_type_activite = self.split_by_roles(tns_autres_revenus_type_activite_holder)
tns_autres_revenus_type_activite = simulation.calculate('tns_autres_revenus_type_activite', period) #new
#has_conjoint = simulation.calculate('nb_par', period) > 1
#nb_enfant_rsa = simulation.calculate('nb_enfant_rsa', period)
P = simulation.legislation_at(period.start)
P_agr = P.tns.exploitant_agricole
P_micro = P.ir.rpns.microentreprise
maj_2p = P_agr.maj_2p
maj_1e_2ad = P_agr.maj_1e_2ad
maj_e_sup = P_agr.maj_e_sup
#def eligibilite_agricole(has_conjoint, nb_enfant_rsa, tns_benefice_exploitant_agricole, P_agr):
def eligibilite_agricole(tns_benefice_exploitant_agricole, P_agr):
plafond_benefice_agricole = P_agr.plafond_rsa * P.cotsoc.gen.smic_h_b
#taux_avec_conjoint = 1 + maj_2p + maj_1e_2ad * (nb_enfant_rsa > 0) + maj_e_sup * max_(nb_enfant_rsa - 1, 0)
#taux_sans_conjoint = 1 + maj_2p * (nb_enfant_rsa > 0) + maj_e_sup * max_(nb_enfant_rsa - 1, 0)
#taux_majoration = has_conjoint * taux_avec_conjoint + (1 - has_conjoint) * taux_sans_conjoint
taux_majoration = 1 #new
plafond_benefice_agricole_majore = taux_majoration * plafond_benefice_agricole
return tns_benefice_exploitant_agricole < plafond_benefice_agricole_majore
def eligibilite_chiffre_affaire(ca, type_activite, P_micro):
plaf_vente = P_micro.vente.max
plaf_service = P_micro.servi.max
return ((type_activite == 0) * (ca <= plaf_vente)) + ((type_activite >= 1) * (ca <= plaf_service))
eligibilite_agricole = eligibilite_agricole(
# has_conjoint, nb_enfant_rsa, tns_benefice_exploitant_agricole, P_agr
tns_benefice_exploitant_agricole, P_agr
)
eligibilite_chiffre_affaire = (
eligibilite_chiffre_affaire(
# tns_autres_revenus_chiffre_affaires[CHEF], tns_autres_revenus_type_activite[CHEF], P_micro
tns_autres_revenus_chiffre_affaires, tns_autres_revenus_type_activite, P_micro #new
) *
eligibilite_chiffre_affaire(
# tns_autres_revenus_chiffre_affaires[PART], tns_autres_revenus_type_activite[PART], P_micro
tns_autres_revenus_chiffre_affaires, tns_autres_revenus_type_activite, P_micro #new
)
)
return period, eligibilite_agricole * (1 - tns_employe) * eligibilite_chiffre_affaire
In [41]:
class rsa_eligibilite_indiv(Reform_individualisation.Variable):
# On maintient un calcul en fonction du ménage : règle du RSA pour les moins de 25 ans maintenu (s'ils ont des enfants)
column = BoolCol
entity_class = Individus
label = u"Eligibilité au RSA"
def function(self, simulation, period):
period = period.this_month
#age_holder = simulation.compute('age', period)
#age_parents = self.split_by_roles(age_holder, roles = [CHEF, PART])
age = simulation.calculate('age', period) #new
#activite_holder = simulation.compute('activite', period)
#activite_parents = self.split_by_roles(activite_holder, roles = [CHEF, PART])
activite = simulation.calculate('activite', period) #new
#nb_enfant_rsa = simulation.calculate('nb_enfant_rsa', period)
rsa_eligibilite_tns_indiv = simulation.calculate('rsa_eligibilite_tns_indiv', period)
#rsa_condition_nationalite = simulation.compute('rsa_condition_nationalite', period)
#condition_nationalite = self.any_by_roles(rsa_condition_nationalite, roles = [CHEF, PART])
condition_nationalite = simulation.calculate('rsa_condition_nationalite', period) #new
rmi = simulation.legislation_at(period.start).minim.rmi
#age_min = (nb_enfant_rsa_indiv == 0) * rmi.age_pac
quifam = simulation.calculate('quifam', period)
nb_enfant_rsa_indiv = simulation.calculate('nb_enfant_rsa_indiv', period)
condition_age = or_ (age >= rmi.age_pac, (age < rmi.age_pac) * (quifam == 0) * (nb_enfant_rsa_indiv > 1))
# ce qui est après le or_ a été codé pour le RSA jeune, mais je ne suis pas sûr du tout que ce soit la vraie règle
#eligib = (
# (age_parents[CHEF] >= age_min) * not_(activite_parents[CHEF] == 2) +
# (age_parents[PART] >= age_min) * not_(activite_parents[PART] == 2)
#)
eligib = condition_age * not_(activite == 2) * (
condition_nationalite *
rsa_eligibilite_tns_indiv
)
return period, eligib
In [42]:
class nb_par_indiv(Reform_individualisation.Variable):
entity_class = Individus
label = u"Nombre de parents de la famille"
variable = Familles.column_by_name['nb_par']
In [43]:
#@Reform_individualisation.formula
#class af_nbenf_indiv(EntityToPersonColumn):
# entity_class = Individus
# label = u"Nombre d'enfants de la famille (au sens des allocations familiales)"
# variable = Familles.column_by_name['af_nbenf']
In [44]:
class supp_monoparental(Reform_individualisation.Variable):
label = u"Supplément RSA monoparental"
column = FloatCol
entity_class = Individus
def function(self, simulation, period):
quifam = simulation.calculate('quifam', period)
nb_enfant_rsa_indiv = simulation.calculate('nb_enfant_rsa_indiv', period)
nb_par_indiv = simulation.calculate('nb_par_indiv', period)
rmi = simulation.legislation_at(period.start).minim.rmi
return period, self.zeros() + (quifam == 0) * (nb_par_indiv == 1) * (nb_enfant_rsa_indiv > 0) * rmi.rmi * rmi.txp2 # - revenu de base enfants
In [45]:
class aspa_asi_ass_famille(Reform_individualisation.Variable):
# Comme on ne pouvait pas individualiser ces trois prestations, on a récupéré les prestations familialisées pour le calcul du RSA individuel
entity_class = Individus
label = u"Somme de l'ASPA, ASI et ASS de la famille"
variable = Familles.column_by_name['br_rmi_ms']
In [46]:
class rsa_indiv(Reform_individualisation.Variable):
# Concernant les minimas sociaux qui sont déduits du RSA : - minimas sociaux individuels (aah, caah) : pas de problème
# - minimas sociaux familialisés (aspa, asi, ass) : on a pris en compte l'allocation familialisée ; il faudrait idéalement les individualiser (mais c'est une autre réforme)
label = u"RSA individualisé"
column = FloatCol
entity_class = Individus
def function(self, simulation, period):
period = period.start.offset('first-of', 'month').period('month')
eligib = simulation.calculate('rsa_eligibilite_indiv', period)
ra_rsa_i = simulation.calculate('ra_rsa_i', period)
br_rmi_i = simulation.calculate('br_rmi_i', period)
aah = simulation.calculate('aah', period)
caah = simulation.calculate('caah', period)
aspa_asi_ass_famille = simulation.calculate('aspa_asi_ass_famille', period)
supp_monoparental = simulation.calculate('supp_monoparental', period)
rmi = simulation.legislation_at(period.start).minim.rmi
br_rmi_indiv = br_rmi_i + ra_rsa_i + aspa_asi_ass_famille + aah + caah
return period, self.zeros() + eligib * (supp_monoparental + max_(rmi.rmi - rmi.rmi * rmi.forfait_logement.taux1 - br_rmi_indiv + rmi.pente * ra_rsa_i, 0) )
In [47]:
reform = Reform_individualisation()
reform.modify_legislation_json(modifier_function = modify_legislation_json)
In [48]:
scenario = reform.new_scenario()
In [49]:
scenario.init_single_entity(
period = 2012,
parent1 = dict(
age = 30,
salaire_de_base = 15000,
),
enfants = [
dict(age = 10),
dict(age = 12),
dict(age = 18),
],
)
Out[49]:
In [50]:
reform_simulation = scenario.new_simulation()
In [51]:
reform_simulation.calculate('rsa', "2015-01")
Out[51]:
In [52]:
reform_simulation.calculate('rsa_indiv', "2015-01")
In [ ]:
scenario.init_single_entity(
period = 2015,
parent1 = dict(
age = 30,
salaire_de_base = 0,
),
enfants = [
dict(birth = date(2005,1,1)),
dict(birth = date(2005,1,1)),
],
)
In [ ]:
reform_simulation2 = scenario.new_simulation()
In [ ]:
reform_simulation2.calculate('rsa', "2015-12")
In [ ]:
reform_simulation2.calculate('rsa_indiv', "2015-12")
In [53]:
reform_simulation2.calculate('age', "2015-03")
In [54]:
reform_simulation.calculate('rsa_indiv', "2012-12")
In [ ]:
In [ ]: