Plafonnement de l'avantage du quotient conjugal dans le calcul de l'IRPP


In [51]:
from datetime import date

from openfisca_france import init_country
from openfisca_france.model.base import *

Adaptation pour faciliter l'usage de ce notebook

Ce correctif permet de redéfinir plusieurs fois la même variable sans provoquer d'erreur.

Variable avec formule

Variable avec différentes formules en fonction de la date

Système socio-fiscal


In [52]:
TaxBenefitSystem = init_country()
tax_benefit_system = TaxBenefitSystem()

Simulation


In [53]:
# age = 60
# ages = [12, 37, 28]

# jean_eric = {
#     'name': u'Jean-Éric',
#     'age': 33,
# }
# aurelie = dict(
#     name = u'Aurélie',
#     age = 33,
# )

# personnes = [aurelie, jean_eric]

In [54]:
scenario = tax_benefit_system.new_scenario().init_single_entity(
    period = 2014,
    parent1 = dict(
        birth = date(1980, 1, 1),
        salaire_de_base = 400000,
        statmarit = 5,
        ),
    parent2 = dict(
        birth = date(1980, 1, 1),
        salaire_imposable = 0,
        ),
    enfants = [
        ],
    )

simulation_exemple = scenario.new_simulation(debug = True)

In [55]:
simulation_exemple2 = tax_benefit_system.new_scenario().init_single_entity(
    period = 2014,
    parent1 = dict(
        birth = date(1980, 1, 1),
        salaire_de_base = 400000,
        ),
    enfants = [
        ],
    ).new_simulation(debug = True)

In [56]:
print "exemple 1",simulation_exemple.calculate("impo"), \
       ", exemple 2", simulation_exemple2.calculate("impo")


exemple 1 [ 0.] , exemple 2 [-140569.]

In [57]:
scenario = tax_benefit_system.new_scenario().init_single_entity(
    period = 2014,
    parent1 = dict(
        birth = date(1980, 1, 1),
        salaire_imposable = 400000,
        statmarit = 5,
        ),
    )

simulation_exemple = scenario.new_simulation(debug = True)

In [58]:
import json
import urllib
import webbrowser
def get_trace_tool_link(scenario, variables, api_url = u'http://api-test.openfisca.fr',
        trace_tool_url = u'http://www.openfisca.fr/outils/trace'):
    scenario_json = scenario.to_json()
    simulation_json = {
        'scenarios': [scenario_json],
        'variables': variables,
        }
    url = trace_tool_url + '?' + urllib.urlencode({
        'simulation': json.dumps(simulation_json),
        'api_url': api_url,
        })
    return url

In [59]:
print get_trace_tool_link(scenario, ["impo"])


http://www.openfisca.fr/outils/trace?api_url=http%3A%2F%2Fapi-test.openfisca.fr&simulation=%7B%22scenarios%22%3A+%5B%7B%22period%22%3A+%222014%22%2C+%22test_case%22%3A+%7B%22familles%22%3A+%5B%7B%22id%22%3A+0%2C+%22parents%22%3A+%5B%22ind0%22%5D%7D%5D%2C+%22foyers_fiscaux%22%3A+%5B%7B%22id%22%3A+0%2C+%22declarants%22%3A+%5B%22ind0%22%5D%7D%5D%2C+%22individus%22%3A+%5B%7B%22id%22%3A+%22ind0%22%2C+%22salaire_imposable%22%3A+400000.0%2C+%22statmarit%22%3A+5%2C+%22birth%22%3A+%221980-01-01%22%7D%5D%2C+%22menages%22%3A+%5B%7B%22id%22%3A+0%2C+%22personne_de_reference%22%3A+%22ind0%22%7D%5D%7D%7D%5D%2C+%22variables%22%3A+%5B%22impo%22%5D%7D

Réforme


In [60]:
from openfisca_core import reforms

from numpy import (datetime64, logical_and as and_, logical_not as not_, logical_or as or_, logical_xor as xor_,
    maximum as max_, minimum as min_, round)

In [61]:
Reform = reforms.make_reform(
    key = 'plafonnement_gain_quotient_conjugal',
    name = u"Réforme des cotisations pour un Revenu de base",
    reference = tax_benefit_system,
    )

