0004-toulouse_maelis-add-FSL-webservice-69045.patch
passerelle/contrib/toulouse_maelis/models.py | ||
---|---|---|
153 | 153 |
for child in data['childList']: |
154 | 154 |
add_text_value('Sex', child, ['sexe']) |
155 | 155 |
add_text_value('DietCode', child, ['dietcode']) |
156 | 156 |
add_text_value('PAI', child, ['paiInfoBean', 'code']) |
157 | 157 |
for kind in ('authorized', 'emergency'): |
158 | 158 |
for person in data[kind + 'PersonList']: |
159 | 159 |
add_text_value('Civility', person, ['civility']) |
160 | 160 |
add_text_value('Quality', person, ['quality']) |
161 | ||
162 |
# convert O/N string into boolean |
|
163 |
for child in data['childList']: |
|
164 |
if child.get('fsl'): |
|
165 |
for key in ( |
|
166 |
'allergieAlimentaire', |
|
167 |
'allergieRespiratoire', |
|
168 |
'allergieAutre', |
|
169 |
'allergieMedicament', |
|
170 |
'asthme', |
|
171 |
'flPAI', |
|
172 |
'flImage', |
|
173 |
): |
|
174 |
child['fsl'][key] = bool(child['fsl'][key] == 'O') |
|
161 | 175 |
return data |
162 | 176 | |
163 | 177 |
def replace_null_values(self, dico): |
164 | 178 |
'''send null fields as empty SOAP tag to tell maelis to empty the value''' |
165 | 179 |
for key, value in dico.items(): |
166 | 180 |
if isinstance(value, dict): |
167 | 181 |
self.replace_null_values(value) |
168 | 182 |
if value is None: |
... | ... | |
619 | 633 |
# use None to empty date passed as an empty string by date filter |
620 | 634 |
for key in 'dateDeb', 'dateFin': |
621 | 635 |
if post_data[key] == '': |
622 | 636 |
post_data[key] = None |
623 | 637 | |
624 | 638 |
self.call('Family', 'updateChildPAI', personNumber=child_id, **post_data) |
625 | 639 |
return {'data': 'ok'} |
626 | 640 | |
641 |
@endpoint( |
|
642 |
display_category='Famille', |
|
643 |
description="Créer ou mettre à jour la fiche sanitaire d'un enfant", |
|
644 |
name='update-child-fsl', |
|
645 |
perm='can_access', |
|
646 |
parameters={ |
|
647 |
'NameID': {'description': 'Publik NameID'}, |
|
648 |
'child_id': {'description': "Numéro de l'enfant"}, |
|
649 |
}, |
|
650 |
post={'request_body': {'schema': {'application/json': schemas.FSL_SCHEMA}}}, |
|
651 |
) |
|
652 |
def update_child_fsl(self, request, NameID, child_id, post_data): |
|
653 |
self.get_link(NameID) |
|
654 | ||
655 |
# maelis expect strings O/N |
|
656 |
for key in ( |
|
657 |
'allergieAlimentaire', |
|
658 |
'allergieRespiratoire', |
|
659 |
'allergieAutre', |
|
660 |
'allergieMedicament', |
|
661 |
'asthme', |
|
662 |
'flPAI', |
|
663 |
'flImage', |
|
664 |
): |
|
665 |
post_data[key] = 'O' if post_data.get(key) else 'N' |
|
666 | ||
667 |
# use None to empty optional date passed as an empty string by date filter |
|
668 |
if post_data.get('dtcPrap1') == '': |
|
669 |
post_data['dtcPrap1'] = None |
|
670 | ||
671 |
self.call('Family', 'createOrUpdateFSL', arg0=child_id, arg1=post_data) |
|
672 |
return {'data': 'ok'} |
|
673 | ||
627 | 674 | |
628 | 675 |
class Link(models.Model): |
629 | 676 |
resource = models.ForeignKey(ToulouseMaelis, on_delete=models.CASCADE) |
630 | 677 |
name_id = models.CharField(blank=False, max_length=256) |
631 | 678 |
family_id = models.CharField(blank=False, max_length=128) |
632 | 679 |
created = models.DateTimeField(auto_now_add=True) |
633 | 680 |
updated = models.DateTimeField(auto_now=True) |
634 | 681 |
passerelle/contrib/toulouse_maelis/schemas.py | ||
---|---|---|
281 | 281 |
}, |
282 | 282 |
'dateFin': { |
283 | 283 |
'description': 'Date de fin', |
284 | 284 |
'type': 'string', |
285 | 285 |
'pattern': '^[0-9]{4}-[0-9]{2}-[0-9]{2}$', |
286 | 286 |
}, |
287 | 287 |
'allergieAlimentaire': { |
288 | 288 |
'description': 'Allergie alimentaire', |
289 |
'oneOf': [{'type': 'null'}, {'type': 'string'}],
|
|
289 |
'oneOf': [{'type': 'null'}] + BOOLEAN_TYPES,
|
|
290 | 290 |
}, |
291 | 291 |
'allergieRespiratoire': { |
292 | 292 |
'description': 'Allergie respiratoire', |
293 |
'oneOf': [{'type': 'null'}, {'type': 'string'}],
|
|
293 |
'oneOf': [{'type': 'null'}] + BOOLEAN_TYPES,
|
|
294 | 294 |
}, |
295 | 295 |
'allergieAutre': { |
296 | 296 |
'description': 'Allergie autre', |
297 |
'oneOf': [{'type': 'null'}, {'type': 'string'}],
|
|
297 |
'oneOf': [{'type': 'null'}] + BOOLEAN_TYPES,
|
|
298 | 298 |
}, |
299 | 299 |
'allergieMedicament': { |
300 | 300 |
'description': 'Allergie médicament', |
301 |
'oneOf': [{'type': 'null'}, {'type': 'string'}],
|
|
301 |
'oneOf': [{'type': 'null'}] + BOOLEAN_TYPES,
|
|
302 | 302 |
}, |
303 | 303 |
'asthme': { |
304 | 304 |
'description': 'Asthmatique', |
305 |
'oneOf': [{'type': 'null'}, {'type': 'string'}],
|
|
305 |
'oneOf': [{'type': 'null'}] + BOOLEAN_TYPES,
|
|
306 | 306 |
}, |
307 | 307 |
'flPAI': { |
308 | 308 |
'description': 'PAI', |
309 |
'oneOf': [{'type': 'null'}, {'type': 'string'}],
|
|
309 |
'oneOf': [{'type': 'null'}] + BOOLEAN_TYPES,
|
|
310 | 310 |
}, |
311 | 311 |
'flImage': { |
312 | 312 |
'description': 'Autorisation photo', |
313 |
'oneOf': [{'type': 'null'}, {'type': 'string'}],
|
|
313 |
'oneOf': [{'type': 'null'}] + BOOLEAN_TYPES,
|
|
314 | 314 |
}, |
315 | 315 |
'dtcPrap1': { |
316 | 316 |
'description': 'Date du dernier rappel DT Polio', |
317 | 317 |
'type': 'string', |
318 |
'pattern': '^[0-9]{4}-[0-9]{2}-[0-9]{2}$',
|
|
318 |
'pattern': '^([0-9]{4}-[0-9]{2}-[0-9]{2}){0,1}$',
|
|
319 | 319 |
}, |
320 | 320 |
'obsMed1': { |
321 | 321 |
'description': 'Observation médecin 1', |
322 | 322 |
'oneOf': [{'type': 'null'}, {'type': 'string'}], |
323 | 323 |
}, |
324 | 324 |
'obsMed2': { |
325 | 325 |
'description': 'Observation médecin 2', |
326 | 326 |
'oneOf': [{'type': 'null'}, {'type': 'string'}], |
tests/data/toulouse_maelis/Q_update_child_fsl.xml | ||
---|---|---|
1 |
<soap-env:Envelope xmlns:soap-env="http://schemas.xmlsoap.org/soap/envelope/"> |
|
2 |
<soap-env:Header> |
|
3 |
<wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"> |
|
4 |
<wsse:UsernameToken> |
|
5 |
<wsse:Username>maelis-webservice</wsse:Username> |
|
6 |
<wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">maelis-password</wsse:Password> |
|
7 |
</wsse:UsernameToken> |
|
8 |
</wsse:Security> |
|
9 |
</soap-env:Header> |
|
10 |
<soap-env:Body> |
|
11 |
<ns0:createOrUpdateFSL xmlns:ns0="family.ws.maelis.sigec.com"> |
|
12 |
<arg0>613878</arg0> |
|
13 |
<arg1> |
|
14 |
<dateDeb>2022-01-01</dateDeb> |
|
15 |
<dateFin>2022-12-31</dateFin> |
|
16 |
<allergieAlimentaire>O</allergieAlimentaire> |
|
17 |
<allergieRespiratoire>O</allergieRespiratoire> |
|
18 |
<allergieAutre>O</allergieAutre> |
|
19 |
<allergieMedicament>O</allergieMedicament> |
|
20 |
<asthme>N</asthme> |
|
21 |
<flPAI>N</flPAI> |
|
22 |
<flImage>N</flImage> |
|
23 |
<dtcPrap1>2022-02-22</dtcPrap1> |
|
24 |
<obsMed1>some obsMed1 text</obsMed1> |
|
25 |
<obsMed2>some obsMed2 text</obsMed2> |
|
26 |
<obsMed3>some obsMed3 text</obsMed3> |
|
27 |
<obsDir1>some obsDir1 text</obsDir1> |
|
28 |
<obsDir2>some obsDir2 text</obsDir2> |
|
29 |
<obsDir3>some obsDir3 text</obsDir3> |
|
30 |
<obsAssist1>some obsAssist1 text</obsAssist1> |
|
31 |
<obsAssist2>some obsAssist2 text</obsAssist2> |
|
32 |
<obsAssist3>some obsAssist3 text</obsAssist3> |
|
33 |
<cons1Med>some cons1Med text</cons1Med> |
|
34 |
<cons2Med>some cons2Med text</cons2Med> |
|
35 |
</arg1> |
|
36 |
</ns0:createOrUpdateFSL> |
|
37 |
</soap-env:Body> |
|
38 |
</soap-env:Envelope> |
tests/data/toulouse_maelis/R_update_child_fsl.xml | ||
---|---|---|
1 |
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"> |
|
2 |
<soap:Body> |
|
3 |
<ns2:createOrUpdateFSLResponse xmlns:ns2="family.ws.maelis.sigec.com"/> |
|
4 |
</soap:Body> |
|
5 |
</soap:Envelope> |
tests/data/toulouse_maelis/R_update_child_fsl_soap_error.xml | ||
---|---|---|
1 |
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"> |
|
2 |
<soap:Body> |
|
3 |
<soap:Fault> |
|
4 |
<faultcode>soap:Server</faultcode> |
|
5 |
<faultstring>Une erreur est survenue : java.sql.SQLException: ORA-12899: valeur trop grande pour la colonne "MAELIS"."H_FICHESAN"."FS_OBSMED1" (réelle : 71, maximum : 70) |
|
6 |
</faultstring> |
|
7 |
<detail> |
|
8 |
<ns1:MaelisFamilyException xmlns:ns1="family.ws.maelis.sigec.com"> |
|
9 |
<message xmlns:ns2="family.ws.maelis.sigec.com">Une erreur est survenue : java.sql.SQLException: ORA-12899: valeur trop grande pour la colonne "MAELIS"."H_FICHESAN"."FS_OBSMED1" (réelle : 71, maximum : 70) |
|
10 |
</message> |
|
11 |
</ns1:MaelisFamilyException> |
|
12 |
</detail> |
|
13 |
</soap:Fault> |
|
14 |
</soap:Body> |
|
15 |
</soap:Envelope> |
tests/test_toulouse_maelis.py | ||
---|---|---|
62 | 62 |
CREATE_FAMILY = FakedResponse(content=get_xml_file('R_create_family.xml'), status_code=200) |
63 | 63 |
CREATE_FAMILY_ERR = FakedResponse(content=get_xml_file('R_create_family_error.xml'), status_code=200) |
64 | 64 |
UPDATE_FAMILY = FakedResponse(content=get_xml_file('R_update_family.xml'), status_code=200) |
65 | 65 |
UPDATE_FAMILY_ERR = FakedResponse(content=get_xml_file('R_update_family_error.xml'), status_code=200) |
66 | 66 |
UPDATE_FAMILY_500 = FakedResponse(content=get_xml_file('R_update_family_soap_error.xml'), status_code=500) |
67 | 67 |
UPDATE_DIETCODE = FakedResponse(content=get_xml_file('R_update_child_dietcode.xml'), status_code=200) |
68 | 68 |
UPDATE_PAI = FakedResponse(content=get_xml_file('R_update_child_pai.xml'), status_code=200) |
69 | 69 |
UPDATE_PAI_500 = FakedResponse(content=get_xml_file('R_update_child_pai_soap_error.xml'), status_code=500) |
70 |
UPDATE_FSL = FakedResponse(content=get_xml_file('R_update_child_fsl.xml'), status_code=200) |
|
71 |
UPDATE_FSL_500 = FakedResponse(content=get_xml_file('R_update_child_fsl_soap_error.xml'), status_code=500) |
|
70 | 72 | |
71 | 73 | |
72 | 74 |
def assert_sent_payload(mocked_post, query_file): |
73 | 75 |
soap_sent = etree.tostring(etree.fromstring(mocked_post.call_args.kwargs['data']), pretty_print=True) |
74 | 76 |
expected = etree.tostring(etree.fromstring(get_xml_file(query_file)), pretty_print=True) |
75 | 77 |
assert soap_sent.decode() == expected.decode() |
76 | 78 | |
77 | 79 | |
... | ... | |
610 | 612 |
'dateDeb': '2022-01-01T00:00:00+01:00', |
611 | 613 |
'dateFin': '2022-12-31T00:00:00+01:00', |
612 | 614 |
'description': 'bla bla PAI', |
613 | 615 |
}, |
614 | 616 |
} |
615 | 617 |
assert resp.json['data']['childList'][0]['fsl'] == { |
616 | 618 |
'dateDeb': '2022-01-01T00:00:00+01:00', |
617 | 619 |
'dateFin': '2022-12-31T00:00:00+01:00', |
618 |
'allergieAlimentaire': 'O',
|
|
619 |
'allergieRespiratoire': 'O',
|
|
620 |
'allergieAutre': 'O',
|
|
621 |
'allergieMedicament': 'O',
|
|
622 |
'asthme': 'N',
|
|
623 |
'flPAI': 'N',
|
|
624 |
'flImage': 'N',
|
|
620 |
'allergieAlimentaire': True,
|
|
621 |
'allergieRespiratoire': True,
|
|
622 |
'allergieAutre': True,
|
|
623 |
'allergieMedicament': True,
|
|
624 |
'asthme': False,
|
|
625 |
'flPAI': False,
|
|
626 |
'flImage': False,
|
|
625 | 627 |
'dtcPrap1': '2022-02-22T00:00:00+01:00', |
626 | 628 |
'obsMed1': 'some obsMed1 text', |
627 | 629 |
'obsMed2': 'some obsMed2 text', |
628 | 630 |
'obsMed3': 'some obsMed3 text', |
629 | 631 |
'obsDir1': 'some obsDir1 text', |
630 | 632 |
'obsDir2': 'some obsDir2 text', |
631 | 633 |
'obsDir3': 'some obsDir3 text', |
632 | 634 |
'obsAssist1': 'some obsAssist1 text', |
... | ... | |
1456 | 1458 |
} |
1457 | 1459 | |
1458 | 1460 |
Link.objects.create(resource=con, family_id='1312', name_id='local') |
1459 | 1461 |
resp = app.post_json(url + '?NameID=local&child_id=613878', params=params) |
1460 | 1462 |
assert resp.json['err'] == 'Family-updateChildPAI-soap:Server' |
1461 | 1463 |
assert 'Une erreur est survenue' in resp.json['err_desc'] |
1462 | 1464 |
assert 'valeur trop grande' in resp.json['err_desc'] |
1463 | 1465 |
assert 'maximum : 500' in resp.json['err_desc'] |
1466 | ||
1467 | ||
1468 |
@mock.patch('passerelle.utils.Request.get') |
|
1469 |
@mock.patch('passerelle.utils.Request.post') |
|
1470 |
def test_update_child_fsl(mocked_post, mocked_get, con, app): |
|
1471 |
mocked_get.return_value = FAMILY_SERVICE_WSDL |
|
1472 |
mocked_post.return_value = UPDATE_FSL |
|
1473 |
url = get_endpoint('update-child-fsl') |
|
1474 |
params = { |
|
1475 |
'dateDeb': '2022-01-01', |
|
1476 |
'dateFin': '2022-12-31', |
|
1477 |
'allergieAlimentaire': True, |
|
1478 |
'allergieRespiratoire': True, |
|
1479 |
'allergieAutre': True, |
|
1480 |
'allergieMedicament': True, |
|
1481 |
'asthme': False, |
|
1482 |
'flPAI': False, |
|
1483 |
'flImage': False, |
|
1484 |
'dtcPrap1': '2022-02-22', |
|
1485 |
'obsMed1': 'some obsMed1 text', |
|
1486 |
'obsMed2': 'some obsMed2 text', |
|
1487 |
'obsMed3': 'some obsMed3 text', |
|
1488 |
'obsDir1': 'some obsDir1 text', |
|
1489 |
'obsDir2': 'some obsDir2 text', |
|
1490 |
'obsDir3': 'some obsDir3 text', |
|
1491 |
'obsAssist1': 'some obsAssist1 text', |
|
1492 |
'obsAssist2': 'some obsAssist2 text', |
|
1493 |
'obsAssist3': 'some obsAssist3 text', |
|
1494 |
'cons1Med': 'some cons1Med text', |
|
1495 |
'cons2Med': 'some cons2Med text', |
|
1496 |
} |
|
1497 | ||
1498 |
Link.objects.create(resource=con, family_id='1312', name_id='local') |
|
1499 |
resp = app.post_json(url + '?NameID=local&child_id=613878', params=params) |
|
1500 |
assert_sent_payload(mocked_post, 'Q_update_child_fsl.xml') |
|
1501 |
assert resp.json['err'] == 0 |
|
1502 |
assert resp.json['data'] == 'ok' |
|
1503 | ||
1504 | ||
1505 |
def test_update_child_fsl_not_linked_error(con, app): |
|
1506 |
url = get_endpoint('update-child-fsl') |
|
1507 |
params = { |
|
1508 |
'dateDeb': '2022-01-01', |
|
1509 |
'dateFin': '2022-12-31', |
|
1510 |
} |
|
1511 | ||
1512 |
resp = app.post_json(url + '?NameID=local&child_id=613878', params=params) |
|
1513 |
assert resp.json['err'] == 'not-linked' |
|
1514 |
assert resp.json['err_desc'] == 'User not linked to family' |
|
1515 | ||
1516 | ||
1517 |
@mock.patch('passerelle.utils.Request.get') |
|
1518 |
@mock.patch('passerelle.utils.Request.post') |
|
1519 |
def test_update_child_fsl_soap_error(mocked_post, mocked_get, con, app): |
|
1520 |
mocked_get.return_value = FAMILY_SERVICE_WSDL |
|
1521 |
mocked_post.return_value = UPDATE_FSL_500 |
|
1522 |
url = get_endpoint('update-child-fsl') |
|
1523 |
params = { |
|
1524 |
'dateDeb': '2022-01-01', |
|
1525 |
'dateFin': '2022-12-31', |
|
1526 |
'obsMed1': 'a' * 71, |
|
1527 |
} |
|
1528 | ||
1529 |
Link.objects.create(resource=con, family_id='1312', name_id='local') |
|
1530 |
resp = app.post_json(url + '?NameID=local&child_id=613878', params=params) |
|
1531 |
assert resp.json['err'] == 'Family-createOrUpdateFSL-soap:Server' |
|
1532 |
assert 'Une erreur est survenue' in resp.json['err_desc'] |
|
1533 |
assert 'valeur trop grande' in resp.json['err_desc'] |
|
1534 |
assert 'maximum : 70' in resp.json['err_desc'] |
|
1464 |
- |