From c09863f6edc982cf6f770eb2c010f658869b179b Mon Sep 17 00:00:00 2001
From: Nicolas ROCHE <nroche@entrouvert.com>
Date: Wed, 14 Dec 2022 17:11:53 +0100
Subject: [PATCH] toulouse-maelis: add enpoints to list family members (#72411)

---
 functests/toulouse_maelis/test_family.py     |  89 ++++++++++++++
 passerelle/contrib/toulouse_maelis/models.py | 120 ++++++++++++++++++-
 tests/test_toulouse_maelis.py                | 114 ++++++++++++++++++
 3 files changed, 322 insertions(+), 1 deletion(-)

diff --git a/functests/toulouse_maelis/test_family.py b/functests/toulouse_maelis/test_family.py
index 722d2c44..c71e5cc3 100644
--- a/functests/toulouse_maelis/test_family.py
+++ b/functests/toulouse_maelis/test_family.py
@@ -807,8 +807,97 @@ def test_update_quotient(conn, create_data):
 
     # test read-family with reference year
     url = conn + '/read-family?NameID=%s&income_year=%s' % (create_data['name_id'], '2020')
     resp = requests.get(url)
     resp.raise_for_status()
     res = resp.json()
     assert res['err'] == 0
     return len(res['data']['RL1']['quotientList']) == 1
+
+
+def test_read_family_members(conn, update_data):
+    unlink(conn, update_data['name_id'])
+    link(conn, update_data)
+
+    # list RLs
+    text_template = '{{ firstname }}'
+    url = conn + '/read-rl-list?NameID=%s&text_template=%s' % (update_data['name_id'], text_template)
+    resp = requests.get(url)
+    resp.raise_for_status()
+    res = resp.json()
+    assert res['err'] == 0
+    assert len(res['data']) == 2
+    assert res['data'][1]['text'] == 'HOMER'
+
+    # get RL
+    rl_id = res['data'][1]['id']
+    url = conn + '/read-rl?NameID=%s&rl_id=%s' % (update_data['name_id'], rl_id)
+    resp = requests.get(url)
+    resp.raise_for_status()
+    res = resp.json()
+    assert res['err'] == 0
+    assert res['data']['firstname'] == 'HOMER'
+
+    # list persons
+    text_template = '{{ firstname }}'
+    url = conn + '/read-person-list?NameID=%s&text_template=%s' % (update_data['name_id'], text_template)
+    resp = requests.get(url)
+    resp.raise_for_status()
+    res = resp.json()
+    assert res['err'] == 0
+    assert len(res['data']) == 2
+    assert res['data'][1]['text'] == 'SELMA'
+
+    # get person
+    person_id = res['data'][1]['id']
+    url = conn + '/read-person?NameID=%s&person_id=%s' % (update_data['name_id'], person_id)
+    resp = requests.get(url)
+    resp.raise_for_status()
+    res = resp.json()
+    assert res['err'] == 0
+    assert res['data']['firstname'] == 'SELMA'
+
+    # list childs
+    text_template = '{{ firstname }}'
+    url = conn + '/read-child-list?NameID=%s&text_template=%s' % (update_data['name_id'], text_template)
+    resp = requests.get(url)
+    resp.raise_for_status()
+    res = resp.json()
+    assert res['err'] == 0
+    assert len(res['data']) == 3
+    assert res['data'][0]['text'] == 'BART'
+
+    # get child
+    child_id = res['data'][0]['id']
+    url = conn + '/read-child?NameID=%s&child_id=%s' % (update_data['name_id'], child_id)
+    resp = requests.get(url)
+    resp.raise_for_status()
+    res = resp.json()
+    assert res['err'] == 0
+    assert res['data']['firstname'] == 'BART'
+
+    # list child persons
+    text_template = '{{ personInfo.firstname }}'
+    url = conn + '/read-child-person-list?NameID=%s&child_id=%s&text_template=%s' % (
+        update_data['name_id'],
+        child_id,
+        text_template,
+    )
+    resp = requests.get(url)
+    resp.raise_for_status()
+    res = resp.json()
+    assert res['err'] == 0
+    assert len(res['data']) == 2
+    assert res['data'][0]['text'] == 'ABRAHAM JEBEDIAH'
+
+    # get child person
+    person_id = res['data'][0]['id']
+    url = conn + '/read-child-person?NameID=%s&child_id=%s&person_id=%s' % (
+        update_data['name_id'],
+        child_id,
+        person_id,
+    )
+    resp = requests.get(url)
+    resp.raise_for_status()
+    res = resp.json()
+    assert res['err'] == 0
+    assert res['data']['personInfo']['firstname'] == 'ABRAHAM JEBEDIAH'
diff --git a/passerelle/contrib/toulouse_maelis/models.py b/passerelle/contrib/toulouse_maelis/models.py
index 862035aa..397d8fbc 100644
--- a/passerelle/contrib/toulouse_maelis/models.py
+++ b/passerelle/contrib/toulouse_maelis/models.py
@@ -21,16 +21,17 @@ from django.db import models
 from django.utils.timezone import now
 from zeep.helpers import serialize_object
 from zeep.wsse.username import UsernameToken
 
 from passerelle.base.models import BaseResource, HTTPResource
 from passerelle.utils.api import endpoint
 from passerelle.utils.conversion import simplify
 from passerelle.utils.jsonresponse import APIError
+from passerelle.utils.templates import render_to_string
 
 from . import schemas
 
 
 class UpdateError(Exception):
     pass
 
 
@@ -734,16 +735,133 @@ class ToulouseMaelis(BaseResource, HTTPResource):
             'income_year': {'description': 'Année de revenu pour filtrer les quotients'},
         },
     )
     def read_family(self, request, NameID, income_year=None):
         family_id = self.get_link(NameID).family_id
         data = self.get_family(family_id, incomeYear=income_year)
         return {'data': data}
 
