From d8a6f39736c900fd81b38fbb2359df96a7cf2f18 Mon Sep 17 00:00:00 2001
From: Nicolas ROCHE <nroche@entrouvert.com>
Date: Sun, 11 Sep 2022 17:03:32 +0200
Subject: [PATCH 2/5] toulouse_maelis: add dietcode webservice (#69045)

---
 passerelle/contrib/toulouse_maelis/models.py  | 19 +++++++++++
 .../Q_update_child_dietcode.xml               | 16 ++++++++++
 .../R_update_child_dietcode.xml               |  5 +++
 tests/test_toulouse_maelis.py                 | 32 +++++++++++++++++++
 4 files changed, 72 insertions(+)
 create mode 100644 tests/data/toulouse_maelis/Q_update_child_dietcode.xml
 create mode 100644 tests/data/toulouse_maelis/R_update_child_dietcode.xml

diff --git a/passerelle/contrib/toulouse_maelis/models.py b/passerelle/contrib/toulouse_maelis/models.py
index 68787b34..970f1210 100644
--- a/passerelle/contrib/toulouse_maelis/models.py
+++ b/passerelle/contrib/toulouse_maelis/models.py
@@ -147,16 +147,17 @@ class ToulouseMaelis(BaseResource, HTTPResource):
         add_text_value('Situation', data, ['situation'])
         for rlg in 'RL1', 'RL2':
             add_text_value('Civility', data, [rlg, 'civility'])
             add_text_value('Quality', data, [rlg, 'quality'])
             add_text_value('Complement', data, [rlg, 'adresse', 'numComp'])
             add_text_value('CSP', data, [rlg, 'profession', 'codeCSP'])
         for child in data['childList']:
             add_text_value('Sex', child, ['sexe'])
+            add_text_value('DietCode', child, ['dietcode'])
         for kind in ('authorized', 'emergency'):
             for person in data[kind + 'PersonList']:
                 add_text_value('Civility', person, ['civility'])
                 add_text_value('Quality', person, ['quality'])
         return data
 
     def replace_null_values(self, dico):
         '''send null fields as empty SOAP tag to tell maelis to empty the value'''
@@ -577,16 +578,34 @@ class ToulouseMaelis(BaseResource, HTTPResource):
             'dossierNumber': family_id,
             'categorie': family['category'],
             'situation': family['situation'],
             kind + 'PersonList': [{'personList': personList}],
         }
         self.call('Family', 'updateFamily', **payload)
         return {'data': 'ok'}
 
+    @endpoint(
+        display_category='Famille',
+        description="Créer ou mettre à jour le régime alimentaire d'un enfant",
+        name='update-child-dietcode',
+        perm='can_access',
+        parameters={
+            'NameID': {'description': 'Publik NameID'},
+            'child_id': {'description': "Numéro de l'enfant"},
+            'dietcode': {'description': 'code du régime alimentaire'},
+        },
+        methods=['post'],
+    )
+    def update_child_dietcode(self, request, NameID, child_id, dietcode):
+        self.get_link(NameID)
+
+        self.call('Family', 'createOrUpdateChildDiet', personNumber=child_id, code=dietcode)
+        return {'data': 'ok'}
+
 
 class Link(models.Model):
     resource = models.ForeignKey(ToulouseMaelis, on_delete=models.CASCADE)
     name_id = models.CharField(blank=False, max_length=256)
     family_id = models.CharField(blank=False, max_length=128)
     created = models.DateTimeField(auto_now_add=True)
     updated = models.DateTimeField(auto_now=True)
 
