toulouse-maelis: add webservices to manage childs (#67328)

This commit is contained in:
Nicolas Roche 2022-07-17 17:40:53 +02:00
parent 34b5803b55
commit 90a8f87f48
4 changed files with 405 additions and 2 deletions

View File

@ -325,17 +325,48 @@ class ToulouseMaelis(BaseResource, HTTPResource):
)
return {'data': person}
@endpoint(
display_category=_('Family'),
description="Informations sur un enfant",
perm='can_access',
name='read-child',
parameters={
'NameID': {'description': _('Publik ID')},
'child_id': {'description': "Numéro de l'enfant"},
},
)
def read_child(self, request, NameID, child_id):
family_id = self.get_link(NameID).family_id
data = self.get_family(family_id)
for child in data['childList']:
if child['num'] == child_id:
break
else:
raise APIError("no '%s' child on '%s' family" % (child_id, family_id), err_code='not-found')
return {'data': child}
@endpoint(
display_category=_('Family'),
description="Vérifier qu'un responsable légal existe en base",
perm='can_access',
name='is-rl-exists',
post={'request_body': {'schema': {'application/json': schemas.ISRLEXISTS_SCHEMA}}},
post={'request_body': {'schema': {'application/json': schemas.ISEXISTS_SCHEMA}}},
)
def is_rl_exists(self, request, post_data):
response = self.call('Family', 'isRLExists', **post_data)
return {'data': response}
@endpoint(
display_category=_('Family'),
description="Vérifier qu'un responsable légal existe en base",
perm='can_access',
name='is-child-exists',
post={'request_body': {'schema': {'application/json': schemas.ISEXISTS_SCHEMA}}},
)
def is_child_exists(self, request, post_data):
response = self.call('Family', 'isChildExists', **post_data)
return {'data': response}
@endpoint(
display_category=_('Family'),
description='Création de la famille',

View File

@ -52,7 +52,7 @@ LINK_SCHEMA = {
},
}
ISRLEXISTS_SCHEMA = {
ISEXISTS_SCHEMA = {
'$schema': 'http://json-schema.org/draft-04/schema#',
'title': 'Link',
'description': "Appairage d'un usager Publik à une famille dans Maelis",
@ -265,6 +265,299 @@ RLINFO_SCHEMA = {
},
}
CHILDBIRTH_SCHEMA = {
'$schema': 'http://json-schema.org/draft-04/schema#',
'title': 'Child birth',
'description': "Informations sur la naissance d'un enfant",
'type': 'object',
'required': ['dateBirth'],
'properties': {
'dateBirth': {
'description': 'Date de naissance',
'type': 'string',
'pattern': '^[0-9]{4}-[0-9]{2}-[0-9]{2}$',
},
'place': {
'description': 'Lieu de naissance',
'oneOf': [{'type': 'null'}, {'type': 'string'}],
},
},
}
FSL_SCHEMA = {
'$schema': 'http://json-schema.org/draft-04/schema#',
'title': 'FSL',
'description': 'Informations sur la fiche sanitaire',
'oneOf': [
{'type': 'null'},
{
'type': 'object',
'properties': {
'dateDeb': {
'description': 'Date de début',
'type': 'string',
'pattern': '^[0-9]{4}-[0-9]{2}-[0-9]{2}$',
},
'dateFin': {
'description': 'Date de fin',
'type': 'string',
'pattern': '^[0-9]{4}-[0-9]{2}-[0-9]{2}$',
},
'allergieAlimentaire': {
'description': 'Allergie alimentaire',
'oneOf': [{'type': 'null'}, {'type': 'string'}],
},
'allergieRespiratoire': {
'description': 'Allergie respiratoire',
'oneOf': [{'type': 'null'}, {'type': 'string'}],
},
'allergieAutre': {
'description': 'Allergie autre',
'oneOf': [{'type': 'null'}, {'type': 'string'}],
},
'allergieMedicament': {
'description': 'Allergie médicament',
'oneOf': [{'type': 'null'}, {'type': 'string'}],
},
'asthme': {
'description': 'Asthmatique',
'oneOf': [{'type': 'null'}, {'type': 'string'}],
},
'flPAI': {
'description': 'PAI',
'oneOf': [{'type': 'null'}, {'type': 'string'}],
},
'flImage': {
'description': 'Autorisation photo',
'oneOf': [{'type': 'null'}, {'type': 'string'}],
},
'dtcPrap1': {
'description': 'Date du dernier rappel DT Polio',
'type': 'string',
'pattern': '^[0-9]{4}-[0-9]{2}-[0-9]{2}$',
},
'obsMed1': {
'description': 'Observation médecin 1',
'oneOf': [{'type': 'null'}, {'type': 'string'}],
},
'obsMed2': {
'description': 'Observation médecin 2',
'oneOf': [{'type': 'null'}, {'type': 'string'}],
},
'obsMed3': {
'description': 'Observation médecin 3',
'oneOf': [{'type': 'null'}, {'type': 'string'}],
},
'obsDir1': {
'description': 'Observation directeur 1',
'oneOf': [{'type': 'null'}, {'type': 'string'}],
},
'obsDir2': {
'description': 'Observation directeur 2',
'oneOf': [{'type': 'null'}, {'type': 'string'}],
},
'obsDir3': {
'description': 'Observation directeur 3',
'oneOf': [{'type': 'null'}, {'type': 'string'}],
},
'obsAssist1': {
'description': 'Observation assistant sanitaire 1',
'oneOf': [{'type': 'null'}, {'type': 'string'}],
},
'obsAssist2': {
'description': 'Observation assistant sanitaire 2',
'oneOf': [{'type': 'null'}, {'type': 'string'}],
},
'obsAssist3': {
'description': 'Observation assistant sanitaire 3',
'oneOf': [{'type': 'null'}, {'type': 'string'}],
},
'cons1Med': {
'description': 'Conseil médecin 1',
'oneOf': [{'type': 'null'}, {'type': 'string'}],
},
'cons2Med': {
'description': 'Conseil médecin 2',
'oneOf': [{'type': 'null'}, {'type': 'string'}],
},
},
},
],
}
DOCTORADDRESS_SCHEMA = {
'$schema': 'http://json-schema.org/draft-04/schema#',
'title': 'Doctor address',
'description': "Informations sur l'adresse du docteur",
'type': 'object',
'properties': {
'street1': {
'description': 'Libellé de la voie',
'type': 'string',
},
'town': {
'description': 'Ville',
'type': 'string',
},
'zipcode': {
'description': 'Code postal',
'type': 'string',
},
},
}
FAMILYDOCTOR_SCHEMA = {
'$schema': 'http://json-schema.org/draft-04/schema#',
'title': 'Family doctor',
'description': "Informations sur le docteur",
'type': 'object',
'properties': {
'name': {
'description': 'Nom',
'oneOf': [{'type': 'null'}, {'type': 'string'}],
},
'phone': {
'description': 'Téléphone',
'oneOf': [{'type': 'null'}, {'type': 'string'}],
},
'address': DOCTORADDRESS_SCHEMA,
},
}
VACCIN_SCHEMA = {
'$schema': 'http://json-schema.org/draft-04/schema#',
'title': 'Vaccin',
'description': "Informations sur le vaccin",
'type': 'object',
'properties': {
'code': {
'description': 'Code du vaccin',
'oneOf': [{'type': 'null'}, {'type': 'string'}],
},
'label': {
'description': 'Nom du vaccin',
'oneOf': [{'type': 'null'}, {'type': 'string'}],
},
'vaccinationDate': {
'description': 'Date du vaccin',
'type': 'string',
'pattern': '^[0-9]{4}-[0-9]{2}-[0-9]{2}$',
},
},
}
MEDICALRECORD_SCHEMA = {
'$schema': 'http://json-schema.org/draft-04/schema#',
'title': 'Medical record',
'description': "Informations médicales",
'oneOf': [
{'type': 'null'},
{
'type': 'object',
'properties': {
'familyDoctor': FAMILYDOCTOR_SCHEMA,
'vaccinList': {
'oneOf': [
{'type': 'null'},
{
'type': 'array',
'items': VACCIN_SCHEMA,
},
],
},
},
},
],
}
PAIINFO_SCHEMA = {
'$schema': 'http://json-schema.org/draft-04/schema#',
'title': 'PAI Info',
'description': "Informations médicales",
'oneOf': [
{'type': 'null'},
{
'type': 'object',
'properties': {
'code': {
'description': 'Code',
'oneOf': [{'type': 'null'}, {'type': 'string'}],
},
'dateDeb': {
'description': 'Date de début',
'type': 'string',
'pattern': '^[0-9]{4}-[0-9]{2}-[0-9]{2}$',
},
'dateFin': {
'description': 'Date de fin',
'type': 'string',
'pattern': '^[0-9]{4}-[0-9]{2}-[0-9]{2}$',
},
'description': {
'description': 'Texte libre de description (max 500 caractères)',
'oneOf': [{'type': 'null'}, {'type': 'string'}],
},
},
},
],
}
"""
I was borred with WSDL specificities and provide all field for the 3 concerned endpoints.
Ex: on createFamily, "fsl" will be accepted, even if it should not be provided.
| enpoint | bean | fsl | dietcode | bPhoto | bLeaveAlone | paiInfoBean |
| createFamily | ChildBean | | X | | | |
| createChild | ChildCreateBean | | | X | X | X |
| updateFamily | ChildInfoBean | X | X | X | X | X |
"""
CHILD_SCHEMA = {
'$schema': 'http://json-schema.org/draft-04/schema#',
'title': 'Child',
'description': "Informations sur la création d'un enfant",
'type': 'object',
'required': ['sexe', 'firstname', 'lastname'],
'oneOf': [
{'required': ['dateBirth']}, # createFamily
{'required': ['birth']}, # updateFamily
],
'properties': {
'firstname': {
'description': 'Prénom',
'type': 'string',
},
'lastname': {
'description': 'Nom',
'type': 'string',
},
'sexe': {
'description': 'Sexe',
'type': 'string',
},
'dateBirth': {
'description': 'Date de naissance',
'type': 'string',
'pattern': '^[0-9]{4}-[0-9]{2}-[0-9]{2}$',
},
'birth': CHILDBIRTH_SCHEMA,
'dietcode': {
'description': 'Code de régime alimentaire',
'oneOf': [{'type': 'null'}, {'type': 'string'}],
},
'bPhoto': {
'description': 'Autorisation photo',
'oneOf': BOOLEAN_TYPES,
},
'bLeaveAlone': {
'description': 'Autorisation à partir seul',
'oneOf': BOOLEAN_TYPES,
},
'fsl': FSL_SCHEMA,
'medicalRecord': MEDICALRECORD_SCHEMA,
'paiInfoBean': PAIINFO_SCHEMA,
},
}
CONTACTLIGHT_SCHEMA = {
'$schema': 'http://json-schema.org/draft-04/schema#',
'title': 'Contact',
@ -393,6 +686,15 @@ CREATE_FAMILY_SCHEMA = {
},
],
},
'childList': {
'oneOf': [
{'type': 'null'},
{
'type': 'array',
'items': CHILD_SCHEMA,
},
],
},
},
'unflatten': True,
}

