Example #1
0
def build_reform(tax_benefit_system):
    Reform = reforms.make_reform(
        key = 'plf2015',
        name = u'Projet de Loi de Finances 2015',
        reference = tax_benefit_system,
        )

    @Reform.formula
    class decote(formulas.SimpleFormulaColumn):
        label = u"Nouvelle décote 2015"
        reference = ir.decote

        def function(self, simulation, period):
            period = period.start.offset('first-of', 'year').period('year')
            ir_plaf_qf = simulation.calculate('ir_plaf_qf', period)
            nb_adult = simulation.calculate('nb_adult', period)
            plf = simulation.legislation_at(period.start).plf2015

            decote_celib = (ir_plaf_qf < plf.decote_seuil_celib) * (plf.decote_seuil_celib - ir_plaf_qf)
            decote_couple = (ir_plaf_qf < plf.decote_seuil_couple) * (plf.decote_seuil_couple - ir_plaf_qf)
            return period, (nb_adult == 1) * decote_celib + (nb_adult == 2) * decote_couple

    reform = Reform()
    reform.modify_legislation_json(modifier_function = modify_legislation_json)
    return reform
def test_check():
    for employee_type, test_parameters in test_case_by_employee_type.iteritems():
        Reform = reforms.make_reform(
            key = u'smic_h_b_9_euros',
            name = u"Réforme pour simulation ACOSS SMIC horaire brut fixe à 9 euros",
            reference = tax_benefit_system,
            )
        reform = Reform()
        reform.modify_legislation_json(modifier_function = modify_legislation_json)

        simulation_period = 2011
        parent1 = dict(
            birth = datetime.date(periods.period(simulation_period).start.year - 40, 1, 1),
            )
        parent1.update(test_parameters['input_variables'])

        simulation = reform.new_scenario().init_single_entity(
            period = simulation_period,
            parent1 = parent1,
            ).new_simulation(debug = True)

        for variable, amounts in test_parameters['output_variables'].iteritems():
            if isinstance(amounts, dict):
                for period_str, amount in sorted(amounts.iteritems()):
                    output = simulation.calculate_add_divide(variable, period = periods.period(period_str))
                    variable_message = "{} at {}".format(variable, period_str)
                    yield assert_variable, variable_message, employee_type, amount, output
            else:
                output = simulation.calculate(variable)
                variable_message = variable
                amount = amounts
                yield assert_variable, variable_message, employee_type, amount, output
Example #3
0
def test_check():
    Reform = reforms.make_reform(
        key=u'smic_h_b_9_euros',
        name=u"Réforme pour simulation ACOSS SMIC horaire brut fixe à 9 euros",
        reference=tax_benefit_system,
    )
    reform = Reform()
    reform.modify_legislation_json(modifier_function=modify_legislation_json)

    for employee_type, test_parameters in test_case_by_employee_type.iteritems(
    ):
        simulation_period = 2013
        parent1 = dict(date_naissance=datetime.date(
            periods.period(simulation_period).start.year - 40, 1, 1), )
        parent1.update(test_parameters['input_variables'])

        simulation = reform.new_scenario().init_single_entity(
            period=simulation_period,
            parent1=parent1,
        ).new_simulation()

        for variable, amounts in test_parameters['output_variables'].iteritems(
        ):
            if isinstance(amounts, dict):
                for period_str, amount in sorted(amounts.iteritems()):
                    output = simulation.calculate_add_divide(
                        variable, period=periods.period(period_str))
                    variable_message = "{} at {}".format(variable, period_str)
                    yield assert_variable, variable_message, employee_type, amount, output
            else:
                output = simulation.calculate(variable)
                variable_message = variable
                amount = amounts
                yield assert_variable, variable_message, employee_type, amount, output
Example #4
0
def build_reform(tax_benefit_system):
    Reform = reforms.make_reform(
        key = 'plf2016',
        name = u'Projet de Loi de Finances 2016 appliquée aux revenus 2014',
        reference = tax_benefit_system,
        )

    class decote(Reform.DatedVariable):
        label = u"Décote IR 2016 appliquée en 2015 sur revenus 2014"
        reference = ir.decote

        @dated_function(start = date(2014, 1, 1), stop = date(2014, 12, 31))
        def function_2014(self, simulation, period):
            period = period.start.offset('first-of', 'year').period('year')
            ir_plaf_qf = simulation.calculate('ir_plaf_qf', period)
            nb_adult = simulation.calculate('nb_adult', period)
            plf = simulation.legislation_at(period.start).plf2016

            decote_celib = (ir_plaf_qf < plf.decote_seuil_celib) * (plf.decote_seuil_celib - .75 * ir_plaf_qf)
            decote_couple = (ir_plaf_qf < plf.decote_seuil_couple) * (plf.decote_seuil_couple - .75 * ir_plaf_qf)
            return period, (nb_adult == 1) * decote_celib + (nb_adult == 2) * decote_couple

    reform = Reform()
    reform.modify_legislation_json(modifier_function = modify_legislation_json)
    return reform
def build_reform(tax_benefit_system):
    Reform = reforms.make_reform(
        name = u'Inversion des revenus',
        new_formulas = (chobrut, rstbrut, salbrut),
        reference = tax_benefit_system,
        )
    return Reform()
Example #6
0
def build_counterfactual_reform(tax_benefit_system):
    Reform = reforms.make_reform(
        key='plf2016_counterfactual',
        name=u'Contrefactuel du PLF 2016 sur les revenus 2015',
        reference=tax_benefit_system,
    )

    class decote(Reform.DatedVariable):
        label = u"Décote IR 2015 appliquée sur revenus 2015 (contrefactuel)"
        reference = ir.decote

        @dated_function(start=date(2015, 1, 1))
        def function_2015__(self, simulation, period):
            period = period.start.offset('first-of', 'year').period('year')
            ir_plaf_qf = simulation.calculate('ir_plaf_qf', period)
            nb_adult = simulation.calculate('nb_adult', period)
            plf2016 = simulation.legislation_at(
                period.start).plf2016_conterfactual
            decote_seuil_celib = plf2016.decote_seuil_celib
            decote_seuil_couple = plf2016.decote_seuil_couple

            decote_celib = (ir_plaf_qf < decote_seuil_celib) * (
                decote_seuil_celib - ir_plaf_qf)
            decote_couple = (ir_plaf_qf < decote_seuil_couple) * (
                decote_seuil_couple - ir_plaf_qf)

            return period, (nb_adult == 1) * decote_celib + (
                nb_adult == 2) * decote_couple

    reform = Reform()
    reform.modify_legislation_json(
        modifier_function=counterfactual_modify_legislation_json)
    return reform
Example #7
0
def build_counterfactual_reform(tax_benefit_system):
    Reform = reforms.make_reform(
        key = 'plf2016_counterfactual',
        name = u'Contrefactuel du PLF 2016 sur les revenus 2015',
        reference = tax_benefit_system,
        )

    class decote(Reform.DatedVariable):
        label = u"Décote IR 2015 appliquée sur revenus 2015 (contrefactuel)"
        reference = ir.decote

        @dated_function(start = date(2015, 1, 1))
        def function_2015__(self, simulation, period):
            period = period.start.offset('first-of', 'year').period('year')
            ir_plaf_qf = simulation.calculate('ir_plaf_qf', period)
            nb_adult = simulation.calculate('nb_adult', period)
            plf2016 = simulation.legislation_at(period.start).plf2016_conterfactual
            decote_seuil_celib = plf2016.decote_seuil_celib
            decote_seuil_couple = plf2016.decote_seuil_couple

            decote_celib = (ir_plaf_qf < decote_seuil_celib) * (decote_seuil_celib - ir_plaf_qf)
            decote_couple = (ir_plaf_qf < decote_seuil_couple) * (decote_seuil_couple - ir_plaf_qf)

            return period, (nb_adult == 1) * decote_celib + (nb_adult == 2) * decote_couple

    reform = Reform()
    reform.modify_legislation_json(modifier_function = counterfactual_modify_legislation_json)
    return reform
def build_reform(tax_benefit_system):
    reference_legislation_json = tax_benefit_system.legislation_json
    reform_legislation_json = copy.deepcopy(reference_legislation_json)
    reform_year = 2014
    reform_period = periods.period('year', reform_year)

    reform_legislation_json = reforms.update_legislation(
        legislation_json = reform_legislation_json,
        path = ('children', 'ir', 'children', 'bareme', 'brackets', 1, 'rate'),
        period = reform_period,
        value = 0,
        )
    reform_legislation_json = reforms.update_legislation(
        legislation_json = reform_legislation_json,
        path = ('children', 'ir', 'children', 'bareme', 'brackets', 2, 'threshold'),
        period = reform_period,
        value = 9690,
        )
    reform_legislation_json['children'].update(reform_legislation_subtree)

    Reform = reforms.make_reform(
        legislation_json = reform_legislation_json,
        name = u'PLF2015',
        new_formulas = (decote, ),
        reference = tax_benefit_system,
        )
    return Reform()
Example #9
0
def build_reform(tax_benefit_system):
    Reform = reforms.make_reform(
        key='plf2015',
        name=u'Projet de Loi de Finances 2015 appliquée aux revenus 2013',
        reference=tax_benefit_system,
    )

    class decote(Reform.DatedVariable):
        label = u"Décote IR 2015 appliquée sur IR 2014 (revenus 2013)"
        reference = ir.decote

        @dated_function(start=date(2013, 1, 1), stop=date(2013, 12, 31))
        def function_2013(self, simulation, period):
            period = period.this_year
            ir_plaf_qf = simulation.calculate('ir_plaf_qf', period)
            nb_adult = simulation.calculate('nb_adult', period)
            plf = simulation.legislation_at(period.start).plf2015

            decote_celib = (ir_plaf_qf < plf.seuil_celib) * (plf.seuil_celib -
                                                             ir_plaf_qf)
            decote_couple = (ir_plaf_qf < plf.seuil_couple) * (
                plf.seuil_couple - ir_plaf_qf)
            return period, (nb_adult == 1) * decote_celib + (
                nb_adult == 2) * decote_couple

    reform = Reform()
    reform.modify_legislation_json(modifier_function=modify_legislation_json)
    return reform
def build_reform(tax_benefit_system):

    Reform = reforms.make_reform(
        name = u'Réforme 1',
        reference = tax_benefit_system,
    )

    @Reform.formula
    class cmu_base_ressources(formulas.SimpleFormulaColumn):
        reference = cmu.cmu_base_ressources

    def function(self, simulation, period):
        self.reference
        period = period.start.offset('first-of', 'month').period('month')
        previous_year = period.start.period('year').offset(-1)
        aspa = simulation.calculate('aspa', period)
        ass = simulation.calculate('ass', period)
        asi = simulation.calculate('asi', period)
        af = simulation.calculate('af', period)
        cf = simulation.calculate_divide('cf', period)
        asf = simulation.calculate_divide('asf', period)
        paje_clca = simulation.calculate_add('paje_clca', previous_year)
        paje_prepare = simulation.calculate_add('paje_prepare', previous_year)
        statut_occupation_holder = simulation.compute('statut_occupation', period)
        aide_logement = simulation.calculate('aide_logement', period)
        cmu_forfait_logement_base = simulation.calculate('cmu_forfait_logement_base', period)
        cmu_forfait_logement_al = simulation.calculate('cmu_forfait_logement_al', period)
        age_holder = simulation.compute('age', period)
        cmu_base_ressources_i_holder = simulation.compute('cmu_base_ressources_i', period)
        P = simulation.legislation_at(period.start).cmu

        statut_occupation = self.cast_from_entity_to_roles(statut_occupation_holder)
        statut_occupation = self.filter_role(statut_occupation, role = CHEF)

        cmu_br_i_par = self.split_by_roles(cmu_base_ressources_i_holder, roles = [CHEF, PART])
        cmu_br_i_pac = self.split_by_roles(cmu_base_ressources_i_holder, roles = ENFS)

        age_pac = self.split_by_roles(age_holder, roles = ENFS)

        forfait_logement = (((statut_occupation == 2) + (statut_occupation == 6)) * cmu_forfait_logement_base +
            (aide_logement > 0) * min_(cmu_forfait_logement_al, aide_logement * 12))

        res = cmu_br_i_par[CHEF] + cmu_br_i_par[PART] + forfait_logement

        # Prestations calculées, donc valeurs mensuelles. On estime l'annuel en multipliant par 12
        res += 12 * (aspa + ass + asi + af + cf + asf)

        res += paje_clca + paje_prepare

        for key, age in age_pac.iteritems():
            res += (0 <= age) * (age <= P.age_limite_pac) * cmu_br_i_pac[key]

        return period, res

    return Reform()
def build_reform(tax_benefit_system):
    reference_legislation_json = tax_benefit_system.legislation_json
    reform_legislation_json = copy.deepcopy(reference_legislation_json)
    reform_legislation_json['children'].update(reform_legislation_subtree)
    Reform = reforms.make_reform(
        legislation_json = reform_legislation_json,
        name = u"Contribution execptionnelle sur les très hauts revenus d'activité (invalidée par le CC)",
        new_formulas = (cesthra, irpp),
        reference = tax_benefit_system,
        )
    return Reform()
Example #12
0
def build_reform(tax_benefit_system):
    # reference_legislation_json = tax_benefit_system.legislation_json
    # reform_legislation_json = copy.deepcopy(reference_legislation_json)
    # reform_legislation_json['children'].update(reform_legislation_subtree)
    Reform = reforms.make_reform(
        # legislation_json = reform_legislation_json,
        name=u'Pas de réduction d impôt ',
        new_formulas=[iaidrdi],
        reference=tax_benefit_system,
    )
    return Reform()
def build_reform(tax_benefit_system):
    reference_legislation_json = tax_benefit_system.legislation_json
    reform_legislation_json = copy.deepcopy(reference_legislation_json)
    reform_legislation_json['children'].update(reform_legislation_subtree)
    Reform = reforms.make_reform(
        legislation_json = reform_legislation_json,
        name = u'Allocations familiales imposables',
        new_formulas = (rbg, rfr, allocations_familiales_imposables),
        reference = tax_benefit_system,
        )
    return Reform()
def build_reform(tax_benefit_system):
    reference_legislation_json = tax_benefit_system.legislation_json
    reform_legislation_json = copy.deepcopy(reference_legislation_json)
    reform_legislation_json['children'].update(reform_legislation_subtree)
    Reform = reforms.make_reform(
        legislation_json = reform_legislation_json,
        name = u'PLFR 2014',
        new_formulas = (reduction_impot_exceptionnelle, reductions),
        reference = tax_benefit_system,
        )
    return Reform()
Example #15
0
def build_reform(tax_benefit_system):
#    reference_legislation_json = tax_benefit_system.legislation_json
#    reform_legislation_json = copy.deepcopy(reference_legislation_json)
#    reform_legislation_json['children'].update(reform_legislation_subtree)
    Reform = reforms.make_reform(
#        legislation_json = reform_legislation_json,
        name = u'Pas de charge deductible',
        new_formulas = (rng,),
        reference = tax_benefit_system,
        )
    return Reform()
Example #16
0
def build_reform(tax_benefit_system):
    Reform = reforms.make_reform(
        key='cesthra_invalidee',
        name=
        u"Contribution execptionnelle sur les très hauts revenus d'activité (invalidée par le CC)",
        reference=tax_benefit_system,
    )

    class cesthra(Reform.Variable):
        column = columns.FloatCol
        entity_class = entities.FoyersFiscaux
        label = u"Contribution exceptionnelle de solidarité sur les très hauts revenus d'activité"

        # PLF 2013 (rejeté) : 'taxe à 75%'

        def function(self, simulation, period):
            period = period.this_year
            salaire_imposable_holder = simulation.calculate(
                "salaire_imposable", period)
            law_cesthra = simulation.legislation_at(period.start).cesthra
            salaire_imposable = self.split_by_roles(salaire_imposable_holder)

            cesthra = 0
            for rev in salaire_imposable.itervalues():
                cesthra += max_(rev - law_cesthra.seuil, 0) * law_cesthra.taux
            return period, cesthra

    class irpp(Reform.Variable):
        label = u"Impôt sur le revenu des personnes physiques (réformée pour intégrer la cesthra)"
        reference = ir.irpp

        def function(self, simulation, period):
            '''
            Montant après seuil de recouvrement (hors ppe)
            '''
            period = period.this_year
            iai = simulation.calculate('iai', period)
            credits_impot = simulation.calculate('credits_impot', period)
            cehr = simulation.calculate('cehr', period)
            cesthra = simulation.calculate('cesthra', period=period)
            P = simulation.legislation_at(period.start).ir.recouvrement

            pre_result = iai - credits_impot + cehr + cesthra
            return period, ((iai > P.seuil) *
                            ((pre_result < P.min) *
                             (pre_result > 0) * iai * 0 +
                             ((pre_result <= 0) + (pre_result >= P.min)) *
                             (-pre_result)) + (iai <= P.seuil) *
                            ((pre_result < 0) * (-pre_result) +
                             (pre_result >= 0) * 0 * iai))

    reform = Reform()
    reform.modify_legislation_json(modifier_function=modify_legislation_json)
    return reform
Example #17
0
def build_reform(tax_benefit_system):
    # reference_legislation_json = tax_benefit_system.legislation_json
    # reform_legislation_json = copy.deepcopy(reference_legislation_json)
    # reform_legislation_json['children'].update(reform_legislation_subtree)
    Reform = reforms.make_reform(
        # legislation_json = reform_legislation_json,
        name=u'Revenu imposable + 10',
        new_formulas=[rni],
        reference=tax_benefit_system,
    )
    return Reform()
def build_reform(tax_benefit_system):
    reference_legislation_json = tax_benefit_system.legislation_json
    reform_legislation_json = copy.deepcopy(reference_legislation_json)
    reform_legislation_json['children'].update(reform_legislation_subtree)
    Reform = reforms.make_reform(
        legislation_json = reform_legislation_json,
        name = u'Loyer comme charge déductible (Trannoy-Wasmer)',
        new_formulas = (charges_deduc, charge_loyer),
        reference = tax_benefit_system,
        )
    return Reform()
Example #19
0
def build_reform(tax_benefit_system):
    # reference_legislation_json = tax_benefit_system.legislation_json
    # reform_legislation_json = copy.deepcopy(reference_legislation_json)
    # reform_legislation_json['children'].update(reform_legislation_subtree)
    Reform = reforms.make_reform(
        # legislation_json = reform_legislation_json,
        name = u'Pas de réduction d impôt ',
        new_formulas = [iaidrdi],
        reference = tax_benefit_system,
        )
    return Reform()
