Projet

Général

Profil

0002-toulouse-maelis-add-read-family-person-endpoint-6989.patch

Nicolas Roche, 05 octobre 2022 09:14

Télécharger (17,5 ko)

Voir les différences:

Subject: [PATCH 2/5] toulouse-maelis: add read family person endpoint (#69891)

 passerelle/contrib/toulouse_maelis/models.py  | 38 +++++++++++++++++++
 tests/data/toulouse_maelis/FamilyService.wsdl | 21 +++++-----
 tests/data/toulouse_maelis/R_read_family.xml  | 19 ++++++++++
 tests/test_toulouse_maelis.py                 | 22 ++++++++++-
 4 files changed, 87 insertions(+), 13 deletions(-)
passerelle/contrib/toulouse_maelis/models.py
151 151

  
152 152
    def get_child_raw(self, family_id, child_id):
153 153
        data = self.get_family_raw(family_id)
154 154
        for child in data['childList']:
155 155
            if child['num'] == child_id:
156 156
                return child
157 157
        raise APIError("no '%s' child on '%s' family" % (child_id, family_id), err_code='not-found')
158 158

  
159
    def get_child_person_raw(self, family_id, child_id, person_id):
160
        data = self.get_child_raw(family_id, child_id)
161
        for person in data['authorizedPersonList']:
162
            if str(person['personInfo']['num']) == person_id:
163
                return person
164
        raise APIError(
165
            "no '%s' authorized person on '%s' child" % (person_id, child_id), err_code='not-found'
166
        )
167

  
159 168
    def add_text_value(self, referential_name, data, keys):
160 169
        '''add text from referentials'''
161 170
        last_key = keys.pop()
162 171
        for key in keys:
163 172
            if not isinstance(data, dict) or not key in data:
164 173
                return
165 174
            data = data[key]
166 175
        if isinstance(data, dict) and last_key in data and data[last_key] is not None:
167 176
            data[last_key + '_text'] = self.get_referential_value(referential_name, data[last_key])
168 177

  
178
    def add_text_value_to_child_person(self, data):
179
        self.add_text_value('Civility', data, ['personInfo', 'civility'])
180
        self.add_text_value('Quality', data, ['personQuality', 'code'])
181
        self.add_text_value('Sex', data, ['personInfo', 'sexe'])
182
        return data
183

  
169 184
    def add_text_value_to_child(self, data):
170 185
        self.add_text_value('Sex', data, ['sexe'])
171 186
        self.add_text_value('DietCode', data, ['dietcode'])
172 187
        self.add_text_value('PAI', data, ['paiInfoBean', 'code'])
188
        for person in data['authorizedPersonList']:
189
            self.add_text_value_to_child_person(person)
173 190

  
174 191
        # convert O/N string into boolean
175 192
        if data.get('fsl'):
176 193
            for key in (
177 194
                'allergieAlimentaire',
178 195
                'allergieRespiratoire',
179 196
                'allergieAutre',
180 197
                'allergieMedicament',
......
203 220
                self.add_text_value_to_rl(data[rlg])
204 221
        for child in data['childList']:
205 222
            self.add_text_value_to_child(child)
206 223
        for kind in ('authorized', 'emergency'):
207 224
            for person in data[kind + 'PersonList']:
208 225
                self.add_text_value_to_person(person)
209 226
        return data
210 227

  
228
    def get_child_person(self, family_id, child_id, person_id):
229
        data = self.get_child_person_raw(family_id, child_id, person_id)
230
        self.add_text_value_to_child_person(data)
231
        return data
232

  
211 233
    def get_child(self, family_id, child_id):
212 234
        data = self.get_child_raw(family_id, child_id)
213 235
        self.add_text_value_to_child(data)
214 236
        return data
215 237

  
216 238
    def get_person(self, family_id, person_id, kind='authorized'):
217 239
        data = self.get_person_raw(family_id, person_id, kind)
218 240
        self.add_text_value_to_person(data)
......
440 462
            'child_id': {'description': "Numéro de l'enfant"},
441 463
        },
442 464
    )
443 465
    def read_child(self, request, NameID, child_id):