diff --git a/tests/data/toulouse_maelis/Q_update_child_dietcode.xml b/tests/data/toulouse_maelis/Q_update_child_dietcode.xml
new file mode 100644
index 00000000..a38f924e
--- /dev/null
+++ b/tests/data/toulouse_maelis/Q_update_child_dietcode.xml
@@ -0,0 +1,16 @@
+<soap-env:Envelope xmlns:soap-env="http://schemas.xmlsoap.org/soap/envelope/">
+  <soap-env:Header>
+    <wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
+      <wsse:UsernameToken>
+        <wsse:Username>maelis-webservice</wsse:Username>
+        <wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">maelis-password</wsse:Password>
+      </wsse:UsernameToken>
+    </wsse:Security>
+  </soap-env:Header>
+  <soap-env:Body>
+    <ns0:createOrUpdateChildDiet xmlns:ns0="family.ws.maelis.sigec.com">
+      <personNumber>613878</personNumber>
+      <code>RSV</code>
+    </ns0:createOrUpdateChildDiet>
+  </soap-env:Body>
+</soap-env:Envelope>
diff --git a/tests/data/toulouse_maelis/R_update_child_dietcode.xml b/tests/data/toulouse_maelis/R_update_child_dietcode.xml
new file mode 100644
index 00000000..5a305508
--- /dev/null
+++ b/tests/data/toulouse_maelis/R_update_child_dietcode.xml
@@ -0,0 +1,5 @@
+<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
+  <soap:Body>
+    <ns2:createOrUpdateChildDietResponse xmlns:ns2="family.ws.maelis.sigec.com"/>
+  </soap:Body>
+</soap:Envelope>
diff --git a/tests/test_toulouse_maelis.py b/tests/test_toulouse_maelis.py
index ae105e6e..51cc256a 100644
--- a/tests/test_toulouse_maelis.py
+++ b/tests/test_toulouse_maelis.py
@@ -59,16 +59,17 @@ IS_CHILD_EXISTS_TRUE = FakedResponse(content=get_xml_file('R_is_child_exists.xml
 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)
 UPDATE_FAMILY_ERR = FakedResponse(content=get_xml_file('R_update_family_error.xml'), status_code=200)
 UPDATE_FAMILY_500 = FakedResponse(content=get_xml_file('R_update_family_soap_error.xml'), status_code=500)
+UPDATE_DIETCODE = FakedResponse(content=get_xml_file('R_update_child_dietcode.xml'), status_code=200)
 
 
 def assert_sent_payload(mocked_post, query_file):
     soap_sent = etree.tostring(etree.fromstring(mocked_post.call_args.kwargs['data']), pretty_print=True)
     expected = etree.tostring(etree.fromstring(get_xml_file(query_file)), pretty_print=True)
     assert soap_sent.decode() == expected.decode()
 
 
@@ -517,16 +518,17 @@ def test_read_family(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,
         READ_CSP,
+        READ_DIETCODE,
     ]
     url = get_endpoint('read-family')
     Link.objects.create(resource=con, family_id='1312', name_id='local')
 
     resp = app.get(url + '?NameID=local')
     assert resp.json['err'] == 0
     data = resp.json['data']
     del data['RL1']
@@ -584,16 +586,17 @@ def test_read_family(mocked_post, mocked_get, con, app):
     assert data == {
         'num': '613880',
         'lastname': 'DOE',
         'firstname': 'JANNIS',
         'sexe': 'F',
         'sexe_text': 'Féminin',
         'birth': {'dateBirth': '1943-01-19T00:00:00+01:00', 'place': None},
         'dietcode': 'RSV',
+        'dietcode_text': '3- RÉGIME SANS VIANDE',
         'bPhoto': False,
         'bLeaveAlone': False,
         'authorizedPersonList': [],
         'indicatorList': [],
         'subscribeSchoolList': [],
         'mother': {'num': 613963, 'civility': 'MME', 'firstname': 'JANE', 'lastname': 'DOE'},
         'father': {'num': 613878, 'civility': 'M.', 'firstname': 'JHON', 'lastname': 'DOE'},
         'rl': None,
@@ -679,16 +682,17 @@ def test_read_rl1(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,
         READ_CSP,
+        READ_DIETCODE,
     ]
     url = get_endpoint('read-rl')
     Link.objects.create(resource=con, family_id='1312', name_id='local')
 
     resp = app.get(url + '?NameID=local&rl_id=613878')
     assert resp.json['err'] == 0
     assert resp.json['data']['firstname'] == 'JHON'
 
@@ -699,16 +703,17 @@ def test_read_rl2(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,
         READ_CSP,
+        READ_DIETCODE,
     ]
     url = get_endpoint('read-rl')
     Link.objects.create(resource=con, family_id='1312', name_id='local')
 
     resp = app.get(url + '?NameID=local&rl_id=613879')
     assert resp.json['err'] == 0
     assert resp.json['data'] == {
         'num': '613879',
@@ -762,16 +767,17 @@ def test_read_rl_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,
         READ_CSP,
+        READ_DIETCODE,
     ]
     url = get_endpoint('read-rl')
     Link.objects.create(resource=con, family_id='1312', name_id='local')
 
     resp = app.get(url + '?NameID=local&rl_id=000000')
     assert resp.json['err'] == 'not-found'
     assert resp.json['err_desc'] == "no '000000' RL on '1312' family"
 
@@ -782,16 +788,17 @@ def test_read_person(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,
         READ_CSP,
+        READ_DIETCODE,
     ]
     url = get_endpoint('read-person')
     Link.objects.create(resource=con, family_id='1312', name_id='local')
 
     resp = app.get(url + '?NameID=local&person_id=614059&kind=emergency')
     assert resp.json['err'] == 0
     assert resp.json['data']['firstname'] == 'KENY'
 
@@ -818,16 +825,17 @@ def test_read_person_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,
         READ_CSP,
+        READ_DIETCODE,
     ]
     url = get_endpoint('read-person')
     Link.objects.create(resource=con, family_id='1312', name_id='local')
 
     resp = app.get(url + '?NameID=local&person_id=000000&kind=emergency')
     assert resp.json['err'] == 'not-found'
     assert resp.json['err_desc'] == "no '000000' emergency person on '1312' family"
 
@@ -838,16 +846,17 @@ 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,
         READ_CSP,
+        READ_DIETCODE,
     ]
     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'] == 'JANNIS'
 