Example #20
0
def build_reform(tax_benefit_system):
    # reference_legislation_json = tax_benefit_system.legislation_json
    # reform_legislation_json = copy.deepcopy(reference_legislation_json)
    # reform_legislation_json['children'].update(reform_legislation_subtree)
    Reform = reforms.make_reform(
        #        legislation_json = reform_legislation_json,
        name=u'Pas de charge deductible',
        new_formulas=(rng, ),
        reference=tax_benefit_system,
    )
    return Reform()
def build_reform(tax_benefit_system):

    Reform = reforms.make_reform(
        key='de_net_a_brut',
        name=u'Inversion du calcul brut -> net',
        reference=tax_benefit_system,
    )

    class salaire_de_base(Reform.Variable):
        column = columns.FloatCol
        entity_class = entities.Individus
        label = u"Salaire brut ou traitement indiciaire brut"
        reference = tax_benefit_system.column_by_name["salaire_de_base"]
        url = u"http://www.trader-finance.fr/lexique-finance/definition-lettre-S/Salaire-brut.html"

        def function(self, simulation, period):
            # Calcule le salaire brut à partir du salaire net par inversion numérique.

            net = simulation.get_array('salaire_net_a_payer', period)

            assert net is not None

            simulation = self.holder.entity.simulation

            # List of variables already calculated. We will need it to remove their holders,
            # that might contain undesired cache
            requested_variable_names = simulation.requested_periods_by_variable_name.keys(
            )
            if requested_variable_names:
                requested_variable_names.remove(u'salaire_de_base')
            # Clean 'requested_periods_by_variable_name', that is used by -core to check for computation cycles.
            # This variable, salaire_de_base, might have been called from variable X,
            # that will be calculated again in our iterations to compute the salaire_net requested
            # as an input variable, hence producing a cycle error
            simulation.requested_periods_by_variable_name = dict()

            def solve_func(net):
                def innerfunc(essai):
                    return calculate_net_from(essai, simulation, period,
                                              requested_variable_names) - net

                return innerfunc

            brut_calcule = \
                fsolve(
                    solve_func(net),
                    net*1.5,  # on entend souvent parler cette méthode...
                    xtol = 1/10  # précision
                    )

            return period, brut_calcule

    return Reform()
Example #22
0
def build_reform(tax_benefit_system):
    reference_legislation_json = tax_benefit_system.legislation_json
    reform_legislation_json = copy.deepcopy(reference_legislation_json)
    reform_year = 2007
    reform_period = periods.period('year', reform_year)

    def update_threshold_bracket(bracket, amount):
        return reforms.update_legislation(
            legislation_json = reform_legislation_json,
            path = ('children', 'ir', 'children', 'bareme', 'brackets', bracket, 'threshold'),
            period = reform_period,
            value = amount,
            )

    def update_rate_bracket(bracket, rate):
        return reforms.update_legislation(
            legislation_json = reform_legislation_json,
            path = ('children', 'ir', 'children', 'bareme', 'brackets', bracket, 'rate'),
            period = reform_period,
            value = rate,
            )

    reform_legislation_json = update_rate_bracket(bracket = 0, rate = 0)
    reform_legislation_json = update_rate_bracket(bracket = 1, rate = .0683)
    reform_legislation_json = update_rate_bracket(bracket = 2, rate = .1914)
    reform_legislation_json = update_rate_bracket(bracket = 3, rate = .2826)
    reform_legislation_json = update_rate_bracket(bracket = 4, rate = .3738)
    reform_legislation_json = update_rate_bracket(bracket = 5, rate = .4262)
    reform_legislation_json = update_rate_bracket(bracket = 6, rate = .4809)

    inflation = 1
    reform_legislation_json = update_threshold_bracket(bracket = 0, amount = 0)
    reform_legislation_json = update_threshold_bracket(bracket = 1, amount = 4412 * inflation)
    reform_legislation_json = update_threshold_bracket(bracket = 2, amount = 8677 * inflation)
    reform_legislation_json = update_threshold_bracket(bracket = 3, amount = 15274 * inflation)
    reform_legislation_json = update_threshold_bracket(bracket = 4, amount = 24731 * inflation)
    reform_legislation_json = update_threshold_bracket(bracket = 5, amount = 40241 * inflation)
    reform_legislation_json = update_threshold_bracket(bracket = 6, amount = 49624 * inflation)

    reform_legislation_json = reforms.update_legislation(
        legislation_json = reform_legislation_json,
        path = ('children', 'ir', 'children', 'tspr', 'children', 'sabatsalpen'),
        period = reform_period,
        value = 0,
        )

    Reform = reforms.make_reform(
        legislation_json = reform_legislation_json,
        name = u'ir_2006',
        new_formulas = (),
        reference = tax_benefit_system,
        )
    return Reform()
def build_reform(tax_benefit_system):
    Reform = reforms.make_reform(
        key = 'cesthra_invalidee',
        name = u"Contribution execptionnelle sur les très hauts revenus d'activité (invalidée par le CC)",
        reference = tax_benefit_system,
        )

    @Reform.formula
    class cesthra(formulas.SimpleFormulaColumn):
        column = columns.FloatCol
        entity_class = entities.FoyersFiscaux
        label = u"Contribution exceptionnelle de solidarité sur les très hauts revenus d'activité"
        # PLF 2013 (rejeté) : 'taxe à 75%'

        def function(self, simulation, period):
            period = period.start.offset('first-of', 'year').period('year')
            salaire_imposable_holder = simulation.calculate("salaire_imposable", period)
            law_cesthra = simulation.legislation_at(period.start).cesthra
            salaire_imposable = self.split_by_roles(salaire_imposable_holder)

            cesthra = 0
            for rev in salaire_imposable.itervalues():
                cesthra += max_(rev - law_cesthra.seuil, 0) * law_cesthra.taux
            return period, cesthra

    @Reform.formula
    class irpp(formulas.SimpleFormulaColumn):
        label = u"Impôt sur le revenu des personnes physiques (réformée pour intégrer la cesthra)"
        reference = ir.irpp

        def function(self, simulation, period):
            '''
            Montant après seuil de recouvrement (hors ppe)
            '''
            period = period.start.offset('first-of', 'year').period('year')
            iai = simulation.calculate('iai', period)
            credits_impot = simulation.calculate('credits_impot', period)
            cehr = simulation.calculate('cehr', period)
            cesthra = simulation.calculate('cesthra', period = period)
            P = simulation.legislation_at(period.start).ir.recouvrement

            pre_result = iai - credits_impot + cehr + cesthra
            return period, ((iai > P.seuil) *
                ((pre_result < P.min) * (pre_result > 0) * iai * 0 +
                ((pre_result <= 0) + (pre_result >= P.min)) * (- pre_result)) +
                (iai <= P.seuil) * ((pre_result < 0) * (-pre_result) +
                (pre_result >= 0) * 0 * iai))

    reform = Reform()
    reform.modify_legislation_json(modifier_function = modify_legislation_json)
    return reform
def build_reform(tax_benefit_system):
    # Removing the formula starting in 2015-07-01
    # TODO: improve because very dirty
    # may be by creating the following functions
    # get_formulas(entity, variable, period), set_formulas(entity, variable, period)

    Reform = reforms.make_reform(
        key = 'plafond_qf_enfant_unlimited',
        name = u"Legislion du plafond qf de 2012 et des af sans modulations",
        reference = tax_benefit_system,
        )
    reform = Reform()
    reform.modify_legislation_json(modifier_function = modify_legislation_json)
    return reform
Example #25
0
def build_reform(tax_benefit_system):

    Reform = reforms.make_reform(
        key = 'de_net_a_brut',
        name = u'Inversion du calcul brut -> net',
        reference = tax_benefit_system,
        )

    class salaire_de_base(Reform.Variable):
        column = columns.FloatCol
        entity_class = entities.Individus
        label = u"Salaire brut ou traitement indiciaire brut"
        reference = tax_benefit_system.column_by_name["salaire_de_base"]
        url = u"http://www.trader-finance.fr/lexique-finance/definition-lettre-S/Salaire-brut.html"

        def function(self, simulation, period):
            # Calcule le salaire brut à partir du salaire net par inversion numérique.

            net = simulation.get_array('salaire_net_a_payer', period)

            assert net is not None

            simulation = self.holder.entity.simulation

            # List of variables already calculated. We will need it to remove their holders,
            # that might contain undesired cache
            requested_variable_names = simulation.requested_periods_by_variable_name.keys()
            if requested_variable_names:
                requested_variable_names.remove(u'salaire_de_base')
            # Clean 'requested_periods_by_variable_name', that is used by -core to check for computation cycles.
            # This variable, salaire_de_base, might have been called from variable X,
            # that will be calculated again in our iterations to compute the salaire_net requested
            # as an input variable, hence producing a cycle error
            simulation.requested_periods_by_variable_name = dict()

            def solve_func(net):
                def innerfunc(essai):
                    return calculate_net_from(essai, simulation, period, requested_variable_names) - net
                return innerfunc

            brut_calcule = \
                fsolve(
                    solve_func(net),
                    net*1.5,  # on entend souvent parler cette méthode...
                    xtol = 1/10  # précision
                    )

            return period, brut_calcule

    return Reform()
def create_simulation(year = 2014, bareme = False):

    simulation_period = periods.period('year', year)
    reference_legislation_json = tax_benefit_system.legislation_json
    reform_legislation_json = reforms.update_legislation(
        legislation_json = reference_legislation_json,
        path = ('children', 'ir', 'children', 'bareme', 'slices', 0, 'rate'),
        period = simulation_period,
        value = 1,
        )

    Reform = reforms.make_reform(
        name =  u"Imposition à 100% dès le premier euro et jusqu'à la fin de la 1ère tranche",
        legislation_json = reform_legislation_json,
        reference = tax_benefit_system
        )
    reform = Reform()
    parent1 = dict(
        birth = datetime.date(year - 40, 1, 1),
        salaire_de_base = 10000 if bareme is False else None,
        type_sal = 0,
        )
#    parent2 = dict(
#        birth = datetime.date(year - 40, 1, 1),
#        salaire_de_base = 0,
#        )
    # Adding a husband/wife on the same tax sheet (foyer)
    menage = dict(
        loyer = 1000,
        statut_occupation = 4,
        )
    axes = [
        dict(
            count = 200,
            name = 'salaire_de_base',
            max = 300000,
            min = 0,
            ),
        ]
    scenario = reform.new_scenario().init_single_entity(
        axes = axes if bareme else None,
        menage = menage,
        parent1 = parent1,
        # parent2 = parent2,
        period = periods.period('year', year),
        )
    reference_simulation = scenario.new_simulation(debug = True, reference = True)
    reform_simulation = scenario.new_simulation(debug = True)

    return reform_simulation, reference_simulation
def build_reform(tax_benefit_system):
    Reform = reforms.make_reform(
        key = 'trannoy_wasmer',
        name = u'Loyer comme charge déductible (Trannoy-Wasmer)',
        reference = tax_benefit_system,
        )

    @Reform.formula
    class charges_deduc(formulas.SimpleFormulaColumn):
        label = u"Charge déductibles intégrant la charge pour loyer (Trannoy-Wasmer)"
        reference = charges_deductibles.charges_deduc

        def function(self, simulation, period):
            period = period.start.offset('first-of', 'year').period('year')
            cd1 = simulation.calculate('cd1', period)
            cd2 = simulation.calculate('cd2', period)
            charge_loyer = simulation.calculate('charge_loyer', period)

            return period, cd1 + cd2 + charge_loyer

    @Reform.formula
    class charge_loyer(formulas.SimpleFormulaColumn):
        column = columns.FloatCol
        entity_class = entities.FoyersFiscaux
        label = u"Charge déductible pour paiement d'un loyer"

        def function(self, simulation, period):
            period = period.start.offset('first-of', 'year').period('year')
            loyer_holder = simulation.calculate('loyer', period)
            nbptr = simulation.calculate('nbptr', period)
            loyer = self.cast_from_entity_to_role(loyer_holder, entity = "menage", role = PREF)
            loyer = self.sum_by_entity(loyer)
            charge_loyer = simulation.legislation_at(period.start).charge_loyer

            plaf = charge_loyer.plaf
            plaf_nbp = charge_loyer.plaf_nbp
            plafond = plaf * (not_(plaf_nbp) + plaf * nbptr * plaf_nbp)

            return period, 12 * min_(loyer / 12, plafond)

    reform = Reform()
    reform.modify_legislation_json(modifier_function = modify_legislation_json)
    return reform
def build_reform(tax_benefit_system):
    Reform = reforms.make_reform(
        key='trannoy_wasmer',
        name=u'Loyer comme charge déductible (Trannoy-Wasmer)',
        reference=tax_benefit_system,
    )

    class charges_deduc(Reform.Variable):
        label = u"Charge déductibles intégrant la charge pour loyer (Trannoy-Wasmer)"
        reference = charges_deductibles.charges_deduc

        def function(self, simulation, period):
            period = period.this_year
            cd1 = simulation.calculate('cd1', period)
            cd2 = simulation.calculate('cd2', period)
            charge_loyer = simulation.calculate('charge_loyer', period)

            return period, cd1 + cd2 + charge_loyer

    class charge_loyer(Reform.Variable):
        column = columns.FloatCol
        entity_class = entities.FoyersFiscaux
        label = u"Charge déductible pour paiement d'un loyer"

        def function(self, simulation, period):
            period = period.this_year
            loyer_holder = simulation.calculate('loyer', period)
            nbptr = simulation.calculate('nbptr', period)
            loyer = self.cast_from_entity_to_role(loyer_holder,
                                                  entity="menage",
                                                  role=PREF)
            loyer = self.sum_by_entity(loyer)
            charge_loyer = simulation.legislation_at(period.start).charge_loyer

            plaf = charge_loyer.plaf
            plaf_nbp = charge_loyer.plaf_nbp
            plafond = plaf * (not_(plaf_nbp) + plaf * nbptr * plaf_nbp)

            return period, 12 * min_(loyer / 12, plafond)

    reform = Reform()
    reform.modify_legislation_json(modifier_function=modify_legislation_json)
    return reform
def test_parametric_reform():

    def modify_legislation_json(reference_legislation_json_copy):
        # FIXME update_legislation is deprecated.
        reform_legislation_json = reforms.update_legislation(
            legislation_json = reference_legislation_json_copy,
            path = ('children', 'ir', 'children', 'bareme', 'brackets', 0, 'rate'),
            period = simulation_period,
            value = 1,
            )
        return reform_legislation_json

    simulation_year = 2013
    simulation_period = periods.period('year', simulation_year)
    Reform = reforms.make_reform(
        key = 'ir_100_tranche_1',
        name = u"Imposition à 100% dès le premier euro et jusqu'à la fin de la 1ère tranche",
        reference = tax_benefit_system,
        )
    reform = Reform()
    reform.modify_legislation_json(modifier_function = modify_legislation_json)

    scenario = reform.new_scenario().init_single_entity(
        axes = [
            dict(
                count = 3,
                name = 'salaire_imposable',
                max = 100000,
                min = 0,
                ),
            ],
        period = simulation_period,
        parent1 = dict(date_naissance = datetime.date(simulation_year - 40, 1, 1)),
        )

    reference_simulation = scenario.new_simulation(reference = True)
    assert_near(reference_simulation.calculate('impo'), [0, -7889.20019531, -23435.52929688],
        absolute_error_margin = .01)

    reform_simulation = scenario.new_simulation()
    assert_near(reform_simulation.calculate('impo'), [0, -13900.20019531, -29446.52929688],
        absolute_error_margin = .0001)
def build_reform(tax_benefit_system):
    Reform = reforms.make_reform(
        key="alimentation",
        name=u"Réforme de l'imposition indirecte des biens alimentaires",
        reference=tax_benefit_system,
    )

    class charges_deduc(Reform.Variable):
        label = u"Charge déductibles intégrant la charge pour loyer (Trannoy-Wasmer)"
        reference = charges_deductibles.charges_deduc

        def function(self, simulation, period):
            period = period.this_year
            cd1 = simulation.calculate("cd1", period)
            cd2 = simulation.calculate("cd2", period)
            charge_loyer = simulation.calculate("charge_loyer", period)

            return period, cd1 + cd2 + charge_loyer

    class charge_loyer(Reform.Variable):
        column = columns.FloatCol
        entity_class = entities.FoyersFiscaux
        label = u"Charge déductible pour paiement d'un loyer"

        def function(self, simulation, period):
            period = period.this_year
            loyer_holder = simulation.calculate("loyer", period)
            nbptr = simulation.calculate("nbptr", period)
            loyer = self.cast_from_entity_to_role(loyer_holder, entity="menage", role=PREF)
            loyer = self.sum_by_entity(loyer)
            charge_loyer = simulation.legislation_at(period.start).charge_loyer

            plaf = charge_loyer.plaf
            plaf_nbp = charge_loyer.plaf_nbp
            plafond = plaf * (not_(plaf_nbp) + plaf * nbptr * plaf_nbp)

            return period, 12 * min_(loyer / 12, plafond)

    reform = Reform()
    reform.modify_legislation_json(modifier_function=modify_legislation_json)
    return reform
def test_parametric_reform():
    simulation_year = 2013
    simulation_period = periods.period('year', simulation_year)
    reference_legislation_json = tax_benefit_system.legislation_json

    reform_legislation_json = reforms.update_legislation(
        legislation_json = reference_legislation_json,
        path = ('children', 'ir', 'children', 'bareme', 'brackets', 0, 'rate'),
        period = simulation_period,
        value = 1,
        )

    Reform = reforms.make_reform(
        legislation_json = reform_legislation_json,
        # name = u'IR_100_tranche_1',
        name = u"Imposition à 100% dès le premier euro et jusqu'à la fin de la 1ère tranche",
        reference = tax_benefit_system,
        )
    reform = Reform()

    scenario = reform.new_scenario().init_single_entity(
        axes = [
            dict(
                count = 3,
                name = 'sal',
                max = 100000,
                min = 0,
                ),
            ],
        period = simulation_period,
        parent1 = dict(birth = datetime.date(simulation_year - 40, 1, 1)),
        )

    reference_simulation = scenario.new_simulation(debug = True, reference = True)
    assert_near(reference_simulation.calculate('impo'), [0, -7889.20019531, -23435.52929688], error_margin = .01)

    reform_simulation = scenario.new_simulation(debug = True)
    assert_near(reform_simulation.calculate('impo'), [0, -13900.20019531, -29446.52929688], error_margin = .0001)