In [62]:
class rev_cat_tspr_individuel(Reform.Variable):
    column = FloatCol
    entity_class = Individus
    label = u"Nouvelles cotisations contributives"

    def function(self, simulation, period):
        period = period.start.offset('first-of', 'year').period('year')
        tspr = simulation.calculate('tspr', period)
        indu_plaf_abat_pen = simulation.calculate('indu_plaf_abat_pen_individuel', period)
        return period, tspr + indu_plaf_abat_pen
    
class indu_plaf_abat_pen_individuel(Reform.Variable):
    column = FloatCol(default = 0)
    entity_class = Individus
    label = u"indu_plaf_abat_pen"

    def function(self, simulation, period):
        """
        Plafonnement de l'abattement de 10% sur les pensions du foyer
        'foy'
        """
        period = period.start.offset('first-of', 'year').period('year')
        abatpen = simulation.legislation_at(period.start).ir.tspr.abatpen

        pen_net = simulation.calculate('pen_net', period)
        rev_pen = simulation.calculate('rev_pen', period)
        print type(pen_net)

        abat = rev_pen - pen_net
        return period, abat - min_(abat, abatpen.max)

In [63]:
class rev_cat_individuel(Reform.Variable):
    column = FloatCol(default = 0)
    entity_class = Individus
    label = u"Revenus catégoriels"
    url = "http://www.insee.fr/fr/methodes/default.asp?page=definitions/revenus-categoriesl.htm"

    def function(self, simulation, period):
        '''
        Revenus Categoriels
        '''
        period = period.start.offset('first-of', 'year').period('year')
        rev_cat_tspr_individuel = simulation.calculate('rev_cat_tspr_individuel', period)
       # rev_cat_rvcm = simulation.calculate('rev_cat_rvcm', period)
       # rev_cat_rfon = simulation.calculate('rev_cat_rfon', period)
       # rev_cat_rpns = simulation.calculate('rev_cat_rpns', period)
       # rev_cat_pv = simulation.calculate('rev_cat_pv', period)

        return period, rev_cat_tspr_individuel # + rev_cat_rvcm + rev_cat_rfon + rev_cat_rpns + rev_cat_pv TODO :Add everything

In [64]:
class rbg_individuel(Reform.Variable):
    column = FloatCol(default = 0)
    entity_class = Individus
    label = u"Revenu brut global"
    url = "http://www.documentissime.fr/dossiers-droit-pratique/dossier-19-l-impot-sur-le-revenu-les-modalites-generales-d-imposition/la-determination-du-revenu-imposable/le-revenu-brut-global.html"

    def function(self, simulation, period):
        '''Revenu brut global
        '''
        period = period.start.offset('first-of', 'year').period('year')
        rev_cat_individuel = simulation.calculate('rev_cat_individuel', period)
       # deficit_ante = simulation.calculate('deficit_ante', period)
      #  f6gh = simulation.calculate('f6gh', period)
        #nbic_impm_individuel = simulation.calculate('nbic_impm', period)
        #nacc_pvce_individuel = simulation.calculate('nacc_pvce', period)
        cga = simulation.legislation_at(period.start).ir.rpns.cga_taux2

        # (Total 17)
        # sans les revenus au quotient
        #nacc_pvce = self.sum_by_entity(nacc_pvce_holder)
        return period, max_(0, rev_cat_individuel) # + f6gh + nbic_impm_individuel + nacc_pvce) * (1 + cga) - deficit_ante

In [65]:
class rng_individuel(Reform.Variable):
    column = FloatCol(default = 0)
    entity_class = Individus
    label = u"Revenu net global"
    url = "http://impotsurlerevenu.org/definitions/114-revenu-net-global.php"

    def function(self, simulation, period):
        ''' Revenu net global (total 20) '''
        period = period.start.offset('first-of', 'year').period('year')
        rbg_individuel = simulation.calculate('rbg_individuel', period)
        csg_deduc = simulation.calculate('csg_deduc', period)
        #print csg_deduc  #TODO : CHeck that, why is it a Foyer size ?
        charges_deduc = simulation.calculate('charges_deduc', period)

        return period, max_(0, rbg_individuel - csg_deduc - charges_deduc)

