In [1]:
from datetime import date
import json
import openfisca_france
from openfisca_france.model.base import *
#importer numpy permet de coller deux sections de courbes (nécessaire quand on fait varier le salaire de base en-dessous du SMIC mensuel)
import numpy as np
from numpy import round
# to debug / trace
from openfisca_core import tools
from openfisca_core.reforms import Reform
In [2]:
tax_benefit_system = openfisca_france.FranceTaxBenefitSystem()
In [3]:
from numpy import logical_not as not_, minimum as min_, maximum as max_, logical_and as and_, logical_or as or_
#- MISE EN PLACE DU RDB
#- Mise en place d'un revenu de base adulte égal à RSA socle célibataire - forfait logement célibataire,
#- dont on déduit l'AAH jusqu'à sa hauteur
#- Mise en place d'un crédit d'impot familles monoparentales montant ??? (150€)
#- Supprimer le RSA
#- Supprimer la prime d'activité
#- Création du RdB enfant
#- CHANGEMENT DE L'ASSIETTE DE L'IRPP
#- Réforme de l'abattement pour frais professionnels :
#- le taux d'abattement pour frais professionnels est réduit à 0%
#- seuls 30% de frais réels donnent droit à un abattement
#- le taux d'abattement sur les pensions est réduit à 0%
#- La CSG déductible sur les salaires ne l'est plus
#- La CSG déductible sur le chômage ne l'est plus
#- La CSG déductible sur les pensions ne l'est plus
#- Les charges déductibles (abattements) suivantes sont supprimées : cd_deddiv, cd_doment, cd_eparet, cd_grorep, cd_percap
#- Les charges déductibles (abattements) suivantes sont maintenues : cd_acc75a, cd_penali
#- La CSG déductible sur le patrimoine ne l'est plus
#- Les réductions d'impôts suivants sont remplacés par des abattements : cotsyn, dfppce, donapd, garext
#- Les crédits d'impôt suivants sont remplacés par des abattements : aidper, ci_garext, quaenv, saldom2
#- le revenu de base adulte et le crédit d'impot familles monoparentales sont ajoutés au revenu imposable
#- CHANGEMENT DU CALCUL DE L'IRPP
#- le barème est modifié avec les tranches 0%, 30%, 41%, 45%
#- les tranches sont modifiées : RDB adulte, XXXXX €, XXXXX €
#- la décote est annulée (ou non prise en compte)
#- les enfants sont retirés du nombre de parts (maintien du quotient conjugal et de la demi-part pour familles monoparentales)
#- Le revenu de base et le crédit familles monoparentales sont intégres au revenu imposable
#- Les réductions d'impôt suivantes sont supprimées : accult, adhcga, assvie, cappme, creaen, daepad, deffor, doment, domlog, domsoc, duflot, ecodev, ecpess, intagr, intcon, intemp, invfor, invlst, invrev, ip_net, locmeu, mecena, mohist, patnat, prcomp, reduction_impot_exceptionnelle, repsoc, resimm, rsceha, saldom, scelli, sofica, sofipe, spfcpi
#- Seules 30% des réductions d'impôt suivantes sont prise en compte : (vide)
#- Les crédits d'impôt suivants sont supprimés : accult, acqgpl, aidmob, assloy, autent, cotsyn, creimp, creimp_exc_2008, direpa, divide, drbail, inthab, jeunes, mecena, percvm, preetu, prlire
#- Intégrer le revenu de base au revenu disponible
#-Visualisation graphique en abscisse salaire brut et en ordonnée variation du revenu disponible
# pour un célibataire sans enfant
# pour un couple sans enfant
# une famille monoparentale
In [4]:
#- Les paramètres de taux d'abattement sont annulés
#- paramètre abattement_minimum : l'abattemnt minimum est réduit à 0
#- paramètre abatpro.taux : le taux d'abattement pour frais professionnels est réduit à 0%
#- paramètre abatpen.taux : le taux d'abattement sur les pensions est réduit à 0%
def modify_legislation_json(reference_legislation_json_copy):
for value_json in reference_legislation_json_copy['children']['ir']['children']['tspr']['children']['abatpro']['children']['taux']['values']:
value_json['value'] = 0
for value_json in reference_legislation_json_copy['children']['ir']['children']['tspr']['children']['abatpen']['children']['taux']['values']:
value_json['value'] = 0
return reference_legislation_json_copy
In [5]:
#- Variable salaire_imposable (individus)
#- La CSG déductible sur les salaires ne l'est plus
class salaire_imposable(Variable):
def function(self, simulation, period):
period = period.start.period(u'month').offset('first-of')
salaire_de_base = simulation.calculate('salaire_de_base', period)
primes_salaires = simulation.calculate('primes_salaires', period)
primes_fonction_publique = simulation.calculate('primes_fonction_publique', period)
indemnite_residence = simulation.calculate('indemnite_residence', period)
supp_familial_traitement = simulation.calculate('supp_familial_traitement', period)
csg_deductible_salaire = simulation.calculate('csg_deductible_salaire', period)
cotisations_salariales = simulation.calculate('cotisations_salariales', period)
remuneration_principale = simulation.calculate('remuneration_principale', period)
hsup = simulation.calculate('hsup', period)
rev_microsocial_declarant1 = simulation.calculate_divide('rev_microsocial_declarant1', period)
indemnite_fin_contrat = simulation.calculate('indemnite_fin_contrat', period)
return period, (
salaire_de_base + primes_salaires + remuneration_principale +
primes_fonction_publique + indemnite_residence + supp_familial_traitement +
cotisations_salariales - hsup + rev_microsocial_declarant1 + indemnite_fin_contrat
)
In [6]:
#- Variable chomage_imposable (individus)
#- La CSG déductible sur le chômage ne l'est plus
class chomage_imposable(Variable):
def function(self, simulation, period):
period = period
chomage_brut = simulation.calculate('chomage_brut', period)
csg_deductible_chomage = simulation.calculate_add('csg_deductible_chomage', period)
return period, chomage_brut
In [7]:
#- Variable retraite_imposable (individus)
#- La CSG déductible sur les pensions de retraite ne l'est plus
class retraite_imposable(Variable):
def function(self, simulation, period):
period = period
retraite_brute = simulation.calculate_add('retraite_brute', period)
csg_deductible_retraite = simulation.calculate_add('csg_deductible_retraite', period)
return period, retraite_brute
In [8]:
#- variable revenu_assimile_salaire_apres_abattements (Individu) :
#- seuls 30% de frais réels donnent droit à un abattement
class revenu_assimile_salaire_apres_abattements(Variable):
def function(self, simulation, period):
'''
blabla
'''
period = period.this_year
revenu_assimile_salaire = simulation.calculate('revenu_assimile_salaire', period)
chomeur_longue_duree = simulation.calculate('chomeur_longue_duree', period)
frais_reels = simulation.calculate('frais_reels', period)
abatpro = simulation.legislation_at(period.start).ir.tspr.abatpro
abattement_minimum = abatpro.min * not_(chomeur_longue_duree) + abatpro.min2 * chomeur_longue_duree
abatfor = round(min_(max_(abatpro.taux * revenu_assimile_salaire, abattement_minimum), abatpro.max))
return period, (frais_reels > abatfor) * (revenu_assimile_salaire - frais_reels/3) + (frais_reels <= abatfor) * max_(0, revenu_assimile_salaire - abatfor)
In [9]:
#- variable cd1 (FoyersFiscaux) :
#- Les charges déductibles (abattements) suivantes sont supprimées : cd_deddiv, cd_doment, cd_eparet, cd_grorep, cd_percap
#- Les charges déductibles (abattements) suivantes sont maintenues : cd_acc75a, cd_penali
class cd1(Variable):
def function(self, simulation, period):
'''
Renvoie la liste des charges déductibles avant rbg_int pour 2014
'''
period = period.this_year
cd_penali = simulation.calculate('cd_penali', period)
cd_acc75a = simulation.calculate('cd_acc75a', period)
cd_deddiv = simulation.calculate('cd_deddiv', period)
cd_eparet = simulation.calculate('cd_eparet', period)
cd_grorep = simulation.calculate('cd_grorep', period)
niches1 = cd_penali + cd_acc75a
# log.error("Charges déductibles to be checked because not defined for %s", 2014)
return period, niches1
In [10]:
#- CHANGEMENT DE L'ASSIETTE DE L'IRPP
#- variable rng (FoyersFiscaux):
#- La CSG déductible sur le patrimoine ne l'est plus
#- Les réductions d'impôts suivantes sont remplacées par des abattements : dfppce (dons aux oeuvres), donapd (dons aide à la personne), garext (frais de garde extérieur)
#- Les crédits d'impôt suivants sont remplacés par des abattements : aidper, ci_garext, quaenv, saldom2
#- Le revenu de base et le crédit familles monoparentales sont intégrés au revenu imposable
class rng(Variable):
def function(self, simulation, period):
'''
Revenu net global (total 20)
'''
period = period.this_year
rbg = simulation.calculate('rbg', period)
csg_deduc = simulation.calculate('csg_deduc', period)
charges_deduc = simulation.calculate('charges_deduc', period)
'''
Renvoie la somme des réductions d'impôt à intégrer pour l'année 2014 et + (non vérifiée)
'''
period = period.this_year
accult = simulation.calculate('accult', period)
adhcga = simulation.calculate('adhcga', period)
cappme = simulation.calculate('cappme', period)
creaen = simulation.calculate('creaen', period)
daepad = simulation.calculate('daepad', period)
deffor = simulation.calculate('deffor', period)
dfppce = simulation.calculate('dfppce', period)
doment = simulation.calculate('doment', period)
domlog = simulation.calculate('domlog', period)
donapd = simulation.calculate('donapd', period)
duflot = simulation.calculate('duflot', period)
ecpess = simulation.calculate('ecpess', period)
garext = simulation.calculate('garext', period)
intagr = simulation.calculate('intagr', period)
invfor = simulation.calculate('invfor', period)
invlst = simulation.calculate('invlst', period)
ip_net = simulation.calculate('ip_net', period)
locmeu = simulation.calculate('locmeu', period)
mecena = simulation.calculate('mecena', period)
mohist = simulation.calculate('mohist', period)
patnat = simulation.calculate('patnat', period)
prcomp = simulation.calculate('prcomp', period)
reduction_impot_exceptionnelle = simulation.calculate('reduction_impot_exceptionnelle', period)
repsoc = simulation.calculate('repsoc', period)
resimm = simulation.calculate('resimm', period)
rsceha = simulation.calculate('rsceha', period)
saldom = simulation.calculate('saldom', period)
scelli = simulation.calculate('scelli', period)
sofica = simulation.calculate('sofica', period)
spfcpi = simulation.calculate('spfcpi', period)
""" Crédits d'impôt crédités l'impôt sur les revenus de 2014 et + (non vérifié)"""
period = period.this_year
accult = simulation.calculate('accult', period)
aidper = simulation.calculate('aidper', period)
assloy = simulation.calculate('assloy', period)
autent = simulation.calculate('autent', period)
ci_garext = simulation.calculate('ci_garext', period)
cotsyn = simulation.calculate('cotsyn', period)
creimp = simulation.calculate('creimp', period)
direpa = simulation.calculate('direpa', period)
drbail = simulation.calculate('drbail', period)
inthab = simulation.calculate('inthab', period)
mecena = simulation.calculate('mecena', period)
preetu = simulation.calculate('preetu', period)
prlire = simulation.calculate('prlire', period)
quaenv = simulation.calculate('quaenv', period)
saldom2 = simulation.calculate('saldom2', period)
"""agrégation des RDB adultes + supplément famille monoparentale"""
rdb = self.sum_by_entity(rdb_holder)
sum_rdb_adulte = self.sum_by_entity(tspr_holder)
credit_impot_monoparentales_holder = simulation.calculate_add('credit_impot_monoparentales', period)
return period, max_(0, rbg + sum_rdb_adulte + credit_impot_monoparentales_holder - charges_deduc - (dfppce + donapd * garext) - (aidper, ci_garext, quaenv, saldom2))
In [11]:
#- variable ip_net - irpp après décote (foyer fiscal):
#- la décote est évacuée du calcul de l'impôt
class ip_net(Variable):
def function(self, simulation, period):
'''
irpp après décote
'''
period = period.this_year
ir_plaf_qf = simulation.calculate('ir_plaf_qf', period)
cncn_info_holder = simulation.compute('cncn_info', period)
decote = simulation.calculate('decote', period)
taux = simulation.legislation_at(period.start).ir.rpns.taux16
return period, max_(0, ir_plaf_qf + self.sum_by_entity(cncn_info_holder) * taux)
In [12]:
#- variable reductions (Foyers Fiscaux) :
#- Les réductions d'impôt sont toutes supprimées : accult, adhcga, assvie, cappme, creaen, daepad, deffor, doment, domlog, domsoc, duflot, ecodev, ecpess, intagr, intcon, intemp, invfor, invlst, invrev, ip_net, locmeu, mecena, mohist, patnat, prcomp, reduction_impot_exceptionnelle, repsoc, resimm, rsceha, saldom, scelli, sofica, sofipe, spfcpi
#- Rappelons que les réductions d'impôt suivantes avaient été basculées vers des abattements : dfppce (dons aux oeuvres), donapd (dons aide à la personne), garext (frais de garde extérieur)
class reductions(Variable):
@dated_function(start = date(2014, 1, 1)) # Not checked
def function_2014__(self, simulation, period):
'''
Renvoie la somme des réductions d'impôt à intégrer pour l'année 2014 et + (non vérifiée)
'''
period = period.this_year
accult = simulation.calculate('accult', period)
adhcga = simulation.calculate('adhcga', period)
cappme = simulation.calculate('cappme', period)
creaen = simulation.calculate('creaen', period)
daepad = simulation.calculate('daepad', period)
deffor = simulation.calculate('deffor', period)
dfppce = simulation.calculate('dfppce', period)
doment = simulation.calculate('doment', period)
domlog = simulation.calculate('domlog', period)
donapd = simulation.calculate('donapd', period)
duflot = simulation.calculate('duflot', period)
ecpess = simulation.calculate('ecpess', period)
garext = simulation.calculate('garext', period)
intagr = simulation.calculate('intagr', period)
invfor = simulation.calculate('invfor', period)
invlst = simulation.calculate('invlst', period)
ip_net = simulation.calculate('ip_net', period)
locmeu = simulation.calculate('locmeu', period)
mecena = simulation.calculate('mecena', period)
mohist = simulation.calculate('mohist', period)
patnat = simulation.calculate('patnat', period)
prcomp = simulation.calculate('prcomp', period)
reduction_impot_exceptionnelle = simulation.calculate('reduction_impot_exceptionnelle', period)
repsoc = simulation.calculate('repsoc', period)
resimm = simulation.calculate('resimm', period)
rsceha = simulation.calculate('rsceha', period)
saldom = simulation.calculate('saldom', period)
scelli = simulation.calculate('scelli', period)
sofica = simulation.calculate('sofica', period)
spfcpi = simulation.calculate('spfcpi', period)
total_reductions = 0
return period, min_(ip_net, total_reductions)
In [13]:
#- variable credits_impot (Foyers Fiscaux) :
#- Les crédits d'impôt sont tous supprimés : accult, acqgpl, aidmob, assloy, autent, cotsyn, creimp, creimp_exc_2008, direpa, divide, drbail, inthab, jeunes, mecena, percvm, preetu, prlire
#- Rappelons que les crédits d'impôt suivants savaient été basculés vers des abattements : aidper, ci_garext, quaenv, saldom2
class credits_impot(Variable):
def function(self, simulation, period):
""" Crédits d'impôt crédités l'impôt sur les revenus de 2014 et + (non vérifié)"""
period = period.this_year
accult = simulation.calculate('accult', period)
aidper = simulation.calculate('aidper', period)
assloy = simulation.calculate('assloy', period)
autent = simulation.calculate('autent', period)
ci_garext = simulation.calculate('ci_garext', period)
cotsyn = simulation.calculate('cotsyn', period)
creimp = simulation.calculate('creimp', period)
direpa = simulation.calculate('direpa', period)
drbail = simulation.calculate('drbail', period)
inthab = simulation.calculate('inthab', period)
mecena = simulation.calculate('mecena', period)
preetu = simulation.calculate('preetu', period)
prlire = simulation.calculate('prlire', period)
quaenv = simulation.calculate('quaenv', period)
saldom2 = simulation.calculate('saldom2', period)
return period, 0
In [14]:
#- Mise en place d'un revenu de base adulte égal à RSA socle célibataire - forfait logement célibataire
#- Pour les personnes en situation de handicap, le revenu de base est inclus dans l'Allocation Adulte Handicapé (AAH)
class rdb(Variable):
column = FloatCol
entity_class = Individus
label = u"Revenu de base"
def function(self, simulation, period):
period = period.start.offset('first-of', 'month').period('month')
age = simulation.calculate('age')
rmi = simulation.legislation_at(period.start).minim.rmi
retraite_brute = simulation.calculate('retraite_brute',period)
chomage_brut = simulation.calculate('chomage_brut',period)
aah = simulation.calculate('aah',period)
return period, max_(((age >= 18)* rmi.rmi * ( 1 -rmi.forfait_logement.taux1) + not_(age >= 18) * 0) - aah, 0)
In [15]:
# On enlève les enfants du calcul du nbptr (quotient_familial.enf*)
class nbptr(Variable):
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.enf1 : nb part 2 premiers enfants
quotient_familial.enf2 : nb part enfants de rang 3 ou plus
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)
maries_ou_pacses = simulation.calculate('maries_ou_pacses', period)
celibataire_ou_divorce = simulation.calculate('celibataire_ou_divorce', period)
veuf = simulation.calculate('veuf', period)
jeune_veuf = simulation.calculate('jeune_veuf', 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)
# # nombre de parts liées aux enfants à charge
# que des enfants en résidence alternée
enf1 = (no_pac & has_alt) * (quotient_familial.enf1 * min_(nbH, 2) * 0.5
+ quotient_familial.enf2 * max_(nbH - 2, 0) * 0.5)
# pas que des enfants en résidence alternée
enf2 = (has_pac & has_alt) * ((nb_pac == 1) * (quotient_familial.enf1 * min_(nbH, 1) * 0.5
+ quotient_familial.enf2 * max_(nbH - 1, 0) * 0.5) + (nb_pac > 1) * (quotient_familial.enf2 * nbH * 0.5))
# pas d'enfant en résidence alternée
enf3 = quotient_familial.enf1 * min_(nb_pac, 2) + quotient_familial.enf2 * max_((nb_pac - 2), 0)
enf = enf1 + enf2 + enf3
# # 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 + enf + n2 + n4
m = 1 + quotient_familial.conj + n2 + n4
# # veufs hors jeune_veuf
# v = 1 + enf + n2 + n3 + n5 + n6
v = 1 + n2 + n3 + n5 + n6
# # celib div
#c = 1 + enf + n2 + n3 + n6 + n7
c = 1 + n2 + n3 + n6 + n7
return period, (maries_ou_pacses | jeune_veuf) * m + (veuf & not_(jeune_veuf)) * v + celibataire_ou_divorce * c
In [16]:
# Suppression des allocations familiales
class af(Variable):
def function(self, simulation, period):
period = period.this_month
af_base = simulation.calculate('af_base', period)
af_majo = simulation.calculate('af_majo', period)
af_forf = simulation.calculate('af_forf', period)
#return period, af_base + af_majo + af_forf
return period, af_base * 0
In [17]:
# Suppression du complément familial
class cf(Variable):
def function(self, simulation, period):
'''
L'allocation de base de la paje n'est pas cumulable avec le complément familial
'''
period = period.this_month
paje_base = simulation.calculate('paje_base', period)
apje_temp = simulation.calculate('apje_temp', period)
ape_temp = simulation.calculate('ape_temp', period)
cf_montant = simulation.calculate('cf_montant', period)
residence_mayotte = simulation.calculate('residence_mayotte', period)
cf_brut = not_(paje_base) * (apje_temp <= cf_montant) * (ape_temp <= cf_montant) * cf_montant
# return period, not_(residence_mayotte) * round(cf_brut, 2)
return period, not_(residence_mayotte) * round(cf_brut, 2) * 0
In [18]:
# Suppression de l'allocation de rentrée scolaire
class ars(Variable):
def function(self, simulation, period):
'''
Allocation de rentrée scolaire brute de CRDS
'''
period_br = period.this_year
return period_br, self.zeros()
In [19]:
# Création d'un revenu de base enfant - Version individus au niveau des allocations familiales actuelles
class rdb_enf(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 + not_(age < 14) * 0.57) * bmaf * (age <= 18)
In [20]:
#- Mise en place d'un crédit d'impot familles monoparentales montant (150€)
class credit_impot_monoparentales(Variable):
column = FloatCol
entity_class = Menages
label = u"credit_impot_monoparentales"
def function(self, simulation, period):
period = period.start.offset('first-of', 'month').period('month')
nb_enf_a_charge = simulation.calculate('nombre_enfants_a_charge_menage',period)
caseT = simulation.calculate('caseT',period) #Egal True si le parent est isolé
#return period, or_(and_(age_holder >= 18, nb_enf_a_charge > 0, caseT), or_(age_holder < 18, nb_enf_a_charge <= 0, not_(caseT)) * 0) * 100
return period, (nb_enf_a_charge > 0) * (caseT) * 150
#Si le parent est isolé, avec au moins un enfant, et qu'il est majeur il reçoit la pension
In [21]:
#- Supprimer le RSA
class rsa_socle(Variable):
def function(self, simulation, period):
period = period.this_month
nb_par = simulation.calculate('nb_par', period)
eligib = simulation.calculate('rsa_eligibilite', period)
nb_enfant_rsa = simulation.calculate('nb_enfant_rsa', period)
rmi = simulation.legislation_at(period.start).minim.rmi
nbp = nb_par + nb_enfant_rsa
taux = (
1 +
(nbp >= 2) * rmi.txp2 +
(nbp >= 3) * rmi.txp3 +
(nbp >= 4) * ((nb_par == 1) * rmi.txps + (nb_par != 1) * rmi.txp3) +
max_(nbp - 4, 0) * rmi.txps
)
#on met à zéro
return period, eligib * rmi.rmi * taux * 0
In [22]:
#- Supprimer la prime d'activité (PPA)
class ppa(DatedVariable):
@dated_function(start = date(2016, 1, 1))
def function(self, simulation, period):
period = period.this_month
seuil_non_versement = simulation.legislation_at(period.start).minim.ppa.seuil_non_versement
# éligibilité étudiants
ppa_eligibilite_etudiants = simulation.calculate('ppa_eligibilite_etudiants', period)
m_1 = period.last_month
m_2 = m_1.last_month
m_3 = m_2.last_month
ppa = sum(simulation.calculate('ppa_fictive', period2, extra_params = [period])
for period2 in [m_1, m_2, m_3]) / 3
ppa = ppa * ppa_eligibilite_etudiants * (ppa >= seuil_non_versement)
return period, ppa*0
In [23]:
#- Intégrer le revenu de base au revenu disponible
#- (la ppe est maintenue dans cette simulation, jusqu'à sa disparition en 2016)
class revdisp(Variable):
def function(self, simulation, period):
'''
Revenu disponible - ménage
'men'
'''
period = period.start.period('year').offset('first-of')
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_holder = simulation.calculate_add('rdb', period)
credit_impot_monoparentales_holder = simulation.calculate_add('credit_impot_monoparentales', period)
rdb_enf_holder = simulation.calculate_add('rdb_enf', 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 = self.sum_by_entity(rdb_holder)
rdb_enf = self.sum_by_entity(rdb_enf_holder)
return period, rev_trav + pen + rev_cap + psoc + ppe + impo + rdb + credit_impot_monoparentales_holder + rdb_enf
In [24]:
# Legislation JSON related helpers
from openfisca_core import legislations, periods
def get_node(legislation_json, path):
'''
Return a node in the `legislation_json` tree at the given `path`.
'''
node = legislation_json
for key in path:
assert 'children' in node, 'Expected "children" key, got: {}'.format(legislation_json.keys())
assert key in node['children'], 'Expected "{}" key, got: {}'.format(key, legislation_json['children'].keys())
node = node['children'][key]
return node
def is_scale(node):
'''
Returns True if the given `node` is a "Scale" (Barème in French).
'''
return node.get('@type') == 'Scale' and isinstance(node.get('brackets'), list)
def replace_rate(scale_node, period, new_rate, old_rate=None, bracket_index=None):
'''
In a given `scale_node`, for a given `period`, replace either:
- an `old_rate` by a `new_rate`
- a `new_rate` given a `bracket_index`
Modifies the `scale_node`.
'''
assert bool(old_rate is not None) ^ bool(bracket_index is not None), 'You must provide either `old_rate` or `bracket_index`'
assert is_scale(scale_node), 'Scale node expected'
period = periods.period(period)
if bracket_index is not None:
bracket = scale_node['brackets'][bracket_index]
for rate in bracket['rate']:
if rate['start'] >= str(period.start) and ('stop' not in rate or rate['stop'] <= str(period.stop)):
rate['value'] = new_rate
elif old_rate is not None:
for bracket in scale_node['brackets']:
for rate in bracket['rate']:
if rate['value'] == old_rate and rate['start'] >= str(period.start) and (
'stop' not in rate or rate['stop'] <= str(period.stop)):
rate['value'] = new_rate
def at_instant(node, instant):
instant = str(periods.instant(instant))
dated_node = legislations.generate_dated_node_json(node, instant)
return dated_node
def print_json(node):
print(json.dumps(node, indent=2))
In [25]:
#- CHANGEMENT DU CALCUL DE L'IRPP
#- le barème est modifié avec les tranches 0%, 30%, 41%, 45%
#- les tranches sont modifiées : RDB adulte, XXXXX €, XXXXX €
def modify_legislation_json(reference_legislation_json):
ir_bareme = get_node(reference_legislation_json, ['ir', 'bareme'])
assert is_scale(ir_bareme)
period = periods.period(2016)
# print_json(at_instant(ir_bareme, period.start))
replace_rate(ir_bareme, period=period, bracket_index=0, new_rate=0.3)
replace_rate(ir_bareme, period=period, bracket_index=1, new_rate=0.3)
replace_rate(ir_bareme, period=period, bracket_index=2, new_rate=0.3)
# print_json(at_instant(ir_bareme, period.start))
return reference_legislation_json
In [26]:
class ReformeRevenuDeBase_IRPP(Reform):
name = u"Réforme Revenu de base par IRPP"
# On écrit dans la parenthèse ci-dessous toutes les variables que l'on a redéfinies
def apply(self):
for variable in [salaire_imposable, chomage_imposable, retraite_imposable, revenu_assimile_salaire_apres_abattements, credits_impot, cd1, rng, ip_net, rdb, nbptr, af, cf, ars, rdb_enf, credit_impot_monoparentales, rsa_socle, ppa, revdisp]:
self.update_variable(variable)
self.modify_legislation_json(modifier_function = modify_legislation_json)
In [27]:
reform = ReformeRevenuDeBase_IRPP(tax_benefit_system)
In [28]:
parent1_salaire_de_base = 60000
In [29]:
scenario_ref_individu_seul = tax_benefit_system.new_scenario().init_single_entity(
period = 2014,
parent1 = dict(
date_naissance = date(1980, 1, 1),
salaire_de_base = parent1_salaire_de_base,
statut_marital = u'Célibataire',
),
foyer_fiscal = dict(
caseT = True,
),
enfants = [
dict(
date_naissance = date(2010, 1, 1),
),
],
)
In [31]:
simulation_ref_individu_seul = scenario_ref_individu_seul.new_simulation(debug = True)
In [32]:
scenario_rdb_individu_seul = reform.new_scenario().init_single_entity(
period = 2014,
parent1 = dict(
date_naissance = date(1980, 1, 1),
salaire_de_base = parent1_salaire_de_base,
statut_marital = u'Célibataire',
),
foyer_fiscal = dict(
caseT = True,
),
enfants = [
dict(
date_naissance = date(2010, 1, 1),
),
],
)
In [33]:
simulation_rdb_individu_seul = scenario_rdb_individu_seul.new_simulation(debug = True)
Calculs de référence (revenu disponible, IR, RSA, CSG imposable/deductible, impot total)
In [34]:
simulation_ref_individu_seul.calculate('irpp')
Out[34]:
In [40]:
simulation_rdb_individu_seul.calculate('irpp')
In [36]:
simulation_ref_individu_seul.calculate_add('rsa')
Out[36]:
In [38]:
simulation_ref_individu_seul.calculate_add('csg_imposable_salaire')
Out[38]:
In [42]:
simulation_ref_individu_seul.calculate_add('csg_deductible_salaire')
Out[42]:
In [43]:
simulation_ref_individu_seul.calculate_add('tot_impot')
Out[43]:
Calculs avec réforme RDB (revenu disponible, IR, RSA, CSG imposable/deductible, impot total)
In [45]:
simulation_rdb_individu_seul.calculate('revdisp')
In [ ]:
simulation_rdb_individu_seul.calculate('irpp')
In [ ]:
simulation_rdb_individu_seul.calculate('csg_deductible_salaire')
In [ ]:
simulation_rdb_individu_seul.calculate('tot_impot')
In [ ]:
# trace
simulation_rdb_individu_seul.calculate('tot_impot')
#print web_tools.get_trace_tool_link(scenario, ['tot_impot'])
In [ ]: