From a174bc24ebc29456d4ba44f015ecfb49477728fe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Laur=C3=A9line=20Gu=C3=A9rin?= Date: Mon, 27 Jan 2020 15:39:31 +0100 Subject: [PATCH] toulouse_axel: add labels to explain some values (#39291) --- functests/toulouse_axel/test_toulouse_axel.py | 7 +-- passerelle/contrib/toulouse_axel/models.py | 28 +++++++++++ passerelle/contrib/toulouse_axel/utils.py | 50 +++++++++++++++++++ tests/data/toulouse_axel/family_info.xml | 4 +- tests/test_toulouse_axel.py | 47 ++++++++++++++++- 5 files changed, 130 insertions(+), 6 deletions(-) diff --git a/functests/toulouse_axel/test_toulouse_axel.py b/functests/toulouse_axel/test_toulouse_axel.py index 7142bbe3..744ca7ad 100644 --- a/functests/toulouse_axel/test_toulouse_axel.py +++ b/functests/toulouse_axel/test_toulouse_axel.py @@ -45,14 +45,14 @@ def test_link(conn, user): payload['DROITALIMAGE'] = 'NON' payload['REVENUS']['CHOIXREVENU'] = '' # remove non editable fields - for key in ['SITUATIONFAMILIALE', 'NBENFANTACTIF', 'NBRLACTIF', 'IDDUI', 'CODEMISEAJOUR']: + for key in ['SITUATIONFAMILIALE', 'SITUATIONFAMILIALE_label', 'NBENFANTACTIF', 'NBRLACTIF', 'IDDUI', 'CODEMISEAJOUR']: payload.pop(key) - for key in ['IDPERSONNE', 'NOM', 'PRENOM', 'NOMJEUNEFILLE', 'DATENAISSANCE', 'CIVILITE', 'INDICATEURRL']: + for key in ['IDPERSONNE', 'NOM', 'PRENOM', 'NOMJEUNEFILLE', 'DATENAISSANCE', 'CIVILITE', 'INDICATEURRL', 'CSP_label']: if 'RL1' in payload: payload['RL1'].pop(key) if 'RL2' in payload: payload['RL2'].pop(key) - for key in ['MONTANTTOTAL', 'DATEVALIDITE', 'SFI', 'IREVENUS', 'RNF', 'NBENFANTSACHARGE']: + for key in ['MONTANTTOTAL', 'DATEVALIDITE', 'SFI', 'IREVENUS', 'RNF', 'NBENFANTSACHARGE', 'TYPEREGIME_label']: payload['REVENUS'].pop(key, None) for enfant in payload['ENFANT']: for key in ['id', 'text', 'NOM', 'DATENAISSANCE', 'SEXE', 'PRENOMPERE', 'PRENOMMERE', 'NOMPERE', 'NOMMERE', 'RATTACHEAUTREDUI', 'PRENOM', @@ -63,6 +63,7 @@ def test_link(conn, user): for contact in enfant.get('CONTACT', []): contact.pop('id') contact.pop('text') + contact.pop('LIENPARENTE_label') if 'SANITAIRE' not in enfant: continue # manage handicap data (not the same schema) diff --git a/passerelle/contrib/toulouse_axel/models.py b/passerelle/contrib/toulouse_axel/models.py index 94d9e083..78c20417 100644 --- a/passerelle/contrib/toulouse_axel/models.py +++ b/passerelle/contrib/toulouse_axel/models.py @@ -452,6 +452,22 @@ class ToulouseAxel(BaseResource): link.delete() return {'link': link_id, 'deleted': True, 'dui': link.dui} + @endpoint( + description=_("Get a referential"), + perm='can_access', + pattern=r'^(?P[\w-]+)/?$', + example_pattern='csp', + parameters={ + 'code': {'description': _('Referential code. Possible values: situation_familiale, csp, lien_parente, type_regime')}, + }) + def referential(self, request, code): + if code not in ['situation_familiale', 'csp', 'lien_parente', 'type_regime']: + raise APIError('Referential not found', err_code='not-found') + references = getattr(utils, '{}_mapping'.format(code)) + if references is None: + raise APIError('Referential not found', err_code='not-found', http_status=404) + return {'data': [{'id': key, 'text': val} for key, val in references.items()]} + def get_family_data(self, dui, check_registrations=False): try: result = ref_famille_dui(self, {'PORTAIL': {'DUI': {'IDDUI': dui}}}) @@ -480,12 +496,24 @@ class ToulouseAxel(BaseResource): child['clae_cantine_current'] = children_registred_for_current_year.get(child['IDPERSONNE']) child['clae_cantine_next'] = children_registred_for_next_year.get(child['IDPERSONNE']) + family_data['SITUATIONFAMILIALE_label'] = utils.get_label(utils.situation_familiale_mapping, family_data['SITUATIONFAMILIALE']) + for key in ['RL1', 'RL2']: + if key not in family_data: + continue + rl = family_data[key] + rl['CSP_label'] = utils.get_label(utils.csp_mapping, rl['CSP']) + for child in family_data.get('ENFANT', []): child['id'] = child['IDPERSONNE'] child['text'] = '{} {}'.format(child['PRENOM'], child['NOM']).strip() for i, contact in enumerate(child.get('CONTACT', [])): contact['id'] = i contact['text'] = '{} {}'.format(contact['PRENOM'], contact['NOM']).strip() + contact['LIENPARENTE_label'] = utils.get_label(utils.lien_parente_mapping, contact['LIENPARENTE']) + + if 'REVENUS' in family_data: + family_data['REVENUS']['TYPEREGIME_label'] = utils.get_label(utils.type_regime_mapping, family_data['REVENUS']['TYPEREGIME']) + return family_data @endpoint( diff --git a/passerelle/contrib/toulouse_axel/utils.py b/passerelle/contrib/toulouse_axel/utils.py index 0b1dd4d5..2c5d64b2 100644 --- a/passerelle/contrib/toulouse_axel/utils.py +++ b/passerelle/contrib/toulouse_axel/utils.py @@ -1,3 +1,4 @@ +# -*- coding: utf-8 -*- # passerelle - uniform access to multiple data sources and services # Copyright (C) 2020 Entr'ouvert # @@ -14,6 +15,9 @@ # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see . +from __future__ import unicode_literals + +from collections import OrderedDict import datetime import xml.etree.ElementTree as ET @@ -37,6 +41,52 @@ xml_date_format = '%d/%m/%Y' xml_datetime_format = '%d/%m/%Y %H:%M:%S' +situation_familiale_mapping = OrderedDict([ + ('C', 'Célibataire'), + ('D', 'Divorcé (e)'), + ('M', 'Marié (e)'), + ('S', 'Séparé (e)'), + ('V', 'Veuf (ve)'), + ('VM', 'Vie Maritale'), + ('P', 'Pacs'), +]) + +csp_mapping = OrderedDict([ + ('OUV', 'Ouvriers'), + ('EMP', 'Employés'), + ('ETU', 'Etudiants'), + ('RET', 'Retraités'), + ('STA', 'Personnes en stage'), + ('AGEX', 'Agriculteurs exploitants'), + ('ARCO', 'Artisans commercants chefs entreprise'), + ('CADP', 'Cadres professions intellectuelles supérieures'), + ('PRIN', 'Professions intermediaires'), + ('SACT', 'Autres personnes sans activité professionnelle'), + ('REC', 'Recherche emploi'), +]) + +lien_parente_mapping = OrderedDict([ + ('GRP1', 'Grands-parents paternels'), + ('GRP2', 'Grands-parents maternels'), + ('VOI', 'Voisin'), + ('FRE', "Frère de l'enfant"), + ('SOE', "Soeur de l'enfant"), + ('AMI', 'Ami (e)'), + ('FAMI', 'Membre de la famille'), + ('BABY', 'Baby sitter'), +]) + +type_regime_mapping = OrderedDict([ + ('GENE', 'Régime général'), + ('ZAU', 'Autre'), + ('MSA', 'MSA'), +]) + + +def get_label(mapping, code): + return mapping.get(code, code) + + def indent(tree, space=" ", level=0): # backport from Lib/xml/etree/ElementTree.py python 3.9 if isinstance(tree, ET.ElementTree): diff --git a/tests/data/toulouse_axel/family_info.xml b/tests/data/toulouse_axel/family_info.xml index 2e42f007..efbe4c07 100644 --- a/tests/data/toulouse_axel/family_info.xml +++ b/tests/data/toulouse_axel/family_info.xml @@ -4,7 +4,7 @@ 19 2 2 - P + S NON NON @@ -131,7 +131,7 @@ foo foo - + GRP1 OUI OUI 0505050505 diff --git a/tests/test_toulouse_axel.py b/tests/test_toulouse_axel.py index a27c1ab4..54410d24 100644 --- a/tests/test_toulouse_axel.py +++ b/tests/test_toulouse_axel.py @@ -15,6 +15,8 @@ # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see . +from __future__ import unicode_literals + from contextlib import contextmanager import copy import datetime @@ -45,7 +47,13 @@ from passerelle.contrib.toulouse_axel.models import ( ref_verif_dui, reservation_periode, ) -from passerelle.contrib.toulouse_axel.utils import get_reference_year_from_date +from passerelle.contrib.toulouse_axel.utils import ( + situation_familiale_mapping, + csp_mapping, + lien_parente_mapping, + type_regime_mapping, + get_reference_year_from_date, +) from passerelle.utils.jsonresponse import APIError import utils @@ -625,6 +633,24 @@ def test_unlink_endpoint(app, resource): assert resp.json['deleted'] is True +def test_refetential_endpoint_no_result(app, resource): + resp = app.get('/toulouse-axel/test/referential/foo/') + assert resp.json['err_desc'] == "Referential not found" + assert resp.json['err'] == 'not-found' + + +@pytest.mark.parametrize('code, mapping', [ + ('situation_familiale', situation_familiale_mapping), + ('csp', csp_mapping), + ('lien_parente', lien_parente_mapping), + ('type_regime', type_regime_mapping), +]) +def test_refetential_endpoint(app, resource, code, mapping): + resp = app.get('/toulouse-axel/test/referential/%s/' % code) + expected = [{'id': k, 'text': v} for k, v in mapping.items()] + assert dict(resp.json['data']) == dict(expected) + + def test_family_info_endpoint_axel_error(app, resource): Link.objects.create(resource=resource, name_id='yyy', dui='XXX', person_id='42') with mock.patch('passerelle.contrib.toulouse_axel.models.ref_famille_dui') as operation: @@ -661,6 +687,7 @@ def test_family_info_endpoint(app, resource): 'RL1', 'RL2', 'SITUATIONFAMILIALE', + 'SITUATIONFAMILIALE_label', 'TELFIXE', ]) assert resp.json['data']['ENFANT'][0]['id'] == '4242' @@ -694,6 +721,19 @@ def test_family_info_endpoint(app, resource): assert resp.json['data']['ENFANT'][1]['clae_cantine_current'] is None assert resp.json['data']['ENFANT'][1]['clae_cantine_next'] is True + assert resp.json['data']['SITUATIONFAMILIALE'] == 'S' + assert resp.json['data']['SITUATIONFAMILIALE_label'] == 'Séparé (e)' + assert resp.json['data']['RL1']['CSP'] == 'ETU' + assert resp.json['data']['RL1']['CSP_label'] == 'Etudiants' + assert resp.json['data']['RL2']['CSP'] == 'EMP' + assert resp.json['data']['RL2']['CSP_label'] == 'Employés' + assert resp.json['data']['ENFANT'][0]['CONTACT'][0]['LIENPARENTE'] == 'GRP1' + assert resp.json['data']['ENFANT'][0]['CONTACT'][0]['LIENPARENTE_label'] == 'Grands-parents paternels' + assert resp.json['data']['ENFANT'][0]['CONTACT'][1]['LIENPARENTE'] is None + assert resp.json['data']['ENFANT'][0]['CONTACT'][1]['LIENPARENTE_label'] is None + assert resp.json['data']['REVENUS']['TYPEREGIME'] == 'GENE' + assert resp.json['data']['REVENUS']['TYPEREGIME_label'] == 'Régime général' + def test_children_info_endpoint_axel_error(app, resource): Link.objects.create(resource=resource, name_id='yyy', dui='XXX', person_id='42') @@ -807,6 +847,11 @@ def test_child_info_endpoint(app, resource): assert resp.json['data']['clae_cantine_current'] is None assert resp.json['data']['clae_cantine_next'] is False + assert resp.json['data']['CONTACT'][0]['LIENPARENTE'] == 'GRP1' + assert resp.json['data']['CONTACT'][0]['LIENPARENTE_label'] == 'Grands-parents paternels' + assert resp.json['data']['CONTACT'][1]['LIENPARENTE'] is None + assert resp.json['data']['CONTACT'][1]['LIENPARENTE_label'] is None + def test_child_contacts_info_endpoint_axel_error(app, resource): Link.objects.create(resource=resource, name_id='yyy', dui='XXX', person_id='42')