@@ -866,16 +875,17 @@ 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,
         READ_CSP,
+        READ_DIETCODE,
     ]
     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"
 
@@ -1358,8 +1368,30 @@ def test_delete_person_not_found(mocked_post, mocked_get, con, app):
         'contact/mobile': '0623456789',
         'contact/mail': None,
     }
 
     Link.objects.create(resource=con, family_id='1312', name_id='local')
     resp = app.post_json(url + '?NameID=local&person_id=000000&kind=emergency', params=params)
     assert resp.json['err'] == 'not-found'
     assert resp.json['err_desc'] == "no '000000' authorized person on '1312' family"
+
+
+@mock.patch('passerelle.utils.Request.get')
+@mock.patch('passerelle.utils.Request.post')
+def test_update_child_dietcode(mocked_post, mocked_get, con, app):
+    mocked_get.return_value = FAMILY_SERVICE_WSDL
+    mocked_post.return_value = UPDATE_DIETCODE
+    url = get_endpoint('update-child-dietcode')
+
+    Link.objects.create(resource=con, family_id='1312', name_id='local')
+    resp = app.post_json(url + '?NameID=local&child_id=613878&dietcode=RSV')
+    assert_sent_payload(mocked_post, 'Q_update_child_dietcode.xml')
+    assert resp.json['err'] == 0
+    assert resp.json['data'] == 'ok'
+
+
+def test_update_child_dietcode_not_linked_error(con, app):
+    url = get_endpoint('update-child-dietcode')
+
+    resp = app.post_json(url + '?NameID=local&child_id=613878&dietcode=RVS')
+    assert resp.json['err'] == 'not-linked'
+    assert resp.json['err_desc'] == 'User not linked to family'
-- 
2.30.2

