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