Beispiel #1
0
def test_round_marginal_tax_scale():

    base = np.array([200, 200.2, 200.002, 200.6, 200.006, 200.5, 200.005])

    marginal_tax_scale = MarginalRateTaxScale()
    marginal_tax_scale.add_bracket(0, 0)
    marginal_tax_scale.add_bracket(100, 0.1)

    assert_near(
        marginal_tax_scale.calc(base),
        [10, 10.02, 10.0002, 10.06, 10.0006, 10.05, 10.0005],
        absolute_error_margin=1e-10,
    )
    assert_near(
        marginal_tax_scale.calc(base, round_base_decimals=1),
        [10, 10., 10., 10.1, 10., 10, 10.],
        absolute_error_margin=1e-10,
    )
    assert_near(
        marginal_tax_scale.calc(base, round_base_decimals=2),
        [10, 10.02, 10., 10.06, 10.00, 10.05, 10],
        absolute_error_margin=1e-10,
    )
    assert_near(
        marginal_tax_scale.calc(base, round_base_decimals=3),
        [10, 10.02, 10., 10.06, 10.001, 10.05, 10],
        absolute_error_margin=1e-10,
    )
Beispiel #2
0
def creerBareme(personne, period, impot, type):
    nbTranches = personne.pays(f'nombre_tranches_{impot}_{type}', period)[0]
    bareme = MarginalRateTaxScale(name='Bareme custom')
    for tranche in range(1, nbTranches + 1):
        bareme.add_bracket(
            personne.pays(f'seuil_{impot}_{type}_tranche_{tranche}',
                          period)[0],
            personne.pays(f'taux_{impot}_{type}_tranche_{tranche}', period)[0])
    return bareme
def test_inverse_marginal_tax_scale():
    marginal_tax_scale = MarginalRateTaxScale()
    marginal_tax_scale.add_bracket(0, 0)
    marginal_tax_scale.add_bracket(1, 0.1)
    marginal_tax_scale.add_bracket(3, 0.05)

    brut = np.array([1, 2, 3, 4, 5, 3.28976, 8764])
    net = brut - marginal_tax_scale.calc(brut)
    inverse = marginal_tax_scale.inverse()
    assert_near(brut, inverse.calc(net), 1e-15)
        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
def test_round_marginal_tax_scale():

    base = np.array([200, 200.2, 200.002, 200.6, 200.006, 200.5, 200.005])

    marginal_tax_scale = MarginalRateTaxScale()
    marginal_tax_scale.add_bracket(0, 0)
    marginal_tax_scale.add_bracket(100, 0.1)

    assert_near(
        marginal_tax_scale.calc(base),
        [10, 10.02, 10.0002, 10.06, 10.0006, 10.05, 10.0005],
        absolute_error_margin = 1e-10,
        )
    assert_near(
        marginal_tax_scale.calc(base, round_base_decimals = 1),
        [10, 10., 10., 10.1, 10., 10, 10.],
        absolute_error_margin = 1e-10,
        )
    assert_near(
        marginal_tax_scale.calc(base, round_base_decimals = 2),
        [10, 10.02, 10., 10.06, 10.00, 10.05, 10],
        absolute_error_margin = 1e-10,
        )
    assert_near(
        marginal_tax_scale.calc(base, round_base_decimals = 3),
        [10, 10.02, 10., 10.06, 10.001, 10.05, 10],
        absolute_error_margin = 1e-10,
        )
    def formula(individu, period, parameters):
        """Calcule le salaire brut à partir du salaire imposable par inversion du barème
        de cotisations sociales correspondant à la catégorie à laquelle appartient le salarié.
        """
        # Get value for year and divide below.
        salaire_imposable_pour_inversion = individu(
            'salaire_imposable_pour_inversion',
            period.start.offset('first-of', 'year').period('year'))

        # 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 = individu('hsup', period)
        categorie_salarie = individu('categorie_salarie', period)
        P = parameters(period)

        salarie = P.cotsoc.cotisations_salarie
        plafond_securite_sociale_annuel = P.cotsoc.gen.plafond_securite_sociale * 12
        taux_csg = parameters(
            period
        ).prelevements_sociaux.contributions.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].items():
        #                    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 == TypesCategorieSalarie.prive_non_cadre) *
            prive_non_cadre.inverse().calc(salaire_imposable_pour_inversion) +
            (categorie_salarie == TypesCategorieSalarie.prive_cadre) *
            prive_cadre.inverse().calc(salaire_imposable_pour_inversion))

        return salaire_de_base + hsup
Beispiel #7
0
def test_simple_linear_average_rate_tax_scale():
    base = np.array([1, 1.5, 2, 2.5, 3.0, 4.0])

    marginal_tax_scale = MarginalRateTaxScale()
    marginal_tax_scale.add_bracket(0, 0)
    marginal_tax_scale.add_bracket(1, 0.1)
    marginal_tax_scale.add_bracket(2, 0.2)
    marginal_tax_scale.add_bracket(3, 0)
    assert_near(marginal_tax_scale.calc(base), [0, .05, .1, .2, .3, .3], absolute_error_margin = 1e-10)
        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
 def formula_2015(individu, period, parameters):
     plafond_securite_sociale_annuel = parameters(period).cotsoc.gen.plafond_securite_sociale * 12
     bareme = MarginalRateTaxScale(name = 'vieillesse')
     assurance_vieillesse = parameters(period).prelevements_sociaux.ret_pl.assurance_vieillesse
     bareme.add_bracket(0, assurance_vieillesse.sous_1_pss)
     bareme.add_bracket(1, assurance_vieillesse.entre_1_et_5_pss)
     bareme.add_bracket(5, 0)
     bareme.multiply_thresholds(plafond_securite_sociale_annuel)
     categorie_non_salarie = individu('categorie_non_salarie', period)
     assiette = (
         + (categorie_non_salarie == TypesCategorieNonSalarie.profession_liberale)
         ) * individu('rpns_individu', period)
     return -bareme.calc(assiette)
 def formula(individu, period, parameters):
     plafond_securite_sociale_annuel = parameters(period).cotsoc.gen.plafond_securite_sociale * 12
     bareme = MarginalRateTaxScale(name = 'maladie_maternite')
     bareme.add_bracket(0, 0)
     bareme.add_bracket(1.1, .065)  # TODO parsing des paramèters IPP pas à jour
     bareme.multiply_thresholds(plafond_securite_sociale_annuel)
     categorie_non_salarie = individu('categorie_non_salarie', period)
     assiette = (
         (categorie_non_salarie == TypesCategorieNonSalarie.profession_liberale)
         * individu('rpns_individu', period)
         )
     taux = (
         .015 + (.065 - .015) * min_(
             max_(
                 assiette / plafond_securite_sociale_annuel,
                 0
                 ),
             1.1
             )
         / 1.1
         )
     return - (
         taux * assiette * (assiette < 1.1 * plafond_securite_sociale_annuel)
         + bareme.calc(assiette)
         )
Beispiel #11
0
def test_linear_average_rate_tax_scale():
    base = np.array([1, 1.5, 2, 2.5])

    marginal_tax_scale = MarginalRateTaxScale()
    marginal_tax_scale.add_bracket(0, 0)
    marginal_tax_scale.add_bracket(1, 0.1)
    marginal_tax_scale.add_bracket(2, 0.2)
    assert_near(marginal_tax_scale.calc(base), [0, .05, .1, .2],
                absolute_error_margin=1e-16)

    average_tax_scale = marginal_tax_scale.to_average()
    # Note: assert_near doesn't work for inf.
    # assert_near(average_tax_scale.thresholds, [0, 1, 2, np.inf], absolute_error_margin = 0)
    assert average_tax_scale.thresholds == [0, 1, 2, np.inf]
    assert_near(average_tax_scale.rates, [0, 0, 0.05, 0.2],
                absolute_error_margin=0)
    assert_near(average_tax_scale.calc(base), [0, 0.0375, 0.1, 0.125],
                absolute_error_margin=1e-10)

    new_marginal_tax_scale = average_tax_scale.to_marginal()
    assert_near(new_marginal_tax_scale.thresholds,
                marginal_tax_scale.thresholds,
                absolute_error_margin=0)
    assert_near(new_marginal_tax_scale.rates,
                marginal_tax_scale.rates,
                absolute_error_margin=0)
    assert_near(average_tax_scale.rates, [0, 0, 0.05, 0.2],
                absolute_error_margin=0)
 def formula_2015(individu, period, parameters):
     plafond_securite_sociale_annuel = parameters(period).cotsoc.gen.plafond_securite_sociale * 12
     bareme = MarginalRateTaxScale(name = 'famille')
     bareme.add_bracket(0, 0)
     bareme.add_bracket(1.4, .031)  # TODO parsing des paramèters pas à jour
     bareme.multiply_thresholds(plafond_securite_sociale_annuel)
     categorie_non_salarie = individu('categorie_non_salarie', period)
     assiette = (
         (categorie_non_salarie == TypesCategorieNonSalarie.artisan)
         + (categorie_non_salarie == TypesCategorieNonSalarie.commercant)
         + (categorie_non_salarie == TypesCategorieNonSalarie.profession_liberale)
         ) * individu('rpns_individu', period)
     taux = (
         0 + (.031) * min_(
             max_(
                 assiette / plafond_securite_sociale_annuel - 1.1,
                 0
                 ),
             (1.4 - 1.1)
             )
         / (1.4 - 1.1)
         )
     return - (
         taux * assiette * (assiette < 1.4 * plafond_securite_sociale_annuel)
         + bareme.calc(assiette)
         )
