def build_reform(tax_benefit_system): Reform = reforms.make_reform( key = 'plf2015', name = u'Projet de Loi de Finances 2015', reference = tax_benefit_system, ) @Reform.formula class decote(formulas.SimpleFormulaColumn): label = u"Nouvelle décote 2015" reference = ir.decote def function(self, simulation, period): period = period.start.offset('first-of', 'year').period('year') ir_plaf_qf = simulation.calculate('ir_plaf_qf', period) nb_adult = simulation.calculate('nb_adult', period) plf = simulation.legislation_at(period.start).plf2015 decote_celib = (ir_plaf_qf < plf.decote_seuil_celib) * (plf.decote_seuil_celib - ir_plaf_qf) decote_couple = (ir_plaf_qf < plf.decote_seuil_couple) * (plf.decote_seuil_couple - ir_plaf_qf) return period, (nb_adult == 1) * decote_celib + (nb_adult == 2) * decote_couple reform = Reform() reform.modify_legislation_json(modifier_function = modify_legislation_json) return reform
def test_check(): for employee_type, test_parameters in test_case_by_employee_type.iteritems(): Reform = reforms.make_reform( key = u'smic_h_b_9_euros', name = u"Réforme pour simulation ACOSS SMIC horaire brut fixe à 9 euros", reference = tax_benefit_system, ) reform = Reform() reform.modify_legislation_json(modifier_function = modify_legislation_json) simulation_period = 2011 parent1 = dict( birth = datetime.date(periods.period(simulation_period).start.year - 40, 1, 1), ) parent1.update(test_parameters['input_variables']) simulation = reform.new_scenario().init_single_entity( period = simulation_period, parent1 = parent1, ).new_simulation(debug = True) for variable, amounts in test_parameters['output_variables'].iteritems(): if isinstance(amounts, dict): for period_str, amount in sorted(amounts.iteritems()): output = simulation.calculate_add_divide(variable, period = periods.period(period_str)) variable_message = "{} at {}".format(variable, period_str) yield assert_variable, variable_message, employee_type, amount, output else: output = simulation.calculate(variable) variable_message = variable amount = amounts yield assert_variable, variable_message, employee_type, amount, output
def test_check(): Reform = reforms.make_reform( key=u'smic_h_b_9_euros', name=u"Réforme pour simulation ACOSS SMIC horaire brut fixe à 9 euros", reference=tax_benefit_system, ) reform = Reform() reform.modify_legislation_json(modifier_function=modify_legislation_json) for employee_type, test_parameters in test_case_by_employee_type.iteritems( ): simulation_period = 2013 parent1 = dict(date_naissance=datetime.date( periods.period(simulation_period).start.year - 40, 1, 1), ) parent1.update(test_parameters['input_variables']) simulation = reform.new_scenario().init_single_entity( period=simulation_period, parent1=parent1, ).new_simulation() for variable, amounts in test_parameters['output_variables'].iteritems( ): if isinstance(amounts, dict): for period_str, amount in sorted(amounts.iteritems()): output = simulation.calculate_add_divide( variable, period=periods.period(period_str)) variable_message = "{} at {}".format(variable, period_str) yield assert_variable, variable_message, employee_type, amount, output else: output = simulation.calculate(variable) variable_message = variable amount = amounts yield assert_variable, variable_message, employee_type, amount, output
def build_reform(tax_benefit_system): Reform = reforms.make_reform( key = 'plf2016', name = u'Projet de Loi de Finances 2016 appliquée aux revenus 2014', reference = tax_benefit_system, ) class decote(Reform.DatedVariable): label = u"Décote IR 2016 appliquée en 2015 sur revenus 2014" reference = ir.decote @dated_function(start = date(2014, 1, 1), stop = date(2014, 12, 31)) def function_2014(self, simulation, period): period = period.start.offset('first-of', 'year').period('year') ir_plaf_qf = simulation.calculate('ir_plaf_qf', period) nb_adult = simulation.calculate('nb_adult', period) plf = simulation.legislation_at(period.start).plf2016 decote_celib = (ir_plaf_qf < plf.decote_seuil_celib) * (plf.decote_seuil_celib - .75 * ir_plaf_qf) decote_couple = (ir_plaf_qf < plf.decote_seuil_couple) * (plf.decote_seuil_couple - .75 * ir_plaf_qf) return period, (nb_adult == 1) * decote_celib + (nb_adult == 2) * decote_couple reform = Reform() reform.modify_legislation_json(modifier_function = modify_legislation_json) return reform
def build_reform(tax_benefit_system): Reform = reforms.make_reform( name = u'Inversion des revenus', new_formulas = (chobrut, rstbrut, salbrut), reference = tax_benefit_system, ) return Reform()
def build_counterfactual_reform(tax_benefit_system): Reform = reforms.make_reform( key='plf2016_counterfactual', name=u'Contrefactuel du PLF 2016 sur les revenus 2015', reference=tax_benefit_system, ) class decote(Reform.DatedVariable): label = u"Décote IR 2015 appliquée sur revenus 2015 (contrefactuel)" reference = ir.decote @dated_function(start=date(2015, 1, 1)) def function_2015__(self, simulation, period): period = period.start.offset('first-of', 'year').period('year') ir_plaf_qf = simulation.calculate('ir_plaf_qf', period) nb_adult = simulation.calculate('nb_adult', period) plf2016 = simulation.legislation_at( period.start).plf2016_conterfactual decote_seuil_celib = plf2016.decote_seuil_celib decote_seuil_couple = plf2016.decote_seuil_couple decote_celib = (ir_plaf_qf < decote_seuil_celib) * ( decote_seuil_celib - ir_plaf_qf) decote_couple = (ir_plaf_qf < decote_seuil_couple) * ( decote_seuil_couple - ir_plaf_qf) return period, (nb_adult == 1) * decote_celib + ( nb_adult == 2) * decote_couple reform = Reform() reform.modify_legislation_json( modifier_function=counterfactual_modify_legislation_json) return reform
def build_counterfactual_reform(tax_benefit_system): Reform = reforms.make_reform( key = 'plf2016_counterfactual', name = u'Contrefactuel du PLF 2016 sur les revenus 2015', reference = tax_benefit_system, ) class decote(Reform.DatedVariable): label = u"Décote IR 2015 appliquée sur revenus 2015 (contrefactuel)" reference = ir.decote @dated_function(start = date(2015, 1, 1)) def function_2015__(self, simulation, period): period = period.start.offset('first-of', 'year').period('year') ir_plaf_qf = simulation.calculate('ir_plaf_qf', period) nb_adult = simulation.calculate('nb_adult', period) plf2016 = simulation.legislation_at(period.start).plf2016_conterfactual decote_seuil_celib = plf2016.decote_seuil_celib decote_seuil_couple = plf2016.decote_seuil_couple decote_celib = (ir_plaf_qf < decote_seuil_celib) * (decote_seuil_celib - ir_plaf_qf) decote_couple = (ir_plaf_qf < decote_seuil_couple) * (decote_seuil_couple - ir_plaf_qf) return period, (nb_adult == 1) * decote_celib + (nb_adult == 2) * decote_couple reform = Reform() reform.modify_legislation_json(modifier_function = counterfactual_modify_legislation_json) return reform
def build_reform(tax_benefit_system): reference_legislation_json = tax_benefit_system.legislation_json reform_legislation_json = copy.deepcopy(reference_legislation_json) reform_year = 2014 reform_period = periods.period('year', reform_year) reform_legislation_json = reforms.update_legislation( legislation_json = reform_legislation_json, path = ('children', 'ir', 'children', 'bareme', 'brackets', 1, 'rate'), period = reform_period, value = 0, ) reform_legislation_json = reforms.update_legislation( legislation_json = reform_legislation_json, path = ('children', 'ir', 'children', 'bareme', 'brackets', 2, 'threshold'), period = reform_period, value = 9690, ) reform_legislation_json['children'].update(reform_legislation_subtree) Reform = reforms.make_reform( legislation_json = reform_legislation_json, name = u'PLF2015', new_formulas = (decote, ), reference = tax_benefit_system, ) return Reform()
def build_reform(tax_benefit_system): Reform = reforms.make_reform( key='plf2015', name=u'Projet de Loi de Finances 2015 appliquée aux revenus 2013', reference=tax_benefit_system, ) class decote(Reform.DatedVariable): label = u"Décote IR 2015 appliquée sur IR 2014 (revenus 2013)" reference = ir.decote @dated_function(start=date(2013, 1, 1), stop=date(2013, 12, 31)) def function_2013(self, simulation, period): period = period.this_year ir_plaf_qf = simulation.calculate('ir_plaf_qf', period) nb_adult = simulation.calculate('nb_adult', period) plf = simulation.legislation_at(period.start).plf2015 decote_celib = (ir_plaf_qf < plf.seuil_celib) * (plf.seuil_celib - ir_plaf_qf) decote_couple = (ir_plaf_qf < plf.seuil_couple) * ( plf.seuil_couple - ir_plaf_qf) return period, (nb_adult == 1) * decote_celib + ( nb_adult == 2) * decote_couple reform = Reform() reform.modify_legislation_json(modifier_function=modify_legislation_json) return reform
def build_reform(tax_benefit_system): Reform = reforms.make_reform( name = u'Réforme 1', reference = tax_benefit_system, ) @Reform.formula class cmu_base_ressources(formulas.SimpleFormulaColumn): reference = cmu.cmu_base_ressources def function(self, simulation, period): self.reference period = period.start.offset('first-of', 'month').period('month') previous_year = period.start.period('year').offset(-1) aspa = simulation.calculate('aspa', period) ass = simulation.calculate('ass', period) asi = simulation.calculate('asi', period) af = simulation.calculate('af', period) cf = simulation.calculate_divide('cf', period) asf = simulation.calculate_divide('asf', period) paje_clca = simulation.calculate_add('paje_clca', previous_year) paje_prepare = simulation.calculate_add('paje_prepare', previous_year) statut_occupation_holder = simulation.compute('statut_occupation', period) aide_logement = simulation.calculate('aide_logement', period) cmu_forfait_logement_base = simulation.calculate('cmu_forfait_logement_base', period) cmu_forfait_logement_al = simulation.calculate('cmu_forfait_logement_al', period) age_holder = simulation.compute('age', period) cmu_base_ressources_i_holder = simulation.compute('cmu_base_ressources_i', period) P = simulation.legislation_at(period.start).cmu statut_occupation = self.cast_from_entity_to_roles(statut_occupation_holder) statut_occupation = self.filter_role(statut_occupation, role = CHEF) cmu_br_i_par = self.split_by_roles(cmu_base_ressources_i_holder, roles = [CHEF, PART]) cmu_br_i_pac = self.split_by_roles(cmu_base_ressources_i_holder, roles = ENFS) age_pac = self.split_by_roles(age_holder, roles = ENFS) forfait_logement = (((statut_occupation == 2) + (statut_occupation == 6)) * cmu_forfait_logement_base + (aide_logement > 0) * min_(cmu_forfait_logement_al, aide_logement * 12)) res = cmu_br_i_par[CHEF] + cmu_br_i_par[PART] + forfait_logement # Prestations calculées, donc valeurs mensuelles. On estime l'annuel en multipliant par 12 res += 12 * (aspa + ass + asi + af + cf + asf) res += paje_clca + paje_prepare for key, age in age_pac.iteritems(): res += (0 <= age) * (age <= P.age_limite_pac) * cmu_br_i_pac[key] return period, res return Reform()
def build_reform(tax_benefit_system): reference_legislation_json = tax_benefit_system.legislation_json reform_legislation_json = copy.deepcopy(reference_legislation_json) reform_legislation_json['children'].update(reform_legislation_subtree) Reform = reforms.make_reform( legislation_json = reform_legislation_json, name = u"Contribution execptionnelle sur les très hauts revenus d'activité (invalidée par le CC)", new_formulas = (cesthra, irpp), reference = tax_benefit_system, ) return Reform()
def build_reform(tax_benefit_system): # reference_legislation_json = tax_benefit_system.legislation_json # reform_legislation_json = copy.deepcopy(reference_legislation_json) # reform_legislation_json['children'].update(reform_legislation_subtree) Reform = reforms.make_reform( # legislation_json = reform_legislation_json, name=u'Pas de réduction d impôt ', new_formulas=[iaidrdi], reference=tax_benefit_system, ) return Reform()
def build_reform(tax_benefit_system): reference_legislation_json = tax_benefit_system.legislation_json reform_legislation_json = copy.deepcopy(reference_legislation_json) reform_legislation_json['children'].update(reform_legislation_subtree) Reform = reforms.make_reform( legislation_json = reform_legislation_json, name = u'Allocations familiales imposables', new_formulas = (rbg, rfr, allocations_familiales_imposables), reference = tax_benefit_system, ) return Reform()
def build_reform(tax_benefit_system): reference_legislation_json = tax_benefit_system.legislation_json reform_legislation_json = copy.deepcopy(reference_legislation_json) reform_legislation_json['children'].update(reform_legislation_subtree) Reform = reforms.make_reform( legislation_json = reform_legislation_json, name = u'PLFR 2014', new_formulas = (reduction_impot_exceptionnelle, reductions), reference = tax_benefit_system, ) return Reform()
def build_reform(tax_benefit_system): # reference_legislation_json = tax_benefit_system.legislation_json # reform_legislation_json = copy.deepcopy(reference_legislation_json) # reform_legislation_json['children'].update(reform_legislation_subtree) Reform = reforms.make_reform( # legislation_json = reform_legislation_json, name = u'Pas de charge deductible', new_formulas = (rng,), reference = tax_benefit_system, ) return Reform()
def build_reform(tax_benefit_system): Reform = reforms.make_reform( key='cesthra_invalidee', name= u"Contribution execptionnelle sur les très hauts revenus d'activité (invalidée par le CC)", reference=tax_benefit_system, ) class cesthra(Reform.Variable): column = columns.FloatCol entity_class = entities.FoyersFiscaux label = u"Contribution exceptionnelle de solidarité sur les très hauts revenus d'activité" # PLF 2013 (rejeté) : 'taxe à 75%' def function(self, simulation, period): period = period.this_year salaire_imposable_holder = simulation.calculate( "salaire_imposable", period) law_cesthra = simulation.legislation_at(period.start).cesthra salaire_imposable = self.split_by_roles(salaire_imposable_holder) cesthra = 0 for rev in salaire_imposable.itervalues(): cesthra += max_(rev - law_cesthra.seuil, 0) * law_cesthra.taux return period, cesthra class irpp(Reform.Variable): label = u"Impôt sur le revenu des personnes physiques (réformée pour intégrer la cesthra)" reference = ir.irpp def function(self, simulation, period): ''' Montant après seuil de recouvrement (hors ppe) ''' period = period.this_year iai = simulation.calculate('iai', period) credits_impot = simulation.calculate('credits_impot', period) cehr = simulation.calculate('cehr', period) cesthra = simulation.calculate('cesthra', period=period) P = simulation.legislation_at(period.start).ir.recouvrement pre_result = iai - credits_impot + cehr + cesthra return period, ((iai > P.seuil) * ((pre_result < P.min) * (pre_result > 0) * iai * 0 + ((pre_result <= 0) + (pre_result >= P.min)) * (-pre_result)) + (iai <= P.seuil) * ((pre_result < 0) * (-pre_result) + (pre_result >= 0) * 0 * iai)) reform = Reform() reform.modify_legislation_json(modifier_function=modify_legislation_json) return reform
def build_reform(tax_benefit_system): # reference_legislation_json = tax_benefit_system.legislation_json # reform_legislation_json = copy.deepcopy(reference_legislation_json) # reform_legislation_json['children'].update(reform_legislation_subtree) Reform = reforms.make_reform( # legislation_json = reform_legislation_json, name=u'Revenu imposable + 10', new_formulas=[rni], reference=tax_benefit_system, ) return Reform()
def build_reform(tax_benefit_system): reference_legislation_json = tax_benefit_system.legislation_json reform_legislation_json = copy.deepcopy(reference_legislation_json) reform_legislation_json['children'].update(reform_legislation_subtree) Reform = reforms.make_reform( legislation_json = reform_legislation_json, name = u'Loyer comme charge déductible (Trannoy-Wasmer)', new_formulas = (charges_deduc, charge_loyer), reference = tax_benefit_system, ) return Reform()
def build_reform(tax_benefit_system): # reference_legislation_json = tax_benefit_system.legislation_json # reform_legislation_json = copy.deepcopy(reference_legislation_json) # reform_legislation_json['children'].update(reform_legislation_subtree) Reform = reforms.make_reform( # legislation_json = reform_legislation_json, name = u'Pas de réduction d impôt ', new_formulas = [iaidrdi], reference = tax_benefit_system, ) return Reform()
def build_reform(tax_benefit_system): # reference_legislation_json = tax_benefit_system.legislation_json # reform_legislation_json = copy.deepcopy(reference_legislation_json) # reform_legislation_json['children'].update(reform_legislation_subtree) Reform = reforms.make_reform( # legislation_json = reform_legislation_json, name=u'Pas de charge deductible', new_formulas=(rng, ), reference=tax_benefit_system, ) return Reform()
def build_reform(tax_benefit_system): Reform = reforms.make_reform( key='de_net_a_brut', name=u'Inversion du calcul brut -> net', reference=tax_benefit_system, ) class salaire_de_base(Reform.Variable): column = columns.FloatCol entity_class = entities.Individus label = u"Salaire brut ou traitement indiciaire brut" reference = tax_benefit_system.column_by_name["salaire_de_base"] url = u"http://www.trader-finance.fr/lexique-finance/definition-lettre-S/Salaire-brut.html" def function(self, simulation, period): # Calcule le salaire brut à partir du salaire net par inversion numérique. net = simulation.get_array('salaire_net_a_payer', period) assert net is not None simulation = self.holder.entity.simulation # List of variables already calculated. We will need it to remove their holders, # that might contain undesired cache requested_variable_names = simulation.requested_periods_by_variable_name.keys( ) if requested_variable_names: requested_variable_names.remove(u'salaire_de_base') # Clean 'requested_periods_by_variable_name', that is used by -core to check for computation cycles. # This variable, salaire_de_base, might have been called from variable X, # that will be calculated again in our iterations to compute the salaire_net requested # as an input variable, hence producing a cycle error simulation.requested_periods_by_variable_name = dict() def solve_func(net): def innerfunc(essai): return calculate_net_from(essai, simulation, period, requested_variable_names) - net return innerfunc brut_calcule = \ fsolve( solve_func(net), net*1.5, # on entend souvent parler cette méthode... xtol = 1/10 # précision ) return period, brut_calcule return Reform()
def build_reform(tax_benefit_system): reference_legislation_json = tax_benefit_system.legislation_json reform_legislation_json = copy.deepcopy(reference_legislation_json) reform_year = 2007 reform_period = periods.period('year', reform_year) def update_threshold_bracket(bracket, amount): return reforms.update_legislation( legislation_json = reform_legislation_json, path = ('children', 'ir', 'children', 'bareme', 'brackets', bracket, 'threshold'), period = reform_period, value = amount, ) def update_rate_bracket(bracket, rate): return reforms.update_legislation( legislation_json = reform_legislation_json, path = ('children', 'ir', 'children', 'bareme', 'brackets', bracket, 'rate'), period = reform_period, value = rate, ) reform_legislation_json = update_rate_bracket(bracket = 0, rate = 0) reform_legislation_json = update_rate_bracket(bracket = 1, rate = .0683) reform_legislation_json = update_rate_bracket(bracket = 2, rate = .1914) reform_legislation_json = update_rate_bracket(bracket = 3, rate = .2826) reform_legislation_json = update_rate_bracket(bracket = 4, rate = .3738) reform_legislation_json = update_rate_bracket(bracket = 5, rate = .4262) reform_legislation_json = update_rate_bracket(bracket = 6, rate = .4809) inflation = 1 reform_legislation_json = update_threshold_bracket(bracket = 0, amount = 0) reform_legislation_json = update_threshold_bracket(bracket = 1, amount = 4412 * inflation) reform_legislation_json = update_threshold_bracket(bracket = 2, amount = 8677 * inflation) reform_legislation_json = update_threshold_bracket(bracket = 3, amount = 15274 * inflation) reform_legislation_json = update_threshold_bracket(bracket = 4, amount = 24731 * inflation) reform_legislation_json = update_threshold_bracket(bracket = 5, amount = 40241 * inflation) reform_legislation_json = update_threshold_bracket(bracket = 6, amount = 49624 * inflation) reform_legislation_json = reforms.update_legislation( legislation_json = reform_legislation_json, path = ('children', 'ir', 'children', 'tspr', 'children', 'sabatsalpen'), period = reform_period, value = 0, ) Reform = reforms.make_reform( legislation_json = reform_legislation_json, name = u'ir_2006', new_formulas = (), reference = tax_benefit_system, ) return Reform()
def build_reform(tax_benefit_system): Reform = reforms.make_reform( key = 'cesthra_invalidee', name = u"Contribution execptionnelle sur les très hauts revenus d'activité (invalidée par le CC)", reference = tax_benefit_system, ) @Reform.formula class cesthra(formulas.SimpleFormulaColumn): column = columns.FloatCol entity_class = entities.FoyersFiscaux label = u"Contribution exceptionnelle de solidarité sur les très hauts revenus d'activité" # PLF 2013 (rejeté) : 'taxe à 75%' def function(self, simulation, period): period = period.start.offset('first-of', 'year').period('year') salaire_imposable_holder = simulation.calculate("salaire_imposable", period) law_cesthra = simulation.legislation_at(period.start).cesthra salaire_imposable = self.split_by_roles(salaire_imposable_holder) cesthra = 0 for rev in salaire_imposable.itervalues(): cesthra += max_(rev - law_cesthra.seuil, 0) * law_cesthra.taux return period, cesthra @Reform.formula class irpp(formulas.SimpleFormulaColumn): label = u"Impôt sur le revenu des personnes physiques (réformée pour intégrer la cesthra)" reference = ir.irpp def function(self, simulation, period): ''' Montant après seuil de recouvrement (hors ppe) ''' period = period.start.offset('first-of', 'year').period('year') iai = simulation.calculate('iai', period) credits_impot = simulation.calculate('credits_impot', period) cehr = simulation.calculate('cehr', period) cesthra = simulation.calculate('cesthra', period = period) P = simulation.legislation_at(period.start).ir.recouvrement pre_result = iai - credits_impot + cehr + cesthra return period, ((iai > P.seuil) * ((pre_result < P.min) * (pre_result > 0) * iai * 0 + ((pre_result <= 0) + (pre_result >= P.min)) * (- pre_result)) + (iai <= P.seuil) * ((pre_result < 0) * (-pre_result) + (pre_result >= 0) * 0 * iai)) reform = Reform() reform.modify_legislation_json(modifier_function = modify_legislation_json) return reform
def build_reform(tax_benefit_system): # Removing the formula starting in 2015-07-01 # TODO: improve because very dirty # may be by creating the following functions # get_formulas(entity, variable, period), set_formulas(entity, variable, period) Reform = reforms.make_reform( key = 'plafond_qf_enfant_unlimited', name = u"Legislion du plafond qf de 2012 et des af sans modulations", reference = tax_benefit_system, ) reform = Reform() reform.modify_legislation_json(modifier_function = modify_legislation_json) return reform
def build_reform(tax_benefit_system): Reform = reforms.make_reform( key = 'de_net_a_brut', name = u'Inversion du calcul brut -> net', reference = tax_benefit_system, ) class salaire_de_base(Reform.Variable): column = columns.FloatCol entity_class = entities.Individus label = u"Salaire brut ou traitement indiciaire brut" reference = tax_benefit_system.column_by_name["salaire_de_base"] url = u"http://www.trader-finance.fr/lexique-finance/definition-lettre-S/Salaire-brut.html" def function(self, simulation, period): # Calcule le salaire brut à partir du salaire net par inversion numérique. net = simulation.get_array('salaire_net_a_payer', period) assert net is not None simulation = self.holder.entity.simulation # List of variables already calculated. We will need it to remove their holders, # that might contain undesired cache requested_variable_names = simulation.requested_periods_by_variable_name.keys() if requested_variable_names: requested_variable_names.remove(u'salaire_de_base') # Clean 'requested_periods_by_variable_name', that is used by -core to check for computation cycles. # This variable, salaire_de_base, might have been called from variable X, # that will be calculated again in our iterations to compute the salaire_net requested # as an input variable, hence producing a cycle error simulation.requested_periods_by_variable_name = dict() def solve_func(net): def innerfunc(essai): return calculate_net_from(essai, simulation, period, requested_variable_names) - net return innerfunc brut_calcule = \ fsolve( solve_func(net), net*1.5, # on entend souvent parler cette méthode... xtol = 1/10 # précision ) return period, brut_calcule return Reform()
def create_simulation(year = 2014, bareme = False): simulation_period = periods.period('year', year) reference_legislation_json = tax_benefit_system.legislation_json reform_legislation_json = reforms.update_legislation( legislation_json = reference_legislation_json, path = ('children', 'ir', 'children', 'bareme', 'slices', 0, 'rate'), period = simulation_period, value = 1, ) Reform = reforms.make_reform( name = u"Imposition à 100% dès le premier euro et jusqu'à la fin de la 1ère tranche", legislation_json = reform_legislation_json, reference = tax_benefit_system ) reform = Reform() parent1 = dict( birth = datetime.date(year - 40, 1, 1), salaire_de_base = 10000 if bareme is False else None, type_sal = 0, ) # parent2 = dict( # birth = datetime.date(year - 40, 1, 1), # salaire_de_base = 0, # ) # Adding a husband/wife on the same tax sheet (foyer) menage = dict( loyer = 1000, statut_occupation = 4, ) axes = [ dict( count = 200, name = 'salaire_de_base', max = 300000, min = 0, ), ] scenario = reform.new_scenario().init_single_entity( axes = axes if bareme else None, menage = menage, parent1 = parent1, # parent2 = parent2, period = periods.period('year', year), ) reference_simulation = scenario.new_simulation(debug = True, reference = True) reform_simulation = scenario.new_simulation(debug = True) return reform_simulation, reference_simulation
def build_reform(tax_benefit_system): Reform = reforms.make_reform( key = 'trannoy_wasmer', name = u'Loyer comme charge déductible (Trannoy-Wasmer)', reference = tax_benefit_system, ) @Reform.formula class charges_deduc(formulas.SimpleFormulaColumn): label = u"Charge déductibles intégrant la charge pour loyer (Trannoy-Wasmer)" reference = charges_deductibles.charges_deduc def function(self, simulation, period): period = period.start.offset('first-of', 'year').period('year') cd1 = simulation.calculate('cd1', period) cd2 = simulation.calculate('cd2', period) charge_loyer = simulation.calculate('charge_loyer', period) return period, cd1 + cd2 + charge_loyer @Reform.formula class charge_loyer(formulas.SimpleFormulaColumn): column = columns.FloatCol entity_class = entities.FoyersFiscaux label = u"Charge déductible pour paiement d'un loyer" def function(self, simulation, period): period = period.start.offset('first-of', 'year').period('year') loyer_holder = simulation.calculate('loyer', period) nbptr = simulation.calculate('nbptr', period) loyer = self.cast_from_entity_to_role(loyer_holder, entity = "menage", role = PREF) loyer = self.sum_by_entity(loyer) charge_loyer = simulation.legislation_at(period.start).charge_loyer plaf = charge_loyer.plaf plaf_nbp = charge_loyer.plaf_nbp plafond = plaf * (not_(plaf_nbp) + plaf * nbptr * plaf_nbp) return period, 12 * min_(loyer / 12, plafond) reform = Reform() reform.modify_legislation_json(modifier_function = modify_legislation_json) return reform
def build_reform(tax_benefit_system): Reform = reforms.make_reform( key='trannoy_wasmer', name=u'Loyer comme charge déductible (Trannoy-Wasmer)', reference=tax_benefit_system, ) class charges_deduc(Reform.Variable): label = u"Charge déductibles intégrant la charge pour loyer (Trannoy-Wasmer)" reference = charges_deductibles.charges_deduc def function(self, simulation, period): period = period.this_year cd1 = simulation.calculate('cd1', period) cd2 = simulation.calculate('cd2', period) charge_loyer = simulation.calculate('charge_loyer', period) return period, cd1 + cd2 + charge_loyer class charge_loyer(Reform.Variable): column = columns.FloatCol entity_class = entities.FoyersFiscaux label = u"Charge déductible pour paiement d'un loyer" def function(self, simulation, period): period = period.this_year loyer_holder = simulation.calculate('loyer', period) nbptr = simulation.calculate('nbptr', period) loyer = self.cast_from_entity_to_role(loyer_holder, entity="menage", role=PREF) loyer = self.sum_by_entity(loyer) charge_loyer = simulation.legislation_at(period.start).charge_loyer plaf = charge_loyer.plaf plaf_nbp = charge_loyer.plaf_nbp plafond = plaf * (not_(plaf_nbp) + plaf * nbptr * plaf_nbp) return period, 12 * min_(loyer / 12, plafond) reform = Reform() reform.modify_legislation_json(modifier_function=modify_legislation_json) return reform
def test_parametric_reform(): def modify_legislation_json(reference_legislation_json_copy): # FIXME update_legislation is deprecated. reform_legislation_json = reforms.update_legislation( legislation_json = reference_legislation_json_copy, path = ('children', 'ir', 'children', 'bareme', 'brackets', 0, 'rate'), period = simulation_period, value = 1, ) return reform_legislation_json simulation_year = 2013 simulation_period = periods.period('year', simulation_year) Reform = reforms.make_reform( key = 'ir_100_tranche_1', name = u"Imposition à 100% dès le premier euro et jusqu'à la fin de la 1ère tranche", reference = tax_benefit_system, ) reform = Reform() reform.modify_legislation_json(modifier_function = modify_legislation_json) scenario = reform.new_scenario().init_single_entity( axes = [ dict( count = 3, name = 'salaire_imposable', max = 100000, min = 0, ), ], period = simulation_period, parent1 = dict(date_naissance = datetime.date(simulation_year - 40, 1, 1)), ) reference_simulation = scenario.new_simulation(reference = True) assert_near(reference_simulation.calculate('impo'), [0, -7889.20019531, -23435.52929688], absolute_error_margin = .01) reform_simulation = scenario.new_simulation() assert_near(reform_simulation.calculate('impo'), [0, -13900.20019531, -29446.52929688], absolute_error_margin = .0001)
def build_reform(tax_benefit_system): Reform = reforms.make_reform( key="alimentation", name=u"Réforme de l'imposition indirecte des biens alimentaires", reference=tax_benefit_system, ) class charges_deduc(Reform.Variable): label = u"Charge déductibles intégrant la charge pour loyer (Trannoy-Wasmer)" reference = charges_deductibles.charges_deduc def function(self, simulation, period): period = period.this_year cd1 = simulation.calculate("cd1", period) cd2 = simulation.calculate("cd2", period) charge_loyer = simulation.calculate("charge_loyer", period) return period, cd1 + cd2 + charge_loyer class charge_loyer(Reform.Variable): column = columns.FloatCol entity_class = entities.FoyersFiscaux label = u"Charge déductible pour paiement d'un loyer" def function(self, simulation, period): period = period.this_year loyer_holder = simulation.calculate("loyer", period) nbptr = simulation.calculate("nbptr", period) loyer = self.cast_from_entity_to_role(loyer_holder, entity="menage", role=PREF) loyer = self.sum_by_entity(loyer) charge_loyer = simulation.legislation_at(period.start).charge_loyer plaf = charge_loyer.plaf plaf_nbp = charge_loyer.plaf_nbp plafond = plaf * (not_(plaf_nbp) + plaf * nbptr * plaf_nbp) return period, 12 * min_(loyer / 12, plafond) reform = Reform() reform.modify_legislation_json(modifier_function=modify_legislation_json) return reform
def test_parametric_reform(): simulation_year = 2013 simulation_period = periods.period('year', simulation_year) reference_legislation_json = tax_benefit_system.legislation_json reform_legislation_json = reforms.update_legislation( legislation_json = reference_legislation_json, path = ('children', 'ir', 'children', 'bareme', 'brackets', 0, 'rate'), period = simulation_period, value = 1, ) Reform = reforms.make_reform( legislation_json = reform_legislation_json, # name = u'IR_100_tranche_1', name = u"Imposition à 100% dès le premier euro et jusqu'à la fin de la 1ère tranche", reference = tax_benefit_system, ) reform = Reform() scenario = reform.new_scenario().init_single_entity( axes = [ dict( count = 3, name = 'sal', max = 100000, min = 0, ), ], period = simulation_period, parent1 = dict(birth = datetime.date(simulation_year - 40, 1, 1)), ) reference_simulation = scenario.new_simulation(debug = True, reference = True) assert_near(reference_simulation.calculate('impo'), [0, -7889.20019531, -23435.52929688], error_margin = .01) reform_simulation = scenario.new_simulation(debug = True) assert_near(reform_simulation.calculate('impo'), [0, -13900.20019531, -29446.52929688], error_margin = .0001)
def build_counterfactual_2014_reform(tax_benefit_system): Reform = reforms.make_reform( key = 'plf2016_counterfactual_2014', name = u'Contrefactuel 2014 du PLF 2016 sur les revenus 2015', reference = tax_benefit_system, ) class decote(Reform.DatedVariable): reference = ir.decote @dated_function(start = date(2015, 1, 1)) def function_2015(self, simulation, period): period = period.start.offset('first-of', 'year').period('year') ir_plaf_qf = simulation.calculate('ir_plaf_qf', period) inflator = 1 + .001 + .005 decote = simulation.legislation_at(period.start).ir.decote assert decote.seuil == 1016 return period, (ir_plaf_qf < decote.seuil * inflator) * (decote.seuil * inflator - ir_plaf_qf) * 0.5 class reduction_impot_exceptionnelle(Reform.DatedVariable): reference = reductions_impot.reduction_impot_exceptionnelle @dated_function(start = date(2015, 1, 1), stop = date(2015, 12, 31)) def function_2015(self, simulation, period): period = period.start.offset('first-of', 'year').period('year') nb_adult = simulation.calculate('nb_adult') nb_parents = simulation.calculate('nb_parents') rfr = simulation.calculate('rfr') inflator = 1 + .001 + .005 # params = simulation.legislation_at(period.start).ir.reductions_impots.reduction_impot_exceptionnelle seuil = 13795 * inflator majoration_seuil = 3536 * inflator montant_plafond = 350 * inflator plafond = seuil * nb_adult + (nb_parents - nb_adult) * 2 * majoration_seuil montant = montant_plafond * nb_adult return period, min_(max_(plafond + montant - rfr, 0), montant) class reductions(Reform.DatedVariable): label = u"Somme des réductions d'impôt" reference = reductions_impot.reductions @dated_function(start = date(2013, 1, 1), stop = date(2015, 12, 31)) def function_20130101_20131231(self, simulation, period): period = period.start.offset('first-of', 'year').period('year') accult = simulation.calculate('accult') adhcga = simulation.calculate('adhcga') cappme = simulation.calculate('cappme') creaen = simulation.calculate('creaen') daepad = simulation.calculate('daepad') deffor = simulation.calculate('deffor') dfppce = simulation.calculate('dfppce') doment = simulation.calculate('doment') domlog = simulation.calculate('domlog') donapd = simulation.calculate('donapd') duflot = simulation.calculate('duflot') ecpess = simulation.calculate('ecpess') garext = simulation.calculate('garext') intagr = simulation.calculate('intagr') invfor = simulation.calculate('invfor') invlst = simulation.calculate('invlst') ip_net = simulation.calculate('ip_net') locmeu = simulation.calculate('locmeu') mecena = simulation.calculate('mecena') mohist = simulation.calculate('mohist') patnat = simulation.calculate('patnat') prcomp = simulation.calculate('prcomp') reduction_impot_exceptionnelle = simulation.calculate('reduction_impot_exceptionnelle') repsoc = simulation.calculate('repsoc') resimm = simulation.calculate('resimm') rsceha = simulation.calculate('rsceha') saldom = simulation.calculate('saldom') scelli = simulation.calculate('scelli') sofica = simulation.calculate('sofica') spfcpi = simulation.calculate('spfcpi') total_reductions = accult + adhcga + cappme + creaen + daepad + deffor + dfppce + doment + domlog + \ donapd + duflot + ecpess + garext + intagr + invfor + invlst + locmeu + mecena + mohist + patnat + \ prcomp + repsoc + resimm + rsceha + saldom + scelli + sofica + spfcpi + reduction_impot_exceptionnelle return period, min_(ip_net, total_reductions) reform = Reform() reform.modify_legislation_json(modifier_function = counterfactual_2014_modify_legislation_json) return reform
def build_reform(base_tax_benefit_system): Reform = reforms.make_reform( reference=base_tax_benefit_system, key='landais_piketty_saez', name=u'Landais Piketty Saez', ) class assiette_csg(Reform.Variable): column = columns.FloatCol entity_class = entities.Individus label = u"Assiette de la CSG" def function(self, simulation, period): period = period.start.offset('first-of', 'month').period('year') salaire_de_base = simulation.calculate('salaire_de_base', period) chomage_brut = simulation.calculate('chomage_brut', period) retraite_brute = simulation.calculate('retraite_brute', period) rev_cap_bar_holder = simulation.compute_add('rev_cap_bar', period) rev_cap_lib_holder = simulation.compute_add('rev_cap_lib', period) rev_cap_bar = self.cast_from_entity_to_role(rev_cap_bar_holder, role=QUIFOY['vous']) rev_cap_lib = self.cast_from_entity_to_role(rev_cap_lib_holder, role=QUIFOY['vous']) return period, salaire_de_base + chomage_brut + retraite_brute + rev_cap_bar + rev_cap_lib class impot_revenu_lps(Reform.Variable): column = columns.FloatCol entity_class = entities.Individus label = u"Impôt individuel sur l'ensemble de l'assiette de la csg, comme proposé par Landais, Piketty et Saez" def function(self, simulation, period): period = period.start.offset('first-of', 'month').period('year') nbF_holder = simulation.compute('nbF') nbF = self.cast_from_entity_to_role(nbF_holder, role=QUIFOY['vous']) nbH_holder = simulation.compute('nbH') nbH = self.cast_from_entity_to_role(nbH_holder, role=QUIFOY['vous']) nbEnf = (nbF + nbH / 2) lps = simulation.legislation_at(period.start).landais_piketty_saez ae = nbEnf * lps.abatt_enfant re = nbEnf * lps.reduc_enfant ce = nbEnf * lps.credit_enfant statut_marital = simulation.calculate('statut_marital') couple = (statut_marital == 1) | (statut_marital == 5) ac = couple * lps.abatt_conj rc = couple * lps.reduc_conj assiette_csg = simulation.calculate('assiette_csg') return period, -max_( 0, lps.bareme.calc(max_(assiette_csg - ae - ac, 0)) - re - rc) + ce class revenu_disponible(Reform.Variable): column = columns.FloatCol(default=0) entity_class = entities.Menages label = u"Revenu disponible du ménage" url = u"http://fr.wikipedia.org/wiki/Revenu_disponible" def function(self, simulation, period): period = period.start.offset('first-of', 'month').period('year') impot_revenu_lps_holder = simulation.compute('impot_revenu_lps') impot_revenu_lps = self.sum_by_entity(impot_revenu_lps_holder) pen_holder = simulation.compute('pen') pen = self.sum_by_entity(pen_holder) psoc_holder = simulation.compute('psoc') psoc = self.cast_from_entity_to_role(psoc_holder, role=QUIFAM['chef']) psoc = self.sum_by_entity(psoc) rev_cap_holder = simulation.compute('rev_cap') rev_cap = self.sum_by_entity(rev_cap_holder) rev_trav_holder = simulation.compute('rev_trav') rev_trav = self.sum_by_entity(rev_trav_holder) return rev_trav + pen + rev_cap + impot_revenu_lps + psoc reform = Reform() reform.modify_legislation_json(modifier_function=modify_legislation_json) return reform
def build_reform(tax_benefit_system): Reform = reforms.make_reform( key='allocations_familiales_imposables', name=u'Allocations familiales imposables', reference=tax_benefit_system, ) class rbg(Reform.Variable): label = u"Nouveau revenu brut global intégrant les allocations familiales" reference = ir.rbg def function(self, simulation, period): period = period.this_year allocations_familiales_imposables = simulation.calculate_add( 'allocations_familiales_imposables', period) deficit_ante = simulation.calculate('deficit_ante', period) f6gh = simulation.calculate('f6gh', period) nacc_pvce_holder = simulation.calculate('nacc_pvce', period) nbic_impm_holder = simulation.calculate('nbic_impm', period) rev_cat = simulation.calculate('rev_cat', period) cga = simulation.legislation_at(period.start).ir.rpns.cga_taux2 nacc_pvce = self.sum_by_entity(nacc_pvce_holder) return period, max_( 0, allocations_familiales_imposables + rev_cat + f6gh + (self.sum_by_entity(nbic_impm_holder) + nacc_pvce) * (1 + cga) - deficit_ante) class rfr(Reform.Variable): label = u"Nouveau revenu fiscal de référence intégrant les allocations familiales" reference = ir.rfr def function(self, simulation, period): period = period.this_year allocations_familiales_imposables = simulation.calculate( 'allocations_familiales_imposables') f3va_holder = simulation.calculate('f3va') f3vi_holder = simulation.calculate('f3vi') f3vz = simulation.calculate('f3vz') rfr_cd = simulation.calculate('rfr_cd') rfr_rvcm = simulation.calculate('rfr_rvcm') rni = simulation.calculate('rni') rpns_exon_holder = simulation.calculate('rpns_exon') rpns_pvce_holder = simulation.calculate('rpns_pvce') rev_cap_lib = simulation.calculate_add('rev_cap_lib') microentreprise = simulation.calculate('microentreprise') f3va = self.sum_by_entity(f3va_holder) f3vi = self.sum_by_entity(f3vi_holder) rpns_exon = self.sum_by_entity(rpns_exon_holder) rpns_pvce = self.sum_by_entity(rpns_pvce_holder) return period, (max_(0, rni - allocations_familiales_imposables) + rfr_cd + rfr_rvcm + rev_cap_lib + f3vi + rpns_exon + rpns_pvce + f3va + f3vz + microentreprise) class allocations_familiales_imposables(Reform.Variable): column = columns.FloatCol entity_class = entities.FoyersFiscaux label = u"Allocations familiales imposables" def function(self, simulation, period): period = period.this_year af_holder = simulation.calculate_add('af') imposition = simulation.legislation_at( period.start).allocations_familiales_imposables.imposition af = self.cast_from_entity_to_role(af_holder, entity="famille", role=QUIFOY['vous']) af = self.sum_by_entity(af) return period, af * imposition reform = Reform() reform.modify_legislation_json(modifier_function=modify_legislation_json) return reform
def build_reform(tax_benefit_system): Reform = reforms.make_reform( key=u'douanes', name=u'Droits de douane, droits de consommation et TVA', reference=tax_benefit_system, ) def yaml_tree_variable_function(self, simulation, period): # yaml_blocks is defined in outer scope match = match_conditions(yaml_blocks, simulation, period) result = self.zeros() + match['results'][self.__class__.__name__] \ if match is not None \ else self.zeros() return period, result # Input variables class code_produit(Reform.Variable): column = StrCol entity_class = Individus label = u'Code du produit importé suivant la nomenclature des douanes' class moyen_transport(Reform.Variable): column = EnumCol(enum=Enum([u'avion', u'bateau', u'route', u'train'])) entity_class = Individus label = u'Moyen de transport utilisé pour importer un produit' class quantite_produit(Reform.Variable): column = IntCol entity_class = Individus label = u'Quantité du produit importé' class valeur_produit(Reform.Variable): column = FloatCol entity_class = Individus label = u'Valeur du produit importé' class zone_provenance_produit(Reform.Variable): column = EnumCol(enum=Enum([u'Andorra', u'non_EU', u'EU'])) entity_class = Individus label = u'Zone de provenance du produit importé' # Variables with formulas class taux_droits_douane_max(Reform.Variable): column = FloatCol entity_class = Individus function = yaml_tree_variable_function label = u'Taux de droits de douane sur un produit importé' class droits_consommation(Reform.Variable): column = FloatCol entity_class = Individus function = yaml_tree_variable_function label = u'Taux de droits de consommation sur un produit importé' class droits_specifiques(Reform.Variable): column = FloatCol entity_class = Individus function = yaml_tree_variable_function label = u'TODO' class tva(Reform.Variable): column = FloatCol entity_class = Individus function = yaml_tree_variable_function label = u'Taux de TVA sur un produit importé' class importation_interdite(Reform.Variable): column = BoolCol entity_class = Individus function = yaml_tree_variable_function label = u'L\'importation du produit est interdite' # This creates reform.column_by_name reform = Reform() categories_produits = read_yaml_categories_produits() validate_yaml_tree = conv.make_validate_yaml_tree( categories_produits=categories_produits, variable_names=reform.column_by_name.keys(), ) yaml_file_paths = glob.glob(os.path.join(trees_dir_path, '*.yaml')) yaml_blocks = list( itertools.chain.from_iterable( read_yaml_tree(yaml_file_path, validate_yaml_tree) for yaml_file_path in yaml_file_paths)) return reform
def build_reform(tax_benefit_system): Reform = reforms.make_reform( key='ayrault_muet', name=u'Amendement Ayrault-Muet au PLF2016', reference=tax_benefit_system, ) class variator(Reform.Variable): column = FloatCol(default=1) entity_class = FoyersFiscaux label = u'Multiplicateur du seuil de régularisation' class reduction_csg(Reform.DatedVariable): column = FloatCol entity_class = Individus label = u"Réduction dégressive de CSG" @dated_function(start=date(2015, 1, 1)) def function_2015__(self, simulation, period): period = period.start.offset('first-of', 'year').period('year') smic_proratise = simulation.calculate_add('smic_proratise', period) assiette_csg_abattue = simulation.calculate_add( 'assiette_csg_abattue', period) seuil = 1.34 coefficient_correctif = .9 taux_csg = (simulation.legislation_at( period.start).csg.activite.imposable.taux + simulation.legislation_at( period.start).csg.activite.deductible.taux) tx_max = coefficient_correctif * taux_csg ratio_smic_salaire = smic_proratise / (assiette_csg_abattue + 1e-16) # règle d'arrondi: 4 décimales au dix-millième le plus proche taux_allegement_csg = tx_max * min_( 1, max_(seuil - 1 / ratio_smic_salaire, 0) / (seuil - 1)) # Montant de l'allegment return period, taux_allegement_csg * assiette_csg_abattue class reduction_csg_foyer_fiscal(Reform.PersonToEntityColumn): entity_class = FoyersFiscaux label = u"Réduction dégressive de CSG des memebres du foyer fiscal" operation = 'add' variable = reduction_csg class reduction_csg_nette(Reform.DatedVariable): column = FloatCol entity_class = Individus label = u"Réduction dégressive de CSG" @dated_function(start=date(2015, 1, 1)) def function_2015__(self, simulation, period): period = period.start.offset('first-of', 'year').period('year') reduction_csg = simulation.calculate('reduction_csg', period) ppe_elig_bis_individu = simulation.calculate( 'ppe_elig_bis_individu', period) return period, reduction_csg * ppe_elig_bis_individu class ppe_elig_bis(Reform.Variable): column = BoolCol(default=False) entity_class = FoyersFiscaux label = u"ppe_elig_bis" def function(self, simulation, period): ''' PPE: eligibilité à la ppe, condition sur le revenu fiscal de référence 'foy' ''' period = period.start.offset('first-of', 'year').period('year') rfr = simulation.calculate('rfr', period) ppe_coef = simulation.calculate('ppe_coef', period) marpac = simulation.calculate('marpac', period) veuf = simulation.calculate('veuf', period) celdiv = simulation.calculate('celdiv', period) nbptr = simulation.calculate('nbptr', period) variator = simulation.calculate('variator', period) ppe = simulation.legislation_at(period.start).ir.credits_impot.ppe seuil = (veuf | celdiv) * (ppe.eligi1 + 2 * max_(nbptr - 1, 0) * ppe.eligi3) \ + marpac * (ppe.eligi2 + 2 * max_(nbptr - 2, 0) * ppe.eligi3) return period, (rfr * ppe_coef) <= (seuil * variator) class ppe_elig_bis_individu(Reform.EntityToPersonColumn): entity_class = Individus variable = ppe_elig_bis class regularisation_reduction_csg(Reform.DatedVariable): column = FloatCol entity_class = FoyersFiscaux label = u"Régularisation complète réduction dégressive de CSG" @dated_function(start=date(2015, 1, 1)) def function_2015__(self, simulation, period): period = period.start.offset('first-of', 'year').period('year') reduction_csg = simulation.calculate('reduction_csg_foyer_fiscal', period) ppe_elig_bis = simulation.calculate('ppe_elig_bis', period) return period, not_(ppe_elig_bis) * (reduction_csg > 1) reform = Reform() reform.modify_legislation_json( modifier_function=ayrault_muet_modify_legislation_json) return reform
def build_reform(tax_benefit_system): Reform = reforms.make_reform( key = 'revenu_de_base_cotisations', name = u"Réforme des cotisations pour un Revenu de base", reference = tax_benefit_system, ) @Reform.formula class cotisations_contributives(SimpleFormulaColumn): column = FloatCol entity_class = Individus label = u"Nouvelles cotisations contributives" def function(self, simulation, period): ags = simulation.calculate('ags', period) agff_tranche_a_employeur = simulation.calculate('agff_tranche_a_employeur', period) apec_employeur = simulation.calculate('apec_employeur', period) arrco_tranche_a_employeur = simulation.calculate('arrco_tranche_a_employeur', period) assedic_employeur = simulation.calculate('assedic_employeur', period) cotisation_exceptionnelle_temporaire_employeur = simulation.calculate( 'cotisation_exceptionnelle_temporaire_employeur', period) fonds_emploi_hospitalier = simulation.calculate('fonds_emploi_hospitalier', period) ircantec_employeur = simulation.calculate('ircantec_employeur', period) pension_civile_employeur = simulation.calculate('pension_civile_employeur', period) prevoyance_obligatoire_cadre = simulation.calculate('prevoyance_obligatoire_cadre', period) rafp_employeur = simulation.calculate('rafp_employeur', period) vieillesse_deplafonnee_employeur = simulation.calculate('vieillesse_deplafonnee_employeur', period) vieillesse_plafonnee_employeur = simulation.calculate('vieillesse_plafonnee_employeur', period) allocations_temporaires_invalidite = simulation.calculate('allocations_temporaires_invalidite', period) accident_du_travail = simulation.calculate('accident_du_travail', period) agff_tranche_a_employe = simulation.calculate('agff_tranche_a_employe', period) agirc_tranche_b_employe = simulation.calculate('agirc_tranche_b_employe', period) apec_employe = simulation.calculate('apec_employe', period) arrco_tranche_a_employe = simulation.calculate('arrco_tranche_a_employe', period) assedic_employe = simulation.calculate('assedic_employe', period) cotisation_exceptionnelle_temporaire_employe = simulation.calculate( 'cotisation_exceptionnelle_temporaire_employe', period) ircantec_employe = simulation.calculate('ircantec_employe', period) pension_civile_employe = simulation.calculate('pension_civile_employe', period) rafp_employe = simulation.calculate('rafp_employe', period) vieillesse_deplafonnee_employe = simulation.calculate('vieillesse_deplafonnee_employe', period) vieillesse_plafonnee_employe = simulation.calculate('vieillesse_plafonnee_employe', period) cotisations_contributives = ( # cotisations patronales contributives dans le prive ags + agff_tranche_a_employeur + apec_employeur + arrco_tranche_a_employeur + assedic_employeur + cotisation_exceptionnelle_temporaire_employeur + prevoyance_obligatoire_cadre + # TODO contributive ou pas vieillesse_deplafonnee_employeur + vieillesse_plafonnee_employeur + # cotisations patronales contributives dans le public fonds_emploi_hospitalier + ircantec_employeur + pension_civile_employeur + rafp_employeur + # anciennes cot patronales non-contributives classées ici comme contributives allocations_temporaires_invalidite + accident_du_travail + # anciennes cotisations salariales contributives dans le prive agff_tranche_a_employe + agirc_tranche_b_employe + apec_employe + arrco_tranche_a_employe + assedic_employe + cotisation_exceptionnelle_temporaire_employe + vieillesse_deplafonnee_employe + vieillesse_plafonnee_employe + # anciennes cotisations salariales contributives dans le public ircantec_employe + pension_civile_employe + rafp_employe ) return period, cotisations_contributives @Reform.formula class nouv_salaire_de_base(SimpleFormulaColumn): reference = tax_benefit_system.column_by_name['salaire_de_base'] # Le salaire brut se définit dans la réforme comme le salaire super-brut auquel # on retranche les cotisations contributives def function(self, simulation, period): period = period.start.period('month').offset('first-of') salsuperbrut = simulation.calculate('salsuperbrut', period) cotisations_contributives = simulation.calculate('cotisations_contributives', period) nouv_salaire_de_base = ( salsuperbrut - cotisations_contributives ) return period, nouv_salaire_de_base @Reform.formula class nouv_csg(SimpleFormulaColumn): reference = tax_benefit_system.column_by_name['csg_imposable_salaire'] # On applique une CSG unique à 22,5% qui finance toutes les prestations non-contributives def function(self, simulation, period): period = period.start.period('month').offset('first-of') nouv_salaire_de_base = simulation.calculate('nouv_salaire_de_base', period) nouv_csg = ( -0.225 * nouv_salaire_de_base ) return period, nouv_csg @Reform.formula class salaire_net(SimpleFormulaColumn): reference = tax_benefit_system.column_by_name['salaire_net'] # On retire la nouvelle CSG (pas celle qui finance le RDB) pour trouver le nouveau salaire net def function(self, simulation, period): period = period.start.period('month').offset('first-of') nouv_salaire_de_base = simulation.calculate('nouv_salaire_de_base', period) nouv_csg = simulation.calculate('nouv_csg', period) salaire_net = ( nouv_salaire_de_base + nouv_csg ) return period, salaire_net @Reform.formula class salaire_imposable(SimpleFormulaColumn): reference = tax_benefit_system.column_by_name['salaire_imposable'] # Nous sommes partis du nouveau salaire net et par rapport au salaire imposable actuel, # nous avons supprimé : les heures sup, la déductibilité de CSG def function(self, simulation, period): period = period hsup = simulation.calculate('hsup', period) salaire_net = simulation.calculate('salaire_net', period) primes_fonction_publique = simulation.calculate('primes_fonction_publique', period) indemnite_residence = simulation.calculate('indemnite_residence', period) supp_familial_traitement = simulation.calculate('supp_familial_traitement', period) rev_microsocial_declarant1 = simulation.calculate('rev_microsocial_declarant1', period) return period, ( salaire_net + primes_fonction_publique + indemnite_residence + supp_familial_traitement + hsup + rev_microsocial_declarant1 ) return Reform()
'Familles', 'FloatCol', 'FoyersFiscaux', 'Individus', 'IntCol', 'Menages', 'openfisca_france_tax_benefit_system', 'PART', 'PersonToEntityColumn', 'QUIFAM', 'QUIFOY', 'TaxBenefitSystem', 'Variable', 'VOUS', ] OpenFiscaFranceTaxBenefitSystem = openfisca_france.init_country() openfisca_france_tax_benefit_system = OpenFiscaFranceTaxBenefitSystem() TaxBenefitSystem = reforms.make_reform( key = 'openfisca_france_data', name = u"OpenFisca for survey data", reference = openfisca_france_tax_benefit_system, ) # Export reform classes to register variables in reform column_by_name dict. DatedVariable = TaxBenefitSystem.DatedVariable EntityToPersonColumn = TaxBenefitSystem.EntityToPersonColumn PersonToEntityColumn = TaxBenefitSystem.PersonToEntityColumn Variable = TaxBenefitSystem.Variable
def build_reform(tax_benefit_system): Reform = reforms.make_reform( key='revenu_de_base_cotisations', name=u"Réforme des cotisations pour un Revenu de base", reference=tax_benefit_system, ) class cotisations_contributives(Variable): column = FloatCol entity_class = Individus label = u"Nouvelles cotisations contributives" def function(self, simulation, period): ags = simulation.calculate('ags', period) agff_tranche_a_employeur = simulation.calculate( 'agff_tranche_a_employeur', period) apec_employeur = simulation.calculate('apec_employeur', period) arrco_tranche_a_employeur = simulation.calculate( 'arrco_tranche_a_employeur', period) assedic_employeur = simulation.calculate('assedic_employeur', period) cotisation_exceptionnelle_temporaire_employeur = simulation.calculate( 'cotisation_exceptionnelle_temporaire_employeur', period) fonds_emploi_hospitalier = simulation.calculate( 'fonds_emploi_hospitalier', period) ircantec_employeur = simulation.calculate('ircantec_employeur', period) pension_civile_employeur = simulation.calculate( 'pension_civile_employeur', period) prevoyance_obligatoire_cadre = simulation.calculate( 'prevoyance_obligatoire_cadre', period) rafp_employeur = simulation.calculate('rafp_employeur', period) vieillesse_deplafonnee_employeur = simulation.calculate( 'vieillesse_deplafonnee_employeur', period) vieillesse_plafonnee_employeur = simulation.calculate( 'vieillesse_plafonnee_employeur', period) allocations_temporaires_invalidite = simulation.calculate( 'allocations_temporaires_invalidite', period) accident_du_travail = simulation.calculate('accident_du_travail', period) agff_tranche_a_employe = simulation.calculate( 'agff_tranche_a_employe', period) agirc_tranche_b_employe = simulation.calculate( 'agirc_tranche_b_employe', period) apec_employe = simulation.calculate('apec_employe', period) arrco_tranche_a_employe = simulation.calculate( 'arrco_tranche_a_employe', period) assedic_employe = simulation.calculate('assedic_employe', period) cotisation_exceptionnelle_temporaire_employe = simulation.calculate( 'cotisation_exceptionnelle_temporaire_employe', period) ircantec_employe = simulation.calculate('ircantec_employe', period) pension_civile_employe = simulation.calculate( 'pension_civile_employe', period) rafp_employe = simulation.calculate('rafp_employe', period) vieillesse_deplafonnee_employe = simulation.calculate( 'vieillesse_deplafonnee_employe', period) vieillesse_plafonnee_employe = simulation.calculate( 'vieillesse_plafonnee_employe', period) cotisations_contributives = ( # cotisations patronales contributives dans le prive ags + agff_tranche_a_employeur + apec_employeur + arrco_tranche_a_employeur + assedic_employeur + cotisation_exceptionnelle_temporaire_employeur + prevoyance_obligatoire_cadre + # TODO contributive ou pas vieillesse_deplafonnee_employeur + vieillesse_plafonnee_employeur + # cotisations patronales contributives dans le public fonds_emploi_hospitalier + ircantec_employeur + pension_civile_employeur + rafp_employeur + # anciennes cot patronales non-contributives classées ici comme contributives allocations_temporaires_invalidite + accident_du_travail + # anciennes cotisations salariales contributives dans le prive agff_tranche_a_employe + agirc_tranche_b_employe + apec_employe + arrco_tranche_a_employe + assedic_employe + cotisation_exceptionnelle_temporaire_employe + vieillesse_deplafonnee_employe + vieillesse_plafonnee_employe + # anciennes cotisations salariales contributives dans le public ircantec_employe + pension_civile_employe + rafp_employe) return period, cotisations_contributives class nouv_salaire_de_base(Variable): reference = tax_benefit_system.column_by_name['salaire_de_base'] # Le salaire brut se définit dans la réforme comme le salaire super-brut auquel # on retranche les cotisations contributives def function(self, simulation, period): period = period.start.period('month').offset('first-of') salsuperbrut = simulation.calculate('salsuperbrut', period) cotisations_contributives = simulation.calculate( 'cotisations_contributives', period) nouv_salaire_de_base = (salsuperbrut - cotisations_contributives) return period, nouv_salaire_de_base class nouv_csg(Variable): reference = tax_benefit_system.column_by_name['csg_imposable_salaire'] # On applique une CSG unique à 22,5% qui finance toutes les prestations non-contributives def function(self, simulation, period): period = period.start.period('month').offset('first-of') nouv_salaire_de_base = simulation.calculate( 'nouv_salaire_de_base', period) nouv_csg = (-0.225 * nouv_salaire_de_base) return period, nouv_csg class salaire_net(Variable): reference = tax_benefit_system.column_by_name['salaire_net'] # On retire la nouvelle CSG (pas celle qui finance le RDB) pour trouver le nouveau salaire net def function(self, simulation, period): period = period.start.period('month').offset('first-of') nouv_salaire_de_base = simulation.calculate( 'nouv_salaire_de_base', period) nouv_csg = simulation.calculate('nouv_csg', period) salaire_net = (nouv_salaire_de_base + nouv_csg) return period, salaire_net class salaire_imposable(Variable): reference = tax_benefit_system.column_by_name['salaire_imposable'] # Nous sommes partis du nouveau salaire net et par rapport au salaire imposable actuel, # nous avons supprimé : les heures sup, la déductibilité de CSG def function(self, simulation, period): period = period hsup = simulation.calculate('hsup', period) salaire_net = simulation.calculate('salaire_net', period) primes_fonction_publique = simulation.calculate( 'primes_fonction_publique', period) indemnite_residence = simulation.calculate('indemnite_residence', period) supp_familial_traitement = simulation.calculate( 'supp_familial_traitement', period) rev_microsocial_declarant1 = simulation.calculate( 'rev_microsocial_declarant1', period) return period, (salaire_net + primes_fonction_publique + indemnite_residence + supp_familial_traitement + hsup + rev_microsocial_declarant1) return Reform()
def build_reform(tax_benefit_system): Reform = reforms.make_reform( key='inversion_directe_salaires', name=u'Inversion des revenus', reference=tax_benefit_system, ) class salaire_imposable_pour_inversion(Reform.Variable): column = columns.FloatCol entity_class = entities.Individus label = u'Salaire imposable utilisé pour remonter au salaire brut' class salaire_de_base(Reform.Variable): column = columns.FloatCol entity_class = entities.Individus label = u"Salaire brut" reference = tax_benefit_system.column_by_name["salaire_de_base"] def function(self, simulation, period): """Calcule le salaire brut à partir du salaire imposable ou sinon du salaire net. Sauf pour les fonctionnaires où il renvoie le traitement indiciaire brut Note : le supplément familial de traitement est imposable. """ # Get value for year and divide below. salaire_imposable_pour_inversion = simulation.calculate( 'salaire_imposable_pour_inversion', period.start.offset('first-of', 'year').period('year')) # Calcule le salaire brut à partir du salaire imposable par inversion numérique. # if salaire_imposable_pour_inversion == 0 or (salaire_imposable_pour_inversion == 0).all(): # # Quick path to avoid fsolve when using default value of input variables. # return period, salaire_imposable_pour_inversion # Calcule le salaire brut à partir du salaire imposable. # Sauf pour les fonctionnaires où il renvoie le traitement indiciaire brut # Note : le supplément familial de traitement est imposable. hsup = simulation.calculate('hsup', period) categorie_salarie = simulation.calculate('categorie_salarie', period) P = simulation.legislation_at(period.start) salarie = P.cotsoc.cotisations_salarie plafond_securite_sociale_annuel = P.cotsoc.gen.plafond_securite_sociale * 12 taux_csg = P.csg.activite.deductible.taux * (1 - .0175) csg = MarginalRateTaxScale(name='csg') csg.add_bracket(0, taux_csg) # cat = None # if (categorie_salarie == 0).all(): # cat = 'prive_non_cadre' # elif (categorie_salarie == 1).all(): # cat = 'prive_cadre' # elif (categorie_salarie == 2).all(): # cat = 'public_titulaire_etat' # if cat is not None: # for name, bareme in salarie[cat].iteritems(): # print name, bareme prive_non_cadre = salarie['prive_non_cadre'].combine_tax_scales( ).scale_tax_scales(plafond_securite_sociale_annuel) prive_cadre = salarie['prive_cadre'].combine_tax_scales( ).scale_tax_scales(plafond_securite_sociale_annuel) # On ajoute la CSG deductible prive_non_cadre.add_tax_scale(csg) prive_cadre.add_tax_scale(csg) salaire_de_base = ( (categorie_salarie == CAT['prive_non_cadre']) * prive_non_cadre .inverse().calc(salaire_imposable_pour_inversion) + (categorie_salarie == CAT['prive_cadre']) * prive_cadre.inverse().calc(salaire_imposable_pour_inversion)) return period, salaire_de_base + hsup class traitement_indiciaire_brut(Reform.Variable): column = columns.FloatCol entity_class = entities.Individus label = u"Traitement indiciaire brut" reference = tax_benefit_system.column_by_name[ "traitement_indiciaire_brut"] def function(self, simulation, period): """Calcule le tratement indiciaire brut à partir du salaire imposable. """ # Get value for year and divide below. salaire_imposable_pour_inversion = simulation.calculate( 'salaire_imposable_pour_inversion', period.start.offset('first-of', 'year').period('year')) # Calcule le salaire brut à partir du salaire imposable par inversion numérique. # if salaire_imposable_pour_inversion == 0 or (salaire_imposable_pour_inversion == 0).all(): # # Quick path to avoid fsolve when using default value of input variables. # return period, salaire_imposable_pour_inversion # Calcule le salaire brut à partir du salaire imposable. # Sauf pour les fonctionnaires où il renvoie le traitement indiciaire brut # Note : le supplément familial de traitement est imposable. categorie_salarie = simulation.calculate('categorie_salarie', period) P = simulation.legislation_at(period.start) taux_csg = P.csg.activite.deductible.taux * (1 - .0175) csg = MarginalRateTaxScale(name='csg') csg.add_bracket(0, taux_csg) salarie = P.cotsoc.cotisations_salarie # cat = None # if (categorie_salarie == 2).all(): # cat = 'public_titulaire_etat' # if cat is not None: # for name, bareme in salarie[cat].iteritems(): # print name, bareme # public etat # TODO: modifier la contribution exceptionelle de solidarité # en fixant son seuil de non imposition dans le barème (à corriger dans param.xml # et en tenant compte des éléments de l'assiette # salarie['fonc']['etat']['excep_solidarite'] = salarie['fonc']['commun']['solidarite'] public_titulaire_etat = salarie['public_titulaire_etat'].copy() public_titulaire_etat['rafp'].multiply_rates(TAUX_DE_PRIME, inplace=True) public_titulaire_etat = salarie[ 'public_titulaire_etat'].combine_tax_scales() # public_titulaire_territoriale = salarie['public_titulaire_territoriale'].combine_tax_scales() # public_titulaire_hospitaliere = salarie['public_titulaire_hospitaliere'].combine_tax_scales() # public_non_titulaire = salarie['public_non_titulaire'].combine_tax_scales() # Pour a fonction publique la csg est calculée sur l'ensemble salbrut(=TIB) + primes # Imposable = TIB - csg( (1+taux_prime)*TIB ) - pension(TIB) + taux_prime*TIB bareme_csg_public_titulaire_etat = csg.multiply_rates( 1 + TAUX_DE_PRIME, inplace=False, new_name="csg deduc titutaire etat") public_titulaire_etat.add_tax_scale( bareme_csg_public_titulaire_etat) bareme_prime = MarginalRateTaxScale(name="taux de prime") bareme_prime.add_bracket( 0, -TAUX_DE_PRIME) # barème équivalent à taux_prime*TIB public_titulaire_etat.add_tax_scale(bareme_prime) traitement_indiciaire_brut = ( (categorie_salarie == CAT['public_titulaire_etat']) * public_titulaire_etat.inverse().calc( salaire_imposable_pour_inversion)) # TODO: complete this to deal with the fonctionnaire # supp_familial_traitement = 0 # TODO: dépend de salbrut # indemnite_residence = 0 # TODO: fix bug return period, traitement_indiciaire_brut class primes_fonction_publique(Reform.Variable): column = columns.FloatCol entity_class = entities.Individus label = u"Primes de la fonction publique" reference = tax_benefit_system.column_by_name[ "primes_fonction_publique"] def function(self, simulation, period): """Calcule les primes. """ # Get value for year and divide below. traitement_indiciaire_brut = simulation.calculate( 'traitement_indiciaire_brut', period.start.offset('first-of', 'year').period('year')) return period, TAUX_DE_PRIME * traitement_indiciaire_brut return Reform()
def build_reform(tax_benefit_system): Reform = reforms.make_reform( key=u'plfr2014', name=u'Projet de Loi de Finances Rectificative 2014', reference=tax_benefit_system, ) class reduction_impot_exceptionnelle(Reform.DatedVariable): reference = reductions_impot.reduction_impot_exceptionnelle @dated_function(start=date(2013, 1, 1), stop=date(2013, 12, 31)) def function(self, simulation, period): period = period.this_year nb_adult = simulation.calculate('nb_adult') nb_parents = simulation.calculate('nb_parents') rfr = simulation.calculate('rfr') params = simulation.legislation_at( period.start).plfr2014.reduction_impot_exceptionnelle plafond = params.seuil * nb_adult + ( nb_parents - nb_adult) * 2 * params.majoration_seuil montant = params.montant_plafond * nb_adult return period, min_(max_(plafond + montant - rfr, 0), montant) class reductions(Reform.DatedVariable): label = u"Somme des réductions d'impôt à intégrer pour l'année 2013" reference = reductions_impot.reductions @dated_function(start=date(2013, 1, 1), stop=date(2013, 12, 31)) def function_20130101_20131231(self, simulation, period): period = period.this_year accult = simulation.calculate('accult') adhcga = simulation.calculate('adhcga') cappme = simulation.calculate('cappme') creaen = simulation.calculate('creaen') daepad = simulation.calculate('daepad') deffor = simulation.calculate('deffor') dfppce = simulation.calculate('dfppce') doment = simulation.calculate('doment') domlog = simulation.calculate('domlog') donapd = simulation.calculate('donapd') duflot = simulation.calculate('duflot') ecpess = simulation.calculate('ecpess') garext = simulation.calculate('garext') intagr = simulation.calculate('intagr') invfor = simulation.calculate('invfor') invlst = simulation.calculate('invlst') ip_net = simulation.calculate('ip_net') locmeu = simulation.calculate('locmeu') mecena = simulation.calculate('mecena') mohist = simulation.calculate('mohist') patnat = simulation.calculate('patnat') prcomp = simulation.calculate('prcomp') reduction_impot_exceptionnelle = simulation.calculate( 'reduction_impot_exceptionnelle') repsoc = simulation.calculate('repsoc') resimm = simulation.calculate('resimm') rsceha = simulation.calculate('rsceha') saldom = simulation.calculate('saldom') scelli = simulation.calculate('scelli') sofica = simulation.calculate('sofica') spfcpi = simulation.calculate('spfcpi') total_reductions = accult + adhcga + cappme + creaen + daepad + deffor + dfppce + doment + domlog + \ donapd + duflot + ecpess + garext + intagr + invfor + invlst + locmeu + mecena + mohist + patnat + \ prcomp + repsoc + resimm + rsceha + saldom + scelli + sofica + spfcpi + reduction_impot_exceptionnelle return period, min_(ip_net, total_reductions) reform = Reform() reform.modify_legislation_json(modifier_function=modify_legislation_json) return reform
def build_reform(tax_benefit_system): Reform = reforms.make_reform( key='aides_cd93', name=u'Aides du conseil départemental du 93', reference=tax_benefit_system, ) class perte_autonomie(Reform.Variable): column = BoolCol entity_class = Individus label = u"Personne en perte d'autonomie" class resident_93(Reform.Variable): column = BoolCol label = u"Résident en Seine-Saint-Denis" entity_class = Menages def function(self, simulation, period): period = period.this_month depcom = simulation.calculate('depcom', period) def is_resident_93(code_insee): prefix = code_insee[0:2] result = (prefix == "93") return result is_resident_93_vec = vectorize(is_resident_93) result = is_resident_93_vec(depcom) return period, result class adpa_eligibilite(Reform.Variable): column = BoolCol label = u"Eligibilité à l'ADPA" entity_class = Individus def function(self, simulation, period): period = period.this_month age = simulation.calculate('age', period) resident_93 = simulation.calculate('resident_93', period) perte_autonomie = simulation.calculate('perte_autonomie', period) result = (age >= 60) * resident_93 * perte_autonomie return period, result class adpa_base_ressources_i(Reform.Variable): column = FloatCol label = u"Base ressources ADPA pour un individu" entity_class = Individus def function(self, simulation, period): period = period.this_month previous_year = period.start.period('year').offset(-1) salaire_imposable = simulation.calculate_add( 'salaire_imposable', period.n_2) retraite_imposable = simulation.calculate_add( 'retraite_imposable', period.n_2) chomage_imposable = simulation.calculate_add( 'chomage_imposable', period.n_2) revenus_capital = simulation.calculate_add('revenus_capital', previous_year) revenus_locatifs = simulation.calculate_add( 'revenus_locatifs', previous_year) # Prélevements libératoire forfaitaire à prendre en compte sans abattement valeur_locative_immo_non_loue = simulation.calculate_add( 'valeur_locative_immo_non_loue', previous_year) valeur_locative_terrains_non_loue = simulation.calculate_add( 'valeur_locative_terrains_non_loue', previous_year) base_ressource_mensuelle = ( salaire_imposable + retraite_imposable + chomage_imposable + revenus_locatifs + revenus_capital * 0.30 + valeur_locative_immo_non_loue * 0.5 + valeur_locative_terrains_non_loue * 0.8) / 12 return period, base_ressource_mensuelle class adpa_base_ressources(Reform.Variable): column = FloatCol label = u"Base ressources ADPA pour une famille" entity_class = Familles def function(self, simulation, period): period = period.this_month adpa_base_ressources_i = simulation.compute( 'adpa_base_ressources_i', period) adpa_base_ressources = self.sum_by_entity(adpa_base_ressources_i) return period, adpa_base_ressources class adpa(Reform.Variable): column = FloatCol label = u"ADPA" entity_class = Familles def function(self, simulation, period): period = period.this_month adpa_eligibilite_holder = simulation.compute( 'adpa_eligibilite', period) adpa_eligibilite = self.any_by_roles(adpa_eligibilite_holder) base_ressource_mensuelle = simulation.calculate( 'adpa_base_ressources', period) en_couple = simulation.calculate('en_couple', period) # On ne prend pas en compte le cas où le conjoint est placé. quotient_familial = 1 + 0.7 * en_couple base_ressource_mensuelle = base_ressource_mensuelle / quotient_familial majorationTiercePersonne = 1103.08 seuil1 = 0.67 * majorationTiercePersonne seuil2 = 2.67 * majorationTiercePersonne participation_usager = ((base_ressource_mensuelle < seuil1) * 0 + (base_ressource_mensuelle >= seuil1) * (base_ressource_mensuelle <= seuil2) * 90 * (base_ressource_mensuelle - seuil1) / (2 * majorationTiercePersonne) + (base_ressource_mensuelle > seuil2) * 90) participation_departement = 100 - participation_usager return period, participation_departement * adpa_eligibilite reform = Reform() return reform
def build_counterfactual_2014_reform(tax_benefit_system): Reform = reforms.make_reform( key='plf2016_counterfactual_2014', name=u'Contrefactuel 2014 du PLF 2016 sur les revenus 2015', reference=tax_benefit_system, ) class decote(Reform.DatedVariable): reference = ir.decote @dated_function(start=date(2015, 1, 1)) def function_2015(self, simulation, period): period = period.start.offset('first-of', 'year').period('year') ir_plaf_qf = simulation.calculate('ir_plaf_qf', period) inflator = 1 + .001 + .005 decote = simulation.legislation_at(period.start).ir.decote assert decote.seuil == 1016 return period, (ir_plaf_qf < decote.seuil * inflator) * ( decote.seuil * inflator - ir_plaf_qf) * 0.5 class reduction_impot_exceptionnelle(Reform.DatedVariable): reference = reductions_impot.reduction_impot_exceptionnelle @dated_function(start=date(2015, 1, 1), stop=date(2015, 12, 31)) def function_2015(self, simulation, period): period = period.start.offset('first-of', 'year').period('year') nb_adult = simulation.calculate('nb_adult') nb_parents = simulation.calculate('nb_parents') rfr = simulation.calculate('rfr') inflator = 1 + .001 + .005 # params = simulation.legislation_at(period.start).ir.reductions_impots.reduction_impot_exceptionnelle seuil = 13795 * inflator majoration_seuil = 3536 * inflator montant_plafond = 350 * inflator plafond = seuil * nb_adult + (nb_parents - nb_adult) * 2 * majoration_seuil montant = montant_plafond * nb_adult return period, min_(max_(plafond + montant - rfr, 0), montant) class reductions(Reform.DatedVariable): label = u"Somme des réductions d'impôt" reference = reductions_impot.reductions @dated_function(start=date(2013, 1, 1), stop=date(2015, 12, 31)) def function_20130101_20131231(self, simulation, period): period = period.start.offset('first-of', 'year').period('year') accult = simulation.calculate('accult') adhcga = simulation.calculate('adhcga') cappme = simulation.calculate('cappme') creaen = simulation.calculate('creaen') daepad = simulation.calculate('daepad') deffor = simulation.calculate('deffor') dfppce = simulation.calculate('dfppce') doment = simulation.calculate('doment') domlog = simulation.calculate('domlog') donapd = simulation.calculate('donapd') duflot = simulation.calculate('duflot') ecpess = simulation.calculate('ecpess') garext = simulation.calculate('garext') intagr = simulation.calculate('intagr') invfor = simulation.calculate('invfor') invlst = simulation.calculate('invlst') ip_net = simulation.calculate('ip_net') locmeu = simulation.calculate('locmeu') mecena = simulation.calculate('mecena') mohist = simulation.calculate('mohist') patnat = simulation.calculate('patnat') prcomp = simulation.calculate('prcomp') reduction_impot_exceptionnelle = simulation.calculate( 'reduction_impot_exceptionnelle') repsoc = simulation.calculate('repsoc') resimm = simulation.calculate('resimm') rsceha = simulation.calculate('rsceha') saldom = simulation.calculate('saldom') scelli = simulation.calculate('scelli') sofica = simulation.calculate('sofica') spfcpi = simulation.calculate('spfcpi') total_reductions = accult + adhcga + cappme + creaen + daepad + deffor + dfppce + doment + domlog + \ donapd + duflot + ecpess + garext + intagr + invfor + invlst + locmeu + mecena + mohist + patnat + \ prcomp + repsoc + resimm + rsceha + saldom + scelli + sofica + spfcpi + reduction_impot_exceptionnelle return period, min_(ip_net, total_reductions) reform = Reform() reform.modify_legislation_json( modifier_function=counterfactual_2014_modify_legislation_json) return reform
def build_reform(tax_benefit_system): Reform = reforms.make_reform( key = 'inversion_directe_salaires', name = u'Inversion des revenus', reference = tax_benefit_system, ) class salaire_imposable_pour_inversion(Reform.Variable): column = columns.FloatCol entity_class = entities.Individus label = u'Salaire imposable utilisé pour remonter au salaire brut' class salaire_de_base(Reform.Variable): column = columns.FloatCol entity_class = entities.Individus label = u"Salaire brut" reference = tax_benefit_system.column_by_name["salaire_de_base"] def function(self, simulation, period): """Calcule le salaire brut à partir du salaire imposable ou sinon du salaire net. Sauf pour les fonctionnaires où il renvoie le traitement indiciaire brut Note : le supplément familial de traitement est imposable. """ # Get value for year and divide below. salaire_imposable_pour_inversion = simulation.calculate('salaire_imposable_pour_inversion', period.start.offset('first-of', 'year').period('year')) # Calcule le salaire brut à partir du salaire imposable par inversion numérique. # if salaire_imposable_pour_inversion == 0 or (salaire_imposable_pour_inversion == 0).all(): # # Quick path to avoid fsolve when using default value of input variables. # return period, salaire_imposable_pour_inversion # Calcule le salaire brut à partir du salaire imposable. # Sauf pour les fonctionnaires où il renvoie le traitement indiciaire brut # Note : le supplément familial de traitement est imposable. hsup = simulation.calculate('hsup', period) type_sal = simulation.calculate('type_sal', period) P = simulation.legislation_at(period.start) salarie = P.cotsoc.cotisations_salarie plafond_securite_sociale_annuel = P.cotsoc.gen.plafond_securite_sociale * 12 taux_csg = P.csg.activite.deductible.taux * (1 - .0175) csg = MarginalRateTaxScale(name = 'csg') csg.add_bracket(0, taux_csg) # cat = None # if (type_sal == 0).all(): # cat = 'prive_non_cadre' # elif (type_sal == 1).all(): # cat = 'prive_cadre' # elif (type_sal == 2).all(): # cat = 'public_titulaire_etat' # if cat is not None: # for name, bareme in salarie[cat].iteritems(): # print name, bareme prive_non_cadre = salarie['prive_non_cadre'].combine_tax_scales().scale_tax_scales( plafond_securite_sociale_annuel) prive_cadre = salarie['prive_cadre'].combine_tax_scales().scale_tax_scales(plafond_securite_sociale_annuel) # On ajoute la CSG deductible prive_non_cadre.add_tax_scale(csg) prive_cadre.add_tax_scale(csg) salaire_de_base = ( (type_sal == CAT['prive_non_cadre']) * prive_non_cadre.inverse().calc(salaire_imposable_pour_inversion) + (type_sal == CAT['prive_cadre']) * prive_cadre.inverse().calc(salaire_imposable_pour_inversion) ) return period, salaire_de_base + hsup class traitement_indiciaire_brut(Reform.Variable): column = columns.FloatCol entity_class = entities.Individus label = u"Traitement indiciaire brut" reference = tax_benefit_system.column_by_name["traitement_indiciaire_brut"] def function(self, simulation, period): """Calcule le tratement indiciaire brut à partir du salaire imposable. """ # Get value for year and divide below. salaire_imposable_pour_inversion = simulation.calculate('salaire_imposable_pour_inversion', period.start.offset('first-of', 'year').period('year')) # Calcule le salaire brut à partir du salaire imposable par inversion numérique. # if salaire_imposable_pour_inversion == 0 or (salaire_imposable_pour_inversion == 0).all(): # # Quick path to avoid fsolve when using default value of input variables. # return period, salaire_imposable_pour_inversion # Calcule le salaire brut à partir du salaire imposable. # Sauf pour les fonctionnaires où il renvoie le traitement indiciaire brut # Note : le supplément familial de traitement est imposable. type_sal = simulation.calculate('type_sal', period) P = simulation.legislation_at(period.start) taux_csg = P.csg.activite.deductible.taux * (1 - .0175) csg = MarginalRateTaxScale(name = 'csg') csg.add_bracket(0, taux_csg) salarie = P.cotsoc.cotisations_salarie # cat = None # if (type_sal == 2).all(): # cat = 'public_titulaire_etat' # if cat is not None: # for name, bareme in salarie[cat].iteritems(): # print name, bareme # public etat # TODO: modifier la contribution exceptionelle de solidarité # en fixant son seuil de non imposition dans le barème (à corriger dans param.xml # et en tenant compte des éléments de l'assiette # salarie['fonc']['etat']['excep_solidarite'] = salarie['fonc']['commun']['solidarite'] public_titulaire_etat = salarie['public_titulaire_etat'].copy() public_titulaire_etat['rafp'].multiply_rates(TAUX_DE_PRIME, inplace = True) public_titulaire_etat = salarie['public_titulaire_etat'].combine_tax_scales() # public_titulaire_territoriale = salarie['public_titulaire_territoriale'].combine_tax_scales() # public_titulaire_hospitaliere = salarie['public_titulaire_hospitaliere'].combine_tax_scales() # public_non_titulaire = salarie['public_non_titulaire'].combine_tax_scales() # Pour a fonction publique la csg est calculée sur l'ensemble salbrut(=TIB) + primes # Imposable = TIB - csg( (1+taux_prime)*TIB ) - pension(TIB) + taux_prime*TIB bareme_csg_public_titulaire_etat = csg.multiply_rates( 1 + TAUX_DE_PRIME, inplace = False, new_name = "csg deduc titutaire etat") public_titulaire_etat.add_tax_scale(bareme_csg_public_titulaire_etat) bareme_prime = MarginalRateTaxScale(name = "taux de prime") bareme_prime.add_bracket(0, -TAUX_DE_PRIME) # barème équivalent à taux_prime*TIB public_titulaire_etat.add_tax_scale(bareme_prime) traitement_indiciaire_brut = ( (type_sal == CAT['public_titulaire_etat']) * public_titulaire_etat.inverse().calc(salaire_imposable_pour_inversion) ) # TODO: complete this to deal with the fonctionnaire # supp_familial_traitement = 0 # TODO: dépend de salbrut # indemnite_residence = 0 # TODO: fix bug return period, traitement_indiciaire_brut class primes_fonction_publique(Reform.Variable): column = columns.FloatCol entity_class = entities.Individus label = u"Primes de la fonction publique" reference = tax_benefit_system.column_by_name["primes_fonction_publique"] def function(self, simulation, period): """Calcule les primes. """ # Get value for year and divide below. traitement_indiciaire_brut = simulation.calculate('traitement_indiciaire_brut', period.start.offset('first-of', 'year').period('year')) return period, TAUX_DE_PRIME * traitement_indiciaire_brut return Reform()
def build_reform(tax_benefit_system): Reform = reforms.make_reform( key = 'allocations_familiales_imposables', name = u'Allocations familiales imposables', reference = tax_benefit_system, ) @Reform.formula class rbg(formulas.SimpleFormulaColumn): label = u"Nouveau revenu brut global intégrant les allocations familiales" reference = ir.rbg def function(self, simulation, period): period = period.start.offset('first-of', 'year').period('year') allocations_familiales_imposables = simulation.calculate_add('allocations_familiales_imposables', period) deficit_ante = simulation.calculate('deficit_ante', period) f6gh = simulation.calculate('f6gh', period) nacc_pvce_holder = simulation.calculate('nacc_pvce', period) nbic_impm_holder = simulation.calculate('nbic_impm', period) rev_cat = simulation.calculate('rev_cat', period) cga = simulation.legislation_at(period.start).ir.rpns.cga_taux2 nacc_pvce = self.sum_by_entity(nacc_pvce_holder) return period, max_( 0, allocations_familiales_imposables + rev_cat + f6gh + (self.sum_by_entity(nbic_impm_holder) + nacc_pvce) * (1 + cga) - deficit_ante ) @Reform.formula class rfr(formulas.SimpleFormulaColumn): label = u"Nouveau revenu fiscal de référence intégrant les allocations familiales" reference = ir.rfr def function(self, simulation, period): period = period.start.offset('first-of', 'year').period('year') allocations_familiales_imposables = simulation.calculate('allocations_familiales_imposables') f3va_holder = simulation.calculate('f3va') f3vi_holder = simulation.calculate('f3vi') f3vz = simulation.calculate('f3vz') rfr_cd = simulation.calculate('rfr_cd') rfr_rvcm = simulation.calculate('rfr_rvcm') rni = simulation.calculate('rni') rpns_exon_holder = simulation.calculate('rpns_exon') rpns_pvce_holder = simulation.calculate('rpns_pvce') rev_cap_lib = simulation.calculate_add('rev_cap_lib') microentreprise = simulation.calculate('microentreprise') f3va = self.sum_by_entity(f3va_holder) f3vi = self.sum_by_entity(f3vi_holder) rpns_exon = self.sum_by_entity(rpns_exon_holder) rpns_pvce = self.sum_by_entity(rpns_pvce_holder) return period, ( max_(0, rni - allocations_familiales_imposables) + rfr_cd + rfr_rvcm + rev_cap_lib + f3vi + rpns_exon + rpns_pvce + f3va + f3vz + microentreprise ) @Reform.formula class allocations_familiales_imposables(formulas.SimpleFormulaColumn): column = columns.FloatCol entity_class = entities.FoyersFiscaux label = u"Allocations familiales imposables" def function(self, simulation, period): period = period.start.offset('first-of', 'year').period('year') af_holder = simulation.calculate_add('af') imposition = simulation.legislation_at(period.start).allocations_familiales_imposables.imposition af = self.cast_from_entity_to_role(af_holder, entity= "famille", role = QUIFOY['vous']) af = self.sum_by_entity(af) return period, af * imposition reform = Reform() reform.modify_legislation_json(modifier_function = modify_legislation_json) return reform
def build_reform(tax_benefit_system): Reform = reforms.make_reform( decomposition_dir_name=os.path.dirname( os.path.abspath(decompositions.__file__)), decomposition_file_name='decomposition.xml', key='revenu_de_base_enfants', name=u"Revenu de base enfants", reference=tax_benefit_system, ) class nbptr(Variable): reference = tax_benefit_system.column_by_name['nbptr'] # On enlève les enfants du calcul du nbptr (quotient_familial.enf*) def function(self, simulation, period): ''' Nombre de parts du foyer 'foy' note 1 enfants et résidence alternée (formulaire 2041 GV page 10) quotient_familial.conj : nb part associées au conjoint d'un couple marié ou pacsé quotient_familial.enf1 : nb part 2 premiers enfants quotient_familial.enf2 : nb part enfants de rang 3 ou plus quotient_familial.inv1 : nb part supp enfants invalides (I, G) quotient_familial.inv2 : nb part supp adultes invalides (R) quotient_familial.not31 : nb part supp note 3 : cases W ou G pour veuf, celib ou div quotient_familial.not32 : nb part supp note 3 : personne seule ayant élevé des enfants quotient_familial.not41 : nb part supp adultes invalides (vous et/ou conjoint) note 4 quotient_familial.not42 : nb part supp adultes anciens combattants (vous et/ou conjoint) note 4 quotient_familial.not6 : nb part supp note 6 quotient_familial.isol : demi-part parent isolé (T) quotient_familial.edcd : enfant issu du mariage avec conjoint décédé; ''' period = period.start.offset('first-of', 'month').period('year') nb_pac = simulation.calculate('nb_pac', period) marpac = simulation.calculate('marpac', period) celdiv = simulation.calculate('celdiv', period) veuf = simulation.calculate('veuf', period) jveuf = simulation.calculate('jveuf', period) nbF = simulation.calculate('nbF', period) nbG = simulation.calculate('nbG', period) nbH = simulation.calculate('nbH', period) nbI = simulation.calculate('nbI', period) nbR = simulation.calculate('nbR', period) nbJ = simulation.calculate('nbJ', period) caseP = simulation.calculate('caseP', period) caseW = simulation.calculate('caseW', period) caseG = simulation.calculate('caseG', period) caseE = simulation.calculate('caseE', period) caseK = simulation.calculate('caseK', period) caseN = simulation.calculate('caseN', period) caseF = simulation.calculate('caseF', period) caseS = simulation.calculate('caseS', period) caseL = simulation.calculate('caseL', period) caseT = simulation.calculate('caseT', period) quotient_familial = simulation.legislation_at( period.start).ir.quotient_familial no_pac = nb_pac == 0 # Aucune personne à charge en garde exclusive has_pac = not_(no_pac) no_alt = nbH == 0 # Aucun enfant à charge en garde alternée has_alt = not_(no_alt) # # nombre de parts liées aux enfants à charge # que des enfants en résidence alternée # enf1 = (no_pac & has_alt) * (quotient_familial.enf1 * min_(nbH, 2) * 0.5 # + quotient_familial.enf2 * max_(nbH - 2, 0) * 0.5) # # pas que des enfants en résidence alternée # enf2 = (has_pac & has_alt) * ((nb_pac == 1) * (quotient_familial.enf1 * min_(nbH, 1) * 0.5 # + quotient_familial.enf2 * max_(nbH - 1, 0) * 0.5) + # (nb_pac > 1) * (quotient_familial.enf2 * nbH * 0.5)) # # pas d'enfant en résidence alternée # enf3 = quotient_familial.enf1 * min_(nb_pac, 2) + quotient_familial.enf2 * max_((nb_pac - 2), 0) # enf = enf1 + enf2 + enf3 # # note 2 : nombre de parts liées aux invalides (enfant + adulte) n2 = quotient_familial.inv1 * ( nbG + nbI / 2) + quotient_familial.inv2 * nbR # # note 3 : Pas de personne à charge # - invalide n31a = quotient_familial.not31a * (no_pac & no_alt & caseP) # - ancien combatant n31b = quotient_familial.not31b * (no_pac & no_alt & (caseW | caseG)) n31 = max_(n31a, n31b) # - personne seule ayant élevé des enfants n32 = quotient_familial.not32 * (no_pac & no_alt & ((caseE | caseK) & not_(caseN))) n3 = max_(n31, n32) # # note 4 Invalidité de la personne ou du conjoint pour les mariés ou # # jeunes veuf(ve)s n4 = max_(quotient_familial.not41 * (1 * caseP + 1 * caseF), quotient_familial.not42 * (caseW | caseS)) # # note 5 # - enfant du conjoint décédé n51 = quotient_familial.cdcd * (caseL & ((nbF + nbJ) > 0)) # - enfant autre et parent isolé n52 = quotient_familial.isol * caseT * (((no_pac & has_alt) * ( (nbH == 1) * 0.5 + (nbH >= 2))) + 1 * has_pac) n5 = max_(n51, n52) # # note 6 invalide avec personne à charge n6 = quotient_familial.not6 * (caseP & (has_pac | has_alt)) # # note 7 Parent isolé n7 = quotient_familial.isol * caseT * ((no_pac & has_alt) * ((nbH == 1) * 0.5 + (nbH >= 2)) + 1 * has_pac) # # Régime des mariés ou pacsés # m = 1 + quotient_familial.conj + enf + n2 + n4 m = 1 + quotient_familial.conj + n2 + n4 # # veufs hors jveuf # v = 1 + enf + n2 + n3 + n5 + n6 v = 1 + n2 + n3 + n5 + n6 # # celib div # c = 1 + enf + n2 + n3 + n6 + n7 c = 1 + n2 + n3 + n6 + n7 return period, (marpac | jveuf) * m + ( veuf & not_(jveuf)) * v + celdiv * c # Suppression des allocations familiales class af(Variable): reference = tax_benefit_system.column_by_name['af'] def function(self, simulation, period): period = period.start.offset('first-of', 'month').period('month') af_base = simulation.calculate('af_base', period) # af_majo = simulation.calculate('af_majo', period) # af_forf = simulation.calculate('af_forf', period) # return period, af_base + af_majo + af_forf return period, af_base * 0 # Suppression du complément familial class cf(Variable): reference = tax_benefit_system.column_by_name['cf'] def function(self, simulation, period): ''' L'allocation de base de la paje n'est pas cumulable avec le complément familial ''' period = period.start.offset('first-of', 'month').period('month') paje_base_montant = simulation.calculate('paje_base_montant', period) apje_temp = simulation.calculate('apje_temp', period) ape_temp = simulation.calculate('ape_temp', period) cf_montant = simulation.calculate('cf_montant', period) residence_mayotte = simulation.calculate('residence_mayotte', period) cf_brut = (paje_base_montant < cf_montant) * ( apje_temp <= cf_montant) * (ape_temp <= cf_montant) * cf_montant # return period, not_(residence_mayotte) * round(cf_brut, 2) return period, not_(residence_mayotte) * round(cf_brut, 2) * 0 # Suppression de l'allocation de rentrée scolaire class ars(Variable): reference = tax_benefit_system.column_by_name['ars'] def function(self, simulation, period): ''' Allocation de rentrée scolaire brute de CRDS ''' period = period.start.offset('first-of', 'month').period('month') # age_holder = simulation.compute('age', period) # af_nbenf = simulation.calculate('af_nbenf', period) # smic55_holder = simulation.compute('smic55', period) br_pf = simulation.calculate('br_pf', period) return period, br_pf * 0 # Suppression du nombre d'enfants dans le calcul du RSA socle class rsa_socle(Variable): reference = tax_benefit_system.column_by_name['rsa_socle'] def function(self, simulation, period): period = period.start.offset('first-of', 'month').period('month') age_holder = simulation.compute('age', period) # smic55_holder = simulation.compute('smic55', period) activite_holder = simulation.compute('activite', period) nb_par = simulation.calculate('nb_par', period) rmi = simulation.legislation_at(period.start).minim.rmi age_parents = self.split_by_roles(age_holder, roles=[CHEF, PART]) activite_parents = self.split_by_roles(activite_holder, roles=[CHEF, PART]) # age_enf = self.split_by_roles(age_holder, roles = ENFS) # smic55_enf = self.split_by_roles(smic55_holder, roles = ENFS) nbp = nb_par eligib = ((age_parents[CHEF] >= rmi.age_pac) * not_(activite_parents[CHEF] == 2)) | ( (age_parents[PART] >= rmi.age_pac) * not_(activite_parents[PART] == 2)) taux = (1 + (nbp >= 2) * rmi.txp2 + (nbp >= 3) * rmi.txp3 + (nbp >= 4) * ((nb_par == 1) * rmi.txps + (nb_par != 1) * rmi.txp3) + max_(nbp - 4, 0) * rmi.txps) return period, eligib * rmi.rmi * taux # Suppression du nombre d'enfants dans le calcul du RSA forfait logement class rmi_nbp(Variable): reference = tax_benefit_system.column_by_name['rmi_nbp'] def function(self, simulation, period): # period = period.start.offset('first-of', 'month').period('month') # age_holder = simulation.compute('age', period) # smic55_holder = simulation.compute('smic55', period) nb_par = simulation.calculate('nb_par', period) # P = simulation.legislation_at(period.start).minim.rmi # age = self.split_by_roles(age_holder, roles = ENFS) # smic55 = self.split_by_roles(smic55_holder, roles = ENFS) return period, nb_par # + nb_enf(age, smic55, 0, P.age_pac - 1) # Suppression de la cotisation patronale famille class famille(Variable): reference = tax_benefit_system.column_by_name['famille'] def function(self, simulation, period): period = period.start.period(u'month').offset('first-of') salaire_de_base = simulation.calculate('salaire_de_base', period) return period, salaire_de_base * 0 # Baisse de l'éxonération Fillon # TODO /!\ CHANGER LES PARAMÈTRES DE L'ÉXONÉRATION FILLON (-5,25%) # def taux_exo_fillon(ratio_smic_salaire, majoration, P): # ''' # Exonération Fillon # http://www.securite-sociale.fr/comprendre/dossiers/exocotisations/exoenvigueur/fillon.htm # ''' # # La divison par zéro engendre un warning # # Le montant maximum de l’allègement dépend de l’effectif de l’entreprise. # # Le montant est calculé chaque année civile, pour chaque salarié ; # # il est égal au produit de la totalité de la rémunération annuelle telle # # que visée à l’article L. 242-1 du code de la Sécurité sociale par un # # coefficient. # # Ce montant est majoré de 10 % pour les entreprises de travail temporaire # # au titre des salariés temporaires pour lesquels elle est tenue à # # l’obligation d’indemnisation compensatrice de congés payés. # # Pf = P.exo_bas_sal.fillon # seuil = Pf.seuil # tx_max = (Pf.tx_max * not_(majoration) + Pf.tx_max2 * majoration) - 0.0525 # if seuil <= 1: # return 0 # # règle d'arrondi: 4 décimales au dix-millième le plus proche # taux_fillon = round_(tx_max * min_(1, max_(seuil * ratio_smic_salaire - 1, 0) / (seuil - 1)), 4) # return taux_fillon # Création d'un revenu de base enfant - Version famille class rdb_enfant_famille(Variable): column = FloatCol entity_class = Familles label = u"Revenu de base enfant" def function(self, simulation, period): period = period.start.offset('first-of', 'month').period('month') age_holder = simulation.compute('age', period) P = simulation.legislation_at(period.start).fam.af bmaf = P.bmaf smic55_holder = simulation.compute('smic55', period) smic55 = self.split_by_roles(smic55_holder, roles=ENFS) age = self.split_by_roles(age_holder, roles=ENFS) smic5 = {role: array * 0 for role, array in smic55.iteritems()} nbenf_inf13 = nb_enf(age, smic5, 0, 13) nbenf_sup14 = nb_enf(age, smic5, 14, 18) return period, (nbenf_inf13 * 0.41 + nbenf_sup14 * 0.57) * bmaf # Les taux 0,41 et 0,16 (0,57-0,41) sont issus des allocations familiales # Création d'un revenu de base enfant - Version individus class rdb_enf(Variable): column = FloatCol entity_class = Individus label = u"Revenu de base enfant" def function(self, simulation, period): period = period.start.offset('first-of', 'month').period('month') age = simulation.calculate('age') P = simulation.legislation_at(period.start).fam.af bmaf = P.bmaf return period, ( (age < 14) * 0.41 + not_(age < 14) * 0.57) * bmaf * (age <= 18) # Création d'une CSG enfant class csgenf(Variable): column = FloatCol entity_class = Individus label = u"CSG enfant" def function(self, simulation, period): period = period.start.offset('first-of', 'month').period('month') revnet = simulation.calculate('revenu_net_individu', period) montant_csg = revnet * 0.025 return period, -montant_csg class csg(Variable): reference = tax_benefit_system.column_by_name['csg'] def function(self, simulation, period): """Contribution sociale généralisée""" period = period.start.offset('first-of', 'month').period('year') csg_imposable_salaire = simulation.calculate( 'csg_imposable_salaire', period) csgsald = simulation.calculate('csgsald', period) csgchoi = simulation.calculate('csgchoi', period) csgchod = simulation.calculate('csgchod', period) csgrsti = simulation.calculate('csgrsti', period) csgrstd = simulation.calculate('csgrstd', period) csg_fon_holder = simulation.compute('csg_fon', period) csg_cap_lib_declarant1 = simulation.calculate( 'csg_cap_lib_declarant1', period) csg_cap_bar_declarant1 = simulation.calculate( 'csg_cap_bar_declarant1', period) csg_pv_mo_holder = simulation.compute('csg_pv_mo', period) csg_pv_immo_holder = simulation.compute('csg_pv_immo', period) csgenfant = simulation.calculate('csgenf', period) csg_fon = self.cast_from_entity_to_role(csg_fon_holder, role=VOUS) csg_pv_immo = self.cast_from_entity_to_role(csg_pv_immo_holder, role=VOUS) csg_pv_mo = self.cast_from_entity_to_role(csg_pv_mo_holder, role=VOUS) return period, (csg_imposable_salaire + csgsald + csgchoi + csgchod + csgrsti + csgrstd + csg_fon + csg_cap_lib_declarant1 + csg_pv_mo + csg_pv_immo + csg_cap_bar_declarant1 + csgenfant) class revdisp(Variable): reference = tax_benefit_system.column_by_name['revdisp'] def function(self, simulation, period): ''' Revenu disponible - ménage 'men' ''' period = period.start.offset('first-of', 'month').period('year') rev_trav_holder = simulation.compute('rev_trav', period) pen_holder = simulation.compute('pen', period) rev_cap_holder = simulation.compute('rev_cap', period) psoc_holder = simulation.compute('psoc', period) ppe_holder = simulation.compute('ppe', period) impo = simulation.calculate('impo', period) rdb_enfant_holder = simulation.compute('rdb_enf', period) pen = self.sum_by_entity(pen_holder) ppe = self.cast_from_entity_to_role(ppe_holder, role=VOUS) ppe = self.sum_by_entity(ppe) psoc = self.cast_from_entity_to_role(psoc_holder, role=CHEF) psoc = self.sum_by_entity(psoc) rev_cap = self.sum_by_entity(rev_cap_holder) rev_trav = self.sum_by_entity(rev_trav_holder) rdb_enfant = self.sum_by_entity(rdb_enfant_holder) return period, rev_trav + pen + rev_cap + psoc + ppe + impo + rdb_enfant reform = Reform() reform.modify_legislation_json(modifier_function=modify_legislation_json) return reform
def build_reform(tax_benefit_system): Reform = reforms.make_reform( key = 'ayrault_muet', name = u'Amendement Ayrault-Muet au PLF2016', reference = tax_benefit_system, ) class variator(Reform.Variable): column = FloatCol(default = 1) entity_class = FoyersFiscaux label = u'Multiplicateur du seuil de régularisation' class reduction_csg(Reform.DatedVariable): column = FloatCol entity_class = Individus label = u"Réduction dégressive de CSG" @dated_function(start = date(2015, 1, 1)) def function_2015__(self, simulation, period): period = period.start.offset('first-of', 'year').period('year') smic_proratise = simulation.calculate_add('smic_proratise', period) assiette_csg_abattue = simulation.calculate_add('assiette_csg_abattue', period) seuil = 1.34 coefficient_correctif = .9 taux_csg = ( simulation.legislation_at(period.start).csg.activite.imposable.taux + simulation.legislation_at(period.start).csg.activite.deductible.taux ) tx_max = coefficient_correctif * taux_csg ratio_smic_salaire = smic_proratise / (assiette_csg_abattue + 1e-16) # règle d'arrondi: 4 décimales au dix-millième le plus proche taux_allegement_csg = tx_max * min_(1, max_(seuil - 1 / ratio_smic_salaire, 0) / (seuil - 1)) # Montant de l'allegment return period, taux_allegement_csg * assiette_csg_abattue class reduction_csg_foyer_fiscal(Reform.PersonToEntityColumn): entity_class = FoyersFiscaux label = u"Réduction dégressive de CSG des memebres du foyer fiscal" operation = 'add' variable = reduction_csg class reduction_csg_nette(Reform.DatedVariable): column = FloatCol entity_class = Individus label = u"Réduction dégressive de CSG" @dated_function(start = date(2015, 1, 1)) def function_2015__(self, simulation, period): period = period.start.offset('first-of', 'year').period('year') reduction_csg = simulation.calculate('reduction_csg', period) ppe_elig_bis_individu = simulation.calculate('ppe_elig_bis_individu', period) return period, reduction_csg * ppe_elig_bis_individu class ppe_elig_bis(Reform.Variable): column = BoolCol(default = False) entity_class = FoyersFiscaux label = u"ppe_elig_bis" def function(self, simulation, period): ''' PPE: eligibilité à la ppe, condition sur le revenu fiscal de référence 'foy' ''' period = period.start.offset('first-of', 'year').period('year') rfr = simulation.calculate('rfr', period) ppe_coef = simulation.calculate('ppe_coef', period) maries_ou_pacses = simulation.calculate('maries_ou_pacses', period) veuf = simulation.calculate('veuf', period) celibataire_ou_divorce = simulation.calculate('celibataire_ou_divorce', period) nbptr = simulation.calculate('nbptr', period) variator = simulation.calculate('variator', period) ppe = simulation.legislation_at(period.start).ir.credits_impot.ppe seuil = (veuf | celibataire_ou_divorce) * (ppe.eligi1 + 2 * max_(nbptr - 1, 0) * ppe.eligi3) \ + maries_ou_pacses * (ppe.eligi2 + 2 * max_(nbptr - 2, 0) * ppe.eligi3) return period, (rfr * ppe_coef) <= (seuil * variator) class ppe_elig_bis_individu(Reform.EntityToPersonColumn): entity_class = Individus variable = ppe_elig_bis class regularisation_reduction_csg(Reform.DatedVariable): column = FloatCol entity_class = FoyersFiscaux label = u"Régularisation complète réduction dégressive de CSG" @dated_function(start = date(2015, 1, 1)) def function_2015__(self, simulation, period): period = period.start.offset('first-of', 'year').period('year') reduction_csg = simulation.calculate('reduction_csg_foyer_fiscal', period) ppe_elig_bis = simulation.calculate('ppe_elig_bis', period) return period, not_(ppe_elig_bis) * (reduction_csg > 1) reform = Reform() reform.modify_legislation_json(modifier_function = ayrault_muet_modify_legislation_json) return reform
def build_reform(tax_benefit_system): from scipy.optimize import fsolve Reform = reforms.make_reform( key='inversion_revenus', name=u'Inversion des revenus', reference=tax_benefit_system, ) class salaire_imposable_pour_inversion(Reform.Variable): column = columns.FloatCol entity = entities.Individu label = u'Salaire imposable utilisé pour remonter au salaire brut' class chomage_imposable_pour_inversion(Reform.Variable): column = columns.FloatCol entity = entities.Individu label = u'Autres revenus imposables (chômage, préretraite), utilisé pour l’inversion' class retraite_imposable_pour_inversion(Reform.Variable): column = columns.FloatCol entity = entities.Individu label = u'Pensions, retraites, rentes connues imposables, utilisé pour l’inversion' class salaire_de_base(Reform.Variable): column = columns.FloatCol entity = entities.Individu label = u"Salaire brut ou traitement indiciaire brut" reference = tax_benefit_system.column_by_name["salaire_de_base"] url = u"http://www.trader-finance.fr/lexique-finance/definition-lettre-S/Salaire-brut.html" def function(self, simulation, period): """Calcule le salaire brut à partir du salaire imposable ou sinon du salaire net. Sauf pour les fonctionnaires où il renvoie le traitement indiciaire brut Note : le supplément familial de traitement est imposable. """ # period = period.this_month # Get value for year and divide below. salaire_imposable_pour_inversion = simulation.get_array( 'salaire_imposable_pour_inversion', period.this_year) if salaire_imposable_pour_inversion is None: salaire_net = simulation.get_array('salaire_net', period) if salaire_net is not None: # Calcule le salaire brut à partir du salaire net par inversion numérique. if (salaire_net == 0).all(): # Quick path to avoid fsolve when using default value of input variables. return period, salaire_net simulation = self.holder.entity.simulation def solve_function(salaire_de_base): return brut_to_target( target_name='salaire_net', period=period, salaire_de_base=salaire_de_base, simulation=simulation, ) - salaire_net return period, fsolve(solve_function, salaire_net) salaire_imposable_pour_inversion = simulation.calculate_add_divide( 'salaire_imposable_pour_inversion', period) # Calcule le salaire brut à partir du salaire imposable par inversion numérique. if (salaire_imposable_pour_inversion == 0).all(): # Quick path to avoid fsolve when using default value of input variables. return period, salaire_imposable_pour_inversion simulation = self.holder.entity.simulation def solve_function(salaire_de_base): return brut_to_target( target_name='salaire_imposable', period=period, salaire_de_base=salaire_de_base, simulation=simulation, ) - salaire_imposable_pour_inversion return period, fsolve(solve_function, salaire_imposable_pour_inversion) # TODO: inclure un taux de prime et calculer les primes en même temps que salaire_de_base # # Calcule le salaire brut à partir du salaire imposable. # # Sauf pour les fonctionnaires où il renvoie le traitement indiciaire brut # # Note : le supplément familial de traitement est imposable. # # hsup = simulation.calculate('hsup', period) # categorie_salarie = simulation.calculate('categorie_salarie', period) # P = simulation.legislation_at(period.start) # # plafond_securite_sociale = P.cotsoc.gen.plafond_securite_sociale # # salarie = P.cotsoc.sal.scale_tax_scales(plafond_securite_sociale) # csg = P.csg.scale_tax_scales(plafond_securite_sociale) # # salarie['noncadre'].update(salarie['commun']) # salarie['cadre'].update(salarie['commun']) # # # log.info( # # "Le dictionnaire des barèmes des cotisations salariés des titulaires de l'Etat contient : \n %s", # # salarie['fonc']["etat"], # # ) # # # Salariés du privé # # noncadre = salarie['noncadre'].combine_tax_scales() # cadre = salarie['cadre'].combine_tax_scales() # # # On ajoute la CSG deductible # noncadre.add_tax_scale(csg['activite']['deductible']) # cadre.add_tax_scale(csg['activite']['deductible']) # # nca = noncadre.inverse() # cad = cadre.inverse() # brut_nca = nca.calc(salaire_imposable_pour_inversion) # brut_cad = cad.calc(salaire_imposable_pour_inversion) # salbrut = brut_nca * (categorie_salarie == CATEGORIE_SALARIE['prive_non_cadre']) # salbrut += brut_cad * (categorie_salarie == CATEGORIE_SALARIE['prive_cadre']) # # # public etat # # TODO: modifier la contribution exceptionelle de solidarité # # en fixant son seuil de non imposition dans le barème (à corriger dans param.xml # # et en tenant compte des éléments de l'assiette # salarie['fonc']['etat']['excep_solidarite'] = salarie['fonc']['commun']['solidarite'] # # public_etat = salarie['fonc']['etat']['pension'] # # public_colloc = salarie['fonc']["colloc"].combine_tax_scales() TODO # # # Pour a fonction publique la csg est calculée sur l'ensemble salbrut(=TIB) + primes # # Imposable = TIB - csg( (1+taux_prime)*TIB ) - pension(TIB) + taux_prime*TIB # bareme_csg_titulaire_etat = csg['act']['deduc'].multiply_rates(1 + TAUX_DE_PRIME, inplace = False, # new_name = "csg deduc titutaire etat") # public_etat.add_tax_scale(bareme_csg_titulaire_etat) # bareme_prime = MarginalRateTaxScale(name = "taux de prime") # bareme_prime.add_bracket(0, -TAUX_DE_PRIME) # barème équivalent à taux_prime*TIB # public_etat.add_tax_scale(bareme_prime) # # etat = public_etat.inverse() # # # TODO: complete this to deal with the fonctionnaire # # supp_familial_traitement = 0 # TODO: dépend de salbrut # # indemnite_residence = 0 # TODO: fix bug # # # print 'salaire_imposable_pour_inversion', salaire_imposable_pour_inversion # brut_etat = etat.calc(salaire_imposable_pour_inversion) # # print 'brut_etat', brut_etat # # print 'impot', public_etat.calc(brut_etat) # # print 'brut_etat', brut_etat # salbrut_etat = (brut_etat) # # TODO: fonctionnaire # # print 'salbrut_etat', salbrut_etat # salbrut += salbrut_etat * (categorie_salarie == CATEGORIE_SALARIE['public_titulaire_etat']) # # #<NODE desc= "Supplément familial de traitement " shortname="Supp. fam." code= "supp_familial_traitement"/> # #<NODE desc= "Indemnité de résidence" shortname="Ind. rés." code= "indemenite_residence"/> # return period, salbrut + hsup class chomage_brut(Reform.Variable): column = columns.FloatCol entity = entities.Individu label = u"Allocations chômage brutes" url = u"http://vosdroits.service-public.fr/particuliers/N549.xhtml" def function(self, simulation, period): """"Calcule les allocations chômage brutes à partir des allocations imposables ou sinon des allocations nettes. """ # Get value for year and divide below. chomage_imposable_pour_inversion = simulation.get_array( 'chomage_imposable_pour_inversion', period.this_year) if chomage_imposable_pour_inversion is None: chomage_net = simulation.get_array('chomage_net', period) if chomage_net is not None: # Calcule les allocations chomage brutes à partir des allocations nettes par inversion numérique. if (chomage_net == 0).all(): # Quick path to avoid fsolve when using default value of input variables. return period, chomage_net simulation = self.holder.entity.simulation def solve_function(chomage_brut): return brut_to_target( chomage_brut=chomage_brut, target_name='chomage_net', period=period, simulation=simulation, ) - chomage_net return period, fsolve(solve_function, chomage_net) chomage_imposable_pour_inversion = simulation.calculate_add_divide( 'chomage_imposable_pour_inversion', period) # Calcule les allocations chômage brutes à partir des allocations imposables. # taux_csg_remplacement = simulation.calculate('taux_csg_remplacement', period) if (chomage_imposable_pour_inversion == 0).all(): # Quick path to avoid fsolve when using default value of input variables. return period, chomage_imposable_pour_inversion simulation = self.holder.entity.simulation def solve_function(chomage_brut): return brut_to_target( chomage_brut=chomage_brut, # taux_csg_remplacement = taux_csg_remplacement, target_name='chomage_imposable', period=period, simulation=simulation, ) - chomage_imposable_pour_inversion return period, fsolve(solve_function, chomage_imposable_pour_inversion) class retraite_brute(Reform.Variable): column = columns.FloatCol entity = entities.Individu label = u"Pensions de retraite brutes" url = u"http://vosdroits.service-public.fr/particuliers/N20166.xhtml" def function(self, simulation, period): """"Calcule les pensions de retraite brutes à partir des pensions imposables ou sinon des pensions nettes. """ # period = period.this_month # Get value for year and divide below. retraite_imposable_pour_inversion = simulation.get_array( 'retraite_imposable_pour_inversion', period.this_year) if retraite_imposable_pour_inversion is None: retraite_nette = simulation.get_array('retraite_nette', period) if retraite_nette is not None: # Calcule les pensions de retraite brutes à partir des pensions nettes par inversion numérique. if (retraite_nette == 0).all(): # Quick path to avoid fsolve when using default value of input variables. return period, retraite_nette simulation = self.holder.entity.simulation def solve_function(retraite_brute): return brut_to_target( target_name='retraite_nette', period=period, retraite_brute=retraite_brute, simulation=simulation, ) - retraite_nette return period, fsolve(solve_function, retraite_nette) retraite_imposable_pour_inversion = simulation.calculate_add_divide( 'retraite_imposable_pour_inversion', period) # Calcule les pensions de retraite brutes à partir des pensions imposables. taux_csg_remplacement = simulation.calculate( 'taux_csg_remplacement', period) if (retraite_imposable_pour_inversion == 0).all(): # Quick path to avoid fsolve when using default value of input variables. return period, retraite_imposable_pour_inversion simulation = self.holder.entity.simulation def solve_function(retraite_brute): return brut_to_target( retraite_brute=retraite_brute, taux_csg_remplacement=taux_csg_remplacement, target_name='retraite_imposable', period=period, simulation=simulation, ) - retraite_imposable_pour_inversion return period, fsolve(solve_function, retraite_imposable_pour_inversion) return Reform()
def build_reform(tax_benefit_system): Reform = reforms.make_reform( key = u'plfr2014', name = u'Projet de Loi de Finances Rectificative 2014', reference = tax_benefit_system, ) @Reform.formula class reduction_impot_exceptionnelle(formulas.SimpleFormulaColumn): column = columns.FloatCol entity_class = entities.FoyersFiscaux label = u"Réduction d'impôt exceptionnelle" def function(self, simulation, period): period = period.start.offset('first-of', 'year').period('year') nb_adult = simulation.calculate('nb_adult') nb_par = simulation.calculate('nb_par') rfr = simulation.calculate('rfr') params = simulation.legislation_at(period.start).plfr2014.reduction_impot_exceptionnelle plafond = params.seuil * nb_adult + (nb_par - nb_adult) * 2 * params.majoration_seuil montant = params.montant_plafond * nb_adult return period, min_(max_(plafond + montant - rfr, 0), montant) @Reform.formula class reductions(formulas.DatedFormulaColumn): label = u"Somme des réductions d'impôt à intégrer pour l'année 2013" reference = reductions_impot.reductions @dated_function(start = date(2013, 1, 1), stop = date(2013, 12, 31)) def function_20130101_20131231(self, simulation, period): period = period.start.offset('first-of', 'year').period('year') accult = simulation.calculate('accult') adhcga = simulation.calculate('adhcga') cappme = simulation.calculate('cappme') creaen = simulation.calculate('creaen') daepad = simulation.calculate('daepad') deffor = simulation.calculate('deffor') dfppce = simulation.calculate('dfppce') doment = simulation.calculate('doment') domlog = simulation.calculate('domlog') donapd = simulation.calculate('donapd') duflot = simulation.calculate('duflot') ecpess = simulation.calculate('ecpess') garext = simulation.calculate('garext') intagr = simulation.calculate('intagr') invfor = simulation.calculate('invfor') invlst = simulation.calculate('invlst') ip_net = simulation.calculate('ip_net') locmeu = simulation.calculate('locmeu') mecena = simulation.calculate('mecena') mohist = simulation.calculate('mohist') patnat = simulation.calculate('patnat') prcomp = simulation.calculate('prcomp') reduction_impot_exceptionnelle = simulation.calculate('reduction_impot_exceptionnelle') repsoc = simulation.calculate('repsoc') resimm = simulation.calculate('resimm') rsceha = simulation.calculate('rsceha') saldom = simulation.calculate('saldom') scelli = simulation.calculate('scelli') sofica = simulation.calculate('sofica') spfcpi = simulation.calculate('spfcpi') total_reductions = accult + adhcga + cappme + creaen + daepad + deffor + dfppce + doment + domlog + \ donapd + duflot + ecpess + garext + intagr + invfor + invlst + locmeu + mecena + mohist + patnat + \ prcomp + repsoc + resimm + rsceha + saldom + scelli + sofica + spfcpi + reduction_impot_exceptionnelle return period, min_(ip_net, total_reductions) reform = Reform() reform.modify_legislation_json(modifier_function = modify_legislation_json) return reform
def build_reform(tax_benefit_system): # Removing the formula starting in 2015-07-01 # TODO: improve because very dirty # may be by creating the following functions # get_formulas(entity, variable, period), set_formulas(entity, variable, period) Reform = reforms.make_reform( key = 'plaf_qf_2012_sans_modulation_af', name = u"Legislation du plafond qf de 2012 et des af sans modulations", reference = tax_benefit_system, ) # af_base = Reform.column_by_name['af_base'] # if len(af_base.formula_class.dated_formulas_class) > 1: # del af_base.formula_class.dated_formulas_class[1] # af_base.formula_class.dated_formulas_class[0]['stop_instant'] = None # class af_taux_modulation(formulas.DatedVariable): # column = columns.FloatCol # entity_class = Familles # label = u"Taux de modulation à appliquer au montant des AF depuis 2015" # # @dated_function(start = date(2002, 1, 1)) # def function_2002(self, simulation, period): # period = period.start.offset('first-of', 'month').period('month') # af_nbenf = simulation.calculate('af_nbenf', period) # return period, 1 + 0 * af_nbenf # Trick pour avoir la bonne longueur d'array numpy. #Todo trouver mieux # # @dated_function(start = date(9999, 7, 1)) # def function_2015(self, simulation, period): # period = period.start.offset('first-of', 'month').period('month') # af_nbenf = simulation.calculate('af_nbenf', period) # pfam = simulation.legislation_at(period.start).fam.af # br_pf = simulation.calculate('br_pf', period) # modulation = pfam.modulation # plafond1 = modulation.plafond1 + af_nbenf * modulation.enfant_supp # plafond2 = modulation.plafond2 + af_nbenf * modulation.enfant_supp # # taux = ( # (br_pf <= plafond1) * 1 + # (br_pf > plafond1) * (br_pf <= plafond2) * modulation.taux1 + # (br_pf > plafond2) * modulation.taux2 # ) # # return period, taux # # class af_complement_degressif(DatedVariable): # column = FloatCol # entity_class = Familles # label = u"AF - Complément dégressif en cas de dépassement du plafond" # # @dated_function(start = date(9999, 7, 1)) # def function_2015(self, simulation, period): # period = period.start.offset('first-of', 'month').period('month') # af_nbenf = simulation.calculate('af_nbenf', period) # br_pf = simulation.calculate('br_pf', period) # af_base = simulation.calculate('af_base', period) # af_majo = simulation.calculate('af_majo', period) # pfam = simulation.legislation_at(period.start).fam.af # modulation = pfam.modulation # plafond1 = modulation.plafond1 + af_nbenf * modulation.enfant_supp # plafond2 = modulation.plafond2 + af_nbenf * modulation.enfant_supp # # depassement_plafond1 = max_(0, br_pf - plafond1) # depassement_plafond2 = max_(0, br_pf - plafond2) # # depassement_mensuel = ( # (depassement_plafond2 == 0) * depassement_plafond1 + # (depassement_plafond2 > 0) * depassement_plafond2 # ) / 12 # # af = af_base + af_majo # return period, max_(0, af - depassement_mensuel) * (depassement_mensuel > 0) #################### #################### class af_taux_modulation(DatedVariable): column = FloatCol entity_class = Familles label = u"Taux de modulation à appliquer au montant des AF depuis 2015" @dated_function(start = date(2002, 1, 1)) def function_2002(self, simulation, period): period = period.start.offset('first-of', 'month').period('month') af_nbenf = simulation.calculate('af_nbenf', period) return period, 1 + 0 * af_nbenf # Trick pour avoir la bonne longueur d'array numpy. #Todo trouver mieux @dated_function(start = date(9999, 7, 1)) def function_2015(self, simulation, period): period = period.start.offset('first-of', 'month').period('month') af_nbenf = simulation.calculate('af_nbenf', period) pfam = simulation.legislation_at(period.start).fam.af br_pf = simulation.calculate('br_pf', period) modulation = pfam.modulation plafond1 = modulation.plafond1 + af_nbenf * modulation.enfant_supp plafond2 = modulation.plafond2 + af_nbenf * modulation.enfant_supp taux = ( (br_pf <= plafond1) * 1 + (br_pf > plafond1) * (br_pf <= plafond2) * modulation.taux1 + (br_pf > plafond2) * modulation.taux2 ) return period, taux class af_forf_taux_modulation(DatedVariable): column = FloatCol entity_class = Familles label = u"Taux de modulation à appliquer à l'allocation forfaitaire des AF depuis 2015" @dated_function(start = date(2002, 1, 1)) def function_2002(self, simulation, period): period = period.start.offset('first-of', 'month').period('month') af_nbenf = simulation.calculate('af_nbenf', period) return period, 1 + 0 * af_nbenf # Trick pour avoir la bonne longueur d'array numpy. #Todo trouver mieux @dated_function(start = date(9999, 7, 1)) def function_2015(self, simulation, period): period = period.start.offset('first-of', 'month').period('month') pfam = simulation.legislation_at(period.start).fam.af af_nbenf = simulation.calculate('af_nbenf', period) af_forf_nbenf = simulation.calculate('af_forf_nbenf', period) nb_enf_tot = af_nbenf + af_forf_nbenf br_pf = simulation.calculate('br_pf', period) modulation = pfam.modulation plafond1 = modulation.plafond1 + nb_enf_tot * modulation.enfant_supp plafond2 = modulation.plafond2 + nb_enf_tot * modulation.enfant_supp taux = ( (br_pf <= plafond1) * 1 + (br_pf > plafond1) * (br_pf <= plafond2) * modulation.taux1 + (br_pf > plafond2) * modulation.taux2 ) return period, taux class af_complement_degressif(DatedVariable): column = FloatCol entity_class = Familles label = u"AF - Complément dégressif en cas de dépassement du plafond" @dated_function(start = date(9999, 7, 1)) def function_2015(self, simulation, period): period = period.start.offset('first-of', 'month').period('month') af_nbenf = simulation.calculate('af_nbenf', period) br_pf = simulation.calculate('br_pf', period) af_base = simulation.calculate('af_base', period) af_majo = simulation.calculate('af_majo', period) pfam = simulation.legislation_at(period.start).fam.af modulation = pfam.modulation plafond1 = modulation.plafond1 + af_nbenf * modulation.enfant_supp plafond2 = modulation.plafond2 + af_nbenf * modulation.enfant_supp depassement_plafond1 = max_(0, br_pf - plafond1) depassement_plafond2 = max_(0, br_pf - plafond2) depassement_mensuel = ( (depassement_plafond2 == 0) * depassement_plafond1 + (depassement_plafond2 > 0) * depassement_plafond2 ) / 12 af = af_base + af_majo return period, max_(0, af - depassement_mensuel) * (depassement_mensuel > 0) class af_forf_complement_degressif(DatedVariable): column = FloatCol entity_class = Familles label = u"AF - Complément dégressif pour l'allocation forfaitaire en cas de dépassement du plafond" @dated_function(start = date(9999, 7, 1)) def function_2015(self, simulation, period): period = period.start.offset('first-of', 'month').period('month') af_nbenf = simulation.calculate('af_nbenf', period) af_forf_nbenf = simulation.calculate('af_forf_nbenf', period) pfam = simulation.legislation_at(period.start).fam.af nb_enf_tot = af_nbenf + af_forf_nbenf br_pf = simulation.calculate('br_pf', period) af_forf = simulation.calculate('af_forf', period) modulation = pfam.modulation plafond1 = modulation.plafond1 + nb_enf_tot * modulation.enfant_supp plafond2 = modulation.plafond2 + nb_enf_tot * modulation.enfant_supp depassement_plafond1 = max_(0, br_pf - plafond1) depassement_plafond2 = max_(0, br_pf - plafond2) depassement_mensuel = ( (depassement_plafond2 == 0) * depassement_plafond1 + (depassement_plafond2 > 0) * depassement_plafond2 ) / 12 return period, max_(0, af_forf - depassement_mensuel) * (depassement_mensuel > 0) af_forf + af_complement_degressif + af_forf_complement_degressif reform = Reform() reform.modify_legislation_json(modifier_function = modify_legislation_json) return reform
def build_reform(tax_benefit_system): Reform = reforms.make_reform( key = 'aides_ville_paris', name = u'Aides de la ville de Paris', reference = tax_benefit_system, ) class parisien(Reform.Variable): column = columns.BoolCol entity_class = entities.Menages label = u"Résidant à Paris au moins 3 ans dans les 5 dernières années" class a_charge_fiscale(Reform.Variable): column = columns.BoolCol entity_class = entities.Individus label = u"Enfant à charge fiscale du demandeur" class enfant_place(Reform.Variable): column = columns.BoolCol entity_class = entities.Individus label = u"Enfant placé en structure spécialisée ou famille d'accueil" class paris_logement_familles_elig(Reform.Variable): column = columns.BoolCol label = u"Eligibilité à Paris-Logement-Familles" entity_class = entities.Familles def function(self, simulation, period): parisien = simulation.calculate('parisien', period) statut_occupation_logement = simulation.calculate('statut_occupation_logement', period) charge_logement = ( (statut_occupation_logement == 1) + (statut_occupation_logement == 2) + (statut_occupation_logement == 3) + (statut_occupation_logement == 4) + (statut_occupation_logement == 5) + (statut_occupation_logement == 7) ) result = parisien * charge_logement return period, result class paris_logement_familles_br_i(Reform.Variable): column = columns.FloatCol label = u"Base de ressources individuelle pour Paris Logement Famille" entity_class = entities.Individus def function(self, simulation, period): period = period.this_month last_year = period.last_year salaire_net = simulation.calculate('salaire_net', period) chomage_net = simulation.calculate('chomage_net', period) retraite_nette = simulation.calculate('retraite_nette', period) pensions_alimentaires_percues = simulation.calculate('pensions_alimentaires_percues', period) pensions_alimentaires_versees_individu = simulation.calculate( 'pensions_alimentaires_versees_individu', period) rsa_base_ressources_patrimoine_i = simulation.calculate_add('rsa_base_ressources_patrimoine_individu', period) indemnites_journalieres_imposables = simulation.calculate('indemnites_journalieres_imposables', period) indemnites_stage = simulation.calculate('indemnites_stage', period) revenus_stage_formation_pro = simulation.calculate('revenus_stage_formation_pro', period) allocation_securisation_professionnelle = simulation.calculate( 'allocation_securisation_professionnelle', period) prestation_compensatoire = simulation.calculate('prestation_compensatoire', period) pensions_invalidite = simulation.calculate('pensions_invalidite', period) indemnites_chomage_partiel = simulation.calculate('indemnites_chomage_partiel', period) bourse_recherche = simulation.calculate('bourse_recherche', period) gains_exceptionnels = simulation.calculate('gains_exceptionnels', period) def revenus_tns(): revenus_auto_entrepreneur = simulation.calculate_add('tns_auto_entrepreneur_benefice', period) # Les revenus TNS hors AE sont estimés en se basant sur le revenu N-1 tns_micro_entreprise_benefice = simulation.calculate('tns_micro_entreprise_benefice', last_year) / 12 tns_benefice_exploitant_agricole = simulation.calculate('tns_benefice_exploitant_agricole', last_year) / 12 tns_autres_revenus = simulation.calculate('tns_autres_revenus', last_year) / 12 return revenus_auto_entrepreneur + tns_micro_entreprise_benefice + tns_benefice_exploitant_agricole + tns_autres_revenus result = ( salaire_net + indemnites_chomage_partiel + indemnites_stage + chomage_net + retraite_nette + pensions_alimentaires_percues - abs_(pensions_alimentaires_versees_individu) + rsa_base_ressources_patrimoine_i + allocation_securisation_professionnelle + indemnites_journalieres_imposables + prestation_compensatoire + pensions_invalidite + bourse_recherche + gains_exceptionnels + revenus_tns() + revenus_stage_formation_pro ) return period, result class paris_logement_familles_br(Reform.Variable): column = columns.FloatCol label = u"Base de ressource pour Paris Logement Famille" entity_class = entities.Familles def function(self, simulation, period): period = period.this_month paris_logement_familles_br_i_holder = simulation.compute('paris_logement_familles_br_i', period) paris_logement_familles_br = self.sum_by_entity(paris_logement_familles_br_i_holder) result = paris_logement_familles_br return period, result class plf_enfant_handicape(Reform.Variable): column = columns.BoolCol label = u"Enfant handicapé au sens de la mairie de Paris" entity_class = entities.Individus def function(self, simulation, period): period = period.this_month handicap = simulation.calculate('handicap', period) plf_enfant = simulation.calculate('plf_enfant', period) return period, plf_enfant * handicap class plf_enfant(Reform.Variable): column = columns.BoolCol label = u"Enfant pris en compte par la mairie de Paris pour PLF" entity_class = entities.Individus def function(self, simulation, period): period = period.this_month est_enfant_dans_famille = simulation.calculate('est_enfant_dans_famille', period) enfant_place = simulation.calculate('enfant_place', period) a_charge_fiscale = simulation.calculate('a_charge_fiscale', period) return period, est_enfant_dans_famille * (1 - enfant_place) * a_charge_fiscale class plf_enfant_garde_alternee(Reform.Variable): column = columns.BoolCol label = u"Enfant en garde alternée pris en compte par la mairie de Paris pour PLF" entity_class = entities.Individus def function(self, simulation, period): period = period.this_month garde_alternee = simulation.calculate('garde_alternee', period) plf_enfant = simulation.calculate('plf_enfant', period) return period, garde_alternee * plf_enfant class plf_enfant_handicape_garde_alternee(Reform.Variable): column = columns.BoolCol label = u"Enfant handicapé en garde alternée pris en compte par la mairie de Paris pour PLF" entity_class = entities.Individus def function(self, simulation, period): period = period.this_month garde_alternee = simulation.calculate('garde_alternee', period) plf_enfant_handicape = simulation.calculate('plf_enfant_handicape', period) return period, garde_alternee * plf_enfant_handicape class plf_handicap(Reform.Variable): column = columns.FloatCol entity_class = entities.Familles label = u"Allocation Paris-Logement-Familles en cas d'enfant handicapé" def function(self, simulation, period): period = period.this_month plf_enfant_handicape = simulation.compute('plf_enfant_handicape', period) plf_enfant_handicape_garde_alternee = simulation.compute('plf_enfant_handicape_garde_alternee', period) br = simulation.calculate('paris_logement_familles_br', period) nb_enf_handicape = self.sum_by_entity(plf_enfant_handicape) nb_enf_handicape_garde_alternee = self.sum_by_entity(plf_enfant_handicape_garde_alternee) P = simulation.legislation_at(period.start).aides_locales.paris.paris_logement_familles plafond = P.plafond_haut_3enf montant = P.montant_haut_3enf plf_handicap = (nb_enf_handicape > 0) * (br <= plafond) * montant # Si tous les enfants handicapés sont en garde alternée garde_alternee = nb_enf_handicape - nb_enf_handicape_garde_alternee == 0 deduction_garde_alternee = garde_alternee * 0.5 * plf_handicap plf_handicap = plf_handicap - deduction_garde_alternee return period, plf_handicap class paris_logement_familles(Reform.Variable): column = columns.FloatCol label = u"Allocation Paris Logement Familles" entity_class = entities.Familles url = "http://www.paris.fr/pratique/toutes-les-aides-et-allocations/aides-sociales/paris-logement-familles-prestation-ville-de-paris/rub_9737_stand_88805_port_24193" # noqa def function(self, simulation, period): period = period.this_month elig = simulation.calculate('paris_logement_familles_elig', period) br = simulation.calculate('paris_logement_familles_br', period) plf_enfant = simulation.compute('plf_enfant', period) nbenf = self.sum_by_entity(plf_enfant) plf_enfant_garde_alternee = simulation.compute('plf_enfant_garde_alternee', period) nbenf_garde_alternee = self.sum_by_entity(plf_enfant_garde_alternee) plf_handicap = simulation.calculate('plf_handicap', period) loyer = simulation.calculate('loyer', period) + simulation.calculate('charges_locatives', period) P = simulation.legislation_at(period.start).aides_locales.paris.paris_logement_familles ressources_sous_plaf_bas = (br <= P.plafond_bas_3enf) ressources_sous_plaf_haut = (br <= P.plafond_haut_3enf) * (br > P.plafond_bas_3enf) montant_base_3enfs = (nbenf >= 3) * ( ressources_sous_plaf_bas * P.montant_haut_3enf + ressources_sous_plaf_haut * P.montant_bas_3enf ) montant_enf_sup = ( ressources_sous_plaf_bas * P.montant_haut_enf_sup + ressources_sous_plaf_haut * P.montant_bas_enf_sup ) montant_3enfs = montant_base_3enfs + montant_enf_sup * max_(nbenf - 3, 0) montant_2enfs = (nbenf == 2) * (br <= P.plafond_2enf) * P.montant_2enf plf = montant_2enfs + montant_3enfs deduction_garde_alternee = (nbenf_garde_alternee > 0) * ( (nbenf - nbenf_garde_alternee < 3) * 0.5 * plf + (nbenf - nbenf_garde_alternee >= 3) * nbenf_garde_alternee * 0.5 * montant_enf_sup ) plf = plf - deduction_garde_alternee plf = max_(plf, plf_handicap) plf = elig * plf plf = min_(plf, loyer) return period, plf reform = Reform() reform.modify_legislation_json(modifier_function = modify_legislation_json) return reform
def build_reform(tax_benefit_system): reference_legislation_json = tax_benefit_system.legislation_json reform_legislation_json = copy.deepcopy(reference_legislation_json) reform_year = 2007 reform_period = periods.period('year', reform_year) def update_threshold_bracket(bracket, amount): return reforms.update_legislation( legislation_json=reform_legislation_json, path=('children', 'ir', 'children', 'bareme', 'brackets', bracket, 'threshold'), period=reform_period, value=amount, ) def update_rate_bracket(bracket, rate): return reforms.update_legislation( legislation_json=reform_legislation_json, path=('children', 'ir', 'children', 'bareme', 'brackets', bracket, 'rate'), period=reform_period, value=rate, ) reform_legislation_json = update_rate_bracket(bracket=0, rate=0) reform_legislation_json = update_rate_bracket(bracket=1, rate=.0683) reform_legislation_json = update_rate_bracket(bracket=2, rate=.1914) reform_legislation_json = update_rate_bracket(bracket=3, rate=.2826) reform_legislation_json = update_rate_bracket(bracket=4, rate=.3738) reform_legislation_json = update_rate_bracket(bracket=5, rate=.4262) reform_legislation_json = update_rate_bracket(bracket=6, rate=.4809) inflation = 1 reform_legislation_json = update_threshold_bracket(bracket=0, amount=0) reform_legislation_json = update_threshold_bracket(bracket=1, amount=4412 * inflation) reform_legislation_json = update_threshold_bracket(bracket=2, amount=8677 * inflation) reform_legislation_json = update_threshold_bracket(bracket=3, amount=15274 * inflation) reform_legislation_json = update_threshold_bracket(bracket=4, amount=24731 * inflation) reform_legislation_json = update_threshold_bracket(bracket=5, amount=40241 * inflation) reform_legislation_json = update_threshold_bracket(bracket=6, amount=49624 * inflation) reform_legislation_json = reforms.update_legislation( legislation_json=reform_legislation_json, path=('children', 'ir', 'children', 'tspr', 'children', 'sabatsalpen'), period=reform_period, value=0, ) Reform = reforms.make_reform( legislation_json=reform_legislation_json, name=u'ir_2006', new_formulas=(), reference=tax_benefit_system, ) return Reform()