In [66]:
class rni_individuel(Reform.Variable):
    column = FloatCol(default = 0)
    entity_class = Individus
    label = u"Revenu net imposable"
    url = "http://impotsurlerevenu.org/definitions/115-revenu-net-imposable.php"

    def function(self, simulation, period):
        ''' Revenu net imposable ou déficit à reporter'''
        period = period.start.offset('first-of', 'year').period('year')
        rng_individuel = simulation.calculate('rng_individuel', period)
        #abat_spe = simulation.calculate('abat_spe', period)

        return period, rng_individuel #- abat_spe

In [67]:
class ir_brut_individuel(Reform.Variable):
    column = FloatCol(default = 0)
    entity_class = Individus
    label = u"Impot sur le revenu brut avant non imposabilité et plafonnement du quotient"

    def function(self, simulation, period):
        period = period.start.offset('first-of', 'month').period('year')
        nbptr_holder = simulation.compute('nbptr', period)
        nbptr_individualise = self.cast_from_entity_to_roles(nbptr_holder)
        nb_adult = simulation.calculate('nb_adult', period)
        nbptr_individuel = nbptr_individualise * (nb_adult == 1) + (nbptr_individualise/2) * (nb_adult == 2)    
        taux_effectif = simulation.calculate('taux_effectif', period)
        rni_individuel = simulation.calculate('rni_individuel', period)
        bareme = simulation.legislation_at(period.start).ir.bareme

        return period, (taux_effectif == 0) * nbptr_individuel * bareme.calc(rni_individuel / nbptr_individualise) + \
                        taux_effectif * rni_individuel

In [68]:
class ir_qf_conjugual_plafonne_revenu_de_base(Reform.Variable):
    column = FloatCol(default = 0)
    entity_class = FoyersFiscaux
    label = u""

    def function(self, simulation, period):
        period = period.start.offset('first-of', 'month').period('year')
        seuil = 6032
        ir_brut = simulation.calculate('ir_brut', period)
        ir_brut_individuel_holder = simulation.compute('ir_brut_individuel', period)
        ir_indivudel_somme = self.sum_by_entity(ir_brut_individuel_holder)
        ir_qf_conj_plaf = max_(ir_indivudel_somme- seuil, ir_brut )
        return period, ir_qf_conj_plaf

In [69]:
reform = Reform()

In [70]:
reform_simulation =  reform.new_scenario().init_single_entity(
                                                                period = 2014,
                                                                parent1 = dict(
                                                                    birth = date(1980, 1, 1),
                                                                    salaire_imposable = 400000,
                                                                    ),
                                                                parent2 = dict(
                                                                    birth = date(1980, 1, 1),
                                                                    salaire_imposable = 100000,
                                                                    ),
                                                                enfants = [
                                                                    ],
                                                                ).new_simulation(debug = True)

In [71]:
print reform_simulation.calculate('ir_qf_conjugual_plafonne_revenu_de_base')


<type 'numpy.ndarray'>
[ 195419.328125]

In [72]:
reform_simulation.calculate('irpp') - reform_simulation.calculate('ir_qf_conjugual_plafonne_revenu_de_base')


Out[72]:
array([-397673.9375], dtype=float32)

In [73]:
reform_simulation.calculate('rev_cat_individuel')


Out[73]:
array([ 387843.,   90000.], dtype=float32)

In [74]:
reform_simulation.calculate('cotisations_contributives')


---------------------------------------------------------------------------
KeyError                                  Traceback (most recent call last)
<ipython-input-74-c56b25471fe0> in <module>()
----> 1 reform_simulation.calculate('cotisations_contributives')

/home/openfisca/openfisca-core/openfisca_core/simulations.pyc in calculate(self, column_name, period, **parameters)
     74         if period is None:
     75             period = self.period
---> 76         return self.compute(column_name, period = period, **parameters).array
     77 
     78     def calculate_add(self, column_name, period = None, **parameters):

/home/openfisca/openfisca-core/openfisca_core/simulations.pyc in compute(self, column_name, period, **parameters)
    154             if variable_infos not in caller_input_variables_infos:
    155                 caller_input_variables_infos.append(variable_infos)
--> 156         holder = self.get_or_new_holder(column_name)
    157         return holder.compute(period = period, **parameters)
    158 

/home/openfisca/openfisca-core/openfisca_core/simulations.pyc in get_or_new_holder(self, column_name)
    229     def get_or_new_holder(self, column_name):
    230         holder = self.holder_by_name.get(column_name)