Example #32
0
def build_counterfactual_2014_reform(tax_benefit_system):
    Reform = reforms.make_reform(
        key = 'plf2016_counterfactual_2014',
        name = u'Contrefactuel 2014 du PLF 2016 sur les revenus 2015',
        reference = tax_benefit_system,
        )

    class decote(Reform.DatedVariable):
        reference = ir.decote

        @dated_function(start = date(2015, 1, 1))
        def function_2015(self, simulation, period):
            period = period.start.offset('first-of', 'year').period('year')
            ir_plaf_qf = simulation.calculate('ir_plaf_qf', period)
            inflator = 1 + .001 + .005
            decote = simulation.legislation_at(period.start).ir.decote
            assert decote.seuil == 1016
            return period, (ir_plaf_qf < decote.seuil * inflator) * (decote.seuil * inflator - ir_plaf_qf) * 0.5

    class reduction_impot_exceptionnelle(Reform.DatedVariable):
        reference = reductions_impot.reduction_impot_exceptionnelle

        @dated_function(start = date(2015, 1, 1), stop = date(2015, 12, 31))
        def function_2015(self, simulation, period):
            period = period.start.offset('first-of', 'year').period('year')
            nb_adult = simulation.calculate('nb_adult')
            nb_parents = simulation.calculate('nb_parents')
            rfr = simulation.calculate('rfr')
            inflator = 1 + .001 + .005
            # params = simulation.legislation_at(period.start).ir.reductions_impots.reduction_impot_exceptionnelle
            seuil = 13795 * inflator
            majoration_seuil = 3536 * inflator
            montant_plafond = 350 * inflator
            plafond = seuil * nb_adult + (nb_parents - nb_adult) * 2 * majoration_seuil
            montant = montant_plafond * nb_adult
            return period, min_(max_(plafond + montant - rfr, 0), montant)

    class reductions(Reform.DatedVariable):
        label = u"Somme des réductions d'impôt"
        reference = reductions_impot.reductions

        @dated_function(start = date(2013, 1, 1), stop = date(2015, 12, 31))
        def function_20130101_20131231(self, simulation, period):
            period = period.start.offset('first-of', 'year').period('year')
            accult = simulation.calculate('accult')
            adhcga = simulation.calculate('adhcga')
            cappme = simulation.calculate('cappme')
            creaen = simulation.calculate('creaen')
            daepad = simulation.calculate('daepad')
            deffor = simulation.calculate('deffor')
            dfppce = simulation.calculate('dfppce')
            doment = simulation.calculate('doment')
            domlog = simulation.calculate('domlog')
            donapd = simulation.calculate('donapd')
            duflot = simulation.calculate('duflot')
            ecpess = simulation.calculate('ecpess')
            garext = simulation.calculate('garext')
            intagr = simulation.calculate('intagr')
            invfor = simulation.calculate('invfor')
            invlst = simulation.calculate('invlst')
            ip_net = simulation.calculate('ip_net')
            locmeu = simulation.calculate('locmeu')
            mecena = simulation.calculate('mecena')
            mohist = simulation.calculate('mohist')
            patnat = simulation.calculate('patnat')
            prcomp = simulation.calculate('prcomp')
            reduction_impot_exceptionnelle = simulation.calculate('reduction_impot_exceptionnelle')
            repsoc = simulation.calculate('repsoc')
            resimm = simulation.calculate('resimm')
            rsceha = simulation.calculate('rsceha')
            saldom = simulation.calculate('saldom')
            scelli = simulation.calculate('scelli')
            sofica = simulation.calculate('sofica')
            spfcpi = simulation.calculate('spfcpi')
            total_reductions = accult + adhcga + cappme + creaen + daepad + deffor + dfppce + doment + domlog + \
                donapd + duflot + ecpess + garext + intagr + invfor + invlst + locmeu + mecena + mohist + patnat + \
                prcomp + repsoc + resimm + rsceha + saldom + scelli + sofica + spfcpi + reduction_impot_exceptionnelle

            return period, min_(ip_net, total_reductions)

    reform = Reform()
    reform.modify_legislation_json(modifier_function = counterfactual_2014_modify_legislation_json)
    return reform
Example #33
0
def build_reform(base_tax_benefit_system):
    Reform = reforms.make_reform(
        reference=base_tax_benefit_system,
        key='landais_piketty_saez',
        name=u'Landais Piketty Saez',
    )

    class assiette_csg(Reform.Variable):
        column = columns.FloatCol
        entity_class = entities.Individus
        label = u"Assiette de la CSG"

        def function(self, simulation, period):
            period = period.start.offset('first-of', 'month').period('year')
            salaire_de_base = simulation.calculate('salaire_de_base', period)
            chomage_brut = simulation.calculate('chomage_brut', period)
            retraite_brute = simulation.calculate('retraite_brute', period)
            rev_cap_bar_holder = simulation.compute_add('rev_cap_bar', period)
            rev_cap_lib_holder = simulation.compute_add('rev_cap_lib', period)
            rev_cap_bar = self.cast_from_entity_to_role(rev_cap_bar_holder,
                                                        role=QUIFOY['vous'])
            rev_cap_lib = self.cast_from_entity_to_role(rev_cap_lib_holder,
                                                        role=QUIFOY['vous'])
            return period, salaire_de_base + chomage_brut + retraite_brute + rev_cap_bar + rev_cap_lib

    class impot_revenu_lps(Reform.Variable):
        column = columns.FloatCol
        entity_class = entities.Individus
        label = u"Impôt individuel sur l'ensemble de l'assiette de la csg, comme proposé par Landais, Piketty et Saez"

        def function(self, simulation, period):
            period = period.start.offset('first-of', 'month').period('year')
            nbF_holder = simulation.compute('nbF')
            nbF = self.cast_from_entity_to_role(nbF_holder,
                                                role=QUIFOY['vous'])
            nbH_holder = simulation.compute('nbH')
            nbH = self.cast_from_entity_to_role(nbH_holder,
                                                role=QUIFOY['vous'])
            nbEnf = (nbF + nbH / 2)
            lps = simulation.legislation_at(period.start).landais_piketty_saez
            ae = nbEnf * lps.abatt_enfant
            re = nbEnf * lps.reduc_enfant
            ce = nbEnf * lps.credit_enfant
            statut_marital = simulation.calculate('statut_marital')
            couple = (statut_marital == 1) | (statut_marital == 5)
            ac = couple * lps.abatt_conj
            rc = couple * lps.reduc_conj
            assiette_csg = simulation.calculate('assiette_csg')
            return period, -max_(
                0,
                lps.bareme.calc(max_(assiette_csg - ae - ac, 0)) - re -
                rc) + ce

    class revenu_disponible(Reform.Variable):
        column = columns.FloatCol(default=0)
        entity_class = entities.Menages
        label = u"Revenu disponible du ménage"
        url = u"http://fr.wikipedia.org/wiki/Revenu_disponible"

        def function(self, simulation, period):
            period = period.start.offset('first-of', 'month').period('year')
            impot_revenu_lps_holder = simulation.compute('impot_revenu_lps')
            impot_revenu_lps = self.sum_by_entity(impot_revenu_lps_holder)
            pen_holder = simulation.compute('pen')
            pen = self.sum_by_entity(pen_holder)
            psoc_holder = simulation.compute('psoc')
            psoc = self.cast_from_entity_to_role(psoc_holder,
                                                 role=QUIFAM['chef'])
            psoc = self.sum_by_entity(psoc)
            rev_cap_holder = simulation.compute('rev_cap')
            rev_cap = self.sum_by_entity(rev_cap_holder)
            rev_trav_holder = simulation.compute('rev_trav')
            rev_trav = self.sum_by_entity(rev_trav_holder)
            return rev_trav + pen + rev_cap + impot_revenu_lps + psoc

    reform = Reform()
    reform.modify_legislation_json(modifier_function=modify_legislation_json)
    return reform
Example #34
0
def build_reform(tax_benefit_system):
    Reform = reforms.make_reform(
        key='allocations_familiales_imposables',
        name=u'Allocations familiales imposables',
        reference=tax_benefit_system,
    )

    class rbg(Reform.Variable):
        label = u"Nouveau revenu brut global intégrant les allocations familiales"
        reference = ir.rbg

        def function(self, simulation, period):
            period = period.this_year
            allocations_familiales_imposables = simulation.calculate_add(
                'allocations_familiales_imposables', period)
            deficit_ante = simulation.calculate('deficit_ante', period)
            f6gh = simulation.calculate('f6gh', period)
            nacc_pvce_holder = simulation.calculate('nacc_pvce', period)
            nbic_impm_holder = simulation.calculate('nbic_impm', period)
            rev_cat = simulation.calculate('rev_cat', period)
            cga = simulation.legislation_at(period.start).ir.rpns.cga_taux2

            nacc_pvce = self.sum_by_entity(nacc_pvce_holder)
            return period, max_(
                0, allocations_familiales_imposables + rev_cat + f6gh +
                (self.sum_by_entity(nbic_impm_holder) + nacc_pvce) *
                (1 + cga) - deficit_ante)

    class rfr(Reform.Variable):
        label = u"Nouveau revenu fiscal de référence intégrant les allocations familiales"
        reference = ir.rfr

        def function(self, simulation, period):
            period = period.this_year

            allocations_familiales_imposables = simulation.calculate(
                'allocations_familiales_imposables')
            f3va_holder = simulation.calculate('f3va')
            f3vi_holder = simulation.calculate('f3vi')
            f3vz = simulation.calculate('f3vz')
            rfr_cd = simulation.calculate('rfr_cd')
            rfr_rvcm = simulation.calculate('rfr_rvcm')
            rni = simulation.calculate('rni')
            rpns_exon_holder = simulation.calculate('rpns_exon')
            rpns_pvce_holder = simulation.calculate('rpns_pvce')
            rev_cap_lib = simulation.calculate_add('rev_cap_lib')
            microentreprise = simulation.calculate('microentreprise')

            f3va = self.sum_by_entity(f3va_holder)
            f3vi = self.sum_by_entity(f3vi_holder)
            rpns_exon = self.sum_by_entity(rpns_exon_holder)
            rpns_pvce = self.sum_by_entity(rpns_pvce_holder)

            return period, (max_(0, rni - allocations_familiales_imposables) +
                            rfr_cd + rfr_rvcm + rev_cap_lib + f3vi +
                            rpns_exon + rpns_pvce + f3va + f3vz +
                            microentreprise)

    class allocations_familiales_imposables(Reform.Variable):
        column = columns.FloatCol
        entity_class = entities.FoyersFiscaux
        label = u"Allocations familiales imposables"

        def function(self, simulation, period):
            period = period.this_year
            af_holder = simulation.calculate_add('af')
            imposition = simulation.legislation_at(
                period.start).allocations_familiales_imposables.imposition

            af = self.cast_from_entity_to_role(af_holder,
                                               entity="famille",
                                               role=QUIFOY['vous'])
            af = self.sum_by_entity(af)
            return period, af * imposition

    reform = Reform()
    reform.modify_legislation_json(modifier_function=modify_legislation_json)
    return reform
Example #35
0
def build_reform(tax_benefit_system):
    Reform = reforms.make_reform(
        key=u'douanes',
        name=u'Droits de douane, droits de consommation et TVA',
        reference=tax_benefit_system,
    )

    def yaml_tree_variable_function(self, simulation, period):
        # yaml_blocks is defined in outer scope
        match = match_conditions(yaml_blocks, simulation, period)
        result = self.zeros() + match['results'][self.__class__.__name__] \
            if match is not None \
            else self.zeros()
        return period, result

    # Input variables

    class code_produit(Reform.Variable):
        column = StrCol
        entity_class = Individus
        label = u'Code du produit importé suivant la nomenclature des douanes'

    class moyen_transport(Reform.Variable):
        column = EnumCol(enum=Enum([u'avion', u'bateau', u'route', u'train']))
        entity_class = Individus
        label = u'Moyen de transport utilisé pour importer un produit'

    class quantite_produit(Reform.Variable):
        column = IntCol
        entity_class = Individus
        label = u'Quantité du produit importé'

    class valeur_produit(Reform.Variable):
        column = FloatCol
        entity_class = Individus
        label = u'Valeur du produit importé'

    class zone_provenance_produit(Reform.Variable):
        column = EnumCol(enum=Enum([u'Andorra', u'non_EU', u'EU']))
        entity_class = Individus
        label = u'Zone de provenance du produit importé'

    # Variables with formulas

    class taux_droits_douane_max(Reform.Variable):
        column = FloatCol
        entity_class = Individus
        function = yaml_tree_variable_function
        label = u'Taux de droits de douane sur un produit importé'

    class droits_consommation(Reform.Variable):
        column = FloatCol
        entity_class = Individus
        function = yaml_tree_variable_function
        label = u'Taux de droits de consommation sur un produit importé'

    class droits_specifiques(Reform.Variable):
        column = FloatCol
        entity_class = Individus
        function = yaml_tree_variable_function
        label = u'TODO'

    class tva(Reform.Variable):
        column = FloatCol
        entity_class = Individus
        function = yaml_tree_variable_function
        label = u'Taux de TVA sur un produit importé'

    class importation_interdite(Reform.Variable):
        column = BoolCol
        entity_class = Individus
        function = yaml_tree_variable_function
        label = u'L\'importation du produit est interdite'

    # This creates reform.column_by_name
    reform = Reform()

    categories_produits = read_yaml_categories_produits()
    validate_yaml_tree = conv.make_validate_yaml_tree(
        categories_produits=categories_produits,
        variable_names=reform.column_by_name.keys(),
    )
    yaml_file_paths = glob.glob(os.path.join(trees_dir_path, '*.yaml'))
    yaml_blocks = list(
        itertools.chain.from_iterable(
            read_yaml_tree(yaml_file_path, validate_yaml_tree)
            for yaml_file_path in yaml_file_paths))

    return reform
def build_reform(tax_benefit_system):
    Reform = reforms.make_reform(
        key='ayrault_muet',
        name=u'Amendement Ayrault-Muet au PLF2016',
        reference=tax_benefit_system,
    )

    class variator(Reform.Variable):
        column = FloatCol(default=1)
        entity_class = FoyersFiscaux
        label = u'Multiplicateur du seuil de régularisation'

    class reduction_csg(Reform.DatedVariable):
        column = FloatCol
        entity_class = Individus
        label = u"Réduction dégressive de CSG"

        @dated_function(start=date(2015, 1, 1))
        def function_2015__(self, simulation, period):
            period = period.start.offset('first-of', 'year').period('year')
            smic_proratise = simulation.calculate_add('smic_proratise', period)
            assiette_csg_abattue = simulation.calculate_add(
                'assiette_csg_abattue', period)

            seuil = 1.34
            coefficient_correctif = .9
            taux_csg = (simulation.legislation_at(
                period.start).csg.activite.imposable.taux +
                        simulation.legislation_at(
                            period.start).csg.activite.deductible.taux)
            tx_max = coefficient_correctif * taux_csg
            ratio_smic_salaire = smic_proratise / (assiette_csg_abattue +
                                                   1e-16)
            # règle d'arrondi: 4 décimales au dix-millième le plus proche
            taux_allegement_csg = tx_max * min_(
                1,
                max_(seuil - 1 / ratio_smic_salaire, 0) / (seuil - 1))
            # Montant de l'allegment

            return period, taux_allegement_csg * assiette_csg_abattue

    class reduction_csg_foyer_fiscal(Reform.PersonToEntityColumn):
        entity_class = FoyersFiscaux
        label = u"Réduction dégressive de CSG des memebres du foyer fiscal"
        operation = 'add'
        variable = reduction_csg

    class reduction_csg_nette(Reform.DatedVariable):
        column = FloatCol
        entity_class = Individus
        label = u"Réduction dégressive de CSG"

        @dated_function(start=date(2015, 1, 1))
        def function_2015__(self, simulation, period):
            period = period.start.offset('first-of', 'year').period('year')
            reduction_csg = simulation.calculate('reduction_csg', period)
            ppe_elig_bis_individu = simulation.calculate(
                'ppe_elig_bis_individu', period)
            return period, reduction_csg * ppe_elig_bis_individu

    class ppe_elig_bis(Reform.Variable):
        column = BoolCol(default=False)
        entity_class = FoyersFiscaux
        label = u"ppe_elig_bis"

        def function(self, simulation, period):
            '''
            PPE: eligibilité à la ppe, condition sur le revenu fiscal de référence
            'foy'
            '''
            period = period.start.offset('first-of', 'year').period('year')
            rfr = simulation.calculate('rfr', period)
            ppe_coef = simulation.calculate('ppe_coef', period)
            marpac = simulation.calculate('marpac', period)
            veuf = simulation.calculate('veuf', period)
            celdiv = simulation.calculate('celdiv', period)
            nbptr = simulation.calculate('nbptr', period)
            variator = simulation.calculate('variator', period)
            ppe = simulation.legislation_at(period.start).ir.credits_impot.ppe
            seuil = (veuf | celdiv) * (ppe.eligi1 + 2 * max_(nbptr - 1, 0) * ppe.eligi3) \
                + marpac * (ppe.eligi2 + 2 * max_(nbptr - 2, 0) * ppe.eligi3)
            return period, (rfr * ppe_coef) <= (seuil * variator)

    class ppe_elig_bis_individu(Reform.EntityToPersonColumn):
        entity_class = Individus
        variable = ppe_elig_bis

    class regularisation_reduction_csg(Reform.DatedVariable):
        column = FloatCol
        entity_class = FoyersFiscaux
        label = u"Régularisation complète réduction dégressive de CSG"

        @dated_function(start=date(2015, 1, 1))
        def function_2015__(self, simulation, period):
            period = period.start.offset('first-of', 'year').period('year')
            reduction_csg = simulation.calculate('reduction_csg_foyer_fiscal',
                                                 period)
            ppe_elig_bis = simulation.calculate('ppe_elig_bis', period)
            return period, not_(ppe_elig_bis) * (reduction_csg > 1)

    reform = Reform()
    reform.modify_legislation_json(
        modifier_function=ayrault_muet_modify_legislation_json)
    return reform
def build_reform(tax_benefit_system):
    Reform = reforms.make_reform(
        key = 'revenu_de_base_cotisations',
        name = u"Réforme des cotisations pour un Revenu de base",
        reference = tax_benefit_system,
        )

    @Reform.formula
    class cotisations_contributives(SimpleFormulaColumn):
        column = FloatCol
        entity_class = Individus
        label = u"Nouvelles cotisations contributives"

        def function(self, simulation, period):
            ags = simulation.calculate('ags', period)
            agff_tranche_a_employeur = simulation.calculate('agff_tranche_a_employeur', period)
            apec_employeur = simulation.calculate('apec_employeur', period)
            arrco_tranche_a_employeur = simulation.calculate('arrco_tranche_a_employeur', period)
            assedic_employeur = simulation.calculate('assedic_employeur', period)
            cotisation_exceptionnelle_temporaire_employeur = simulation.calculate(
                'cotisation_exceptionnelle_temporaire_employeur', period)
            fonds_emploi_hospitalier = simulation.calculate('fonds_emploi_hospitalier', period)
            ircantec_employeur = simulation.calculate('ircantec_employeur', period)
            pension_civile_employeur = simulation.calculate('pension_civile_employeur', period)
            prevoyance_obligatoire_cadre = simulation.calculate('prevoyance_obligatoire_cadre', period)
            rafp_employeur = simulation.calculate('rafp_employeur', period)
            vieillesse_deplafonnee_employeur = simulation.calculate('vieillesse_deplafonnee_employeur', period)
            vieillesse_plafonnee_employeur = simulation.calculate('vieillesse_plafonnee_employeur', period)
            allocations_temporaires_invalidite = simulation.calculate('allocations_temporaires_invalidite', period)
            accident_du_travail = simulation.calculate('accident_du_travail', period)
            agff_tranche_a_employe = simulation.calculate('agff_tranche_a_employe', period)
            agirc_tranche_b_employe = simulation.calculate('agirc_tranche_b_employe', period)
            apec_employe = simulation.calculate('apec_employe', period)
            arrco_tranche_a_employe = simulation.calculate('arrco_tranche_a_employe', period)
            assedic_employe = simulation.calculate('assedic_employe', period)
            cotisation_exceptionnelle_temporaire_employe = simulation.calculate(
                'cotisation_exceptionnelle_temporaire_employe', period)
            ircantec_employe = simulation.calculate('ircantec_employe', period)
            pension_civile_employe = simulation.calculate('pension_civile_employe', period)
            rafp_employe = simulation.calculate('rafp_employe', period)
            vieillesse_deplafonnee_employe = simulation.calculate('vieillesse_deplafonnee_employe', period)
            vieillesse_plafonnee_employe = simulation.calculate('vieillesse_plafonnee_employe', period)

            cotisations_contributives = (
                # cotisations patronales contributives dans le prive
                ags +
                agff_tranche_a_employeur +
                apec_employeur +
                arrco_tranche_a_employeur +
                assedic_employeur +
                cotisation_exceptionnelle_temporaire_employeur +
                prevoyance_obligatoire_cadre +  # TODO contributive ou pas
                vieillesse_deplafonnee_employeur +
                vieillesse_plafonnee_employeur +
                # cotisations patronales contributives dans le public
                fonds_emploi_hospitalier +
                ircantec_employeur +
                pension_civile_employeur +
                rafp_employeur +
                # anciennes cot patronales non-contributives classées ici comme contributives
                allocations_temporaires_invalidite +
                accident_du_travail +
                # anciennes cotisations salariales contributives dans le prive
                agff_tranche_a_employe +
                agirc_tranche_b_employe +
                apec_employe +
                arrco_tranche_a_employe +
                assedic_employe +
                cotisation_exceptionnelle_temporaire_employe +
                vieillesse_deplafonnee_employe +
                vieillesse_plafonnee_employe +
                # anciennes cotisations salariales contributives dans le public
                ircantec_employe +
                pension_civile_employe +
                rafp_employe
                )
            return period, cotisations_contributives

    @Reform.formula
    class nouv_salaire_de_base(SimpleFormulaColumn):
        reference = tax_benefit_system.column_by_name['salaire_de_base']

        # Le salaire brut se définit dans la réforme comme le salaire super-brut auquel
        # on retranche les cotisations contributives

        def function(self, simulation, period):
            period = period.start.period('month').offset('first-of')
            salsuperbrut = simulation.calculate('salsuperbrut', period)
            cotisations_contributives = simulation.calculate('cotisations_contributives', period)

            nouv_salaire_de_base = (
                salsuperbrut -
                cotisations_contributives
                )
            return period, nouv_salaire_de_base

    @Reform.formula
    class nouv_csg(SimpleFormulaColumn):
        reference = tax_benefit_system.column_by_name['csg_imposable_salaire']

        # On applique une CSG unique à 22,5% qui finance toutes les prestations non-contributives

        def function(self, simulation, period):
            period = period.start.period('month').offset('first-of')
            nouv_salaire_de_base = simulation.calculate('nouv_salaire_de_base', period)

            nouv_csg = (
                -0.225 * nouv_salaire_de_base
                )
            return period, nouv_csg

    @Reform.formula
    class salaire_net(SimpleFormulaColumn):
        reference = tax_benefit_system.column_by_name['salaire_net']

        # On retire la nouvelle CSG (pas celle qui finance le RDB) pour trouver le nouveau salaire net

        def function(self, simulation, period):
            period = period.start.period('month').offset('first-of')
            nouv_salaire_de_base = simulation.calculate('nouv_salaire_de_base', period)
            nouv_csg = simulation.calculate('nouv_csg', period)

            salaire_net = (
                nouv_salaire_de_base +
                nouv_csg
                )
            return period, salaire_net

    @Reform.formula
    class salaire_imposable(SimpleFormulaColumn):
        reference = tax_benefit_system.column_by_name['salaire_imposable']

        # Nous sommes partis du nouveau salaire net et par rapport au salaire imposable actuel,
        # nous avons supprimé : les heures sup, la déductibilité de CSG

        def function(self, simulation, period):
            period = period
            hsup = simulation.calculate('hsup', period)
            salaire_net = simulation.calculate('salaire_net', 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)
            rev_microsocial_declarant1 = simulation.calculate('rev_microsocial_declarant1', period)

            return period, (
                salaire_net +
                primes_fonction_publique +
                indemnite_residence +
                supp_familial_traitement +
                hsup +
                rev_microsocial_declarant1
                )

    return Reform()
Example #38
0
    'Familles',
    'FloatCol',
    'FoyersFiscaux',
    'Individus',
    'IntCol',
    'Menages',
    'openfisca_france_tax_benefit_system',
    'PART',
    'PersonToEntityColumn',
    'QUIFAM',
    'QUIFOY',
    'TaxBenefitSystem',
    'Variable',
    'VOUS',
    ]

OpenFiscaFranceTaxBenefitSystem = openfisca_france.init_country()
openfisca_france_tax_benefit_system = OpenFiscaFranceTaxBenefitSystem()

TaxBenefitSystem = reforms.make_reform(
    key = 'openfisca_france_data',
    name = u"OpenFisca for survey data",
    reference = openfisca_france_tax_benefit_system,
    )

# Export reform classes to register variables in reform column_by_name dict.
DatedVariable = TaxBenefitSystem.DatedVariable
EntityToPersonColumn = TaxBenefitSystem.EntityToPersonColumn
PersonToEntityColumn = TaxBenefitSystem.PersonToEntityColumn
Variable = TaxBenefitSystem.Variable
def build_reform(tax_benefit_system):
    Reform = reforms.make_reform(
        key='revenu_de_base_cotisations',
        name=u"Réforme des cotisations pour un Revenu de base",
        reference=tax_benefit_system,
    )

    class cotisations_contributives(Variable):
        column = FloatCol
        entity_class = Individus
        label = u"Nouvelles cotisations contributives"

        def function(self, simulation, period):
            ags = simulation.calculate('ags', period)
            agff_tranche_a_employeur = simulation.calculate(
                'agff_tranche_a_employeur', period)
            apec_employeur = simulation.calculate('apec_employeur', period)
            arrco_tranche_a_employeur = simulation.calculate(
                'arrco_tranche_a_employeur', period)
            assedic_employeur = simulation.calculate('assedic_employeur',
                                                     period)
            cotisation_exceptionnelle_temporaire_employeur = simulation.calculate(
                'cotisation_exceptionnelle_temporaire_employeur', period)
            fonds_emploi_hospitalier = simulation.calculate(
                'fonds_emploi_hospitalier', period)
            ircantec_employeur = simulation.calculate('ircantec_employeur',
                                                      period)
            pension_civile_employeur = simulation.calculate(
                'pension_civile_employeur', period)
            prevoyance_obligatoire_cadre = simulation.calculate(
                'prevoyance_obligatoire_cadre', period)
            rafp_employeur = simulation.calculate('rafp_employeur', period)
            vieillesse_deplafonnee_employeur = simulation.calculate(
                'vieillesse_deplafonnee_employeur', period)
            vieillesse_plafonnee_employeur = simulation.calculate(
                'vieillesse_plafonnee_employeur', period)
            allocations_temporaires_invalidite = simulation.calculate(
                'allocations_temporaires_invalidite', period)
            accident_du_travail = simulation.calculate('accident_du_travail',
                                                       period)
            agff_tranche_a_employe = simulation.calculate(
                'agff_tranche_a_employe', period)
            agirc_tranche_b_employe = simulation.calculate(
                'agirc_tranche_b_employe', period)
            apec_employe = simulation.calculate('apec_employe', period)
            arrco_tranche_a_employe = simulation.calculate(
                'arrco_tranche_a_employe', period)
            assedic_employe = simulation.calculate('assedic_employe', period)
            cotisation_exceptionnelle_temporaire_employe = simulation.calculate(
                'cotisation_exceptionnelle_temporaire_employe', period)
            ircantec_employe = simulation.calculate('ircantec_employe', period)
            pension_civile_employe = simulation.calculate(
                'pension_civile_employe', period)
            rafp_employe = simulation.calculate('rafp_employe', period)
            vieillesse_deplafonnee_employe = simulation.calculate(
                'vieillesse_deplafonnee_employe', period)
            vieillesse_plafonnee_employe = simulation.calculate(
                'vieillesse_plafonnee_employe', period)

            cotisations_contributives = (
                # cotisations patronales contributives dans le prive
                ags + agff_tranche_a_employeur + apec_employeur +
                arrco_tranche_a_employeur + assedic_employeur +
                cotisation_exceptionnelle_temporaire_employeur +
                prevoyance_obligatoire_cadre +  # TODO contributive ou pas
                vieillesse_deplafonnee_employeur +
                vieillesse_plafonnee_employeur +
                # cotisations patronales contributives dans le public
                fonds_emploi_hospitalier + ircantec_employeur +
                pension_civile_employeur + rafp_employeur +
                # anciennes cot patronales non-contributives classées ici comme contributives
                allocations_temporaires_invalidite + accident_du_travail +
                # anciennes cotisations salariales contributives dans le prive
                agff_tranche_a_employe + agirc_tranche_b_employe +
                apec_employe + arrco_tranche_a_employe + assedic_employe +
                cotisation_exceptionnelle_temporaire_employe +
                vieillesse_deplafonnee_employe + vieillesse_plafonnee_employe +
                # anciennes cotisations salariales contributives dans le public
                ircantec_employe + pension_civile_employe + rafp_employe)
            return period, cotisations_contributives

    class nouv_salaire_de_base(Variable):
        reference = tax_benefit_system.column_by_name['salaire_de_base']

        # Le salaire brut se définit dans la réforme comme le salaire super-brut auquel
        # on retranche les cotisations contributives

        def function(self, simulation, period):
            period = period.start.period('month').offset('first-of')
            salsuperbrut = simulation.calculate('salsuperbrut', period)
            cotisations_contributives = simulation.calculate(
                'cotisations_contributives', period)

            nouv_salaire_de_base = (salsuperbrut - cotisations_contributives)
            return period, nouv_salaire_de_base

    class nouv_csg(Variable):
        reference = tax_benefit_system.column_by_name['csg_imposable_salaire']

        # On applique une CSG unique à 22,5% qui finance toutes les prestations non-contributives

        def function(self, simulation, period):
            period = period.start.period('month').offset('first-of')
            nouv_salaire_de_base = simulation.calculate(
                'nouv_salaire_de_base', period)

            nouv_csg = (-0.225 * nouv_salaire_de_base)
            return period, nouv_csg

    class salaire_net(Variable):
        reference = tax_benefit_system.column_by_name['salaire_net']

        # On retire la nouvelle CSG (pas celle qui finance le RDB) pour trouver le nouveau salaire net

        def function(self, simulation, period):
            period = period.start.period('month').offset('first-of')
            nouv_salaire_de_base = simulation.calculate(
                'nouv_salaire_de_base', period)
            nouv_csg = simulation.calculate('nouv_csg', period)

            salaire_net = (nouv_salaire_de_base + nouv_csg)
            return period, salaire_net

    class salaire_imposable(Variable):
        reference = tax_benefit_system.column_by_name['salaire_imposable']

        # Nous sommes partis du nouveau salaire net et par rapport au salaire imposable actuel,
        # nous avons supprimé : les heures sup, la déductibilité de CSG

        def function(self, simulation, period):
            period = period
            hsup = simulation.calculate('hsup', period)
            salaire_net = simulation.calculate('salaire_net', 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)
            rev_microsocial_declarant1 = simulation.calculate(
                'rev_microsocial_declarant1', period)

            return period, (salaire_net + primes_fonction_publique +
                            indemnite_residence + supp_familial_traitement +
                            hsup + rev_microsocial_declarant1)

    return Reform()
def build_reform(tax_benefit_system):

    Reform = reforms.make_reform(
        key='inversion_directe_salaires',
        name=u'Inversion des revenus',
        reference=tax_benefit_system,
    )

    class salaire_imposable_pour_inversion(Reform.Variable):
        column = columns.FloatCol
        entity_class = entities.Individus
        label = u'Salaire imposable utilisé pour remonter au salaire brut'

    class salaire_de_base(Reform.Variable):
        column = columns.FloatCol
        entity_class = entities.Individus
        label = u"Salaire brut"
        reference = tax_benefit_system.column_by_name["salaire_de_base"]

        def function(self, simulation, period):
            """Calcule le salaire brut à partir du salaire imposable ou sinon du salaire net.

            Sauf pour les fonctionnaires où il renvoie le traitement indiciaire brut
            Note : le supplément familial de traitement est imposable.
            """
            # Get value for year and divide below.
            salaire_imposable_pour_inversion = simulation.calculate(
                'salaire_imposable_pour_inversion',
                period.start.offset('first-of', 'year').period('year'))

            # Calcule le salaire brut à partir du salaire imposable par inversion numérique.
            #            if salaire_imposable_pour_inversion == 0 or (salaire_imposable_pour_inversion == 0).all():
            #                # Quick path to avoid fsolve when using default value of input variables.
            #                return period, salaire_imposable_pour_inversion

            # Calcule le salaire brut à partir du salaire imposable.
            # Sauf pour les fonctionnaires où il renvoie le traitement indiciaire brut
            # Note : le supplément familial de traitement est imposable.

            hsup = simulation.calculate('hsup', period)
            categorie_salarie = simulation.calculate('categorie_salarie',
                                                     period)
            P = simulation.legislation_at(period.start)

            salarie = P.cotsoc.cotisations_salarie
            plafond_securite_sociale_annuel = P.cotsoc.gen.plafond_securite_sociale * 12
            taux_csg = P.csg.activite.deductible.taux * (1 - .0175)
            csg = MarginalRateTaxScale(name='csg')
            csg.add_bracket(0, taux_csg)

            #            cat = None
            #            if (categorie_salarie == 0).all():
            #                cat = 'prive_non_cadre'
            #            elif (categorie_salarie == 1).all():
            #                cat = 'prive_cadre'
            #            elif (categorie_salarie == 2).all():
            #                cat = 'public_titulaire_etat'
            #            if cat is not None:
            #                for name, bareme in salarie[cat].iteritems():
            #                    print name, bareme

            prive_non_cadre = salarie['prive_non_cadre'].combine_tax_scales(
            ).scale_tax_scales(plafond_securite_sociale_annuel)
            prive_cadre = salarie['prive_cadre'].combine_tax_scales(
            ).scale_tax_scales(plafond_securite_sociale_annuel)
            # On ajoute la CSG deductible
            prive_non_cadre.add_tax_scale(csg)
            prive_cadre.add_tax_scale(csg)
            salaire_de_base = (
                (categorie_salarie == CAT['prive_non_cadre']) * prive_non_cadre
                .inverse().calc(salaire_imposable_pour_inversion) +
                (categorie_salarie == CAT['prive_cadre']) *
                prive_cadre.inverse().calc(salaire_imposable_pour_inversion))
            return period, salaire_de_base + hsup

    class traitement_indiciaire_brut(Reform.Variable):
        column = columns.FloatCol
        entity_class = entities.Individus
        label = u"Traitement indiciaire brut"
        reference = tax_benefit_system.column_by_name[
            "traitement_indiciaire_brut"]

        def function(self, simulation, period):
            """Calcule le tratement indiciaire brut à partir du salaire imposable.
            """
            # Get value for year and divide below.
            salaire_imposable_pour_inversion = simulation.calculate(
                'salaire_imposable_pour_inversion',
                period.start.offset('first-of', 'year').period('year'))

            # Calcule le salaire brut à partir du salaire imposable par inversion numérique.
            #            if salaire_imposable_pour_inversion == 0 or (salaire_imposable_pour_inversion == 0).all():
            #                # Quick path to avoid fsolve when using default value of input variables.
            #                return period, salaire_imposable_pour_inversion

            # Calcule le salaire brut à partir du salaire imposable.
            # Sauf pour les fonctionnaires où il renvoie le traitement indiciaire brut
            # Note : le supplément familial de traitement est imposable.
            categorie_salarie = simulation.calculate('categorie_salarie',
                                                     period)
            P = simulation.legislation_at(period.start)
            taux_csg = P.csg.activite.deductible.taux * (1 - .0175)
            csg = MarginalRateTaxScale(name='csg')
            csg.add_bracket(0, taux_csg)

            salarie = P.cotsoc.cotisations_salarie
            #            cat = None
            #            if (categorie_salarie == 2).all():
            #                cat = 'public_titulaire_etat'
            #            if cat is not None:
            #                for name, bareme in salarie[cat].iteritems():
            #                    print name, bareme

            # public etat
            # TODO: modifier la contribution exceptionelle de solidarité
            # en fixant son seuil de non imposition dans le barème (à corriger dans param.xml
            # et en tenant compte des éléments de l'assiette
            # salarie['fonc']['etat']['excep_solidarite'] = salarie['fonc']['commun']['solidarite']

            public_titulaire_etat = salarie['public_titulaire_etat'].copy()
            public_titulaire_etat['rafp'].multiply_rates(TAUX_DE_PRIME,
                                                         inplace=True)
            public_titulaire_etat = salarie[
                'public_titulaire_etat'].combine_tax_scales()

            # public_titulaire_territoriale = salarie['public_titulaire_territoriale'].combine_tax_scales()
            # public_titulaire_hospitaliere = salarie['public_titulaire_hospitaliere'].combine_tax_scales()
            # public_non_titulaire = salarie['public_non_titulaire'].combine_tax_scales()

            # Pour a fonction publique la csg est calculée sur l'ensemble salbrut(=TIB) + primes
            # Imposable = TIB - csg( (1+taux_prime)*TIB ) - pension(TIB) + taux_prime*TIB
            bareme_csg_public_titulaire_etat = csg.multiply_rates(
                1 + TAUX_DE_PRIME,
                inplace=False,
                new_name="csg deduc titutaire etat")
            public_titulaire_etat.add_tax_scale(
                bareme_csg_public_titulaire_etat)
            bareme_prime = MarginalRateTaxScale(name="taux de prime")
            bareme_prime.add_bracket(
                0, -TAUX_DE_PRIME)  # barème équivalent à taux_prime*TIB
            public_titulaire_etat.add_tax_scale(bareme_prime)
            traitement_indiciaire_brut = (
                (categorie_salarie == CAT['public_titulaire_etat']) *
                public_titulaire_etat.inverse().calc(
                    salaire_imposable_pour_inversion))
            # TODO: complete this to deal with the fonctionnaire
            # supp_familial_traitement = 0  # TODO: dépend de salbrut
            # indemnite_residence = 0  # TODO: fix bug
            return period, traitement_indiciaire_brut

    class primes_fonction_publique(Reform.Variable):
        column = columns.FloatCol
        entity_class = entities.Individus
        label = u"Primes de la fonction publique"
        reference = tax_benefit_system.column_by_name[
            "primes_fonction_publique"]

        def function(self, simulation, period):
            """Calcule les primes.
            """
            # Get value for year and divide below.
            traitement_indiciaire_brut = simulation.calculate(
                'traitement_indiciaire_brut',
                period.start.offset('first-of', 'year').period('year'))

            return period, TAUX_DE_PRIME * traitement_indiciaire_brut

    return Reform()