Beispiel #13
0
 def formula_2013(individu, period, parameters):
     plafond_securite_sociale_annuel = parameters(
         period).cotsoc.gen.plafond_securite_sociale * 12
     bareme = MarginalRateTaxScale(name='retraite_complementaire')
     bareme.add_bracket(0, .09)  # TODO taux à la louche car hétérogène
     bareme.add_bracket(5, 0)
     bareme.multiply_thresholds(plafond_securite_sociale_annuel)
     categorie_non_salarie = individu('categorie_non_salarie', period)
     assiette = (+(categorie_non_salarie == TypesCategorieNonSalarie.
                   profession_liberale)) * individu('rpns_individu', period)
     return -bareme.calc(assiette)
    def formula(individu, period, parameters):
        """Calcule le salaire brut à partir du salaire imposable par inversion du barème
        de cotisations sociales correspondant à la catégorie à laquelle appartient le salarié.
        """
        # Get value for year and divide below.
        salaire_imposable_pour_inversion = individu('salaire_imposable_pour_inversion',
            period.start.offset('first-of', 'year').period('year'))

        # 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 = individu('hsup', period)
        categorie_salarie = individu('categorie_salarie', period)
        P = parameters(period)

        salarie = P.cotsoc.cotisations_salarie
        plafond_securite_sociale_annuel = P.cotsoc.gen.plafond_securite_sociale * 12
        taux_csg = parameters(period).prelevements_sociaux.contributions.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].items():
#                    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 == TypesCategorieSalarie.prive_non_cadre)
            * prive_non_cadre.inverse().calc(salaire_imposable_pour_inversion)
            + (categorie_salarie == TypesCategorieSalarie.prive_cadre)
            * prive_cadre.inverse().calc(salaire_imposable_pour_inversion)
            )

        return salaire_de_base + hsup
Beispiel #15
0
    def function(self, simulation, period):
        '''
        Cotisation sociales patronales
        '''
        period = period.start.offset('first-of', 'month').period('year')
        salaire_brut = simulation.calculate('salaire_brut', period = period)
        categorie_salarie = simulation.calculate('categorie_salarie', period = period)
        _P = simulation.legislation_at(period.start)

        # TODO traiter les différents régimes séparément ?

        smig = _P.cotisations_sociales.gen.smig
        cotisations_sociales = MarginalRateTaxScale('cotisations_sociales', _P.cotisations_sociales)

        plaf_ss = 12 * smig
        # TODO: clean all this
        n = len(salaire_brut)
        cotpat = zeros(n)
        for categ in CAT:
            iscat = (categorie_salarie == categ[1])
            if categ[0] == 're':
                return period, salaire_brut  # on retounre le salaire_brut pour les étudiants
            else:
                continue
            if 'pat' in cotisations_sociales[categ[0]]:
                pat = cotisations_sociales[categ[0]]['pat']
                baremes = scale_tax_scales(pat, plaf_ss)
                bar = combine_tax_scales(baremes)
                temp = - iscat * bar.calc(salaire_brut)
                cotpat += temp
        return period, cotpat
Beispiel #16
0
    def function(self, simulation, period):
        '''
        Calcule le salaire brut à partir du salaire net
        '''
        period = period.start.offset('first-of', 'month').period('year')
        salaire_imposable = simulation.calculate('salaire_imposable', period = period)
        categorie_salarie = simulation.calculate('categorie_salarie', period = period)
        _defaultP = simulation.legislation_at(period.start, reference = True)

        smig = _defaultP.cotisations_sociales.gen.smig
        cotisations_sociales = MarginalRateTaxScale('cotisations_sociales', _defaultP.cotisations_sociales)

        plaf_ss = 12 * smig

        n = len(salaire_imposable)
        salaire_brut = zeros(n)
        # TODO améliorer tout cela !!
        for categ in CAT:
            iscat = (categorie_salarie == categ[1])
            if categ[0] == 're':
                return period, salaire_imposable  # on retourne le salaire_imposable pour les étudiants
            else:
                continue

            if 'sal' in cotisations_sociales[categ[0]]:
                sal = cotisations_sociales[categ[0]]['sal']
                baremes = sal.scale_tax_scales(plaf_ss)
                bar = combine_bracket(baremes)
                invbar = bar.inverse()
                temp = iscat * invbar.calc(salaire_imposable)
                salaire_brut += temp
        return period, salaire_brut
Beispiel #17
0
def test_simple_linear_average_rate_tax_scale():
    base = np.array([1, 1.5, 2, 2.5, 3.0, 4.0])

    marginal_tax_scale = MarginalRateTaxScale()
    marginal_tax_scale.add_bracket(0, 0)
    marginal_tax_scale.add_bracket(1, 0.1)
    marginal_tax_scale.add_bracket(2, 0.2)
    marginal_tax_scale.add_bracket(3, 0)
    assert_near(marginal_tax_scale.calc(base), [0, .05, .1, .2, .3, .3], absolute_error_margin = 1e-10)
Beispiel #18
0
 def formula(individu, period, parameters):
     plafond_securite_sociale_annuel = parameters(
         period).cotsoc.gen.plafond_securite_sociale * 12
     bareme = MarginalRateTaxScale(name='formation_profession_liberale')
     taux = parameters(
         period
     ).prelevements_sociaux.formation_pl.formation_professionnelle.sous_pss
     bareme.add_bracket(0, taux)
     bareme.add_bracket(1, 0)
     bareme.multiply_thresholds(plafond_securite_sociale_annuel)
     categorie_non_salarie = individu('categorie_non_salarie', period)
     assiette = (+(categorie_non_salarie == TypesCategorieNonSalarie.
                   profession_liberale)) * individu('rpns_individu', period)
     return -bareme.calc(assiette)
 def formula_2013(individu, period, parameters):
     plafond_securite_sociale_annuel = parameters(period).cotsoc.gen.plafond_securite_sociale * 12
     bareme = MarginalRateTaxScale(name = 'retraite_complementaire')
     bareme.add_bracket(0, .09)  # TODO taux à la louche car hétérogène
     bareme.add_bracket(5, 0)
     bareme.multiply_thresholds(plafond_securite_sociale_annuel)
     categorie_non_salarie = individu('categorie_non_salarie', period)
     assiette = (
         + (categorie_non_salarie == TypesCategorieNonSalarie.profession_liberale)
         ) * individu('rpns_individu', period)
     return -bareme.calc(assiette)
        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
Beispiel #21
0
    def formula_2015(individu, period, parameters):
        plafond_securite_sociale_annuel = parameters(
            period).cotsoc.gen.plafond_securite_sociale * 12
        bareme = MarginalRateTaxScale(name='deces')
        deces = parameters(period).prelevements_sociaux.deces_ac.artisans
        bareme.add_bracket(0, deces.sous_pss)
        bareme.add_bracket(1, 0)
        bareme.multiply_thresholds(plafond_securite_sociale_annuel)
        categorie_non_salarie = individu('categorie_non_salarie', period)
        assiette = (
            (categorie_non_salarie == TypesCategorieNonSalarie.artisan) +
            (categorie_non_salarie == TypesCategorieNonSalarie.commercant)
        ) * individu('rpns_individu', period)

        return -bareme.calc(assiette)
 def formula(individu, period, parameters):
     plafond_securite_sociale_annuel = parameters(period).cotsoc.gen.plafond_securite_sociale * 12
     bareme = MarginalRateTaxScale(name = 'formation_profession_liberale')
     taux = parameters(period).prelevements_sociaux.formation_pl.formation_professionnelle.sous_pss
     bareme.add_bracket(0, taux)
     bareme.add_bracket(1, 0)
     bareme.multiply_thresholds(plafond_securite_sociale_annuel)
     categorie_non_salarie = individu('categorie_non_salarie', period)
     assiette = (
         + (categorie_non_salarie == TypesCategorieNonSalarie.profession_liberale)
         ) * individu('rpns_individu', period)
     return -bareme.calc(assiette)
 def formula_2014(individu, period, parameters):
     plafond_securite_sociale_annuel = parameters(period).cotsoc.gen.plafond_securite_sociale * 12
     vieillesse_artisan_commercant = parameters(period).prelevements_sociaux.ret_ac
     bareme = MarginalRateTaxScale(name = 'vieillesse')
     bareme.add_bracket(0, vieillesse_artisan_commercant.artisans.sous_pss + vieillesse_artisan_commercant.tous_independants.tout_salaire)
     bareme.add_bracket(1, vieillesse_artisan_commercant.tous_independants.tout_salaire)
     bareme.multiply_thresholds(plafond_securite_sociale_annuel)
     categorie_non_salarie = individu('categorie_non_salarie', period)
     assiette = (
         (categorie_non_salarie == TypesCategorieNonSalarie.artisan)
         + (categorie_non_salarie == TypesCategorieNonSalarie.commercant)
         ) * individu('rpns_individu', period)
     return -bareme.calc(assiette)
Beispiel #24
0
 def formula(individu, period, parameters):
     plafond_securite_sociale_annuel = parameters(
         period).cotsoc.gen.plafond_securite_sociale * 12
     bareme = MarginalRateTaxScale(name='maladie_maternite')
     bareme.add_bracket(0, 0)
     bareme.add_bracket(1.1,
                        .065)  # TODO parsing des paramèters IPP pas à jour
     bareme.multiply_thresholds(plafond_securite_sociale_annuel)
     categorie_non_salarie = individu('categorie_non_salarie', period)
     assiette = ((categorie_non_salarie
                  == TypesCategorieNonSalarie.profession_liberale) *
                 individu('rpns_individu', period))
     taux = (.015 + (.065 - .015) * min_(
         max_(assiette / plafond_securite_sociale_annuel, 0), 1.1) / 1.1)
     return -(taux * assiette *
              (assiette < 1.1 * plafond_securite_sociale_annuel) +
              bareme.calc(assiette))
    def formula_2015(individu, period, parameters):
        plafond_securite_sociale_annuel = parameters(period).cotsoc.gen.plafond_securite_sociale * 12
        bareme = MarginalRateTaxScale(name = 'deces')
        deces = parameters(period).prelevements_sociaux.deces_ac.artisans
        bareme.add_bracket(0, deces.sous_pss)
        bareme.add_bracket(1, 0)
        bareme.multiply_thresholds(plafond_securite_sociale_annuel)
        categorie_non_salarie = individu('categorie_non_salarie', period)
        assiette = (
            (categorie_non_salarie == TypesCategorieNonSalarie.artisan)
            + (categorie_non_salarie == TypesCategorieNonSalarie.commercant)
            ) * individu('rpns_individu', period)

        return -bareme.calc(assiette)
 def formula_2013(individu, period, parameters):
     plafond_securite_sociale_annuel = parameters(period).cotsoc.gen.plafond_securite_sociale * 12
     retraite_complementaire = parameters(period).prelevements_sociaux.ret_comp_ac.artisans_industriels_commercants
     montant_du_plafond_rci = retraite_complementaire.montant_du_plafond_rci
     bareme = MarginalRateTaxScale(name = 'retraite_complementaire')
     bareme.add_bracket(0, retraite_complementaire.sous_plafond_rci)
     bareme.add_bracket(montant_du_plafond_rci, retraite_complementaire.entre_1_plafond_rci_et_4_plafonds_pss)
     bareme.add_bracket(4 * plafond_securite_sociale_annuel, 0)
     categorie_non_salarie = individu('categorie_non_salarie', period)
     assiette = (
         (categorie_non_salarie == TypesCategorieNonSalarie.artisan)
         + (categorie_non_salarie == TypesCategorieNonSalarie.commercant)
         ) * individu('rpns_individu', period)
     return -bareme.calc(assiette)
Beispiel #27
0
 def formula_2014(individu, period, parameters):
     plafond_securite_sociale_annuel = parameters(
         period).cotsoc.gen.plafond_securite_sociale * 12
     vieillesse_artisan_commercant = parameters(
         period).prelevements_sociaux.ret_ac
     bareme = MarginalRateTaxScale(name='vieillesse')
     bareme.add_bracket(
         0, vieillesse_artisan_commercant.artisans.sous_pss +
         vieillesse_artisan_commercant.tous_independants.tout_salaire)
     bareme.add_bracket(
         1, vieillesse_artisan_commercant.tous_independants.tout_salaire)
     bareme.multiply_thresholds(plafond_securite_sociale_annuel)
     categorie_non_salarie = individu('categorie_non_salarie', period)
     assiette = (
         (categorie_non_salarie == TypesCategorieNonSalarie.artisan) +
         (categorie_non_salarie == TypesCategorieNonSalarie.commercant)
     ) * individu('rpns_individu', period)
     return -bareme.calc(assiette)
Beispiel #28
0
 def formula_2017(individu, period, parameters):
     plafond_securite_sociale_annuel = parameters(
         period).cotsoc.gen.plafond_securite_sociale * 12
     bareme = MarginalRateTaxScale(name='famille')
     bareme.add_bracket(0, 0)
     bareme.add_bracket(.7, .065)
     bareme.multiply_thresholds(plafond_securite_sociale_annuel)
     categorie_non_salarie = individu('categorie_non_salarie', period)
     assiette = (
         (categorie_non_salarie == TypesCategorieNonSalarie.artisan) +
         (categorie_non_salarie == TypesCategorieNonSalarie.commercant)
     ) * individu('rpns_individu', period)
     cotisation_sous_1_1_pss = assiette * (
         (assiette < .7 * plafond_securite_sociale_annuel) *
         ((.065 - .035) * assiette /
          (.7 * plafond_securite_sociale_annuel) +
          .035  # TODO check taux non nul à assiette quasi nulle
          ))
     return -(cotisation_sous_1_1_pss + bareme.calc(assiette))
Beispiel #29
0
 def formula_2013(individu, period, parameters):
     plafond_securite_sociale_annuel = parameters(
         period).cotsoc.gen.plafond_securite_sociale * 12
     retraite_complementaire = parameters(
         period
     ).prelevements_sociaux.ret_comp_ac.artisans_industriels_commercants
     montant_du_plafond_rci = retraite_complementaire.montant_du_plafond_rci
     bareme = MarginalRateTaxScale(name='retraite_complementaire')
     bareme.add_bracket(0, retraite_complementaire.sous_plafond_rci)
     bareme.add_bracket(
         montant_du_plafond_rci,
         retraite_complementaire.entre_1_plafond_rci_et_4_plafonds_pss)
     bareme.add_bracket(4 * plafond_securite_sociale_annuel, 0)
     categorie_non_salarie = individu('categorie_non_salarie', period)
     assiette = (
         (categorie_non_salarie == TypesCategorieNonSalarie.artisan) +
         (categorie_non_salarie == TypesCategorieNonSalarie.commercant)
     ) * individu('rpns_individu', period)
     return -bareme.calc(assiette)
def _rstbrut_from_rstnet(rstnet, csg_rempl, _defaultP):
    '''
    Calcule les pensions de retraites brutes à partir des pensions nettes
    '''
    P = _defaultP.csg.retraite
    plaf_ss = 12 * _defaultP.cotsoc.gen.plaf_ss
    csg = scale_tax_scales(TaxScalesTree('csg', P), plaf_ss)
    crds = scale_tax_scales(_defaultP.crds.rst, plaf_ss)
    taux_plein = combine_tax_scales(csg['plein'])
    taux_reduit = combine_tax_scales(csg['reduit'])
    taux_plein.add_tax_scale(crds)
    taux_reduit.add_tax_scale(crds)

    if hasattr(_defaultP.prelsoc, 'add_ret'):
        casa = MarginalRateTaxScale(name = "casa")
        casa.add_bracket(0, _defaultP.prelsoc.add_ret)
        taux_plein.add_tax_scale(casa)
        taux_reduit.add_tax_scale(casa)

    rst_plein = taux_plein.inverse()
    rst_reduit = taux_reduit.inverse()
    rstbrut = (csg_rempl == 2) * rst_reduit.calc(rstnet) + (csg_rempl == 3) * rst_plein.calc(rstnet)
    return rstbrut
 def formula_2018(individu, period, parameters):
     plafond_securite_sociale_annuel = parameters(period).cotsoc.gen.plafond_securite_sociale * 12
     bareme = MarginalRateTaxScale(name = 'famille')
     bareme.add_bracket(0, 0)
     bareme.add_bracket(1.1, .072)
     bareme.add_bracket(5, .065)
     bareme.multiply_thresholds(plafond_securite_sociale_annuel)
     categorie_non_salarie = individu('categorie_non_salarie', period)
     assiette = (
         (categorie_non_salarie == TypesCategorieNonSalarie.artisan)
         + (categorie_non_salarie == TypesCategorieNonSalarie.commercant)
         ) * individu('rpns_individu', period)
     cotisation_sous_1_1_pss = assiette * (
         (assiette > .4 * plafond_securite_sociale_annuel) * (assiette <= 1.1 * plafond_securite_sociale_annuel)
         * (
             (.072 - .022) * assiette / (1.1 * plafond_securite_sociale_annuel) + .022
             )
         + (assiette <= .4 * plafond_securite_sociale_annuel)
         * (
             (.022 - .085) * assiette / (0.4 * plafond_securite_sociale_annuel) + .085
             )
         )
     return - (cotisation_sous_1_1_pss + bareme.calc(assiette))
Beispiel #32
0
 def formula_2015(individu, period, parameters):
     plafond_securite_sociale_annuel = parameters(
         period).cotsoc.gen.plafond_securite_sociale * 12
     bareme = MarginalRateTaxScale(name='famille')
     bareme.add_bracket(0, 0)
     bareme.add_bracket(1.4, .031)  # TODO parsing des paramèters pas à jour
     bareme.multiply_thresholds(plafond_securite_sociale_annuel)
     categorie_non_salarie = individu('categorie_non_salarie', period)
     assiette = (
         (categorie_non_salarie == TypesCategorieNonSalarie.artisan) +
         (categorie_non_salarie == TypesCategorieNonSalarie.commercant) +
         (categorie_non_salarie
          == TypesCategorieNonSalarie.profession_liberale)) * individu(
              'rpns_individu', period)
     taux = (0 + (.031) *
             min_(max_(assiette / plafond_securite_sociale_annuel - 1.1, 0),
                  (1.4 - 1.1)) / (1.4 - 1.1))
     return -(taux * assiette *
              (assiette < 1.4 * plafond_securite_sociale_annuel) +
              bareme.calc(assiette))
