Skip to content

Commit

Permalink
Pour les aides RSA et PPA décalage de la période de référence d'un mo…
Browse files Browse the repository at this point in the history
…is (#2337)
  • Loading branch information
Martin-Billard-iMSA authored Sep 16, 2024
2 parents fba1e6b + c759a36 commit d5c0136
Show file tree
Hide file tree
Showing 6 changed files with 338 additions and 107 deletions.
18 changes: 14 additions & 4 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,22 +1,32 @@
# Changelog

## 168.0.16 [2337](https://github.com/openfisca/openfisca-france/pull/2337)

* Évolution du système socio-fiscal.
* Périodes concernées : À partir du 2024/10/01.
* Zones impactées :
- `openfisca_france/model/prestations/minima_sociaux/ppa.py.`
- `openfisca_france/model/prestations/minima_sociaux/rsa.py.`
* Détails :
- Modification de la période de référence pour les aides RSA et PPA
- Refactoring du code de ces méthodes pour éviter la duplication de code

## 168.0.15 [2348](https://github.com/openfisca/openfisca-france/pull/2349)

* Évolution du système socio-fiscal changement mineur.
* Périodes concernées : 01/01/2023.
* Périodes concernées : 01/01/2023.
* Zones impactées : `openfisca_france/parameters/impot_revenu/bareme_ir_depuis_1945/bareme.yaml`.
* Détails : Ajoute référence 2024 article codifié impôt sur le revenu

## 168.0.14 [2348](https://github.com/openfisca/openfisca-france/pull/2348)

* Changement mineur : Modification d'un label
* Périodes concernées : toutes.
* Périodes concernées : toutes.
* Zones impactées : `openfisca_france/model/revenus/activite/salarie.py`.
* Détails : La variable `contrat_de_travail` et la variable `contrat_de_travail_type` ont le même label, pourtant elles ne représentent pas la même chose. La première concerne les types de durées de travail du contrat (Temps plein, partiel, convention, etc.) ; la seconde, le type de contrat (CDD,CDI). Cette PR change le label de la première et propose de parler de "Type de durée de travail" pour les distinguer.

[Service-Public.fr](https://www.service-public.fr/particuliers/vosdroits/F19261) en parle aussi sous cette forme.


## 168.0.13 [2344](https://github.com/openfisca/openfisca-france/pull/2344)

* Évolution du système socio-fiscal. | Amélioration technique. Ces changements modifient l'API publique d'OpenFisca France et ajoutent une fonctionnalité : la possibilité de modifier des paramètres actuellement en dur dans les formules.
Expand Down
27 changes: 19 additions & 8 deletions openfisca_france/model/prestations/minima_sociaux/ppa.py
Original file line number Diff line number Diff line change
Expand Up @@ -502,15 +502,11 @@ class ppa(Variable):
# Prime pour l'Activité sur service-public.fr
reference = 'https://www.service-public.fr/particuliers/vosdroits/F2882'

def formula_2016_01_01(famille, period, parameters):
seuil_non_versement = parameters(period).prestations_sociales.solidarite_insertion.minima_sociaux.ppa.pa_m.montant_minimum_verse
# éligibilité étudiants

ppa_eligibilite_etudiants = famille('ppa_eligibilite_etudiants', period)
ppa = famille('ppa_fictive', period.last_3_months, options = [ADD]) / 3
ppa = ppa * ppa_eligibilite_etudiants * (ppa >= seuil_non_versement)
def formula_2024_10(famille, period, parameters):
return ppa_base_formula(famille=famille, parameters=parameters, period=period, three_months_of_reference=last_3_months_offset_minus_1(period))

return ppa
def formula_2016_01_01(famille, period, parameters):
return ppa_base_formula(famille=famille, parameters=parameters, period=period, three_months_of_reference=period.last_3_months)


class crds_ppa(Variable):
Expand Down Expand Up @@ -576,3 +572,18 @@ def formula(famille, period, parameters):
+ famille('ppa', period.last_month) * (remainder == 1)
+ famille('ppa', period.last_month.last_month) * (remainder == 2)
)


def last_3_months_offset_minus_1(period) -> Period:
return period.last_month.last_3_months


def ppa_base_formula(famille, parameters, period, three_months_of_reference):
seuil_non_versement = parameters(period).prestations_sociales.solidarite_insertion.minima_sociaux.ppa.pa_m.montant_minimum_verse
# éligibilité étudiants

ppa_eligibilite_etudiants = famille('ppa_eligibilite_etudiants', period)
ppa = famille('ppa_fictive', three_months_of_reference, options = [ADD]) / 3
ppa = ppa * ppa_eligibilite_etudiants * (ppa >= seuil_non_versement)

return ppa
238 changes: 144 additions & 94 deletions openfisca_france/model/prestations/minima_sociaux/rsa.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
from numpy import datetime64, logical_and as and_, logical_or as or_

from openfisca_core.periods import Period

from openfisca_france.model.base import *
from openfisca_france.model.prestations.prestations_familiales.base_ressource import nb_enf

Expand Down Expand Up @@ -79,58 +78,11 @@ class rsa_base_ressources_individu(Variable):
set_input = set_input_divide_by_period
reference = 'https://www.legifrance.gouv.fr/affichCodeArticle.do?cidTexte=LEGITEXT000006073189&idArticle=LEGIARTI000036393176&dateTexte=&categorieLien=id'

def formula_2009_06_01(individu, period, parameters):
# Revenus professionels
types_revenus_pros = [
'chomage_net',
'retraite_nette',
]

possede_ressources_substitution = individu('rsa_has_ressources_substitution', period)

# Les revenus pros interrompus au mois M sont neutralisés s'il n'y a pas de revenus de substitution.
revenus_pro = sum(
individu(type_revenu, period.last_3_months, options = [ADD]) * not_(
(individu(type_revenu, period) == 0)
* (individu(type_revenu, period.last_month) > 0)
* not_(possede_ressources_substitution)
)
for type_revenu in types_revenus_pros
)

types_revenus_non_pros = [
'allocation_securisation_professionnelle',
'dedommagement_victime_amiante',
'gains_exceptionnels',
'pensions_alimentaires_percues',
'pensions_invalidite',
'prestation_compensatoire',
'prime_forfaitaire_mensuelle_reprise_activite',
'rsa_base_ressources_patrimoine_individu',
'rsa_indemnites_journalieres_hors_activite',
]

# Les revenus non-pro interrompus au mois M sont neutralisés dans la limite d'un montant forfaitaire,
# sans condition de revenu de substitution.
montant_de_base_du_rsa = parameters(period).prestations_sociales.solidarite_insertion.minima_sociaux.rsa.rsa_m.montant_de_base_du_rsa
montant_forfaitaire_neutralisation = 3 * montant_de_base_du_rsa
revenus_non_pros = sum(
max_(
0,
individu(type_revenu, period.last_3_months, options = [ADD])
- (
montant_forfaitaire_neutralisation
* (individu(type_revenu, period) == 0)
* (individu(type_revenu, period.last_month) > 0)
)
)
for type_revenu in types_revenus_non_pros
)

rentes_viageres = individu.foyer_fiscal('rente_viagere_titre_onereux', period.last_3_months, options = [ADD])
revenus_foyer_fiscal_projetes = rentes_viageres * individu.has_role(FoyerFiscal.DECLARANT_PRINCIPAL)
def formula_2024_10(individu, period, parameters):
return rsa_base_ressources_individu_base_formula(individu= individu, period= period, three_months_of_reference= last_3_months_offset_minus_1(period), parameters=parameters)

return (revenus_pro + revenus_non_pros + revenus_foyer_fiscal_projetes) / 3
def formula_2009_06_01(individu, period, parameters):
return rsa_base_ressources_individu_base_formula(individu= individu, period= period, three_months_of_reference= period.last_3_months, parameters=parameters)

def formula(individu, period, parameters):
# Revenus professionels
Expand Down Expand Up @@ -193,15 +145,13 @@ class rsa_base_ressources_minima_sociaux(Variable):
definition_period = MONTH
set_input = set_input_divide_by_period

def formula_2024_10(famille, period):
three_months_of_reference = last_3_months_offset_minus_1(period)
return calcul_minima_sociaux(famille= famille, period= period, three_months_of_reference=three_months_of_reference)

def formula(famille, period):
three_previous_months = period.last_3_months
aspa = famille('aspa', period)

ass_i = famille.members('ass', three_previous_months, options = [ADD])
aah_i = famille.members('aah', three_previous_months, options = [ADD])
asi_i = famille.members('asi', three_previous_months, options = [ADD])
caah_i = famille.members('caah', three_previous_months, options = [ADD])
return aspa + famille.sum(ass_i + aah_i + asi_i + caah_i) / 3
return calcul_minima_sociaux(famille= famille, period= period, three_months_of_reference=three_previous_months)


class rsa_base_ressources_prestations_familiales(Variable):
Expand Down Expand Up @@ -527,43 +477,13 @@ class rsa_revenu_activite_individu(Variable):
definition_period = MONTH
set_input = set_input_divide_by_period

def formula_2024_10(individu, period):
period_m2_m4 = last_3_months_offset_minus_1(period)
return rsa_revenu_activite_individu_base_formula(individu= individu, period=period, three_months_of_reference=period_m2_m4)

def formula_2009_06(individu, period):
last_3_months = period.last_3_months

# Note Auto-entrepreneurs:
# D'après les caisses, le revenu pris en compte pour les AE pour le RSA ne prend en compte que
# l'abattement standard sur le CA, mais pas les cotisations pour charges sociales.

types_revenus_activite = [
'salaire_net',
'indemnites_chomage_partiel',
'remuneration_apprenti',
'indemnites_volontariat',
'revenus_stage_formation_pro',
'bourse_recherche',
'hsup',
'etr',
'rpns_auto_entrepreneur_benefice',
'rsa_indemnites_journalieres_activite',
]

possede_ressource_substitution = individu('rsa_has_ressources_substitution', period)

# Les revenus pros interrompus au mois M sont neutralisés s'il n'y a pas de revenus de substitution.
revenus_moyennes = sum(
individu(type_revenu, last_3_months, options = [ADD]) * not_(
(individu(type_revenu, period) == 0)
* (individu(type_revenu, period.last_month) > 0)
* not_(possede_ressource_substitution)
)
for type_revenu in types_revenus_activite
) / 3

revenus_tns_annualises = 0
if period.start.date >= date(2017, 1, 1):
revenus_tns_annualises = individu('ppa_rsa_derniers_revenus_tns_annuels_connus', period.this_year)

return revenus_moyennes + revenus_tns_annualises
return rsa_revenu_activite_individu_base_formula(individu= individu, period=period, three_months_of_reference=last_3_months)


class rsa_montant(Variable):
Expand Down Expand Up @@ -1043,3 +963,133 @@ def formula_2009_06_01(famille, period, parameters):
socle = rsa.rsa_m.montant_de_base_du_rsa

return eligib * socle * taux


def last_3_months_offset_minus_1(period) -> Period:
return period.last_month.last_3_months


def rsa_revenu_activite_individu_base_formula(individu, period, three_months_of_reference):
revenus_moyennes = calcul_revenu_moyenne(individu= individu, period=period, three_months_of_reference=three_months_of_reference)
revenus_tns_annualises = calcul_revenu_tns_annualises(individu=individu, period=period)

return revenus_moyennes + revenus_tns_annualises


def rsa_base_ressources_individu_base_formula(individu, period, three_months_of_reference, parameters):
revenus_pro = calcul_revenu_pro(individu=individu, period= period, three_months_of_reference= three_months_of_reference)
revenus_non_pros = calcul_revenu_non_pro(individu=individu, period= period, three_months_of_reference= three_months_of_reference, parameters= parameters)
revenus_foyer_fiscal_projetes = calcul_foyer_fiscal_projetes(individu=individu, three_months_of_reference= three_months_of_reference)

return (revenus_pro + revenus_non_pros + revenus_foyer_fiscal_projetes) / 3


def calcul_revenu_pro(individu, period, three_months_of_reference):
# Revenus professionels
types_revenus_pros = [
'chomage_net',
'retraite_nette',
]

possede_ressources_substitution = individu('rsa_has_ressources_substitution', period)

# Les revenus pros interrompus au mois M sont neutralisés s'il n'y a pas de revenus de substitution.
revenus_pro = sum(
individu(type_revenu, three_months_of_reference, options = [ADD]) * not_(
(individu(type_revenu, period) == 0)
* (individu(type_revenu, period.last_month) > 0)
* not_(possede_ressources_substitution)
)
for type_revenu in types_revenus_pros
)

return revenus_pro


def calcul_revenu_non_pro(individu, period, three_months_of_reference, parameters):
types_revenus_non_pros = [
'allocation_securisation_professionnelle',
'dedommagement_victime_amiante',
'gains_exceptionnels',
'pensions_alimentaires_percues',
'pensions_invalidite',
'prestation_compensatoire',
'prime_forfaitaire_mensuelle_reprise_activite',
'rsa_base_ressources_patrimoine_individu',
'rsa_indemnites_journalieres_hors_activite',
]

# Les revenus non-pro interrompus au mois M sont neutralisés dans la limite d'un montant forfaitaire,
# sans condition de revenu de substitution.
montant_de_base_du_rsa = parameters(period).prestations_sociales.solidarite_insertion.minima_sociaux.rsa.rsa_m.montant_de_base_du_rsa
montant_forfaitaire_neutralisation = 3 * montant_de_base_du_rsa
revenus_non_pros = sum(
max_(
0,
individu(type_revenu, three_months_of_reference, options = [ADD])
- (
montant_forfaitaire_neutralisation
* (individu(type_revenu, period) == 0)
* (individu(type_revenu, period.last_month) > 0)
)
)
for type_revenu in types_revenus_non_pros
)

return revenus_non_pros


def calcul_foyer_fiscal_projetes(individu, three_months_of_reference):
rentes_viageres = individu.foyer_fiscal('rente_viagere_titre_onereux', three_months_of_reference, options = [ADD])
revenus_foyer_fiscal_projetes = rentes_viageres * individu.has_role(FoyerFiscal.DECLARANT_PRINCIPAL)
return revenus_foyer_fiscal_projetes


def calcul_revenu_moyenne(individu, period, three_months_of_reference):
# Note Auto-entrepreneurs:
# D'après les caisses, le revenu pris en compte pour les AE pour le RSA ne prend en compte que
# l'abattement standard sur le CA, mais pas les cotisations pour charges sociales.

types_revenus_activite = [
'salaire_net',
'indemnites_chomage_partiel',
'remuneration_apprenti',
'indemnites_volontariat',
'revenus_stage_formation_pro',
'bourse_recherche',
'hsup',
'etr',
'rpns_auto_entrepreneur_benefice',
'rsa_indemnites_journalieres_activite',
]

possede_ressource_substitution = individu('rsa_has_ressources_substitution', period)

# Les revenus pros interrompus au mois M sont neutralisés s'il n'y a pas de revenus de substitution.
revenus_moyennes = sum(
individu(type_revenu, three_months_of_reference, options = [ADD]) * not_(
(individu(type_revenu, period) == 0)
* (individu(type_revenu, period.last_month) > 0)
* not_(possede_ressource_substitution)
)
for type_revenu in types_revenus_activite
) / 3

return revenus_moyennes


def calcul_revenu_tns_annualises(individu, period):
revenus_tns_annualises = 0
if period.start.date >= date(2017, 1, 1):
revenus_tns_annualises = individu('ppa_rsa_derniers_revenus_tns_annuels_connus', period.this_year)
return revenus_tns_annualises


def calcul_minima_sociaux(famille, period, three_months_of_reference):
aspa = famille('aspa', period)

ass_i = famille.members('ass', three_months_of_reference, options = [ADD])
aah_i = famille.members('aah', three_months_of_reference, options = [ADD])
asi_i = famille.members('asi', three_months_of_reference, options = [ADD])
caah_i = famille.members('caah', three_months_of_reference, options = [ADD])
return aspa + famille.sum(ass_i + aah_i + asi_i + caah_i) / 3
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@

setup(
name = 'OpenFisca-France',
version = '168.0.15',
version = '168.0.16',
author = 'OpenFisca Team',
author_email = '[email protected]',
classifiers = [
Expand Down
Loading

0 comments on commit d5c0136

Please sign in to comment.