Commit 332936a2 authored by David Foucher's avatar David Foucher

Merge branch 'BFC-remu-maj' into 'master'

Bfc remu maj

See merge request !12
parents 85691f3c 73b9503c
Pipeline #2142 passed with stage
in 1 minute and 20 seconds
......@@ -31,6 +31,23 @@ async def simulate(data, financements):
if key.startswith("financement"):
del data[key]
async def simulate_remuneration(data, remunerations):
# Prepare context
flatten(data)
context = Context(data.copy())
routine.extrapolate_context(context)
routine.preprocess(context)
for remuneration in remunerations:
copy = context.copy()
routine.check_remuneration(context, remuneration)
data.update(copy.cleaned_data)
# FIXME (limits of the single-store-all context object)
# Clean keys not meant to be exposed
for key in list(data.keys()):
if key.startswith("remuneration"):
del data[key]
def get_financements(tags=None):
financements = [config.Financement(f) for f in config.FINANCEMENTS]
......
......@@ -5,7 +5,13 @@ from roll.extensions import cors
import ujson as json
from . import VERSION, get_financements, get_remunerations, simulate
from . import (
VERSION,
get_financements,
get_remunerations,
simulate,
simulate_remuneration,
)
from . import routine
from .config import FINANCEMENTS, GLOSSARY, IDCC, NAF, RAW_RULES, SCHEMA
from .context import Context
......@@ -65,8 +71,8 @@ async def simulate_(request, response):
body = {"financements": financements}
if request.query.bool("context", False):
body["context"] = {
k: v for k, v in context.items()
if k in SCHEMA and "label" in SCHEMA[k]}
k: v for k, v in context.items() if k in SCHEMA and "label" in SCHEMA[k]
}
if request.query.bool("scenario", False):
body["scenario"] = make_scenario(context, financements)
response.json = body
......@@ -77,24 +83,10 @@ async def simulate_(request, response):
# TODO : add pointer error for bad region number + test
@app.route("/remuneration", methods=["POST"])
async def remuneration_(request, response):
data = request.json
context = request.json
remunerations = get_remunerations(tags=request.query.list("tags", []))
try:
flatten(data)
context = Context(data.copy())
routine.extrapolate_context(context)
routine.preprocess(context)
for remuneration in remunerations:
copy = context.copy()
routine.check_remuneration(context, remuneration)
data.update(copy.cleaned_data)
# FIXME (limits of the single-store-all context object)
# Clean keys not meant to be exposed
for key in list(data.keys()):
if key.startswith("remuneration"):
del data[key]
await simulate_remuneration(context, remunerations)
except DataError as err:
error = {err.key: err.error}
log_simulate(context, errors=error)
......
......@@ -288,7 +288,7 @@ Scénario: Cas parent isolé
Quand je sélectionne le financement «Action collective financée par la Région»
Alors la rémunération applicable vaut 863.0
Et le montant de l'aide au transport vaut «98,79€ par mois (sous condition)»
Et le montant de l'aide au logement vaut «101,84€ par mois (sous condition)»
Et le montant de l'aide à l'hébergement vaut «101,84€ par mois (sous condition)»
Scénario: Cas non salarié ayant travaillé
......@@ -341,7 +341,7 @@ Scénario: Cas travailleur handicapé
Et c'est un travailleur handicapé
Quand je demande un calcul de financement
Quand je sélectionne le financement «Action collective financée par la Région»
Alors la rémunération applicable vaut 910.02
Alors la rémunération applicable vaut 1001.02
Scénario: Cas travailleur handicapé rémunération > 910
Soit un bénéficiaire et une formation
......@@ -370,7 +370,7 @@ Scénario: Cas travailleur handicapé rémunération
Et c'est un travailleur handicapé
Quand je demande un calcul de financement
Quand je sélectionne le financement «Action collective financée par la Région»
Alors la rémunération applicable vaut 910.02
Alors la rémunération applicable vaut 1001.02
Scénario: Cas ESSFIMO
Soit un bénéficiaire et une formation
......
Fonctionnalité: Rémunérations et aides en Bourgogne-Franche-Comté
Scénario: Rému et aides moins de 18 ans
Soit un bénéficiaire et une formation
Et c'est un demandeur d'emploi
Et l'âge du bénéficiaire vaut 16
Et les codes financeur de la formation valent [«Conseil régional»]
Et la région de la formation vaut «Bourgogne-Franche-Comté»
Quand je demande un calcul de rémunération
Alors la rémunération applicable vaut 455.01
Et une aide à l'hébergement est éligible
Et une aide au transport est éligible
Scénario: Rému et aides plus de 18 ans
Soit un bénéficiaire et une formation
Et c'est un demandeur d'emploi
Et l'âge du bénéficiaire vaut 36
Et les codes financeur de la formation valent [«Conseil régional»]
Et la région de la formation vaut «Bourgogne-Franche-Comté»
Quand je demande un calcul de rémunération
Alors la rémunération applicable vaut 652.18
Et aucune aide à l'hébergement n'est éligible
Et une aide au transport est éligible
Scénario: Rému et aides parent isolée
Soit un bénéficiaire et une formation
Et c'est un demandeur d'emploi
Et l'âge du bénéficiaire vaut 36
Et c'est un parent isolé
Et les codes financeur de la formation valent [«Conseil régional»]
Et la région de la formation vaut «Bourgogne-Franche-Comté»
Quand je demande un calcul de rémunération
Alors la rémunération applicable vaut 863.0
Et une aide à l'hébergement est éligible
Et une aide au transport est éligible
Scénario: Rému et aides moins de 18 ans ayant travaillé 12 mois dont au moins 6 consécutifs
Soit un bénéficiaire et une formation
Et c'est un demandeur d'emploi
Et l'âge du bénéficiaire vaut 17
Et c'est un bénéficiaire non salarié qui a travaillé pendant douze mois dont au moins six mois consécutifs dans les trois ans qui précèdent l'entrée en formation
Et les codes financeur de la formation valent [«Conseil régional»]
Et la région de la formation vaut «Bourgogne-Franche-Comté»
Quand je demande un calcul de rémunération
Alors la rémunération applicable vaut 708.59
Et aucune aide à l'hébergement n'est éligible
Et une aide au transport est éligible
Scénario: Rému pour une pesonnes handicapée ayant déjà travaillé
Soit un bénéficiaire et une formation
Et c'est un demandeur d'emploi
Et c'est un travailleur handicapé
Et c'est un bénéficiaire non salarié qui a travaillé pendant douze mois dont au moins six mois consécutifs dans les trois ans qui précèdent l'entrée en formation
Et les codes financeur de la formation valent [«Conseil régional»]
Et la région de la formation vaut «Bourgogne-Franche-Comté»
Quand je demande un calcul de rémunération
Alors la rémunération applicable vaut 910.02
Et aucune aide à l'hébergement n'est éligible
Et une aide au transport est éligible
Scénario: Rému pour une pesonnes handicapée n'ayant pas travaillée
Soit un bénéficiaire et une formation
Et c'est un demandeur d'emploi
Et c'est un travailleur handicapé
Et les codes financeur de la formation valent [«Conseil régional»]
Et la région de la formation vaut «Bourgogne-Franche-Comté»
Quand je demande un calcul de rémunération
Alors la rémunération applicable vaut 1001.02
Et aucune aide à l'hébergement n'est éligible
Et une aide au transport est éligible
from behave import given, when, then, use_step_matcher
from behave.api.async_step import async_run_until_complete
from trefle import simulate, get_financements
from trefle import simulate, simulate_remuneration, get_financements, get_remunerations
from trefle.config import FINANCEMENTS
from trefle.helpers import revert_dict
from trefle.helpers import revert_dict, remove_namespace
from trefle.rules import LABELS, SCHEMA, Pointer
INTITULES_FINANCEMENTS = set(f["intitule"] for f in FINANCEMENTS)
......@@ -49,6 +49,20 @@ async def when_simulate(context):
context.passed = [f for f in financements if f['eligible']]
@when('je demande un calcul de rémunération')
@async_run_until_complete
async def when_remunerate(context):
remunerations = get_remunerations()
await simulate_remuneration(context.data, remunerations)
context.passed = [r for r in remunerations if r['remuneration']]
for result in context.passed:
if result['remuneration']:
context.result = result
break
else:
raise AssertionError(f'No result found')
@then(r"il y a (?P<expected>\d+) financements? proposés?")
def then_check_count(context, expected):
assert found == int(expected), f'Found {found}'
......@@ -86,10 +100,7 @@ def then_check_organisme(context, name):
@then(r"(?:le |la |l')(?P<label>.*) vaut (?P<value>.+)")
def then_check_output(context, label, value):
value = Pointer(value).get({})
if(LABELS[label].startswith("financement")):
key = LABELS[label][12:] # Remove "financement." namespace.
if(LABELS[label].startswith("remuneration")):
key = LABELS[label][13:] # Remove "remuneration." namespace.
key = remove_namespace(LABELS[label])
assert context.result[key] == value, (f'key = {key} '
f'label = {LABELS[label]}'
f'{context.result[key]} '
......@@ -111,6 +122,21 @@ def then_check_true_boolean_value(context, label):
f'{key} is True'
@then(r"une? (?P<label>.+) est éligible")
def then_check_true_eligibility(context, label):
key = LABELS[label]
assert context.result.get(remove_namespace(key)) \
and context.result[remove_namespace(key)] is True,\
f'{label} is True'
@then(r"aucune? (?P<label>.+) n'est éligible")
def then_check_false_eligibility(context, label):
key = LABELS[label]
assert context.result.get(remove_namespace(key)) is None,\
f'{label} is False'
@then("aucun financement n'est proposé")
def then_no_results(context):
assert not context.passed, f"Results found: {context.passed}"
......@@ -3,37 +3,95 @@ Si les codes financeur de la formation contiennent «Conseil régional»
Si l'allocation du bénéficiaire est définie
Alors la rémunération applicable est égale au montant de l'allocation du bénéficiaire
# Par défaut
#####################
# Aide au transport #
#####################
Si c'est un travailleur handicapé
Alors l'aide au transport est éligible
Et le texte de l'aide au transport vaut «L'indemnité de transport est limitée à un aller/retour sur la durée de la formation.»
Si ce n'est pas un travailleur handicapé
Alors l'aide au transport est éligible
Et le montant de l'aide au transport vaut «98,79€ par mois (sous condition)»
Et le texte de l'aide au transport vaut «Si la distance vers le lieu de votre formation est supérieure ou égale à 16km. Alors vous pouvez bénéficier d'une aide au transport.»
# Ligne 45 46
Si c'est un bénéficiaire non salarié qui a travaillé pendant douze mois dont au moins six mois consécutifs dans les trois ans qui précèdent l'entrée en formation
Et ce n'est pas un parent isolé
Et ce n'est pas une mère de famille ayant au moins trois enfants
Et ce n'est pas une femme divorcée, veuve ou séparée judiciairement depuis moins de trois ans
Et ce n'est pas une femme seule et enceinte
Alors l'aide au transport est éligible
Et le texte de l'aide au transport vaut «L'indemnité de transport est limitée à un aller/retour sur la durée de la formation.»
####################
# Aide à l'hébergement #
####################
Si c'est un bénéficiaire qui a déjà travaillé six mois sur une période de douze mois
Ou c'est un bénéficiaire qui a déjà travaillé douze mois sur une période de vingt-quatre mois
Ou c'est un parent isolé
Ou c'est une mère de famille ayant au moins trois enfants
Ou c'est une femme divorcée, veuve ou séparée judiciairement depuis moins de trois ans
Ou c'est une femme seule et enceinte
Alors l'aide à l'hébergement est éligible
Et le montant de l'aide à l'hébergement vaut «101,84€ par mois (sous condition)»
Et le texte de l'aide à l'hébergement vaut «Si la distance vers le lieu de votre formation est supérieure à 250km. Alors vous pouvez bénéficier d'une aide à l'hébergement. Cette aide est non cumulable avec l'aide au transport.»
# Tableau de regles: ligne 24
Si l'âge du bénéficiaire est inférieur à 18
Et la rémunération applicable est inférieure à 455.01
Alors la rémunération applicable vaut 455.01
Si l'âge du bénéficiaire est supérieur ou égal à 18
Et la rémunération applicable est inférieure à 652.18
Alors la rémunération applicable vaut 652.18
Et ce n'est pas un bénéficiaire qui a déjà travaillé six mois sur une période de douze mois
Et ce n'est pas un bénéficiaire qui a déjà travaillé douze mois sur une période de vingt-quatre mois
Et ce n'est pas un bénéficiaire non salarié qui a travaillé pendant douze mois dont au moins six mois consécutifs dans les trois ans qui précèdent l'entrée en formation
Alors l'aide à l'hébergement est éligible
Et le montant de l'aide à l'hébergement vaut «37,20€ par mois (sous condition)»
Et le texte de l'aide à l'hébergement vaut «Si la distance vers le lieu de votre formation est inférieure ou égale à 15km. Alors vous pouvez bénéficier d'une aide à l'hébergement.»
################
# Rémunération #
################
Si ce n'est pas un bénéficiaire qui a déjà travaillé six mois sur une période de douze mois
Et ce n'est pas un bénéficiaire qui a déjà travaillé douze mois sur une période de vingt-quatre mois
Et ce n'est pas un bénéficiaire non salarié qui a travaillé pendant douze mois dont au moins six mois consécutifs dans les trois ans qui précèdent l'entrée en formation
Si l'âge du bénéficiaire est inférieur à 18
Et la rémunération applicable est inférieure à 455.01
Alors la rémunération applicable vaut 455.01
Si l'âge du bénéficiaire est supérieur ou égal à 18
Et la rémunération applicable est inférieure à 652.18
Alors la rémunération applicable vaut 652.18
Si c'est un travailleur handicapé
Et la rémunération applicable est inférieure à 1001.02
Alors la rémunération applicable vaut 1001.02
# Tableau de regles: ligne 4 et 7
Si c'est un travailleur handicapé
Et la rémunération applicable est inférieure à 910.02
Si c'est un bénéficiaire qui a déjà travaillé six mois sur une période de douze mois
Ou c'est un bénéficiaire qui a déjà travaillé douze mois sur une période de vingt-quatre mois
Ou c'est un bénéficiaire non salarié qui a travaillé pendant douze mois dont au moins six mois consécutifs dans les trois ans qui précèdent l'entrée en formation
Alors la rémunération applicable vaut 910.02
Et le texte de la rémunération vaut «C'est une rémunération minimum en fonction de votre expérience»
# Tableau de regles: ligne 4 et 8 à 13
Si c'est un bénéficiaire qui a déjà travaillé six mois sur une période de douze mois
Ou c'est un bénéficiaire qui a déjà travaillé douze mois sur une période de vingt-quatre mois
Et la rémunération applicable est inférieure à 863.00
Alors la rémunération applicable vaut 863.00
Si la rémunération applicable est inférieure à 863.0
Alors la rémunération applicable vaut 863.00
# Tableau de regles: ligne 38 à 44
Si c'est un bénéficiaire non salarié qui a travaillé pendant douze mois dont au moins six mois consécutifs dans les trois ans qui précèdent l'entrée en formation
Et la rémunération applicable est inférieure à 708.59
Alors la rémunération applicable vaut 708.59
# Règles spécifiques
Si c'est un parent isolé
Ou c'est une mère de famille ayant au moins trois enfants
Ou c'est une femme divorcée, veuve ou séparée judiciairement depuis moins de trois ans
Ou c'est une femme seule et enceinte
#Ou c'est un demandeur d'emploi # A confirmer
Alors l'aide au transport est éligible
Et le montant de l'aide au transport vaut «98,79€ par mois (sous condition)»
Et le texte de l'aide au transport vaut «Si la distance vers le lieu de votre formation est supérieure à 16km. Alors vous pouvez bénéficier d'une aide au transport.»
Et l'aide au logement est éligible
Et le montant de l'aide au logement vaut «101,84€ par mois (sous condition)»
Et le texte de l'aide au logement vaut «Si la distance vers le lieu de votre formation est supérieure à 250km. Alors vous pouvez bénéficier d'une aide à l'hébergement. Cette aide est non cumulable avec l'aide au transport.»
Si la rémunération applicable est inférieure à 863.00
Alors la rémunération applicable vaut 863.00
Si c'est un travailleur handicapé
Et la rémunération applicable est inférieure à 910.02
Alors la rémunération applicable vaut 910.02
Et le texte de la rémunération vaut «C'est une rémunération minimum en fonction de votre expérience»
# TODO ajouter cas détenu
# Si c'est un détenu
......
......@@ -1066,7 +1066,7 @@ aide: &aide
public: true
label: texte de l'aide complémentaire
droit_aide_transport:
description: le bénéficiaire a droit a une aide au transport
description: le bénéficiaire a droit à une aide au transport
type: boolean
public: true
label: aide au transport
......@@ -1080,21 +1080,21 @@ aide: &aide
type: string
public: true
label: texte de l'aide au transport
droit_aide_logement:
description: le bénéficiaire a droit a une aide au logement
droit_aide_hebergement:
description: le bénéficiaire a droit a une aide à l'hébergement
type: boolean
public: true
label: aide au logement
montant_aide_logement:
description: le montant de l'aide au logement
label: aide à l'hébergement
montant_aide_hebergement:
description: le montant de l'aide à l'hébergement
type: string
public: true
label: montant de l'aide au logement
description_aide_logement:
label: montant de l'aide à l'hébergement
description_aide_hebergement:
description: texte de description de l'aide au transport
type: string
public: true
label: texte de l'aide au logement
label: texte de l'aide à l'hébergement
remuneration: &remuneration
intitule_remuneration: # add _remuneration to not overlap financement.intitule
description: le nom de la règle de rémuneration
......
......@@ -140,6 +140,10 @@ def revert_dict(d):
return {v: k for k, v in d.items()}
def remove_namespace(s):
return s[(s.find('.') + 1):]
def json_path(pattern, data):
steps = pattern.split(".")
......
......@@ -257,9 +257,9 @@ def compute_remuneration(context, facility, facility_name="financement"):
"droit_aide_transport",
"montant_aide_transport",
"description_aide_transport",
"droit_aide_logement",
"montant_aide_logement",
"description_aide_logement",
"droit_aide_hebergement",
"montant_aide_hebergement",
"description_aide_hebergement",
]
for key in keys:
name = facility_name + f".{key}"
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment