add ATOS Genesys connector (fixes #26333)

It provides the following webservices:
- /codifications, to list Genesys referentials
- /codifications/<category>/, to list values in a specific Genesys
referential
- /link, to create a link between a NameID and an account in Genesys
extranet
- /unlink, to delete a link created using the previous WS,
- /dossiers, to get all datas associates to Genesys extranet accounts
for a given NameID
This commit is contained in:
Benjamin Dauvergne 2018-09-17 11:58:19 +02:00
parent 36636be67f
commit 34f2a6321d
11 changed files with 1771 additions and 0 deletions

View File

View File

@ -0,0 +1,63 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11.10 on 2018-09-18 09:42
from __future__ import unicode_literals
from django.db import migrations, models
import django.db.models.deletion
import jsonfield.fields
class Migration(migrations.Migration):
initial = True
dependencies = [
('base', '0006_resourcestatus'),
]
operations = [
migrations.CreateModel(
name='Link',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('name_id', models.CharField(max_length=256, verbose_name='NameID')),
('id_per', models.CharField(max_length=64, verbose_name='ID Per')),
('created', models.DateTimeField(auto_now_add=True, verbose_name='Creation date')),
('extra', jsonfield.fields.JSONField(null=True, verbose_name='Anything')),
],
options={
'ordering': ['created'],
},
),
migrations.CreateModel(
name='Resource',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('title', models.CharField(max_length=50, verbose_name='Title')),
('description', models.TextField(verbose_name='Description')),
('slug', models.SlugField(unique=True)),
('log_level', models.CharField(choices=[(b'NOTSET', b'NOTSET'), (b'DEBUG', b'DEBUG'), (b'INFO', b'INFO'), (b'WARNING', b'WARNING'), (b'ERROR', b'ERROR'), (b'CRITICAL', b'CRITICAL'), (b'FATAL', b'FATAL')], default=b'INFO', max_length=10, verbose_name='Log Level')),
('basic_auth_username', models.CharField(blank=True, max_length=128, verbose_name='Basic authentication username')),
('basic_auth_password', models.CharField(blank=True, max_length=128, verbose_name='Basic authentication username')),
('client_certificate', models.FileField(blank=True, null=True, upload_to=b'', verbose_name='TLS client certificate')),
('trusted_certificate_authorities', models.FileField(blank=True, null=True, upload_to=b'', verbose_name='TLS trusted CAs')),
('verify_cert', models.BooleanField(default=True, verbose_name='TLS verify certificates')),
('http_proxy', models.CharField(blank=True, max_length=128, verbose_name='HTTP and HTTPS proxy')),
('webservice_base_url', models.URLField(verbose_name='Webservice Base URL')),
('cod_rgp', models.CharField(default=b'RGP_PUB', max_length=64, verbose_name='Code RGP')),
('users', models.ManyToManyField(blank=True, to='base.ApiUser')),
],
options={
'verbose_name': 'ATOS Genesys',
},
),
migrations.AddField(
model_name='link',
name='resource',
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='atos_genesys.Resource'),
),
migrations.AlterUniqueTogether(
name='link',
unique_together=set([('resource', 'name_id', 'id_per')]),
),
]

View File

@ -0,0 +1,285 @@
# passerelle - uniform access to multiple data sources and services
# Copyright (C) 2018 Entr'ouvert
#
# This program is free software: you can redistribute it and/or modify it
# under the terms of the GNU Affero General Public License as published
# by the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
import urlparse
import requests
import xml.etree.ElementTree as ET
import six
import jsonfield
from django.db import models
from django.utils.translation import ugettext_lazy as _
from passerelle.utils import xml as xmlutils
from passerelle.utils.jsonresponse import APIError
from passerelle.utils.api import endpoint
from passerelle.base.models import BaseResource, HTTPResource
from . import utils
class Resource(BaseResource, HTTPResource):
category = _('Business Process Connectors')
webservice_base_url = models.URLField(_('Webservice Base URL'))
cod_rgp = models.CharField(_('Code RGP'), max_length=64, default='RGP_PUB')
class Meta:
verbose_name = _('ATOS Genesys')
@property
def select_codifications_url(self):
return urlparse.urljoin(self.webservice_base_url, 'selectCodifications')
def xml_request(self, url, *args, **kwargs):
try:
response = self.requests.get(url, *args, **kwargs)
response.raise_for_status()
except requests.RequestException as e:
raise APIError('HTTP request failed', data={'exception': six.text_type(e)})
try:
root = ET.fromstring(response.content)
except ET.ParseError as e:
raise APIError('XML parsing failed', data={'exception': six.text_type(e)})
if root.tag != 'return':
raise APIError('root XML node is not return', data={'content': response.text[:1024]})
row = root.find('ROWSET/ROW')
if row is None:
raise APIError('no ROWSET/ROW node', data={'content': response.text[:1024]})
return row
def call_select_codifications(self):
root = self.xml_request(self.select_codifications_url)
categories = {}
for category in root.findall('CATEGORIES/CATEGORIES_ROW'):
code = category.find('CD_CAT_CODIF')
label = category.find('LB_CAT_CODIF')
if None in (code, label):
self.logger.warning('invalid category: %s', ET.tostring(category))
continue
categories[xmlutils.text_content(code)] = {
'label': xmlutils.text_content(label),
'codifications': []
}
for codification in root.findall('CODIFICATIONS/CODIFICATIONS_ROW'):
code = codification.find('CD_CODIF')
label = codification.find('LB_CODIF')
in_val = codification.find('IN_VAL_CODIF')
category_cod = codification.find('CD_CAT_CODIF')
if None in (code, label, category_cod):
self.logger.warning('invalid codification: %s', ET.tostring(codification))
continue
category_cod = xmlutils.text_content(category_cod)
if category_cod not in categories:
self.logger.warning('unknown category: %s', category_cod)
continue
categories[category_cod]['codifications'].append({
'code': xmlutils.text_content(code),
'label': xmlutils.text_content(label),
'enabled': xmlutils.text_content(in_val).strip().lower() == 'o' if in_val is not None else True,
})
return categories
def get_codifications(self):
cache = utils.RowLockedCache(
function=self.call_select_codifications,
row=self,
key_prefix='atos-genesys-codifications')
return cache()
@endpoint(name='codifications',
description=_('List of codifications categories'))
def codifications(self, request):
codifications = self.get_codifications()
items = []
for code, category in codifications.items():
items.append({
'id': code,
'label': category['label'],
})
items.sort(key=lambda c: c['label'])
return {'data': items}
@endpoint(name='codifications',
pattern=r'^(?P<category>[\w-]+)/$',
example_pattern='{category}/',
description=_('List of codifications'),
parameters={
'category': {
'description': _('Category of codification'),
'example_value': u'MOT_APA',
}
})
def codifications_list(self, request, category):
codifications = self.get_codifications().get(category, {}).get('codifications', [])
items = [{
'id': codification['code'],
'text': codification['label']
} for codification in codifications]
return {'data': items}
def check_status(self):
return bool(self.call_select_codifications())
@property
def select_appairage_url(self):
return urlparse.urljoin(self.webservice_base_url, 'selectAppairage')
def call_select_appairage(self, login, password, email):
row = self.xml_request(self.select_appairage_url, params={
'login': login,
'password': password,
'email': email,
})
row_d = xmlutils.to_json(row)
id_per = row_d.get('ID_PER', '').strip()
code = row_d.get('CD_RET', '').strip()
label = row_d.get('LB_RET', '').strip()
error = None
if code not in ['1', '2', '3', '4', '5', '6']:
error = 'invalid CD_RET: %s' % code,
if code in ['2', '3', '5'] and not id_per:
error = 'missing ID_PER'
if error:
raise APIError(error, data={'response': repr(ET.tostring(row))})
return code, label, id_per
@endpoint(name='link',
methods=['post'],
description=_('Create link with an extranet account'),
parameters={
'NameID':{
'description': _('Publik NameID'),
'example_value': 'xyz24d934',
},
'email': {
'description': _('Publik known email'),
'example_value': 'john.doe@example.com',
},
'login': {
'description': _('ATOS Genesys extranet login'),
'example_value': '1234',
},
'password': {
'description': _('ATOS Genesys extranet password'),
'example_value': 'password',
}
})
def link(self, request, NameID, email, login, password):
code, label, id_per = self.call_select_appairage(login, password, email)
if code in ['2', '3', '5']:
link, created = Link.objects.get_or_create(
resource=self,
name_id=NameID,
id_per=id_per)
return {'link_id': link.pk, 'new': created, 'code': code, 'label': label}
elif code == '6':
raise APIError('unknown-login', data={'code': code, 'label': label})
elif code in ['4', '1']:
raise APIError('invalid-password', data={'code': code, 'label': label})
@endpoint(name='unlink',
methods=['post'],
description=_('Delete link with an extranet account'),
parameters={
'NameID':{
'description': _('Publik NameID'),
'example_value': 'xyz24d934',
},
'link_id': {
'description': _('Identifier of the link'),
'example_value': '1',
},
})
def unlink(self, request, NameID, link_id):
try:
link_id = int(link_id.strip())
except ValueError:
raise APIError('invalid link_id')
qs = Link.objects.filter(
resource=self,
name_id=NameID,
pk=link_id)
count = qs.count()
qs.delete()
return {'deleted': count}
@property
def select_usager_url(self):
return urlparse.urljoin(self.webservice_base_url, 'selectUsager')
def call_select_usager(self, id_per):
row = self.xml_request(self.select_usager_url, params={
'idPer': id_per,
'codRgp': self.cod_rgp,
})
return xmlutils.to_json(row)
@endpoint(name='dossiers',
description=_('Get datas for all links'),
parameters={
'NameID':{
'description': _('Publik NameID'),
'example_value': 'xyz24d934',
},
})
def dossiers(self, request, NameID):
qs = Link.objects.filter(
resource=self,
name_id=NameID)
data = []
for link in qs:
cache = utils.RowLockedCache(
function=self.call_select_usager,
row=link,
key_prefix='atos-genesys-usager')
id_per = link.id_per
dossier = cache(id_per)
data.append({
'id_per': id_per,
'dossier': dossier,
})
return {'data': data}
class Link(models.Model):
resource = models.ForeignKey(
Resource,
on_delete=models.CASCADE)
name_id = models.CharField(
verbose_name=_('NameID'),
blank=False,
max_length=256)
id_per = models.CharField(
verbose_name=_('ID Per'),
blank=False,
max_length=64)
created = models.DateTimeField(
verbose_name=_('Creation date'),
auto_now_add=True)
extra = jsonfield.JSONField(
verbose_name=_('Anything'),
null=True)
class Meta:
unique_together = (
'resource', 'name_id', 'id_per',
)
ordering = ['created']

View File