Example #41
0
def build_reform(tax_benefit_system):
    Reform = reforms.make_reform(
        key=u'plfr2014',
        name=u'Projet de Loi de Finances Rectificative 2014',
        reference=tax_benefit_system,
    )

    class reduction_impot_exceptionnelle(Reform.DatedVariable):
        reference = reductions_impot.reduction_impot_exceptionnelle

        @dated_function(start=date(2013, 1, 1), stop=date(2013, 12, 31))
        def function(self, simulation, period):
            period = period.this_year
            nb_adult = simulation.calculate('nb_adult')
            nb_parents = simulation.calculate('nb_parents')
            rfr = simulation.calculate('rfr')
            params = simulation.legislation_at(
                period.start).plfr2014.reduction_impot_exceptionnelle
            plafond = params.seuil * nb_adult + (
                nb_parents - nb_adult) * 2 * params.majoration_seuil
            montant = params.montant_plafond * nb_adult
            return period, min_(max_(plafond + montant - rfr, 0), montant)

    class reductions(Reform.DatedVariable):
        label = u"Somme des réductions d'impôt à intégrer pour l'année 2013"
        reference = reductions_impot.reductions

        @dated_function(start=date(2013, 1, 1), stop=date(2013, 12, 31))
        def function_20130101_20131231(self, simulation, period):
            period = period.this_year
            accult = simulation.calculate('accult')
            adhcga = simulation.calculate('adhcga')
            cappme = simulation.calculate('cappme')
            creaen = simulation.calculate('creaen')
            daepad = simulation.calculate('daepad')
            deffor = simulation.calculate('deffor')
            dfppce = simulation.calculate('dfppce')
            doment = simulation.calculate('doment')
            domlog = simulation.calculate('domlog')
            donapd = simulation.calculate('donapd')
            duflot = simulation.calculate('duflot')
            ecpess = simulation.calculate('ecpess')
            garext = simulation.calculate('garext')
            intagr = simulation.calculate('intagr')
            invfor = simulation.calculate('invfor')
            invlst = simulation.calculate('invlst')
            ip_net = simulation.calculate('ip_net')
            locmeu = simulation.calculate('locmeu')
            mecena = simulation.calculate('mecena')
            mohist = simulation.calculate('mohist')
            patnat = simulation.calculate('patnat')
            prcomp = simulation.calculate('prcomp')
            reduction_impot_exceptionnelle = simulation.calculate(
                'reduction_impot_exceptionnelle')
            repsoc = simulation.calculate('repsoc')
            resimm = simulation.calculate('resimm')
            rsceha = simulation.calculate('rsceha')
            saldom = simulation.calculate('saldom')
            scelli = simulation.calculate('scelli')
            sofica = simulation.calculate('sofica')
            spfcpi = simulation.calculate('spfcpi')
            total_reductions = accult + adhcga + cappme + creaen + daepad + deffor + dfppce + doment + domlog + \
                donapd + duflot + ecpess + garext + intagr + invfor + invlst + locmeu + mecena + mohist + patnat + \
                prcomp + repsoc + resimm + rsceha + saldom + scelli + sofica + spfcpi + reduction_impot_exceptionnelle
            return period, min_(ip_net, total_reductions)

    reform = Reform()
    reform.modify_legislation_json(modifier_function=modify_legislation_json)
    return reform
Example #42
0
def build_reform(tax_benefit_system):
    Reform = reforms.make_reform(
        key='aides_cd93',
        name=u'Aides du conseil départemental du 93',
        reference=tax_benefit_system,
    )

    class perte_autonomie(Reform.Variable):
        column = BoolCol
        entity_class = Individus
        label = u"Personne en perte d'autonomie"

    class resident_93(Reform.Variable):
        column = BoolCol
        label = u"Résident en Seine-Saint-Denis"
        entity_class = Menages

        def function(self, simulation, period):
            period = period.this_month
            depcom = simulation.calculate('depcom', period)

            def is_resident_93(code_insee):
                prefix = code_insee[0:2]
                result = (prefix == "93")
                return result

            is_resident_93_vec = vectorize(is_resident_93)

            result = is_resident_93_vec(depcom)

            return period, result

    class adpa_eligibilite(Reform.Variable):
        column = BoolCol
        label = u"Eligibilité à l'ADPA"
        entity_class = Individus

        def function(self, simulation, period):
            period = period.this_month
            age = simulation.calculate('age', period)
            resident_93 = simulation.calculate('resident_93', period)
            perte_autonomie = simulation.calculate('perte_autonomie', period)

            result = (age >= 60) * resident_93 * perte_autonomie

            return period, result

    class adpa_base_ressources_i(Reform.Variable):
        column = FloatCol
        label = u"Base ressources ADPA pour un individu"
        entity_class = Individus

        def function(self, simulation, period):
            period = period.this_month
            previous_year = period.start.period('year').offset(-1)
            salaire_imposable = simulation.calculate_add(
                'salaire_imposable', period.n_2)
            retraite_imposable = simulation.calculate_add(
                'retraite_imposable', period.n_2)
            chomage_imposable = simulation.calculate_add(
                'chomage_imposable', period.n_2)
            revenus_capital = simulation.calculate_add('revenus_capital',
                                                       previous_year)
            revenus_locatifs = simulation.calculate_add(
                'revenus_locatifs', previous_year)
            # Prélevements libératoire forfaitaire à prendre en compte sans abattement
            valeur_locative_immo_non_loue = simulation.calculate_add(
                'valeur_locative_immo_non_loue', previous_year)
            valeur_locative_terrains_non_loue = simulation.calculate_add(
                'valeur_locative_terrains_non_loue', previous_year)

            base_ressource_mensuelle = (
                salaire_imposable + retraite_imposable + chomage_imposable +
                revenus_locatifs + revenus_capital * 0.30 +
                valeur_locative_immo_non_loue * 0.5 +
                valeur_locative_terrains_non_loue * 0.8) / 12

            return period, base_ressource_mensuelle

    class adpa_base_ressources(Reform.Variable):
        column = FloatCol
        label = u"Base ressources ADPA pour une famille"
        entity_class = Familles

        def function(self, simulation, period):
            period = period.this_month
            adpa_base_ressources_i = simulation.compute(
                'adpa_base_ressources_i', period)
            adpa_base_ressources = self.sum_by_entity(adpa_base_ressources_i)

            return period, adpa_base_ressources

    class adpa(Reform.Variable):
        column = FloatCol
        label = u"ADPA"
        entity_class = Familles

        def function(self, simulation, period):
            period = period.this_month

            adpa_eligibilite_holder = simulation.compute(
                'adpa_eligibilite', period)
            adpa_eligibilite = self.any_by_roles(adpa_eligibilite_holder)
            base_ressource_mensuelle = simulation.calculate(
                'adpa_base_ressources', period)
            en_couple = simulation.calculate('en_couple', period)

            # On ne prend pas en compte le cas où le conjoint est placé.
            quotient_familial = 1 + 0.7 * en_couple
            base_ressource_mensuelle = base_ressource_mensuelle / quotient_familial

            majorationTiercePersonne = 1103.08
            seuil1 = 0.67 * majorationTiercePersonne
            seuil2 = 2.67 * majorationTiercePersonne

            participation_usager = ((base_ressource_mensuelle < seuil1) * 0 +
                                    (base_ressource_mensuelle >= seuil1) *
                                    (base_ressource_mensuelle <= seuil2) * 90 *
                                    (base_ressource_mensuelle - seuil1) /
                                    (2 * majorationTiercePersonne) +
                                    (base_ressource_mensuelle > seuil2) * 90)

            participation_departement = 100 - participation_usager

            return period, participation_departement * adpa_eligibilite

    reform = Reform()
    return reform
Example #43
0
def build_counterfactual_2014_reform(tax_benefit_system):
    Reform = reforms.make_reform(
        key='plf2016_counterfactual_2014',
        name=u'Contrefactuel 2014 du PLF 2016 sur les revenus 2015',
        reference=tax_benefit_system,
    )

    class decote(Reform.DatedVariable):
        reference = ir.decote

        @dated_function(start=date(2015, 1, 1))
        def function_2015(self, simulation, period):
            period = period.start.offset('first-of', 'year').period('year')
            ir_plaf_qf = simulation.calculate('ir_plaf_qf', period)
            inflator = 1 + .001 + .005
            decote = simulation.legislation_at(period.start).ir.decote
            assert decote.seuil == 1016
            return period, (ir_plaf_qf < decote.seuil * inflator) * (
                decote.seuil * inflator - ir_plaf_qf) * 0.5

    class reduction_impot_exceptionnelle(Reform.DatedVariable):
        reference = reductions_impot.reduction_impot_exceptionnelle

        @dated_function(start=date(2015, 1, 1), stop=date(2015, 12, 31))
        def function_2015(self, simulation, period):
            period = period.start.offset('first-of', 'year').period('year')
            nb_adult = simulation.calculate('nb_adult')
            nb_parents = simulation.calculate('nb_parents')
            rfr = simulation.calculate('rfr')
            inflator = 1 + .001 + .005
            # params = simulation.legislation_at(period.start).ir.reductions_impots.reduction_impot_exceptionnelle
            seuil = 13795 * inflator
            majoration_seuil = 3536 * inflator
            montant_plafond = 350 * inflator
            plafond = seuil * nb_adult + (nb_parents -
                                          nb_adult) * 2 * majoration_seuil
            montant = montant_plafond * nb_adult
            return period, min_(max_(plafond + montant - rfr, 0), montant)

    class reductions(Reform.DatedVariable):
        label = u"Somme des réductions d'impôt"
        reference = reductions_impot.reductions

        @dated_function(start=date(2013, 1, 1), stop=date(2015, 12, 31))
        def function_20130101_20131231(self, simulation, period):
            period = period.start.offset('first-of', 'year').period('year')
            accult = simulation.calculate('accult')
            adhcga = simulation.calculate('adhcga')
            cappme = simulation.calculate('cappme')
            creaen = simulation.calculate('creaen')
            daepad = simulation.calculate('daepad')
            deffor = simulation.calculate('deffor')
            dfppce = simulation.calculate('dfppce')
            doment = simulation.calculate('doment')
            domlog = simulation.calculate('domlog')
            donapd = simulation.calculate('donapd')
            duflot = simulation.calculate('duflot')
            ecpess = simulation.calculate('ecpess')
            garext = simulation.calculate('garext')
            intagr = simulation.calculate('intagr')
            invfor = simulation.calculate('invfor')
            invlst = simulation.calculate('invlst')
            ip_net = simulation.calculate('ip_net')
            locmeu = simulation.calculate('locmeu')
            mecena = simulation.calculate('mecena')
            mohist = simulation.calculate('mohist')
            patnat = simulation.calculate('patnat')
            prcomp = simulation.calculate('prcomp')
            reduction_impot_exceptionnelle = simulation.calculate(
                'reduction_impot_exceptionnelle')
            repsoc = simulation.calculate('repsoc')
            resimm = simulation.calculate('resimm')
            rsceha = simulation.calculate('rsceha')
            saldom = simulation.calculate('saldom')
            scelli = simulation.calculate('scelli')
            sofica = simulation.calculate('sofica')
            spfcpi = simulation.calculate('spfcpi')
            total_reductions = accult + adhcga + cappme + creaen + daepad + deffor + dfppce + doment + domlog + \
                donapd + duflot + ecpess + garext + intagr + invfor + invlst + locmeu + mecena + mohist + patnat + \
                prcomp + repsoc + resimm + rsceha + saldom + scelli + sofica + spfcpi + reduction_impot_exceptionnelle

            return period, min_(ip_net, total_reductions)

    reform = Reform()
    reform.modify_legislation_json(
        modifier_function=counterfactual_2014_modify_legislation_json)
    return reform
def build_reform(tax_benefit_system):

    Reform = reforms.make_reform(
        key = 'inversion_directe_salaires',
        name = u'Inversion des revenus',
        reference = tax_benefit_system,
        )

    class salaire_imposable_pour_inversion(Reform.Variable):
        column = columns.FloatCol
        entity_class = entities.Individus
        label = u'Salaire imposable utilisé pour remonter au salaire brut'

    class salaire_de_base(Reform.Variable):
        column = columns.FloatCol
        entity_class = entities.Individus
        label = u"Salaire brut"
        reference = tax_benefit_system.column_by_name["salaire_de_base"]

        def function(self, simulation, period):
            """Calcule le salaire brut à partir du salaire imposable ou sinon du salaire net.

            Sauf pour les fonctionnaires où il renvoie le traitement indiciaire brut
            Note : le supplément familial de traitement est imposable.
            """
            # Get value for year and divide below.
            salaire_imposable_pour_inversion = simulation.calculate('salaire_imposable_pour_inversion',
                period.start.offset('first-of', 'year').period('year'))

            # Calcule le salaire brut à partir du salaire imposable par inversion numérique.
#            if salaire_imposable_pour_inversion == 0 or (salaire_imposable_pour_inversion == 0).all():
#                # Quick path to avoid fsolve when using default value of input variables.
#                return period, salaire_imposable_pour_inversion

            # Calcule le salaire brut à partir du salaire imposable.
            # Sauf pour les fonctionnaires où il renvoie le traitement indiciaire brut
            # Note : le supplément familial de traitement est imposable.

            hsup = simulation.calculate('hsup', period)
            type_sal = simulation.calculate('type_sal', period)
            P = simulation.legislation_at(period.start)

            salarie = P.cotsoc.cotisations_salarie
            plafond_securite_sociale_annuel = P.cotsoc.gen.plafond_securite_sociale * 12
            taux_csg = P.csg.activite.deductible.taux * (1 - .0175)
            csg = MarginalRateTaxScale(name = 'csg')
            csg.add_bracket(0, taux_csg)

#            cat = None
#            if (type_sal == 0).all():
#                cat = 'prive_non_cadre'
#            elif (type_sal == 1).all():
#                cat = 'prive_cadre'
#            elif (type_sal == 2).all():
#                cat = 'public_titulaire_etat'
#            if cat is not None:
#                for name, bareme in salarie[cat].iteritems():
#                    print name, bareme

            prive_non_cadre = salarie['prive_non_cadre'].combine_tax_scales().scale_tax_scales(
                plafond_securite_sociale_annuel)
            prive_cadre = salarie['prive_cadre'].combine_tax_scales().scale_tax_scales(plafond_securite_sociale_annuel)
            # On ajoute la CSG deductible
            prive_non_cadre.add_tax_scale(csg)
            prive_cadre.add_tax_scale(csg)
            salaire_de_base = (
                (type_sal == CAT['prive_non_cadre']) *
                prive_non_cadre.inverse().calc(salaire_imposable_pour_inversion) +
                (type_sal == CAT['prive_cadre']) * prive_cadre.inverse().calc(salaire_imposable_pour_inversion)
                )
            return period, salaire_de_base + hsup

    class traitement_indiciaire_brut(Reform.Variable):
        column = columns.FloatCol
        entity_class = entities.Individus
        label = u"Traitement indiciaire brut"
        reference = tax_benefit_system.column_by_name["traitement_indiciaire_brut"]

        def function(self, simulation, period):
            """Calcule le tratement indiciaire brut à partir du salaire imposable.
            """
            # Get value for year and divide below.
            salaire_imposable_pour_inversion = simulation.calculate('salaire_imposable_pour_inversion',
                period.start.offset('first-of', 'year').period('year'))

            # Calcule le salaire brut à partir du salaire imposable par inversion numérique.
#            if salaire_imposable_pour_inversion == 0 or (salaire_imposable_pour_inversion == 0).all():
#                # Quick path to avoid fsolve when using default value of input variables.
#                return period, salaire_imposable_pour_inversion

            # Calcule le salaire brut à partir du salaire imposable.
            # Sauf pour les fonctionnaires où il renvoie le traitement indiciaire brut
            # Note : le supplément familial de traitement est imposable.
            type_sal = simulation.calculate('type_sal', period)
            P = simulation.legislation_at(period.start)
            taux_csg = P.csg.activite.deductible.taux * (1 - .0175)
            csg = MarginalRateTaxScale(name = 'csg')
            csg.add_bracket(0, taux_csg)

            salarie = P.cotsoc.cotisations_salarie
#            cat = None
#            if (type_sal == 2).all():
#                cat = 'public_titulaire_etat'
#            if cat is not None:
#                for name, bareme in salarie[cat].iteritems():
#                    print name, bareme

            # public etat
            # TODO: modifier la contribution exceptionelle de solidarité
            # en fixant son seuil de non imposition dans le barème (à corriger dans param.xml
            # et en tenant compte des éléments de l'assiette
            # salarie['fonc']['etat']['excep_solidarite'] = salarie['fonc']['commun']['solidarite']

            public_titulaire_etat = salarie['public_titulaire_etat'].copy()
            public_titulaire_etat['rafp'].multiply_rates(TAUX_DE_PRIME, inplace = True)
            public_titulaire_etat = salarie['public_titulaire_etat'].combine_tax_scales()

            # public_titulaire_territoriale = salarie['public_titulaire_territoriale'].combine_tax_scales()
            # public_titulaire_hospitaliere = salarie['public_titulaire_hospitaliere'].combine_tax_scales()
            # public_non_titulaire = salarie['public_non_titulaire'].combine_tax_scales()

            # Pour a fonction publique la csg est calculée sur l'ensemble salbrut(=TIB) + primes
            # Imposable = TIB - csg( (1+taux_prime)*TIB ) - pension(TIB) + taux_prime*TIB
            bareme_csg_public_titulaire_etat = csg.multiply_rates(
                1 + TAUX_DE_PRIME, inplace = False, new_name = "csg deduc titutaire etat")
            public_titulaire_etat.add_tax_scale(bareme_csg_public_titulaire_etat)
            bareme_prime = MarginalRateTaxScale(name = "taux de prime")
            bareme_prime.add_bracket(0, -TAUX_DE_PRIME)  # barème équivalent à taux_prime*TIB
            public_titulaire_etat.add_tax_scale(bareme_prime)
            traitement_indiciaire_brut = (
                (type_sal == CAT['public_titulaire_etat']) *
                public_titulaire_etat.inverse().calc(salaire_imposable_pour_inversion)
                )
            # TODO: complete this to deal with the fonctionnaire
            # supp_familial_traitement = 0  # TODO: dépend de salbrut
            # indemnite_residence = 0  # TODO: fix bug
            return period, traitement_indiciaire_brut

    class primes_fonction_publique(Reform.Variable):
        column = columns.FloatCol
        entity_class = entities.Individus
        label = u"Primes de la fonction publique"
        reference = tax_benefit_system.column_by_name["primes_fonction_publique"]

        def function(self, simulation, period):
            """Calcule les primes.
            """
            # Get value for year and divide below.
            traitement_indiciaire_brut = simulation.calculate('traitement_indiciaire_brut',
                period.start.offset('first-of', 'year').period('year'))

            return period, TAUX_DE_PRIME * traitement_indiciaire_brut

    return Reform()
def build_reform(tax_benefit_system):
    Reform = reforms.make_reform(
        key = 'allocations_familiales_imposables',
        name = u'Allocations familiales imposables',
        reference = tax_benefit_system,
        )

    @Reform.formula
    class rbg(formulas.SimpleFormulaColumn):
        label = u"Nouveau revenu brut global intégrant les allocations familiales"
        reference = ir.rbg

        def function(self, simulation, period):
            period = period.start.offset('first-of', 'year').period('year')
            allocations_familiales_imposables = simulation.calculate_add('allocations_familiales_imposables', period)
            deficit_ante = simulation.calculate('deficit_ante', period)
            f6gh = simulation.calculate('f6gh', period)
            nacc_pvce_holder = simulation.calculate('nacc_pvce', period)
            nbic_impm_holder = simulation.calculate('nbic_impm', period)
            rev_cat = simulation.calculate('rev_cat', period)
            cga = simulation.legislation_at(period.start).ir.rpns.cga_taux2

            nacc_pvce = self.sum_by_entity(nacc_pvce_holder)
            return period, max_(
                0,
                allocations_familiales_imposables + rev_cat + f6gh +
                (self.sum_by_entity(nbic_impm_holder) + nacc_pvce) * (1 + cga) - deficit_ante
                )

    @Reform.formula
    class rfr(formulas.SimpleFormulaColumn):
        label = u"Nouveau revenu fiscal de référence intégrant les allocations familiales"
        reference = ir.rfr

        def function(self, simulation, period):
            period = period.start.offset('first-of', 'year').period('year')

            allocations_familiales_imposables = simulation.calculate('allocations_familiales_imposables')
            f3va_holder = simulation.calculate('f3va')
            f3vi_holder = simulation.calculate('f3vi')
            f3vz = simulation.calculate('f3vz')
            rfr_cd = simulation.calculate('rfr_cd')
            rfr_rvcm = simulation.calculate('rfr_rvcm')
            rni = simulation.calculate('rni')
            rpns_exon_holder = simulation.calculate('rpns_exon')
            rpns_pvce_holder = simulation.calculate('rpns_pvce')
            rev_cap_lib = simulation.calculate_add('rev_cap_lib')
            microentreprise = simulation.calculate('microentreprise')

            f3va = self.sum_by_entity(f3va_holder)
            f3vi = self.sum_by_entity(f3vi_holder)
            rpns_exon = self.sum_by_entity(rpns_exon_holder)
            rpns_pvce = self.sum_by_entity(rpns_pvce_holder)

            return period, (
                max_(0, rni - allocations_familiales_imposables) +
                rfr_cd + rfr_rvcm + rev_cap_lib + f3vi + rpns_exon + rpns_pvce + f3va + f3vz + microentreprise
                )

    @Reform.formula
    class allocations_familiales_imposables(formulas.SimpleFormulaColumn):
        column = columns.FloatCol
        entity_class = entities.FoyersFiscaux
        label = u"Allocations familiales imposables"

        def function(self, simulation, period):
            period = period.start.offset('first-of', 'year').period('year')
            af_holder = simulation.calculate_add('af')
            imposition = simulation.legislation_at(period.start).allocations_familiales_imposables.imposition

            af = self.cast_from_entity_to_role(af_holder, entity= "famille", role = QUIFOY['vous'])
            af = self.sum_by_entity(af)
            return period, af * imposition

    reform = Reform()
    reform.modify_legislation_json(modifier_function = modify_legislation_json)
    return reform
