toulouse_axel: add registration info to family info endpoints (#39242)

This commit is contained in:
Lauréline Guérin 2020-01-30 15:52:01 +01:00
parent 01293dea36
commit d2989056e4
No known key found for this signature in database
GPG Key ID: 1FAB9B9B4F93D473
3 changed files with 155 additions and 30 deletions

View File

@ -55,7 +55,8 @@ def test_link(conn, user):
for key in ['MONTANTTOTAL', 'DATEVALIDITE', 'SFI', 'IREVENUS', 'RNF', 'NBENFANTSACHARGE']:
payload['REVENUS'].pop(key, None)
for enfant in payload['ENFANT']:
for key in ['NOM', 'DATENAISSANCE', 'SEXE', 'PRENOMPERE', 'PRENOMMERE', 'NOMPERE', 'NOMMERE', 'RATTACHEAUTREDUI', 'PRENOM']:
for key in ['NOM', 'DATENAISSANCE', 'SEXE', 'PRENOMPERE', 'PRENOMMERE', 'NOMPERE', 'NOMMERE', 'RATTACHEAUTREDUI', 'PRENOM',
'clae_cantine_current', 'clae_cantine_next']:
enfant.pop(key)
enfant['AUTORISATIONURGENCEMEDICALE'] = 'OUI'
if 'SANITAIRE' not in enfant:

View File

@ -452,17 +452,34 @@ class ToulouseAxel(BaseResource):
link.delete()
return {'link': link_id, 'deleted': True, 'dui': link.dui}
def get_family_data(self, name_id):
link = self.get_link(name_id)
def get_family_data(self, dui, check_registrations=False):
try:
result = ref_famille_dui(self, {'PORTAIL': {'DUI': {'IDDUI': link.dui}}})
result = ref_famille_dui(self, {'PORTAIL': {'DUI': {'IDDUI': dui}}})
except AxelError as e:
raise APIError(
'Axel error: %s' % e,
err_code='error',
data={'xml_request': e.xml_request,
'xml_response': e.xml_response})
return result.json_response['DATA']['PORTAIL']['DUI']
family_data = result.json_response['DATA']['PORTAIL']['DUI']
if check_registrations:
today = datetime.date.today()
current_reference_year = utils.get_reference_year_from_date(today)
next_reference_year = current_reference_year + 1
children_registred_for_current_year = self.are_children_registered(
dui=dui,
reference_year=current_reference_year)
children_registred_for_next_year = self.are_children_registered(
dui=dui,
reference_year=next_reference_year)
for child in family_data.get('ENFANT', []):
child['clae_cantine_current'] = children_registred_for_current_year.get(child['IDPERSONNE'])
child['clae_cantine_next'] = children_registred_for_next_year.get(child['IDPERSONNE'])
return family_data
@endpoint(
description=_("Get information about user's family"),
@ -471,7 +488,8 @@ class ToulouseAxel(BaseResource):
'NameID': {'description': _('Publik ID')},
})
def family_info(self, request, NameID):
family_data = self.get_family_data(NameID)
link = self.get_link(NameID)
family_data = self.get_family_data(link.dui, check_registrations=True)
return {'data': family_data}
@endpoint(
@ -482,9 +500,10 @@ class ToulouseAxel(BaseResource):
'idpersonne': {'description': _('Child ID')},
})
def child_info(self, request, idpersonne, NameID):
family_data = self.get_family_data(NameID)
link = self.get_link(NameID)
family_data = self.get_family_data(link.dui, check_registrations=True)
for child in family_data['ENFANT']:
for child in family_data.get('ENFANT', []):
if child['IDPERSONNE'] == idpersonne:
return {'data': child}
@ -564,7 +583,7 @@ class ToulouseAxel(BaseResource):
UPDATE_FAMILY_SCHEMA['pre_process'] = pre_sanitize_update_family_data
def sanitize_update_family_data(self, name_id, post_data):
def sanitize_update_family_data(self, dui, post_data):
family_data = None
for i, child_data in enumerate(post_data.get('ENFANT', [])):
@ -576,8 +595,8 @@ class ToulouseAxel(BaseResource):
continue
# get family info
if family_data is None:
family_data = self.get_family_data(name_id)
for orig_child in family_data['ENFANT']:
family_data = self.get_family_data(dui)
for orig_child in family_data.get('ENFANT', []):
# find the correct child in family info
if orig_child['IDPERSONNE'] != child_id:
continue
@ -624,7 +643,7 @@ class ToulouseAxel(BaseResource):
if rl not in post_data:
continue
if family_data is None:
family_data = self.get_family_data(name_id)
family_data = self.get_family_data(dui)
# fill missing fields
for key in ['IDPERSONNE', 'NOM', 'PRENOM', 'NOMJEUNEFILLE', 'DATENAISSANCE', 'CIVILITE']:
post_data[rl][key] = family_data[rl][key]
@ -633,7 +652,7 @@ class ToulouseAxel(BaseResource):
# fill NBENFANTSACHARGE
if 'REVENUS' in post_data:
if family_data is None:
family_data = self.get_family_data(name_id)
family_data = self.get_family_data(dui)
post_data['REVENUS']['NBENFANTSACHARGE'] = family_data.get('REVENUS', {}).get('NBENFANTSACHARGE')
# remove flags
@ -660,7 +679,7 @@ class ToulouseAxel(BaseResource):
post_data['IDDUI'] = link.dui
post_data['DATEDEMANDE'] = datetime.date.today().strftime('%Y-%m-%d')
self.sanitize_update_family_data(name_id=NameID, post_data=post_data)
self.sanitize_update_family_data(dui=link.dui, post_data=post_data)
if 'RL2' in post_data and post_data['RL2'].get('IDPERSONNE') == link.person_id:
post_data['QUIACTUALISEDUI'] = '2'
@ -884,7 +903,7 @@ class ToulouseAxel(BaseResource):
'xml_response': e.xml_response})
return {'data': True}
def get_child_activities(self, dui, reference_year, child_id):
def get_children_activities(self, dui, reference_year):
try:
result = enfants_activites(self, {
'DUI': {
@ -900,12 +919,36 @@ class ToulouseAxel(BaseResource):
data={'xml_request': e.xml_request,
'xml_response': e.xml_response})
child_activities_data = result.json_response['DATA']['PORTAIL']['DUI'].get('ENFANT', [])
for child in child_activities_data:
if child['IDPERSONNE'] == child_id:
return child
children_activities = result.json_response['DATA']['PORTAIL']['DUI'].get('ENFANT', [])
return {child['IDPERSONNE']: child for child in children_activities}
raise APIError('Child not found', err_code='not-found')
def get_child_activities(self, dui, reference_year, child_id):
children_activities = self.get_children_activities(dui=dui, reference_year=reference_year)
if child_id not in children_activities:
raise APIError('Child not found', err_code='not-found')
return children_activities[child_id]
def are_children_registered(self, dui, reference_year):
# check reference_year
today = datetime.date.today()
current_reference_year = utils.get_reference_year_from_date(today)
# don't check registration for other years than current and next
if reference_year not in [current_reference_year, current_reference_year + 1]:
return {}
# if next year, check dates.
# check registration for next year only in june or july
if reference_year == current_reference_year + 1 and today.month not in [6, 7]:
return {}
# ok, check registrations
try:
children_activities = self.get_children_activities(dui=dui, reference_year=reference_year)
except APIError:
# don't fail on the check
return {}
return {child_id: bool(child.get('ACTIVITE', [])) for child_id, child in children_activities.items()}
@endpoint(
description=_("Get information about CLAE booking"),

View File

@ -24,6 +24,7 @@ import mock
import os
import xml.etree.ElementTree as ET
import freezegun
import pytest
import xmlschema
@ -44,6 +45,7 @@ from passerelle.contrib.toulouse_axel.models import (
ref_verif_dui,
reservation_periode,
)
from passerelle.contrib.toulouse_axel.utils import get_reference_year_from_date
from passerelle.utils.jsonresponse import APIError
import utils
@ -662,6 +664,26 @@ def test_family_info_endpoint(app, resource):
'TELFIXE',
])
with mock.patch('passerelle.contrib.toulouse_axel.models.ToulouseAxel.are_children_registered') as registered:
registered.side_effect = [{'4242': True}, {}]
with mock_getdata(content, 'RefFamilleDui'):
resp = app.get('/toulouse-axel/test/family_info?NameID=yyy')
assert resp.json['err'] == 0
assert resp.json['data']['ENFANT'][0]['clae_cantine_current'] is True
assert resp.json['data']['ENFANT'][0]['clae_cantine_next'] is None
assert resp.json['data']['ENFANT'][1]['clae_cantine_current'] is None
assert resp.json['data']['ENFANT'][1]['clae_cantine_next'] is None
with mock.patch('passerelle.contrib.toulouse_axel.models.ToulouseAxel.are_children_registered') as registered:
registered.side_effect = [{}, {'4242': False, '3535': True}]
with mock_getdata(content, 'RefFamilleDui'):
resp = app.get('/toulouse-axel/test/family_info?NameID=yyy')
assert resp.json['err'] == 0
assert resp.json['data']['ENFANT'][0]['clae_cantine_current'] is None
assert resp.json['data']['ENFANT'][0]['clae_cantine_next'] is False
assert resp.json['data']['ENFANT'][1]['clae_cantine_current'] is None
assert resp.json['data']['ENFANT'][1]['clae_cantine_next'] is True
def test_child_info_endpoint_axel_error(app, resource):
Link.objects.create(resource=resource, name_id='yyy', dui='XXX', person_id='42')
@ -709,8 +731,26 @@ def test_child_info_endpoint(app, resource):
'RATTACHEAUTREDUI',
'SANITAIRE',
'SEXE',
'clae_cantine_current',
'clae_cantine_next',
])
with mock.patch('passerelle.contrib.toulouse_axel.models.ToulouseAxel.are_children_registered') as registered:
registered.side_effect = [{'4242': True}, {}]
with mock_getdata(content, 'RefFamilleDui'):
resp = app.get('/toulouse-axel/test/child_info?NameID=yyy&idpersonne=4242')
assert resp.json['err'] == 0
assert resp.json['data']['clae_cantine_current'] is True
assert resp.json['data']['clae_cantine_next'] is None
with mock.patch('passerelle.contrib.toulouse_axel.models.ToulouseAxel.are_children_registered') as registered:
registered.side_effect = [{}, {'4242': False}]
with mock_getdata(content, 'RefFamilleDui'):
resp = app.get('/toulouse-axel/test/child_info?NameID=yyy&idpersonne=4242')
assert resp.json['err'] == 0
assert resp.json['data']['clae_cantine_current'] is None
assert resp.json['data']['clae_cantine_next'] is False
def test_update_family_info_endpoint_axel_error(app, resource, update_params, family_data):
Link.objects.create(resource=resource, name_id='yyy', dui='XXX', person_id='42')
@ -786,7 +826,7 @@ def test_sanitize_update_family_data_missing_rl_fields(app, resource, update_par
assert key not in full_update_params['RL2']
with mock.patch('passerelle.contrib.toulouse_axel.models.ToulouseAxel.get_family_data', return_value=family_data):
resource.sanitize_update_family_data(name_id='yyy', post_data=full_update_params)
resource.sanitize_update_family_data(dui='XXX', post_data=full_update_params)
for key in ['IDPERSONNE', 'NOM', 'PRENOM', 'NOMJEUNEFILLE', 'DATENAISSANCE', 'CIVILITE']:
assert full_update_params['RL1'][key] == family_data['RL1'][key]
assert full_update_params['RL2'][key] == family_data['RL2'][key]
@ -801,14 +841,14 @@ def test_sanitize_update_family_data_missing_revenus_fields(app, resource, updat
assert 'NBENFANTSACHARGE' not in update_params['REVENUS']
with mock.patch('passerelle.contrib.toulouse_axel.models.ToulouseAxel.get_family_data', return_value=family_data):
resource.sanitize_update_family_data(name_id='yyy', post_data=full_update_params)
resource.sanitize_update_family_data(dui='XXX', post_data=full_update_params)
assert full_update_params['REVENUS']['NBENFANTSACHARGE'] == family_data['REVENUS']['NBENFANTSACHARGE']
# if revenus are not set in Axel
full_update_params = copy.deepcopy(update_params)
family_data.pop('REVENUS')
with mock.patch('passerelle.contrib.toulouse_axel.models.ToulouseAxel.get_family_data', return_value=family_data):
resource.sanitize_update_family_data(name_id='yyy', post_data=full_update_params)
resource.sanitize_update_family_data(dui='XXX', post_data=full_update_params)
assert full_update_params['REVENUS']['NBENFANTSACHARGE'] is None
@ -1089,7 +1129,7 @@ def test_sanitize_update_family_data_enfant_n_sanitaire_allergie(app, resource,
partial_update_params['ENFANT'][0]['SANITAIRE']['ALLERGIE']['ALIMENTAIRES'] = 'NON'
partial_update_params['ENFANT'][0]['SANITAIRE']['ALLERGIE']['AUTRES'] = ''
with mock.patch('passerelle.contrib.toulouse_axel.models.ToulouseAxel.get_family_data', return_value=family_data):
resource.sanitize_update_family_data(name_id='yyy', post_data=partial_update_params)
resource.sanitize_update_family_data(dui='XXX', post_data=partial_update_params)
assert partial_update_params['ENFANT'][0]['SANITAIRE']['ALLERGIE'] == [
{'TYPE': 'ASTHME', 'ALLERGIQUE': 'NON', 'NOMALLERGIE': None},
{'TYPE': 'MEDICAMENTEUSES', 'ALLERGIQUE': 'NON', 'NOMALLERGIE': None},
@ -1103,7 +1143,7 @@ def test_sanitize_update_family_data_enfant_n_sanitaire_allergie(app, resource,
partial_update_params['ENFANT'][0]['SANITAIRE']['ALLERGIE']['ALIMENTAIRES'] = 'OUI'
partial_update_params['ENFANT'][0]['SANITAIRE']['ALLERGIE']['AUTRES'] = 'accariens'
with mock.patch('passerelle.contrib.toulouse_axel.models.ToulouseAxel.get_family_data', return_value=family_data):
resource.sanitize_update_family_data(name_id='yyy', post_data=partial_update_params)
resource.sanitize_update_family_data(dui='XXX', post_data=partial_update_params)
assert partial_update_params['ENFANT'][0]['SANITAIRE']['ALLERGIE'] == [
{'TYPE': 'ASTHME', 'ALLERGIQUE': 'OUI', 'NOMALLERGIE': None},
{'TYPE': 'MEDICAMENTEUSES', 'ALLERGIQUE': 'OUI', 'NOMALLERGIE': None},
@ -1213,7 +1253,7 @@ def test_sanitize_update_family_data_enfant_n_sanitaire_handicap(app, resource,
resource.pre_sanitize_update_family_data(post_data=partial_update_params)
assert '_to_reset' in partial_update_params['ENFANT'][0]['SANITAIRE']['HANDICAP']
with mock.patch('passerelle.contrib.toulouse_axel.models.ToulouseAxel.get_family_data', return_value=family_data):
resource.sanitize_update_family_data(name_id='yyy', post_data=partial_update_params)
resource.sanitize_update_family_data(dui='XXX', post_data=partial_update_params)
assert len(partial_update_params['ENFANT']) == 1
assert partial_update_params['ENFANT'][0]['IDPERSONNE'] == "4242"
# fields were set with origin values found in Axel
@ -1228,7 +1268,7 @@ def test_sanitize_update_family_data_enfant_n_sanitaire_handicap(app, resource,
partial_update_params['maj:enfant_0'] = False
resource.pre_sanitize_update_family_data(post_data=partial_update_params)
with mock.patch('passerelle.contrib.toulouse_axel.models.ToulouseAxel.get_family_data', return_value=family_data):
resource.sanitize_update_family_data(name_id='yyy', post_data=partial_update_params)
resource.sanitize_update_family_data(dui='XXX', post_data=partial_update_params)
assert len(partial_update_params['ENFANT']) == 1
assert partial_update_params['ENFANT'][0]['IDPERSONNE'] == "3535"
assert 'SANITAIRE' not in partial_update_params['ENFANT'][0]
@ -1239,7 +1279,7 @@ def test_sanitize_update_family_data_enfant_n_sanitaire_handicap(app, resource,
partial_update_params['maj:enfant_0'] = False
resource.pre_sanitize_update_family_data(post_data=partial_update_params)
with mock.patch('passerelle.contrib.toulouse_axel.models.ToulouseAxel.get_family_data', return_value=family_data):
resource.sanitize_update_family_data(name_id='yyy', post_data=partial_update_params)
resource.sanitize_update_family_data(dui='XXX', post_data=partial_update_params)
assert 'ENFANT' not in partial_update_params
# test maj:enfant_n_sanitaire_handicap not set
@ -1252,7 +1292,7 @@ def test_sanitize_update_family_data_enfant_n_sanitaire_handicap(app, resource,
partial_update_params['ENFANT'][0]['SANITAIRE']['HANDICAP'][key] = None
resource.pre_sanitize_update_family_data(post_data=partial_update_params)
with mock.patch('passerelle.contrib.toulouse_axel.models.ToulouseAxel.get_family_data', return_value=family_data):
resource.sanitize_update_family_data(name_id='yyy', post_data=partial_update_params)
resource.sanitize_update_family_data(dui='XXX', post_data=partial_update_params)
new_values = partial_update_params['ENFANT'][0]['SANITAIRE']
for key in handicap_fields:
assert new_values[key] == family_data['ENFANT'][0]['SANITAIRE'][key]
@ -1277,7 +1317,7 @@ def test_sanitize_update_family_data_axel_error(app, resource, update_params, fl
with mock.patch('passerelle.contrib.toulouse_axel.models.ref_famille_dui') as operation:
operation.side_effect = AxelError('FooBar')
with pytest.raises(APIError, match='Axel error: FooBar'):
resource.sanitize_update_family_data(name_id='yyy', post_data=partial_update_params)
resource.sanitize_update_family_data(dui='XXX', post_data=partial_update_params)
def test_update_family_info_endpoint_sanitize_axel_error(app, resource, update_params):
@ -1945,3 +1985,44 @@ def test_clae_booking_info_endpoint(app, resource, child_activities_data):
assert resp.json['data']['ACTIVITE'][2]['booking'] == {}
assert resp.json['data']['ACTIVITE'][3]['IDACTIVITE'] == 'A19P1M4'
assert resp.json['data']['ACTIVITE'][3]['booking'] == {}
def test_are_children_registered_axel_error(resource):
with mock.patch('passerelle.contrib.toulouse_axel.models.enfants_activites') as operation:
operation.side_effect = AxelError('FooBar')
assert resource.are_children_registered(dui='XXX', reference_year=42) == {}
@pytest.mark.parametrize('date_value, year, expected', [
# neither current year nor next year
('2020-01-01', 2018, {}),
('2020-01-01', 2021, {}),
# current year
('2019-08-01', 2019, {'3535': True}),
('2020-07-31', 2019, {'3535': True}),
# too early for next_year
('2019-08-01', 2020, {}),
('2020-01-01', 2020, {}),
('2020-05-31', 2020, {}),
# good period for next year
('2020-06-01', 2020, {'3535': True}),
('2020-07-31', 2020, {'3535': True}),
])
def test_are_children_registered_reference_year(resource, date_value, year, expected):
with mock.patch('passerelle.contrib.toulouse_axel.models.ToulouseAxel.get_children_activities') as get_children_activities:
get_children_activities.return_value = {'3535': {'ACTIVITE': [{}]}}
with freezegun.freeze_time(date_value):
assert resource.are_children_registered(dui='XXX', reference_year=year) == expected
@pytest.mark.parametrize('activities, expected', [
({}, {}),
({'3535': {'ACTIVITE': []}}, {'3535': False}),
({'3535': {'ACTIVITE': [{}]}}, {'3535': True}),
({'3535': {'ACTIVITE': [{}]}, '4242': {}}, {'3535': True, '4242': False}),
])
def test_are_children_registered(resource, activities, expected):
today = datetime.date.today()
with mock.patch('passerelle.contrib.toulouse_axel.models.ToulouseAxel.get_children_activities') as get_children_activities:
get_children_activities.return_value = activities
assert resource.are_children_registered(dui='XXX', reference_year=get_reference_year_from_date(today)) == expected