mirror of
https://github.com/CatalaLang/catala.git
synced 2024-09-20 00:41:05 +03:00
Playing mouse and cat with the CNAF form
This commit is contained in:
parent
309dfb6c3e
commit
7ab74501b8
@ -135,8 +135,8 @@ class LogementChambre(Logement):
|
||||
|
||||
|
||||
class SeulOuCouple(Enum):
|
||||
Seul = 'SEUL'
|
||||
EnCouple = 'COUPLE'
|
||||
Seul = 'CEL'
|
||||
EnCouple = 'VIM'
|
||||
|
||||
|
||||
class Enfant():
|
||||
|
19
french_law/python/cnaf_cross_tester/main.py
Normal file
19
french_law/python/cnaf_cross_tester/main.py
Normal file
@ -0,0 +1,19 @@
|
||||
|
||||
|
||||
from input import AppartementOuMaison, AppartementOuMaisonType, CnafSimulatorInput, Enfant, SeulOuCouple
|
||||
from pupeteer import run_simulator
|
||||
|
||||
# Output identical to the JS test of the housing benefits
|
||||
sample_input = CnafSimulatorInput(
|
||||
code_postal="69001",
|
||||
logement=AppartementOuMaison(
|
||||
AppartementOuMaisonType.Location, meuble=False),
|
||||
loyer=450,
|
||||
seul_ou_couple=SeulOuCouple.EnCouple,
|
||||
enfants=[Enfant(age=7, remuneration_derniere_annee=0),
|
||||
Enfant(age=8, remuneration_derniere_annee=0)],
|
||||
revenu_pris_en_compte=11_500
|
||||
)
|
||||
print(sample_input)
|
||||
housing_benefits = run_simulator(sample_input)
|
||||
print("Aides au logement : {} €".format(housing_benefits))
|
@ -10,7 +10,7 @@ HOME_PAGE = 'https://wwwd.caf.fr/wps/portal/caffr/aidesetservices/lesservicesenl
|
||||
|
||||
def run_simulator(input: CnafSimulatorInput) -> int:
|
||||
with sync_playwright() as p:
|
||||
browser = p.firefox.launch() # headless=False, slow_mo=1500)
|
||||
browser = p.firefox.launch(headless=True, slow_mo=100)
|
||||
page = browser.new_page()
|
||||
|
||||
# Go to the CNAF simulator
|
||||
@ -21,67 +21,67 @@ def run_simulator(input: CnafSimulatorInput) -> int:
|
||||
"div[id=\"popup-accept-cookies\"] >> button")
|
||||
if cookie_button is None:
|
||||
raise RuntimeError
|
||||
cookie_button.click()
|
||||
cookie_button.click(force=True)
|
||||
|
||||
# Click on 'Commencer'
|
||||
commencer_button = page.wait_for_selector('button[id="btn-commencer"]')
|
||||
commencer_button = page.wait_for_selector('button[id="btn-suivant"]')
|
||||
if commencer_button is None:
|
||||
raise RuntimeError
|
||||
commencer_button.click()
|
||||
commencer_button.click(force=True)
|
||||
|
||||
# Code Postal
|
||||
code_postal_input = page.wait_for_selector('input[id="codePostal"]')
|
||||
code_postal_input = page.wait_for_selector('input[id="cpCommune"]')
|
||||
if code_postal_input is None:
|
||||
raise RuntimeError
|
||||
code_postal_input.fill(input.code_postal)
|
||||
|
||||
# Select first match
|
||||
page.wait_for_selector('li[class="uib-typeahead-match"]')
|
||||
page.wait_for_selector('a[class="ng-tns-c31-0"]')
|
||||
page.keyboard.press('Enter')
|
||||
|
||||
# Select residence type
|
||||
type_residence_button = page.wait_for_selector(
|
||||
"label[for=\"nature_{}\"]".format(input.logement.residence()))
|
||||
"input[id=\"lieuResidence_{}\"]".format(input.logement.residence()))
|
||||
if type_residence_button is None:
|
||||
raise RuntimeError
|
||||
type_residence_button.click()
|
||||
type_residence_button.click(force=True)
|
||||
|
||||
# Select housing type for some things
|
||||
if isinstance(input.logement, AppartementOuMaison):
|
||||
type_appartement_ou_maison_button = page.wait_for_selector(
|
||||
"label[for=\"statut_{}\"]".format(input.logement.typ()))
|
||||
"input[id=\"typeOccupation_{}\"]".format(input.logement.typ()))
|
||||
if type_appartement_ou_maison_button is None:
|
||||
raise RuntimeError
|
||||
type_appartement_ou_maison_button.click()
|
||||
type_appartement_ou_maison_button.click(force=True)
|
||||
elif isinstance(input.logement, LogementCrous):
|
||||
type_crous_button = page.wait_for_selector(
|
||||
"label[for=\"typeLocal_{}\"]".format(input.logement.typ()))
|
||||
"input[id=\"typeCrous_{}\"]".format(input.logement.typ()))
|
||||
if type_crous_button is None:
|
||||
raise RuntimeError
|
||||
type_crous_button.click()
|
||||
type_crous_button.click(force=True)
|
||||
|
||||
# Is the location meublee
|
||||
|
||||
if not (input.logement.meublee() is None):
|
||||
meuble_button = page.wait_for_selector(
|
||||
"label[for=\"estMeuble_{}\"]".format("true" if input.logement.meublee() else "false"))
|
||||
"input[id=\"estMeuble_{}\"]".format("true" if input.logement.meublee() else "false"))
|
||||
if meuble_button is None:
|
||||
raise RuntimeError
|
||||
meuble_button.click()
|
||||
meuble_button.click(force=True)
|
||||
|
||||
# Monthly rent
|
||||
loyer_mensuel_input = page.wait_for_selector(
|
||||
'input[name="montantLoyer"]')
|
||||
'input[id="mttDeclare"]')
|
||||
if loyer_mensuel_input is None:
|
||||
raise RuntimeError
|
||||
loyer_mensuel_input.fill("{}".format(input.loyer))
|
||||
|
||||
# Couple or not
|
||||
seul_button = page.wait_for_selector(
|
||||
"label[for=\"situationFamiliale_{}\"]".format(input.seul_ou_couple.value))
|
||||
"input[id=\"situationFamiliale_{}\"]".format(input.seul_ou_couple.value))
|
||||
if seul_button is None:
|
||||
raise RuntimeError
|
||||
seul_button.click()
|
||||
seul_button.click(force=True)
|
||||
|
||||
# Number of children
|
||||
if len(input.enfants) < 0 or len(input.enfants) > 20:
|
||||
@ -90,103 +90,99 @@ def run_simulator(input: CnafSimulatorInput) -> int:
|
||||
if plus_button is None:
|
||||
raise RuntimeError
|
||||
for i in range(len(input.enfants)):
|
||||
plus_button.click()
|
||||
plus_button.click(force=True)
|
||||
|
||||
# Main applicant salary
|
||||
salaires_button = page.wait_for_selector(
|
||||
"button[id=\"allocataire_siSalaire\"]")
|
||||
"button[id=\"SALAIRE_0_checkbox\"]")
|
||||
if salaires_button is None:
|
||||
raise RuntimeError
|
||||
salaires_button.click()
|
||||
salaires_button.click(force=True)
|
||||
salaires_input = page.wait_for_selector(
|
||||
"input[id=\"ressourceallocataire_SALAIRE\"]")
|
||||
"input[id=\"SALAIRE_0_montant\"]")
|
||||
if salaires_input is None:
|
||||
raise RuntimeError
|
||||
salaires_input.fill("{}".format(
|
||||
int(float(input.revenu_pris_en_compte) / 0.9)))
|
||||
# We divide by 0.9 because salaries have a 10% franchise
|
||||
# Now if the salary is too low you have to click another button
|
||||
status_selector = "cnaf-personne[profil=\"'ALLOCATAIRE'\"] >> label[for=\"aucunRevenuAUTRE_SITUATION\"]"
|
||||
status_selector = "input[id=\"sitro_0_SITPRO_ACT_INCONNUE\"]"
|
||||
if not (page.query_selector is None):
|
||||
status_button = page.wait_for_selector(status_selector)
|
||||
if status_button is None:
|
||||
raise RuntimeError
|
||||
status_button.click()
|
||||
status_button.click(force=True)
|
||||
|
||||
# If there is a partner we assume no income for simplicity
|
||||
if input.seul_ou_couple == SeulOuCouple.EnCouple:
|
||||
sans_button = page.wait_for_selector(
|
||||
"button[id=\"conjoint_siAucunRevenu\"]")
|
||||
"button[id=\"aucunRevenu_1\"]")
|
||||
if sans_button is None:
|
||||
raise RuntimeError
|
||||
sans_button.click()
|
||||
sans_button.click(force=True)
|
||||
status_button = page.wait_for_selector(
|
||||
"cnaf-personne[profil=\"'CONJOINT'\"] >> label[for=\"aucunRevenuAUTRE_SITUATION\"]")
|
||||
"input[id=\"sitro_1_SITPRO_ACT_INCONNUE\"]")
|
||||
if status_button is None:
|
||||
raise RuntimeError
|
||||
status_button.click()
|
||||
status_button.click(force=True)
|
||||
|
||||
# Continue
|
||||
continuer_button = page.wait_for_selector('button[id="btn-suivant"]')
|
||||
if continuer_button is None:
|
||||
raise RuntimeError
|
||||
continuer_button.click()
|
||||
continuer_button.click(force=True)
|
||||
|
||||
# Extra questions about children
|
||||
if len(input.enfants) > 0:
|
||||
page.wait_for_selector(
|
||||
selector="div[ng-form=\"vm.questionsEnfantsForm\"]", state='attached')
|
||||
i = 0
|
||||
for element in page.query_selector_all("cnaf-personne[profil=\"'ENFANT'\"]"):
|
||||
for i in range(len(input.enfants)):
|
||||
if input.enfants[i].age < 21:
|
||||
yes_button = element.wait_for_selector(
|
||||
"label[for=\"personneAGE_MINIMUM\"][uib-btn-radio=\"true\"]")
|
||||
yes_button = page.wait_for_selector(
|
||||
"input[id=\"QUESTION_AGE_MAX_{}_true\"]".format(i))
|
||||
if yes_button is None:
|
||||
raise RuntimeError
|
||||
yes_button.click()
|
||||
yes_button.click(force=True)
|
||||
else:
|
||||
no_button = element.wait_for_selector(
|
||||
"label[for=\"personneAGE_MINIMUM\"][uib-btn-radio=\"false\"]")
|
||||
no_button = page.wait_for_selector(
|
||||
"input[id=\"QUESTION_AGE_MAX_{}_false\"]".format(i))
|
||||
if no_button is None:
|
||||
raise RuntimeError
|
||||
no_button.click()
|
||||
no_button.click(force=True)
|
||||
if int(float(input.enfants[i].remuneration_derniere_annee) / 0.9) > 4500:
|
||||
yes_button = element.wait_for_selector(
|
||||
"label[for=\"ENFANT_MONTANT_MAX\"][uib-btn-radio=\"true\"]")
|
||||
yes_button = page.wait_for_selector(
|
||||
"input[id=\"QUESTION_REVENUS_DERNIERSMOIS_{}_true\"]".format(i))
|
||||
if yes_button is None:
|
||||
raise RuntimeError
|
||||
yes_button.click()
|
||||
yes_button.click(force=True)
|
||||
# We have to provide the exact remuneration
|
||||
salaires_button = element.wait_for_selector(
|
||||
"label[for=\"enfant_{}_siSalaire\"]".format(i))
|
||||
salaires_button = page.wait_for_selector(
|
||||
"button[id=\"salaire{}_checkbox\"]".format(i))
|
||||
if salaires_button is None:
|
||||
raise RuntimeError
|
||||
salaires_button.click()
|
||||
salaires_input = element.wait_for_selector(
|
||||
"input[id=\"ressourceenfant_{}_SALAIRE\"]".format(i))
|
||||
salaires_button.click(force=True)
|
||||
salaires_input = page.wait_for_selector(
|
||||
"input[id=\"MONTANT_salaire{}\"]".format(i))
|
||||
if salaires_input is None:
|
||||
raise RuntimeError
|
||||
salaires_input.fill("{}".format(
|
||||
int(float(input.enfants[i].remuneration_derniere_annee) / 0.9)))
|
||||
salaires_status = element.wait_for_selector(
|
||||
"label[for=\"enfantSalarieSALARIE\"]")
|
||||
salaires_status = page.wait_for_selector(
|
||||
"input[id=\"QUESTION_SITPRO_{}_SALARIE_CP\"]".format(i))
|
||||
if salaires_status is None:
|
||||
raise RuntimeError
|
||||
salaires_status.click()
|
||||
salaires_status.click(force=True)
|
||||
else:
|
||||
no_button = element.wait_for_selector(
|
||||
"label[for=\"ENFANT_MONTANT_MAX\"][uib-btn-radio=\"false\"]")
|
||||
no_button = page.wait_for_selector(
|
||||
"input[id=\"QUESTION_REVENUS_DERNIERSMOIS_{}_false\"]".format(i))
|
||||
if no_button is None:
|
||||
raise RuntimeError
|
||||
no_button.click()
|
||||
i += 1
|
||||
no_button.click(force=True)
|
||||
|
||||
# Continue
|
||||
continuer_button = page.wait_for_selector(
|
||||
'button[id="btn-suivant"]')
|
||||
if continuer_button is None:
|
||||
raise RuntimeError
|
||||
continuer_button.click()
|
||||
continuer_button.click(force=True)
|
||||
|
||||
# Retrieve the amount
|
||||
page.wait_for_selector('section[id="resultat"]')
|
||||
@ -203,18 +199,3 @@ def run_simulator(input: CnafSimulatorInput) -> int:
|
||||
|
||||
browser.close()
|
||||
return int(housing_benefits)
|
||||
|
||||
|
||||
input = CnafSimulatorInput(
|
||||
code_postal="69001",
|
||||
logement=AppartementOuMaison(
|
||||
AppartementOuMaisonType.Location, meuble=False),
|
||||
loyer=450,
|
||||
seul_ou_couple=SeulOuCouple.EnCouple,
|
||||
enfants=[Enfant(age=7, remuneration_derniere_annee=0),
|
||||
Enfant(age=14, remuneration_derniere_annee=5000)],
|
||||
revenu_pris_en_compte=11_500
|
||||
)
|
||||
print(input)
|
||||
housing_benefits = run_simulator(input)
|
||||
print("Aides au logement : {} €".format(housing_benefits))
|
||||
|
Loading…
Reference in New Issue
Block a user