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 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 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) )
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 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
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 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 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_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): 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 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(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
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)
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_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_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): """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
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_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 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)
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)
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))
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) marginal_tax_scale.add_bracket(4, 0) net = brut - marginal_tax_scale.calc(brut) inverse = marginal_tax_scale.inverse() assert_near(brut, inverse.calc(net), 1e-15)
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 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 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 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_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 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 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 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))
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))
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)
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 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
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 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_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 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 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 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