--> 231         entity = self.entity_by_column_name[column_name]
    232         if holder is None:
    233             column = entity.column_by_name[column_name]

KeyError: 'cotisations_contributives'

In [75]:
reform_simulation.calculate_add('nouv_salbrut')


---------------------------------------------------------------------------
KeyError                                  Traceback (most recent call last)
<ipython-input-75-8adbc8cbb2fd> in <module>()
----> 1 reform_simulation.calculate_add('nouv_salbrut')

/home/openfisca/openfisca-core/openfisca_core/simulations.pyc in calculate_add(self, column_name, period, **parameters)
     79         if period is None:
     80             period = self.period
---> 81         return self.compute_add(column_name, period = period, **parameters).array
     82 
     83     def calculate_add_divide(self, column_name, period = None, **parameters):

/home/openfisca/openfisca-core/openfisca_core/simulations.pyc in compute_add(self, column_name, period, **parameters)
    168             if variable_infos not in caller_input_variables_infos:
    169                 caller_input_variables_infos.append(variable_infos)
--> 170         holder = self.get_or_new_holder(column_name)
    171         return holder.compute_add(period = period, **parameters)
    172 

/home/openfisca/openfisca-core/openfisca_core/simulations.pyc in get_or_new_holder(self, column_name)
    229     def get_or_new_holder(self, column_name):
    230         holder = self.holder_by_name.get(column_name)
--> 231         entity = self.entity_by_column_name[column_name]
    232         if holder is None:
    233             column = entity.column_by_name[column_name]

KeyError: 'nouv_salbrut'

In [76]:
reform_simulation.calculate('salbrut')


---------------------------------------------------------------------------
KeyError                                  Traceback (most recent call last)
<ipython-input-76-f415b040beea> in <module>()
----> 1 reform_simulation.calculate('salbrut')

/home/openfisca/openfisca-core/openfisca_core/simulations.pyc in calculate(self, column_name, period, **parameters)
     74         if period is None:
     75             period = self.period
---> 76         return self.compute(column_name, period = period, **parameters).array
     77 
     78     def calculate_add(self, column_name, period = None, **parameters):

/home/openfisca/openfisca-core/openfisca_core/simulations.pyc in compute(self, column_name, period, **parameters)
    154             if variable_infos not in caller_input_variables_infos:
    155                 caller_input_variables_infos.append(variable_infos)
--> 156         holder = self.get_or_new_holder(column_name)
    157         return holder.compute(period = period, **parameters)
    158 

/home/openfisca/openfisca-core/openfisca_core/simulations.pyc in get_or_new_holder(self, column_name)
    229     def get_or_new_holder(self, column_name):
    230         holder = self.holder_by_name.get(column_name)
--> 231         entity = self.entity_by_column_name[column_name]
    232         if holder is None:
    233             column = entity.column_by_name[column_name]

KeyError: 'salbrut'

In [77]:
reform_simulation.calculate('salnet')


---------------------------------------------------------------------------
KeyError                                  Traceback (most recent call last)
<ipython-input-77-d22f98d7cee6> in <module>()
----> 1 reform_simulation.calculate('salnet')

/home/openfisca/openfisca-core/openfisca_core/simulations.pyc in calculate(self, column_name, period, **parameters)
     74         if period is None:
     75             period = self.period
---> 76         return self.compute(column_name, period = period, **parameters).array
     77 
     78     def calculate_add(self, column_name, period = None, **parameters):

/home/openfisca/openfisca-core/openfisca_core/simulations.pyc in compute(self, column_name, period, **parameters)
    154             if variable_infos not in caller_input_variables_infos:
    155                 caller_input_variables_infos.append(variable_infos)
--> 156         holder = self.get_or_new_holder(column_name)
    157         return holder.compute(period = period, **parameters)
    158 

/home/openfisca/openfisca-core/openfisca_core/simulations.pyc in get_or_new_holder(self, column_name)
    229     def get_or_new_holder(self, column_name):
    230         holder = self.holder_by_name.get(column_name)
--> 231         entity = self.entity_by_column_name[column_name]
    232         if holder is None:
    233             column = entity.column_by_name[column_name]

KeyError: 'salnet'

In [ ]:
#