View File

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<ns2:isChildExistsResponse xmlns:ns2="family.ws.maelis.sigec.com">
<result>%s</result>
</ns2:isChildExistsResponse>
</soap:Body>
</soap:Envelope>

View File

@ -49,6 +49,10 @@ READ_QUALITIES = FakedResponse(content=get_xml_file('R_read_quality_list.xml'),
READ_SITUATIONS = FakedResponse(content=get_xml_file('R_read_situation_list.xml'), status_code=200)
IS_RL_EXISTS_TRUE = FakedResponse(content=get_xml_file('R_is_rl_exists.xml') % b'true', status_code=200)
IS_RL_EXISTS_FALSE = FakedResponse(content=get_xml_file('R_is_rl_exists.xml') % b'false', status_code=200)
IS_CHILD_EXISTS_TRUE = FakedResponse(content=get_xml_file('R_is_child_exists.xml') % b'true', status_code=200)
IS_CHILD_EXISTS_FALSE = FakedResponse(
content=get_xml_file('R_is_child_exists.xml') % b'false', status_code=200
)
CREATE_FAMILY = FakedResponse(content=get_xml_file('R_create_family.xml'), status_code=200)
CREATE_FAMILY_ERR = FakedResponse(content=get_xml_file('R_create_family_error.xml'), status_code=200)
UPDATE_FAMILY = FakedResponse(content=get_xml_file('R_update_family.xml'), status_code=200)
@ -587,6 +591,40 @@ def test_read_person_not_found(mocked_post, mocked_get, con, app):
assert resp.json['err_desc'] == "no '000000' emergency person on '1312' family"
@mock.patch('passerelle.utils.Request.get')
@mock.patch('passerelle.utils.Request.post')
def test_read_child(mocked_post, mocked_get, con, app):
mocked_get.return_value = FAMILY_SERVICE_WSDL
mocked_post.side_effect = [READ_FAMILY, READ_CATEGORIES, READ_SITUATIONS, READ_CIVILITIES, READ_QUALITIES]
url = get_endpoint('read-child')
Link.objects.create(resource=con, family_id='1312', name_id='local')
resp = app.get(url + '?NameID=local&child_id=613880')
assert resp.json['err'] == 0
assert resp.json['data']['firstname'] == 'CASSANDRA'
def test_read_child_not_linked_error(con, app):
url = get_endpoint('read-child')
resp = app.get(url + '?NameID=local&child_id=613880')
assert resp.json['err'] == 'not-linked'
assert resp.json['err_desc'] == 'User not linked to family'
@mock.patch('passerelle.utils.Request.get')
@mock.patch('passerelle.utils.Request.post')
def test_read_child_not_found(mocked_post, mocked_get, con, app):
mocked_get.return_value = FAMILY_SERVICE_WSDL
mocked_post.side_effect = [READ_FAMILY, READ_CATEGORIES, READ_SITUATIONS, READ_CIVILITIES, READ_QUALITIES]
url = get_endpoint('read-child')
Link.objects.create(resource=con, family_id='1312', name_id='local')
resp = app.get(url + '?NameID=local&child_id=000000')
assert resp.json['err'] == 'not-found'
assert resp.json['err_desc'] == "no '000000' child on '1312' family"
@pytest.mark.parametrize(
'post_response, result',
[
@ -624,6 +662,30 @@ def test_is_rl_exists_schema_error(con, app):
assert "does not match '^[0-9]{4}-[0-9]{2}-[0-9]{2}$'" in resp.json['err_desc']
@pytest.mark.parametrize(
'post_response, result',
[
(IS_CHILD_EXISTS_TRUE, True),
(IS_CHILD_EXISTS_FALSE, False),
],
)
@mock.patch('passerelle.utils.Request.get')
@mock.patch('passerelle.utils.Request.post')
def test_is_child_exists(mocked_post, mocked_get, post_response, result, con, app):
mocked_get.return_value = FAMILY_SERVICE_WSDL
mocked_post.return_value = post_response
url = get_endpoint('is-child-exists')
params = {
'firstname': 'Cassandra',
'lastname': 'Costanze',
'datebirth': '2021-06-22',
}
resp = app.post_json(url, params=params)
assert resp.json['err'] == 0
assert resp.json['data'] == result
@mock.patch('passerelle.utils.Request.get')
@mock.patch('passerelle.utils.Request.post')
def test_create_family(mocked_post, mocked_get, con, app):