@ -0,0 +1,77 @@
import time
import six
import threading
from contextlib import contextmanager
from django.db import transaction
from django.core.cache import cache
DEFAULT_DURATION = 5 * 60 # 5 minutes
# keep data in cache for 1 day, i.e. we can answer a request from cache for 1 day
# day
CACHE_DURATION = 86400
@contextmanager
def row_lock(row):
if row:
with transaction.atomic():
list(row.__class__.objects.filter(pk=row.pk).select_for_update())
yield
else:
yield
class RowLockedCache(object):
'''Cache return value of a function, always return the cached value for
performance but if the cache is stale update it asynchronously using
a thread, prevent multiple update using row locks on database models and
an update cache key.
'''
def __init__(self, function, row=None, duration=DEFAULT_DURATION, key_prefix=None):
self.function = function
self.row = row
self.duration = duration
self.key_prefix = key_prefix or function.__name__
def _key(self, *args, **kwargs):
keys = []
if self.row:
keys.append(str(self.row.pk))
for arg in args:
if isinstance(arg, six.string_types):
keys.append(arg)
else:
keys.append(hash(arg))
return self.key_prefix + '-' + '-'.join(keys)
def __call__(self, *args, **kwargs):
now = time.time()
key = self._key(*args, **kwargs)
# Fast path
cacheline = cache.get(key)
if cacheline:
timestamp = cacheline['timestamp']
if now - timestamp >= self.duration:
with row_lock(self.row):
# Slow path, check cacheline again
cacheline = cache.get(key)
if now - timestamp < self.duration:
return cacheline['value']
updatekey = 'update-' + key
update = cache.get(updatekey)
if not update or (update['timestamp'] - now >= self.duration):
cache.set(updatekey, {'timestamp': now}, CACHE_DURATION)
def update():
value = self.function(*args, **kwargs)
cache.set(key, {'value': value, 'timestamp': now}, CACHE_DURATION)
cache.delete(updatekey)
threading.Thread(target=update).start()
return cacheline['value']
else:
value = self.function(*args, **kwargs)
cache.set(key, {'value': value, 'timestamp': now}, CACHE_DURATION)
return value

View File