Beispiel #33
0
    def _get_at_instant(self, instant):
        brackets = [
            bracket.get_at_instant(instant) for bracket in self.brackets
        ]

        if self.metadata.get('type') == 'single_amount':
            scale = SingleAmountTaxScale()
            for bracket in brackets:
                if 'amount' in bracket._children and 'threshold' in bracket._children:
                    amount = bracket.amount
                    threshold = bracket.threshold
                    scale.add_bracket(threshold, amount)
            return scale
        elif any('amount' in bracket._children for bracket in brackets):
            scale = MarginalAmountTaxScale()
            for bracket in brackets:
                if 'amount' in bracket._children and 'threshold' in bracket._children:
                    amount = bracket.amount
                    threshold = bracket.threshold
                    scale.add_bracket(threshold, amount)
            return scale
        elif any('average_rate' in bracket._children for bracket in brackets):
            scale = LinearAverageRateTaxScale()

            for bracket in brackets:
                if 'base' in bracket._children:
                    base = bracket.base
                else:
                    base = 1.
                if 'average_rate' in bracket._children and 'threshold' in bracket._children:
                    average_rate = bracket.average_rate
                    threshold = bracket.threshold
                    scale.add_bracket(threshold, average_rate * base)
            return scale
        else:
            scale = MarginalRateTaxScale()

            for bracket in brackets:
                if 'base' in bracket._children:
                    base = bracket.base
                else:
                    base = 1.
                if 'rate' in bracket._children and 'threshold' in bracket._children:
                    rate = bracket.rate
                    threshold = bracket.threshold
                    scale.add_bracket(threshold, rate * base)
            return scale
 def formula_2017(individu, period, parameters):
     plafond_securite_sociale_annuel = parameters(period).cotsoc.gen.plafond_securite_sociale * 12
     bareme = MarginalRateTaxScale(name = 'famille')
     bareme.add_bracket(0, 0)
     bareme.add_bracket(.7, .065)
     bareme.multiply_thresholds(plafond_securite_sociale_annuel)
     categorie_non_salarie = individu('categorie_non_salarie', period)
     assiette = (
         (categorie_non_salarie == TypesCategorieNonSalarie.artisan)
         + (categorie_non_salarie == TypesCategorieNonSalarie.commercant)
         ) * individu('rpns_individu', period)
     cotisation_sous_1_1_pss = assiette * (
         (assiette < .7 * plafond_securite_sociale_annuel)
         * (
             (.065 - .035) * assiette / (.7 * plafond_securite_sociale_annuel) + .035  # TODO check taux non nul à assiette quasi nulle
             )
         )
     return -(cotisation_sous_1_1_pss + bareme.calc(assiette))
def test_linear_average_rate_tax_scale():
    base = np.array([1, 1.5, 2, 2.5])

    marginal_tax_scale = MarginalRateTaxScale()
    marginal_tax_scale.add_bracket(0, 0)
    marginal_tax_scale.add_bracket(1, 0.1)
    marginal_tax_scale.add_bracket(2, 0.2)
    assert_near(marginal_tax_scale.calc(base), [0, .05, .1, .2], absolute_error_margin = 0)

    average_tax_scale = marginal_tax_scale.to_average()
    # Note: assert_near doesn't work for inf.
    # assert_near(average_tax_scale.thresholds, [0, 1, 2, np.inf], absolute_error_margin = 0)
    assert average_tax_scale.thresholds == [0, 1, 2, np.inf]
    assert_near(average_tax_scale.rates, [0, 0, 0.05, 0.2], absolute_error_margin = 0)
    assert_near(average_tax_scale.calc(base), [0, 0.0375, 0.1, 0.125], absolute_error_margin = 1e-10)

    new_marginal_tax_scale = average_tax_scale.to_marginal()
    assert_near(new_marginal_tax_scale.thresholds, marginal_tax_scale.thresholds, absolute_error_margin = 0)
    assert_near(new_marginal_tax_scale.rates, marginal_tax_scale.rates, absolute_error_margin = 0)
    assert_near(average_tax_scale.rates, [0, 0, 0.05, 0.2], absolute_error_margin = 0)
Beispiel #36
0
 def formula_2015(individu, period, parameters):
     plafond_securite_sociale_annuel = parameters(
         period).cotsoc.gen.plafond_securite_sociale * 12
     bareme = MarginalRateTaxScale(name='vieillesse')
     assurance_vieillesse = parameters(
         period).prelevements_sociaux.ret_pl.assurance_vieillesse
     bareme.add_bracket(0, assurance_vieillesse.sous_1_pss)
     bareme.add_bracket(1, assurance_vieillesse.entre_1_et_5_pss)
     bareme.add_bracket(5, 0)
     bareme.multiply_thresholds(plafond_securite_sociale_annuel)
     categorie_non_salarie = individu('categorie_non_salarie', period)
     assiette = (+(categorie_non_salarie == TypesCategorieNonSalarie.
                   profession_liberale)) * individu('rpns_individu', period)
     return -bareme.calc(assiette)
 def formula_2015(individu, period, parameters):
     plafond_securite_sociale_annuel = parameters(period).cotsoc.gen.plafond_securite_sociale * 12
     formation = parameters(period).prelevements_sociaux.formation_ac
     # Artisan
     bareme_artisan = MarginalRateTaxScale(name = 'formation_artisan')
     bareme_artisan.add_bracket(0, formation.artisans_sous_pss)
     bareme_artisan.add_bracket(1, 0)
     bareme_artisan.multiply_thresholds(plafond_securite_sociale_annuel)
     # Comemrcant
     bareme_commercant = MarginalRateTaxScale(name = 'formation_commercant')
     bareme_commercant.add_bracket(0, formation.commercants_industriels.sous_pss)
     bareme_commercant.add_bracket(1, 0)
     bareme_commercant.multiply_thresholds(plafond_securite_sociale_annuel)
     assiette = individu('rpns_individu', period)
     categorie_non_salarie = individu('categorie_non_salarie', period)
     artisan = (categorie_non_salarie == TypesCategorieNonSalarie.artisan)
     commercant = (categorie_non_salarie == TypesCategorieNonSalarie.commercant)
     return -bareme_artisan.calc(assiette * artisan) - bareme_commercant.calc(assiette * commercant)
def create_salaire_de_base(individus,
                           period=None,
                           revenu_type='imposable',
                           tax_benefit_system=None):
    """
    
    Calcule la variable salaire_de_base à partir du salaire imposable par inversion du barème
    de cotisations sociales correspondant à la catégorie à laquelle appartient le salarié.
    
    """
    assert period is not None
    assert revenu_type in ['net', 'imposable']
    for variable in [
            'categorie_salarie', 'contrat_de_travail',
            'heures_remunerees_volume'
    ]:
        assert variable in individus.columns, "{} is missing".format(variable)
    assert tax_benefit_system is not None

    if revenu_type == 'imposable':
        salaire_pour_inversion = individus.salaire_imposable
    else:
        salaire_pour_inversion = individus.salaire_net

    categorie_salarie = individus.categorie_salarie
    contrat_de_travail = individus.contrat_de_travail
    heures_remunerees_volume = individus.heures_remunerees_volume

    parameters = tax_benefit_system.get_parameters_at_instant(period.start)
    salarie = parameters.cotsoc.cotisations_salarie
    plafond_securite_sociale_mensuel = parameters.cotsoc.gen.plafond_securite_sociale
    parameters_csg_deductible = parameters.prelevements_sociaux.contributions.csg.activite.deductible
    taux_csg = parameters_csg_deductible.taux
    taux_abattement = parameters_csg_deductible.abattement.rates[0]
    try:
        seuil_abattement = parameters_csg_deductible.abattement.thresholds[1]
    except IndexError:  # Pour gérer le fait que l'abattement n'a pas toujours était limité à 4 PSS
        seuil_abattement = None
    csg_deductible = MarginalRateTaxScale(name='csg_deductible')
    csg_deductible.add_bracket(0, taux_csg * (1 - taux_abattement))
    if seuil_abattement is not None:
        csg_deductible.add_bracket(seuil_abattement, taux_csg)

    if revenu_type == 'net':  # On ajoute CSG imposable et crds

        parameters_csg_imposable = parameters.prelevements_sociaux.contributions.csg.activite.imposable
        taux_csg = parameters_csg_imposable.taux
        taux_abattement = parameters_csg_imposable.abattement.rates[0]
        try:
            seuil_abattement = parameters_csg_imposable.abattement.thresholds[
                1]
        except IndexError:  # Pour gérer le fait que l'abattement n'a pas toujours était limité à 4 PSS
            seuil_abattement = None
        csg_imposable = MarginalRateTaxScale(name='csg_imposable')
        csg_imposable.add_bracket(0, taux_csg * (1 - taux_abattement))
        if seuil_abattement is not None:
            csg_imposable.add_bracket(seuil_abattement, taux_csg)

        parameters_crds = parameters.prelevements_sociaux.contributions.crds.activite
        taux_csg = parameters_crds.taux
        taux_abattement = parameters_crds.abattement.rates[0]
        try:
            seuil_abattement = parameters_crds.abattement.thresholds[1]
        except IndexError:  # Pour gérer le fait que l'abattement n'a pas toujours était limité à 4 PSS
            seuil_abattement = None
        crds = MarginalRateTaxScale(name='crds')
        crds.add_bracket(0, taux_csg * (1 - taux_abattement))
        if seuil_abattement is not None:
            crds.add_bracket(seuil_abattement, taux_csg)

    # Check baremes
    target = dict()
    target['prive_non_cadre'] = set([
        'maladie', 'arrco', 'vieillesse_deplafonnee', 'vieillesse', 'agff',
        'assedic'
    ])
    target['prive_cadre'] = set([
        'maladie', 'arrco', 'vieillesse_deplafonnee', 'agirc', 'cet', 'apec',
        'vieillesse', 'agff', 'assedic'
    ])
    target['public_non_titulaire'] = set([
        'excep_solidarite', 'maladie', 'ircantec', 'vieillesse_deplafonnee',
        'vieillesse'
    ])

    for categorie in [
            'prive_non_cadre', 'prive_cadre', 'public_non_titulaire'
    ]:
        baremes_collection = salarie[categorie]
        baremes_to_remove = list()
        for name, bareme in baremes_collection._children.items():
            if name.endswith('alsace_moselle'):
                baremes_to_remove.append(name)
        for name in baremes_to_remove:
            del baremes_collection._children[name]

    for categorie in [
            'prive_non_cadre', 'prive_cadre', 'public_non_titulaire'
    ]:
        test = set(name
                   for name, bareme in salarie[categorie]._children.items()
                   if isinstance(bareme, MarginalRateTaxScale))
        assert target[categorie] == test, 'target: {} \n test {}'.format(
            target[categorie], test)
    del bareme

    # On ajoute la CSG deductible et on proratise par le plafond de la sécurité sociale
    # Pour éviter les divisions 0 /0 dans le switch qui sert à calculer le salaire_pour_inversion_proratise
    if period.unit == 'year':
        plafond_securite_sociale = plafond_securite_sociale_mensuel * 12
        heures_temps_plein = 52 * 35
    elif period.unit == 'month':
        plafond_securite_sociale = plafond_securite_sociale_mensuel * period.size
        heures_temps_plein = (52 * 35 / 12) * period.size
    else:
        raise

    heures_remunerees_volume_avoid_warning = heures_remunerees_volume + (
        heures_remunerees_volume == 0) * 1e9
    salaire_pour_inversion_proratise = switch(
        contrat_de_travail,
        {
            # temps plein
            0:
            salaire_pour_inversion / plafond_securite_sociale,
            # temps partiel
            1:
            salaire_pour_inversion /
            ((heures_remunerees_volume_avoid_warning / heures_temps_plein) *
             plafond_securite_sociale),
        })

    def add_agirc_gmp_to_agirc(agirc, parameters):
        plafond_securite_sociale_annuel = parameters.cotsoc.gen.plafond_securite_sociale * 12
        salaire_charniere = parameters.prelevements_sociaux.gmp.salaire_charniere_annuel / plafond_securite_sociale_annuel
        cotisation = parameters.prelevements_sociaux.gmp.cotisation_forfaitaire_mensuelle_en_euros.part_salariale * 12
        n = (cotisation + 1) * 12
        agirc.add_bracket(n / plafond_securite_sociale_annuel, 0)
        agirc.rates[0] = cotisation / n
        agirc.thresholds[2] = salaire_charniere

    salaire_de_base = 0.0
    for categorie in [
            'prive_non_cadre', 'prive_cadre', 'public_non_titulaire'
    ]:
        if categorie == 'prive_cadre':
            add_agirc_gmp_to_agirc(salarie[categorie].agirc, parameters)

        bareme = combine_tax_scales(salarie[categorie])
        bareme.add_tax_scale(csg_deductible)
        if revenu_type == 'net':
            bareme.add_tax_scale(csg_imposable)
            bareme.add_tax_scale(crds)

        assert bareme.inverse(
        ).thresholds[0] == 0, "Invalid inverse bareme for {}:\n {}".format(
            categorie, bareme.inverse())
        for rate in bareme.inverse(
        ).rates:  # Vérification que l'on peut inverser correctement
            assert rate > 0

        brut_proratise = bareme.inverse().calc(
            salaire_pour_inversion_proratise)
        assert np.isfinite(brut_proratise).all()
        brut = plafond_securite_sociale * switch(
            contrat_de_travail,
            {
                # temps plein
                0:
                brut_proratise,
                # temps partiel
                1:
                brut_proratise * (heures_remunerees_volume /
                                  (heures_temps_plein)),
            })
        salaire_de_base += (
            (categorie_salarie == TypesCategorieSalarie[categorie].index) *
            brut)

    individus['salaire_de_base'] = salaire_de_base

    if period.unit == 'year':
        year = period.start.year
        individus.loc[(individus.contrat_de_travail == 0) &
                      (individus.salaire_de_base > 0),
                      'salaire_de_base'] = np.maximum(
                          salaire_de_base,
                          smic_horaire_brut[year] * 35 * 52 / 12)
        individus.loc[(individus.contrat_de_travail == 1) &
                      (individus.salaire_de_base > 0),
                      'salaire_de_base'] = np.maximum(
                          salaire_de_base,
                          smic_horaire_brut[year] * heures_remunerees_volume)
def create_salaire_de_base(individus,
                           period=None,
                           revenu_type='imposable',
                           tax_and_benefit_system=None):
    """Calcule le salaire brut à partir du salaire imposable par inversion du barème
        de cotisations sociales correspondant à la catégorie à laquelle appartient le salarié.
        """
    assert period is not None
    assert revenu_type in ['net', 'imposable']
    for variable in [
            'categorie_salarie', 'contrat_de_travail',
            'heures_remunerees_volume'
    ]:
        assert variable in individus.columns
    assert tax_and_benefit_system is not None

    if revenu_type == 'imposable':
        salaire_pour_inversion = individus.salaire_imposable
    else:
        salaire_pour_inversion = individus.salaire_net

    categorie_salarie = individus.categorie_salarie
    contrat_de_travail = individus.contrat_de_travail
    heures_remunerees_volume = individus.heures_remunerees_volume
    # hsup = simulation.calculate('hsup', period = this_year)

    simulation = tax_and_benefit_system.new_scenario().init_single_entity(
        period=period, parent1=dict()).new_simulation()
    parameters = simulation.parameters_at(period.start)

    salarie = parameters.cotsoc.cotisations_salarie
    plafond_securite_sociale_mensuel = parameters.cotsoc.gen.plafond_securite_sociale
    parameters_csg_deductible = parameters.prelevements_sociaux.contributions.csg.activite.deductible
    taux_csg = parameters_csg_deductible.taux
    taux_abattement = parameters_csg_deductible.abattement.rates[0]
    try:
        seuil_abattement = parameters_csg_deductible.abattement.thresholds[1]
    except IndexError:  # Pour gérer le fait que l'abattement n'a pas toujours était limité à 4 PSS
        seuil_abattement = None
    csg_deductible = MarginalRateTaxScale(name='csg_deductible')
    csg_deductible.add_bracket(0, taux_csg * (1 - taux_abattement))
    if seuil_abattement is not None:
        csg_deductible.add_bracket(seuil_abattement, taux_csg)

    if revenu_type == 'net':  # On ajoute CSG imposable et crds
        # csg imposable
        parameters_csg_imposable = parameters.prelevements_sociaux.contributions.csg.activite.imposable
        taux_csg = parameters_csg_imposable.taux
        taux_abattement = parameters_csg_imposable.abattement.rates[0]
        try:
            seuil_abattement = parameters_csg_imposable.abattement.thresholds[
                1]
        except IndexError:  # Pour gérer le fait que l'abattement n'a pas toujours était limité à 4 PSS
            seuil_abattement = None
        csg_imposable = MarginalRateTaxScale(name='csg_imposable')
        csg_imposable.add_bracket(0, taux_csg * (1 - taux_abattement))
        if seuil_abattement is not None:
            csg_imposable.add_bracket(seuil_abattement, taux_csg)
        # crds
        # csg imposable
        parameters_crds = parameters.prelevements_sociaux.contributions.crds.activite
        taux_csg = parameters_crds.taux
        taux_abattement = parameters_crds.abattement.rates[0]
        try:
            seuil_abattement = parameters_crds.abattement.thresholds[1]
        except IndexError:  # Pour gérer le fait que l'abattement n'a pas toujours était limité à 4 PSS
            seuil_abattement = None
        crds = MarginalRateTaxScale(name='crds')
        crds.add_bracket(0, taux_csg * (1 - taux_abattement))
        if seuil_abattement is not None:
            crds.add_bracket(seuil_abattement, taux_csg)

    # Check baremes
    target = dict()
    target['prive_non_cadre'] = set([
        'maladie', 'arrco', 'vieillesse_deplafonnee', 'vieillesse', 'agff',
        'assedic'
    ])
    target['prive_cadre'] = set([
        'maladie', 'arrco', 'vieillesse_deplafonnee', 'agirc', 'cet', 'apec',
        'vieillesse', 'agff', 'assedic'
    ])

    for categorie in ['prive_non_cadre', 'prive_cadre']:
        baremes_collection = salarie[categorie]
        baremes_to_remove = list()
        for name, bareme in baremes_collection._children.iteritems():
            if name.endswith('alsace_moselle'):
                baremes_to_remove.append(name)
        for name in baremes_to_remove:
            del baremes_collection._children[name]

    for categorie in ['prive_non_cadre', 'prive_cadre']:
        test = set(
            name for name, bareme in salarie[categorie]._children.iteritems()
            if isinstance(bareme, MarginalRateTaxScale))
        assert target[categorie] == test, 'target: {} \n test {}'.format(
            target[categorie], test)
    del bareme
    # On ajoute la CSG deductible et on proratise par le plafond de la sécurité sociale
    # Pour éviter les divisions 0 /0 dans le switch
    if period.unit == 'year':
        plafond_securite_sociale = plafond_securite_sociale_mensuel * 12
        heures_temps_plein = 52 * 35
    elif period.unit == 'month':
        plafond_securite_sociale = plafond_securite_sociale_mensuel * period.size
        heures_temps_plein = (52 * 35 / 12) * period.size

    else:
        raise
    heures_remunerees_volume_avoid_warning = heures_remunerees_volume + (
        heures_remunerees_volume == 0) * 1e9
    salaire_pour_inversion_proratise = switch(
        contrat_de_travail,
        {
            # temps plein
            0:
            salaire_pour_inversion / plafond_securite_sociale,
            # temps partiel
            1:
            salaire_pour_inversion /
            ((heures_remunerees_volume_avoid_warning / heures_temps_plein) *
             plafond_securite_sociale),
        })
    salaire_de_base = 0.0
    for categorie in ['prive_non_cadre', 'prive_cadre']:
        bareme = combine_tax_scales(salarie[categorie])
        bareme.add_tax_scale(csg_deductible)
        if revenu_type == 'net':
            bareme.add_tax_scale(csg_imposable)
            bareme.add_tax_scale(crds)

        brut_proratise = bareme.inverse().calc(
            salaire_pour_inversion_proratise)
        assert np.isfinite(brut_proratise).all()
        brut = plafond_securite_sociale * switch(
            contrat_de_travail,
            {
                # temps plein
                0:
                brut_proratise,
                # temps partiel
                1:
                brut_proratise * (heures_remunerees_volume /
                                  (heures_temps_plein)),
            })
        salaire_de_base += (
            (categorie_salarie == CATEGORIE_SALARIE[categorie]) * brut)
        assert (salaire_de_base >= 0).all()
        assert (salaire_de_base < 1e9).all()

    # agirc_gmp
    # gmp = P.prelevements_sociaux.gmp
    # salaire_charniere = gmp.salaire_charniere_annuel
    # cotisation_forfaitaire = gmp.cotisation_forfaitaire_mensuelle_en_euros.part_salariale * 12
    # salaire_de_base += (
    #     (categorie_salarie == CATEGORIE_SALARIE['prive_cadre']) *
    #     (salaire_de_base <= salaire_charniere) *
    #     cotisation_forfaitaire
    #     )
    individus['salaire_de_base'] = salaire_de_base