Example #46
0
def build_reform(tax_benefit_system):
    Reform = reforms.make_reform(
        decomposition_dir_name=os.path.dirname(
            os.path.abspath(decompositions.__file__)),
        decomposition_file_name='decomposition.xml',
        key='revenu_de_base_enfants',
        name=u"Revenu de base enfants",
        reference=tax_benefit_system,
    )

    class nbptr(Variable):
        reference = tax_benefit_system.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.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)
            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)

            # # 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 jveuf
            # 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, (marpac | jveuf) * m + (
                veuf & not_(jveuf)) * v + celdiv * c

    # Suppression des allocations familiales
    class af(Variable):
        reference = tax_benefit_system.column_by_name['af']

        def function(self, simulation, period):
            period = period.start.offset('first-of', 'month').period('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

    # Suppression du complément familial
    class cf(Variable):
        reference = tax_benefit_system.column_by_name['cf']

        def function(self, simulation, period):
            '''
            L'allocation de base de la paje n'est pas cumulable avec le complément familial
            '''
            period = period.start.offset('first-of', 'month').period('month')
            paje_base_montant = simulation.calculate('paje_base_montant',
                                                     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 = (paje_base_montant < cf_montant) * (
                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

    # Suppression de l'allocation de rentrée scolaire
    class ars(Variable):
        reference = tax_benefit_system.column_by_name['ars']

        def function(self, simulation, period):
            '''
            Allocation de rentrée scolaire brute de CRDS
            '''

            period = period.start.offset('first-of', 'month').period('month')
            # age_holder = simulation.compute('age', period)
            # af_nbenf = simulation.calculate('af_nbenf', period)
            # smic55_holder = simulation.compute('smic55', period)
            br_pf = simulation.calculate('br_pf', period)

            return period, br_pf * 0

    # Suppression du nombre d'enfants dans le calcul du RSA socle
    class rsa_socle(Variable):
        reference = tax_benefit_system.column_by_name['rsa_socle']

        def function(self, simulation, period):
            period = period.start.offset('first-of', 'month').period('month')
            age_holder = simulation.compute('age', period)
            # smic55_holder = simulation.compute('smic55', period)
            activite_holder = simulation.compute('activite', period)
            nb_par = simulation.calculate('nb_par', period)
            rmi = simulation.legislation_at(period.start).minim.rmi

            age_parents = self.split_by_roles(age_holder, roles=[CHEF, PART])
            activite_parents = self.split_by_roles(activite_holder,
                                                   roles=[CHEF, PART])
            # age_enf = self.split_by_roles(age_holder, roles = ENFS)
            # smic55_enf = self.split_by_roles(smic55_holder, roles = ENFS)

            nbp = nb_par

            eligib = ((age_parents[CHEF] >= rmi.age_pac) *
                      not_(activite_parents[CHEF] == 2)) | (
                          (age_parents[PART] >= rmi.age_pac) *
                          not_(activite_parents[PART] == 2))

            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)
            return period, eligib * rmi.rmi * taux

    # Suppression du nombre d'enfants dans le calcul du RSA forfait logement
    class rmi_nbp(Variable):
        reference = tax_benefit_system.column_by_name['rmi_nbp']

        def function(self, simulation, period):
            # period = period.start.offset('first-of', 'month').period('month')
            # age_holder = simulation.compute('age', period)
            # smic55_holder = simulation.compute('smic55', period)
            nb_par = simulation.calculate('nb_par', period)
            # P = simulation.legislation_at(period.start).minim.rmi

            # age = self.split_by_roles(age_holder, roles = ENFS)
            # smic55 = self.split_by_roles(smic55_holder, roles = ENFS)

            return period, nb_par  # + nb_enf(age, smic55, 0, P.age_pac - 1)

    # Suppression de la cotisation patronale famille
    class famille(Variable):
        reference = tax_benefit_system.column_by_name['famille']

        def function(self, simulation, period):
            period = period.start.period(u'month').offset('first-of')
            salaire_de_base = simulation.calculate('salaire_de_base', period)

            return period, salaire_de_base * 0

    # Baisse de l'éxonération Fillon
    # TODO /!\ CHANGER LES PARAMÈTRES DE L'ÉXONÉRATION FILLON (-5,25%)
    # def taux_exo_fillon(ratio_smic_salaire, majoration, P):
    #    '''
    #    Exonération Fillon
    #    http://www.securite-sociale.fr/comprendre/dossiers/exocotisations/exoenvigueur/fillon.htm
    #    '''
    #    # La divison par zéro engendre un warning
    #    # Le montant maximum de l’allègement dépend de l’effectif de l’entreprise.
    #    # Le montant est calculé chaque année civile, pour chaque salarié ;
    #    # il est égal au produit de la totalité de la rémunération annuelle telle
    #    # que visée à l’article L. 242-1 du code de la Sécurité sociale par un
    #    # coefficient.
    #    # Ce montant est majoré de 10 % pour les entreprises de travail temporaire
    #    # au titre des salariés temporaires pour lesquels elle est tenue à
    #    # l’obligation d’indemnisation compensatrice de congés payés.
    #
    #    Pf = P.exo_bas_sal.fillon
    #    seuil = Pf.seuil
    #    tx_max = (Pf.tx_max * not_(majoration) + Pf.tx_max2 * majoration) - 0.0525
    #    if seuil <= 1:
    #        return 0
    #    # règle d'arrondi: 4 décimales au dix-millième le plus proche
    #    taux_fillon = round_(tx_max * min_(1, max_(seuil * ratio_smic_salaire - 1, 0) / (seuil - 1)), 4)
    #    return taux_fillon

    # Création d'un revenu de base enfant - Version famille
    class rdb_enfant_famille(Variable):
        column = FloatCol
        entity_class = Familles
        label = u"Revenu de base enfant"

        def function(self, simulation, period):
            period = period.start.offset('first-of', 'month').period('month')
            age_holder = simulation.compute('age', period)
            P = simulation.legislation_at(period.start).fam.af
            bmaf = P.bmaf

            smic55_holder = simulation.compute('smic55', period)
            smic55 = self.split_by_roles(smic55_holder, roles=ENFS)
            age = self.split_by_roles(age_holder, roles=ENFS)

            smic5 = {role: array * 0 for role, array in smic55.iteritems()}
            nbenf_inf13 = nb_enf(age, smic5, 0, 13)
            nbenf_sup14 = nb_enf(age, smic5, 14, 18)

            return period, (nbenf_inf13 * 0.41 + nbenf_sup14 * 0.57) * bmaf

    # Les taux 0,41 et 0,16 (0,57-0,41) sont issus des allocations familiales

    # Création d'un revenu de base enfant - Version individus
    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)

    # Création d'une CSG enfant
    class csgenf(Variable):
        column = FloatCol
        entity_class = Individus
        label = u"CSG enfant"

        def function(self, simulation, period):
            period = period.start.offset('first-of', 'month').period('month')
            revnet = simulation.calculate('revenu_net_individu', period)

            montant_csg = revnet * 0.025
            return period, -montant_csg

    class csg(Variable):
        reference = tax_benefit_system.column_by_name['csg']

        def function(self, simulation, period):
            """Contribution sociale généralisée"""
            period = period.start.offset('first-of', 'month').period('year')
            csg_imposable_salaire = simulation.calculate(
                'csg_imposable_salaire', period)
            csgsald = simulation.calculate('csgsald', period)
            csgchoi = simulation.calculate('csgchoi', period)
            csgchod = simulation.calculate('csgchod', period)
            csgrsti = simulation.calculate('csgrsti', period)
            csgrstd = simulation.calculate('csgrstd', period)
            csg_fon_holder = simulation.compute('csg_fon', period)
            csg_cap_lib_declarant1 = simulation.calculate(
                'csg_cap_lib_declarant1', period)
            csg_cap_bar_declarant1 = simulation.calculate(
                'csg_cap_bar_declarant1', period)
            csg_pv_mo_holder = simulation.compute('csg_pv_mo', period)
            csg_pv_immo_holder = simulation.compute('csg_pv_immo', period)

            csgenfant = simulation.calculate('csgenf', period)

            csg_fon = self.cast_from_entity_to_role(csg_fon_holder, role=VOUS)
            csg_pv_immo = self.cast_from_entity_to_role(csg_pv_immo_holder,
                                                        role=VOUS)
            csg_pv_mo = self.cast_from_entity_to_role(csg_pv_mo_holder,
                                                      role=VOUS)

            return period, (csg_imposable_salaire + csgsald + csgchoi +
                            csgchod + csgrsti + csgrstd + csg_fon +
                            csg_cap_lib_declarant1 + csg_pv_mo + csg_pv_immo +
                            csg_cap_bar_declarant1 + csgenfant)

    class revdisp(Variable):
        reference = tax_benefit_system.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('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_enfant = self.sum_by_entity(rdb_enfant_holder)

            return period, rev_trav + pen + rev_cap + psoc + ppe + impo + rdb_enfant

    reform = Reform()
    reform.modify_legislation_json(modifier_function=modify_legislation_json)
    return reform
def build_reform(tax_benefit_system):
    Reform = reforms.make_reform(
        key = 'ayrault_muet',
        name = u'Amendement Ayrault-Muet au PLF2016',
        reference = tax_benefit_system,
        )

    class variator(Reform.Variable):
        column = FloatCol(default = 1)
        entity_class = FoyersFiscaux
        label = u'Multiplicateur du seuil de régularisation'

    class reduction_csg(Reform.DatedVariable):
        column = FloatCol
        entity_class = Individus
        label = u"Réduction dégressive de CSG"

        @dated_function(start = date(2015, 1, 1))
        def function_2015__(self, simulation, period):
            period = period.start.offset('first-of', 'year').period('year')
            smic_proratise = simulation.calculate_add('smic_proratise', period)
            assiette_csg_abattue = simulation.calculate_add('assiette_csg_abattue', period)

            seuil = 1.34
            coefficient_correctif = .9
            taux_csg = (
                simulation.legislation_at(period.start).csg.activite.imposable.taux +
                simulation.legislation_at(period.start).csg.activite.deductible.taux
                )
            tx_max = coefficient_correctif * taux_csg
            ratio_smic_salaire = smic_proratise / (assiette_csg_abattue + 1e-16)
            # règle d'arrondi: 4 décimales au dix-millième le plus proche
            taux_allegement_csg = tx_max * min_(1, max_(seuil - 1 / ratio_smic_salaire, 0) / (seuil - 1))
            # Montant de l'allegment

            return period, taux_allegement_csg * assiette_csg_abattue

    class reduction_csg_foyer_fiscal(Reform.PersonToEntityColumn):
        entity_class = FoyersFiscaux
        label = u"Réduction dégressive de CSG des memebres du foyer fiscal"
        operation = 'add'
        variable = reduction_csg

    class reduction_csg_nette(Reform.DatedVariable):
        column = FloatCol
        entity_class = Individus
        label = u"Réduction dégressive de CSG"

        @dated_function(start = date(2015, 1, 1))
        def function_2015__(self, simulation, period):
            period = period.start.offset('first-of', 'year').period('year')
            reduction_csg = simulation.calculate('reduction_csg', period)
            ppe_elig_bis_individu = simulation.calculate('ppe_elig_bis_individu', period)
            return period, reduction_csg * ppe_elig_bis_individu

    class ppe_elig_bis(Reform.Variable):
        column = BoolCol(default = False)
        entity_class = FoyersFiscaux
        label = u"ppe_elig_bis"

        def function(self, simulation, period):
            '''
            PPE: eligibilité à la ppe, condition sur le revenu fiscal de référence
            'foy'
            '''
            period = period.start.offset('first-of', 'year').period('year')
            rfr = simulation.calculate('rfr', period)
            ppe_coef = simulation.calculate('ppe_coef', period)
            maries_ou_pacses = simulation.calculate('maries_ou_pacses', period)
            veuf = simulation.calculate('veuf', period)
            celibataire_ou_divorce = simulation.calculate('celibataire_ou_divorce', period)
            nbptr = simulation.calculate('nbptr', period)
            variator = simulation.calculate('variator', period)
            ppe = simulation.legislation_at(period.start).ir.credits_impot.ppe
            seuil = (veuf | celibataire_ou_divorce) * (ppe.eligi1 + 2 * max_(nbptr - 1, 0) * ppe.eligi3) \
                + maries_ou_pacses * (ppe.eligi2 + 2 * max_(nbptr - 2, 0) * ppe.eligi3)
            return period, (rfr * ppe_coef) <= (seuil * variator)

    class ppe_elig_bis_individu(Reform.EntityToPersonColumn):
        entity_class = Individus
        variable = ppe_elig_bis

    class regularisation_reduction_csg(Reform.DatedVariable):
        column = FloatCol
        entity_class = FoyersFiscaux
        label = u"Régularisation complète réduction dégressive de CSG"

        @dated_function(start = date(2015, 1, 1))
        def function_2015__(self, simulation, period):
            period = period.start.offset('first-of', 'year').period('year')
            reduction_csg = simulation.calculate('reduction_csg_foyer_fiscal', period)
            ppe_elig_bis = simulation.calculate('ppe_elig_bis', period)
            return period, not_(ppe_elig_bis) * (reduction_csg > 1)

    reform = Reform()
    reform.modify_legislation_json(modifier_function = ayrault_muet_modify_legislation_json)
    return reform
def build_reform(tax_benefit_system):
    from scipy.optimize import fsolve

    Reform = reforms.make_reform(
        key='inversion_revenus',
        name=u'Inversion des revenus',
        reference=tax_benefit_system,
    )

    class salaire_imposable_pour_inversion(Reform.Variable):
        column = columns.FloatCol
        entity = entities.Individu
        label = u'Salaire imposable utilisé pour remonter au salaire brut'

    class chomage_imposable_pour_inversion(Reform.Variable):
        column = columns.FloatCol
        entity = entities.Individu
        label = u'Autres revenus imposables (chômage, préretraite), utilisé pour l’inversion'

    class retraite_imposable_pour_inversion(Reform.Variable):
        column = columns.FloatCol
        entity = entities.Individu
        label = u'Pensions, retraites, rentes connues imposables, utilisé pour l’inversion'

    class salaire_de_base(Reform.Variable):
        column = columns.FloatCol
        entity = entities.Individu
        label = u"Salaire brut ou traitement indiciaire brut"
        reference = tax_benefit_system.column_by_name["salaire_de_base"]
        url = u"http://www.trader-finance.fr/lexique-finance/definition-lettre-S/Salaire-brut.html"

        def function(self, simulation, period):
            """Calcule le salaire brut à partir du salaire imposable ou sinon du salaire net.

            Sauf pour les fonctionnaires où il renvoie le traitement indiciaire brut
            Note : le supplément familial de traitement est imposable.
            """
            #        period = period.this_month

            # Get value for year and divide below.
            salaire_imposable_pour_inversion = simulation.get_array(
                'salaire_imposable_pour_inversion', period.this_year)
            if salaire_imposable_pour_inversion is None:
                salaire_net = simulation.get_array('salaire_net', period)
                if salaire_net is not None:
                    # Calcule le salaire brut à partir du salaire net par inversion numérique.
                    if (salaire_net == 0).all():
                        # Quick path to avoid fsolve when using default value of input variables.
                        return period, salaire_net
                    simulation = self.holder.entity.simulation

                    def solve_function(salaire_de_base):
                        return brut_to_target(
                            target_name='salaire_net',
                            period=period,
                            salaire_de_base=salaire_de_base,
                            simulation=simulation,
                        ) - salaire_net

                    return period, fsolve(solve_function, salaire_net)

                salaire_imposable_pour_inversion = simulation.calculate_add_divide(
                    'salaire_imposable_pour_inversion', period)

            # Calcule le salaire brut à partir du salaire imposable par inversion numérique.
            if (salaire_imposable_pour_inversion == 0).all():
                # Quick path to avoid fsolve when using default value of input variables.
                return period, salaire_imposable_pour_inversion
            simulation = self.holder.entity.simulation

            def solve_function(salaire_de_base):
                return brut_to_target(
                    target_name='salaire_imposable',
                    period=period,
                    salaire_de_base=salaire_de_base,
                    simulation=simulation,
                ) - salaire_imposable_pour_inversion

            return period, fsolve(solve_function,
                                  salaire_imposable_pour_inversion)

    #       TODO: inclure un taux de prime et calculer les primes en même temps que salaire_de_base

    #        # Calcule le salaire brut à partir du salaire imposable.
    #        # Sauf pour les fonctionnaires où il renvoie le traitement indiciaire brut
    #        # Note : le supplément familial de traitement est imposable.
    #
    #        hsup = simulation.calculate('hsup', period)
    #        categorie_salarie = simulation.calculate('categorie_salarie', period)
    #        P = simulation.legislation_at(period.start)
    #
    #        plafond_securite_sociale = P.cotsoc.gen.plafond_securite_sociale
    #
    #        salarie = P.cotsoc.sal.scale_tax_scales(plafond_securite_sociale)
    #        csg = P.csg.scale_tax_scales(plafond_securite_sociale)
    #
    #        salarie['noncadre'].update(salarie['commun'])
    #        salarie['cadre'].update(salarie['commun'])
    #
    #        # log.info(
    #        #     "Le dictionnaire des barèmes des cotisations salariés des titulaires de l'Etat contient : \n %s",
    #        #     salarie['fonc']["etat"],
    #        #     )
    #
    #        # Salariés du privé
    #
    #        noncadre = salarie['noncadre'].combine_tax_scales()
    #        cadre = salarie['cadre'].combine_tax_scales()
    #
    #        # On ajoute la CSG deductible
    #        noncadre.add_tax_scale(csg['activite']['deductible'])
    #        cadre.add_tax_scale(csg['activite']['deductible'])
    #
    #        nca = noncadre.inverse()
    #        cad = cadre.inverse()
    #        brut_nca = nca.calc(salaire_imposable_pour_inversion)
    #        brut_cad = cad.calc(salaire_imposable_pour_inversion)
    #        salbrut = brut_nca * (categorie_salarie == CATEGORIE_SALARIE['prive_non_cadre'])
    #        salbrut += brut_cad * (categorie_salarie == CATEGORIE_SALARIE['prive_cadre'])
    #
    #        # public etat
    #        # TODO: modifier la contribution exceptionelle de solidarité
    #        # en fixant son seuil de non imposition dans le barème (à corriger dans param.xml
    #        # et en tenant compte des éléments de l'assiette
    #        salarie['fonc']['etat']['excep_solidarite'] = salarie['fonc']['commun']['solidarite']
    #
    #        public_etat = salarie['fonc']['etat']['pension']
    #        # public_colloc = salarie['fonc']["colloc"].combine_tax_scales()  TODO
    #
    #        # Pour a fonction publique la csg est calculée sur l'ensemble salbrut(=TIB) + primes
    #        # Imposable = TIB - csg( (1+taux_prime)*TIB ) - pension(TIB) + taux_prime*TIB
    #        bareme_csg_titulaire_etat = csg['act']['deduc'].multiply_rates(1 + TAUX_DE_PRIME, inplace = False,
    #            new_name = "csg deduc titutaire etat")
    #        public_etat.add_tax_scale(bareme_csg_titulaire_etat)
    #        bareme_prime = MarginalRateTaxScale(name = "taux de prime")
    #        bareme_prime.add_bracket(0, -TAUX_DE_PRIME)  # barème équivalent à taux_prime*TIB
    #        public_etat.add_tax_scale(bareme_prime)
    #
    #        etat = public_etat.inverse()
    #
    #        # TODO: complete this to deal with the fonctionnaire
    #        # supp_familial_traitement = 0  # TODO: dépend de salbrut
    #        # indemnite_residence = 0  # TODO: fix bug
    #
    #        # print 'salaire_imposable_pour_inversion', salaire_imposable_pour_inversion
    #        brut_etat = etat.calc(salaire_imposable_pour_inversion)
    #        # print 'brut_etat', brut_etat
    #        # print 'impot', public_etat.calc(brut_etat)
    #        # print 'brut_etat', brut_etat
    #        salbrut_etat = (brut_etat)
    #        # TODO: fonctionnaire
    #        # print 'salbrut_etat', salbrut_etat
    #        salbrut += salbrut_etat * (categorie_salarie == CATEGORIE_SALARIE['public_titulaire_etat'])
    #
    #        #<NODE desc= "Supplément familial de traitement " shortname="Supp. fam." code= "supp_familial_traitement"/>
    #        #<NODE desc= "Indemnité de résidence" shortname="Ind. rés." code= "indemenite_residence"/>
    #        return period, salbrut + hsup

    class chomage_brut(Reform.Variable):
        column = columns.FloatCol
        entity = entities.Individu
        label = u"Allocations chômage brutes"
        url = u"http://vosdroits.service-public.fr/particuliers/N549.xhtml"

        def function(self, simulation, period):
            """"Calcule les allocations chômage brutes à partir des allocations imposables ou sinon des allocations nettes.
            """
            # Get value for year and divide below.
            chomage_imposable_pour_inversion = simulation.get_array(
                'chomage_imposable_pour_inversion', period.this_year)
            if chomage_imposable_pour_inversion is None:
                chomage_net = simulation.get_array('chomage_net', period)
                if chomage_net is not None:
                    # Calcule les allocations chomage brutes à partir des allocations nettes par inversion numérique.
                    if (chomage_net == 0).all():
                        # Quick path to avoid fsolve when using default value of input variables.
                        return period, chomage_net
                    simulation = self.holder.entity.simulation

                    def solve_function(chomage_brut):
                        return brut_to_target(
                            chomage_brut=chomage_brut,
                            target_name='chomage_net',
                            period=period,
                            simulation=simulation,
                        ) - chomage_net

                    return period, fsolve(solve_function, chomage_net)

                chomage_imposable_pour_inversion = simulation.calculate_add_divide(
                    'chomage_imposable_pour_inversion', period)

            # Calcule les allocations chômage brutes à partir des allocations imposables.
            # taux_csg_remplacement = simulation.calculate('taux_csg_remplacement', period)
            if (chomage_imposable_pour_inversion == 0).all():
                # Quick path to avoid fsolve when using default value of input variables.
                return period, chomage_imposable_pour_inversion
            simulation = self.holder.entity.simulation

            def solve_function(chomage_brut):
                return brut_to_target(
                    chomage_brut=chomage_brut,
                    # taux_csg_remplacement = taux_csg_remplacement,
                    target_name='chomage_imposable',
                    period=period,
                    simulation=simulation,
                ) - chomage_imposable_pour_inversion

            return period, fsolve(solve_function,
                                  chomage_imposable_pour_inversion)

    class retraite_brute(Reform.Variable):
        column = columns.FloatCol
        entity = entities.Individu
        label = u"Pensions de retraite brutes"
        url = u"http://vosdroits.service-public.fr/particuliers/N20166.xhtml"

        def function(self, simulation, period):
            """"Calcule les pensions de retraite brutes à partir des pensions imposables ou sinon des pensions nettes.
            """
            # period = period.this_month

            # Get value for year and divide below.
            retraite_imposable_pour_inversion = simulation.get_array(
                'retraite_imposable_pour_inversion', period.this_year)
            if retraite_imposable_pour_inversion is None:
                retraite_nette = simulation.get_array('retraite_nette', period)
                if retraite_nette is not None:
                    # Calcule les pensions de retraite brutes à partir des pensions nettes par inversion numérique.
                    if (retraite_nette == 0).all():
                        # Quick path to avoid fsolve when using default value of input variables.
                        return period, retraite_nette
                    simulation = self.holder.entity.simulation

                    def solve_function(retraite_brute):
                        return brut_to_target(
                            target_name='retraite_nette',
                            period=period,
                            retraite_brute=retraite_brute,
                            simulation=simulation,
                        ) - retraite_nette

                    return period, fsolve(solve_function, retraite_nette)

                retraite_imposable_pour_inversion = simulation.calculate_add_divide(
                    'retraite_imposable_pour_inversion', period)

            # Calcule les pensions de retraite brutes à partir des pensions imposables.
            taux_csg_remplacement = simulation.calculate(
                'taux_csg_remplacement', period)
            if (retraite_imposable_pour_inversion == 0).all():
                # Quick path to avoid fsolve when using default value of input variables.
                return period, retraite_imposable_pour_inversion
            simulation = self.holder.entity.simulation

            def solve_function(retraite_brute):
                return brut_to_target(
                    retraite_brute=retraite_brute,
                    taux_csg_remplacement=taux_csg_remplacement,
                    target_name='retraite_imposable',
                    period=period,
                    simulation=simulation,
                ) - retraite_imposable_pour_inversion

            return period, fsolve(solve_function,
                                  retraite_imposable_pour_inversion)

    return Reform()
Example #49
0
def build_reform(tax_benefit_system):
    Reform = reforms.make_reform(
        key = u'plfr2014',
        name = u'Projet de Loi de Finances Rectificative 2014',
        reference = tax_benefit_system,
        )

    @Reform.formula
    class reduction_impot_exceptionnelle(formulas.SimpleFormulaColumn):
        column = columns.FloatCol
        entity_class = entities.FoyersFiscaux
        label = u"Réduction d'impôt exceptionnelle"

        def function(self, simulation, period):
            period = period.start.offset('first-of', 'year').period('year')
            nb_adult = simulation.calculate('nb_adult')
            nb_par = simulation.calculate('nb_par')
            rfr = simulation.calculate('rfr')
            params = simulation.legislation_at(period.start).plfr2014.reduction_impot_exceptionnelle
            plafond = params.seuil * nb_adult + (nb_par - nb_adult) * 2 * params.majoration_seuil
            montant = params.montant_plafond * nb_adult
            return period, min_(max_(plafond + montant - rfr, 0), montant)

    @Reform.formula
    class reductions(formulas.DatedFormulaColumn):
        label = u"Somme des réductions d'impôt à intégrer pour l'année 2013"
        reference = reductions_impot.reductions

        @dated_function(start = date(2013, 1, 1), stop = date(2013, 12, 31))
        def function_20130101_20131231(self, simulation, period):
            period = period.start.offset('first-of', 'year').period('year')
            accult = simulation.calculate('accult')
            adhcga = simulation.calculate('adhcga')
            cappme = simulation.calculate('cappme')
            creaen = simulation.calculate('creaen')
            daepad = simulation.calculate('daepad')
            deffor = simulation.calculate('deffor')
            dfppce = simulation.calculate('dfppce')
            doment = simulation.calculate('doment')
            domlog = simulation.calculate('domlog')
            donapd = simulation.calculate('donapd')
            duflot = simulation.calculate('duflot')
            ecpess = simulation.calculate('ecpess')
            garext = simulation.calculate('garext')
            intagr = simulation.calculate('intagr')
            invfor = simulation.calculate('invfor')
            invlst = simulation.calculate('invlst')
            ip_net = simulation.calculate('ip_net')
            locmeu = simulation.calculate('locmeu')
            mecena = simulation.calculate('mecena')
            mohist = simulation.calculate('mohist')
            patnat = simulation.calculate('patnat')
            prcomp = simulation.calculate('prcomp')
            reduction_impot_exceptionnelle = simulation.calculate('reduction_impot_exceptionnelle')
            repsoc = simulation.calculate('repsoc')
            resimm = simulation.calculate('resimm')
            rsceha = simulation.calculate('rsceha')
            saldom = simulation.calculate('saldom')
            scelli = simulation.calculate('scelli')
            sofica = simulation.calculate('sofica')
            spfcpi = simulation.calculate('spfcpi')
            total_reductions = accult + adhcga + cappme + creaen + daepad + deffor + dfppce + doment + domlog + \
                donapd + duflot + ecpess + garext + intagr + invfor + invlst + locmeu + mecena + mohist + patnat + \
                prcomp + repsoc + resimm + rsceha + saldom + scelli + sofica + spfcpi + reduction_impot_exceptionnelle
            return period, min_(ip_net, total_reductions)

    reform = Reform()
    reform.modify_legislation_json(modifier_function = modify_legislation_json)
    return reform
def build_reform(tax_benefit_system):
    # Removing the formula starting in 2015-07-01
    # TODO: improve because very dirty
    # may be by creating the following functions
    # get_formulas(entity, variable, period), set_formulas(entity, variable, period)

    Reform = reforms.make_reform(
        key = 'plaf_qf_2012_sans_modulation_af',
        name = u"Legislation du plafond qf de 2012 et des af sans modulations",
        reference = tax_benefit_system,
        )
#    af_base = Reform.column_by_name['af_base']
#    if len(af_base.formula_class.dated_formulas_class) > 1:
#        del af_base.formula_class.dated_formulas_class[1]
#        af_base.formula_class.dated_formulas_class[0]['stop_instant'] = None


#    class af_taux_modulation(formulas.DatedVariable):
#        column = columns.FloatCol
#        entity_class = Familles
#        label = u"Taux de modulation à appliquer au montant des AF depuis 2015"
#
#        @dated_function(start = date(2002, 1, 1))
#        def function_2002(self, simulation, period):
#            period = period.start.offset('first-of', 'month').period('month')
#            af_nbenf = simulation.calculate('af_nbenf', period)
#            return period, 1 + 0 * af_nbenf  # Trick pour avoir la bonne longueur d'array numpy. #Todo trouver mieux
#
#        @dated_function(start = date(9999, 7, 1))
#        def function_2015(self, simulation, period):
#            period = period.start.offset('first-of', 'month').period('month')
#            af_nbenf = simulation.calculate('af_nbenf', period)
#            pfam = simulation.legislation_at(period.start).fam.af
#            br_pf = simulation.calculate('br_pf', period)
#            modulation = pfam.modulation
#            plafond1 = modulation.plafond1 + af_nbenf * modulation.enfant_supp
#            plafond2 = modulation.plafond2 + af_nbenf * modulation.enfant_supp
#
#            taux = (
#                (br_pf <= plafond1) * 1 +
#                (br_pf > plafond1) * (br_pf <= plafond2) * modulation.taux1 +
#                (br_pf > plafond2) * modulation.taux2
#            )
#
#            return period, taux
#

#    class af_complement_degressif(DatedVariable):
#        column = FloatCol
#        entity_class = Familles
#        label = u"AF - Complément dégressif en cas de dépassement du plafond"
#
#        @dated_function(start = date(9999, 7, 1))
#        def function_2015(self, simulation, period):
#            period = period.start.offset('first-of', 'month').period('month')
#            af_nbenf = simulation.calculate('af_nbenf', period)
#            br_pf = simulation.calculate('br_pf', period)
#            af_base = simulation.calculate('af_base', period)
#            af_majo = simulation.calculate('af_majo', period)
#            pfam = simulation.legislation_at(period.start).fam.af
#            modulation = pfam.modulation
#            plafond1 = modulation.plafond1 + af_nbenf * modulation.enfant_supp
#            plafond2 = modulation.plafond2 + af_nbenf * modulation.enfant_supp
#
#            depassement_plafond1 = max_(0, br_pf - plafond1)
#            depassement_plafond2 = max_(0, br_pf - plafond2)
#
#            depassement_mensuel = (
#                (depassement_plafond2 == 0) * depassement_plafond1 +
#                (depassement_plafond2 > 0) * depassement_plafond2
#            ) / 12
#
#            af = af_base + af_majo
#            return period, max_(0, af - depassement_mensuel) * (depassement_mensuel > 0)


####################
####################
    class af_taux_modulation(DatedVariable):
        column = FloatCol
        entity_class = Familles
        label = u"Taux de modulation à appliquer au montant des AF depuis 2015"

        @dated_function(start = date(2002, 1, 1))
        def function_2002(self, simulation, period):
            period = period.start.offset('first-of', 'month').period('month')
            af_nbenf = simulation.calculate('af_nbenf', period)
            return period, 1 + 0 * af_nbenf  # Trick pour avoir la bonne longueur d'array numpy. #Todo trouver mieux

        @dated_function(start = date(9999, 7, 1))
        def function_2015(self, simulation, period):
            period = period.start.offset('first-of', 'month').period('month')
            af_nbenf = simulation.calculate('af_nbenf', period)
            pfam = simulation.legislation_at(period.start).fam.af
            br_pf = simulation.calculate('br_pf', period)
            modulation = pfam.modulation
            plafond1 = modulation.plafond1 + af_nbenf * modulation.enfant_supp
            plafond2 = modulation.plafond2 + af_nbenf * modulation.enfant_supp

            taux = (
                (br_pf <= plafond1) * 1 +
                (br_pf > plafond1) * (br_pf <= plafond2) * modulation.taux1 +
                (br_pf > plafond2) * modulation.taux2
            )

            return period, taux


    class af_forf_taux_modulation(DatedVariable):
        column = FloatCol
        entity_class = Familles
        label = u"Taux de modulation à appliquer à l'allocation forfaitaire des AF depuis 2015"

        @dated_function(start = date(2002, 1, 1))
        def function_2002(self, simulation, period):
            period = period.start.offset('first-of', 'month').period('month')
            af_nbenf = simulation.calculate('af_nbenf', period)
            return period, 1 + 0 * af_nbenf  # Trick pour avoir la bonne longueur d'array numpy. #Todo trouver mieux

        @dated_function(start = date(9999, 7, 1))
        def function_2015(self, simulation, period):
            period = period.start.offset('first-of', 'month').period('month')
            pfam = simulation.legislation_at(period.start).fam.af
            af_nbenf = simulation.calculate('af_nbenf', period)
            af_forf_nbenf = simulation.calculate('af_forf_nbenf', period)
            nb_enf_tot = af_nbenf + af_forf_nbenf
            br_pf = simulation.calculate('br_pf', period)
            modulation = pfam.modulation
            plafond1 = modulation.plafond1 + nb_enf_tot * modulation.enfant_supp
            plafond2 = modulation.plafond2 + nb_enf_tot * modulation.enfant_supp

            taux = (
                (br_pf <= plafond1) * 1 +
                (br_pf > plafond1) * (br_pf <= plafond2) * modulation.taux1 +
                (br_pf > plafond2) * modulation.taux2
            )

            return period, taux


    class af_complement_degressif(DatedVariable):
        column = FloatCol
        entity_class = Familles
        label = u"AF - Complément dégressif en cas de dépassement du plafond"

        @dated_function(start = date(9999, 7, 1))
        def function_2015(self, simulation, period):
            period = period.start.offset('first-of', 'month').period('month')
            af_nbenf = simulation.calculate('af_nbenf', period)
            br_pf = simulation.calculate('br_pf', period)
            af_base = simulation.calculate('af_base', period)
            af_majo = simulation.calculate('af_majo', period)
            pfam = simulation.legislation_at(period.start).fam.af
            modulation = pfam.modulation
            plafond1 = modulation.plafond1 + af_nbenf * modulation.enfant_supp
            plafond2 = modulation.plafond2 + af_nbenf * modulation.enfant_supp

            depassement_plafond1 = max_(0, br_pf - plafond1)
            depassement_plafond2 = max_(0, br_pf - plafond2)

            depassement_mensuel = (
                (depassement_plafond2 == 0) * depassement_plafond1 +
                (depassement_plafond2 > 0) * depassement_plafond2
            ) / 12

            af = af_base + af_majo
            return period, max_(0, af - depassement_mensuel) * (depassement_mensuel > 0)


    class af_forf_complement_degressif(DatedVariable):
        column = FloatCol
        entity_class = Familles
        label = u"AF - Complément dégressif pour l'allocation forfaitaire en cas de dépassement du plafond"

        @dated_function(start = date(9999, 7, 1))
        def function_2015(self, simulation, period):
            period = period.start.offset('first-of', 'month').period('month')
            af_nbenf = simulation.calculate('af_nbenf', period)
            af_forf_nbenf = simulation.calculate('af_forf_nbenf', period)
            pfam = simulation.legislation_at(period.start).fam.af
            nb_enf_tot = af_nbenf + af_forf_nbenf
            br_pf = simulation.calculate('br_pf', period)
            af_forf = simulation.calculate('af_forf', period)
            modulation = pfam.modulation
            plafond1 = modulation.plafond1 + nb_enf_tot * modulation.enfant_supp
            plafond2 = modulation.plafond2 + nb_enf_tot * modulation.enfant_supp

            depassement_plafond1 = max_(0, br_pf - plafond1)
            depassement_plafond2 = max_(0, br_pf - plafond2)

            depassement_mensuel = (
                (depassement_plafond2 == 0) * depassement_plafond1 +
                (depassement_plafond2 > 0) * depassement_plafond2
            ) / 12

            return period, max_(0, af_forf - depassement_mensuel) * (depassement_mensuel > 0)
            af_forf + af_complement_degressif + af_forf_complement_degressif

    reform = Reform()
    reform.modify_legislation_json(modifier_function = modify_legislation_json)
    return reform
def build_reform(tax_benefit_system):
    Reform = reforms.make_reform(
        key = 'aides_ville_paris',
        name = u'Aides de la ville de Paris',
        reference = tax_benefit_system,
        )

    class parisien(Reform.Variable):
        column = columns.BoolCol
        entity_class = entities.Menages
        label = u"Résidant à Paris au moins 3 ans dans les 5 dernières années"

    class a_charge_fiscale(Reform.Variable):
        column = columns.BoolCol
        entity_class = entities.Individus
        label = u"Enfant à charge fiscale du demandeur"

    class enfant_place(Reform.Variable):
        column = columns.BoolCol
        entity_class = entities.Individus
        label = u"Enfant placé en structure spécialisée ou famille d'accueil"

    class paris_logement_familles_elig(Reform.Variable):
        column = columns.BoolCol
        label = u"Eligibilité à Paris-Logement-Familles"
        entity_class = entities.Familles

        def function(self, simulation, period):
            parisien = simulation.calculate('parisien', period)
            statut_occupation_logement = simulation.calculate('statut_occupation_logement', period)
            charge_logement = (
                (statut_occupation_logement == 1) +
                (statut_occupation_logement == 2) +
                (statut_occupation_logement == 3) +
                (statut_occupation_logement == 4) +
                (statut_occupation_logement == 5) +
                (statut_occupation_logement == 7)
                )

            result = parisien * charge_logement

            return period, result

    class paris_logement_familles_br_i(Reform.Variable):
        column = columns.FloatCol
        label = u"Base de ressources individuelle pour Paris Logement Famille"
        entity_class = entities.Individus

        def function(self, simulation, period):
            period = period.this_month
            last_year = period.last_year
            salaire_net = simulation.calculate('salaire_net', period)
            chomage_net = simulation.calculate('chomage_net', period)
            retraite_nette = simulation.calculate('retraite_nette', period)
            pensions_alimentaires_percues = simulation.calculate('pensions_alimentaires_percues', period)
            pensions_alimentaires_versees_individu = simulation.calculate(
                'pensions_alimentaires_versees_individu', period)
            rsa_base_ressources_patrimoine_i = simulation.calculate_add('rsa_base_ressources_patrimoine_individu', period)
            indemnites_journalieres_imposables = simulation.calculate('indemnites_journalieres_imposables', period)
            indemnites_stage = simulation.calculate('indemnites_stage', period)
            revenus_stage_formation_pro = simulation.calculate('revenus_stage_formation_pro', period)
            allocation_securisation_professionnelle = simulation.calculate(
                'allocation_securisation_professionnelle', period)
            prestation_compensatoire = simulation.calculate('prestation_compensatoire', period)
            pensions_invalidite = simulation.calculate('pensions_invalidite', period)
            indemnites_chomage_partiel = simulation.calculate('indemnites_chomage_partiel', period)
            bourse_recherche = simulation.calculate('bourse_recherche', period)
            gains_exceptionnels = simulation.calculate('gains_exceptionnels', period)

            def revenus_tns():
                revenus_auto_entrepreneur = simulation.calculate_add('tns_auto_entrepreneur_benefice', period)

                # Les revenus TNS hors AE sont estimés en se basant sur le revenu N-1
                tns_micro_entreprise_benefice = simulation.calculate('tns_micro_entreprise_benefice', last_year) / 12
                tns_benefice_exploitant_agricole = simulation.calculate('tns_benefice_exploitant_agricole', last_year) / 12
                tns_autres_revenus = simulation.calculate('tns_autres_revenus', last_year) / 12

                return revenus_auto_entrepreneur + tns_micro_entreprise_benefice + tns_benefice_exploitant_agricole + tns_autres_revenus

            result = (
                salaire_net + indemnites_chomage_partiel + indemnites_stage + chomage_net + retraite_nette +
                pensions_alimentaires_percues - abs_(pensions_alimentaires_versees_individu) +
                rsa_base_ressources_patrimoine_i + allocation_securisation_professionnelle +
                indemnites_journalieres_imposables + prestation_compensatoire +
                pensions_invalidite + bourse_recherche + gains_exceptionnels + revenus_tns() +
                revenus_stage_formation_pro
                )

            return period, result

    class paris_logement_familles_br(Reform.Variable):
        column = columns.FloatCol
        label = u"Base de ressource pour Paris Logement Famille"
        entity_class = entities.Familles

        def function(self, simulation, period):
            period = period.this_month
            paris_logement_familles_br_i_holder = simulation.compute('paris_logement_familles_br_i', period)
            paris_logement_familles_br = self.sum_by_entity(paris_logement_familles_br_i_holder)
            result = paris_logement_familles_br

            return period, result

    class plf_enfant_handicape(Reform.Variable):
        column = columns.BoolCol
        label = u"Enfant handicapé au sens de la mairie de Paris"
        entity_class = entities.Individus

        def function(self, simulation, period):
            period = period.this_month

            handicap = simulation.calculate('handicap', period)
            plf_enfant = simulation.calculate('plf_enfant', period)

            return period, plf_enfant * handicap

    class plf_enfant(Reform.Variable):
        column = columns.BoolCol
        label = u"Enfant pris en compte par la mairie de Paris pour PLF"
        entity_class = entities.Individus

        def function(self, simulation, period):
            period = period.this_month
            est_enfant_dans_famille = simulation.calculate('est_enfant_dans_famille', period)
            enfant_place = simulation.calculate('enfant_place', period)
            a_charge_fiscale = simulation.calculate('a_charge_fiscale', period)

            return period, est_enfant_dans_famille * (1 - enfant_place) * a_charge_fiscale

    class plf_enfant_garde_alternee(Reform.Variable):
        column = columns.BoolCol
        label = u"Enfant en garde alternée pris en compte par la mairie de Paris pour PLF"
        entity_class = entities.Individus

        def function(self, simulation, period):
            period = period.this_month
            garde_alternee = simulation.calculate('garde_alternee', period)
            plf_enfant = simulation.calculate('plf_enfant', period)

            return period, garde_alternee * plf_enfant

    class plf_enfant_handicape_garde_alternee(Reform.Variable):
        column = columns.BoolCol
        label = u"Enfant handicapé en garde alternée pris en compte par la mairie de Paris pour PLF"
        entity_class = entities.Individus

        def function(self, simulation, period):
            period = period.this_month
            garde_alternee = simulation.calculate('garde_alternee', period)
            plf_enfant_handicape = simulation.calculate('plf_enfant_handicape', period)

            return period, garde_alternee * plf_enfant_handicape

    class plf_handicap(Reform.Variable):
        column = columns.FloatCol
        entity_class = entities.Familles
        label = u"Allocation Paris-Logement-Familles en cas d'enfant handicapé"

        def function(self, simulation, period):
            period = period.this_month
            plf_enfant_handicape = simulation.compute('plf_enfant_handicape', period)
            plf_enfant_handicape_garde_alternee = simulation.compute('plf_enfant_handicape_garde_alternee', period)
            br = simulation.calculate('paris_logement_familles_br', period)

            nb_enf_handicape = self.sum_by_entity(plf_enfant_handicape)
            nb_enf_handicape_garde_alternee = self.sum_by_entity(plf_enfant_handicape_garde_alternee)

            P = simulation.legislation_at(period.start).aides_locales.paris.paris_logement_familles
            plafond = P.plafond_haut_3enf
            montant = P.montant_haut_3enf

            plf_handicap = (nb_enf_handicape > 0) * (br <= plafond) * montant

            # Si tous les enfants handicapés sont en garde alternée
            garde_alternee = nb_enf_handicape - nb_enf_handicape_garde_alternee == 0
            deduction_garde_alternee = garde_alternee * 0.5 * plf_handicap

            plf_handicap = plf_handicap - deduction_garde_alternee

            return period, plf_handicap

    class paris_logement_familles(Reform.Variable):
        column = columns.FloatCol
        label = u"Allocation Paris Logement Familles"
        entity_class = entities.Familles
        url = "http://www.paris.fr/pratique/toutes-les-aides-et-allocations/aides-sociales/paris-logement-familles-prestation-ville-de-paris/rub_9737_stand_88805_port_24193"  # noqa

        def function(self, simulation, period):
            period = period.this_month
            elig = simulation.calculate('paris_logement_familles_elig', period)
            br = simulation.calculate('paris_logement_familles_br', period)
            plf_enfant = simulation.compute('plf_enfant', period)
            nbenf = self.sum_by_entity(plf_enfant)
            plf_enfant_garde_alternee = simulation.compute('plf_enfant_garde_alternee', period)
            nbenf_garde_alternee = self.sum_by_entity(plf_enfant_garde_alternee)
            plf_handicap = simulation.calculate('plf_handicap', period)
            loyer = simulation.calculate('loyer', period) + simulation.calculate('charges_locatives', period)
            P = simulation.legislation_at(period.start).aides_locales.paris.paris_logement_familles

            ressources_sous_plaf_bas = (br <= P.plafond_bas_3enf)
            ressources_sous_plaf_haut = (br <= P.plafond_haut_3enf) * (br > P.plafond_bas_3enf)
            montant_base_3enfs = (nbenf >= 3) * (
                ressources_sous_plaf_bas * P.montant_haut_3enf +
                ressources_sous_plaf_haut * P.montant_bas_3enf
                )
            montant_enf_sup = (
                ressources_sous_plaf_bas * P.montant_haut_enf_sup +
                ressources_sous_plaf_haut * P.montant_bas_enf_sup
                )
            montant_3enfs = montant_base_3enfs + montant_enf_sup * max_(nbenf - 3, 0)
            montant_2enfs = (nbenf == 2) * (br <= P.plafond_2enf) * P.montant_2enf

            plf = montant_2enfs + montant_3enfs

            deduction_garde_alternee = (nbenf_garde_alternee > 0) * (
                (nbenf - nbenf_garde_alternee < 3) * 0.5 * plf +
                (nbenf - nbenf_garde_alternee >= 3) * nbenf_garde_alternee * 0.5 * montant_enf_sup
                )

            plf = plf - deduction_garde_alternee

            plf = max_(plf, plf_handicap)
            plf = elig * plf
            plf = min_(plf, loyer)

            return period, plf

    reform = Reform()
    reform.modify_legislation_json(modifier_function = modify_legislation_json)
    return reform
Example #52
0
def build_reform(tax_benefit_system):
    reference_legislation_json = tax_benefit_system.legislation_json
    reform_legislation_json = copy.deepcopy(reference_legislation_json)
    reform_year = 2007
    reform_period = periods.period('year', reform_year)

    def update_threshold_bracket(bracket, amount):
        return reforms.update_legislation(
            legislation_json=reform_legislation_json,
            path=('children', 'ir', 'children', 'bareme', 'brackets', bracket,
                  'threshold'),
            period=reform_period,
            value=amount,
        )

    def update_rate_bracket(bracket, rate):
        return reforms.update_legislation(
            legislation_json=reform_legislation_json,
            path=('children', 'ir', 'children', 'bareme', 'brackets', bracket,
                  'rate'),
            period=reform_period,
            value=rate,
        )

    reform_legislation_json = update_rate_bracket(bracket=0, rate=0)
    reform_legislation_json = update_rate_bracket(bracket=1, rate=.0683)
    reform_legislation_json = update_rate_bracket(bracket=2, rate=.1914)
    reform_legislation_json = update_rate_bracket(bracket=3, rate=.2826)
    reform_legislation_json = update_rate_bracket(bracket=4, rate=.3738)
    reform_legislation_json = update_rate_bracket(bracket=5, rate=.4262)
    reform_legislation_json = update_rate_bracket(bracket=6, rate=.4809)

    inflation = 1
    reform_legislation_json = update_threshold_bracket(bracket=0, amount=0)
    reform_legislation_json = update_threshold_bracket(bracket=1,
                                                       amount=4412 * inflation)
    reform_legislation_json = update_threshold_bracket(bracket=2,
                                                       amount=8677 * inflation)
    reform_legislation_json = update_threshold_bracket(bracket=3,
                                                       amount=15274 *
                                                       inflation)
    reform_legislation_json = update_threshold_bracket(bracket=4,
                                                       amount=24731 *
                                                       inflation)
    reform_legislation_json = update_threshold_bracket(bracket=5,
                                                       amount=40241 *
                                                       inflation)
    reform_legislation_json = update_threshold_bracket(bracket=6,
                                                       amount=49624 *
                                                       inflation)

    reform_legislation_json = reforms.update_legislation(
        legislation_json=reform_legislation_json,
        path=('children', 'ir', 'children', 'tspr', 'children', 'sabatsalpen'),
        period=reform_period,
        value=0,
    )

    Reform = reforms.make_reform(
        legislation_json=reform_legislation_json,
        name=u'ir_2006',
        new_formulas=(),
        reference=tax_benefit_system,
    )
    return Reform()