444 466
        family_id = self.get_link(NameID).family_id
445 467
        data = self.get_child(family_id, child_id)
446 468
        return {'data': data}
447 469

  
470
    @endpoint(
471
        display_category='Famille',
472
        description="Informations sur une personne autorisée à récupérer l'enfant",
473
        perm='can_access',
474
        name='read-child-person',
475
        parameters={
476
            'NameID': {'description': 'Publik NameID'},
477
            'child_id': {'description': "Numéro de l'enfant"},
478
            'person_id': {'description': 'Numéro de la personne'},
479
        },
480
    )
481
    def read_child_person(self, request, NameID, child_id, person_id):
482
        family_id = self.get_link(NameID).family_id
483
        data = self.get_child_person(family_id, child_id, person_id)
484
        return {'data': data}
485

  
448 486
    @endpoint(
449 487
        display_category='Famille',
450 488
        description="Vérifier qu'un responsable légal existe en base",
451 489
        perm='can_access',
452 490
        name='is-rl-exists',
453 491
        post={'request_body': {'schema': {'application/json': schemas.ISEXISTS_SCHEMA}}},
454 492
    )
455 493
    def is_rl_exists(self, request, post_data):
tests/data/toulouse_maelis/FamilyService.wsdl
382 382
    <xs:sequence>
383 383
      <xs:element name="dossierNumber" type="xs:int"/>
384 384
      <xs:element name="personNumber" type="xs:int"/>
385 385
      <xs:element name="quotient" type="tns:familyQuotientRedvBean"/>
386 386
    </xs:sequence>
387 387
  </xs:complexType>
388 388
  <xs:complexType name="familyQuotientRedvBean">
389 389
    <xs:sequence>
390
      <xs:element name="year" type="xs:int"/>
391 390
      <xs:element name="yearRev" type="xs:int"/>
392 391
      <xs:element name="dateStart" type="xs:dateTime"/>
393 392
      <xs:element name="dateEnd" type="xs:dateTime"/>
394 393
      <xs:element name="mtt" type="xs:double"/>
395 394
      <xs:element name="cdquo" type="xs:string"/>
396 395
      <xs:element minOccurs="0" name="codeUti" type="xs:string"/>
397 396
    </xs:sequence>
398 397
  </xs:complexType>
......
749 748
    <xs:complexContent>
750 749
      <xs:extension base="ns1:abstractSpecBean">
751 750
        <xs:sequence>
752 751
          <xs:element minOccurs="0" name="numPerson" type="xs:int"/>
753 752
          <xs:element minOccurs="0" name="civility" type="xs:string"/>
754 753
          <xs:element name="firstname" type="xs:string"/>
755 754
          <xs:element name="lastname" type="xs:string"/>
756 755
          <xs:element name="dateBirth" type="xs:dateTime"/>
756
          <xs:element minOccurs="0" name="sexe" type="xs:string"/>
757 757
          <xs:element name="quality" type="xs:string"/>
758 758
          <xs:element minOccurs="0" name="contact" type="tns:contactLightBean"/>
759 759
        </xs:sequence>
760 760
      </xs:extension>
761 761
    </xs:complexContent>
762 762
  </xs:complexType>
763 763

  
764 764
  <xs:complexType name="contactLightBean">
......
802 802
      <xs:element minOccurs="0" name="place" type="xs:string"/>
803 803
    </xs:sequence>
804 804
  </xs:complexType>
805 805

  
806 806
  <xs:complexType name="relatedPersonBean">
807 807
    <xs:complexContent>
808 808
      <xs:extension base="ns1:abstractSpecBean">
809 809
        <xs:sequence>
810
          <xs:element minOccurs="0" name="person" type="tns:personInfoBean"/>
810
          <xs:element minOccurs="0" name="personInfo" type="tns:personInfoBean"/>
811 811
          <xs:element minOccurs="0" name="personQuality" type="tns:personQualityBean"/>
812 812
        </xs:sequence>
813 813
      </xs:extension>
814 814
    </xs:complexContent>
815 815
  </xs:complexType>
816 816

  
817 817
  <xs:complexType name="personInfoBean">
818 818
    <xs:sequence>
819 819
      <xs:element name="num" type="xs:int"/>
820 820
      <xs:element minOccurs="0" name="lastname" type="xs:string"/>
821 821
      <xs:element minOccurs="0" name="firstname" type="xs:string"/>
822
      <xs:element minOccurs="0" name="dateBirth" type="xs:dateTime"/>
822 823
      <xs:element minOccurs="0" name="civility" type="xs:string"/>
823 824
      <xs:element minOccurs="0" name="sexe" type="xs:string"/>
824
      <xs:element minOccurs="0" name="phone" type="xs:string"/>
825
      <xs:element minOccurs="0" name="mobile" type="xs:string"/>
825
      <xs:element minOccurs="0" name="contact" type="tns:contactLightBean"/>
826 826
    </xs:sequence>
827 827
  </xs:complexType>
828 828

  
829 829
  <xs:complexType name="personQualityBean">
830 830
    <xs:sequence>
831 831
      <xs:element name="code" type="xs:string"/>
832 832
      <xs:element minOccurs="0" name="libelle" type="xs:string"/>
833 833
    </xs:sequence>
......
966 966
      </xs:extension>
967 967
    </xs:complexContent>
968 968
  </xs:complexType>
969 969

  
970 970
  <xs:complexType name="updateChildAutorizationRequestBean">
971 971
    <xs:sequence>
972 972
      <xs:element name="numFamily" type="xs:string"/>
973 973
      <xs:element name="numPerson" type="xs:int"/>
974
      <xs:element maxOccurs="unbounded" name="personList" type="tns:relatedPerson2Bean"/>
974
      <xs:element maxOccurs="unbounded" minOccurs="0" name="personList" nillable="true" type="tns:relatedPerson2Bean"/>
975 975
      <xs:element name="bLeaveAlone" type="xs:boolean"/>
976 976
      <xs:element name="bPhoto" type="xs:boolean"/>
977 977
    </xs:sequence>
978 978
  </xs:complexType>
979 979

  
980 980
  <xs:complexType name="relatedPerson2Bean">
981 981
    <xs:sequence>
982
      <xs:element name="personInfo" type="tns:person2Bean"/>
982
      <xs:element name="personInfo" type="tns:person3Bean"/>
983 983
      <xs:element name="personQuality" type="tns:personQualityBean"/>
984 984
    </xs:sequence>
985 985
  </xs:complexType>
986 986

  
987
  <xs:complexType name="person2Bean">
987
  <xs:complexType name="person3Bean">
988 988
    <xs:sequence>
989 989
      <xs:element minOccurs="0" name="num" type="xs:int"/>
990 990
      <xs:element minOccurs="0" name="civility" type="xs:string"/>
991 991
      <xs:element name="lastname" type="xs:string"/>
992 992
      <xs:element name="firstname" type="xs:string"/>
993 993
      <xs:element name="dateBirth" type="xs:dateTime"/>
994 994
      <xs:element minOccurs="0" name="sexe" type="xs:string"/>
995
      <xs:element minOccurs="0" name="mail" type="xs:string"/>
996
      <xs:element minOccurs="0" name="address" type="tns:addressBean"/>
995
      <xs:element minOccurs="0" name="contact" type="tns:contactLightBean"/>
997 996
    </xs:sequence>
998 997
  </xs:complexType>
999 998

  
1000 999
  <xs:complexType name="subscribeSchoolRequestBean">
1001 1000
    <xs:sequence>
1002 1001
      <xs:element name="personNumber" type="xs:int"/>
1003 1002
      <xs:element minOccurs="0" name="schoolYear" type="xs:int"/>
1004 1003
      <xs:element minOccurs="0" name="dateSubscribe" type="xs:dateTime"/>
......
1815 1814
    </wsdl:operation>
1816 1815
    <wsdl:operation name="createUpdateQuotient">
1817 1816
<wsdl:documentation> Méthode de création/mise à jour d'un quotient
1818 1817

  
1819 1818
 -------------------------
1820 1819
 dossierNumber: numéro de la famille (obligatoire)
1821 1820
 personNumber: numéro de la personne (obligatoire)
