Skip to content

Commit

Permalink
Amélioration récupération du CSV pour le Bail Réel solidaire (#2429)
Browse files Browse the repository at this point in the history
  • Loading branch information
Shamzic authored Feb 7, 2025
2 parents 2452c3d + c714a94 commit cf2254d
Show file tree
Hide file tree
Showing 3 changed files with 71 additions and 62 deletions.
10 changes: 10 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,15 @@
# Changelog

### 169.16.1 [2429](https://github.com/openfisca/openfisca-france/pull/2429)

- Évolution du système socio-fiscal.
- Périodes concernées : à partir du 01/07/2024.
- Zones impactées :
- `openfisca_france/model/prestations/bail_reel_solidaire.py`
- Détails :
- Modification de la récupération du fichier csv des zones pour le BRS
- Amélioration de la lisibilité du code

### 169.16.0 [2427](https://github.com/openfisca/openfisca-france/pull/2427)

- Changement mineur.
Expand Down
121 changes: 60 additions & 61 deletions openfisca_france/model/prestations/bail_reel_solidaire.py
Original file line number Diff line number Diff line change
@@ -1,81 +1,80 @@
from openfisca_france.model.base import *
import os
import openfisca_france
import csv
import codecs
import pkg_resources
import numpy as np


def load_zonage_file(period, parameters):
chemin_fichier_zonage_abc = os.path.join(parameters(period).prestations_sociales.bail_reel_solidaire.parametres_generaux.fichier_zonage[0])
def bail_reel_solidaire_zones_elligibles():
with pkg_resources.resource_stream(openfisca_france.__name__, 'assets/zonage-communes/zonage-abc-juillet-2024.csv') as csv_file:
utf8_reader = codecs.getreader('utf-8')
csv_reader = csv.DictReader(utf8_reader(csv_file), delimiter=';')
return {
row['CODGEO']: row['Zone en vigueur depuis le 5 juillet 2024']
for row in csv_reader
}

if not os.path.exists(chemin_fichier_zonage_abc):
return None

with open(chemin_fichier_zonage_abc, 'r', encoding='utf-8') as csvfile:
csv_reader = csv.DictReader(csvfile, delimiter=';')
return {row['CODGEO']: row['Zone en vigueur depuis le 5 juillet 2024'] for row in csv_reader}


def plafond_par_zone_et_composition(nb_personnes, plafonds_par_zones, zone):
plafond_zone = plafonds_par_zones[f'zone_{zone}']

tranches_composition = range(1, 7)
conditions_nb_personnes = [
nb_personnes == i if i < 6 else nb_personnes >= i
for i in tranches_composition
]

plafonds_revenus = [
plafond_zone[f'nb_personnes_{i}']
for i in tranches_composition
]

return select(conditions_nb_personnes, plafonds_revenus)

class bail_reel_solidaire_zones_menage(Variable):
value_type = str
label = 'Zone du ménage pour le Bail Réel Solidaire'
entity = Menage
definition_period = MONTH

def plafond_supplementaire_par_zone(nb_personnes, plafonds_par_zones, zone, nb_personnes_max):
return where(
nb_personnes > nb_personnes_max,
(nb_personnes - nb_personnes_max) * plafonds_par_zones[f'zone_{zone}']['nb_personnes_supplementaires'],
0
)
def formula(menage, period):
depcom = menage('depcom', period)
return np.fromiter(
(bail_reel_solidaire_zones_elligibles().get(depcom_cell.decode('utf-8')) for depcom_cell in depcom),
dtype='<U4' # String length max for zones (A, Abis, B1, B2, C)
)


class bail_reel_solidaire(Variable):
class bail_reel_solidaire_plafond_total(Variable):
value_type = float
label = 'Plafond de ressources total du Bail Réel Solidaire'
entity = Menage
value_type = bool
reference = [
'https://www.legifrance.gouv.fr/jorf/id/JORFTEXT000032918488',
'https://www.legifrance.gouv.fr/loda/id/JORFTEXT000000437021'
]
label = 'Bail réel solidaire'
definition_period = MONTH

def formula(menage, period, parameters):
parametres = parameters(period).prestations_sociales.bail_reel_solidaire.parametres_generaux
zones_abc_eligibles = parametres.zones_abc_eligibles
nb_personnes_max = parametres.nombre_personnes_maximum

zones_par_depcom = load_zonage_file(period, parameters)
if not zones_par_depcom:
return False

params = parameters(period).prestations_sociales.bail_reel_solidaire
zones_abc_eligibles = params.parametres_generaux.zones_abc_eligibles
plafonds_par_zones = params.plafonds_par_zones
zones_menage = menage('bail_reel_solidaire_zones_menage', period)
nb_personnes = menage.nb_persons()
depcom = menage('depcom', period.first_month)
zones_menage = np.array([zones_par_depcom.get(d.decode('utf-8'), None) for d in depcom])

plafonds_par_zones = parameters(period).prestations_sociales.bail_reel_solidaire.plafonds_par_zones

plafond_revenu_base = select(
nb_personnes_max = params.parametres_generaux.nombre_personnes_maximum

def calcul_plafonds_zone(zone):
plafond_zone = plafonds_par_zones[f'zone_{zone}']
plafond_base = select(
[nb_personnes == i if i < 6 else nb_personnes >= i for i in range(1, 7)],
[plafond_zone[f'nb_personnes_{i}'] for i in range(1, 7)]
)
plafond_supp = where(
nb_personnes > nb_personnes_max,
(nb_personnes - nb_personnes_max) * plafond_zone.nb_personnes_supplementaires,
0
)
return plafond_base + plafond_supp

return select(
[zones_menage == zone for zone in zones_abc_eligibles],
[plafond_par_zone_et_composition(nb_personnes, plafonds_par_zones, zone) for zone in zones_abc_eligibles]
[calcul_plafonds_zone(zone) for zone in zones_abc_eligibles]
)

plafond_revenu_supplementaire = select(
[zones_menage == zone for zone in zones_abc_eligibles],
[plafond_supplementaire_par_zone(nb_personnes, plafonds_par_zones, zone, nb_personnes_max) for zone in zones_abc_eligibles]
)

rfr = menage.sum(menage.members.foyer_fiscal(
'rfr', period.n_2), role=FoyerFiscal.DECLARANT_PRINCIPAL)
class bail_reel_solidaire(Variable):
value_type = bool
label = 'Éligibilité au Bail Réel Solidaire'
entity = Menage
definition_period = MONTH
reference = [
'https://www.legifrance.gouv.fr/jorf/id/JORFTEXT000032918488',
'https://www.legifrance.gouv.fr/loda/id/JORFTEXT000000437021'
]

return where(zones_menage is not None, rfr <= (plafond_revenu_base + plafond_revenu_supplementaire), False)
def formula(menage, period):
plafond_total = menage('bail_reel_solidaire_plafond_total', period)
zones_menage = menage('bail_reel_solidaire_zones_menage', period)
rfr = menage.sum(menage.members.foyer_fiscal('rfr', period.n_2), role=FoyerFiscal.DECLARANT_PRINCIPAL)
return where(zones_menage is not None, rfr <= plafond_total, False)
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[project]
name = "OpenFisca-France"
version = "169.16.0"
version = "169.16.1"
description = "OpenFisca Rules as Code model for France."
readme = "README.md"
keywords = ["microsimulation", "tax", "benefit", "rac", "rules-as-code", "france"]
Expand Down

0 comments on commit cf2254d

Please sign in to comment.