-
Notifications
You must be signed in to change notification settings - Fork 99
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
2 changed files
with
91 additions
and
24 deletions.
There are no files selected for viewing
70 changes: 46 additions & 24 deletions
70
openfisca_france/model/prestations/bail_reel_solidaire.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,53 +1,75 @@ | ||
from openfisca_france.model.base import * | ||
import os | ||
import csv | ||
|
||
import numpy as np | ||
|
||
ZONAGE_ABC = os.path.join( | ||
os.path.dirname(os.path.abspath(__file__)), | ||
'../../assets/zonage-communes/zonage-abc-juillet-2024.csv' | ||
) | ||
|
||
) | ||
ZONES_ABC = ['A', 'Abis', 'B1', 'B2', 'C'] | ||
NB_PERSONNES_MAX = 6 | ||
|
||
def preload_zone_abc(): | ||
if not os.path.exists(ZONAGE_ABC): | ||
return None | ||
|
||
with open(ZONAGE_ABC, 'r', encoding='utf-8') as csvfile: | ||
reader = csv.DictReader(csvfile, delimiter=';') | ||
return { | ||
row['CODGEO']: row['Zone en vigueur depuis le 5 juillet 2024'] | ||
for row in reader | ||
} | ||
|
||
return {row['CODGEO']: row['Zone en vigueur depuis le 5 juillet 2024'] for row in reader} | ||
|
||
class bail_reel_solidaire(Variable): | ||
entity = Menage | ||
value_type = float | ||
value_type = bool | ||
reference = 'https://www.legifrance.gouv.fr/jorf/id/JORFTEXT000032918488' | ||
label = 'Bail réel solidaire' | ||
definition_period = MONTH | ||
|
||
def formula(menage, period, parameters): | ||
nb_personnes = menage.nb_persons()[0] | ||
_zone_abc_by_depcom = preload_zone_abc() | ||
def plafond_par_zone_et_composition(nb_personnes, plafonds_par_zones, zone): | ||
plafond_zone = plafonds_par_zones[f'zone_{zone}'] | ||
conditions = [ | ||
nb_personnes == 1, | ||
nb_personnes == 2, | ||
nb_personnes == 3, | ||
nb_personnes == 4, | ||
nb_personnes == 5, | ||
nb_personnes >= 6 | ||
] | ||
plafonds = [ | ||
plafond_zone['nb_personnes_1'], | ||
plafond_zone['nb_personnes_2'], | ||
plafond_zone['nb_personnes_3'], | ||
plafond_zone['nb_personnes_4'], | ||
plafond_zone['nb_personnes_5'], | ||
plafond_zone['nb_personnes_6'] | ||
] | ||
return select(conditions, plafonds) | ||
|
||
def plafond_supplementaire_par_zone(nb_personnes, plafonds_par_zones, zone): | ||
return where(nb_personnes > NB_PERSONNES_MAX, | ||
(nb_personnes - NB_PERSONNES_MAX) * plafonds_par_zones[f'zone_{zone}']['nb_personnes_supplementaires'], 0) | ||
|
||
if _zone_abc_by_depcom is None: | ||
zones_par_depcom = preload_zone_abc() | ||
if not zones_par_depcom: | ||
return False | ||
|
||
nb_personnes = menage.nb_persons() | ||
depcom = menage('depcom', period.first_month) | ||
zone = _zone_abc_by_depcom.get(depcom[0].decode('utf-8')) | ||
zones = np.array([zones_par_depcom.get(d.decode('utf-8'), None) for d in depcom]) | ||
|
||
if zone is None: | ||
return False | ||
plafonds_par_zones = parameters(period).prestations_sociales.bail_reel_solidaire.plafonds_par_zones | ||
|
||
params = parameters(period).prestations_sociales.bail_reel_solidaire.plafonds_par_zones[f'zone_{zone}'] | ||
rfr = menage.sum(menage.members.foyer_fiscal('rfr', period.n_2), role = FoyerFiscal.DECLARANT_PRINCIPAL)[0] | ||
plafond_base = select( | ||
[zones == zone for zone in ZONES_ABC], | ||
[plafond_par_zone_et_composition(nb_personnes, plafonds_par_zones, zone) for zone in ZONES_ABC] | ||
) | ||
|
||
if nb_personnes > 6: | ||
plafond_base = params.nb_personnes_6 | ||
personnes_supp = nb_personnes - 6 | ||
plafond = plafond_base + (personnes_supp * params.nb_personnes_supplementaires) | ||
else: | ||
plafond = getattr(params, f'nb_personnes_{nb_personnes}') | ||
plafond_supp = select( | ||
[zones == zone for zone in ZONES_ABC], | ||
[plafond_supplementaire_par_zone(nb_personnes, plafonds_par_zones, zone) for zone in ZONES_ABC] | ||
) | ||
|
||
return rfr <= plafond | ||
rfr = menage.sum(menage.members.foyer_fiscal('rfr', period.n_2), role=FoyerFiscal.DECLARANT_PRINCIPAL) | ||
|
||
return where(zones != None, rfr <= (plafond_base + plafond_supp), False) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters