add actesweb connector (#22395)
This commit is contained in:
parent
7d97dd326d
commit
7d0dbcb654
|
@ -0,0 +1,28 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('base', '0006_resourcestatus'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='ActesWeb',
|
||||
fields=[
|
||||
('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
|
||||
('title', models.CharField(max_length=50, verbose_name='Title')),
|
||||
('description', models.TextField(verbose_name='Description')),
|
||||
('slug', models.SlugField(unique=True)),
|
||||
('log_level', models.CharField(default=b'INFO', max_length=10, verbose_name='Log Level', 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')])),
|
||||
('users', models.ManyToManyField(to='base.ApiUser', blank=True)),
|
||||
],
|
||||
options={
|
||||
'verbose_name': "ActesWeb - Demande d'acte d'\xe9tat civil",
|
||||
},
|
||||
),
|
||||
]
|
|
@ -0,0 +1,79 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# 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/>.
|
||||
from __future__ import unicode_literals
|
||||
|
||||
import json
|
||||
import os
|
||||
import tempfile
|
||||
|
||||
from django.core.files.storage import default_storage
|
||||
from django.template.loader import get_template
|
||||
from django.utils.dateparse import parse_date
|
||||
from django.utils.timezone import now
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
|
||||
from passerelle.base.models import BaseResource
|
||||
from passerelle.utils.api import endpoint
|
||||
from passerelle.utils.jsonresponse import APIError
|
||||
|
||||
|
||||
class ActesWeb(BaseResource):
|
||||
category = _('Civil Status Connectors')
|
||||
|
||||
class Meta:
|
||||
verbose_name = u"ActesWeb - Demande d'acte d'état civil"
|
||||
|
||||
@property
|
||||
def basepath(self):
|
||||
return os.path.join(
|
||||
default_storage.path('actesweb'), self.slug)
|
||||
|
||||
@endpoint(perm='can_access', methods=['post'], description=_('Create demand'))
|
||||
def create(self, request, *args, **kwargs):
|
||||
try:
|
||||
payload = json.loads(request.body)
|
||||
except (ValueError,):
|
||||
raise APIError('Invalid payload format: json expected')
|
||||
|
||||
if payload.get('certificate_type') not in ('NA', 'DE', 'MA'):
|
||||
raise APIError("Invalid <certificate_type>: expected ('NA', 'DE', 'MA')")
|
||||
payload['event_date_start'] = parse_date(payload['event_date_start']).strftime('%Y%m%d')
|
||||
template_name = 'actesweb/demand.txt'
|
||||
demand_content = get_template(template_name).render(payload)
|
||||
application_id = payload['application_id']
|
||||
# create tmp dir
|
||||
tmp_dir = os.path.join(self.basepath, 'tmp')
|
||||
if not os.path.exists(tmp_dir):
|
||||
if default_storage.directory_permissions_mode:
|
||||
d_umask = os.umask(0)
|
||||
try:
|
||||
os.makedirs(tmp_dir, mode=default_storage.directory_permissions_mode)
|
||||
except OSError:
|
||||
pass
|
||||
finally:
|
||||
os.umask(d_umask)
|
||||
else:
|
||||
os.makedirs(tmp_dir)
|
||||
|
||||
filename = '%s.DEM' % now().strftime('%Y-%m-%d_%H-%M-%S_%f')
|
||||
filepath = os.path.join(self.basepath, filename)
|
||||
with tempfile.NamedTemporaryFile(dir=tmp_dir, suffix='.DEM', delete=False) as tpf:
|
||||
tpf.write(demand_content)
|
||||
tpf.flush()
|
||||
os.fsync(tpf.file.fileno())
|
||||
os.rename(tpf.name, filepath)
|
||||
demand_id = '%s_%s' % (application_id, os.path.basename(filepath))
|
||||
return {'data': {'demand_id': demand_id}}
|
|
@ -0,0 +1,46 @@
|
|||
CODAGE=TXT
|
||||
TYPE=DEMANDE
|
||||
VERSION=03
|
||||
TYPE_DEMANDEUR={{applicant_type}}
|
||||
PRIORITE={{application_priority}}
|
||||
DEMANDEUR_CIVILITE={{applicant_title_label}}
|
||||
DEMANDEUR_NOM={{application_priority}}
|
||||
DEMANDEUR_NOM_USAGE={{applicant_usual_name}}
|
||||
DEMANDEUR_PRENOMS={{applicant_firstnames}}
|
||||
DEMANDEUR_ADRESSE1={{applicant_address_street}}
|
||||
DEMANDEUR_ADRESSE2={{applicant_address_complement}}
|
||||
DEMANDEUR_VILLE={{applicant_address_city}}
|
||||
DEMANDEUR_PAYS={{applicant_address_country}}
|
||||
DEMANDEUR_TEL={{applicant_phone}}
|
||||
DEMANDEUR_ADR={{applicant_email}}
|
||||
DEMANDE_NOM={{concerned_lastname}}
|
||||
DEMANDE_PRENOMS={{concerned_firstnames}}
|
||||
DEMANDE_DATE_EVENEMENT={{event_date_start}}
|
||||
TYPE_DEMANDE={{document_type_label}}
|
||||
ACTE={{certificate_type|default:"particulier"}}
|
||||
NB={{document_copies}}
|
||||
LIEN={{applicant_status}}
|
||||
MANDANT_NOM=
|
||||
MANDANT_PRENOMS=
|
||||
LIEU_EVENEMENT={{event_city}}
|
||||
REF_ACTE={{document_ref|default:"inconnu"}}
|
||||
PERE_NOM={{concerned_parent1_lastname}}
|
||||
PERE_PRENOMS={{concerned_parent1_firstnames}}
|
||||
MERE_NOM={{concerned_parent2_lastname}}
|
||||
MERE_PRENOMS={{concerned_parent2_firstnames}}
|
||||
CONJOINT_NOM={{partner_lastname}}
|
||||
CONJOINT_PRENOMS={{partner_firstnames}}
|
||||
CONJOINT_PERE_NOM={{partner_parent1_lastname}}
|
||||
CONJOINT_PERE_PRENOMS={{partner_parent1_firstnames}}
|
||||
CONJOINT_MERE_NOM={{partner_parent2_lastname}}
|
||||
CONJOINT_MERE_PRENOMS={{partner_parent2_firstnames}}
|
||||
MOTIF={{application_reason}}
|
||||
DEMANDE_SEXE={{concerned_sex}}
|
||||
DPERE_SEXE={{concerned_parent1_sex}}
|
||||
DMERE_SEXE={{concerned_parent2_sex}}
|
||||
CONJOINT_SEXE={{partner_sex}}
|
||||
CPERE_SEXE={{partner_parent1_sex}}
|
||||
CMERE_SEXE={{partner_parent2_sex}}
|
||||
{% spaceless %}
|
||||
COMMENTAIRE={{application_comment}}
|
||||
{% endspaceless %}
|
|
@ -115,6 +115,7 @@ INSTALLED_APPS = (
|
|||
'passerelle.base',
|
||||
'passerelle.datasources',
|
||||
# connectors
|
||||
'passerelle.apps.actesweb',
|
||||
'passerelle.apps.airquality',
|
||||
'passerelle.apps.api_particulier',
|
||||
'passerelle.apps.atos_genesys',
|
||||
|
|
|
@ -0,0 +1,50 @@
|
|||
{
|
||||
"applicant_address_city": "Nancy",
|
||||
"applicant_address_complement": "Bat A",
|
||||
"applicant_address_country": "France",
|
||||
"applicant_address_county": "Meurthe-et-Moselle",
|
||||
"applicant_address_street": "37 Rue du Cheval Blanc",
|
||||
"applicant_address_zipcode": "54000",
|
||||
"applicant_email": "chelsea@whatever.com",
|
||||
"applicant_firstnames": "Kim Chelsea",
|
||||
"applicant_lastname": "Whatever",
|
||||
"applicant_name_usage": "nom d'epouse",
|
||||
"applicant_phone": "+33 6 55 44 22 11",
|
||||
"applicant_status": "concerne",
|
||||
"applicant_title": "Mme",
|
||||
"applicant_title_label": "Madame",
|
||||
"applicant_usual_name": "Whatever",
|
||||
"application_id": "N201610154",
|
||||
"application_origin": "internet",
|
||||
"application_reason": "They are just messy",
|
||||
"application_time": "2016-10-20T14:41:20Z",
|
||||
"certificate_type": "NA",
|
||||
"certificate_type_label": "Acte de naissance",
|
||||
"concerned_birth_city": "Harare",
|
||||
"concerned_birth_country": "Zimbabwe",
|
||||
"concerned_birth_county": "",
|
||||
"concerned_birth_date": "1980-02-29",
|
||||
"concerned_firstnames": "Kevin",
|
||||
"concerned_lastname": "Whatever",
|
||||
"concerned_name_usage": "",
|
||||
"concerned_parent1_firstnames": "John Oliver",
|
||||
"concerned_parent1_lastname": "Smith",
|
||||
"concerned_parent1_name_usage": "Smith",
|
||||
"concerned_parent1_title": "M",
|
||||
"concerned_parent1_title_label": "Monsieur",
|
||||
"concerned_parent1_usual_name": "Smith",
|
||||
"concerned_parent2_firstnames": "Kim",
|
||||
"concerned_parent2_lastname": "Smith",
|
||||
"concerned_parent2_name_usage": "nom d'\u00e9pouse",
|
||||
"concerned_parent2_title": "Mme",
|
||||
"concerned_parent2_usual_name": "Smith",
|
||||
"concerned_sex": "m",
|
||||
"concerned_title": "M",
|
||||
"concerned_usual_name": "Whatever",
|
||||
"document_copies": "1",
|
||||
"document_type": "CPI",
|
||||
"document_type_label": "Copie Integrale",
|
||||
"event_city": "Nancy",
|
||||
"event_date_end": "",
|
||||
"event_date_start": "2012-07-14"
|
||||
}
|
|
@ -0,0 +1,37 @@
|
|||
{
|
||||
"applicant_address_city": "Nancy",
|
||||
"applicant_address_complement": "Bat A",
|
||||
"applicant_address_country": "France",
|
||||
"applicant_address_county": "Meurthe-et-Moselle",
|
||||
"applicant_email": "chelsea@whatever.com",
|
||||
"applicant_phone": "+33 6 55 44 22 11",
|
||||
"applicant_address_street": "37 Rue du Cheval Blanc",
|
||||
"applicant_address_zipcode": "54000",
|
||||
"applicant_firstnames": "Kim Chelsea",
|
||||
"applicant_lastname": "Whatever",
|
||||
"applicant_name_usage": "nom d'epouse",
|
||||
"applicant_status": "concerne",
|
||||
"applicant_title": "Mme",
|
||||
"applicant_title_label": "Madame",
|
||||
"applicant_usual_name": "Whatever",
|
||||
"application_id": "D201610171",
|
||||
"application_origin": "internet",
|
||||
"application_reason": "",
|
||||
"application_time": "2016-10-20T14:41:20Z",
|
||||
"certificate_type": "DE",
|
||||
"certificate_type_label": "Acte de d\u00e9c\u00e8s",
|
||||
"concerned_birth_city": "Harare",
|
||||
"concerned_birth_country": "Zimbabwe",
|
||||
"concerned_birth_county": "",
|
||||
"concerned_birth_date": "1980-02-29",
|
||||
"concerned_firstnames": "Kevin",
|
||||
"concerned_lastname": "Whatever",
|
||||
"concerned_sex": "m",
|
||||
"concerned_title": "M",
|
||||
"concerned_usual_name": "Whatever",
|
||||
"document_copies": "1",
|
||||
"document_type": "EXTSF",
|
||||
"document_type_label": "Extrait sans filiation",
|
||||
"event_city": "Nancy",
|
||||
"event_date_start": "2012-07-14"
|
||||
}
|
|
@ -0,0 +1,68 @@
|
|||
{
|
||||
"applicant_address_city": "Nancy",
|
||||
"applicant_address_complement": "Bat A",
|
||||
"applicant_address_country": "France",
|
||||
"applicant_address_county": "Meurthe-et-Moselle",
|
||||
"applicant_email": "chelsea@whatever.com",
|
||||
"applicant_phone": "+33 6 55 44 22 11",
|
||||
"applicant_address_street": "37 Rue du Cheval Blanc",
|
||||
"applicant_address_zipcode": "54000",
|
||||
"applicant_firstnames": "Kim Chelsea",
|
||||
"applicant_lastname": "Whatever",
|
||||
"applicant_name_usage": "nom d'epouse",
|
||||
"applicant_status": "concerne",
|
||||
"applicant_title": "Mme",
|
||||
"applicant_title_label": "Madame",
|
||||
"applicant_usual_name": "Whatever",
|
||||
"application_id": "M201610161",
|
||||
"application_origin": "internet",
|
||||
"application_reason": "Happy mariage",
|
||||
"application_time": "2016-10-20T14:41:20Z",
|
||||
"certificate_type": "MA",
|
||||
"certificate_type_label": "Acte de naissance",
|
||||
"concerned_birth_city": "Harare",
|
||||
"concerned_birth_country": "Zimbabwe",
|
||||
"concerned_birth_county": "",
|
||||
"concerned_birth_date": "1980-02-29",
|
||||
"concerned_firstnames": "Kevin",
|
||||
"concerned_lastname": "Whatever",
|
||||
"concerned_name_usage": "",
|
||||
"concerned_parent1_firstnames": "John Oliver",
|
||||
"concerned_parent1_lastname": "Smith",
|
||||
"concerned_parent1_name_usage": "Smith",
|
||||
"concerned_parent1_title": "M",
|
||||
"concerned_parent1_title_label": "Monsieur",
|
||||
"concerned_parent1_usual_name": "Smith",
|
||||
"concerned_parent2_firstnames": "Kim",
|
||||
"concerned_parent2_lastname": "Smith",
|
||||
"concerned_parent2_name_usage": "nom d'\u00e9pouse",
|
||||
"concerned_parent2_title": "Mme",
|
||||
"concerned_parent2_usual_name": "Smith",
|
||||
"concerned_sex": "m",
|
||||
"concerned_title": "M",
|
||||
"document_copies": "1",
|
||||
"document_type": "CPI",
|
||||
"document_type_label": "Copie Integrale",
|
||||
"event_city": "Nancy",
|
||||
"event_date_end": "",
|
||||
"event_date_start": "2012-07-14",
|
||||
"partner_birth_city": "Harare",
|
||||
"partner_birth_country": "Zimbabwe",
|
||||
"partner_birth_county": "",
|
||||
"partner_birth_date": "1984-02-29",
|
||||
"partner_firstnames": "Chelsea",
|
||||
"partner_lastname": "Contrao",
|
||||
"partner_name_usage": "",
|
||||
"partner_parent1_firstnames": "Antonio",
|
||||
"partner_parent1_lastname": "Scaramucci",
|
||||
"partner_parent1_title": "M",
|
||||
"partner_parent1_title_label": "Monsieur",
|
||||
"partner_parent2_firstnames": "Marguerite",
|
||||
"partner_parent2_lastname": "Scaramucci",
|
||||
"partner_parent2_name_usage": "nom d'\u00e9pouse",
|
||||
"partner_parent2_title": "Mme",
|
||||
"partner_parent2_usual_name": "Gaye",
|
||||
"partner_sex": "F",
|
||||
"partner_title": "Mme",
|
||||
"partner_usual_name": "Scaramucci"
|
||||
}
|
|
@ -0,0 +1,171 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# Passerelle - uniform access to data 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; exclude 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.deepcopy of the GNU Affero General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
from __future__ import unicode_literals
|
||||
|
||||
import json
|
||||
import io
|
||||
import os
|
||||
import shutil
|
||||
|
||||
import pytest
|
||||
|
||||
import utils
|
||||
from passerelle.apps.actesweb.models import ActesWeb
|
||||
|
||||
|
||||
def get_test_base_dir(name):
|
||||
return os.path.join(os.path.dirname(__file__), 'data', name)
|
||||
|
||||
|
||||
def get_file_from_test_base_dir(filename):
|
||||
path = os.path.join(get_test_base_dir('actesweb'), filename)
|
||||
with open(path, 'rb') as fd:
|
||||
return fd.read()
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def actesweb(db):
|
||||
return utils.make_resource(ActesWeb, **{'slug': 'test'})
|
||||
|
||||
|
||||
@pytest.fixture(autouse=True)
|
||||
def media_dir(tmpdir, settings):
|
||||
tmp_dir = tmpdir.mkdir('actesweb').dirname
|
||||
settings.MEDIA_ROOT = tmp_dir
|
||||
yield tmp_dir
|
||||
shutil.rmtree(tmp_dir, ignore_errors=True)
|
||||
|
||||
|
||||
PAYLOAD = [
|
||||
{
|
||||
'birth': json.loads(get_file_from_test_base_dir('payload_birth.json'))
|
||||
},
|
||||
{
|
||||
'mariage': json.loads(get_file_from_test_base_dir('payload_mariage.json'))
|
||||
},
|
||||
{
|
||||
'death': json.loads(get_file_from_test_base_dir('payload_death.json'))
|
||||
}
|
||||
]
|
||||
|
||||
|
||||
@pytest.fixture(params=PAYLOAD)
|
||||
def payload(request):
|
||||
return request.param
|
||||
|
||||
|
||||
def get_demand_filepath(con, demand_id):
|
||||
filename = '_'.join(demand_id.split('_')[1:])
|
||||
return os.path.join(con.basepath, filename)
|
||||
|
||||
|
||||
def assert_file_content_values(filename, expectations):
|
||||
with io.open(filename, 'rb') as fp:
|
||||
for line in fp.readlines():
|
||||
field, value = line.split('=')
|
||||
if field in expectations:
|
||||
assert value.strip() == expectations[field]
|
||||
|
||||
|
||||
def test_demand_creation(app, payload, actesweb):
|
||||
url = '/actesweb/test/create/'
|
||||
if 'birth' in payload:
|
||||
response = app.post_json(url, params=payload['birth'])
|
||||
demand_id = response.json['data']['demand_id']
|
||||
demfile = get_demand_filepath(actesweb, demand_id)
|
||||
assert_file_content_values(
|
||||
demfile, dict(
|
||||
DEMANDEUR_CIVILITE="Madame",
|
||||
DEMANDEUR_NOM_USAGE="Whatever",
|
||||
DEMANDEUR_PRENOMS="Kim Chelsea",
|
||||
DEMANDEUR_ADRESSE1="37 Rue du Cheval Blanc",
|
||||
DEMANDEUR_VILLE="Nancy",
|
||||
DEMANDEUR_PAYS="France",
|
||||
DEMANDEUR_TEL="+33 6 55 44 22 11",
|
||||
DEMANDEUR_ADR="chelsea@whatever.com",
|
||||
DEMANDE_NOM="Whatever",
|
||||
DEMANDE_PRENOMS="Kevin",
|
||||
DEMANDE_DATE_EVENEMENT="20120714",
|
||||
TYPE_DEMANDE="Copie Integrale",
|
||||
ACTE="NA",
|
||||
NB="1",
|
||||
LIEU_EVENEMENT="Nancy",
|
||||
PERE_NOM="Smith",
|
||||
PERE_PRENOMS="John Oliver",
|
||||
MERE_NOM="Smith",
|
||||
MERE_PRENOM="Kim",
|
||||
DEMANDE_SEXE="m"
|
||||
)
|
||||
)
|
||||
elif 'mariage' in payload:
|
||||
response = app.post_json(url, params=payload['mariage'])
|
||||
demand_id = response.json['data']['demand_id']
|
||||
demfile = get_demand_filepath(actesweb, demand_id)
|
||||
assert_file_content_values(
|
||||
demfile, dict(
|
||||
DEMANDEUR_CIVILITE="Madame",
|
||||
DEMANDEUR_NOM_USAGE="Whatever",
|
||||
DEMANDEUR_PRENOMS="Kim Chelsea",
|
||||
DEMANDEUR_ADRESSE1="37 Rue du Cheval Blanc",
|
||||
DEMANDEUR_VILLE="Nancy",
|
||||
DEMANDEUR_PAYS="France",
|
||||
DEMANDEUR_TEL="+33 6 55 44 22 11",
|
||||
DEMANDEUR_ADR="chelsea@whatever.com",
|
||||
DEMANDE_NOM="Whatever",
|
||||
DEMANDE_PRENOMS="Kevin",
|
||||
DEMANDE_DATE_EVENEMENT="20120714",
|
||||
TYPE_DEMANDE="Copie Integrale",
|
||||
ACTE="MA",
|
||||
NB="1",
|
||||
LIEU_EVENEMENT="Nancy",
|
||||
PERE_NOM="Smith",
|
||||
PERE_PRENOMS="John Oliver",
|
||||
MERE_NOM="Smith",
|
||||
MERE_PRENOM="Kim",
|
||||
DEMANDE_SEXE="m",
|
||||
CONJOINT_NOM="Contrao",
|
||||
CONJOIN_PRENOMS="Chelsea",
|
||||
CONJOINT_PERE_NOM="Scaramucci",
|
||||
CONJOINT_PERE_PRENOMS="Antonio",
|
||||
CONJOINT_MERE_NOM="Scaramucci",
|
||||
CONJOINT_MERE_PRENOMS="Marguerite",
|
||||
)
|
||||
)
|
||||
else:
|
||||
response = app.post_json(url, params=payload['death'])
|
||||
demand_id = response.json['data']['demand_id']
|
||||
demfile = get_demand_filepath(actesweb, demand_id)
|
||||
assert_file_content_values(
|
||||
demfile, dict(
|
||||
DEMANDEUR_CIVILITE="Madame",
|
||||
DEMANDEUR_NOM_USAGE="Whatever",
|
||||
DEMANDEUR_PRENOMS="Kim Chelsea",
|
||||
DEMANDEUR_ADRESSE1="37 Rue du Cheval Blanc",
|
||||
DEMANDEUR_VILLE="Nancy",
|
||||
DEMANDEUR_PAYS="France",
|
||||
DEMANDEUR_TEL="+33 6 55 44 22 11",
|
||||
DEMANDEUR_ADR="chelsea@whatever.com",
|
||||
DEMANDE_NOM="Whatever",
|
||||
DEMANDE_PRENOMS="Kevin",
|
||||
DEMANDE_DATE_EVENEMENT="20120714",
|
||||
TYPE_DEMANDE="Extrait sans filiation",
|
||||
ACTE="DE",
|
||||
NB="1",
|
||||
LIEU_EVENEMENT="Nancy",
|
||||
DEMANDE_SEXE="m"
|
||||
)
|
||||
)
|
Loading…
Reference in New Issue