Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Reform dynamique : ajoute la gestion de la condition attached_to_institution #191

Merged
merged 5 commits into from
Nov 27, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,11 @@
# Changelog
## [6.8.0] - 2023-11-22

_Pour les changements détaillés et les discussions associées, référencez la pull request [#191](https://github.com/openfisca/openfisca-france-local/pull/191)

### Added

- Ajoute la gestion de la condition attaches_to_institution dans la `aides_jeunes_reform_dynamic`

## [6.7.2] - 2023-11-23

Expand Down
57 changes: 40 additions & 17 deletions openfisca_france_local/aides_jeunes_reform.py
Original file line number Diff line number Diff line change
Expand Up @@ -237,10 +237,6 @@ def is_situation_handicap(individu: Population, period: Period) -> np.array:
return individu('handicap', period)


def not_implemented_condition(_: Population, __: Period, condition: ParameterNodeAtInstant) -> np.array:
raise NotImplementedError(f'Condition in `{condition.name}` is not implemented')


condition_table = {
'age': is_age_eligible,
'regions': is_region_eligible,
Expand All @@ -255,7 +251,6 @@ def not_implemented_condition(_: Population, __: Period, condition: ParameterNod
'communes': is_commune_eligible,
'epcis': is_epci_eligible,
'taux_incapacite': is_taux_incapacite_eligible,
'attached_to_institution': not_implemented_condition,
}


Expand Down Expand Up @@ -295,7 +290,7 @@ def build_condition_evaluator_list(conditions: 'list[dict]') -> 'list[ConditionE
for condition in conditions
]
except KeyError as e:
raise KeyError(f"Condition `{(e.args[0])}` is unknown.")
raise NotImplementedError(f"Condition `{(e.args[0])}` is unknown.")

return evaluators

Expand All @@ -304,7 +299,7 @@ def build_profil_evaluator(profil: dict) -> ProfileEvaluator:
try:
predicate = profil_table[profil['type']]
except KeyError:
raise KeyError(f"Profil `{profil['type']}` is unknown.")
raise NotImplementedError(f"Profil `{profil['type']}` is unknown.")

conditions = profil.get('conditions', [])

Expand Down Expand Up @@ -379,22 +374,23 @@ def formula(individu: Population, period: Period, parameters):
})


root = '.'
benefit_path = 'test_data/benefits'
current_path = path.join(root, benefit_path)
default_benefit_path = 'test_data/benefits'
default_institutions_path = 'test_data/institutions'


class aides_jeunes_reform_dynamic(reforms.Reform):
def __init__(self, baseline, benefits_folder_path=current_path):
def __init__(self, baseline, benefits_folder_path=default_benefit_path, institutions_folder_path=default_institutions_path):
self.benefits_folder_path = getenv('DYNAMIC_BENEFIT_FOLDER', benefits_folder_path)
self.institutions_folder_path = getenv('DYNAMIC_INSTITUTION_FOLDER', institutions_folder_path)
super().__init__(baseline)

def apply(self):
try:
benefit_files_paths: 'list[str]' = self._extract_benefits_paths(self.benefits_folder_path)
benefit_files_paths: 'list[str]' = self._extract_paths(self.benefits_folder_path)

for benefit_path in benefit_files_paths:
benefit: dict = self._extract_benefit_file_content(benefit_path)

benefit_parameters: ParameterNode = convert_benefit_conditions_to_parameters(benefit)
self._add_parameters_into_current_tax_and_benefits_system(benefit_parameters)

Expand All @@ -406,21 +402,48 @@ def apply(self):
raise

def _extract_benefit_file_content(self, benefit_path: str):
def _convert_institution_to_condition(benefit: dict) -> dict:
if {'type': 'attached_to_institution'} in benefit['conditions_generales']:
conditions_generales_without_attached_institution = [
condition for condition
in benefit['conditions_generales']
if condition != {'type': 'attached_to_institution'}]

with open(f'{self.institutions_folder_path}/{benefit["institution"]}.yml') as file:
institution: dict = yaml.safe_load(file)

institution_type = institution['type']
if institution_type in ['msa', 'caf']:
condition_type = 'departements'
condition_value = institution['departments']
elif institution_type == 'epci':
condition_type = 'epcis'
Allan-CodeWorks marked this conversation as resolved.
Show resolved Hide resolved
condition_value = [institution['code_siren']]
else:
condition_type = f"{institution_type}s"
baptou12 marked this conversation as resolved.
Show resolved Hide resolved
condition_value = [institution['code_insee']]

conditions_generales_without_attached_institution.append({'type': condition_type, 'values': condition_value})

benefit = {**benefit, 'conditions_generales': conditions_generales_without_attached_institution}
return benefit

def _slug_from_path(path: str):
return path.split('/')[-1].replace('-', '_').split('.')[0]

benefit: dict = yaml.safe_load(open(benefit_path))
benefit['slug'] = _slug_from_path(benefit_path)

with open(benefit_path) as file:
benefit: dict = yaml.safe_load(file)
benefit['slug'] = _slug_from_path(benefit_path)
benefit = _convert_institution_to_condition(benefit)
return benefit