+    @endpoint(
+        display_category='Famille',
+        description="Liste des responsables légaux",
+        perm='can_access',
+        name='read-rl-list',
+        parameters={
+            'NameID': {'description': 'Publik NameID'},
+            'text_template': {
+                'description': 'template utilisée pour la valeur text',
+                'example_value': '{{ lastname }} {{ firstname }}',
+            },
+            'income_year': {'description': 'Année de revenu pour filtrer les quotients'},
+        },
+    )
+    def read_rl_list(self, request, NameID, text_template=None, income_year=None):
+        family_id = self.get_link(NameID).family_id
+        result = self.get_family_raw(family_id, incomeYear=income_year)
+        if not text_template:
+            text_template = '{{ lastname }} {{ firstname }}'
+
+        data = []
+        for rlg in 'RL1', 'RL2':
+            item = result.get(rlg)
+            self.add_text_value_to_rl(item)
+            if not item:
+                break
+            item['id'] = item['num']
+            item['text'] = render_to_string(text_template, item).strip()
+            item['family_id'] = family_id
+            data.append(item)
+        return {'data': data}
+
+    @endpoint(
+        display_category='Famille',
+        description="Liste des personnes à prévenir en cas d'urgence",
+        perm='can_access',
+        name='read-person-list',
+        parameters={
+            'NameID': {'description': 'Publik NameID'},
+            'text_template': {
+                'description': 'template utilisée pour la valeur text',
+                'example_value': '{{ lastname }} {{ firstname }}',
+            },
+        },
+    )
+    def read_person_list(self, request, NameID, text_template=None):
+        family_id = self.get_link(NameID).family_id
+        result = self.get_family_raw(family_id)
+        if not text_template:
+            text_template = '{{ lastname }} {{ firstname }}'
+
+        data = []
+        for item in result['emergencyPersonList']:
+            self.add_text_value_to_person(item)
+            item['id'] = item['numPerson']
+            item['text'] = render_to_string(text_template, item).strip()
+            item['family_id'] = family_id
+            data.append(item)
+        return {'data': data}
+
+    @endpoint(
+        display_category='Famille',
+        description="Liste des enfants",
+        perm='can_access',
+        name='read-child-list',
+        parameters={
+            'NameID': {'description': 'Publik NameID'},
+            'text_template': {
+                'description': 'template utilisée pour la valeur text',
+                'example_value': '{{ lastname }} {{ firstname }}',
+            },
+        },
+    )
+    def read_child_list(self, request, NameID, text_template=None):
+        family_id = self.get_link(NameID).family_id
+        result = self.get_family_raw(family_id)
+        if not text_template:
+            text_template = '{{ lastname }} {{ firstname }}'
+
+        data = []
+        for item in result['childList']:
+            self.add_text_value_to_child(item)
+            item['id'] = item['num']
+            item['text'] = render_to_string(text_template, item).strip()
+            item['family_id'] = family_id
+            data.append(item)
+        return {'data': data}
+
+    @endpoint(
+        display_category='Famille',
+        description="Liste des personnes autorisées à récupérer l'enfant",
+        perm='can_access',
+        name='read-child-person-list',
+        parameters={
+            'NameID': {'description': 'Publik NameID'},
+            'child_id': {'description': "Numéro de l'enfant"},
+            'text_template': {
+                'description': 'template utilisée pour la valeur text',
+                'example_value': '{{ personInfo.lastname }} {{ personInfo.firstname }}',
+            },
+        },
+    )
+    def read_child_person_list(self, request, NameID, child_id, text_template=None):
+        family_id = self.get_link(NameID).family_id
+        result = self.get_child_raw(family_id, child_id)
+        if not text_template:
+            text_template = '{{ personInfo.lastname }} {{ personInfo.firstname }}'
+
+        data = []
+        for item in result['authorizedPersonList']:
+            self.add_text_value_to_child_person(item)
+            item['id'] = item['personInfo']['num']
+            item['text'] = render_to_string(text_template, item).strip()
+            item['family_id'] = family_id
+            data.append(item)
+        return {'data': data}
+
     @endpoint(
         display_category='Famille',
         description="Informations sur un responsable légal",
         perm='can_access',
         name='read-rl',
         parameters={
             'NameID': {'description': 'Publik NameID'},
             'rl_id': {'description': 'Numéro du représentant légal'},
@@ -752,17 +870,17 @@ class ToulouseMaelis(BaseResource, HTTPResource):
     )
     def read_rl(self, request, NameID, rl_id, income_year=None):
         family_id = self.get_link(NameID).family_id
         data = self.get_rl(family_id, rl_id, incomeYear=income_year)
         return {'data': data}
 
     @endpoint(
         display_category='Famille',
-        description="Informations sur une personne autorisée à récupérer les enfants ou à prévenir en cas d'urgence",
+        description="Informations sur une personne autorisée à récupérer les enfants",
         perm='can_access',
         name='read-person',
         parameters={
             'NameID': {'description': 'Publik NameID'},
             'person_id': {'description': 'Numéro de la personne'},
         },
     )
     def read_person(self, request, NameID, person_id):
diff --git a/tests/test_toulouse_maelis.py b/tests/test_toulouse_maelis.py
index 0f5ef10c..ba585396 100644
--- a/tests/test_toulouse_maelis.py
+++ b/tests/test_toulouse_maelis.py
@@ -661,16 +661,130 @@ def test_read_vaccin_list(con, app):
             'id': 'DTC',
             'code': 'DTC',
             'text': 'DIPHTERIE TETANOS COQUELUCHE',
             'libelle': 'DIPHTERIE TETANOS COQUELUCHE',
         },
     ]
 
 