1822 1821
 Quotient : (obligatoire) 
1823
 	- year : année de référence (obligatoire)
1824 1822
	- yearRev : année de revenue (obligatoire)
1825 1823
	- dateStart : date de début (format DD/MM/YYYY) (obligatoire)
1826 1824
	- dateFin : date de fin (format DD/MM/YYYY) (obligatoire)
1827 1825
	- mtt : montant (obligatoire)
1828 1826
	- cdQuo : code du quotient (obligatoire)
1829 1827
	- codeUti : code de l'utilisateur
1830 1828

  
1831 1829
 -------------------------
1832 1830
 Traitement :
1833 1831
	Récupère l'identifiant de quotient
1834
	Récupère les quotients existant de cette personne/année/code quotient (table H_QUOREDV)
1835 1832
	Clôture les anciens quotients (si la date de fin du quotient est supérieure à la date de début du quotient à insérer)
1836 1833
	Insère le nouveau quotient
1837 1834
	Renvoie l'identifiant du quotient créé</wsdl:documentation>
1838 1835
      <wsdl:input message="tns:createUpdateQuotient" name="createUpdateQuotient">
1839 1836
    </wsdl:input>
1840 1837
      <wsdl:output message="tns:createUpdateQuotientResponse" name="createUpdateQuotientResponse">
1841 1838
    </wsdl:output>
1842 1839
      <wsdl:fault message="tns:MaelisFamilyException" name="MaelisFamilyException">
......
2202 2199
    </wsdl:output>
2203 2200
      <wsdl:fault message="tns:MaelisFamilyException" name="MaelisFamilyException">
2204 2201
    </wsdl:fault>
2205 2202
    </wsdl:operation>
2206 2203
    <wsdl:operation name="updateFamilyAuthorizedPersonList">
2207 2204
<wsdl:documentation>Méthode de mise à jour de la liste des personnes autorisées sur la famille
2208 2205
 La liste comporte toutes les personnes autorisées. 
2209 2206
 Les personnes non présentes dans cette liste sont supprimées en tant que personne autorisée.
2210
 Dépressié : il faut utiliser la méthode updateChildAutorization car nouvelle gestion par enfant (famille recomposée)  
2207
 Déprécié : il faut utiliser la méthode updateChildAutorization car nouvelle gestion par enfant (famille recomposée)  
2211 2208

  
2212 2209
 ------------------------------
2213 2210
 numDossier : numéro de dossier famille  (obligatoire)
2214 2211
 authorizedPersonList : liste des personnes autorisées
2215 2212

  
2216 2213
 -----------------------------</wsdl:documentation>
2217 2214
      <wsdl:input message="tns:updateFamilyAuthorizedPersonList" name="updateFamilyAuthorizedPersonList">
2218 2215
    </wsdl:input>
tests/data/toulouse_maelis/R_read_family.xml
118 118
            <obsAssist1>some obsAssist1 text</obsAssist1>
119 119
            <obsAssist2>some obsAssist2 text</obsAssist2>
120 120
            <obsAssist3>some obsAssist3 text</obsAssist3>
121 121
            <cons1Med>some cons1Med text</cons1Med>
122 122
            <cons2Med>some cons2Med text</cons2Med>
123 123
          </fsl>
124 124
          <bPhoto>true</bPhoto>
125 125
          <bLeaveAlone>false</bLeaveAlone>
126
          <authorizedPersonList>
127
            <personInfo>
128
              <num>614719</num>
129
              <lastname>BENT</lastname>
130
              <firstname>AMEL</firstname>
131
              <dateBirth>1985-06-21T00:00:00+02:00</dateBirth>
132
              <civility>MME</civility>
133
              <sexe>F</sexe>
134
              <contact>
135
                <phone>0123456789</phone>
136
                <mobile>0623456789</mobile>
137
                <mail>abent@example.org</mail>
138
              </contact>
139
            </personInfo>
140
            <personQuality>
141
              <code>T</code>
142
              <libelle>TANTE</libelle>
143
            </personQuality>
144
          </authorizedPersonList>
126 145
          <medicalRecord>
127 146
            <familyDoctor>
128 147
              <name>DRE</name>
129 148
              <phone>0612341234</phone>
130 149
              <address>
131 150
                <street1>Alameda</street1>
132 151
                <zipcode>90220</zipcode>
133 152
                <town>Compton</town>
tests/test_toulouse_maelis.py
589 589
        },
590 590
        'CAFInfo': None,
591 591
        'civility_text': 'Monsieur',
592 592
        'quality_text': 'PERE',
593 593
    }
594 594
    data = resp.json['data']['childList'][0]
595 595
    del data['fsl']
596 596
    del data['medicalRecord']
597
    del data['authorizedPersonList']
597 598
    assert data == {
598 599
        'num': '613880',
599 600
        'lastname': 'DOE',
600 601
        'firstname': 'JANNIS',
601 602
        'sexe': 'F',
602 603
        'sexe_text': 'Féminin',
603 604
        'birth': {'dateBirth': '1943-01-19T00:00:00+01:00', 'place': None},
604 605
        'dietcode': 'RSV',
605 606
        'dietcode_text': '3- RÉGIME SANS VIANDE',
606 607
        'bPhoto': True,
607 608
        'bLeaveAlone': False,
608
        'authorizedPersonList': [],
609 609
        'indicatorList': [],
610 610
        'subscribeSchoolList': [],
611 611
        'mother': {'num': 613963, 'civility': 'MME', 'firstname': 'JANE', 'lastname': 'DOE'},
612 612
        'father': {'num': 613878, 'civility': 'M.', 'firstname': 'JHON', 'lastname': 'DOE'},
613 613
        'rl': None,
614 614
        'subscribeActivityList': [],
615 615
        'paiInfoBean': {
616 616
            'code': 'PAIALI',
......
673 673
        'dateBirth': '1982-12-20T00:00:00+01:00',
674 674
        'quality': 'T',
675 675
        'civility': 'MME',
676 676
        'contact': {'phone': '0123456789', 'mobile': None, 'mail': 'pueblo@example.org'},
677 677
        'numPerson': 614059,
678 678
        'civility_text': 'Madame',
679 679
        'quality_text': 'TANTE',
680 680
    }
681
    assert resp.json['data']['childList'][0]['authorizedPersonList'][0] == {
682
        'personInfo': {
683
            'num': 614719,
684
            'lastname': 'BENT',
685
            'firstname': 'AMEL',
686
            'dateBirth': '1985-06-21T00:00:00+02:00',
687
            'civility': 'MME',
688
            'civility_text': 'Madame',
689
            'sexe': 'F',
690
            'sexe_text': 'Féminin',
691
            'contact': {'phone': '0123456789', 'mobile': '0623456789', 'mail': 'abent@example.org'},
692
        },
693
        'personQuality': {
694
            'code': 'T',
695
            'code_text': 'TANTE',
696
            'libelle': 'TANTE',
697
        },
698
    }
681 699

  
682 700

  
683 701
def test_read_family_not_linked_error(con, app):
684 702
    url = get_endpoint('read-family')
685 703

  
686 704
    resp = app.get(url + '?NameID=')
687 705
    assert resp.json['err'] == 'not-linked'
688 706
    assert resp.json['err_desc'] == 'User not linked to family'
......
830 848
@mock.patch('passerelle.utils.Request.get')
831 849
@mock.patch('passerelle.utils.Request.post')
832 850
def test_read_child(mocked_post, mocked_get, con, app):
833 851
    mocked_get.return_value = FAMILY_SERVICE_WSDL
834 852
    mocked_post.side_effect = [
835 853
        READ_FAMILY,
836 854
        READ_DIETCODE,
837 855
        READ_PAI,
856
        READ_CIVILITIES,
857
        READ_QUALITIES,
838 858
    ]
839 859
    url = get_endpoint('read-child')
840 860
    Link.objects.create(resource=con, family_id='1312', name_id='local')
841 861

  
842 862
    resp = app.get(url + '?NameID=local&child_id=613880')
843 863
    assert resp.json['err'] == 0
844 864
    assert resp.json['data']['firstname'] == 'JANNIS'
845 865

  
846
-