Compare commits
23 Commits
95030b91f5
...
ee1baf8b50
Author | SHA1 | Date |
---|---|---|
Benjamin Dauvergne | ee1baf8b50 | |
Benjamin Dauvergne | 37536df9d1 | |
Thomas NOËL | 514c3f1995 | |
Thomas NOËL | dd87030c50 | |
Nicolas Roche | 104f96b61c | |
Thomas NOËL | 6f3516297e | |
Thomas NOËL | 43e2d9222a | |
Thomas NOËL | d0ecf8af77 | |
Thomas NOËL | 31a0828d6d | |
Thomas NOËL | 020a402a96 | |
Nicolas Roche | 0010095146 | |
Corentin Sechet | b377b87d5d | |
Thomas NOËL | 52886c216c | |
Thomas NOËL | b8fc9716a4 | |
Thomas NOËL | 40c3c6affb | |
Nicolas Roche | ec8dd0a43c | |
Nicolas Roche | 5ad847df95 | |
Nicolas Roche | 8e6f61ceb7 | |
Nicolas Roche | 13fe6411eb | |
Thomas NOËL | 6101988404 | |
Serghei Mihai | 8b3b8edfda | |
Pierre Ducroquet | 52981183ff | |
Benjamin Dauvergne | afab9d49a1 |
|
@ -11,19 +11,34 @@ pipeline {
|
|||
RAND_TEST = "${Math.abs(new Random().nextInt(max+1))}"
|
||||
}
|
||||
stages {
|
||||
stage('Unit Tests') {
|
||||
steps {
|
||||
sh "NUMPROCESSES=6 RAND_TEST=${env.RAND_TEST} tox -rv"
|
||||
}
|
||||
post {
|
||||
always {
|
||||
script {
|
||||
utils = new Utils()
|
||||
utils.publish_coverage('coverage.xml')
|
||||
utils.publish_coverage_native('index.html')
|
||||
utils.publish_pylint('pylint.out')
|
||||
stage('Tests (in parallel)') {
|
||||
failFast true
|
||||
parallel {
|
||||
stage('Unit Tests (pytest)') {
|
||||
steps {
|
||||
sh "NUMPROCESSES=12 RAND_TEST=${env.RAND_TEST} tox -rv"
|
||||
}
|
||||
post {
|
||||
always {
|
||||
script {
|
||||
utils = new Utils()
|
||||
utils.publish_coverage('coverage.xml')
|
||||
utils.publish_coverage_native('index.html')
|
||||
utils.publish_pylint('pylint.out')
|
||||
}
|
||||
mergeJunitResults()
|
||||
}
|
||||
}
|
||||
}
|
||||
stage('Unit Tests (vitest)') {
|
||||
steps {
|
||||
sh "NUMPROCESSES=12 RAND_TEST=${env.RAND_TEST} tox -rv -e vitest"
|
||||
}
|
||||
}
|
||||
stage('Linter (pylint)') {
|
||||
steps {
|
||||
sh "NUMPROCESSES=12 RAND_TEST=${env.RAND_TEST} tox -rv -e pylint"
|
||||
}
|
||||
mergeJunitResults()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,17 @@
|
|||
# Generated by Django 3.2.18 on 2023-12-13 10:33
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
dependencies = [
|
||||
('api_particulier', '0006_api_key_length_1024'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='apiparticulier',
|
||||
name='api_key',
|
||||
field=models.CharField(blank=True, default='', max_length=2048, verbose_name='API key'),
|
||||
),
|
||||
]
|
|
@ -63,7 +63,7 @@ class APIParticulier(BaseResource):
|
|||
choices=[(key, platform['label']) for key, platform in PLATFORMS.items()],
|
||||
)
|
||||
|
||||
api_key = models.CharField(max_length=1024, default='', blank=True, verbose_name=_('API key'))
|
||||
api_key = models.CharField(max_length=2048, default='', blank=True, verbose_name=_('API key'))
|
||||
|
||||
log_requests_errors = False
|
||||
|
||||
|
|
|
@ -891,7 +891,7 @@ class AstreGS(BaseResource):
|
|||
for item in r.liste.EnregRechercheTiersReturn:
|
||||
tiers_data = serialize_object(item)
|
||||
tiers_data['id'] = tiers_data['N']
|
||||
tiers_data['text'] = '%{Nom_Enregistrement}s (%{N}s)'.format(**tiers_data)
|
||||
tiers_data['text'] = '{Nom_Enregistrement} ({N})'.format(**tiers_data)
|
||||
data.append(tiers_data)
|
||||
return {'data': data}
|
||||
|
||||
|
|
|
@ -38,6 +38,8 @@ class Matrix42(BaseResource, HTTPResource):
|
|||
|
||||
log_requests_errors = False
|
||||
|
||||
_category_ordering = [_('Fragments'), _('Objects')]
|
||||
|
||||
class Meta:
|
||||
verbose_name = _('Matrix42 Public API')
|
||||
|
||||
|
@ -59,7 +61,9 @@ class Matrix42(BaseResource, HTTPResource):
|
|||
'Authorization': 'Bearer ' + token['RawToken'],
|
||||
}
|
||||
|
||||
def request(self, uri, params=None, json=None, headers=None, method=None, dict_response=True):
|
||||
def request(
|
||||
self, uri, params=None, json=None, headers=None, method=None, dict_response=True, allow_empty=False
|
||||
):
|
||||
if headers is None:
|
||||
headers = self.get_authorization_headers()
|
||||
if method is None:
|
||||
|
@ -67,6 +71,10 @@ class Matrix42(BaseResource, HTTPResource):
|
|||
url = urljoin(self.base_url, uri)
|
||||
response = self.requests.request(method, url, params=params, json=json, headers=headers)
|
||||
status_code = response.status_code
|
||||
if status_code == 204:
|
||||
if allow_empty:
|
||||
return None
|
||||
raise APIError('Matrix42 returned an empty response (status 204)')
|
||||
try:
|
||||
response = response.json()
|
||||
except ValueError:
|
||||
|
@ -210,3 +218,24 @@ class Matrix42(BaseResource, HTTPResource):
|
|||
):
|
||||
uri = urljoin(self.base_url, 'data/objects/%s' % ciname)
|
||||
return {'data': self.request(uri, json=post_data, dict_response=False)}
|
||||
|
||||
@endpoint(
|
||||
name='generic',
|
||||
display_category=_('Generic: ticket, task, change, problem, …'),
|
||||
methods=['post'],
|
||||
pattern=r'^(?P<object_type>.+)/(?P<action>.+)$',
|
||||
example_pattern='ticket/Transform',
|
||||
post={
|
||||
'description': _('Perform action on object(s)'),
|
||||
'request_body': {'schema': {'application/json': DICT_SCHEMA}},
|
||||
},
|
||||
)
|
||||
def generic(
|
||||
self,
|
||||
request,
|
||||
object_type,
|
||||
action,
|
||||
post_data,
|
||||
):
|
||||
uri = urljoin(self.base_url, '%s/%s' % (object_type, action))
|
||||
return {'data': self.request(uri, json=post_data, dict_response=False, allow_empty=True)}
|
||||
|
|
|
@ -59,11 +59,11 @@ class Migration(migrations.Migration):
|
|||
),
|
||||
(
|
||||
'zeep_strict',
|
||||
models.BooleanField(default=True, verbose_name='Be strict with returned XML'),
|
||||
models.BooleanField(default=False, verbose_name='Be strict with returned XML'),
|
||||
),
|
||||
(
|
||||
'zeep_xsd_ignore_sequence_order',
|
||||
models.BooleanField(default=False, verbose_name='Ignore sequence order'),
|
||||
models.BooleanField(default=True, verbose_name='Ignore sequence order'),
|
||||
),
|
||||
(
|
||||
'zeep_wsse_username',
|
||||
|
|
|
@ -33,7 +33,7 @@ from passerelle.utils.json import unflatten
|
|||
from passerelle.utils.jsonresponse import APIError
|
||||
|
||||
|
||||
class SOAPConnector(BaseResource, HTTPResource):
|
||||
class AbstractSOAPConnector(BaseResource, HTTPResource):
|
||||
wsdl_url = models.URLField(
|
||||
max_length=400, verbose_name=_('WSDL URL'), help_text=_('URL of the WSDL file')
|
||||
)
|
||||
|
@ -50,7 +50,8 @@ class SOAPConnector(BaseResource, HTTPResource):
|
|||
category = _('Business Process Connectors')
|
||||
|
||||
class Meta:
|
||||
verbose_name = _('SOAP connector')
|
||||
abstract = True
|
||||
verbose_name = _('Abstract SOAP connector')
|
||||
|
||||
def clean(self):
|
||||
if (not self.client_certificate or self.client_certificate._committed) and (
|
||||
|
@ -247,3 +248,8 @@ class SOAPConnector(BaseResource, HTTPResource):
|
|||
return schema
|
||||
|
||||
return t2s(xsd_type)
|
||||
|
||||
|
||||
class SOAPConnector(AbstractSOAPConnector):
|
||||
class Meta:
|
||||
verbose_name = _('SOAP connector')
|
||||
|
|
|
@ -0,0 +1,35 @@
|
|||
# Generated by Django 3.2.18 on 2023-12-14 16:45
|
||||
|
||||
import django.db.models.deletion
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
initial = True
|
||||
|
||||
dependencies = [
|
||||
('soap', '0001_initial'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='Scrib',
|
||||
fields=[
|
||||
(
|
||||
'soapconnector_ptr',
|
||||
models.OneToOneField(
|
||||
auto_created=True,
|
||||
on_delete=django.db.models.deletion.CASCADE,
|
||||
parent_link=True,
|
||||
primary_key=True,
|
||||
serialize=False,
|
||||
to='soap.soapconnector',
|
||||
),
|
||||
),
|
||||
],
|
||||
options={
|
||||
'verbose_name': 'Scrib SOAP API',
|
||||
},
|
||||
bases=('soap.soapconnector',),
|
||||
),
|
||||
]
|
|
@ -0,0 +1,92 @@
|
|||
# Generated by Django 3.2.18 on 2023-12-19 11:06
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
dependencies = [
|
||||
('base', '0030_resourcelog_base_resour_appname_298cbc_idx'),
|
||||
('nantes_scrib', '0001_initial'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='SOAPScrib',
|
||||
fields=[
|
||||
(
|
||||
'id',
|
||||
models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID'),
|
||||
),
|
||||
('title', models.CharField(max_length=50, verbose_name='Title')),
|
||||
('slug', models.SlugField(unique=True, verbose_name='Identifier')),
|
||||
('description', models.TextField(verbose_name='Description')),
|
||||
(
|
||||
'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 password'
|
||||
),
|
||||
),
|
||||
(
|
||||
'client_certificate',
|
||||
models.FileField(
|
||||
blank=True, null=True, upload_to='', verbose_name='TLS client certificate'
|
||||
),
|
||||
),
|
||||
(
|
||||
'trusted_certificate_authorities',
|
||||
models.FileField(blank=True, null=True, upload_to='', verbose_name='TLS trusted CAs'),
|
||||
),
|
||||
(
|
||||
'verify_cert',
|
||||
models.BooleanField(blank=True, default=True, verbose_name='TLS verify certificates'),
|
||||
),
|
||||
(
|
||||
'http_proxy',
|
||||
models.CharField(blank=True, max_length=128, verbose_name='HTTP and HTTPS proxy'),
|
||||
),
|
||||
(
|
||||
'wsdl_url',
|
||||
models.URLField(
|
||||
help_text='URL of the WSDL file', max_length=400, verbose_name='WSDL URL'
|
||||
),
|
||||
),
|
||||
(
|
||||
'zeep_strict',
|
||||
models.BooleanField(default=False, verbose_name='Be strict with returned XML'),
|
||||
),
|
||||
(
|
||||
'zeep_xsd_ignore_sequence_order',
|
||||
models.BooleanField(default=True, verbose_name='Ignore sequence order'),
|
||||
),
|
||||
(
|
||||
'zeep_wsse_username',
|
||||
models.CharField(blank=True, default='', max_length=256, verbose_name='WSSE Username'),
|
||||
),
|
||||
(
|
||||
'zeep_wsse_password',
|
||||
models.CharField(blank=True, default='', max_length=256, verbose_name='WSSE Password'),
|
||||
),
|
||||
(
|
||||
'users',
|
||||
models.ManyToManyField(
|
||||
blank=True,
|
||||
related_name='_nantes_scrib_soapscrib_users_+',
|
||||
related_query_name='+',
|
||||
to='base.ApiUser',
|
||||
),
|
||||
),
|
||||
],
|
||||
options={
|
||||
'verbose_name': 'Scrib SOAP API',
|
||||
},
|
||||
),
|
||||
migrations.DeleteModel(
|
||||
name='Scrib',
|
||||
),
|
||||
]
|
|
@ -0,0 +1,95 @@
|
|||
# passerelle - uniform access to multiple data sources and services
|
||||
# Copyright (C) 2023 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 django.utils.translation import gettext_lazy as _
|
||||
|
||||
from passerelle.apps.soap.models import AbstractSOAPConnector
|
||||
from passerelle.utils.api import endpoint
|
||||
from passerelle.utils.jsonresponse import APIError
|
||||
|
||||
DICT_SCHEMA = {
|
||||
'$schema': 'http://json-schema.org/draft-04/schema#',
|
||||
'type': 'object',
|
||||
'additionalProperties': True,
|
||||
'unflatten': True,
|
||||
}
|
||||
|
||||
|
||||
def lax_int(value):
|
||||
try:
|
||||
return int(value)
|
||||
except (ValueError, TypeError):
|
||||
return None
|
||||
|
||||
|
||||
class SOAPScrib(AbstractSOAPConnector):
|
||||
category = _('Business Process Connectors')
|
||||
|
||||
class Meta:
|
||||
verbose_name = _('Scrib SOAP API')
|
||||
|
||||
@endpoint(
|
||||
name='depot',
|
||||
description=_('Clean payload and sent it to method/depot'),
|
||||
display_order=-1,
|
||||
display_category=_('Publik compatible API'),
|
||||
methods=['post'],
|
||||
post={'request_body': {'schema': {'application/json': DICT_SCHEMA}}},
|
||||
)
|
||||
def depot(self, request, post_data):
|
||||
# clean "bac" list: keep only bacCollecteXXX if bacCollecteXXX is True
|
||||
if not isinstance(post_data.get('demandeBacs', {}).get('bac'), list):
|
||||
raise APIError('missing demandeBacs/bac list', http_status=400)
|
||||
|
||||
demandeBacs = post_data['demandeBacs']
|
||||
|
||||
cleaned_bacs = []
|
||||
for bac in demandeBacs['bac']:
|
||||
if not isinstance(bac, dict):
|
||||
continue
|
||||
cleaned_bac = {}
|
||||
for key in [k for k in bac if k.startswith('bac')]:
|
||||
if bac[key] not in (True, 'true', 'True', 1, '1'):
|
||||
continue
|
||||
cleaned_bac[key] = 'true'
|
||||
numkey = 'numBac' + key[3:]
|
||||
num = (bac.get(numkey, '') or '').strip()
|
||||
if num:
|
||||
cleaned_bac[numkey] = num
|
||||
if cleaned_bac:
|
||||
cleaned_bacs.append(cleaned_bac)
|
||||
demandeBacs['bac'] = cleaned_bacs
|
||||
|
||||
# remove numeroVoie if empty or non-integer (xsd:int/xsd:short in wsdl)
|
||||
for key in ('numeroVoie', 'nombrePersonnesFoyer'):
|
||||
if key in demandeBacs:
|
||||
demandeBacs[key] = lax_int(demandeBacs[key])
|
||||
if demandeBacs[key] is None: # was not an integer, remove it
|
||||
del demandeBacs[key]
|
||||
|
||||
# remove raisonDemande and typeDegradation if empty (or not string)
|
||||
for key in ('raisonDemande', 'typeDegradation'):
|
||||
if key in demandeBacs:
|
||||
if isinstance(demandeBacs[key], str) and demandeBacs[key].strip():
|
||||
continue
|
||||
del demandeBacs[key]
|
||||
|
||||
response = self.method(request, method_name='depot', post_data=post_data)
|
||||
codeRetour = response['data'].get('codeRetour') # should be True
|
||||
codeErreur = response['data'].get('codeErreur') # should be empty
|
||||
if not codeRetour or codeErreur:
|
||||
response['err'] = 1
|
||||
return response
|
|
@ -34,7 +34,7 @@ from django.template.loader import render_to_string as render_template_to_string
|
|||
from django.utils import dateformat
|
||||
from django.utils.dateparse import parse_date, parse_datetime
|
||||
from django.utils.text import slugify
|
||||
from django.utils.timezone import now
|
||||
from django.utils.timezone import localtime, now
|
||||
from requests.exceptions import RequestException
|
||||
from zeep.helpers import serialize_object
|
||||
from zeep.wsse.username import UsernameToken
|
||||
|
@ -43,7 +43,7 @@ from passerelle.apps.base_adresse.models import CityModel
|
|||
from passerelle.base.models import BaseResource, HTTPResource
|
||||
from passerelle.base.signature import sign_url
|
||||
from passerelle.utils.api import endpoint
|
||||
from passerelle.utils.conversion import simplify
|
||||
from passerelle.utils.conversion import normalize, simplify
|
||||
from passerelle.utils.jsonresponse import APIError
|
||||
from passerelle.utils.soap import SOAPFault, SOAPServiceUnreachable
|
||||
from passerelle.utils.templates import render_to_string
|
||||
|
@ -291,14 +291,62 @@ class ToulouseMaelis(BaseResource, HTTPResource):
|
|||
town.item_data['zip_and_text'] = '%s %s' % (zipcode, town.item_text)
|
||||
town.save()
|
||||
|
||||
def daily(self):
|
||||
super().daily()
|
||||
self.update_referentials()
|
||||
@classmethod
|
||||
def earliest_updated(cls, qs):
|
||||
timestamp = qs.aggregate(updated=models.Min('updated'))['updated']
|
||||
if timestamp:
|
||||
timestamp = localtime(timestamp)
|
||||
return timestamp
|
||||
|
||||
def get_activity_referentials_earliest_timestamp(self):
|
||||
referentials = self.referential.filter(
|
||||
referential_name__in=['Activity', 'ActivityNatureType', 'Direct', 'Service']
|
||||
)
|
||||
return self.earliest_updated(referentials)
|
||||
|
||||
def is_activity_referentials_too_old(self):
|
||||
timestamp = self.get_activity_referentials_earliest_timestamp()
|
||||
return not timestamp or (now() - timestamp >= datetime.timedelta(hours=6))
|
||||
|
||||
def every5min(self):
|
||||
self.update_activity_referentials()
|
||||
try:
|
||||
self.update_activity_referentials()
|
||||
except UpdateError as e:
|
||||
if self.is_activity_referentials_too_old():
|
||||
self.logger.error('Erreur sur la mise à jour (depuis plus de 6 heures): %s' % e)
|
||||
else:
|
||||
self.logger.warning('Erreur sur la mise à jour: %s' % e)
|
||||
else:
|
||||
self.logger.info('Réferentiels mis à jour.')
|
||||
|
||||
def get_referentials_earliest_timestamp(self):
|
||||
referentials = self.referential.exclude(
|
||||
referential_name__in=['Activity', 'ActivityNatureType', 'Direct', 'Service']
|
||||
)
|
||||
return self.earliest_updated(referentials)
|
||||
|
||||
def should_update_referentials(self):
|
||||
timestamp = self.get_referentials_earliest_timestamp()
|
||||
# try to update every 24 hours, then do it as long as it fails
|
||||
if not timestamp:
|
||||
return True
|
||||
if now() - timestamp >= datetime.timedelta(hours=24):
|
||||
return True
|
||||
# also after a failure do it prefentially after midnight
|
||||
if (now() - timestamp > datetime.timedelta(hours=7)) and (
|
||||
datetime.time(0, 0) < localtime(now()).time() < datetime.time(6, 0)
|
||||
):
|
||||
return True
|
||||
return False
|
||||
|
||||
def is_referentials_too_old(self):
|
||||
# referentials are tool old if any entry is more than 30 hours old
|
||||
timestamp = self.get_referentials_earliest_timestamp()
|
||||
return not timestamp or (now() - timestamp >= datetime.timedelta(hours=30))
|
||||
|
||||
def update_referentials(self):
|
||||
if not self.should_update_referentials():
|
||||
return
|
||||
try:
|
||||
self.update_family_referentials()
|
||||
self.update_site_referentials()
|
||||
|
@ -307,7 +355,10 @@ class ToulouseMaelis(BaseResource, HTTPResource):
|
|||
# merge zip codes from base adresse into town referential
|
||||
self.merge_zipcodes()
|
||||
except UpdateError as e:
|
||||
self.logger.warning('Erreur sur la mise à jour: %s' % e)
|
||||
if self.is_referentials_too_old():
|
||||
self.logger.error('Erreur sur la mise à jour (depuis plus de 30 heures): %s' % e)
|
||||
else:
|
||||
self.logger.warning('Erreur sur la mise à jour: %s' % e)
|
||||
else:
|
||||
self.logger.info('Réferentiels mis à jour.')
|
||||
|
||||
|
@ -349,9 +400,11 @@ class ToulouseMaelis(BaseResource, HTTPResource):
|
|||
subscription.trigger()
|
||||
|
||||
def hourly(self):
|
||||
super().hourly()
|
||||
self.notify_invoices_paid()
|
||||
self.cancel_basket_invoices()
|
||||
self.trigger_subscriptions_cron()
|
||||
self.update_referentials()
|
||||
|
||||
def get_referential(self, referential_name, id=None, q=None, limit=None, distinct=True):
|
||||
if id is not None:
|
||||
|
@ -1165,8 +1218,8 @@ class ToulouseMaelis(BaseResource, HTTPResource):
|
|||
)
|
||||
continue
|
||||
if (
|
||||
response[rlg]['firstname'] == post_data['firstname'].upper()
|
||||
and response[rlg]['lastname'] == post_data['lastname'].upper()
|
||||
response[rlg]['firstname'] == normalize(post_data['firstname']).upper()
|
||||
and response[rlg]['lastname'] == normalize(post_data['lastname']).upper()
|
||||
and response[rlg]['birth']['dateBirth'].strftime('%Y-%m-%d') == post_data['dateBirth']
|
||||
):
|
||||
break
|
||||
|
@ -2505,12 +2558,20 @@ class ToulouseMaelis(BaseResource, HTTPResource):
|
|||
response = self.call('Activity', 'getPersonScheduleList', **payload)
|
||||
|
||||
date_min_prev = None
|
||||
warning_msg = "No week calendar for activity '%s' on %s" % (
|
||||
activity_id,
|
||||
ref_date.strftime(utils.json_date_format),
|
||||
)
|
||||
recurrent_week = []
|
||||
day_names = ['Lundi', 'Mardi', 'Mercredi', 'Jeudi', 'Vendredi', 'Samedi', 'Dimanche']
|
||||
for result_data in response or []:
|
||||
for schedule in result_data['activityScheduleList']:
|
||||
if schedule['activity']['idAct'] != activity_id or not schedule.get('weeklyCalendar'):
|
||||
continue
|
||||
warning_msg = "No open day for activity '%s' on %s" % (
|
||||
activity_id,
|
||||
ref_date.strftime(utils.json_date_format),
|
||||
)
|
||||
units = []
|
||||
for item in schedule['unitScheduleList']:
|
||||
key = item['unit']['calendarLetter']
|
||||
|
@ -2524,6 +2585,7 @@ class ToulouseMaelis(BaseResource, HTTPResource):
|
|||
day_num = item['dayNum']
|
||||
day_str = day_names[day_num - 1]
|
||||
for key, value in units:
|
||||
warning_msg = None
|
||||
recurrent_week.append(
|
||||
{
|
||||
'id': '%s-%s' % (day_num, key),
|
||||
|
@ -2533,15 +2595,12 @@ class ToulouseMaelis(BaseResource, HTTPResource):
|
|||
'text': '%s %s' % (day_str, value),
|
||||
}
|
||||
)
|
||||
if not recurrent_week:
|
||||
raise APIError(
|
||||
'No week calendar for activity %s on %s'
|
||||
% (activity_id, ref_date.strftime(utils.json_date_format))
|
||||
)
|
||||
return {
|
||||
'data': recurrent_week,
|
||||
'meta': {'date_min_prev': date_min_prev.strftime(utils.json_date_format)},
|
||||
}
|
||||
if date_min_prev:
|
||||
date_min_prev = date_min_prev.strftime(utils.json_date_format)
|
||||
if warning_msg and "'None'" not in warning_msg:
|
||||
# do not raise on 'None' activity
|
||||
raise APIError(warning_msg, log_error=True)
|
||||
return {'data': recurrent_week, 'meta': {'date_min_prev': date_min_prev, 'warning_msg': warning_msg}}
|
||||
|
||||
@endpoint(
|
||||
display_category='Réservation',
|
||||
|
@ -2860,7 +2919,7 @@ class ToulouseMaelis(BaseResource, HTTPResource):
|
|||
]
|
||||
|
||||
data = []
|
||||
for activity in self.get_referential('Activity'):
|
||||
for activity in self.get_referential('Activity', distinct=False):
|
||||
activity_type = activity['activityPortail'].get('activityType')
|
||||
activity_nature = activity_type.get('natureSpec') if activity_type else None
|
||||
if not activity_nature or activity_nature['code'] not in self.get_loisir_nature_codes():
|
||||
|
@ -2883,17 +2942,21 @@ class ToulouseMaelis(BaseResource, HTTPResource):
|
|||
|
||||
update_criterias_order_field(criterias, ['service', 'nature', 'type', 'day'])
|
||||
|
||||
many_units = len(activity['unitPortailList']) > 1
|
||||
for unit in activity.pop('unitPortailList'):
|
||||
unit['id'] = unit['idUnit']
|
||||
unit['text'] = unit['libelle']
|
||||
unit_text_item = ''
|
||||
if many_units:
|
||||
unit_text_item = ' (%s)' % unit['text']
|
||||
|
||||
criterias['public']['data'] = {}
|
||||
start_dob = unit['birthDateStart']
|
||||
end_dob = unit['birthDateEnd']
|
||||
if start_dob:
|
||||
start_dob = parse_date(start_dob)
|
||||
start_dob = parse_datetime(start_dob)
|
||||
if end_dob:
|
||||
end_dob = parse_date(end_dob)
|
||||
end_dob = parse_datetime(end_dob)
|
||||
for key, value in utils.get_public_criterias(datetime.date.today(), start_dob, end_dob):
|
||||
add_criteria('public', key, value)
|
||||
|
||||
|
@ -2909,7 +2972,7 @@ class ToulouseMaelis(BaseResource, HTTPResource):
|
|||
data.append(
|
||||
{
|
||||
'id': '%s-%s-%s' % (activity['id'], unit['id'], place['id']),
|
||||
'text': '%s, %s, %s' % (activity['text'], unit['text'], place['text']),
|
||||
'text': '%s%s, %s' % (activity['text'], unit_text_item, place['text']),
|
||||
'activity': activity,
|
||||
'unit': unit,
|
||||
'place': place,
|
||||
|
|
|
@ -7,7 +7,7 @@ msgid ""
|
|||
msgstr ""
|
||||
"Project-Id-Version: Passerelle 0\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2023-11-22 21:24+0100\n"
|
||||
"POT-Creation-Date: 2023-12-22 12:20+0100\n"
|
||||
"PO-Revision-Date: 2023-11-22 21:24+0100\n"
|
||||
"Last-Translator: Frederic Peters <fpeters@entrouvert.com>\n"
|
||||
"Language: fr\n"
|
||||
|
@ -110,11 +110,11 @@ msgstr "Jeton d’accès aux API (API token)"
|
|||
#: contrib/grenoble_gru/models.py contrib/isere_ens/models.py
|
||||
#: contrib/isere_esrh/models.py contrib/iws/models.py
|
||||
#: contrib/lille_kimoce/models.py contrib/mdph13/models.py
|
||||
#: contrib/planitech/models.py contrib/rsa13/models.py
|
||||
#: contrib/sigerly/models.py contrib/solis_afi_mss/models.py
|
||||
#: contrib/solis_apa/models.py contrib/teamnet_axel/models.py
|
||||
#: contrib/toulouse_axel/models.py contrib/toulouse_foederis/models.py
|
||||
#: contrib/toulouse_smart/models.py
|
||||
#: contrib/nantes_scrib/models.py contrib/planitech/models.py
|
||||
#: contrib/rsa13/models.py contrib/sigerly/models.py
|
||||
#: contrib/solis_afi_mss/models.py contrib/solis_apa/models.py
|
||||
#: contrib/teamnet_axel/models.py contrib/toulouse_axel/models.py
|
||||
#: contrib/toulouse_foederis/models.py contrib/toulouse_smart/models.py
|
||||
msgid "Business Process Connectors"
|
||||
msgstr "Connecteurs métiers"
|
||||
|
||||
|
@ -125,7 +125,7 @@ msgstr "Adullact Pastell"
|
|||
#: apps/adullact_pastell/models.py
|
||||
msgid "API token or authentication username and password should be defined."
|
||||
msgstr ""
|
||||
"Le jeton d’accès aux API ou l'identifiant et mot de passe doivent être "
|
||||
"Le jeton d’accès aux API ou l’identifiant et mot de passe doivent être "
|
||||
"définis."
|
||||
|
||||
#: apps/adullact_pastell/models.py
|
||||
|
@ -629,7 +629,7 @@ msgstr "Statut des demandes"
|
|||
#: apps/astech/models.py
|
||||
msgid "Base API URL (example: https://astech-symphonie.com/app.php/)"
|
||||
msgstr ""
|
||||
"URL de base de l'API (par exemple : https://astech-symphonie.com/app.php/)"
|
||||
"URL de base de l’API (par exemple : https://astech-symphonie.com/app.php/)"
|
||||
|
||||
#: apps/astech/models.py
|
||||
msgid "Connection code"
|
||||
|
@ -3055,6 +3055,14 @@ msgstr "Récupérer le statut d’une demande"
|
|||
msgid "Get submission decree"
|
||||
msgstr "Récupérer l’acte d’une demande"
|
||||
|
||||
#: apps/matrix42/models.py
|
||||
msgid "Fragments"
|
||||
msgstr "Fragments (fragments)"
|
||||
|
||||
#: apps/matrix42/models.py
|
||||
msgid "Objects"
|
||||
msgstr "Objets (objects)"
|
||||
|
||||
#: apps/matrix42/models.py
|
||||
msgid "Matrix42 Public API"
|
||||
msgstr "Matrix42 API Publique"
|
||||
|
@ -3071,10 +3079,6 @@ msgstr "Jeton d’authentification"
|
|||
msgid "Fragment Query"
|
||||
msgstr "Requête sur fragments"
|
||||
|
||||
#: apps/matrix42/models.py
|
||||
msgid "Fragments"
|
||||
msgstr "Fragments (fragments)"
|
||||
|
||||
#: apps/matrix42/models.py
|
||||
msgid "Technical name of the Data Definition"
|
||||
msgstr "Nom technique de la définition de donnée"
|
||||
|
@ -3116,14 +3120,18 @@ msgstr "Récupérer le fragment complet pour cet ID"
|
|||
msgid "Get an object"
|
||||
msgstr "Récupérer un objet"
|
||||
|
||||
#: apps/matrix42/models.py
|
||||
msgid "Objects"
|
||||
msgstr "Objets (objects)"
|
||||
|
||||
#: apps/matrix42/models.py
|
||||
msgid "Create an new object"
|
||||
msgstr "Créer un objet"
|
||||
|
||||
#: apps/matrix42/models.py
|
||||
msgid "Generic: ticket, task, change, problem, …"
|
||||
msgstr "Générique : ticket, task, change, problem, …"
|
||||
|
||||
#: apps/matrix42/models.py
|
||||
msgid "Perform action on object(s)"
|
||||
msgstr "Exécuter l’action sur le(s) objet(s)"
|
||||
|
||||
#: apps/mdel/models.py
|
||||
msgid "SFTP server for outgoing files"
|
||||
msgstr "Serveur SFTP pour les fichiers sortants"
|
||||
|
@ -3896,7 +3904,7 @@ msgstr ""
|
|||
#: apps/pdf/models.py
|
||||
msgid "Return possible values for PDF's combo or list form fields"
|
||||
msgstr ""
|
||||
"Renvoie les valeurs possibles pour un champ liste à choix d'un formulaire PDF"
|
||||
"Renvoie les valeurs possibles pour un champ liste à choix d’un formulaire PDF"
|
||||
|
||||
#: apps/pdf/models.py
|
||||
msgid "Identifier of the field"
|
||||
|
@ -4192,7 +4200,7 @@ msgstr "Obtenir les informations sur l’accès au lecteur de code QR"
|
|||
|
||||
#: apps/qrcode/models.py
|
||||
msgid "Open a QRCode reader page."
|
||||
msgstr "Obtenir l'URL du lecteur de code QR"
|
||||
msgstr "Obtenir l’URL du lecteur de code QR"
|
||||
|
||||
#: apps/qrcode/models.py
|
||||
msgid "Last modification"
|
||||
|
@ -4220,7 +4228,7 @@ msgstr "De"
|
|||
|
||||
#: apps/qrcode/templates/qrcode/qrcode-reader.html
|
||||
msgid "This QR code isn't supported by this application."
|
||||
msgstr "Ce code QR n'est pas supporté par cette application."
|
||||
msgstr "Ce code QR n’est pas supporté par cette application."
|
||||
|
||||
#: apps/qrcode/templates/qrcode/qrcode-reader.html
|
||||
msgid "Signature verification failed."
|
||||
|
@ -4231,12 +4239,12 @@ msgid ""
|
|||
"QR code reader isn\\'t supported on your platform. Please update your "
|
||||
"browser."
|
||||
msgstr ""
|
||||
"Le lecteur de code QR n'est pas supporté sur votre plateforme. Essayez de "
|
||||
"mettre à jour votre navigateur ou d'en changer."
|
||||
"Le lecteur de code QR n’est pas supporté sur votre plateforme. Essayez de "
|
||||
"mettre à jour votre navigateur ou d’en changer."
|
||||
|
||||
#: apps/qrcode/templates/qrcode/qrcode-reader.html
|
||||
msgid "QR code not yet valid"
|
||||
msgstr "Le certificat n'est pas encore valide."
|
||||
msgstr "Le certificat n’est pas encore valide."
|
||||
|
||||
#: apps/qrcode/templates/qrcode/qrcode-reader.html sms/forms.py
|
||||
msgid "To"
|
||||
|
@ -4249,11 +4257,11 @@ msgstr "Code QR et certificat valide"
|
|||
#: apps/qrcode/templates/qrcode/qrcode-reader.html
|
||||
msgid "Reader isn't usable yet."
|
||||
msgstr ""
|
||||
"Vous n'êtes pas encore autorisé à lire les codes QR, veuillez attendre."
|
||||
"Vous n’êtes pas encore autorisé à lire les codes QR, veuillez attendre."
|
||||
|
||||
#: apps/qrcode/templates/qrcode/qrcode-reader.html
|
||||
msgid "Reader has expired."
|
||||
msgstr "La période d'autorisation de votre lecteur de code QR est terminée."
|
||||
msgstr "La période d’autorisation de votre lecteur de code QR est terminée."
|
||||
|
||||
#: apps/sector/models.py
|
||||
msgid "all"
|
||||
|
@ -4586,13 +4594,13 @@ msgstr "Obtenir la finition d’un véhicule par numéro d’immatriculation"
|
|||
#: apps/sivin/models.py
|
||||
msgid "Get vehicle \"finition\" by registration plate, ordered by rangs"
|
||||
msgstr ""
|
||||
"Obtenir la finition théorique d'un véhicule par numéro d'immatriculation, "
|
||||
"Obtenir la finition théorique d’un véhicule par numéro d’immatriculation, "
|
||||
"ordonnée par rang"
|
||||
|
||||
#: apps/sivin/models.py
|
||||
msgid "Get vehicle theorical \"finition\" by registration plate"
|
||||
msgstr ""
|
||||
"Obtenir la finition théorique d'un véhicule par numéro d'immatriculation"
|
||||
"Obtenir la finition théorique d’un véhicule par numéro d’immatriculation"
|
||||
|
||||
#: apps/smsfactor/models.py apps/twilio/models.py
|
||||
msgid "Auth Token"
|
||||
|
@ -4636,13 +4644,17 @@ msgid "WSSE Password"
|
|||
msgstr "Mot de passe WSSE"
|
||||
|
||||
#: apps/soap/models.py
|
||||
msgid "SOAP connector"
|
||||
msgstr "Connecteur SOAP"
|
||||
msgid "Abstract SOAP connector"
|
||||
msgstr "Connecteur SOAP (abstrait)"
|
||||
|
||||
#: apps/soap/models.py
|
||||
msgid "Call a SOAP method"
|
||||
msgstr "Appeler une méthode SOAP"
|
||||
|
||||
#: apps/soap/models.py
|
||||
msgid "SOAP connector"
|
||||
msgstr "Connecteur SOAP"
|
||||
|
||||
#: apps/solis/models.py
|
||||
msgid "Solis API base URL"
|
||||
msgstr "URL de base de l’API Solis"
|
||||
|
@ -5790,7 +5802,7 @@ msgstr "Récupérer les informations officielles"
|
|||
|
||||
#: contrib/isere_esrh/models.py
|
||||
msgid "Official registration number"
|
||||
msgstr "Numéro d'enregistrement officiel"
|
||||
msgstr "Numéro d’enregistrement officiel"
|
||||
|
||||
#: contrib/isere_esrh/models.py
|
||||
msgid "Public authority"
|
||||
|
@ -5814,7 +5826,7 @@ msgstr ""
|
|||
|
||||
#: contrib/isere_esrh/models.py
|
||||
msgid "Get job types"
|
||||
msgstr "Lister les types d'emploi"
|
||||
msgstr "Lister les types d’emploi"
|
||||
|
||||
#: contrib/iws/models.py
|
||||
msgid "URL of SOAP operation endpoint"
|
||||
|
@ -5988,6 +6000,18 @@ msgstr "Requête : "
|
|||
msgid "Response : "
|
||||
msgstr "Réponse : "
|
||||
|
||||
#: contrib/nantes_scrib/models.py
|
||||
msgid "Scrib SOAP API"
|
||||
msgstr "Scrib API SOAP"
|
||||
|
||||
#: contrib/nantes_scrib/models.py
|
||||
msgid "Clean payload and sent it to method/depot"
|
||||
msgstr "Nettoyer le contenu et l’envoyer à method/depot"
|
||||
|
||||
#: contrib/nantes_scrib/models.py
|
||||
msgid "Publik compatible API"
|
||||
msgstr "API compatible Publik"
|
||||
|
||||
#: contrib/planitech/models.py
|
||||
msgid "Planitec API endpoint"
|
||||
msgstr "Point d’accès à l’API Planitec"
|
||||
|
@ -6767,8 +6791,8 @@ msgstr "Identifiant d’un élément de la source de données « nationalite
|
|||
#: contrib/toulouse_foederis/models.py
|
||||
msgid "Applicant end of working authorization, if nationality is 'other'."
|
||||
msgstr ""
|
||||
"Date de fin d'autorisation de travail du candidat, si sa nationalité est "
|
||||
"'autre'."
|
||||
"Date de fin d’autorisation de travail du candidat, si sa nationalité est "
|
||||
"« autre »."
|
||||
|
||||
#: contrib/toulouse_foederis/models.py
|
||||
msgid "RQTH."
|
||||
|
@ -6797,7 +6821,7 @@ msgstr "Date de fin de validité de la FIMO."
|
|||
#: contrib/toulouse_foederis/models.py
|
||||
msgid "ID of an element of the data source 'situation-actuelle'."
|
||||
msgstr ""
|
||||
"Identifiant d'une élément de la source de données 'situation actuelle'."
|
||||
"Identifiant d'une élément de la source de données « situation actuelle »."
|
||||
|
||||
#: contrib/toulouse_foederis/models.py
|
||||
msgid "Agent's collectivity"
|
||||
|
@ -6854,7 +6878,7 @@ msgstr "Information complémentaires sur la candidature."
|
|||
#: contrib/toulouse_foederis/models.py
|
||||
msgid "ID of an element of the data source 'origine-candidature'."
|
||||
msgstr ""
|
||||
"Identifiant d'un élément de la source de données 'origine-candidature'."
|
||||
"Identifiant d'un élément de la source de données « origine-candidature »."
|
||||
|
||||
#: contrib/toulouse_foederis/models.py
|
||||
msgid "Precisions if 'origine' is 'other'."
|
||||
|
@ -6866,7 +6890,7 @@ msgstr "Accord RGPD."
|
|||
|
||||
#: contrib/toulouse_foederis/models.py
|
||||
msgid "Wanted job types"
|
||||
msgstr "Types d'emploi souhaités"
|
||||
msgstr "Types d’emploi souhaités"
|
||||
|
||||
#: contrib/toulouse_foederis/models.py
|
||||
msgid "IDs of elements of the data source 'domaine-emploi'."
|
||||
|
@ -6979,7 +7003,7 @@ msgstr "Créer une candidature"
|
|||
|
||||
#: contrib/toulouse_foederis/models.py
|
||||
msgid "Couldn't recognize provided phone number."
|
||||
msgstr "La valeur fournie n'est pas un numéro de téléphone."
|
||||
msgstr "La valeur fournie n’est pas un numéro de téléphone."
|
||||
|
||||
#: contrib/toulouse_foederis/models.py
|
||||
msgid "Attach a file to an application."
|
||||
|
|
|
@ -194,11 +194,12 @@ INSTALLED_APPS = (
|
|||
'gadjo',
|
||||
)
|
||||
|
||||
# disable some applications for now
|
||||
# disable (hide) some applications for now
|
||||
PASSERELLE_APP_BDP_ENABLED = False
|
||||
PASSERELLE_APP_GDC_ENABLED = False
|
||||
PASSERELLE_APP_STRASBOURG_EU_ENABLED = False
|
||||
PASSERELLE_APP_TOULOUSE_MAELIS_ENABLED = False
|
||||
PASSERELLE_APP_NANTES_SCRIB_ENABLED = False
|
||||
|
||||
# mark some apps as legacy
|
||||
PASSERELLE_APP_CLICRDV_LEGACY = True
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
{% load gadjo i18n static %}
|
||||
{% block page-title %}Passerelle{% endblock %}
|
||||
{% block site-title %}Passerelle{% endblock %}
|
||||
{% block footer %}Passerelle — Copyright © Entr'ouvert{% endblock %}
|
||||
|
||||
{% block extrascripts %}
|
||||
{{ block.super }}
|
||||
|
|
|
@ -3,4 +3,4 @@
|
|||
pip install $*
|
||||
nodeenv --prebuilt --python-virtualenv
|
||||
source $VIRTUAL_ENV/bin/activate # source again to activate npm from env
|
||||
npm install -g vitest happy-dom
|
||||
npm install -g vitest@"<1.1.0" happy-dom
|
||||
|
|
|
@ -0,0 +1,149 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<definitions xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" xmlns:wsp="http://www.w3.org/ns/ws-policy" xmlns:wsp1_2="http://schemas.xmlsoap.org/ws/2004/09/policy" xmlns:wsam="http://www.w3.org/2007/05/addressing/metadata" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:tns="http://ws.scrib/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://schemas.xmlsoap.org/wsdl/" targetNamespace="http://ws.scrib/" name="DemandeBacWS">
|
||||
<types>
|
||||
<xsd:schema targetNamespace="http://ws.scrib/">
|
||||
<xsd:element name="depot" type="tns:depot"/>
|
||||
<xsd:element name="depotResponse" type="tns:depotResponse"/>
|
||||
<xsd:complexType name="depot">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="demandeBacs" type="tns:demandeBacWsDto" minOccurs="0"/>
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="demandeBacWsDto">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="appartement" type="xsd:string" minOccurs="0"/>
|
||||
<xsd:element name="bac" type="tns:typeNumBacWsDto" nillable="true" minOccurs="0" maxOccurs="unbounded"/>
|
||||
<xsd:element name="batiment" type="xsd:string" minOccurs="0"/>
|
||||
<xsd:element name="codeCivel" type="xsd:string" minOccurs="0"/>
|
||||
<xsd:element name="codeCommune" type="xsd:string" minOccurs="0"/>
|
||||
<xsd:element name="codePostal" type="xsd:string" minOccurs="0"/>
|
||||
<xsd:element name="codeSecteurTrisac" type="xsd:string" minOccurs="0"/>
|
||||
<xsd:element name="commentaires" type="xsd:string" minOccurs="0"/>
|
||||
<xsd:element name="commune" type="xsd:string" minOccurs="0"/>
|
||||
<xsd:element name="complementVoie" type="xsd:string" minOccurs="0"/>
|
||||
<xsd:element name="email" type="xsd:string" minOccurs="0"/>
|
||||
<xsd:element name="etage" type="xsd:string" minOccurs="0"/>
|
||||
<xsd:element name="jourCollecte" type="xsd:string" minOccurs="0"/>
|
||||
<xsd:element name="libelleVoie" type="xsd:string" minOccurs="0"/>
|
||||
<xsd:element name="mention" type="xsd:string" minOccurs="0"/>
|
||||
<xsd:element name="natureDemande" type="tns:natureDemande" minOccurs="0"/>
|
||||
<xsd:element name="natureDemandeur" type="tns:natureDemandeur" minOccurs="0"/>
|
||||
<xsd:element name="nom" type="xsd:string" minOccurs="0"/>
|
||||
<xsd:element name="nomAssociation" type="xsd:string" minOccurs="0"/>
|
||||
<xsd:element name="nomCommercial" type="xsd:string" minOccurs="0"/>
|
||||
<xsd:element name="nombrePersonnesFoyer" type="xsd:short" minOccurs="0"/>
|
||||
<xsd:element name="numeroVoie" type="xsd:int" minOccurs="0"/>
|
||||
<xsd:element name="prenom" type="xsd:string" minOccurs="0"/>
|
||||
<xsd:element name="raisonDemande" type="tns:raisonDemande" minOccurs="0"/>
|
||||
<xsd:element name="raisonSociale" type="xsd:string" minOccurs="0"/>
|
||||
<xsd:element name="sigle" type="xsd:string" minOccurs="0"/>
|
||||
<xsd:element name="telephone" type="xsd:string" minOccurs="0"/>
|
||||
<xsd:element name="typeDegradation" type="tns:typeDegradation" minOccurs="0"/>
|
||||
<xsd:element name="typeHabitat" type="tns:typeHabitat" minOccurs="0"/>
|
||||
<xsd:element name="urlPublik" type="xsd:string" minOccurs="0"/>
|
||||
<xsd:element name="usageBac" type="tns:usageBac" minOccurs="0"/>
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="typeNumBacWsDto">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="bacCollecteDechetsMenagers" type="xsd:boolean" minOccurs="0"/>
|
||||
<xsd:element name="bacCollectePapierCarton" type="xsd:boolean" minOccurs="0"/>
|
||||
<xsd:element name="bacCollecteSelective" type="xsd:boolean" minOccurs="0"/>
|
||||
<xsd:element name="bacCollecteVerre" type="xsd:boolean" minOccurs="0"/>
|
||||
<xsd:element name="numBacCollecteDechetsMenagers" type="xsd:string" minOccurs="0"/>
|
||||
<xsd:element name="numBacCollectePapierCarton" type="xsd:string" minOccurs="0"/>
|
||||
<xsd:element name="numBacCollecteSelective" type="xsd:string" minOccurs="0"/>
|
||||
<xsd:element name="numBacCollecteVerre" type="xsd:string" minOccurs="0"/>
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="depotResponse">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="return" type="tns:demandeBacWsRetour" minOccurs="0"/>
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="demandeBacWsRetour">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="codeErreur" type="tns:codeErreur" minOccurs="0"/>
|
||||
<xsd:element name="codeRetour" type="xsd:boolean"/>
|
||||
<xsd:element name="messageErreur" type="xsd:string" minOccurs="0"/>
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
<xsd:simpleType name="natureDemande">
|
||||
<xsd:restriction base="xsd:string">
|
||||
<xsd:enumeration value="DDOT"/>
|
||||
<xsd:enumeration value="DREN"/>
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
<xsd:simpleType name="natureDemandeur">
|
||||
<xsd:restriction base="xsd:string">
|
||||
<xsd:enumeration value="NPAR"/>
|
||||
<xsd:enumeration value="NPRO"/>
|
||||
<xsd:enumeration value="NASS"/>
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
<xsd:simpleType name="raisonDemande">
|
||||
<xsd:restriction base="xsd:string">
|
||||
<xsd:enumeration value="BVOL"/>
|
||||
<xsd:enumeration value="BDEG"/>
|
||||
<xsd:enumeration value="BBRU"/>
|
||||
<xsd:enumeration value="BAJU"/>
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
<xsd:simpleType name="typeDegradation">
|
||||
<xsd:restriction base="xsd:string">
|
||||
<xsd:enumeration value="TDRO"/>
|
||||
<xsd:enumeration value="TDCU"/>
|
||||
<xsd:enumeration value="TDCO"/>
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
<xsd:simpleType name="typeHabitat">
|
||||
<xsd:restriction base="xsd:string">
|
||||
<xsd:enumeration value="HCOL"/>
|
||||
<xsd:enumeration value="HIND"/>
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
<xsd:simpleType name="usageBac">
|
||||
<xsd:restriction base="xsd:string">
|
||||
<xsd:enumeration value="UPRO"/>
|
||||
<xsd:enumeration value="UPRI"/>
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
<xsd:simpleType name="codeErreur">
|
||||
<xsd:restriction base="xsd:string">
|
||||
<xsd:enumeration value="ERR_TECH"/>
|
||||
<xsd:enumeration value="ERR_FORMAT"/>
|
||||
<xsd:enumeration value="ERR_FONC"/>
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
</xsd:schema>
|
||||
</types>
|
||||
<message name="depot">
|
||||
<part name="parameters" element="tns:depot"/>
|
||||
</message>
|
||||
<message name="depotResponse">
|
||||
<part name="parameters" element="tns:depotResponse"/>
|
||||
</message>
|
||||
<portType name="DemandeBacWS">
|
||||
<operation name="depot">
|
||||
<input wsam:Action="http://ws.scrib/DemandeBacWS/depotRequest" message="tns:depot"/>
|
||||
<output wsam:Action="http://ws.scrib/DemandeBacWS/depotResponse" message="tns:depotResponse"/>
|
||||
</operation>
|
||||
</portType>
|
||||
<binding name="DemandeBacWSPortBinding" type="tns:DemandeBacWS">
|
||||
<soap:binding transport="http://schemas.xmlsoap.org/soap/http" style="document"/>
|
||||
<operation name="depot">
|
||||
<soap:operation soapAction=""/>
|
||||
<input>
|
||||
<soap:body use="literal"/>
|
||||
</input>
|
||||
<output>
|
||||
<soap:body use="literal"/>
|
||||
</output>
|
||||
</operation>
|
||||
</binding>
|
||||
<service name="DemandeBacWS">
|
||||
<port name="DemandeBacWSPort" binding="tns:DemandeBacWSPortBinding">
|
||||
<soap:address location="http://scrib.example.net/scrib2/ws/demandeBac"/>
|
||||
</port>
|
||||
</service>
|
||||
</definitions>
|
|
@ -0,0 +1,466 @@
|
|||
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
|
||||
<soap:Body>
|
||||
<ns2:getPersonScheduleListResponse xmlns:ns2="activity.ws.maelis.sigec.com" xmlns:ns3="bean.persistence.activity.ws.maelis.sigec.com" xmlns:ns4="bean.persistence.school.ws.maelis.sigec.com">
|
||||
<resultBean>
|
||||
<personScheduleList>
|
||||
<person>
|
||||
<numPerson>261768</numPerson>
|
||||
<lastname>NICO</lastname>
|
||||
<firstname>BART</firstname>
|
||||
</person>
|
||||
<activityScheduleList>
|
||||
<activity>
|
||||
<idAct>A10049327682</idAct>
|
||||
<libelle>RESTAURATION SCOLAIRE 22/23</libelle>
|
||||
<activityType>
|
||||
<code>RESTSCOL</code>
|
||||
<libelle>Restauration scolaire</libelle>
|
||||
<natureSpec>
|
||||
<code>R</code>
|
||||
<libelle>Restauration Scolaire</libelle>
|
||||
</natureSpec>
|
||||
</activityType>
|
||||
</activity>
|
||||
<weeklyCalendar>
|
||||
<yearCalendar>2023</yearCalendar>
|
||||
<dayWeekInfoList>
|
||||
<dayNum>1</dayNum>
|
||||
<isOpen>false</isOpen>
|
||||
</dayWeekInfoList>
|
||||
<dayWeekInfoList>
|
||||
<dayNum>2</dayNum>
|
||||
<isOpen>false</isOpen>
|
||||
</dayWeekInfoList>
|
||||
<dayWeekInfoList>
|
||||
<dayNum>3</dayNum>
|
||||
<isOpen>false</isOpen>
|
||||
</dayWeekInfoList>
|
||||
<dayWeekInfoList>
|
||||
<dayNum>4</dayNum>
|
||||
<isOpen>false</isOpen>
|
||||
</dayWeekInfoList>
|
||||
<dayWeekInfoList>
|
||||
<dayNum>5</dayNum>
|
||||
<isOpen>false</isOpen>
|
||||
</dayWeekInfoList>
|
||||
<dayWeekInfoList>
|
||||
<dayNum>6</dayNum>
|
||||
<isOpen>false</isOpen>
|
||||
</dayWeekInfoList>
|
||||
<dayWeekInfoList>
|
||||
<dayNum>7</dayNum>
|
||||
<isOpen>false</isOpen>
|
||||
</dayWeekInfoList>
|
||||
</weeklyCalendar>
|
||||
<unitScheduleList>
|
||||
<unit>
|
||||
<idUnit>A10049355140</idUnit>
|
||||
<libelle>PAI PANIER 22/23</libelle>
|
||||
<calendarLetter>B</calendarLetter>
|
||||
</unit>
|
||||
<datePrevMin>2023-03-27T00:00:00+02:00</datePrevMin>
|
||||
<dayInfoList>
|
||||
<day>2023-04-01T00:00:00+02:00</day>
|
||||
<scheduledPresence>0</scheduledPresence>
|
||||
<realPresence>0</realPresence>
|
||||
<ns3:status>NO_READ</ns3:status>
|
||||
</dayInfoList>
|
||||
<dayInfoList>
|
||||
<day>2023-04-02T00:00:00+02:00</day>
|
||||
<scheduledPresence>0</scheduledPresence>
|
||||
<realPresence>0</realPresence>
|
||||
<ns3:status>NO_READ</ns3:status>
|
||||
</dayInfoList>
|
||||
<dayInfoList>
|
||||
<day>2023-04-03T00:00:00+02:00</day>
|
||||
<scheduledPresence>0</scheduledPresence>
|
||||
<realPresence>0</realPresence>
|
||||
<ns3:status>WRITABLE</ns3:status>
|
||||
<ns3:action>ADD_PRES_PREVI</ns3:action>
|
||||
</dayInfoList>
|
||||
<dayInfoList>
|
||||
<day>2023-04-04T00:00:00+02:00</day>
|
||||
<scheduledPresence>0</scheduledPresence>
|
||||
<realPresence>0</realPresence>
|
||||
<ns3:status>WRITABLE</ns3:status>
|
||||
<ns3:action>ADD_PRES_PREVI</ns3:action>
|
||||
</dayInfoList>
|
||||
<dayInfoList>
|
||||
<day>2023-04-05T00:00:00+02:00</day>
|
||||
<scheduledPresence>0</scheduledPresence>
|
||||
<realPresence>0</realPresence>
|
||||
<ns3:status>NO_READ</ns3:status>
|
||||
</dayInfoList>
|
||||
<dayInfoList>
|
||||
<day>2023-04-06T00:00:00+02:00</day>
|
||||
<scheduledPresence>0</scheduledPresence>
|
||||
<realPresence>0</realPresence>
|
||||
<ns3:status>WRITABLE</ns3:status>
|
||||
<ns3:action>ADD_PRES_PREVI</ns3:action>
|
||||
</dayInfoList>
|
||||
<dayInfoList>
|
||||
<day>2023-04-07T00:00:00+02:00</day>
|
||||
<scheduledPresence>0</scheduledPresence>
|
||||
<realPresence>0</realPresence>
|
||||
<ns3:status>WRITABLE</ns3:status>
|
||||
<ns3:action>ADD_PRES_PREVI</ns3:action>
|
||||
</dayInfoList>
|
||||
<dayInfoList>
|
||||
<day>2023-04-08T00:00:00+02:00</day>
|
||||
<scheduledPresence>0</scheduledPresence>
|
||||
<realPresence>0</realPresence>
|
||||
<ns3:status>NO_READ</ns3:status>
|
||||
</dayInfoList>
|
||||
<dayInfoList>
|
||||
<day>2023-04-09T00:00:00+02:00</day>
|
||||
<scheduledPresence>0</scheduledPresence>
|
||||
<realPresence>0</realPresence>
|
||||
<ns3:status>NO_READ</ns3:status>
|
||||
</dayInfoList>
|
||||
<dayInfoList>
|
||||
<day>2023-04-10T00:00:00+02:00</day>
|
||||
<scheduledPresence>0</scheduledPresence>
|
||||
<realPresence>0</realPresence>
|
||||
<ns3:status>NO_READ</ns3:status>
|
||||
</dayInfoList>
|
||||
<dayInfoList>
|
||||
<day>2023-04-11T00:00:00+02:00</day>
|
||||
<scheduledPresence>0</scheduledPresence>
|
||||
<realPresence>0</realPresence>
|
||||
<ns3:status>WRITABLE</ns3:status>
|
||||
<ns3:action>ADD_PRES_PREVI</ns3:action>
|
||||
</dayInfoList>
|
||||
<dayInfoList>
|
||||
<day>2023-04-12T00:00:00+02:00</day>
|
||||
<scheduledPresence>0</scheduledPresence>
|
||||
<realPresence>0</realPresence>
|
||||
<ns3:status>NO_READ</ns3:status>
|
||||
</dayInfoList>
|
||||
<dayInfoList>
|
||||
<day>2023-04-13T00:00:00+02:00</day>
|
||||
<scheduledPresence>0</scheduledPresence>
|
||||
<realPresence>0</realPresence>
|
||||
<ns3:status>WRITABLE</ns3:status>
|
||||
<ns3:action>ADD_PRES_PREVI</ns3:action>
|
||||
</dayInfoList>
|
||||
<dayInfoList>
|
||||
<day>2023-04-14T00:00:00+02:00</day>
|
||||
<scheduledPresence>0</scheduledPresence>
|
||||
<realPresence>0</realPresence>
|
||||
<ns3:status>WRITABLE</ns3:status>
|
||||
<ns3:action>ADD_PRES_PREVI</ns3:action>
|
||||
</dayInfoList>
|
||||
<dayInfoList>
|
||||
<day>2023-04-15T00:00:00+02:00</day>
|
||||
<scheduledPresence>0</scheduledPresence>
|
||||
<realPresence>0</realPresence>
|
||||
<ns3:status>NO_READ</ns3:status>
|
||||
</dayInfoList>
|
||||
<dayInfoList>
|
||||
<day>2023-04-16T00:00:00+02:00</day>
|
||||
<scheduledPresence>0</scheduledPresence>
|
||||
<realPresence>0</realPresence>
|
||||
<ns3:status>NO_READ</ns3:status>
|
||||
</dayInfoList>
|
||||
<dayInfoList>
|
||||
<day>2023-04-17T00:00:00+02:00</day>
|
||||
<scheduledPresence>0</scheduledPresence>
|
||||
<realPresence>0</realPresence>
|
||||
<ns3:status>WRITABLE</ns3:status>
|
||||
<ns3:action>ADD_PRES_PREVI</ns3:action>
|
||||
</dayInfoList>
|
||||
<dayInfoList>
|
||||
<day>2023-04-18T00:00:00+02:00</day>
|
||||
<scheduledPresence>0</scheduledPresence>
|
||||
<realPresence>0</realPresence>
|
||||
<ns3:status>WRITABLE</ns3:status>
|
||||
<ns3:action>ADD_PRES_PREVI</ns3:action>
|
||||
</dayInfoList>
|
||||
<dayInfoList>
|
||||
<day>2023-04-19T00:00:00+02:00</day>
|
||||
<scheduledPresence>0</scheduledPresence>
|
||||
<realPresence>0</realPresence>
|
||||
<ns3:status>NO_READ</ns3:status>
|
||||
</dayInfoList>
|
||||
<dayInfoList>
|
||||
<day>2023-04-20T00:00:00+02:00</day>
|
||||
<scheduledPresence>0</scheduledPresence>
|
||||
<realPresence>0</realPresence>
|
||||
<ns3:status>WRITABLE</ns3:status>
|
||||
<ns3:action>ADD_PRES_PREVI</ns3:action>
|
||||
</dayInfoList>
|
||||
<dayInfoList>
|
||||
<day>2023-04-21T00:00:00+02:00</day>
|
||||
<scheduledPresence>0</scheduledPresence>
|
||||
<realPresence>0</realPresence>
|
||||
<ns3:status>WRITABLE</ns3:status>
|
||||
<ns3:action>ADD_PRES_PREVI</ns3:action>
|
||||
</dayInfoList>
|
||||
<dayInfoList>
|
||||
<day>2023-04-22T00:00:00+02:00</day>
|
||||
<scheduledPresence>0</scheduledPresence>
|
||||
<realPresence>0</realPresence>
|
||||
<ns3:status>NO_READ</ns3:status>
|
||||
</dayInfoList>
|
||||
<dayInfoList>
|
||||
<day>2023-04-23T00:00:00+02:00</day>
|
||||
<scheduledPresence>0</scheduledPresence>
|
||||
<realPresence>0</realPresence>
|
||||
<ns3:status>NO_READ</ns3:status>
|
||||
</dayInfoList>
|
||||
<dayInfoList>
|
||||
<day>2023-04-24T00:00:00+02:00</day>
|
||||
<scheduledPresence>0</scheduledPresence>
|
||||
<realPresence>0</realPresence>
|
||||
<ns3:status>WRITABLE</ns3:status>
|
||||
<ns3:action>ADD_PRES_PREVI</ns3:action>
|
||||
</dayInfoList>
|
||||
<dayInfoList>
|
||||
<day>2023-04-25T00:00:00+02:00</day>
|
||||
<scheduledPresence>0</scheduledPresence>
|
||||
<realPresence>0</realPresence>
|
||||
<ns3:status>WRITABLE</ns3:status>
|
||||
<ns3:action>ADD_PRES_PREVI</ns3:action>
|
||||
</dayInfoList>
|
||||
<dayInfoList>
|
||||
<day>2023-04-26T00:00:00+02:00</day>
|
||||
<scheduledPresence>0</scheduledPresence>
|
||||
<realPresence>0</realPresence>
|
||||
<ns3:status>NO_READ</ns3:status>
|
||||
</dayInfoList>
|
||||
<dayInfoList>
|
||||
<day>2023-04-27T00:00:00+02:00</day>
|
||||
<scheduledPresence>0</scheduledPresence>
|
||||
<realPresence>0</realPresence>
|
||||
<ns3:status>WRITABLE</ns3:status>
|
||||
<ns3:action>ADD_PRES_PREVI</ns3:action>
|
||||
</dayInfoList>
|
||||
<dayInfoList>
|
||||
<day>2023-04-28T00:00:00+02:00</day>
|
||||
<scheduledPresence>0</scheduledPresence>
|
||||
<realPresence>0</realPresence>
|
||||
<ns3:status>WRITABLE</ns3:status>
|
||||
<ns3:action>ADD_PRES_PREVI</ns3:action>
|
||||
</dayInfoList>
|
||||
<dayInfoList>
|
||||
<day>2023-04-29T00:00:00+02:00</day>
|
||||
<scheduledPresence>0</scheduledPresence>
|
||||
<realPresence>0</realPresence>
|
||||
<ns3:status>NO_READ</ns3:status>
|
||||
</dayInfoList>
|
||||
<dayInfoList>
|
||||
<day>2023-04-30T00:00:00+02:00</day>
|
||||
<scheduledPresence>0</scheduledPresence>
|
||||
<realPresence>0</realPresence>
|
||||
<ns3:status>NO_READ</ns3:status>
|
||||
</dayInfoList>
|
||||
</unitScheduleList>
|
||||
<unitScheduleList>
|
||||
<unit>
|
||||
<idUnit>A10049327683</idUnit>
|
||||
<libelle>RESTAURATION SCOLAIRE 22/23</libelle>
|
||||
<calendarLetter>X</calendarLetter>
|
||||
</unit>
|
||||
<datePrevMin>2023-03-27T00:00:00+02:00</datePrevMin>
|
||||
<dayInfoList>
|
||||
<day>2023-04-01T00:00:00+02:00</day>
|
||||
<scheduledPresence>0</scheduledPresence>
|
||||
<realPresence>0</realPresence>
|
||||
<ns3:status>NO_READ</ns3:status>
|
||||
</dayInfoList>
|
||||
<dayInfoList>
|
||||
<day>2023-04-02T00:00:00+02:00</day>
|
||||
<scheduledPresence>0</scheduledPresence>
|
||||
<realPresence>0</realPresence>
|
||||
<ns3:status>NO_READ</ns3:status>
|
||||
</dayInfoList>
|
||||
<dayInfoList>
|
||||
<day>2023-04-03T00:00:00+02:00</day>
|
||||
<scheduledPresence>1</scheduledPresence>
|
||||
<realPresence>0</realPresence>
|
||||
<ns3:status>WRITABLE</ns3:status>
|
||||
<ns3:action>DEL_PRES_PREVI</ns3:action>
|
||||
</dayInfoList>
|
||||
<dayInfoList>
|
||||
<day>2023-04-04T00:00:00+02:00</day>
|
||||
<scheduledPresence>1</scheduledPresence>
|
||||
<realPresence>0</realPresence>
|
||||
<ns3:status>WRITABLE</ns3:status>
|
||||
<ns3:action>DEL_PRES_PREVI</ns3:action>
|
||||
</dayInfoList>
|
||||
<dayInfoList>
|
||||
<day>2023-04-05T00:00:00+02:00</day>
|
||||
<scheduledPresence>0</scheduledPresence>
|
||||
<realPresence>0</realPresence>
|
||||
<ns3:status>NO_READ</ns3:status>
|
||||
</dayInfoList>
|
||||
<dayInfoList>
|
||||
<day>2023-04-06T00:00:00+02:00</day>
|
||||
<scheduledPresence>1</scheduledPresence>
|
||||
<realPresence>0</realPresence>
|
||||
<ns3:status>WRITABLE</ns3:status>
|
||||
<ns3:action>DEL_PRES_PREVI</ns3:action>
|
||||
</dayInfoList>
|
||||
<dayInfoList>
|
||||
<day>2023-04-07T00:00:00+02:00</day>
|
||||
<scheduledPresence>1</scheduledPresence>
|
||||
<realPresence>0</realPresence>
|
||||
<ns3:status>WRITABLE</ns3:status>
|
||||
<ns3:action>DEL_PRES_PREVI</ns3:action>
|
||||
</dayInfoList>
|
||||
<dayInfoList>
|
||||
<day>2023-04-08T00:00:00+02:00</day>
|
||||
<scheduledPresence>0</scheduledPresence>
|
||||
<realPresence>0</realPresence>
|
||||
<ns3:status>NO_READ</ns3:status>
|
||||
</dayInfoList>
|
||||
<dayInfoList>
|
||||
<day>2023-04-09T00:00:00+02:00</day>
|
||||
<scheduledPresence>0</scheduledPresence>
|
||||
<realPresence>0</realPresence>
|
||||
<ns3:status>NO_READ</ns3:status>
|
||||
</dayInfoList>
|
||||
<dayInfoList>
|
||||
<day>2023-04-10T00:00:00+02:00</day>
|
||||
<scheduledPresence>0</scheduledPresence>
|
||||
<realPresence>0</realPresence>
|
||||
<ns3:status>NO_READ</ns3:status>
|
||||
</dayInfoList>
|
||||
<dayInfoList>
|
||||
<day>2023-04-11T00:00:00+02:00</day>
|
||||
<scheduledPresence>1</scheduledPresence>
|
||||
<realPresence>0</realPresence>
|
||||
<ns3:status>WRITABLE</ns3:status>
|
||||
<ns3:action>DEL_PRES_PREVI</ns3:action>
|
||||
</dayInfoList>
|
||||
<dayInfoList>
|
||||
<day>2023-04-12T00:00:00+02:00</day>
|
||||
<scheduledPresence>0</scheduledPresence>
|
||||
<realPresence>0</realPresence>
|
||||
<ns3:status>NO_READ</ns3:status>
|
||||
</dayInfoList>
|
||||
<dayInfoList>
|
||||
<day>2023-04-13T00:00:00+02:00</day>
|
||||
<scheduledPresence>1</scheduledPresence>
|
||||
<realPresence>0</realPresence>
|
||||
<ns3:status>WRITABLE</ns3:status>
|
||||
<ns3:action>DEL_PRES_PREVI</ns3:action>
|
||||
</dayInfoList>
|
||||
<dayInfoList>
|
||||
<day>2023-04-14T00:00:00+02:00</day>
|
||||
<scheduledPresence>1</scheduledPresence>
|
||||
<realPresence>0</realPresence>
|
||||
<ns3:status>WRITABLE</ns3:status>
|
||||
<ns3:action>DEL_PRES_PREVI</ns3:action>
|
||||
</dayInfoList>
|
||||
<dayInfoList>
|
||||
<day>2023-04-15T00:00:00+02:00</day>
|
||||
<scheduledPresence>0</scheduledPresence>
|
||||
<realPresence>0</realPresence>
|
||||
<ns3:status>NO_READ</ns3:status>
|
||||
</dayInfoList>
|
||||
<dayInfoList>
|
||||
<day>2023-04-16T00:00:00+02:00</day>
|
||||
<scheduledPresence>0</scheduledPresence>
|
||||
<realPresence>0</realPresence>
|
||||
<ns3:status>NO_READ</ns3:status>
|
||||
</dayInfoList>
|
||||
<dayInfoList>
|
||||
<day>2023-04-17T00:00:00+02:00</day>
|
||||
<scheduledPresence>1</scheduledPresence>
|
||||
<realPresence>0</realPresence>
|
||||
<ns3:status>WRITABLE</ns3:status>
|
||||
<ns3:action>DEL_PRES_PREVI</ns3:action>
|
||||
</dayInfoList>
|
||||
<dayInfoList>
|
||||
<day>2023-04-18T00:00:00+02:00</day>
|
||||
<scheduledPresence>1</scheduledPresence>
|
||||
<realPresence>0</realPresence>
|
||||
<ns3:status>WRITABLE</ns3:status>
|
||||
<ns3:action>DEL_PRES_PREVI</ns3:action>
|
||||
</dayInfoList>
|
||||
<dayInfoList>
|
||||
<day>2023-04-19T00:00:00+02:00</day>
|
||||
<scheduledPresence>0</scheduledPresence>
|
||||
<realPresence>0</realPresence>
|
||||
<ns3:status>NO_READ</ns3:status>
|
||||
</dayInfoList>
|
||||
<dayInfoList>
|
||||
<day>2023-04-20T00:00:00+02:00</day>
|
||||
<scheduledPresence>1</scheduledPresence>
|
||||
<realPresence>0</realPresence>
|
||||
<ns3:status>WRITABLE</ns3:status>
|
||||
<ns3:action>DEL_PRES_PREVI</ns3:action>
|
||||
</dayInfoList>
|
||||
<dayInfoList>
|
||||
<day>2023-04-21T00:00:00+02:00</day>
|
||||
<scheduledPresence>1</scheduledPresence>
|
||||
<realPresence>0</realPresence>
|
||||
<ns3:status>WRITABLE</ns3:status>
|
||||
<ns3:action>DEL_PRES_PREVI</ns3:action>
|
||||
</dayInfoList>
|
||||
<dayInfoList>
|
||||
<day>2023-04-22T00:00:00+02:00</day>
|
||||
<scheduledPresence>0</scheduledPresence>
|
||||
<realPresence>0</realPresence>
|
||||
<ns3:status>NO_READ</ns3:status>
|
||||
</dayInfoList>
|
||||
<dayInfoList>
|
||||
<day>2023-04-23T00:00:00+02:00</day>
|
||||
<scheduledPresence>0</scheduledPresence>
|
||||
<realPresence>0</realPresence>
|
||||
<ns3:status>NO_READ</ns3:status>
|
||||
</dayInfoList>
|
||||
<dayInfoList>
|
||||
<day>2023-04-24T00:00:00+02:00</day>
|
||||
<scheduledPresence>1</scheduledPresence>
|
||||
<realPresence>0</realPresence>
|
||||
<ns3:status>WRITABLE</ns3:status>
|
||||
<ns3:action>DEL_PRES_PREVI</ns3:action>
|
||||
</dayInfoList>
|
||||
<dayInfoList>
|
||||
<day>2023-04-25T00:00:00+02:00</day>
|
||||
<scheduledPresence>1</scheduledPresence>
|
||||
<realPresence>0</realPresence>
|
||||
<ns3:status>WRITABLE</ns3:status>
|
||||
<ns3:action>DEL_PRES_PREVI</ns3:action>
|
||||
</dayInfoList>
|
||||
<dayInfoList>
|
||||
<day>2023-04-26T00:00:00+02:00</day>
|
||||
<scheduledPresence>0</scheduledPresence>
|
||||
<realPresence>0</realPresence>
|
||||
<ns3:status>NO_READ</ns3:status>
|
||||
</dayInfoList>
|
||||
<dayInfoList>
|
||||
<day>2023-04-27T00:00:00+02:00</day>
|
||||
<scheduledPresence>1</scheduledPresence>
|
||||
<realPresence>0</realPresence>
|
||||
<ns3:status>WRITABLE</ns3:status>
|
||||
<ns3:action>DEL_PRES_PREVI</ns3:action>
|
||||
</dayInfoList>
|
||||
<dayInfoList>
|
||||
<day>2023-04-28T00:00:00+02:00</day>
|
||||
<scheduledPresence>1</scheduledPresence>
|
||||
<realPresence>0</realPresence>
|
||||
<ns3:status>WRITABLE</ns3:status>
|
||||
<ns3:action>DEL_PRES_PREVI</ns3:action>
|
||||
</dayInfoList>
|
||||
<dayInfoList>
|
||||
<day>2023-04-29T00:00:00+02:00</day>
|
||||
<scheduledPresence>0</scheduledPresence>
|
||||
<realPresence>0</realPresence>
|
||||
<ns3:status>NO_READ</ns3:status>
|
||||
</dayInfoList>
|
||||
<dayInfoList>
|
||||
<day>2023-04-30T00:00:00+02:00</day>
|
||||
<scheduledPresence>0</scheduledPresence>
|
||||
<realPresence>0</realPresence>
|
||||
<ns3:status>NO_READ</ns3:status>
|
||||
</dayInfoList>
|
||||
</unitScheduleList>
|
||||
</activityScheduleList>
|
||||
</personScheduleList>
|
||||
</resultBean>
|
||||
</ns2:getPersonScheduleListResponse>
|
||||
</soap:Body>
|
||||
</soap:Envelope>
|
|
@ -172,6 +172,8 @@
|
|||
<libelle>Vitrail Fusing 1/2 Je Adultes 2022/2023 - Mardi 14h-17h</libelle>
|
||||
<dateStart>2022-09-01T00:00:00+02:00</dateStart>
|
||||
<dateEnd>2023-06-30T00:00:00+02:00</dateEnd>
|
||||
<birthDateStart>2010-01-01T00:00:00+01:00</birthDateStart>
|
||||
<birthDateEnd>2017-12-31T00:00:00+01:00</birthDateEnd>
|
||||
<calendarLetter>X</calendarLetter>
|
||||
<subscribePublication>L</subscribePublication>
|
||||
<numOrder>0</numOrder>
|
||||
|
@ -866,6 +868,92 @@
|
|||
</placeList>
|
||||
</unitPortailList>
|
||||
</activityUnitPlacePortailList>
|
||||
<activityUnitPlacePortailList>
|
||||
<activityPortail>
|
||||
<idAct>A10056517599</idAct>
|
||||
<libelle>TEST promenade forêt enchantée</libelle>
|
||||
<libelle2>Promenade forêt enchantée</libelle2>
|
||||
<blocNoteList>
|
||||
<note>Activité senior du 15 au 16 juin 2023</note>
|
||||
<numIndex>1</numIndex>
|
||||
</blocNoteList>
|
||||
<idService>plop</idService>
|
||||
<dateStart>2023-06-15T00:00:00+02:00</dateStart>
|
||||
<dateEnd>2023-06-16T00:00:00+02:00</dateEnd>
|
||||
<birthControl>B</birthControl>
|
||||
<schoolYear>2022</schoolYear>
|
||||
<calendarGeneration>
|
||||
<code>FORBIDDEN</code>
|
||||
<value>I</value>
|
||||
</calendarGeneration>
|
||||
<calendarMode>N</calendarMode>
|
||||
<activityType>
|
||||
<code>1-APE</code>
|
||||
<libelle>Activité Pédestre Activité régulière</libelle>
|
||||
<natureSpec>
|
||||
<code>1</code>
|
||||
<libelle>Activités Régulières</libelle>
|
||||
</natureSpec>
|
||||
</activityType>
|
||||
<weeklyCalendarActivityList>
|
||||
<yearCalendar>2023</yearCalendar>
|
||||
<dayWeekInfoList>
|
||||
<dayNum>1</dayNum>
|
||||
<isOpen>true</isOpen>
|
||||
</dayWeekInfoList>
|
||||
<dayWeekInfoList>
|
||||
<dayNum>2</dayNum>
|
||||
<isOpen>true</isOpen>
|
||||
</dayWeekInfoList>
|
||||
<dayWeekInfoList>
|
||||
<dayNum>3</dayNum>
|
||||
<isOpen>true</isOpen>
|
||||
</dayWeekInfoList>
|
||||
<dayWeekInfoList>
|
||||
<dayNum>4</dayNum>
|
||||
<isOpen>true</isOpen>
|
||||
</dayWeekInfoList>
|
||||
<dayWeekInfoList>
|
||||
<dayNum>5</dayNum>
|
||||
<isOpen>true</isOpen>
|
||||
</dayWeekInfoList>
|
||||
<dayWeekInfoList>
|
||||
<dayNum>6</dayNum>
|
||||
<isOpen>false</isOpen>
|
||||
</dayWeekInfoList>
|
||||
<dayWeekInfoList>
|
||||
<dayNum>7</dayNum>
|
||||
<isOpen>false</isOpen>
|
||||
</dayWeekInfoList>
|
||||
</weeklyCalendarActivityList>
|
||||
</activityPortail>
|
||||
<openDayList>2023-06-15T00:00:00+02:00</openDayList>
|
||||
<openDayList>2023-06-16T00:00:00+02:00</openDayList>
|
||||
<unitPortailList>
|
||||
<idUnit>A10056517596</idUnit>
|
||||
<libelle>TEST promenade forêt enchantée</libelle>
|
||||
<codeExt>A</codeExt>
|
||||
<dateStart>2023-06-15T00:00:00+02:00</dateStart>
|
||||
<dateEnd>2023-06-16T00:00:00+02:00</dateEnd>
|
||||
<birthDateStart>1900-01-01T00:00:00+01:00</birthDateStart>
|
||||
<birthDateEnd>1963-12-31T00:00:00+01:00</birthDateEnd>
|
||||
<calendarLetter>X</calendarLetter>
|
||||
<subscribePublication>E</subscribePublication>
|
||||
<numOrder>0</numOrder>
|
||||
<calendarPublication>N</calendarPublication>
|
||||
<recordAbsence>O</recordAbsence>
|
||||
<placeList>
|
||||
<id>A10056517597</id>
|
||||
<lib>TERRITOIRE OUEST</lib>
|
||||
<adresse>
|
||||
<num>0</num>
|
||||
</adresse>
|
||||
<capacityInfo>
|
||||
<controlOK>true</controlOK>
|
||||
</capacityInfo>
|
||||
</placeList>
|
||||
</unitPortailList>
|
||||
</activityUnitPlacePortailList>
|
||||
</ReadActivityPortailListResultBean>
|
||||
</ns2:readActivityListResponse>
|
||||
</soap:Body>
|
||||
|
|
|
@ -30,6 +30,7 @@ INSTALLED_APPS += ( # noqa pylint: disable=undefined-variable
|
|||
'passerelle.contrib.lille_urban_card',
|
||||
'passerelle.contrib.mdph13',
|
||||
'passerelle.contrib.nancypoll',
|
||||
'passerelle.contrib.nantes_scrib',
|
||||
'passerelle.contrib.planitech',
|
||||
'passerelle.contrib.rsa13',
|
||||
'passerelle.contrib.sigerly',
|
||||
|
|
|
@ -787,7 +787,7 @@ def test_search_tiers_by_rib(mocked_post, mocked_get, connector, app):
|
|||
for item in resp.json['data']:
|
||||
assert 'id' in item
|
||||
assert 'text' in item
|
||||
assert '487464' in item['text'] or '144984' in item['text']
|
||||
assert item['text'] in ['FOO (144984)', 'BAR (487464)']
|
||||
|
||||
|
||||
@mock.patch('passerelle.utils.Request.get')
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
import json
|
||||
from unittest import mock
|
||||
|
||||
import pytest
|
||||
import responses
|
||||
from django.contrib.contenttypes.models import ContentType
|
||||
|
||||
from passerelle.apps.matrix42.models import Matrix42
|
||||
|
@ -213,6 +215,15 @@ def test_matrix42_bad_rawtoken(mocked_request, app, matrix42):
|
|||
assert resp.json['err_class'] == 'passerelle.utils.jsonresponse.APIError'
|
||||
assert 'not returned a dict' in resp.json['err_desc']
|
||||
|
||||
# empty response: error when not allowed
|
||||
mocked_request.side_effect = [
|
||||
FakedResponse(content='', status_code=204),
|
||||
]
|
||||
resp = app.get(endpoint, params=params, status=200)
|
||||
assert resp.json['err'] == 1
|
||||
assert resp.json['err_class'] == 'passerelle.utils.jsonresponse.APIError'
|
||||
assert 'returned an empty response' in resp.json['err_desc']
|
||||
|
||||
# Matrix42 error
|
||||
mocked_request.side_effect = [
|
||||
FakedResponse(content='{"ExceptionName":"NotFound","Message":"4o4"}', status_code=404),
|
||||
|
@ -302,3 +313,23 @@ def test_matrix42_object(mocked_request, app, matrix42):
|
|||
'ID': '424242',
|
||||
'SPSActivityClassBase': {'TicketNumber': 'TCK0000153', 'TimeStamp': 'AAAAAAHlWr4='},
|
||||
}
|
||||
|
||||
|
||||
def test_matrix42_generic(app, matrix42):
|
||||
api = ApiUser.objects.create(username='all', keytype='', key='')
|
||||
obj_type = ContentType.objects.get_for_model(matrix42)
|
||||
AccessRight.objects.create(
|
||||
codename='can_access', apiuser=api, resource_type=obj_type, resource_pk=matrix42.pk
|
||||
)
|
||||
endpoint = generic_endpoint_url('matrix42', 'generic', slug=matrix42.slug)
|
||||
|
||||
with responses.RequestsMock() as rsps:
|
||||
rsps.post(
|
||||
'https://matrix42.example.net/api/ApiToken/GenerateAccessTokenFromApiToken',
|
||||
status=200,
|
||||
body=TOKEN,
|
||||
)
|
||||
rsps.post('https://matrix42.example.net/api/ticket/Transform', status=204)
|
||||
resp = app.post_json(endpoint + '/ticket/Transform', params={'foo/bar': 'coin'}, status=200)
|
||||
assert json.loads(rsps.calls[1].request.body) == {'foo': {'bar': 'coin'}}
|
||||
assert resp.json == {'err': 0, 'data': None} # empty response 204 is ok here
|
||||
|
|
|
@ -0,0 +1,157 @@
|
|||
# Copyright (C) 2023 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 os
|
||||
|
||||
import pytest
|
||||
import responses
|
||||
|
||||
import tests.utils
|
||||
from passerelle.contrib.nantes_scrib.models import SOAPScrib
|
||||
|
||||
TEST_BASE_DIR = os.path.join(os.path.dirname(__file__), 'data', 'nantes_scrib')
|
||||
|
||||
RSPS_OK = """<?xml version="1.0" encoding="UTF-8"?>
|
||||
<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
|
||||
<S:Body><ns2:depotResponse xmlns:ns2="http://ws.scrib/">
|
||||
<return><codeRetour>true</codeRetour></return>
|
||||
</ns2:depotResponse></S:Body></S:Envelope>"""
|
||||
|
||||
RSPS_ERR_TECH = """<?xml version="1.0" encoding="UTF-8"?>
|
||||
<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
|
||||
<S:Body><ns2:depotResponse xmlns:ns2="http://ws.scrib/">
|
||||
<return><codeErreur>ERR_TECH</codeErreur><codeRetour>false</codeRetour></return>
|
||||
</ns2:depotResponse></S:Body></S:Envelope>"""
|
||||
|
||||
WCS_WSCALL = {
|
||||
# new request (no numBac)
|
||||
'demandeBacs/bac/0/bacCollecteDechetsMenagers': 'true',
|
||||
'demandeBacs/bac/0/bacCollecteSelective': 'false',
|
||||
'demandeBacs/bac/0/bacCollecteVerre': 'false',
|
||||
'demandeBacs/bac/0/numBacCollecteDechetsMenagers': '',
|
||||
'demandeBacs/bac/0/numBacCollecteSelective': None,
|
||||
# error
|
||||
'demandeBacs/bac/1': 'not-a-dict',
|
||||
# renewal (numBac)
|
||||
'demandeBacs/bac/2/bacCollecteDechetsMenagers': 'false',
|
||||
'demandeBacs/bac/2/bacCollecteSelective': 1,
|
||||
'demandeBacs/bac/2/bacCollecteVerre': 'false',
|
||||
'demandeBacs/bac/2/numBacCollecteDechetsMenagers': '2',
|
||||
'demandeBacs/bac/2/numBacCollecteSelective': '576X9812',
|
||||
# no request (nothing is True)
|
||||
'demandeBacs/bac/3/bacCollecteDechetsMenagers': 'false',
|
||||
'demandeBacs/bac/3/bacCollecteSelective': '',
|
||||
'demandeBacs/bac/3/bacCollecteVerre': 'blah',
|
||||
'demandeBacs/bac/3/numBacCollecteDechetsMenagers': '',
|
||||
'demandeBacs/bac/3/numBacCollecteSelective': None,
|
||||
'demandeBacs/bac/3/numBacCollecteVerre': 0,
|
||||
# others parameters
|
||||
'demandeBacs/codeCivel': '1140206',
|
||||
'demandeBacs/codePostal': '44000',
|
||||
'demandeBacs/commune': 'TestVille',
|
||||
'demandeBacs/email': 'test@example.org',
|
||||
'demandeBacs/libelleVoie': 'Route de Test',
|
||||
'demandeBacs/natureDemande': 'DREN',
|
||||
'demandeBacs/natureDemandeur': 'NPAR',
|
||||
'demandeBacs/nom': 'TESTNOM',
|
||||
'demandeBacs/nombrePersonnesFoyer': ' 2 ',
|
||||
'demandeBacs/numeroVoie': ' 42 ',
|
||||
'demandeBacs/prenom': 'TestPrenom',
|
||||
'demandeBacs/raisonDemande': 'BBRU',
|
||||
'demandeBacs/typeDegradation': 'TDRO',
|
||||
'demandeBacs/telephone': '0707070707',
|
||||
'demandeBacs/typeHabitat': 'HCOL',
|
||||
}
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def wsdl():
|
||||
with open(os.path.join(TEST_BASE_DIR, 'scrib.wsdl'), 'rb') as wsdl_file:
|
||||
return wsdl_file.read()
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def connector(db):
|
||||
return tests.utils.setup_access_rights(
|
||||
SOAPScrib.objects.create(slug='test', wsdl_url='https://scrib.example.net/scrib.wsdl')
|
||||
)
|
||||
|
||||
|
||||
def test_scrib(wsdl, connector, app):
|
||||
with responses.RequestsMock() as rsps:
|
||||
rsps.get('https://scrib.example.net/scrib.wsdl', status=200, content_type='text/xml', body=wsdl)
|
||||
rsps.post(
|
||||
'https://scrib.example.net/scrib2/ws/demandeBac',
|
||||
status=200,
|
||||
content_type='text/xml',
|
||||
body=RSPS_OK,
|
||||
)
|
||||
|
||||
resp = app.post_json('/nantes-scrib/test/depot', params=WCS_WSCALL)
|
||||
xml = rsps.calls[1].request.body.decode('utf-8') # post payload
|
||||
assert resp.json == {
|
||||
'data': {'codeErreur': None, 'codeRetour': True, 'messageErreur': None},
|
||||
'err': 0,
|
||||
}
|
||||
# cleaned "bac" list, only two remains
|
||||
assert xml.count('<bac>') == 2
|
||||
assert '<bac><bacCollecteDechetsMenagers>true</bacCollecteDechetsMenagers></bac>' in xml
|
||||
assert (
|
||||
'<bac><bacCollecteSelective>true</bacCollecteSelective>'
|
||||
'<numBacCollecteSelective>576X9812</numBacCollecteSelective></bac>' in xml
|
||||
)
|
||||
assert '<nombrePersonnesFoyer>2</nombrePersonnesFoyer>' in xml
|
||||
assert '<numeroVoie>42</numeroVoie>' in xml
|
||||
assert '<raisonDemande>BBRU</raisonDemande>' in xml
|
||||
assert '<typeDegradation>TDRO</typeDegradation>' in xml
|
||||
|
||||
# remove empty or non-integers fields
|
||||
WCS_WSCALL['demandeBacs/nombrePersonnesFoyer'] = '0'
|
||||
WCS_WSCALL['demandeBacs/numeroVoie'] = ' '
|
||||
WCS_WSCALL['demandeBacs/raisonDemande'] = ' '
|
||||
WCS_WSCALL['demandeBacs/typeDegradation'] = None
|
||||
resp = app.post_json('/nantes-scrib/test/depot', params=WCS_WSCALL)
|
||||
xml = rsps.calls[2].request.body.decode('utf-8') # post payload
|
||||
assert xml.count('<bac>') == 2
|
||||
assert '<nombrePersonnesFoyer>0</nombrePersonnesFoyer>' in xml
|
||||
assert '<numeroVoie>' not in xml
|
||||
assert '<raisonDemande>' not in xml
|
||||
assert '<typeDegradation>' not in xml
|
||||
|
||||
with responses.RequestsMock() as rsps:
|
||||
rsps.post(
|
||||
'https://scrib.example.net/scrib2/ws/demandeBac', status=200, content_type='text/xml', body='booo'
|
||||
)
|
||||
resp = app.post_json('/nantes-scrib/test/depot', params=WCS_WSCALL)
|
||||
assert resp.json['err'] == 1
|
||||
assert resp.json['err_class'] == 'passerelle.utils.soap.SOAPInvalidContent'
|
||||
|
||||
with responses.RequestsMock() as rsps:
|
||||
resp = app.post_json('/nantes-scrib/test/depot', params={}, status=400)
|
||||
assert resp.json['err'] == 1
|
||||
assert resp.json['err_desc'] == 'missing demandeBacs/bac list'
|
||||
|
||||
with responses.RequestsMock() as rsps:
|
||||
rsps.post(
|
||||
'https://scrib.example.net/scrib2/ws/demandeBac',
|
||||
status=200,
|
||||
content_type='text/xml',
|
||||
body=RSPS_ERR_TECH,
|
||||
)
|
||||
resp = app.post_json('/nantes-scrib/test/depot', params=WCS_WSCALL)
|
||||
assert resp.json == {
|
||||
'data': {'codeErreur': 'ERR_TECH', 'codeRetour': False, 'messageErreur': None},
|
||||
'err': 1,
|
||||
}
|
|
@ -25,6 +25,7 @@ import pytest
|
|||
import responses
|
||||
from django.db import transaction
|
||||
from django.utils.dateparse import parse_date
|
||||
from django.utils.timezone import now
|
||||
from requests.exceptions import ConnectionError, ReadTimeout
|
||||
from zeep import Settings
|
||||
from zeep.helpers import serialize_object
|
||||
|
@ -645,6 +646,13 @@ def test_link(family_service, con, app):
|
|||
assert resp.json['err'] == 0
|
||||
assert resp.json['data'] == 'ok'
|
||||
|
||||
# ignore accents provided by user
|
||||
params['firstname'] = 'Jhôñ'
|
||||
resp = app.post_json(url + '?NameID=local', params=params)
|
||||
assert Link.objects.count() == 1
|
||||
assert resp.json['err'] == 0
|
||||
assert resp.json['data'] == 'ok'
|
||||
|
||||
params['lastname'] = 'John'
|
||||
resp = app.post_json(url + '?NameID=local', params=params)
|
||||
assert Link.objects.count() == 1
|
||||
|
@ -6090,12 +6098,61 @@ def test_get_recurrent_week(family_service, activity_service, con, app):
|
|||
'text': 'Vendredi RESTAURATION SCOLAIRE 22/23',
|
||||
},
|
||||
]
|
||||
assert resp.json['meta'] == {'date_min_prev': '2023-03-27'}
|
||||
assert resp.json['meta'] == {'date_min_prev': '2023-03-27', 'warning_msg': None}
|
||||
|
||||
params['activity_id'] = 'plop'
|
||||
resp = app.get(url + '?NameID=local', params=params)
|
||||
assert resp.json['err'] == 1
|
||||
assert resp.json['err_desc'] == 'No week calendar for activity plop on 2023-04-01'
|
||||
assert resp.json['err_desc'] == "No week calendar for activity 'plop' on 2023-04-01"
|
||||
|
||||
del params['activity_id']
|
||||
resp = app.get(url + '?NameID=local', params=params, status=400)
|
||||
assert resp.json['err'] == 1
|
||||
assert resp.json['err_desc'] == "missing parameters: 'activity_id'."
|
||||
|
||||
# do not raise on calls generated by the form providing 'None' activity
|
||||
params['activity_id'] = 'None'
|
||||
resp = app.get(url + '?NameID=local', params=params)
|
||||
assert resp.json['err'] == 0
|
||||
assert resp.json['data'] == []
|
||||
assert resp.json['meta'] == {
|
||||
'date_min_prev': None,
|
||||
'warning_msg': "No week calendar for activity 'None' on 2023-04-01",
|
||||
}
|
||||
|
||||
|
||||
def test_get_recurrent_week_no_open_day(family_service, activity_service, con, app, caplog, settings):
|
||||
family_service.add_soap_response('readFamily', get_xml_file('R_read_family.xml'))
|
||||
activity_service.add_soap_response(
|
||||
'getPersonScheduleList',
|
||||
get_xml_file('R_get_person_schedule_list_with_recurrent_week_no_open_day.xml'),
|
||||
)
|
||||
url = get_endpoint('get-recurrent-week')
|
||||
params = {
|
||||
'person_id': '613880',
|
||||
'activity_id': 'A10049327682',
|
||||
'ref_date': '2023-04-01',
|
||||
}
|
||||
|
||||
con.set_log_level('DEBUG')
|
||||
ResourceLog.objects.all().delete()
|
||||
resp = app.get(url + '?family_id=1312', params=params)
|
||||
assert resp.json['err'] == 1
|
||||
assert resp.json['err_desc'] == "No open day for activity 'A10049327682' on 2023-04-01"
|
||||
|
||||
# SOAP request and response are logged
|
||||
assert '<numDossier>1312</numDossier>' in ResourceLog.objects.all()[2].extra['request_payload']
|
||||
assert '<isOpen>false</isOpen>' in ResourceLog.objects.all()[2].extra['response_content']
|
||||
assert '<isOpen>true</isOpen>' not in ResourceLog.objects.all()[2].extra['response_content']
|
||||
|
||||
# error is logged
|
||||
assert ResourceLog.objects.all()[3].message == 'Error occurred while processing request'
|
||||
assert ResourceLog.objects.all()[3].extra['error_summary'] == [
|
||||
"passerelle.utils.jsonresponse.APIError: No open day for activity 'A10049327682' on 2023-04-01\n"
|
||||
]
|
||||
assert len(caplog.records) == 4
|
||||
assert caplog.records[3].levelno == logging.ERROR
|
||||
assert caplog.records[3].message == 'Error occurred while processing request'
|
||||
|
||||
|
||||
def test_get_recurrent_week_not_linked_error(con, app):
|
||||
|
@ -6567,7 +6624,7 @@ def test_read_activity_list(con, app, freezer):
|
|||
freezer.move_to('2024-02-29')
|
||||
resp = app.get(url)
|
||||
assert resp.json['err'] == 0
|
||||
assert len(resp.json['data']) == 8
|
||||
assert len(resp.json['data']) == 9
|
||||
activity_text = [x['activity']['text'] for x in resp.json['data']]
|
||||
assert activity_text == sorted(activity_text)
|
||||
assert [
|
||||
|
@ -6579,6 +6636,7 @@ def test_read_activity_list(con, app, freezer):
|
|||
for x in resp.json['data']
|
||||
] == [
|
||||
('A10056517594-A10056517595-A10056517597', 'plop', None),
|
||||
('A10056517599-A10056517596-A10056517597', 'plop', None),
|
||||
('A10056514645-A10056514650-A10053179757', None, None),
|
||||
('A10056514645-A10056514648-A10053179876', None, None),
|
||||
('A10056514645-A10056514649-A10053179757', None, None),
|
||||
|
@ -6587,15 +6645,26 @@ def test_read_activity_list(con, app, freezer):
|
|||
('A10051141965-A10051141970-A10053179226', 'A10049329051', 'Sorties'),
|
||||
('A10051141965-A10051141990-A10053179227', 'A10049329051', 'Sorties'),
|
||||
]
|
||||
item = resp.json['data'][4]
|
||||
|
||||
# item text differs on so called maelis "standard" and "non-standard" activities
|
||||
resp = app.get(url)
|
||||
standard_item = resp.json['data'][0] # activity having only one (standard) unit
|
||||
non_standard_item = resp.json['data'][2] # activity having many units
|
||||
assert standard_item['text'] == 'Promenade forêt enchantée, TERRITOIRE OUEST'
|
||||
assert (
|
||||
non_standard_item['text']
|
||||
== 'TEST ECOLE DES SPORTS 22/23 SEMESTRE 2 - MULTIACTIVITES (MERCREDI - 13h45/17h - 8/15Ans), ARGOULETS'
|
||||
)
|
||||
|
||||
item = resp.json['data'][5]
|
||||
item['activity'] = 'N/A'
|
||||
item['unit'] = 'N/A'
|
||||
item['place'] = 'N/A'
|
||||
assert item == {
|
||||
'id': 'A10051141965-A10051141966-A10053179226',
|
||||
'text': 'Vitrail Fusing 1/2 Je Adultes 2022/2023'
|
||||
+ ' - Mardi 14h-17h, Vitrail Fusing 1/2 Je Adultes 2022/2023'
|
||||
+ ' - Mardi 14h-17h, Centre Culturel ALBAN MINVILLE',
|
||||
+ ' - Mardi 14h-17h (Vitrail Fusing 1/2 Je Adultes 2022/2023'
|
||||
+ ' - Mardi 14h-17h), Centre Culturel ALBAN MINVILLE',
|
||||
'activity': 'N/A',
|
||||
'unit': 'N/A',
|
||||
'place': 'N/A',
|
||||
|
@ -6618,15 +6687,8 @@ def test_read_activity_list(con, app, freezer):
|
|||
},
|
||||
'public': {
|
||||
'text': 'Public',
|
||||
'data': {
|
||||
'0': 'Petit enfant (- de 3 ans)',
|
||||
'1': 'Enfant (3-11 ans)',
|
||||
'2': 'Ado (12-17 ans)',
|
||||
'3': 'Jeune (18-25 ans)',
|
||||
'4': 'Adulte (26-59 ans)',
|
||||
'5': 'Sénior (60 ans et plus)',
|
||||
},
|
||||
'order': ['0', '1', '2', '3', '4', '5'],
|
||||
'data': {'1': 'Enfant (3-11 ans)', '2': 'Ado (12-17 ans)'},
|
||||
'order': ['1', '2'],
|
||||
},
|
||||
'day': {'text': 'Jours', 'data': {'2': 'Mardi'}, 'order': ['2']},
|
||||
},
|
||||
|
@ -12023,3 +12085,71 @@ def test_trigger_wcs_api_error(family_service, activity_service, wcs_service, co
|
|||
subscription = con.subscription_set.get(wcs_form_number='13-12')
|
||||
assert subscription.trigger_status() == 'triggered'
|
||||
assert subscription.wcs_trigger_response == {'err': 1, 'err_class': 'Page non trouvée', 'err_desc': None}
|
||||
|
||||
|
||||
def test_earliest_updated(con):
|
||||
con.referential.all().delete()
|
||||
assert con.earliest_updated(con.referential.all()) is None
|
||||
ref = con.referential.create(referential_name='foo', item_id='1', item_data={})
|
||||
assert con.earliest_updated(con.referential.all()) == ref.updated
|
||||
assert con.earliest_updated(con.referential.filter(referential_name='bar')) is None
|
||||
|
||||
|
||||
@pytest.mark.parametrize('ref_name', ['Activity', 'ActivityNatureType', 'Direct', 'Service'])
|
||||
def test_get_activity_referentials_earliest_timestamp(con, ref_name):
|
||||
con.referential.all().delete()
|
||||
assert con.get_activity_referentials_earliest_timestamp() is None
|
||||
con.referential.create(referential_name='foo', item_id='1', item_data={})
|
||||
assert con.get_activity_referentials_earliest_timestamp() is None
|
||||
activity = con.referential.create(referential_name=ref_name, item_id='1', item_data={})
|
||||
assert con.get_activity_referentials_earliest_timestamp() == activity.updated
|
||||
|
||||
|
||||
@pytest.mark.parametrize('ref_name', ['Activity', 'ActivityNatureType', 'Direct', 'Service'])
|
||||
def test_is_activity_referentials_too_old(con, ref_name):
|
||||
con.referential.all().delete()
|
||||
assert con.is_activity_referentials_too_old() is True
|
||||
activity = con.referential.create(referential_name=ref_name, item_id='1', item_data={})
|
||||
assert con.is_activity_referentials_too_old() is False
|
||||
con.referential.update(updated=activity.updated - datetime.timedelta(hours=6, minutes=1))
|
||||
assert con.is_activity_referentials_too_old() is True
|
||||
|
||||
|
||||
@pytest.mark.parametrize('ref_name', ['Activity', 'ActivityNatureType', 'Direct', 'Service'])
|
||||
def test_get_referentials_earliest_timestamp(con, ref_name):
|
||||
con.referential.all().delete()
|
||||
assert con.get_referentials_earliest_timestamp() is None
|
||||
con.referential.create(referential_name=ref_name, item_id='1', item_data={})
|
||||
assert con.get_referentials_earliest_timestamp() is None
|
||||
ref = con.referential.create(referential_name='foo', item_id='1', item_data={})
|
||||
assert con.get_referentials_earliest_timestamp() == ref.updated
|
||||
|
||||
|
||||
def test_is_referentials_too_old(con):
|
||||
con.referential.all().delete()
|
||||
assert con.is_referentials_too_old() is True
|
||||
ref = con.referential.create(referential_name='foo', item_id='1', item_data={})
|
||||
assert con.is_referentials_too_old() is False
|
||||
con.referential.update(updated=ref.updated - datetime.timedelta(hours=30, minutes=1))
|
||||
assert con.is_referentials_too_old() is True
|
||||
|
||||
|
||||
def test_should_update_referentials(con, freezer):
|
||||
freezer.move_to('2023-12-10T12:01:01')
|
||||
|
||||
con.referential.all().delete()
|
||||
assert con.should_update_referentials() is True
|
||||
con.referential.create(referential_name='foo', item_id='1', item_data={})
|
||||
freezer.move_to('2023-12-11T12:00:01')
|
||||
assert con.should_update_referentials() is False
|
||||
# after 24 hours update should happen
|
||||
freezer.move_to('2023-12-11T12:01:01')
|
||||
assert con.should_update_referentials() is True
|
||||
con.referential.update(updated=now())
|
||||
assert con.should_update_referentials() is False
|
||||
# less than 24 hours, update should not happen
|
||||
freezer.move_to('2023-12-11T23:59:01')
|
||||
assert con.should_update_referentials() is False
|
||||
# but between 00:00 and 06:00 if referential is more thant 7 hours old, update
|
||||
freezer.move_to('2023-12-12T00:00:01')
|
||||
assert con.should_update_referentials() is True
|
||||
|
|
Loading…
Reference in New Issue