def _extract_benefits_paths(self, benefits_folder: str) -> 'list[str]':
def _extract_paths(self, folder: str) -> 'list[str]':
def _isYAMLfile(path: str):
return str(path).endswith('.yml') or str(path).endswith('.yaml')

files: 'list[str]' = [
str(benefit)
for benefit in Path(benefits_folder).iterdir()
for benefit in Path(folder).iterdir()
if _isYAMLfile(benefit)
]

Expand Down
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

setup(
name='OpenFisca-France-Local',
version='6.7.2',
version='6.8.0',
author='OpenFisca Team',
author_email='[email protected]',
classifiers=[
Expand Down
10 changes: 10 additions & 0 deletions test_data/benefits/test_condition_attached_to_institution_caf.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
label: Test condition attached_to_institutions caf
institution: institution_caf
prefix: l’
conditions_generales:
- type: attached_to_institution
type: float
unit: €
periodicite: mensuelle
montant: 19
floorAt: 1
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
label: Test condition attached_to_institutions communes
institution: institution_commune
prefix: l’
conditions_generales:
- type: attached_to_institution
type: float
unit: €
periodicite: mensuelle
montant: 16.8
floorAt: 1
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
label: Test condition attached_to_institutions départements
institution: institution_departement
prefix: l’
conditions_generales:
- type: attached_to_institution
type: float
unit: €
periodicite: mensuelle
montant: 17.8
floorAt: 1
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
label: Test condition attached_to_institutions epci
institution: institution_epci
prefix: l’
conditions_generales:
- type: attached_to_institution
type: float
unit: €
periodicite: mensuelle
montant: 18
floorAt: 1
1 change: 0 additions & 1 deletion test_data/benefits/test_profil_beneficiaire_rsa.yaml
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
label: Aide au permis de conduire
institution: intercommunalite_toulon_provence_mediterranee
prefix: l’
conditions_generales:
- type: regions
Expand Down
6 changes: 6 additions & 0 deletions test_data/institutions/institution_caf.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
name: CAF de l'Ain
imgSrc: img/institutions/logo_caf_ain.png
type: caf
code_siren: "779311224"
departments:
- "01"
6 changes: 6 additions & 0 deletions test_data/institutions/institution_commune.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
name: Ville de Bar-le-Duc
imgSrc: img/institutions/logo_ville_bar_le_duc.png
prefix: de la
type: commune
code_insee: "55029"
code_siren: "215500299"
5 changes: 5 additions & 0 deletions test_data/institutions/institution_departement.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
name: Département Alpes-Maritimes
imgSrc: img/institutions/logo_cd06.png
type: departement
code_insee: "06"
code_siren: "220600019"
5 changes: 5 additions & 0 deletions test_data/institutions/institution_epci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
name: Communauté d'agglomération du Grand Verdun
imgSrc: img/institutions/logo_ca_grand_verdun.png
prefix: de la
type: epci
code_siren: "200049187"
5 changes: 2 additions & 3 deletions tests/reforms/aides_jeunes/test_aides_jeunes_reform.py
Original file line number Diff line number Diff line change
@@ -1,16 +1,15 @@
import os
import pytest
from openfisca_france import FranceTaxBenefitSystem
from openfisca_france.scenarios import init_single_entity
from openfisca_france_local.aides_jeunes_reform import aides_jeunes_reform_dynamic


@pytest.mark.parametrize("bogus_benefit_folder", [
'test_missing_condition_key',
'test_missing_profile_key',
])
])
def test_bogus_benefit_structure(bogus_benefit_folder):
with pytest.raises(KeyError):
with pytest.raises(NotImplementedError):
base_tbs = FranceTaxBenefitSystem()
benefits_path = os.path.join('test_data/bogus_benefits/', bogus_benefit_folder)
aides_jeunes_reform_dynamic(base_tbs, benefits_path)
Expand Down
39 changes: 39 additions & 0 deletions tests/reforms/aides_jeunes/test_aides_jeunes_reform.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -251,3 +251,42 @@
- openfisca_france_local.aides_jeunes_reform.aides_jeunes_reform_dynamic
output:
test_pas_de_profile: 0

- period: 2022-11
name: Condition attached_to_institution communes
reforms:
- openfisca_france_local.aides_jeunes_reform.aides_jeunes_reform_dynamic
input:
depcom: [55029, 38000]
output:
test_condition_attached_to_institution_communes: [16.8, 0]


- period: 2022-11
name: Condition attached_to_institution départements
reforms:
- openfisca_france_local.aides_jeunes_reform.aides_jeunes_reform_dynamic
input:
depcom: ['06100']
output:
test_condition_attached_to_institution_departements: [17.8]


- period: 2022-11
name: Condition attached_to_institution epcis
reforms:
- openfisca_france_local.aides_jeunes_reform.aides_jeunes_reform_dynamic
- openfisca_france_local.epci_test_factory.epci_reform
input:
depcom: [55505]
output:
test_condition_attached_to_institution_epcis: [18]

- period: 2022-11
name: Condition attached_to_institution caf + msa
reforms:
- openfisca_france_local.aides_jeunes_reform.aides_jeunes_reform_dynamic
input:
depcom: ['01100']
output:
test_condition_attached_to_institution_caf: [19]