0002-toulouse-maelis-add-read-family-person-endpoint-6989.patch
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 |
- |