@ -117,6 +117,7 @@ INSTALLED_APPS = (
# connectors
'passerelle.apps.airquality',
'passerelle.apps.api_particulier',
'passerelle.apps.atos_genesys',
'passerelle.apps.base_adresse',
'passerelle.apps.bdp',
'passerelle.apps.choosit',

View File

@ -98,3 +98,14 @@ def endpoint_dummy_cache(monkeypatch):
import passerelle.views
monkeypatch.setattr(
passerelle.views, 'cache', caches['dummy'])
@urlmatch()
def internal_server_error(url, request):
return response(500, 'Internal server error')
@pytest.fixture
def mock_500():
with HTTMock(internal_server_error):
yield None

View File

@ -0,0 +1,975 @@
<?xml version="1.0" encoding="UTF-8"?>
<return><ROWSET>
<ROW>
<CODIFICATIONS>
<CODIFICATIONS_ROW>
<CD_CODIF>RNV_APA</CD_CODIF>
<LB_CODIF>Renouvellement</LB_CODIF>
<IN_VAL_CODIF>O</IN_VAL_CODIF>
<CD_CAT_CODIF>MOT_APA</CD_CAT_CODIF>
<LB_CAT_CODIF>Motif des demandes d'APA</LB_CAT_CODIF>
</CODIFICATIONS_ROW>
<CODIFICATIONS_ROW>
<CD_CODIF>AGG_APA</CD_CODIF>
<LB_CODIF>Aggravation</LB_CODIF>
<IN_VAL_CODIF>O</IN_VAL_CODIF>
<CD_CAT_CODIF>MOT_APA</CD_CAT_CODIF>
<LB_CAT_CODIF>Motif des demandes d'APA</LB_CAT_CODIF>
</CODIFICATIONS_ROW>
<CODIFICATIONS_ROW>
<CD_CODIF>SITFAM_V</CD_CODIF>
<LB_CODIF>Veuf/Veuve</LB_CODIF>
<IN_VAL_CODIF>O</IN_VAL_CODIF>
<CD_CAT_CODIF>SITFAM</CD_CAT_CODIF>
<LB_CAT_CODIF>Situation familiale</LB_CAT_CODIF>
</CODIFICATIONS_ROW>
<CODIFICATIONS_ROW>
<CD_CODIF>SITFAM_B</CD_CODIF>
<LB_CODIF>Concubin(e)</LB_CODIF>
<IN_VAL_CODIF>O</IN_VAL_CODIF>
<CD_CAT_CODIF>SITFAM</CD_CAT_CODIF>
<LB_CAT_CODIF>Situation familiale</LB_CAT_CODIF>
</CODIFICATIONS_ROW>
<CODIFICATIONS_ROW>
<CD_CODIF>SITFAM_C</CD_CODIF>
<LB_CODIF>Célibataire</LB_CODIF>
<IN_VAL_CODIF>O</IN_VAL_CODIF>
<CD_CAT_CODIF>SITFAM</CD_CAT_CODIF>
<LB_CAT_CODIF>Situation familiale</LB_CAT_CODIF>
</CODIFICATIONS_ROW>
<CODIFICATIONS_ROW>
<CD_CODIF>SITFAM_M</CD_CODIF>
<LB_CODIF>Marié(e)/Pacsé(e)</LB_CODIF>
<IN_VAL_CODIF>O</IN_VAL_CODIF>
<CD_CAT_CODIF>SITFAM</CD_CAT_CODIF>
<LB_CAT_CODIF>Situation familiale</LB_CAT_CODIF>
</CODIFICATIONS_ROW>
<CODIFICATIONS_ROW>
<CD_CODIF>SITFAM_S</CD_CODIF>
<LB_CODIF>Séparé(e)</LB_CODIF>
<IN_VAL_CODIF>O</IN_VAL_CODIF>
<CD_CAT_CODIF>SITFAM</CD_CAT_CODIF>
<LB_CAT_CODIF>Situation familiale</LB_CAT_CODIF>
</CODIFICATIONS_ROW>
<CODIFICATIONS_ROW>
<CD_CODIF>SITFAM_A</CD_CODIF>
<LB_CODIF>Autre</LB_CODIF>
<IN_VAL_CODIF>O</IN_VAL_CODIF>
<CD_CAT_CODIF>SITFAM</CD_CAT_CODIF>
<LB_CAT_CODIF>Situation familiale</LB_CAT_CODIF>
</CODIFICATIONS_ROW>
<CODIFICATIONS_ROW>
<CD_CODIF>SITFOY_CE</CD_CODIF>
<LB_CODIF>Conjoint en établissement</LB_CODIF>
<IN_VAL_CODIF>O</IN_VAL_CODIF>
<CD_CAT_CODIF>SITFOY</CD_CAT_CODIF>
<LB_CAT_CODIF>Situation foyer</LB_CAT_CODIF>
</CODIFICATIONS_ROW>
<CODIFICATIONS_ROW>
<CD_CODIF>SITFOY_S</CD_CODIF>
<LB_CODIF>Personne seule</LB_CODIF>
<IN_VAL_CODIF>O</IN_VAL_CODIF>
<CD_CAT_CODIF>SITFOY</CD_CAT_CODIF>
<LB_CAT_CODIF>Situation foyer</LB_CAT_CODIF>
</CODIFICATIONS_ROW>
<CODIFICATIONS_ROW>
<CD_CODIF>SITFOY_CD</CD_CODIF>
<LB_CODIF>Conjoint à domicile</LB_CODIF>
<IN_VAL_CODIF>O</IN_VAL_CODIF>
<CD_CAT_CODIF>SITFOY</CD_CAT_CODIF>
<LB_CAT_CODIF>Situation foyer</LB_CAT_CODIF>
</CODIFICATIONS_ROW>
<CODIFICATIONS_ROW>
<CD_CODIF>TYP_ADR_A</CD_CODIF>
<LB_CODIF>En famille d'accueil agréée</LB_CODIF>
<IN_VAL_CODIF>O</IN_VAL_CODIF>
<CD_CAT_CODIF>TYP_ADR</CD_CAT_CODIF>
<LB_CAT_CODIF>Type Adresse</LB_CAT_CODIF>
</CODIFICATIONS_ROW>
<CODIFICATIONS_ROW>
<CD_CODIF>TYP_ADR_E</CD_CODIF>
<LB_CODIF>En établissement médico-social hors-foyer logement</LB_CODIF>
<IN_VAL_CODIF>O</IN_VAL_CODIF>
<CD_CAT_CODIF>TYP_ADR</CD_CAT_CODIF>
<LB_CAT_CODIF>Type Adresse</LB_CAT_CODIF>
</CODIFICATIONS_ROW>
<CODIFICATIONS_ROW>
<CD_CODIF>TYP_ADR_P</CD_CODIF>
<LB_CODIF>Propriétaire</LB_CODIF>
<IN_VAL_CODIF>O</IN_VAL_CODIF>
<CD_CAT_CODIF>TYP_ADR</CD_CAT_CODIF>
<LB_CAT_CODIF>Type Adresse</LB_CAT_CODIF>
</CODIFICATIONS_ROW>
<CODIFICATIONS_ROW>
<CD_CODIF>TYP_ADR_L</CD_CODIF>
<LB_CODIF>Locataire</LB_CODIF>
<IN_VAL_CODIF>O</IN_VAL_CODIF>
<CD_CAT_CODIF>TYP_ADR</CD_CAT_CODIF>
<LB_CAT_CODIF>Type Adresse</LB_CAT_CODIF>
</CODIFICATIONS_ROW>
<CODIFICATIONS_ROW>
<CD_CODIF>TYP_ADR_T</CD_CODIF>
<LB_CODIF>Chez un tiers</LB_CODIF>
<IN_VAL_CODIF>O</IN_VAL_CODIF>
<CD_CAT_CODIF>TYP_ADR</CD_CAT_CODIF>
<LB_CAT_CODIF>Type Adresse</LB_CAT_CODIF>
</CODIFICATIONS_ROW>
<CODIFICATIONS_ROW>
<CD_CODIF>TYP_ADR_U</CD_CODIF>
<LB_CODIF>Usurfrutier(e)</LB_CODIF>
<IN_VAL_CODIF>O</IN_VAL_CODIF>
<CD_CAT_CODIF>TYP_ADR</CD_CAT_CODIF>
<LB_CAT_CODIF>Type Adresse</LB_CAT_CODIF>
</CODIFICATIONS_ROW>
<CODIFICATIONS_ROW>
<CD_CODIF>TYP_ADR_F</CD_CODIF>
<LB_CODIF>En foyer logement</LB_CODIF>
<IN_VAL_CODIF>O</IN_VAL_CODIF>
<CD_CAT_CODIF>TYP_ADR</CD_CAT_CODIF>
<LB_CAT_CODIF>Type Adresse</LB_CAT_CODIF>
</CODIFICATIONS_ROW>
<CODIFICATIONS_ROW>
<CD_CODIF>TYP_LIEN_CUR</CD_CODIF>
<LB_CODIF>Curatelle</LB_CODIF>
<IN_VAL_CODIF>O</IN_VAL_CODIF>
<CD_CAT_CODIF>TYP_LIEN</CD_CAT_CODIF>
<LB_CAT_CODIF>Type Lien</LB_CAT_CODIF>
</CODIFICATIONS_ROW>
<CODIFICATIONS_ROW>
<CD_CODIF>TYP_LIEN_AUT</CD_CODIF>
<LB_CODIF>Autre</LB_CODIF>
<IN_VAL_CODIF>O</IN_VAL_CODIF>
<CD_CAT_CODIF>TYP_LIEN</CD_CAT_CODIF>
<LB_CAT_CODIF>Type Lien</LB_CAT_CODIF>
</CODIFICATIONS_ROW>
<CODIFICATIONS_ROW>
<CD_CODIF>TYP_LIEN_TUT</CD_CODIF>
<LB_CODIF>Tutelle</LB_CODIF>
<IN_VAL_CODIF>O</IN_VAL_CODIF>
<CD_CAT_CODIF>TYP_LIEN</CD_CAT_CODIF>
<LB_CAT_CODIF>Type Lien</LB_CAT_CODIF>
</CODIFICATIONS_ROW>
<CODIFICATIONS_ROW>
<CD_CODIF>TYP_CNT_AUT</CD_CODIF>
<LB_CODIF>Autre</LB_CODIF>
<IN_VAL_CODIF>O</IN_VAL_CODIF>
<CD_CAT_CODIF>TYP_LIEN_CNT</CD_CAT_CODIF>
<LB_CAT_CODIF>Type Lien contacts</LB_CAT_CODIF>
</CODIFICATIONS_ROW>
<CODIFICATIONS_ROW>
<CD_CODIF>TYP_CNT_PAR</CD_CODIF>
<LB_CODIF>Parent</LB_CODIF>
<IN_VAL_CODIF>O</IN_VAL_CODIF>
<CD_CAT_CODIF>TYP_LIEN_CNT</CD_CAT_CODIF>
<LB_CAT_CODIF>Type Lien contacts</LB_CAT_CODIF>
</CODIFICATIONS_ROW>
<CODIFICATIONS_ROW>
<CD_CODIF>TYP_CNT_AID</CD_CODIF>
<LB_CODIF>Aidant</LB_CODIF>
<IN_VAL_CODIF>O</IN_VAL_CODIF>
<CD_CAT_CODIF>TYP_LIEN_CNT</CD_CAT_CODIF>
<LB_CAT_CODIF>Type Lien contacts</LB_CAT_CODIF>
</CODIFICATIONS_ROW>
<CODIFICATIONS_ROW>
<CD_CODIF>TYP_CNT_PRO</CD_CODIF>
<LB_CODIF>Proche</LB_CODIF>
<IN_VAL_CODIF>O</IN_VAL_CODIF>
<CD_CAT_CODIF>TYP_LIEN_CNT</CD_CAT_CODIF>
<LB_CAT_CODIF>Type Lien contacts</LB_CAT_CODIF>
</CODIFICATIONS_ROW>
<CODIFICATIONS_ROW>
<CD_CODIF>TYP_CNT_ENF</CD_CODIF>
<LB_CODIF>Enfant</LB_CODIF>
<IN_VAL_CODIF>O</IN_VAL_CODIF>
<CD_CAT_CODIF>TYP_LIEN_CNT</CD_CAT_CODIF>
<LB_CAT_CODIF>Type Lien contacts</LB_CAT_CODIF>
</CODIFICATIONS_ROW>
<CODIFICATIONS_ROW>
<CD_CODIF>TYP_CNT_FS</CD_CODIF>
<LB_CODIF>Frère - Soeur</LB_CODIF>
<IN_VAL_CODIF>O</IN_VAL_CODIF>
<CD_CAT_CODIF>TYP_LIEN_CNT</CD_CAT_CODIF>
<LB_CAT_CODIF>Type Lien contacts</LB_CAT_CODIF>
</CODIFICATIONS_ROW>
<CODIFICATIONS_ROW>
<CD_CODIF>TYP_CNT_CJT</CD_CODIF>
<LB_CODIF>Conjoint</LB_CODIF>
<IN_VAL_CODIF>O</IN_VAL_CODIF>
<CD_CAT_CODIF>TYP_LIEN_CNT</CD_CAT_CODIF>
<LB_CAT_CODIF>Type Lien contacts</LB_CAT_CODIF>
</CODIFICATIONS_ROW>
</CODIFICATIONS>
<CATEGORIES>
<CATEGORIES_ROW>
<CD_CAT_CODIF>MOT_APA</CD_CAT_CODIF>
<LB_CAT_CODIF>Motif des demandes d'APA</LB_CAT_CODIF>
</CATEGORIES_ROW>
<CATEGORIES_ROW>
<CD_CAT_CODIF>SITFAM</CD_CAT_CODIF>
<LB_CAT_CODIF>Situation familiale</LB_CAT_CODIF>
</CATEGORIES_ROW>
<CATEGORIES_ROW>
<CD_CAT_CODIF>SITFOY</CD_CAT_CODIF>
<LB_CAT_CODIF>Situation foyer</LB_CAT_CODIF>
</CATEGORIES_ROW>
<CATEGORIES_ROW>
<CD_CAT_CODIF>TYP_ADR</CD_CAT_CODIF>
<LB_CAT_CODIF>Type Adresse</LB_CAT_CODIF>
</CATEGORIES_ROW>
<CATEGORIES_ROW>
<CD_CAT_CODIF>TYP_LIEN</CD_CAT_CODIF>
<LB_CAT_CODIF>Type Lien</LB_CAT_CODIF>
</CATEGORIES_ROW>
<CATEGORIES_ROW>
<CD_CAT_CODIF>TYP_LIEN_CNT</CD_CAT_CODIF>
<LB_CAT_CODIF>Type Lien contacts</LB_CAT_CODIF>
</CATEGORIES_ROW>
</CATEGORIES>
<COD_VOIE>
<COD_VOIE_ROW>
<CD_E_COD_VOIE>TOUR</CD_E_COD_VOIE>
<LB_E_COD_VOIE>Tour</LB_E_COD_VOIE>
</COD_VOIE_ROW>
<COD_VOIE_ROW>
<CD_E_COD_VOIE>RUE</CD_E_COD_VOIE>
<LB_E_COD_VOIE>Rue</LB_E_COD_VOIE>
</COD_VOIE_ROW>
<COD_VOIE_ROW>
<CD_E_COD_VOIE>AV</CD_E_COD_VOIE>
<LB_E_COD_VOIE>Avenue</LB_E_COD_VOIE>
</COD_VOIE_ROW>
<COD_VOIE_ROW>
<CD_E_COD_VOIE>QUA</CD_E_COD_VOIE>
<LB_E_COD_VOIE>Quartier</LB_E_COD_VOIE>
</COD_VOIE_ROW>
<COD_VOIE_ROW>
<CD_E_COD_VOIE>CIT</CD_E_COD_VOIE>
<LB_E_COD_VOIE>Cité</LB_E_COD_VOIE>
</COD_VOIE_ROW>
<COD_VOIE_ROW>
<CD_E_COD_VOIE>ESP</CD_E_COD_VOIE>
<LB_E_COD_VOIE>Espace</LB_E_COD_VOIE>
</COD_VOIE_ROW>
<COD_VOIE_ROW>
<CD_E_COD_VOIE>TR</CD_E_COD_VOIE>
<LB_E_COD_VOIE>Traverse</LB_E_COD_VOIE>
</COD_VOIE_ROW>
<COD_VOIE_ROW>
<CD_E_COD_VOIE>IMP</CD_E_COD_VOIE>
<LB_E_COD_VOIE>Impasse</LB_E_COD_VOIE>
</COD_VOIE_ROW>
<COD_VOIE_ROW>
<CD_E_COD_VOIE>ALL</CD_E_COD_VOIE>
<LB_E_COD_VOIE>Allée</LB_E_COD_VOIE>
</COD_VOIE_ROW>
<COD_VOIE_ROW>
<CD_E_COD_VOIE>BLD</CD_E_COD_VOIE>
<LB_E_COD_VOIE>Boulevard</LB_E_COD_VOIE>
</COD_VOIE_ROW>
<COD_VOIE_ROW>
<CD_E_COD_VOIE>CHE</CD_E_COD_VOIE>
<LB_E_COD_VOIE>Chemin</LB_E_COD_VOIE>
</COD_VOIE_ROW>
<COD_VOIE_ROW>
<CD_E_COD_VOIE>IMM</CD_E_COD_VOIE>
<LB_E_COD_VOIE>Immeuble</LB_E_COD_VOIE>
</COD_VOIE_ROW>
<COD_VOIE_ROW>
<CD_E_COD_VOIE>PAR</CD_E_COD_VOIE>
<LB_E_COD_VOIE>Parc</LB_E_COD_VOIE>
</COD_VOIE_ROW>
<COD_VOIE_ROW>
<CD_E_COD_VOIE>PAS</CD_E_COD_VOIE>
<LB_E_COD_VOIE>Passage</LB_E_COD_VOIE>
</COD_VOIE_ROW>
<COD_VOIE_ROW>
<CD_E_COD_VOIE>PL</CD_E_COD_VOIE>
<LB_E_COD_VOIE>Place</LB_E_COD_VOIE>
</COD_VOIE_ROW>
<COD_VOIE_ROW>
<CD_E_COD_VOIE>PTE</CD_E_COD_VOIE>
<LB_E_COD_VOIE>Porte</LB_E_COD_VOIE>
</COD_VOIE_ROW>
<COD_VOIE_ROW>
<CD_E_COD_VOIE>RTE</CD_E_COD_VOIE>
<LB_E_COD_VOIE>Route</LB_E_COD_VOIE>
</COD_VOIE_ROW>
<COD_VOIE_ROW>
<CD_E_COD_VOIE>MTE</CD_E_COD_VOIE>
<LB_E_COD_VOIE>Montée</LB_E_COD_VOIE>
</COD_VOIE_ROW>
<COD_VOIE_ROW>
<CD_E_COD_VOIE>RES</CD_E_COD_VOIE>
<LB_E_COD_VOIE>Résidence</LB_E_COD_VOIE>
</COD_VOIE_ROW>
<COD_VOIE_ROW>
<CD_E_COD_VOIE>VO</CD_E_COD_VOIE>
<LB_E_COD_VOIE>Voie</LB_E_COD_VOIE>
</COD_VOIE_ROW>
<COD_VOIE_ROW>
<CD_E_COD_VOIE>ARC</CD_E_COD_VOIE>
<LB_E_COD_VOIE>Arcade</LB_E_COD_VOIE>
</COD_VOIE_ROW>
<COD_VOIE_ROW>
<CD_E_COD_VOIE>CAV</CD_E_COD_VOIE>
<LB_E_COD_VOIE>Cavée</LB_E_COD_VOIE>
</COD_VOIE_ROW>
<COD_VOIE_ROW>
<CD_E_COD_VOIE>CHS</CD_E_COD_VOIE>
<LB_E_COD_VOIE>Chaussée</LB_E_COD_VOIE>
</COD_VOIE_ROW>
<COD_VOIE_ROW>
<CD_E_COD_VOIE>COT</CD_E_COD_VOIE>
<LB_E_COD_VOIE>Côte</LB_E_COD_VOIE>
</COD_VOIE_ROW>
<COD_VOIE_ROW>
<CD_E_COD_VOIE>LOT</CD_E_COD_VOIE>
<LB_E_COD_VOIE>Lotissement</LB_E_COD_VOIE>
</COD_VOIE_ROW>
<COD_VOIE_ROW>
<CD_E_COD_VOIE>CR</CD_E_COD_VOIE>
<LB_E_COD_VOIE>Cour</LB_E_COD_VOIE>
</COD_VOIE_ROW>
<COD_VOIE_ROW>
<CD_E_COD_VOIE>DIG</CD_E_COD_VOIE>
<LB_E_COD_VOIE>Digue</LB_E_COD_VOIE>
</COD_VOIE_ROW>
<COD_VOIE_ROW>
<CD_E_COD_VOIE>ECL</CD_E_COD_VOIE>
<LB_E_COD_VOIE>Ecluse</LB_E_COD_VOIE>
</COD_VOIE_ROW>
<COD_VOIE_ROW>
<CD_E_COD_VOIE>ESC</CD_E_COD_VOIE>
<LB_E_COD_VOIE>Escalier</LB_E_COD_VOIE>
</COD_VOIE_ROW>
<COD_VOIE_ROW>
<CD_E_COD_VOIE>GE</CD_E_COD_VOIE>
<LB_E_COD_VOIE>Grand ensemble</LB_E_COD_VOIE>
</COD_VOIE_ROW>
<COD_VOIE_ROW>
<CD_E_COD_VOIE>ML</CD_E_COD_VOIE>
<LB_E_COD_VOIE>Moulin</LB_E_COD_VOIE>
</COD_VOIE_ROW>
<COD_VOIE_ROW>
<CD_E_COD_VOIE>PER</CD_E_COD_VOIE>
<LB_E_COD_VOIE>Périphérique</LB_E_COD_VOIE>
</COD_VOIE_ROW>
<COD_VOIE_ROW>
<CD_E_COD_VOIE>PRO</CD_E_COD_VOIE>
<LB_E_COD_VOIE>Promenade</LB_E_COD_VOIE>
</COD_VOIE_ROW>
<COD_VOIE_ROW>
<CD_E_COD_VOIE>PT</CD_E_COD_VOIE>
<LB_E_COD_VOIE>Pont</LB_E_COD_VOIE>
</COD_VOIE_ROW>
<COD_VOIE_ROW>
<CD_E_COD_VOIE>RAM</CD_E_COD_VOIE>
<LB_E_COD_VOIE>Rampe</LB_E_COD_VOIE>
</COD_VOIE_ROW>
<COD_VOIE_ROW>
<CD_E_COD_VOIE>RP</CD_E_COD_VOIE>
<LB_E_COD_VOIE>Rond point</LB_E_COD_VOIE>
</COD_VOIE_ROW>
<COD_VOIE_ROW>
<CD_E_COD_VOIE>RUL</CD_E_COD_VOIE>
<LB_E_COD_VOIE>Ruelle</LB_E_COD_VOIE>
</COD_VOIE_ROW>
<COD_VOIE_ROW>
<CD_E_COD_VOIE>SEN</CD_E_COD_VOIE>
<LB_E_COD_VOIE>Sentier</LB_E_COD_VOIE>
</COD_VOIE_ROW>
<COD_VOIE_ROW>
<CD_E_COD_VOIE>SAS</CD_E_COD_VOIE>
<LB_E_COD_VOIE>Sas</LB_E_COD_VOIE>
</COD_VOIE_ROW>
<COD_VOIE_ROW>
<CD_E_COD_VOIE>PRV</CD_E_COD_VOIE>
<LB_E_COD_VOIE>Parvis</LB_E_COD_VOIE>
</COD_VOIE_ROW>
<COD_VOIE_ROW>
<CD_E_COD_VOIE>PVS</CD_E_COD_VOIE>
<LB_E_COD_VOIE>xxxxxx</LB_E_COD_VOIE>
</COD_VOIE_ROW>
<COD_VOIE_ROW>
<CD_E_COD_VOIE>GAR</CD_E_COD_VOIE>
<LB_E_COD_VOIE>Gare</LB_E_COD_VOIE>
</COD_VOIE_ROW>
<COD_VOIE_ROW>
<CD_E_COD_VOIE>SQ</CD_E_COD_VOIE>
<LB_E_COD_VOIE>Square</LB_E_COD_VOIE>
</COD_VOIE_ROW>
<COD_VOIE_ROW>
<CD_E_COD_VOIE>TPL</CD_E_COD_VOIE>
<LB_E_COD_VOIE>Terre plein</LB_E_COD_VOIE>
</COD_VOIE_ROW>
<COD_VOIE_ROW>
<CD_E_COD_VOIE>Q</CD_E_COD_VOIE>
<LB_E_COD_VOIE>Quai</LB_E_COD_VOIE>
</COD_VOIE_ROW>
<COD_VOIE_ROW>
<CD_E_COD_VOIE>SET</CD_E_COD_VOIE>
<LB_E_COD_VOIE>Sente</LB_E_COD_VOIE>
</COD_VOIE_ROW>
<COD_VOIE_ROW>
<CD_E_COD_VOIE>FAU</CD_E_COD_VOIE>
<LB_E_COD_VOIE>Faubourg</LB_E_COD_VOIE>
</COD_VOIE_ROW>
<COD_VOIE_ROW>
<CD_E_COD_VOIE>HAM</CD_E_COD_VOIE>
<LB_E_COD_VOIE>Hameau</LB_E_COD_VOIE>
</COD_VOIE_ROW>
<COD_VOIE_ROW>
<CD_E_COD_VOIE>LIEU</CD_E_COD_VOIE>
<LB_E_COD_VOIE>Lieudit</LB_E_COD_VOIE>
</COD_VOIE_ROW>
<COD_VOIE_ROW>
<CD_E_COD_VOIE>PRU</CD_E_COD_VOIE>
<LB_E_COD_VOIE>Petite rue</LB_E_COD_VOIE>
</COD_VOIE_ROW>
<COD_VOIE_ROW>
<CD_E_COD_VOIE>PTR</CD_E_COD_VOIE>
<LB_E_COD_VOIE>Pourtour</LB_E_COD_VOIE>
</COD_VOIE_ROW>
<COD_VOIE_ROW>
<CD_E_COD_VOIE>IL</CD_E_COD_VOIE>
<LB_E_COD_VOIE>Ilôt</LB_E_COD_VOIE>
</COD_VOIE_ROW>
<COD_VOIE_ROW>
<CD_E_COD_VOIE>PPL</CD_E_COD_VOIE>
<LB_E_COD_VOIE>Placette</LB_E_COD_VOIE>
</COD_VOIE_ROW>
<COD_VOIE_ROW>
<CD_E_COD_VOIE>STA</CD_E_COD_VOIE>
<LB_E_COD_VOIE>Stade</LB_E_COD_VOIE>
</COD_VOIE_ROW>
<COD_VOIE_ROW>
<CD_E_COD_VOIE>CS</CD_E_COD_VOIE>
<LB_E_COD_VOIE>Complexe sportif</LB_E_COD_VOIE>
</COD_VOIE_ROW>
<COD_VOIE_ROW>
<CD_E_COD_VOIE>ZON</CD_E_COD_VOIE>
<LB_E_COD_VOIE>Zone Industrielle</LB_E_COD_VOIE>
</COD_VOIE_ROW>
<COD_VOIE_ROW>
<CD_E_COD_VOIE>CLO</CD_E_COD_VOIE>
<LB_E_COD_VOIE>Clos</LB_E_COD_VOIE>
</COD_VOIE_ROW>
<COD_VOIE_ROW>
<CD_E_COD_VOIE>CAM</CD_E_COD_VOIE>
<LB_E_COD_VOIE>Camp</LB_E_COD_VOIE>
</COD_VOIE_ROW>
<COD_VOIE_ROW>
<CD_E_COD_VOIE>PSL</CD_E_COD_VOIE>
<LB_E_COD_VOIE>Passerelle</LB_E_COD_VOIE>
</COD_VOIE_ROW>
<COD_VOIE_ROW>
<CD_E_COD_VOIE>GRU</CD_E_COD_VOIE>
<LB_E_COD_VOIE>Grande rue</LB_E_COD_VOIE>
</COD_VOIE_ROW>
<COD_VOIE_ROW>
<CD_E_COD_VOIE>DES</CD_E_COD_VOIE>
<LB_E_COD_VOIE>Desserte</LB_E_COD_VOIE>
</COD_VOIE_ROW>
<COD_VOIE_ROW>
<CD_E_COD_VOIE>ILE</CD_E_COD_VOIE>
<LB_E_COD_VOIE>Ile</LB_E_COD_VOIE>
</COD_VOIE_ROW>
<COD_VOIE_ROW>
<CD_E_COD_VOIE>RU</CD_E_COD_VOIE>
<LB_E_COD_VOIE>Résidence Universitaire</LB_E_COD_VOIE>
</COD_VOIE_ROW>
<COD_VOIE_ROW>
<CD_E_COD_VOIE>CEN</CD_E_COD_VOIE>
<LB_E_COD_VOIE>Centre</LB_E_COD_VOIE>
</COD_VOIE_ROW>
<COD_VOIE_ROW>
<CD_E_COD_VOIE>HOP</CD_E_COD_VOIE>
<LB_E_COD_VOIE>Hopital</LB_E_COD_VOIE>
</COD_VOIE_ROW>
<COD_VOIE_ROW>
<CD_E_COD_VOIE>MAI</CD_E_COD_VOIE>
<LB_E_COD_VOIE>Mail</LB_E_COD_VOIE>
</COD_VOIE_ROW>
<COD_VOIE_ROW>
<CD_E_COD_VOIE>CAR</CD_E_COD_VOIE>
<LB_E_COD_VOIE>Carrefour</LB_E_COD_VOIE>
</COD_VOIE_ROW>
<COD_VOIE_ROW>
<CD_E_COD_VOIE>CRS</CD_E_COD_VOIE>
<LB_E_COD_VOIE>Cours</LB_E_COD_VOIE>
</COD_VOIE_ROW>
<COD_VOIE_ROW>
<CD_E_COD_VOIE>DOM</CD_E_COD_VOIE>
<LB_E_COD_VOIE>Domaine</LB_E_COD_VOIE>
</COD_VOIE_ROW>
<COD_VOIE_ROW>
<CD_E_COD_VOIE>ROC</CD_E_COD_VOIE>
<LB_E_COD_VOIE>Rocade</LB_E_COD_VOIE>
</COD_VOIE_ROW>
<COD_VOIE_ROW>
<CD_E_COD_VOIE>PLE</CD_E_COD_VOIE>
<LB_E_COD_VOIE>Plateforme</LB_E_COD_VOIE>
</COD_VOIE_ROW>
<COD_VOIE_ROW>
<CD_E_COD_VOIE>AUT</CD_E_COD_VOIE>
<LB_E_COD_VOIE>Autoroute</LB_E_COD_VOIE>
</COD_VOIE_ROW>
<COD_VOIE_ROW>
<CD_E_COD_VOIE>ESL</CD_E_COD_VOIE>
<LB_E_COD_VOIE>Esplanade</LB_E_COD_VOIE>
</COD_VOIE_ROW>
<COD_VOIE_ROW>
<CD_E_COD_VOIE>BEGI</CD_E_COD_VOIE>
<LB_E_COD_VOIE>Beguinage</LB_E_COD_VOIE>
</COD_VOIE_ROW>
<COD_VOIE_ROW>
<CD_E_COD_VOIE>COL</CD_E_COD_VOIE>
<LB_E_COD_VOIE>Col</LB_E_COD_VOIE>
</COD_VOIE_ROW>
<COD_VOIE_ROW>
<CD_E_COD_VOIE>GBD</CD_E_COD_VOIE>
<LB_E_COD_VOIE>Grand Boulevard</LB_E_COD_VOIE>
</COD_VOIE_ROW>
<COD_VOIE_ROW>
<CD_E_COD_VOIE>CTR</CD_E_COD_VOIE>
<LB_E_COD_VOIE>Contour</LB_E_COD_VOIE>
</COD_VOIE_ROW>
<COD_VOIE_ROW>
<CD_E_COD_VOIE>VAL</CD_E_COD_VOIE>
<LB_E_COD_VOIE>Val </LB_E_COD_VOIE>
</COD_VOIE_ROW>
<COD_VOIE_ROW>
<CD_E_COD_VOIE>PLG</CD_E_COD_VOIE>
<LB_E_COD_VOIE>Plage</LB_E_COD_VOIE>
</COD_VOIE_ROW>
<COD_VOIE_ROW>
<CD_E_COD_VOIE>ANC</CD_E_COD_VOIE>
<LB_E_COD_VOIE>Ancienne</LB_E_COD_VOIE>
</COD_VOIE_ROW>
<COD_VOIE_ROW>
<CD_E_COD_VOIE>BTP</CD_E_COD_VOIE>
<LB_E_COD_VOIE>Boîte postale</LB_E_COD_VOIE>
</COD_VOIE_ROW>
<COD_VOIE_ROW>
<CD_E_COD_VOIE>ZAC</CD_E_COD_VOIE>
<LB_E_COD_VOIE>ZAC</LB_E_COD_VOIE>
</COD_VOIE_ROW>
<COD_VOIE_ROW>
<CD_E_COD_VOIE>ZONE</CD_E_COD_VOIE>
<LB_E_COD_VOIE>Zone</LB_E_COD_VOIE>
</COD_VOIE_ROW>
<COD_VOIE_ROW>
<CD_E_COD_VOIE>ABE</CD_E_COD_VOIE>
<LB_E_COD_VOIE>Abbaye</LB_E_COD_VOIE>
</COD_VOIE_ROW>
<COD_VOIE_ROW>
<CD_E_COD_VOIE>ACH</CD_E_COD_VOIE>
<LB_E_COD_VOIE>Ancien chemin</LB_E_COD_VOIE>
</COD_VOIE_ROW>
<COD_VOIE_ROW>
<CD_E_COD_VOIE>AGL</CD_E_COD_VOIE>
<LB_E_COD_VOIE>Agglomération</LB_E_COD_VOIE>
</COD_VOIE_ROW>
<COD_VOIE_ROW>
<CD_E_COD_VOIE>AIRE</CD_E_COD_VOIE>
<LB_E_COD_VOIE>Aire</LB_E_COD_VOIE>
</COD_VOIE_ROW>
<COD_VOIE_ROW>
<CD_E_COD_VOIE>ANSE</CD_E_COD_VOIE>
<LB_E_COD_VOIE>Anse</LB_E_COD_VOIE>
</COD_VOIE_ROW>
<COD_VOIE_ROW>
<CD_E_COD_VOIE>ART</CD_E_COD_VOIE>
<LB_E_COD_VOIE>Ancienne route</LB_E_COD_VOIE>
</COD_VOIE_ROW>
<COD_VOIE_ROW>
<CD_E_COD_VOIE>BAST</CD_E_COD_VOIE>
<LB_E_COD_VOIE>Bastion</LB_E_COD_VOIE>
</COD_VOIE_ROW>
<COD_VOIE_ROW>
<CD_E_COD_VOIE>BCH</CD_E_COD_VOIE>
<LB_E_COD_VOIE>Bas chemin</LB_E_COD_VOIE>
</COD_VOIE_ROW>
<COD_VOIE_ROW>
<CD_E_COD_VOIE>BCLE</CD_E_COD_VOIE>
<LB_E_COD_VOIE>Boucle</LB_E_COD_VOIE>
</COD_VOIE_ROW>
<COD_VOIE_ROW>
<CD_E_COD_VOIE>BER</CD_E_COD_VOIE>
<LB_E_COD_VOIE>Berge</LB_E_COD_VOIE>
</COD_VOIE_ROW>
<COD_VOIE_ROW>
<CD_E_COD_VOIE>BOIS</CD_E_COD_VOIE>
<LB_E_COD_VOIE>Bois</LB_E_COD_VOIE>
</COD_VOIE_ROW>
<COD_VOIE_ROW>
<CD_E_COD_VOIE>BRE</CD_E_COD_VOIE>
<LB_E_COD_VOIE>Barrière</LB_E_COD_VOIE>
</COD_VOIE_ROW>
<COD_VOIE_ROW>
<CD_E_COD_VOIE>BRG</CD_E_COD_VOIE>
<LB_E_COD_VOIE>Bourg</LB_E_COD_VOIE>
</COD_VOIE_ROW>
<COD_VOIE_ROW>
<CD_E_COD_VOIE>BSTD</CD_E_COD_VOIE>
<LB_E_COD_VOIE>Bastide</LB_E_COD_VOIE>
</COD_VOIE_ROW>
<COD_VOIE_ROW>
<CD_E_COD_VOIE>BUT</CD_E_COD_VOIE>
<LB_E_COD_VOIE>Butte</LB_E_COD_VOIE>
</COD_VOIE_ROW>
<COD_VOIE_ROW>
<CD_E_COD_VOIE>CALE</CD_E_COD_VOIE>
<LB_E_COD_VOIE>Cale</LB_E_COD_VOIE>
</COD_VOIE_ROW>
<COD_VOIE_ROW>
<CD_E_COD_VOIE>CARE</CD_E_COD_VOIE>
<LB_E_COD_VOIE>Carrière</LB_E_COD_VOIE>
</COD_VOIE_ROW>
<COD_VOIE_ROW>
<CD_E_COD_VOIE>CARR</CD_E_COD_VOIE>
<LB_E_COD_VOIE>Carré</LB_E_COD_VOIE>
</COD_VOIE_ROW>
<COD_VOIE_ROW>
<CD_E_COD_VOIE>CAU</CD_E_COD_VOIE>
<LB_E_COD_VOIE>Carreau</LB_E_COD_VOIE>
</COD_VOIE_ROW>
<COD_VOIE_ROW>
<CD_E_COD_VOIE>CGNE</CD_E_COD_VOIE>
<LB_E_COD_VOIE>Campagne</LB_E_COD_VOIE>
</COD_VOIE_ROW>
<COD_VOIE_ROW>
<CD_E_COD_VOIE>CHEZ</CD_E_COD_VOIE>
<LB_E_COD_VOIE>Chez</LB_E_COD_VOIE>
</COD_VOIE_ROW>
<COD_VOIE_ROW>
<CD_E_COD_VOIE>CHI</CD_E_COD_VOIE>
<LB_E_COD_VOIE>Charmille</LB_E_COD_VOIE>
</COD_VOIE_ROW>
<COD_VOIE_ROW>
<CD_E_COD_VOIE>CHL</CD_E_COD_VOIE>
<LB_E_COD_VOIE>Chalet</LB_E_COD_VOIE>
</COD_VOIE_ROW>
<COD_VOIE_ROW>
<CD_E_COD_VOIE>CHP</CD_E_COD_VOIE>
<LB_E_COD_VOIE>Chapelle</LB_E_COD_VOIE>
</COD_VOIE_ROW>
<COD_VOIE_ROW>
<CD_E_COD_VOIE>CHT</CD_E_COD_VOIE>
<LB_E_COD_VOIE>Château</LB_E_COD_VOIE>
</COD_VOIE_ROW>
<COD_VOIE_ROW>
<CD_E_COD_VOIE>CHV</CD_E_COD_VOIE>
<LB_E_COD_VOIE>Chemin vicinal</LB_E_COD_VOIE>
</COD_VOIE_ROW>
<COD_VOIE_ROW>
<CD_E_COD_VOIE>CLOI</CD_E_COD_VOIE>
<LB_E_COD_VOIE>Cloître</LB_E_COD_VOIE>
</COD_VOIE_ROW>
<COD_VOIE_ROW>
<CD_E_COD_VOIE>COLI</CD_E_COD_VOIE>
<LB_E_COD_VOIE>Colline</LB_E_COD_VOIE>
</COD_VOIE_ROW>
<COD_VOIE_ROW>
<CD_E_COD_VOIE>COR</CD_E_COD_VOIE>
<LB_E_COD_VOIE>Corniche</LB_E_COD_VOIE>
</COD_VOIE_ROW>
<COD_VOIE_ROW>
<CD_E_COD_VOIE>COTT</CD_E_COD_VOIE>
<LB_E_COD_VOIE>Cottage</LB_E_COD_VOIE>
</COD_VOIE_ROW>
<COD_VOIE_ROW>
<CD_E_COD_VOIE>CPG</CD_E_COD_VOIE>
<LB_E_COD_VOIE>Camping</LB_E_COD_VOIE>
</COD_VOIE_ROW>
<COD_VOIE_ROW>
<CD_E_COD_VOIE>CST</CD_E_COD_VOIE>
<LB_E_COD_VOIE>Castel</LB_E_COD_VOIE>
</COD_VOIE_ROW>
<COD_VOIE_ROW>
<CD_E_COD_VOIE>DARS</CD_E_COD_VOIE>
<LB_E_COD_VOIE>Darse</LB_E_COD_VOIE>
</COD_VOIE_ROW>
<COD_VOIE_ROW>
<CD_E_COD_VOIE>DEG</CD_E_COD_VOIE>
<LB_E_COD_VOIE>Degré</LB_E_COD_VOIE>
</COD_VOIE_ROW>
<COD_VOIE_ROW>
<CD_E_COD_VOIE>DSC</CD_E_COD_VOIE>
<LB_E_COD_VOIE>Descente</LB_E_COD_VOIE>
</COD_VOIE_ROW>
<COD_VOIE_ROW>
<CD_E_COD_VOIE>EGL</CD_E_COD_VOIE>
<LB_E_COD_VOIE>Eglise</LB_E_COD_VOIE>
</COD_VOIE_ROW>
<COD_VOIE_ROW>
<CD_E_COD_VOIE>EN</CD_E_COD_VOIE>
<LB_E_COD_VOIE>Enceinte</LB_E_COD_VOIE>
</COD_VOIE_ROW>
<COD_VOIE_ROW>
<CD_E_COD_VOIE>ENC</CD_E_COD_VOIE>
<LB_E_COD_VOIE>Enclos</LB_E_COD_VOIE>
</COD_VOIE_ROW>
<COD_VOIE_ROW>
<CD_E_COD_VOIE>ENV</CD_E_COD_VOIE>
<LB_E_COD_VOIE>Enclave</LB_E_COD_VOIE>
</COD_VOIE_ROW>
<COD_VOIE_ROW>
<CD_E_COD_VOIE>ETNG</CD_E_COD_VOIE>
<LB_E_COD_VOIE>Etang</LB_E_COD_VOIE>
</COD_VOIE_ROW>
<COD_VOIE_ROW>
<CD_E_COD_VOIE>FON</CD_E_COD_VOIE>
<LB_E_COD_VOIE>Fontaine</LB_E_COD_VOIE>
</COD_VOIE_ROW>
<COD_VOIE_ROW>
<CD_E_COD_VOIE>FORM</CD_E_COD_VOIE>
<LB_E_COD_VOIE>Forum</LB_E_COD_VOIE>
</COD_VOIE_ROW>
<COD_VOIE_ROW>
<CD_E_COD_VOIE>FORT</CD_E_COD_VOIE>
<LB_E_COD_VOIE>Fort</LB_E_COD_VOIE>
</COD_VOIE_ROW>
<COD_VOIE_ROW>
<CD_E_COD_VOIE>FOS</CD_E_COD_VOIE>
<LB_E_COD_VOIE>Fosse</LB_E_COD_VOIE>
</COD_VOIE_ROW>
<COD_VOIE_ROW>
<CD_E_COD_VOIE>FYR</CD_E_COD_VOIE>
<LB_E_COD_VOIE>Foyer</LB_E_COD_VOIE>
</COD_VOIE_ROW>
<COD_VOIE_ROW>
<CD_E_COD_VOIE>FRM</CD_E_COD_VOIE>
<LB_E_COD_VOIE>Ferme</LB_E_COD_VOIE>
</COD_VOIE_ROW>
<COD_VOIE_ROW>
<CD_E_COD_VOIE>GAL</CD_E_COD_VOIE>
<LB_E_COD_VOIE>Galerie</LB_E_COD_VOIE>
</COD_VOIE_ROW>
<COD_VOIE_ROW>
<CD_E_COD_VOIE>GARN</CD_E_COD_VOIE>
<LB_E_COD_VOIE>Garenne</LB_E_COD_VOIE>
</COD_VOIE_ROW>
<COD_VOIE_ROW>
<CD_E_COD_VOIE>GPE</CD_E_COD_VOIE>
<LB_E_COD_VOIE>Groupe</LB_E_COD_VOIE>
</COD_VOIE_ROW>
<COD_VOIE_ROW>
<CD_E_COD_VOIE>GPT</CD_E_COD_VOIE>
<LB_E_COD_VOIE>Groupement</LB_E_COD_VOIE>
</COD_VOIE_ROW>
<COD_VOIE_ROW>
<CD_E_COD_VOIE>GRI</CD_E_COD_VOIE>
<LB_E_COD_VOIE>Grimpette</LB_E_COD_VOIE>
</COD_VOIE_ROW>
<COD_VOIE_ROW>
<CD_E_COD_VOIE>HCH</CD_E_COD_VOIE>
<LB_E_COD_VOIE>Hautchemin</LB_E_COD_VOIE>
</COD_VOIE_ROW>
<COD_VOIE_ROW>
<CD_E_COD_VOIE>HIP</CD_E_COD_VOIE>
<LB_E_COD_VOIE>Hippodrome</LB_E_COD_VOIE>
</COD_VOIE_ROW>
<COD_VOIE_ROW>
<CD_E_COD_VOIE>HLE</CD_E_COD_VOIE>
<LB_E_COD_VOIE>Halle</LB_E_COD_VOIE>
</COD_VOIE_ROW>
<COD_VOIE_ROW>
<CD_E_COD_VOIE>HLM</CD_E_COD_VOIE>
<LB_E_COD_VOIE>HLM</LB_E_COD_VOIE>
</COD_VOIE_ROW>
<COD_VOIE_ROW>
<CD_E_COD_VOIE>JAR</CD_E_COD_VOIE>
<LB_E_COD_VOIE>Jardin</LB_E_COD_VOIE>
</COD_VOIE_ROW>
<COD_VOIE_ROW>
<CD_E_COD_VOIE>JTE</CD_E_COD_VOIE>
<LB_E_COD_VOIE>Jetée</LB_E_COD_VOIE>
</COD_VOIE_ROW>
<COD_VOIE_ROW>
<CD_E_COD_VOIE>LEVE</CD_E_COD_VOIE>
<LB_E_COD_VOIE>Levée</LB_E_COD_VOIE>
</COD_VOIE_ROW>
<COD_VOIE_ROW>
<CD_E_COD_VOIE>MAN</CD_E_COD_VOIE>
<LB_E_COD_VOIE>Manoir</LB_E_COD_VOIE>
</COD_VOIE_ROW>
<COD_VOIE_ROW>
<CD_E_COD_VOIE>MAR</CD_E_COD_VOIE>
<LB_E_COD_VOIE>Marché</LB_E_COD_VOIE>
</COD_VOIE_ROW>
<COD_VOIE_ROW>
<CD_E_COD_VOIE>MAS</CD_E_COD_VOIE>
<LB_E_COD_VOIE>Mas</LB_E_COD_VOIE>
</COD_VOIE_ROW>
<COD_VOIE_ROW>
<CD_E_COD_VOIE>MET</CD_E_COD_VOIE>
<LB_E_COD_VOIE>Métro</LB_E_COD_VOIE>
</COD_VOIE_ROW>
<COD_VOIE_ROW>
<CD_E_COD_VOIE>MF</CD_E_COD_VOIE>
<LB_E_COD_VOIE>Maison forestière</LB_E_COD_VOIE>
</COD_VOIE_ROW>
<COD_VOIE_ROW>
<CD_E_COD_VOIE>NTE</CD_E_COD_VOIE>
<LB_E_COD_VOIE>Nouvelle route</LB_E_COD_VOIE>
</COD_VOIE_ROW>
<COD_VOIE_ROW>
<CD_E_COD_VOIE>PAE</CD_E_COD_VOIE>
<LB_E_COD_VOIE>Petite avenue</LB_E_COD_VOIE>
</COD_VOIE_ROW>
<COD_VOIE_ROW>
<CD_E_COD_VOIE>PAL</CD_E_COD_VOIE>
<LB_E_COD_VOIE>Palais</LB_E_COD_VOIE>
</COD_VOIE_ROW>
<COD_VOIE_ROW>
<CD_E_COD_VOIE>PASS</CD_E_COD_VOIE>
<LB_E_COD_VOIE>Passe</LB_E_COD_VOIE>
</COD_VOIE_ROW>
<COD_VOIE_ROW>
<CD_E_COD_VOIE>PAT</CD_E_COD_VOIE>
<LB_E_COD_VOIE>Patio</LB_E_COD_VOIE>
</COD_VOIE_ROW>
<COD_VOIE_ROW>
<CD_E_COD_VOIE>PAV</CD_E_COD_VOIE>
<LB_E_COD_VOIE>Pavillon</LB_E_COD_VOIE>
</COD_VOIE_ROW>
<COD_VOIE_ROW>
<CD_E_COD_VOIE>PCH</CD_E_COD_VOIE>
<LB_E_COD_VOIE>Porche</LB_E_COD_VOIE>
</COD_VOIE_ROW>
<COD_VOIE_ROW>
<CD_E_COD_VOIE>PIM</CD_E_COD_VOIE>
<LB_E_COD_VOIE>Petite impasse</LB_E_COD_VOIE>
</COD_VOIE_ROW>
<COD_VOIE_ROW>
<CD_E_COD_VOIE>PKG</CD_E_COD_VOIE>
<LB_E_COD_VOIE>Parking</LB_E_COD_VOIE>
</COD_VOIE_ROW>
<COD_VOIE_ROW>
<CD_E_COD_VOIE>PLAN</CD_E_COD_VOIE>
<LB_E_COD_VOIE>Plan</LB_E_COD_VOIE>
</COD_VOIE_ROW>
<COD_VOIE_ROW>
<CD_E_COD_VOIE>PLCI</CD_E_COD_VOIE>
<LB_E_COD_VOIE>Placis</LB_E_COD_VOIE>
</COD_VOIE_ROW>
<COD_VOIE_ROW>
<CD_E_COD_VOIE>PLN</CD_E_COD_VOIE>
<LB_E_COD_VOIE>Plaine</LB_E_COD_VOIE>
</COD_VOIE_ROW>
<COD_VOIE_ROW>
<CD_E_COD_VOIE>PLT</CD_E_COD_VOIE>
<LB_E_COD_VOIE>Plateau(x)</LB_E_COD_VOIE>
</COD_VOIE_ROW>
<COD_VOIE_ROW>
<CD_E_COD_VOIE>PN</CD_E_COD_VOIE>
<LB_E_COD_VOIE>Passage à niveau</LB_E_COD_VOIE>
</COD_VOIE_ROW>
<COD_VOIE_ROW>
<CD_E_COD_VOIE>PNT</CD_E_COD_VOIE>
<LB_E_COD_VOIE>Pointe</LB_E_COD_VOIE>
</COD_VOIE_ROW>
<COD_VOIE_ROW>
<CD_E_COD_VOIE>PORQ</CD_E_COD_VOIE>
<LB_E_COD_VOIE>Portique</LB_E_COD_VOIE>
</COD_VOIE_ROW>
<COD_VOIE_ROW>
<CD_E_COD_VOIE>PORT</CD_E_COD_VOIE>
<LB_E_COD_VOIE>Port</LB_E_COD_VOIE>
</COD_VOIE_ROW>
<COD_VOIE_ROW>
<CD_E_COD_VOIE>POT</CD_E_COD_VOIE>
<LB_E_COD_VOIE>Poterne</LB_E_COD_VOIE>
</COD_VOIE_ROW>
<COD_VOIE_ROW>
<CD_E_COD_VOIE>PRE</CD_E_COD_VOIE>
<LB_E_COD_VOIE>Pré</LB_E_COD_VOIE>
</COD_VOIE_ROW>
<COD_VOIE_ROW>
<CD_E_COD_VOIE>PRQ</CD_E_COD_VOIE>
<LB_E_COD_VOIE>Presqu'île</LB_E_COD_VOIE>
</COD_VOIE_ROW>
<COD_VOIE_ROW>
<CD_E_COD_VOIE>PRT</CD_E_COD_VOIE>
<LB_E_COD_VOIE>Petite route</LB_E_COD_VOIE>
</COD_VOIE_ROW>
<COD_VOIE_ROW>
<CD_E_COD_VOIE>PSTY</CD_E_COD_VOIE>
<LB_E_COD_VOIE>Peristyle</LB_E_COD_VOIE>
</COD_VOIE_ROW>
<COD_VOIE_ROW>
<CD_E_COD_VOIE>PTA</CD_E_COD_VOIE>
<LB_E_COD_VOIE>Petite allée</LB_E_COD_VOIE>
</COD_VOIE_ROW>
<COD_VOIE_ROW>
<CD_E_COD_VOIE>RAC</CD_E_COD_VOIE>
<LB_E_COD_VOIE>Raccourci</LB_E_COD_VOIE>
</COD_VOIE_ROW>
<COD_VOIE_ROW>
<CD_E_COD_VOIE>RAID</CD_E_COD_VOIE>
<LB_E_COD_VOIE>Raidillon</LB_E_COD_VOIE>
</COD_VOIE_ROW>
<COD_VOIE_ROW>
<CD_E_COD_VOIE>REM</CD_E_COD_VOIE>
<LB_E_COD_VOIE>Rempart</LB_E_COD_VOIE>
</COD_VOIE_ROW>
<COD_VOIE_ROW>
<CD_E_COD_VOIE>ROQT</CD_E_COD_VOIE>
<LB_E_COD_VOIE>Roquet</LB_E_COD_VOIE>
</COD_VOIE_ROW>
<COD_VOIE_ROW>
<CD_E_COD_VOIE>RTD</CD_E_COD_VOIE>
<LB_E_COD_VOIE>Rotonde</LB_E_COD_VOIE>
</COD_VOIE_ROW>
<COD_VOIE_ROW>
<CD_E_COD_VOIE>TRN</CD_E_COD_VOIE>
<LB_E_COD_VOIE>Terrain</LB_E_COD_VOIE>
</COD_VOIE_ROW>
<COD_VOIE_ROW>
<CD_E_COD_VOIE>TRT</CD_E_COD_VOIE>
<LB_E_COD_VOIE>Tertre</LB_E_COD_VOIE>
</COD_VOIE_ROW>
<COD_VOIE_ROW>
<CD_E_COD_VOIE>TSSE</CD_E_COD_VOIE>
<LB_E_COD_VOIE>Terrasse</LB_E_COD_VOIE>
</COD_VOIE_ROW>
<COD_VOIE_ROW>
<CD_E_COD_VOIE>VCHE</CD_E_COD_VOIE>
<LB_E_COD_VOIE>Vieux chemin</LB_E_COD_VOIE>
</COD_VOIE_ROW>
<COD_VOIE_ROW>
<CD_E_COD_VOIE>VEN</CD_E_COD_VOIE>
<LB_E_COD_VOIE>Venelle</LB_E_COD_VOIE>
</COD_VOIE_ROW>
<COD_VOIE_ROW>
<CD_E_COD_VOIE>VGE</CD_E_COD_VOIE>
<LB_E_COD_VOIE>Village</LB_E_COD_VOIE>
</COD_VOIE_ROW>
<COD_VOIE_ROW>
<CD_E_COD_VOIE>VIA</CD_E_COD_VOIE>
<LB_E_COD_VOIE>Via</LB_E_COD_VOIE>
</COD_VOIE_ROW>
<COD_VOIE_ROW>
<CD_E_COD_VOIE>VLA</CD_E_COD_VOIE>
<LB_E_COD_VOIE>Villa</LB_E_COD_VOIE>
</COD_VOIE_ROW>
<COD_VOIE_ROW>
<CD_E_COD_VOIE>VTE</CD_E_COD_VOIE>
<LB_E_COD_VOIE>Vielle route</LB_E_COD_VOIE>
</COD_VOIE_ROW>
<COD_VOIE_ROW>
<CD_E_COD_VOIE>ZA</CD_E_COD_VOIE>
<LB_E_COD_VOIE>Zone artisanale</LB_E_COD_VOIE>
</COD_VOIE_ROW>
<COD_VOIE_ROW>
<CD_E_COD_VOIE>ZAD</CD_E_COD_VOIE>
<LB_E_COD_VOIE>Zone d'aménagement différé</LB_E_COD_VOIE>
</COD_VOIE_ROW>
<COD_VOIE_ROW>
<CD_E_COD_VOIE>ZUP</CD_E_COD_VOIE>
<LB_E_COD_VOIE>Zone à urbaniser en priorité</LB_E_COD_VOIE>
</COD_VOIE_ROW>
</COD_VOIE>
</ROW>
</ROWSET></return>

View File

@ -0,0 +1,165 @@
<?xml version="1.0"?>
<return><ROWSET>
<ROW num="1">
<IDENTIFICATION>
<IDENTIFICATION_ROW num="1">
<NOM>DOE</NOM>
<NOM_NAISSANCE>TEST</NOM_NAISSANCE>
<PRENOM>John</PRENOM>
<DATE_NAISSANCE>01/01/1923</DATE_NAISSANCE>
<PAYS_NAIS>FRANCE</PAYS_NAIS>
<DPT_NAIS>ALPES-MARITMES</DPT_NAIS>
<CMU_NAIS>NICE</CMU_NAIS>
<CD_CMU_NAIS>12345</CD_CMU_NAIS>
<CODPOS_NAIS>12345</CODPOS_NAIS>
<IDDOS>12345</IDDOS>
<NATIONALITE>Fran&#xE7;aise (Valeurs Possibles&#xA0;: Fran&#xE7;aise, Europ&#xE9;enne,Autre)</NATIONALITE>
<SIT_FAM>C&#xE9;libat</SIT_FAM>
<SEXE>F</SEXE>
<NU_VOIE_ADR>65</NU_VOIE_ADR>
<LB_COD_BTQ_ADR>Bis</LB_COD_BTQ_ADR>
<CD_COD_VOIE_ADR>BLD</CD_COD_VOIE_ADR>
<LB_COD_VOIE_ADR>Boulevard</LB_COD_VOIE_ADR>
<LB_VOIE_ADR>du Revestel</LB_VOIE_ADR>
<LB_PAY_ADR>FRANCE</LB_PAY_ADR>
<CD_PAY_ADR>100 </CD_PAY_ADR>
<COMPLEMENT_ADRESSE>RESIDENCE BLABLA</COMPLEMENT_ADRESSE>
<CODE_POSTAL>06000</CODE_POSTAL>
<VILLE>NICE</VILLE>
<TEL_FIXE>06.44.44.44.44</TEL_FIXE>
<TEL_MOBILE>06.55.55.55.55</TEL_MOBILE>
<MAIL>test@sirus.fr</MAIL>
<CD_SIT_FAM>SITFAM_C</CD_SIT_FAM>
<NUM_AFFILIATION>123456789</NUM_AFFILIATION> (Num&#xE9;ro d&#x2019;affiliation &#xE0; la caisse de retraite)
<CAISSE_RETRAITE>CRAM CAGNES SUR MER</CAISSE_RETRAITE>
<REPRESENTANT_LEGAL/> Non param&#xE9;tr&#xE9; dans le 06
<AUTORITEPARENTALEPARENT/> Non param&#xE9;tr&#xE9; dans le 06
<AUTORITEPARENTALEAUTRE/> Non param&#xE9;tr&#xE9; dans le 06
<ORGA_PAYEUR/> Non param&#xE9;tr&#xE9; dans le 06
<REF_UTI_DOS>123456</REF_UTI_DOS>
<REF_PH_DOS>123456</REF_PH_DOS>
<NSS>253077507312383</NSS>
<CONJOINT>
<CONJOINT_ROW num="1">
<NOM>NOM conjoint</NOM>
<PRENOM>Pr&#xE9;nom</PRENOM>
<DATE_NAISSANCE>01/01/1960</DATE_NAISSANCE>
<NOM_NAISSANCE>NOM </NOM_NAISSANCE>
<NATIONALITE>FRANCE</NATIONALITE>
<NUM_AFFILIATION>123456789</NUM_AFFILIATION>
<CAISSE_RETRAITE>CRAM CAGNES SUR MER</CAISSE_RETRAITE>
<NSS>253077507300584</NSS>
<NU_VOIE_ADR>65</NU_VOIE_ADR>
<LB_COD_BTQ_ADR>Bis</LB_COD_BTQ_ADR>
<CD_COD_VOIE_ADR>BLD</CD_COD_VOIE_ADR>
<LB_COD_VOIE_ADR>Boulevard</LB_COD_VOIE_ADR>
<LB_VOIE_ADR>du Revestel</LB_VOIE_ADR>
<COMPLEMENT_ADRESSE>RESIDENCE ALSACE </COMPLEMENT_ADRESSE>
<CODE_POSTAL>06000</CODE_POSTAL>
<VILLE>NICE</VILLE>
<TEL_FIXE>06.61.75.69.51</TEL_FIXE>
<TEL_MOBILE>06.61.75.69.51</TEL_MOBILE>
<MAIL>test@sirus.fr</MAIL>
</CONJOINT_ROW>
</CONJOINT>
<CONTACTS>
<CONTACTS_ROW num="1">
<NOM>NOM </NOM>
<PRENOM>Pr&#xE9;nom</PRENOM>
<RELATION>TYP_CNT_AID</RELATION>
<NU_VOIE_ADR>65</NU_VOIE_ADR>
<LB_COD_BTQ_ADR>Bis</LB_COD_BTQ_ADR>
<CD_COD_VOIE_ADR>BLD</CD_COD_VOIE_ADR>
<LB_COD_VOIE_ADR>Boulevard</LB_COD_VOIE_ADR>
<LB_VOIE_ADR>GAMBETTA</LB_VOIE_ADR>
<COMPLEMENT_ADRESSE>RESIDENCE BLABLA</COMPLEMENT_ADRESSE>
<CODE_POSTAL>06000</CODE_POSTAL>
<VILLE>NICE</VILLE>
<TEL_FIXE>06.22.22.22.22</TEL_FIXE>
<TEL_MOBILE>06.11.11.11.11</TEL_MOBILE>
<MAIL>test@sirus.fr</MAIL>
</CONTACTS_ROW>
</CONTACTS>
</IDENTIFICATION_ROW>
</IDENTIFICATION>
<DEMANDES>
<DEMANDES_ROW num="1">
<GROUPE>BANDEAU</GROUPE>
<CODE_CATEGORIE>DEC_APA</CODE_CATEGORIE>
<CATEGORIE>D&#xE9;cision</CATEGORIE>
<CODE_ETAPE>DEC_APA01</CODE_ETAPE>
<ETAPE>D&#xE9;cision</ETAPE>
<ID_MES>1234</ID_MES>
<REF_EXT_MES>1234</REF_EXT_MES>
<CD_CODMES_MES>ADAPD </CD_CODMES_MES>
<TYPE_MESURE>A.P.A. &#xE0; Domicile - R&#xE9;vision</TYPE_MESURE>
<DT_FIN>31/12/2019</DT_FIN>
<DT_DMD_ORDER>2016-12-08 00:00:00.0</DT_DMD_ORDER>
<DT_DMD>08/12/2016</DT_DMD>
<DT_MINI_DMD>01/01/2015</DT_MINI_DMD>
<LISTE_ETAPES>
<LISTE_ETAPES_ROW num="1">
<GROUPE>BANDEAU</GROUPE>
<A_SURLIGNER>N</A_SURLIGNER>
<NUM_CAT>1</NUM_CAT>
<CODE_CATEGORIE>INDMD</CODE_CATEGORIE>
<CATEGORIE>Instruction administrative de la demande</CATEGORIE>
<ID_EGST_MES>1234</ID_EGST_MES>
<REF_EXT_MES>1234</REF_EXT_MES>
<LIBELLE_MES>A.P.A. &#xE0; Domicile - R&#xE9;vision</LIBELLE_MES>
<ETP/>
</LISTE_ETAPES_ROW>
<LISTE_ETAPES_ROW num="2">
<GROUPE>BANDEAU</GROUPE>
<A_SURLIGNER>N</A_SURLIGNER>
<NUM_CAT>2</NUM_CAT>
<CODE_CATEGORIE>EVMSD</CODE_CATEGORIE>
<CATEGORIE>&#xC9;valuation m&#xE9;dico-sociale de la demande</CATEGORIE>
<ID_EGST_MES>1234</ID_EGST_MES>
<REF_EXT_MES>1234</REF_EXT_MES>
<LIBELLE_MES>A.P.A. &#xE0; Domicile - R&#xE9;vision</LIBELLE_MES>
<ETP/>
</LISTE_ETAPES_ROW>
<LISTE_ETAPES_ROW num="3">
<GROUPE>BANDEAU</GROUPE>
<A_SURLIGNER>O</A_SURLIGNER>
<NUM_CAT>3</NUM_CAT>
<CODE_CATEGORIE>DEC_APA</CODE_CATEGORIE>
<CATEGORIE>D&#xE9;cision</CATEGORIE>
<ID_EGST_MES>1234</ID_EGST_MES>
<CD_ETP>DEC_APA01</CD_ETP>
<LB_ETP>D&#xE9;cision</LB_ETP>
<CATEGORIE_ETP>D&#xE9;cision</CATEGORIE_ETP>
<REF_EXT_MES>1234</REF_EXT_MES>
<LIBELLE_MES>A.P.A. &#xE0; Domicile - R&#xE9;vision</LIBELLE_MES>
<ETP>
<ETP_ROW num="1">
<ETAPE>D&#xE9;cision</ETAPE>
<NUM_CHAMP>1</NUM_CHAMP>
<CODE_CHAMP>LABEL1</CODE_CHAMP>
<TYP_CHAMP>L</TYP_CHAMP>
<LIBELLE_CHAMP>Votre demande a fait l'objet d'une d&#xE9;cision qui vous sera adress&#xE9;e, prochainement, par voie postale.</LIBELLE_CHAMP>
<VALEUR_LIST_CHAMP/>
</ETP_ROW>
</ETP>
</LISTE_ETAPES_ROW>
</LISTE_ETAPES>
</DEMANDES_ROW>
</DEMANDES>
<DROITS>
<DROITS_ROW num="1">
<ID_PRE>1234</ID_PRE>
<DATE_DEBUT>01/01/2017</DATE_DEBUT>
<DATE_FIN>31/12/2019</DATE_FIN>
<LIBELLE>Un service prestataire </LIBELLE>
<PRESTATAIRE>CLUB AZUR SERVICES </PRESTATAIRE>
<TYPPREST>Aide &#xE0; domicile PA-PH</TYPPREST>
</DROITS_ROW>
</DROITS>
<DEMARCHES>
<DEMARCHES_ROW num="1">
<COD_FORM>F_RNV_APA</COD_FORM>
</DEMARCHES_ROW>
</DEMARCHES>
</ROW>
</ROWSET></return>

193
tests/test_atos_genesys.py Normal file
View File

@ -0,0 +1,193 @@
# -*- coding: utf-8 -*-
import os
import pytest
import utils
from django.utils.http import urlencode
from passerelle.apps.atos_genesys.models import Resource, Link
FAKE_URL = 'https://sirus.fr/genesys/'
@pytest.fixture
def genesys(db):
return utils.make_resource(
Resource,
title='Test 1',
slug='test1',
description='Connecteur de test',
webservice_base_url=FAKE_URL)
@pytest.fixture
def mock_codifications_ok():
response = open(os.path.join(
os.path.dirname(__file__),
'data',
'genesys_select_codifications.xml')).read()
with utils.mock_url(FAKE_URL + 'selectCodifications', response) as mock:
yield mock
def test_ws_categories(app, genesys, mock_codifications_ok):
url = utils.generic_endpoint_url('atos-genesys', 'codifications', slug=genesys.slug)
response = app.get(url)
assert response.json['err'] == 0
assert response.json['data']
assert any(x for x in response.json['data'] if x['id'] == 'MOT_APA')
def test_ws_codifications(app, genesys, mock_codifications_ok):
url = utils.generic_endpoint_url('atos-genesys', 'codifications', slug=genesys.slug)
url += '/MOT_APA/'
response = app.get(url)
assert response.json['err'] == 0
assert response.json['data']
assert any(x for x in response.json['data'] if x['id'] == 'AGG_APA')
def test_ws_codifications_failure(app, genesys, mock_500):
from django.core.cache import cache
cache.clear()
url = utils.generic_endpoint_url('atos-genesys', 'codifications', slug=genesys.slug)
url += '/MOT_APA/'
response = app.get(url)
assert response.json['err'] == 1
RESPONSE_UNKNOWN_LOGIN = '''<return><ROWSET><ROW>
<CD_RET>6</CD_RET>
<LB_RET>Identifiant inconnu de Genesis</LB_RET>
</ROW> </ROWSET></return>'''
def test_ws_link_unknown_appairage(app, genesys):
url = utils.generic_endpoint_url('atos-genesys', 'link', slug=genesys.slug)
with utils.mock_url(FAKE_URL, RESPONSE_UNKNOWN_LOGIN):
response = app.post(url + '?' + urlencode({
'NameID': 'zob',
'login': '1234',
'password': 'xyz',
'email': 'john.doe@example.com'
}))
assert response.json['err'] == 1
assert response.json['data']['code'] == '6'
assert response.json['data']['label']
RESPONSE_CREATED = '''<return><ROWSET><ROW>
<ID_PER>789</ID_PER>
<CD_RET>5</CD_RET>
<LB_RET>Identifiant et mot de passe Genesis corrects. Le compte de l'usager vient d'être créé dans l'Extranet.</LB_RET>
</ROW> </ROWSET></return>'''
def test_ws_link_created(app, genesys):
url = utils.generic_endpoint_url('atos-genesys', 'link', slug=genesys.slug)
assert Link.objects.count() == 0
with utils.mock_url(FAKE_URL, RESPONSE_CREATED):
response = app.post(url + '?' + urlencode({
'NameID': 'zob',
'login': '1234',
'password': 'xyz',
'email': 'john.doe@example.com'
}))
assert response.json['err'] == 0
assert response.json['link_id'] == 1
assert response.json['new']
assert Link.objects.filter(
name_id='zob', id_per='789', resource=genesys).count() == 1
url = utils.generic_endpoint_url('atos-genesys', 'unlink', slug=genesys.slug)
response = app.post(url + '?' + urlencode({
'NameID': 'zob',
'link_id': '1',
}))
assert response.json['err'] == 0
assert response.json['deleted'] == 1
assert Link.objects.count() == 0
def test_ws_dossiers(app, genesys):
Link.objects.create(
resource=genesys,
name_id='zob',
id_per='1234')
xml_response = open(os.path.join(
os.path.dirname(__file__),
'data',
'genesys_select_usager.xml')).read()
url = utils.generic_endpoint_url('atos-genesys', 'dossiers', slug=genesys.slug)
with utils.mock_url(FAKE_URL, xml_response):
response = app.get(url + '?' + urlencode({
'NameID': 'zob',
}))
assert response.json['err'] == 0
assert response.json['data']
assert len(response.json['data']) == 1
assert response.json['data'][0]['id_per'] == '1234'
assert response.json['data'][0]['dossier']
Link.objects.create(
resource=genesys,
name_id='zob',
id_per='4567')
with utils.mock_url(FAKE_URL, RESPONSE_CREATED):
response = app.get(url + '?' + urlencode({
'NameID': 'zob',
}))
assert response.json['err'] == 0
assert response.json['data']
assert len(response.json['data']) == 2
assert response.json['data'][0]['id_per'] == '1234'
assert response.json['data'][0]['dossier']
assert response.json['data'][1]['id_per'] == '4567'
assert response.json['data'][1]['dossier']
@pytest.mark.freeze_time
def test_row_locked_cache(genesys, freezer):
import time
from passerelle.apps.atos_genesys.utils import RowLockedCache
freezer.move_to('2018-01-01 00:00:00')
link = Link.objects.create(
resource=genesys,
name_id='zob',
id_per='4567')
class F(object):
calls = 0
value = 1
def __call__(self):
time.sleep(0.05)
self.calls += 1
return self.value
f = F()
# Check that cache works, f() is called only one time during the cache duration (60 seconds)
rlc = RowLockedCache(duration=60, row=link, function=f, key_prefix='cache')
value = rlc()
assert value == 1
assert f.calls == 1
freezer.move_to('2018-01-01 00:00:59')
for i in range(5):
assert rlc() == 1
assert f.calls == 1
# Check that cache update only launch one thread and f() is called only once again
freezer.move_to('2018-01-01 00:02:00')
F.value = 2
counter = 0
while rlc() == 1 or counter < 5:
counter += 1
assert rlc() == 2
assert f.calls == 2

View File

@ -24,6 +24,7 @@ deps =
django-webtest<1.9.3
lxml
mohawk
pytest-freezegun
commands =
django18: py.test {posargs: {env:FAST:} --junitxml=test_{envname}_results.xml --cov-report xml --cov-report html --cov=passerelle/ --cov-config .coveragerc tests/}
django18: ./pylint.sh passerelle/