def _salbrut_from_sali(sali, hsup, type_sal, _defaultP):
    '''
    Calcule le salaire brut à partir du salaire imposable
    sauf pour les fonctionnaires où il renvoie le tratement indiciaire brut
    Note : le supplément familial de traitement est imposable
    '''
    plaf_ss = 12 * _defaultP.cotsoc.gen.plaf_ss

    salarie = scale_tax_scales(TaxScalesTree('sal', _defaultP.cotsoc.sal), plaf_ss)
    csg = scale_tax_scales(TaxScalesTree('csg', _defaultP.csg), plaf_ss)

    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 = combine_tax_scales(salarie['noncadre'])
    cadre = combine_tax_scales(salarie['cadre'])

    # On ajoute la CSG deductible
    noncadre.add_tax_scale(csg['act']['deduc'])
    cadre.add_tax_scale(csg['act']['deduc'])

    nca = noncadre.inverse()
    cad = cadre.inverse()
    brut_nca = nca.calc(sali)
    brut_cad = cad.calc(sali)
    salbrut = brut_nca * (type_sal == CAT['prive_non_cadre'])
    salbrut += brut_cad * (type_sal == CAT['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 = combine_tax_scales(salarie['fonc']["colloc"]) 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 'sali', sali / 12
    brut_etat = etat.calc(sali)
    # print 'brut_etat', brut_etat/12
    # print 'impot', public_etat.calc(brut_etat) / 12
    # print 'brut_etat', brut_etat / 12
    salbrut_etat = (brut_etat)
    # TODO: fonctionnaire
    # print 'salbrut_etat', salbrut_etat / 12
    salbrut += salbrut_etat * (type_sal == CAT['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 salbrut + hsup
    def formula(individu, period, parameters):
        """Calcule le salaire brut à partir du salaire imposable par inversion du barème
        de cotisations sociales correspondant à la catégorie à laquelle appartient le salarié.
        """
        # Get value for year and divide below.
        this_year = period.this_year
        salaire_imposable_pour_inversion = individu('salaire_imposable_pour_inversion',
            period = this_year)

        # Calcule le salaire brut (salaire de base) à partir du salaire imposable.

        categorie_salarie = individu('categorie_salarie', period = this_year)
        contrat_de_travail = individu('contrat_de_travail', period = this_year)
        heures_remunerees_volume = individu('heures_remunerees_volume', period = this_year)
        hsup = individu('hsup', period = this_year)

        P = parameters(period)

        salarie = P.cotsoc.cotisations_salarie
        plafond_securite_sociale_annuel = P.cotsoc.gen.plafond_securite_sociale * 12
        csg_deductible = parameters(period).prelevements_sociaux.contributions.csg.activite.deductible
        taux_csg = csg_deductible.taux
        taux_abattement = csg_deductible.abattement.rates[0]
        try:
            seuil_abattement = csg_deductible.abattement.thresholds[1]
        except IndexError:  # Pour gérer le fait que l'abattement n'a pas toujours était limité à 4 PSS
            seuil_abattement = None
        csg = MarginalRateTaxScale(name = 'csg')
        csg.add_bracket(0, taux_csg * (1 - taux_abattement))
        if seuil_abattement is not None:
            csg.add_bracket(seuil_abattement, taux_csg)

        target = dict()
        target['prive_non_cadre'] = set(['maladie', 'arrco', 'vieillesse_deplafonnee', 'vieillesse', 'agff', 'assedic'])
        target['prive_cadre'] = set(
            ['maladie', 'arrco', 'vieillesse_deplafonnee', 'agirc', 'cet', 'apec', 'vieillesse', 'agff', 'assedic']
            )

        for categorie in ['prive_non_cadre', 'prive_cadre']:
            baremes_collection = salarie[categorie]
            baremes_to_remove = list()
            for name, bareme in baremes_collection.iteritems():
                if name.endswith('alsace_moselle'):
                    baremes_to_remove.append(name)
            for name in baremes_to_remove:
                del baremes_collection[name]

        for categorie in ['prive_non_cadre', 'prive_cadre']:
            test = set(
                name for name, bareme in salarie[categorie].iteritems()
                if isinstance(bareme, MarginalRateTaxScale)
                )
            assert target[categorie] == test, 'target: {} \n test {}'.format(target[categorie], test)
        del bareme
        # On ajoute la CSG deductible et on proratise par le plafond de la sécurité sociale
        # Pour éviter les divisions 0 /0 dans le switch
        heures_remunerees_volume_avoid_warning = heures_remunerees_volume + (heures_remunerees_volume == 0) * 1e9
        salaire_imposable_proratise = switch(
            contrat_de_travail,
            {
                # temps plein
                0: salaire_imposable_pour_inversion / plafond_securite_sociale_annuel,
                # temps partiel
                1: salaire_imposable_pour_inversion / (
                    (heures_remunerees_volume_avoid_warning / (52 * 35)) * plafond_securite_sociale_annuel
                    ),
                }
            )
        salaire_de_base = 0.0
        for categorie in ['prive_non_cadre', 'prive_cadre']:
            bareme = combine_tax_scales(salarie[categorie])
            bareme.add_tax_scale(csg)
            brut_proratise = bareme.inverse().calc(salaire_imposable_proratise)
            assert np.isfinite(brut_proratise).all()
            brut = plafond_securite_sociale_annuel * switch(
                contrat_de_travail,
                {
                    # temps plein
                    0: brut_proratise,
                    # temps partiel
                    1: brut_proratise * (heures_remunerees_volume / (52 * 35)),
                    }
                )
            salaire_de_base += (
                (categorie_salarie == CATEGORIE_SALARIE[categorie]) * brut
                )
            assert (salaire_de_base > -1e9).all()
            assert (salaire_de_base < 1e9).all()
        # agirc_gmp
        # gmp = P.prelevements_sociaux.gmp
        # salaire_charniere = gmp.salaire_charniere_annuel
        # cotisation_forfaitaire = gmp.cotisation_forfaitaire_mensuelle_en_euros.part_salariale * 12
        # salaire_de_base += (
        #     (categorie_salarie == CATEGORIE_SALARIE['prive_cadre']) *
        #     (salaire_de_base <= salaire_charniere) *
        #     cotisation_forfaitaire
        #     )
        return salaire_de_base + hsup
    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.start.offset('first-of', 'month').period('month')

        sali = simulation.get_array('sali', period)
        if sali is None:
            salnet = simulation.get_array('salnet', period)
            if salnet is not None:
                # Calcule le salaire brut à partir du salaire net par inversion numérique.
                if (salnet == 0).all():
                    # Quick path to avoid fsolve when using default value of input variables.
                    return period, salnet
                simulation = self.holder.entity.simulation
                function = lambda salbrut: brut_to_net(
                    output_name = 'salnet',
                    period = period,
                    salbrut = salbrut,
                    simulation = simulation,
                    ) - salnet
                return period, fsolve(function, salnet)

            sali = simulation.calculate('sali', period)

        # 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)

        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(sali)
        brut_cad = cad.calc(sali)
        salbrut = brut_nca * (type_sal == CAT['prive_non_cadre'])
        salbrut += brut_cad * (type_sal == CAT['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 'sali', sali
        brut_etat = etat.calc(sali)
        # 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 * (type_sal == CAT['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
        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
def create_traitement_indiciaire_brut(individus,
                                      period=None,
                                      revenu_type='imposable',
                                      tax_benefit_system=None):
    """
    Calcule le tratement indiciaire brut à partir du salaire imposable ou du salaire net.
    Note : le supplément familial de traitement est imposable. Pas géré
    """
    assert period is not None
    assert revenu_type in ['net', 'imposable']
    assert tax_benefit_system is not None

    for variable in [
            'categorie_salarie', 'contrat_de_travail',
            'heures_remunerees_volume'
    ]:
        assert variable in individus.columns

    if revenu_type == 'imposable':
        assert 'salaire_imposable' in individus.columns
        salaire_pour_inversion = individus.salaire_imposable
    else:
        assert 'salaire_net' in individus.columns
        salaire_pour_inversion = individus.salaire_net

    categorie_salarie = individus.categorie_salarie
    contrat_de_travail = individus.contrat_de_travail
    heures_remunerees_volume = individus.heures_remunerees_volume

    legislation = tax_benefit_system.get_parameters_at_instant(period.start)

    salarie = legislation.cotsoc.cotisations_salarie
    plafond_securite_sociale_mensuel = legislation.cotsoc.gen.plafond_securite_sociale
    legislation_csg_deductible = legislation.prelevements_sociaux.contributions.csg.activite.deductible
    taux_csg = legislation_csg_deductible.taux
    taux_abattement = legislation_csg_deductible.abattement.rates[0]
    try:
        seuil_abattement = legislation_csg_deductible.abattement.thresholds[1]
    except IndexError:  # Pour gérer le fait que l'abattement n'a pas toujours été limité à 4 PSS
        seuil_abattement = None
    csg_deductible = MarginalRateTaxScale(name='csg_deductible')
    csg_deductible.add_bracket(0, taux_csg * (1 - taux_abattement))
    if seuil_abattement is not None:
        csg_deductible.add_bracket(seuil_abattement, taux_csg)

    if revenu_type == 'net':
        # Cas des revenus nets:
        # comme les salariés du privé, on ajoute CSG imposable et crds qui s'appliquent à tous les revenus
        # 1. csg imposable
        legislation_csg_imposable = legislation.prelevements_sociaux.contributions.csg.activite.imposable
        taux_csg = legislation_csg_imposable.taux
        taux_abattement = legislation_csg_imposable.abattement.rates[0]
        try:
            seuil_abattement = legislation_csg_imposable.abattement.thresholds[
                1]
        except IndexError:  # Pour gérer le fait que l'abattement n'a pas toujours été limité à 4 PSS
            seuil_abattement = None
        csg_imposable = MarginalRateTaxScale(name='csg_imposable')
        csg_imposable.add_bracket(0, taux_csg * (1 - taux_abattement))
        if seuil_abattement is not None:
            csg_imposable.add_bracket(seuil_abattement, taux_csg)
        # 2. crds
        legislation_crds = legislation.prelevements_sociaux.contributions.crds.activite
        taux_csg = legislation_crds.taux
        taux_abattement = legislation_crds.abattement.rates[0]
        try:
            seuil_abattement = legislation_crds.abattement.thresholds[1]
        except IndexError:  # Pour gérer le fait que l'abattement n'a pas toujours été limité à 4 PSS
            seuil_abattement = None
        crds = MarginalRateTaxScale(name='crds')
        crds.add_bracket(0, taux_csg * (1 - taux_abattement))
        if seuil_abattement is not None:
            crds.add_bracket(seuil_abattement, taux_csg)

    # Check baremes
    target = dict()
    target['public_titulaire_etat'] = set(
        ['excep_solidarite', 'pension', 'rafp'])
    target['public_titulaire_hospitaliere'] = set(
        ['excep_solidarite', 'cnracl1', 'rafp'])
    target['public_titulaire_territoriale'] = set(
        ['excep_solidarite', 'cnracl1', 'rafp'])

    categories_salarie_du_public = [
        'public_titulaire_etat',
        'public_titulaire_hospitaliere',
        'public_titulaire_territoriale',
    ]

    for categorie in categories_salarie_du_public:
        baremes_collection = salarie[categorie]
        test = set(
            name for name, bareme in salarie[categorie]._children.items()
            if isinstance(bareme, MarginalRateTaxScale) and name != 'cnracl2')
        assert target[
            categorie] == test, 'target for {}: \n  target = {} \n  test = {}'.format(
                categorie, target[categorie], test)

    # Barèmes à éliminer :
    # cnracl1 = taux hors NBI -> OK
    # cnracl2 = taux NBI -> On ne le prend pas en compte pour l'instant
    for categorie in [
            'public_titulaire_hospitaliere',
            'public_titulaire_territoriale',
    ]:
        baremes_collection = salarie[categorie]
        baremes_to_remove = list()
        baremes_to_remove.append('cnracl2')
        for name in baremes_to_remove:
            if 'cnracl2' in baremes_collection:
                del baremes_collection._children[name]

    salarie = salarie._children.copy()
    # RAFP des agents titulaires
    for categorie in categories_salarie_du_public:
        baremes_collection = salarie[categorie]
        baremes_collection['rafp'].multiply_rates(TAUX_DE_PRIME, inplace=True)

    # On ajoute la CSG déductible et on proratise par le plafond de la sécurité sociale
    if period.unit == 'year':
        plafond_securite_sociale = plafond_securite_sociale_mensuel * 12
        heures_temps_plein = 52 * 35
    elif period.unit == 'month':
        plafond_securite_sociale = plafond_securite_sociale_mensuel * period.size
        heures_temps_plein = (52 * 35 / 12) * period.size
    else:
        raise

    # Pour a fonction publique la csg est calculée sur l'ensemble salbrut(=TIB) + primes
    # Imposable = (1 + taux_prime) * TIB - csg[(1 + taux_prime) * TIB] - pension[TIB]
    for categorie in categories_salarie_du_public:
        bareme_csg_deduc_public = csg_deductible.multiply_rates(
            1 + TAUX_DE_PRIME, inplace=False, new_name="csg deduc public")
        if revenu_type == 'net':
            bareme_csg_imp_public = csg_imposable.multiply_rates(
                1 + TAUX_DE_PRIME,
                inplace=False,
                new_name="csg imposable public")
            bareme_crds_public = crds.multiply_rates(1 + TAUX_DE_PRIME,
                                                     inplace=False,
                                                     new_name="crds public")

    for categorie in categories_salarie_du_public:
        bareme_prime = MarginalRateTaxScale(name="taux de prime")
        bareme_prime.add_bracket(
            0, -TAUX_DE_PRIME)  # barème équivalent à taux_prime*TIB

    heures_remunerees_volume_avoid_warning = heures_remunerees_volume + (
        heures_remunerees_volume == 0) * 1e9
    salaire_pour_inversion_proratise = switch(
        contrat_de_travail,
        {
            # temps plein
            0:
            salaire_pour_inversion / plafond_securite_sociale,
            # temps partiel
            1:
            salaire_pour_inversion /
            ((heures_remunerees_volume_avoid_warning / heures_temps_plein) *
             plafond_securite_sociale),
        })

    traitement_indiciaire_brut = 0.0

    for categorie in categories_salarie_du_public:
        for key, value in salarie[categorie]._children.items():
            log.debug(key, value)
        bareme = combine_tax_scales(salarie[categorie])
        log.debug('bareme cotsoc : {}'.format(bareme))
        bareme.add_tax_scale(bareme_csg_deduc_public)
        log.debug('bareme cotsoc + csg_deduc: {}'.format(bareme))
        if revenu_type == 'net':
            bareme.add_tax_scale(bareme_csg_imp_public)
            log.debug('bareme cotsoc + csg_deduc + csg_imp: {}'.format(bareme))
            bareme.add_tax_scale(bareme_crds_public)
            log.debug('bareme cotsoc + csg_deduc + csg_imp + crds: {}'.format(
                bareme))

        bareme.add_tax_scale(bareme_prime)
        log.debug(
            'bareme cotsoc + csg_deduc + csg_imp + crds + prime: {}'.format(
                bareme))

        brut_proratise = bareme.inverse().calc(
            salaire_pour_inversion_proratise)

        assert np.isfinite(brut_proratise).all()
        brut = plafond_securite_sociale * switch(
            contrat_de_travail,
            {
                # temps plein
                0:
                brut_proratise,
                # temps partiel
                1:
                brut_proratise * (heures_remunerees_volume /
                                  (heures_temps_plein)),
            })
        traitement_indiciaire_brut += (
            (categorie_salarie == TypesCategorieSalarie[categorie].index) *
            brut)
        if (categorie_salarie == TypesCategorieSalarie[categorie].index).any():
            log.debug("Pour {} : brut = {}".format(
                TypesCategorieSalarie[categorie].index, brut))
            log.debug('bareme direct: {}'.format(bareme))

    individus['traitement_indiciaire_brut'] = traitement_indiciaire_brut
    individus[
        'primes_fonction_publique'] = TAUX_DE_PRIME * traitement_indiciaire_brut
Beispiel #45
0
    def formula(self, simulation, period):
        """Calcule le salaire brut à partir du salaire imposable par inversion du barème
        de cotisations sociales correspondant à la catégorie à laquelle appartient le salarié.
        """
        # Get value for year and divide below.
        this_year = period.this_year
        salaire_imposable_pour_inversion = simulation.calculate('salaire_imposable_pour_inversion',
            period = this_year)

        # Calcule le salaire brut (salaire de base) à partir du salaire imposable.

        categorie_salarie = simulation.calculate('categorie_salarie', period = this_year)
        contrat_de_travail = simulation.calculate('contrat_de_travail', period = this_year)
        heures_remunerees_volume = simulation.calculate('heures_remunerees_volume', period = this_year)
        hsup = simulation.calculate('hsup', period = this_year)

        P = simulation.parameters_at(period.start)

        salarie = P.cotsoc.cotisations_salarie
        plafond_securite_sociale_annuel = P.cotsoc.gen.plafond_securite_sociale * 12
        csg_deductible = simulation.parameters_at(period.start).prelevements_sociaux.contributions.csg.activite.deductible
        taux_csg = csg_deductible.taux
        taux_abattement = csg_deductible.abattement.rates[0]
        try:
            seuil_abattement = csg_deductible.abattement.thresholds[1]
        except IndexError:  # Pour gérer le fait que l'abattement n'a pas toujours était limité à 4 PSS
            seuil_abattement = None
        csg = MarginalRateTaxScale(name = 'csg')
        csg.add_bracket(0, taux_csg * (1 - taux_abattement))
        if seuil_abattement is not None:
            csg.add_bracket(seuil_abattement, taux_csg)

        target = dict()
        target['prive_non_cadre'] = set(['maladie', 'arrco', 'vieillesse_deplafonnee', 'vieillesse', 'agff', 'assedic'])
        target['prive_cadre'] = set(
            ['maladie', 'arrco', 'vieillesse_deplafonnee', 'agirc', 'cet', 'apec', 'vieillesse', 'agff', 'assedic']
            )

        for categorie in ['prive_non_cadre', 'prive_cadre']:
            baremes_collection = salarie[categorie]
            baremes_to_remove = list()
            for name, bareme in baremes_collection.iteritems():
                if name.endswith('alsace_moselle'):
                    baremes_to_remove.append(name)
            for name in baremes_to_remove:
                del baremes_collection[name]

        for categorie in ['prive_non_cadre', 'prive_cadre']:
            test = set(
                name for name, bareme in salarie[categorie].iteritems()
                if isinstance(bareme, MarginalRateTaxScale)
                )
            assert target[categorie] == test, 'target: {} \n test {}'.format(target[categorie], test)
        del bareme
        # On ajoute la CSG deductible et on proratise par le plafond de la sécurité sociale
        # Pour éviter les divisions 0 /0 dans le switch
        heures_remunerees_volume_avoid_warning = heures_remunerees_volume + (heures_remunerees_volume == 0) * 1e9
        salaire_imposable_proratise = switch(
            contrat_de_travail,
            {
                # temps plein
                0: salaire_imposable_pour_inversion / plafond_securite_sociale_annuel,
                # temps partiel
                1: salaire_imposable_pour_inversion / (
                    (heures_remunerees_volume_avoid_warning / (52 * 35)) * plafond_securite_sociale_annuel
                    ),
                }
            )
        salaire_de_base = 0.0
        for categorie in ['prive_non_cadre', 'prive_cadre']:
            bareme = combine_tax_scales(salarie[categorie])
            bareme.add_tax_scale(csg)
            brut_proratise = bareme.inverse().calc(salaire_imposable_proratise)
            assert np.isfinite(brut_proratise).all()
            brut = plafond_securite_sociale_annuel * switch(
                contrat_de_travail,
                {
                    # temps plein
                    0: brut_proratise,
                    # temps partiel
                    1: brut_proratise * (heures_remunerees_volume / (52 * 35)),
                    }
                )
            salaire_de_base += (
                (categorie_salarie == CATEGORIE_SALARIE[categorie]) * brut
                )
            assert (salaire_de_base > -1e9).all()
            assert (salaire_de_base < 1e9).all()
        # agirc_gmp
        # gmp = P.prelevements_sociaux.gmp
        # salaire_charniere = gmp.salaire_charniere_annuel
        # cotisation_forfaitaire = gmp.cotisation_forfaitaire_mensuelle_en_euros.part_salariale * 12
        # salaire_de_base += (
        #     (categorie_salarie == CATEGORIE_SALARIE['prive_cadre']) *
        #     (salaire_de_base <= salaire_charniere) *
        #     cotisation_forfaitaire
        #     )
        return salaire_de_base + hsup
Beispiel #46
0
def test_inverse_scaled_marginal_tax_scale():
    marginal_tax_scale = MarginalRateTaxScale()
    marginal_tax_scale.add_bracket(0, 0)
    marginal_tax_scale.add_bracket(1, 0.1)
    marginal_tax_scale.add_bracket(3, 0.05)

    brut = np.array([1, 2, 3, 4, 5, 6])
    net = brut - marginal_tax_scale.calc(brut)
    inverse = marginal_tax_scale.inverse()
    assert_near(brut, inverse.calc(net), 1e-15)

    brut = np.array([1, 2, 3, 4, 5, 6])
    brut_scale = 12.345
    brut_scaled = brut * brut_scale
    scaled_marginal_tax_scale = marginal_tax_scale.scale_tax_scales(brut_scale)
    net_scaled = (brut_scaled - scaled_marginal_tax_scale.calc(brut_scaled))
    scaled_inverse = scaled_marginal_tax_scale.inverse()
    assert_near(brut_scaled, scaled_inverse.calc(net_scaled), 1e-13)

    inverse = marginal_tax_scale.inverse()
    inversed_net = inverse.calc(net)
    net_scale = brut_scale
    inversed_net_scaled = inversed_net * net_scale
    assert_near(brut_scaled, inversed_net_scaled, 1e-13)
Beispiel #47
0
 def formula_2015(individu, period, parameters):
     plafond_securite_sociale_annuel = parameters(
         period).cotsoc.gen.plafond_securite_sociale * 12
     formation = parameters(period).prelevements_sociaux.formation_ac
     # Artisan
     bareme_artisan = MarginalRateTaxScale(name='formation_artisan')
     bareme_artisan.add_bracket(0, formation.artisans_sous_pss)
     bareme_artisan.add_bracket(1, 0)
     bareme_artisan.multiply_thresholds(plafond_securite_sociale_annuel)
     # Comemrcant
     bareme_commercant = MarginalRateTaxScale(name='formation_commercant')
     bareme_commercant.add_bracket(
         0, formation.commercants_industriels.sous_pss)
     bareme_commercant.add_bracket(1, 0)
     bareme_commercant.multiply_thresholds(plafond_securite_sociale_annuel)
     assiette = individu('rpns_individu', period)
     categorie_non_salarie = individu('categorie_non_salarie', period)
     artisan = (categorie_non_salarie == TypesCategorieNonSalarie.artisan)
     commercant = (
         categorie_non_salarie == TypesCategorieNonSalarie.commercant)
     return -bareme_artisan.calc(
         assiette * artisan) - bareme_commercant.calc(assiette * commercant)
    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.start.offset('first-of', 'month').period('month')

        sali = simulation.get_array('sali', period)
        if sali is None:
            salnet = simulation.get_array('salnet', period)
            if salnet is not None:
                # Calcule le salaire brut à partir du salaire net par inversion numérique.
                if (salnet == 0).all():
                    # Quick path to avoid fsolve when using default value of input variables.
                    return period, salnet
                simulation = self.holder.entity.simulation
                function = lambda salbrut: brut_to_net(
                    output_name='salnet',
                    period=period,
                    salbrut=salbrut,
                    simulation=simulation,
                ) - salnet
                return period, fsolve(function, salnet)

            sali = simulation.calculate('sali', period)

        # 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)

        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(sali)
        brut_cad = cad.calc(sali)
        salbrut = brut_nca * (type_sal == CAT['prive_non_cadre'])
        salbrut += brut_cad * (type_sal == CAT['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 'sali', sali
        brut_etat = etat.calc(sali)
        # 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 * (type_sal == CAT['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
Beispiel #49
0
 def formula_2018(individu, period, parameters):
     plafond_securite_sociale_annuel = parameters(
         period).cotsoc.gen.plafond_securite_sociale * 12
     bareme = MarginalRateTaxScale(name='famille')
     bareme.add_bracket(0, 0)
     bareme.add_bracket(1.1, .072)
     bareme.add_bracket(5, .065)
     bareme.multiply_thresholds(plafond_securite_sociale_annuel)
     categorie_non_salarie = individu('categorie_non_salarie', period)
     assiette = (
         (categorie_non_salarie == TypesCategorieNonSalarie.artisan) +
         (categorie_non_salarie == TypesCategorieNonSalarie.commercant)
     ) * individu('rpns_individu', period)
     cotisation_sous_1_1_pss = assiette * (
         (assiette > .4 * plafond_securite_sociale_annuel) *
         (assiette <= 1.1 * plafond_securite_sociale_annuel) *
         ((.072 - .022) * assiette /
          (1.1 * plafond_securite_sociale_annuel) + .022) +
         (assiette <= .4 * plafond_securite_sociale_annuel) *
         ((.022 - .085) * assiette /
          (0.4 * plafond_securite_sociale_annuel) + .085))
     return -(cotisation_sous_1_1_pss + bareme.calc(assiette))