+def test_read_rl_list(family_service, con, app):
+    family_service.add_soap_response('readFamily', get_xml_file('R_read_family.xml'))
+    url = get_endpoint('read-rl-list')
+    Link.objects.create(resource=con, family_id='1312', name_id='local')
+
+    resp = app.get(url + '?NameID=local')
+    assert resp.json['err'] == 0
+    assert [(x['id'], x['text']) for x in resp.json['data']] == [
+        ('613878', 'DOE JHON'),
+        ('613879', 'DOE JANE'),
+    ]
+
+    resp = app.get(url + '?NameID=local&text_template={{ birth.dateBirth|date:"d/m/Y" }}')
+    assert resp.json['err'] == 0
+    assert [(x['id'], x['text']) for x in resp.json['data']] == [
+        ('613878', '25/07/1938'),
+        ('613879', '21/06/1940'),
+    ]
+
+
+def test_read_rl_list_not_linked_error(con, app):
+    url = get_endpoint('read-rl-list')
+
+    resp = app.get(url + '?NameID=local')
+    assert resp.json['err'] == 'not-linked'
+    assert resp.json['err_desc'] == 'User not linked to family'
+
+
+def test_read_person_list(family_service, con, app):
+    family_service.add_soap_response('readFamily', get_xml_file('R_read_family.xml'))
+    url = get_endpoint('read-person-list')
+    Link.objects.create(resource=con, family_id='1312', name_id='local')
+
+    resp = app.get(url + '?NameID=local')
+    assert resp.json['err'] == 0
+    assert [(x['id'], x['text']) for x in resp.json['data']] == [(614059, 'ARKANA KENY')]
+
+    resp = app.get(url + '?NameID=local&text_template={{ dateBirth|date:"d/m/Y" }}')
+    assert resp.json['err'] == 0
+    assert [(x['id'], x['text']) for x in resp.json['data']] == [(614059, '19/12/1982')]
+
+
+def test_read_person_list_not_linked_error(con, app):
+    url = get_endpoint('read-person-list')
+
+    resp = app.get(url + '?NameID=local')
+    assert resp.json['err'] == 'not-linked'
+    assert resp.json['err_desc'] == 'User not linked to family'
+
+
+def test_read_child_list(family_service, con, app):
+    family_service.add_soap_response('readFamily', get_xml_file('R_read_family.xml'))
+    url = get_endpoint('read-child-list')
+    Link.objects.create(resource=con, family_id='1312', name_id='local')
+
+    resp = app.get(url + '?NameID=local')
+    assert resp.json['err'] == 0
+    assert [(x['id'], x['text']) for x in resp.json['data']] == [
+        ('613880', 'DOE JANNIS'),
+        ('613987', 'DOE JOHNNY ALLEN'),
+        ('614051', 'DOE ROBERT'),
+    ]
+
+    resp = app.get(url + '?NameID=local&text_template={{ birth.dateBirth|date:"d/m/Y" }}')
+    assert resp.json['err'] == 0
+    assert [(x['id'], x['text']) for x in resp.json['data']] == [
+        ('613880', '18/01/1943'),
+        ('613987', '26/11/1942'),
+        ('614051', '23/05/1941'),
+    ]
+
+
+def test_read_child_list_not_linked_error(con, app):
+    url = get_endpoint('read-child-list')
+
+    resp = app.get(url + '?NameID=local')
+    assert resp.json['err'] == 'not-linked'
+    assert resp.json['err_desc'] == 'User not linked to family'
+
+
+def test_read_child_person_list(family_service, con, app):
+    family_service.add_soap_response('readFamily', get_xml_file('R_read_family.xml'))
+    url = get_endpoint('read-child-person-list')
+    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 [(x['id'], x['text']) for x in resp.json['data']] == [(614719, 'BENT AMEL')]
+
+    resp = app.get(
+        url + '?NameID=local&child_id=613880&text_template={{ personInfo.dateBirth|date:"d/m/Y" }}'
+    )
+    assert resp.json['err'] == 0
+    assert [(x['id'], x['text']) for x in resp.json['data']] == [(614719, '20/06/1985')]
+
+
+def test_read_child_person_list_not_linked_error(con, app):
+    url = get_endpoint('read-child-person-list')
+
+    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'
+
+
+def test_read_child_person_list_not_exists_error(family_service, con, app):
+    family_service.add_soap_response('readFamily', get_xml_file('R_read_family.xml'))
+    url = get_endpoint('read-child-person-list')
+    Link.objects.create(resource=con, family_id='1312', name_id='local')
+
+    resp = app.get(url + '?NameID=local&child_id=42')
+    assert resp.json['err'] == 'not-found'
+    assert resp.json['err_desc'] == "no '42' child on '1312' family"
+
+
 @pytest.mark.parametrize(
     "xml", ['R_read_family.xml', 'R_read_family_relax.xml', 'R_read_family_reordered.xml']
 )
 def test_read_family(family_service, xml, con, app):
     family_service.add_soap_response('readFamily', get_xml_file(xml))
     url = get_endpoint('read-family')
     Link.objects.create(resource=con, family_id='1312', name_id='local')
 
-- 
2.30.2

