toulouse-maelis: booking endpoints (#72774) #19
|
@ -0,0 +1,47 @@
|
|||
# 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/>.
|
||||
|
||||
|
||||
BOOKING_SCHEMA = {
|
||||
'type': 'object',
|
||||
'properties': {
|
||||
'child_id': {
|
||||
'type': 'string',
|
||||
'minLength': 1,
|
||||
'maxLength': 8,
|
||||
},
|
||||
'booking_list': {
|
||||
'type': 'array',
|
||||
'items': {
|
||||
'type': 'string',
|
||||
'pattern': '[A-Za-z0-9]+:[- A-Za-z0-9]+:[0-9]{4}-[0-9]{2}-[0-9]{2}',
|
||||
},
|
||||
},
|
||||
'start_date': {
|
||||
'type': 'string',
|
||||
'pattern': '^[0-9]{4}-[0-9]{2}-[0-9]{2}$',
|
||||
},
|
||||
'end_date': {
|
||||
'type': 'string',
|
||||
'pattern': '^[0-9]{4}-[0-9]{2}-[0-9]{2}$',
|
||||
},
|
||||
},
|
||||
'required': [
|
||||
'child_id',
|
||||
'booking_list',
|
||||
'start_date',
|
||||
'end_date',
|
||||
],
|
||||
}
|
|
@ -14,12 +14,16 @@
|
|||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import base64
|
||||
import datetime
|
||||
from operator import itemgetter
|
||||
from urllib.parse import urljoin
|
||||
|
||||
import zeep
|
||||
from dateutil import rrule
|
||||
from django.contrib.postgres.fields import JSONField
|
||||
from django.core.serializers.json import DjangoJSONEncoder
|
||||
from django.db import models
|
||||
from django.utils import dateformat
|
||||
from django.utils.timezone import now
|
||||
from zeep.helpers import serialize_object
|
||||
from zeep.wsse.username import UsernameToken
|
||||
|
@ -30,7 +34,7 @@ from passerelle.utils.conversion import simplify
|
|||
from passerelle.utils.jsonresponse import APIError
|
||||
from passerelle.utils.templates import render_to_string
|
||||
|
||||
from . import family_schemas, invoice_schemas, schemas
|
||||
from . import activity_schemas, family_schemas, invoice_schemas, schemas, utils
|
||||
|
||||
|
||||
class UpdateError(Exception):
|
||||
|
@ -1613,6 +1617,231 @@ class ToulouseMaelis(BaseResource, HTTPResource):
|
|||
raise APIError('maelis fails to add the supplied document')
|
||||
return {'data': 'ok'}
|
||||
|
||||
def get_start_and_end_dates(self, start_date, end_date):
|
||||
try:
|
||||
start_date = datetime.datetime.strptime(start_date, utils.json_date_format).date()
|
||||
end_date = datetime.datetime.strptime(end_date, utils.json_date_format).date()
|
||||
except ValueError:
|
||||
raise APIError('bad date format, should be YYYY-MM-DD', err_code='bad-request', http_status=400)
|
||||
|
||||
if start_date > end_date:
|
||||
raise APIError(
|
||||
'start_date should be before end_date',
|
||||
err_code='bad-request',
|
||||
http_status=400,
|
||||
)
|
||||
reference_year = utils.get_reference_year_from_date(start_date)
|
||||
end_reference_year = utils.get_reference_year_from_date(end_date)
|
||||
if reference_year != end_reference_year:
|
||||
raise APIError(
|
||||
'start_date and end_date are in different reference year (%s != %s)'
|
||||
% (reference_year, end_reference_year),
|
||||
err_code='bad-request',
|
||||
http_status=400,
|
||||
)
|
||||
return start_date, end_date, reference_year
|
||||
|
||||
def get_bookings(self, family_id, child_id, start_date, end_date):
|
||||
bookings = []
|
||||
for booking_date in rrule.rrule(rrule.MONTHLY, dtstart=start_date.replace(day=1), until=end_date):
|
||||
payload = {
|
||||
'requestBean': {
|
||||
'numDossier': family_id,
|
||||
'numPerson': child_id,
|
||||
'year': booking_date.year,
|
||||
'month': booking_date.month,
|
||||
}
|
||||
}
|
||||
response = self.call('Activity', 'getPersonScheduleList', **payload)
|
||||
result = serialize_object(response)
|
||||
for result_data in result or []:
|
||||
lguerin marked this conversation as resolved
Outdated
|
||||
for schedule in result_data['activityScheduleList']:
|
||||
activity = schedule['activity']
|
||||
if activity['activityType']['natureSpec']['code'] not in ['A', 'R']:
|
||||
lguerin
commented
Les seuls codes que j'ai pu manipuler avec les données que j'ai. Si on en a d'autres, les activités associées seront ignorées, il faudra mettre cette liste à jour. Les seuls codes que j'ai pu manipuler avec les données que j'ai. Si on en a d'autres, les activités associées seront ignorées, il faudra mettre cette liste à jour.
|
||||
continue
|
||||
activity_id = activity['idAct']
|
||||
for unit in schedule['unitScheduleList']:
|
||||
days = unit['dayInfoList']
|
||||
for day in days:
|
||||
if day['status'] in ['NO_READ', 'NO_CUSTODY']:
|
||||
continue
|
||||
booking = {
|
||||
'id': '%s:%s:%s'
|
||||
% (child_id, activity_id, day['day'].strftime(utils.json_date_format)),
|
||||
'text': dateformat.format(day['day'], 'l j F Y'),
|
||||
'prefill': day['scheduledPresence'] > 0 or day['realPresence'] > 1,
|
||||
'disabled': day['status'] != 'WRITABLE',
|
||||
'details': day,
|
||||
}
|
||||
color = 'white'
|
||||
if booking['prefill']:
|
||||
color = 'green'
|
||||
lguerin
commented
Avec ce qu'on a comme info (scheduledPresence et/ou realPresence), seulement 2 couleurs possibles (blanc=non réservé, vert=réservé) Avec ce qu'on a comme info (scheduledPresence et/ou realPresence), seulement 2 couleurs possibles (blanc=non réservé, vert=réservé)
S'il en faut plus, il me faut le mode d'emploi :)
|
||||
booking['details']['status_color'] = color
|
||||
booking['details']['activity_id'] = activity_id
|
||||
booking['details']['activity_type'] = activity['activityType']['code']
|
||||
booking['details']['activity_label'] = activity['activityType']['libelle']
|
||||
booking['details']['child_id'] = child_id
|
||||
booking['details']['day_str'] = day['day'].strftime(utils.json_date_format)
|
||||
booking['details']['unit_id'] = unit['unit']['idUnit']
|
||||
bookings.append(booking)
|
||||
|
||||
# sort bookings
|
||||
activity_types = ['ACCMAT', 'RESTSCOL']
|
||||
lguerin
commented
Pour le moment, les seuls types d'activités que j'ai pu manipuler avec les données que j'ai. Au pire, si on tombe sur un nouveau type, le tri sera un peu moisi, mais ça sera juste un pb d'affichage. Pour le moment, les seuls types d'activités que j'ai pu manipuler avec les données que j'ai. Au pire, si on tombe sur un nouveau type, le tri sera un peu moisi, mais ça sera juste un pb d'affichage.
|
||||
bookings = [
|
||||
(
|
||||
b['details']['day'],
|
||||
activity_types.index(b['details']['activity_type'])
|
||||
if b['details']['activity_type'] in activity_types
|
||||
else 0,
|
||||
b['details']['activity_label'],
|
||||
b,
|
||||
)
|
||||
for b in bookings
|
||||
]
|
||||
bookings = sorted(bookings, key=itemgetter(0, 1, 2))
|
||||
bookings = [b for d, a, l, b in bookings]
|
||||
return bookings
|
||||
|
||||
@endpoint(
|
||||
display_category='Réservation',
|
||||
description="Agenda d'un enfant",
|
||||
name='read-child-agenda',
|
||||
perm='can_access',
|
||||
parameters={
|
||||
'NameID': {'description': 'Publik NameID'},
|
||||
'child_id': {'description': "Numéro de l'enfant"},
|
||||
'start_date': {'description': 'Début de la période'},
|
||||
'end_date': {'description': 'Fin de la période'},
|
||||
},
|
||||
)
|
||||
def read_child_agenda(self, request, NameID, child_id, start_date, end_date):
|
||||
family_id = self.get_link(NameID).family_id
|
||||
start_date, end_date, reference_year = self.get_start_and_end_dates(start_date, end_date)
|
||||
bookings = self.get_bookings(family_id, child_id, start_date, end_date)
|
||||
return {
|
||||
'data': bookings,
|
||||
'extra_data': {
|
||||
'start_date': start_date,
|
||||
'end_date': end_date,
|
||||
'school_year': '%s/%s' % (reference_year, reference_year + 1),
|
||||
},
|
||||
}
|
||||
|
||||
@endpoint(
|
||||
display_category='Réservation',
|
||||
description="Modifier l'agenda d'un enfant",
|
||||
name='update-child-agenda',
|
||||
perm='can_access',
|
||||
parameters={
|
||||
'NameID': {'description': 'Publik NameID'},
|
||||
},
|
||||
post={
|
||||
'request_body': {
|
||||
'schema': {
|
||||
'application/json': activity_schemas.BOOKING_SCHEMA,
|
||||
}
|
||||
}
|
||||
},
|
||||
)
|
||||
def update_child_agenda(self, request, NameID, post_data):
|
||||
family_id = self.get_link(NameID).family_id
|
||||
child_id = post_data['child_id']
|
||||
start_date, end_date, dummy = self.get_start_and_end_dates(
|
||||
post_data['start_date'], post_data['end_date']
|
||||
)
|
||||
requested_bookings = post_data['booking_list']
|
||||
|
||||
# build list of existing booked days
|
||||
bookings = self.get_bookings(family_id, child_id, start_date, end_date)
|
||||
legacy_bookings = [b['id'] for b in bookings if b['prefill'] is True]
|
||||
available_bookings = [b['id'] for b in bookings if b['disabled'] is False]
|
||||
|
||||
bookings_to_update = []
|
||||
updated = []
|
||||
for booking_info in bookings:
|
||||
day_id = booking_info['id']
|
||||
booked = None
|
||||
action = booking_info['details']['action']
|
||||
if day_id not in available_bookings:
|
||||
# disabled or not available: not bookable
|
||||
booked = None
|
||||
elif (
|
||||
day_id not in legacy_bookings
|
||||
and day_id in requested_bookings
|
||||
and action in ['ADD_PRES_PREVI', 'ADD_PRES_REAL', 'DEL_ABSENCE']
|
||||
):
|
||||
booked = action
|
||||
lguerin
commented
J'applique l'action renvoyée par le WS getPersonScheduleList, en vérifiant quand meme qu'elle est pertinente J'applique l'action renvoyée par le WS getPersonScheduleList, en vérifiant quand meme qu'elle est pertinente
fpeters
commented
test la phrase pas terminée elle s'arrête. test la phrase pas terminée elle s'arrête.
|
||||
elif (
|
||||
day_id in legacy_bookings
|
||||
and day_id not in requested_bookings
|
||||
and action in ['DEL_PRES_PREVI', 'DEL_PRES_REAL', 'ADD_ABSENCE']
|
||||
):
|
||||
booked = action
|
||||
lguerin
commented
idem idem
|
||||
if booked is not None:
|
||||
# no changes, don't send the day
|
||||
bookings_to_update.append(
|
||||
{
|
||||
'numPerson': child_id,
|
||||
'idAct': booking_info['details']['activity_id'],
|
||||
'idUni': booking_info['details']['unit_id'],
|
||||
'date': booking_info['details']['day_str'],
|
||||
'action': booked,
|
||||
}
|
||||
)
|
||||
updated.append(
|
||||
{
|
||||
'activity_id': booking_info['details']['activity_id'],
|
||||
'activity_type': booking_info['details']['activity_type'],
|
||||
'activity_label': booking_info['details']['activity_label'],
|
||||
'day': booking_info['details']['day_str'],
|
||||
'booked': booked in ['ADD_PRES_PREVI', 'ADD_PRES_REAL', 'DEL_ABSENCE'],
|
||||
}
|
||||
)
|
||||
if not bookings_to_update:
|
||||
# don't call maelis if no changes
|
||||
return updated
|
||||
|
||||
payload = {
|
||||
'requestBean': {
|
||||
'numDossier': family_id,
|
||||
'unitPersonDayInfoList': bookings_to_update,
|
||||
}
|
||||
}
|
||||
response = self.call('Activity', 'updatePersonSchedule', **payload)
|
||||
errors = serialize_object(response)
|
||||
if errors:
|
||||
raise APIError(' ; '.join(errors), err_code='agenda-child-error')
|
||||
|
||||
# sort changes
|
||||
activity_types = ['ACCMAT', 'RESTSCOL']
|
||||
updated = [
|
||||
(
|
||||
not u['booked'],
|
||||
activity_types.index(u['activity_type']) if u['activity_type'] in activity_types else 0,
|
||||
u['activity_label'],
|
||||
u['day'],
|
||||
u,
|
||||
)
|
||||
for u in updated
|
||||
]
|
||||
updated = sorted(updated, key=itemgetter(0, 1, 2, 3))
|
||||
updated = [u for b, a, l, d, u in updated]
|
||||
updated = [
|
||||
{
|
||||
'booked': u['booked'],
|
||||
'activity_id': u['activity_id'],
|
||||
'activity_label': u['activity_label'],
|
||||
'day': u['day'],
|
||||
}
|
||||
for u in updated
|
||||
]
|
||||
|
||||
return {
|
||||
'updated': True,
|
||||
'count': len(updated),
|
||||
'changes': updated,
|
||||
}
|
||||
|
||||
@endpoint(
|
||||
display_category='Facture',
|
||||
description="Ajout d'autorisation de prélèvement",
|
||||
|
|
|
@ -0,0 +1,23 @@
|
|||
# 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/>.
|
||||
|
||||
json_date_format = '%Y-%m-%d'
|
||||
|
||||
|
||||
def get_reference_year_from_date(some_date):
|
||||
if some_date.month <= 8:
|
||||
# between january and august, reference year is the year just before
|
||||
return some_date.year - 1
|
||||
return some_date.year
|
|
@ -0,0 +1,250 @@
|
|||
<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">
|
||||
<resultBean>
|
||||
<personScheduleList>
|
||||
<person>
|
||||
<numPerson>613880</numPerson>
|
||||
<lastname>DOE</lastname>
|
||||
<firstname>JANNIS</firstname>
|
||||
</person>
|
||||
<activityScheduleList>
|
||||
<activity>
|
||||
<idAct>A10049327689</idAct>
|
||||
<libelle>CLAE MATIN 22/23</libelle>
|
||||
<activityType>
|
||||
<code>ACCMAT</code>
|
||||
<libelle>Accueil du matin</libelle>
|
||||
<natureSpec>
|
||||
<code>A</code>
|
||||
<libelle>Accueil P\xc3\xa9riscolaire</libelle>
|
||||
</natureSpec>
|
||||
</activityType>
|
||||
</activity>
|
||||
<unitScheduleList>
|
||||
<unit>
|
||||
<idUnit>A10049327690</idUnit>
|
||||
<libelle>CLAE MATIN 22/23</libelle>
|
||||
</unit>
|
||||
<dayInfoList>
|
||||
<day>2023-01-01T00:00:00+01:00</day>
|
||||
<scheduledPresence>0</scheduledPresence>
|
||||
<realPresence>0</realPresence>
|
||||
<ns3:status>NO_READ</ns3:status>
|
||||
</dayInfoList>
|
||||
<dayInfoList>
|
||||
<day>2023-01-02T00:00:00+01:00</day>
|
||||
<scheduledPresence>0</scheduledPresence>
|
||||
<realPresence>0</realPresence>
|
||||
<ns3:status>READ_ONLY</ns3:status>
|
||||
</dayInfoList>
|
||||
<dayInfoList>
|
||||
<day>2023-01-03T00:00:00+01:00</day>
|
||||
<scheduledPresence>0</scheduledPresence>
|
||||
<realPresence>0</realPresence>
|
||||
<ns3:status>READ_ONLY</ns3:status>
|
||||
</dayInfoList>
|
||||
<dayInfoList>
|
||||
<day>2023-01-04T00:00:00+01:00</day>
|
||||
<scheduledPresence>0</scheduledPresence>
|
||||
<realPresence>0</realPresence>
|
||||
<ns3:status>NO_READ</ns3:status>
|
||||
</dayInfoList>
|
||||
<dayInfoList>
|
||||
<day>2023-01-05T00:00:00+01:00</day>
|
||||
<scheduledPresence>1</scheduledPresence>
|
||||
<realPresence>0</realPresence>
|
||||
<ns3:status>WRITABLE</ns3:status>
|
||||
<ns3:action>ADD_ABSENCE</ns3:action>
|
||||
</dayInfoList>
|
||||
<dayInfoList>
|
||||
<day>2023-01-06T00:00:00+01:00</day>
|
||||
<scheduledPresence>1</scheduledPresence>
|
||||
<realPresence>0</realPresence>
|
||||
<ns3:status>WRITABLE</ns3:status>
|
||||
<ns3:action>ADD_ABSENCE</ns3:action>
|
||||
</dayInfoList>
|
||||
<dayInfoList>
|
||||
<day>2023-01-07T00:00:00+01:00</day>
|
||||
<scheduledPresence>0</scheduledPresence>
|
||||
<realPresence>0</realPresence>
|
||||
<ns3:status>NO_READ</ns3:status>
|
||||
</dayInfoList>
|
||||
<dayInfoList>
|
||||
<day>2023-01-08T00:00:00+01:00</day>
|
||||
<scheduledPresence>0</scheduledPresence>
|
||||
<realPresence>0</realPresence>
|
||||
<ns3:status>NO_READ</ns3:status>
|
||||
</dayInfoList>
|
||||
<dayInfoList>
|
||||
<day>2023-01-09T00:00:00+01:00</day>
|
||||
<scheduledPresence>0</scheduledPresence>
|
||||
<realPresence>0</realPresence>
|
||||
<ns3:status>WRITABLE</ns3:status>
|
||||
<ns3:action>ADD_PRES_PREVI</ns3:action>
|
||||
</dayInfoList>
|
||||
<dayInfoList>
|
||||
<day>2023-01-10T00:00:00+01:00</day>
|
||||
<scheduledPresence>0</scheduledPresence>
|
||||
<realPresence>0</realPresence>
|
||||
<ns3:status>WRITABLE</ns3:status>
|
||||
<ns3:action>ADD_PRES_PREVI</ns3:action>
|
||||
</dayInfoList>
|
||||
<dayInfoList>
|
||||
<day>2023-01-11T00:00:00+01:00</day>
|
||||
<scheduledPresence>0</scheduledPresence>
|
||||
<realPresence>0</realPresence>
|
||||
<ns3:status>NO_READ</ns3:status>
|
||||
</dayInfoList>
|
||||
<dayInfoList>
|
||||
<day>2023-01-12T00:00:00+01:00</day>
|
||||
<scheduledPresence>1</scheduledPresence>
|
||||
<realPresence>0</realPresence>
|
||||
<ns3:status>WRITABLE</ns3:status>
|
||||
<ns3:action>DEL_PRES_PREVI</ns3:action>
|
||||
</dayInfoList>
|
||||
<dayInfoList>
|
||||
<day>2023-01-13T00:00:00+01:00</day>
|
||||
<scheduledPresence>1</scheduledPresence>
|
||||
<realPresence>0</realPresence>
|
||||
<ns3:status>WRITABLE</ns3:status>
|
||||
<ns3:action>DEL_PRES_PREVI</ns3:action>
|
||||
</dayInfoList>
|
||||
<dayInfoList>
|
||||
<day>2023-01-14T00:00:00+01:00</day>
|
||||
<scheduledPresence>0</scheduledPresence>
|
||||
<realPresence>0</realPresence>
|
||||
<ns3:status>NO_READ</ns3:status>
|
||||
</dayInfoList>
|
||||
<dayInfoList>
|
||||
<day>2023-01-15T00:00:00+01:00</day>
|
||||
<scheduledPresence>0</scheduledPresence>
|
||||
<realPresence>0</realPresence>
|
||||
<ns3:status>NO_READ</ns3:status>
|
||||
</dayInfoList>
|
||||
</unitScheduleList>
|
||||
</activityScheduleList>
|
||||
<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>
|
||||
<unitScheduleList>
|
||||
<unit>
|
||||
<idUnit>A10049327683</idUnit>
|
||||
<libelle>RESTAURATION SCOLAIRE 22/23</libelle>
|
||||
</unit>
|
||||
<dayInfoList>
|
||||
<day>2023-01-01T00:00:00+01:00</day>
|
||||
<scheduledPresence>0</scheduledPresence>
|
||||
<realPresence>0</realPresence>
|
||||
<ns3:status>NO_READ</ns3:status>
|
||||
</dayInfoList>
|
||||
<dayInfoList>
|
||||
<day>2023-01-02T00:00:00+01:00</day>
|
||||
<scheduledPresence>0</scheduledPresence>
|
||||
<realPresence>0</realPresence>
|
||||
<ns3:status>READ_ONLY</ns3:status>
|
||||
</dayInfoList>
|
||||
<dayInfoList>
|
||||
<day>2023-01-03T00:00:00+01:00</day>
|
||||
<scheduledPresence>1</scheduledPresence>
|
||||
<realPresence>0</realPresence>
|
||||
<ns3:status>READ_ONLY</ns3:status>
|
||||
</dayInfoList>
|
||||
<dayInfoList>
|
||||
<day>2023-01-04T00:00:00+01:00</day>
|
||||
<scheduledPresence>0</scheduledPresence>
|
||||
<realPresence>0</realPresence>
|
||||
<ns3:status>NO_READ</ns3:status>
|
||||
</dayInfoList>
|
||||
<dayInfoList>
|
||||
<day>2023-01-05T00:00:00+01:00</day>
|
||||
<scheduledPresence>1</scheduledPresence>
|
||||
<realPresence>0</realPresence>
|
||||
<ns3:status>WRITABLE</ns3:status>
|
||||
<ns3:action>ADD_ABSENCE</ns3:action>
|
||||
</dayInfoList>
|
||||
<dayInfoList>
|
||||
<day>2023-01-06T00:00:00+01:00</day>
|
||||
<scheduledPresence>0</scheduledPresence>
|
||||
<realPresence>0</realPresence>
|
||||
<ns3:status>WRITABLE</ns3:status>
|
||||
<ns3:action>ADD_PRES_REAL</ns3:action>
|
||||
</dayInfoList>
|
||||
<dayInfoList>
|
||||
<day>2023-01-07T00:00:00+01:00</day>
|
||||
<scheduledPresence>0</scheduledPresence>
|
||||
<realPresence>0</realPresence>
|
||||
<ns3:status>NO_READ</ns3:status>
|
||||
</dayInfoList>
|
||||
<dayInfoList>
|
||||
<day>2023-01-08T00:00:00+01:00</day>
|
||||
<scheduledPresence>0</scheduledPresence>
|
||||
<realPresence>0</realPresence>
|
||||
<ns3:status>NO_READ</ns3:status>
|
||||
</dayInfoList>
|
||||
<dayInfoList>
|
||||
<day>2023-01-09T00:00:00+01:00</day>
|
||||
<scheduledPresence>0</scheduledPresence>
|
||||
<realPresence>0</realPresence>
|
||||
<ns3:status>WRITABLE</ns3:status>
|
||||
<ns3:action>ADD_PRES_PREVI</ns3:action>
|
||||
</dayInfoList>
|
||||
<dayInfoList>
|
||||
<day>2023-01-10T00:00:00+01:00</day>
|
||||
<scheduledPresence>1</scheduledPresence>
|
||||
<realPresence>0</realPresence>
|
||||
<ns3:status>WRITABLE</ns3:status>
|
||||
<ns3:action>DEL_PRES_PREVI</ns3:action>
|
||||
</dayInfoList>
|
||||
<dayInfoList>
|
||||
<day>2023-01-11T00:00:00+01:00</day>
|
||||
<scheduledPresence>0</scheduledPresence>
|
||||
<realPresence>0</realPresence>
|
||||
<ns3:status>NO_READ</ns3:status>
|
||||
</dayInfoList>
|
||||
<dayInfoList>
|
||||
<day>2023-01-12T00:00:00+01:00</day>
|
||||
<scheduledPresence>1</scheduledPresence>
|
||||
<realPresence>0</realPresence>
|
||||
<ns3:status>WRITABLE</ns3:status>
|
||||
<ns3:action>DEL_PRES_PREVI</ns3:action>
|
||||
</dayInfoList>
|
||||
<dayInfoList>
|
||||
<day>2023-01-13T00:00:00+01:00</day>
|
||||
<scheduledPresence>0</scheduledPresence>
|
||||
<realPresence>0</realPresence>
|
||||
<ns3:status>WRITABLE</ns3:status>
|
||||
<ns3:action>ADD_PRES_PREVI</ns3:action>
|
||||
</dayInfoList>
|
||||
<dayInfoList>
|
||||
<day>2023-01-14T00:00:00+01:00</day>
|
||||
<scheduledPresence>0</scheduledPresence>
|
||||
<realPresence>0</realPresence>
|
||||
<ns3:status>NO_READ</ns3:status>
|
||||
</dayInfoList>
|
||||
<dayInfoList>
|
||||
<day>2023-01-15T00:00:00+01: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>
|
|
@ -0,0 +1,10 @@
|
|||
<soap:Envelope
|
||||
xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
|
||||
<soap:Body>
|
||||
<ns2:updatePersonScheduleResponse
|
||||
xmlns:ns2="activity.ws.maelis.sigec.com"
|
||||
xmlns:ns3="bean.persistence.activity.ws.maelis.sigec.com">
|
||||
<resultBean/>
|
||||
</ns2:updatePersonScheduleResponse>
|
||||
</soap:Body>
|
||||
</soap:Envelope>
|
|
@ -0,0 +1,13 @@
|
|||
<soap:Envelope
|
||||
xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
|
||||
<soap:Body>
|
||||
<ns2:updatePersonScheduleResponse
|
||||
xmlns:ns2="activity.ws.maelis.sigec.com"
|
||||
xmlns:ns3="bean.persistence.activity.ws.maelis.sigec.com">
|
||||
<resultBean>
|
||||
<errorMessages>Foo</errorMessages>
|
||||
<errorMessages>Bar</errorMessages>
|
||||
</resultBean>
|
||||
</ns2:updatePersonScheduleResponse>
|
||||
</soap:Body>
|
||||
</soap:Envelope>
|
|
@ -3698,3 +3698,602 @@ def test_read_exemption_reasons_list(con, app):
|
|||
for item in resp.json['data']:
|
||||
assert 'id' in item
|
||||
assert 'text' in item
|
||||
|
||||
|
||||
def test_read_child_agenda(activity_service, con, app):
|
||||
activity_service.add_soap_response(
|
||||
'getPersonScheduleList', get_xml_file('R_get_person_schedule_list.xml')
|
||||
)
|
||||
url = get_endpoint('read-child-agenda')
|
||||
Link.objects.create(resource=con, family_id='1312', name_id='local')
|
||||
|
||||
resp = app.get(url + '?NameID=local&child_id=613880&start_date=2023-01-01&end_date=2023-01-15')
|
||||
|
||||
assert resp.json['err'] == 0
|
||||
assert resp.json['extra_data'] == {
|
||||
'start_date': '2023-01-01',
|
||||
'end_date': '2023-01-15',
|
||||
'school_year': '2022/2023',
|
||||
}
|
||||
assert len(resp.json['data']) == 16
|
||||
assert resp.json['data'] == [
|
||||
{
|
||||
'details': {
|
||||
'absence': None,
|
||||
'action': None,
|
||||
'activity_id': 'A10049327689',
|
||||
'activity_label': 'Accueil du matin',
|
||||
'activity_type': 'ACCMAT',
|
||||
'child_id': '613880',
|
||||
'day': '2023-01-02T00:00:00+01:00',
|
||||
'day_str': '2023-01-02',
|
||||
'hasPlace': None,
|
||||
'realPresence': 0,
|
||||
'scheduledPresence': 0,
|
||||
'status': 'READ_ONLY',
|
||||
'status_color': 'white',
|
||||
'unit_id': 'A10049327690',
|
||||
},
|
||||
'disabled': True,
|
||||
'id': '613880:A10049327689:2023-01-02',
|
||||
'prefill': False,
|
||||
'text': 'Monday 2 January 2023',
|
||||
},
|
||||
{
|
||||
'details': {
|
||||
'absence': None,
|
||||
'action': None,
|
||||
'activity_id': 'A10049327682',
|
||||
'activity_label': 'Restauration scolaire',
|
||||
'activity_type': 'RESTSCOL',
|
||||
'child_id': '613880',
|
||||
'day': '2023-01-02T00:00:00+01:00',
|
||||
'day_str': '2023-01-02',
|
||||
'hasPlace': None,
|
||||
'realPresence': 0,
|
||||
'scheduledPresence': 0,
|
||||
'status': 'READ_ONLY',
|
||||
'status_color': 'white',
|
||||
'unit_id': 'A10049327683',
|
||||
},
|
||||
'disabled': True,
|
||||
'id': '613880:A10049327682:2023-01-02',
|
||||
'prefill': False,
|
||||
'text': 'Monday 2 January 2023',
|
||||
},
|
||||
{
|
||||
'details': {
|
||||
'absence': None,
|
||||
'action': None,
|
||||
'activity_id': 'A10049327689',
|
||||
'activity_label': 'Accueil du matin',
|
||||
'activity_type': 'ACCMAT',
|
||||
'child_id': '613880',
|
||||
'day': '2023-01-03T00:00:00+01:00',
|
||||
'day_str': '2023-01-03',
|
||||
'hasPlace': None,
|
||||
'realPresence': 0,
|
||||
'scheduledPresence': 0,
|
||||
'status': 'READ_ONLY',
|
||||
'status_color': 'white',
|
||||
'unit_id': 'A10049327690',
|
||||
},
|
||||
'disabled': True,
|
||||
'id': '613880:A10049327689:2023-01-03',
|
||||
'prefill': False,
|
||||
'text': 'Tuesday 3 January 2023',
|
||||
},
|
||||
{
|
||||
'details': {
|
||||
'absence': None,
|
||||
'action': None,
|
||||
'activity_id': 'A10049327682',
|
||||
'activity_label': 'Restauration scolaire',
|
||||
'activity_type': 'RESTSCOL',
|
||||
'child_id': '613880',
|
||||
'day': '2023-01-03T00:00:00+01:00',
|
||||
'day_str': '2023-01-03',
|
||||
'hasPlace': None,
|
||||
'realPresence': 0,
|
||||
'scheduledPresence': 1,
|
||||
'status': 'READ_ONLY',
|
||||
'status_color': 'green',
|
||||
'unit_id': 'A10049327683',
|
||||
},
|
||||
'disabled': True,
|
||||
'id': '613880:A10049327682:2023-01-03',
|
||||
'prefill': True,
|
||||
'text': 'Tuesday 3 January 2023',
|
||||
},
|
||||
{
|
||||
'details': {
|
||||
'absence': None,
|
||||
'action': 'ADD_ABSENCE',
|
||||
'activity_id': 'A10049327689',
|
||||
'activity_label': 'Accueil du matin',
|
||||
'activity_type': 'ACCMAT',
|
||||
'child_id': '613880',
|
||||
'day': '2023-01-05T00:00:00+01:00',
|
||||
'day_str': '2023-01-05',
|
||||
'hasPlace': None,
|
||||
'realPresence': 0,
|
||||
'scheduledPresence': 1,
|
||||
'status': 'WRITABLE',
|
||||
'status_color': 'green',
|
||||
'unit_id': 'A10049327690',
|
||||
},
|
||||
'disabled': False,
|
||||
'id': '613880:A10049327689:2023-01-05',
|
||||
'prefill': True,
|
||||
'text': 'Thursday 5 January 2023',
|
||||
},
|
||||
{
|
||||
'details': {
|
||||
'absence': None,
|
||||
'action': 'ADD_ABSENCE',
|
||||
'activity_id': 'A10049327682',
|
||||
'activity_label': 'Restauration scolaire',
|
||||
'activity_type': 'RESTSCOL',
|
||||
'child_id': '613880',
|
||||
'day': '2023-01-05T00:00:00+01:00',
|
||||
'day_str': '2023-01-05',
|
||||
'hasPlace': None,
|
||||
'realPresence': 0,
|
||||
'scheduledPresence': 1,
|
||||
'status': 'WRITABLE',
|
||||
'status_color': 'green',
|
||||
'unit_id': 'A10049327683',
|
||||
},
|
||||
'disabled': False,
|
||||
'id': '613880:A10049327682:2023-01-05',
|
||||
'prefill': True,
|
||||
'text': 'Thursday 5 January 2023',
|
||||
},
|
||||
{
|
||||
'details': {
|
||||
'absence': None,
|
||||
'action': 'ADD_ABSENCE',
|
||||
'activity_id': 'A10049327689',
|
||||
'activity_label': 'Accueil du matin',
|
||||
'activity_type': 'ACCMAT',
|
||||
'child_id': '613880',
|
||||
'day': '2023-01-06T00:00:00+01:00',
|
||||
'day_str': '2023-01-06',
|
||||
'hasPlace': None,
|
||||
'realPresence': 0,
|
||||
'scheduledPresence': 1,
|
||||
'status': 'WRITABLE',
|
||||
'status_color': 'green',
|
||||
'unit_id': 'A10049327690',
|
||||
},
|
||||
'disabled': False,
|
||||
'id': '613880:A10049327689:2023-01-06',
|
||||
'prefill': True,
|
||||
'text': 'Friday 6 January 2023',
|
||||
},
|
||||
{
|
||||
'details': {
|
||||
'absence': None,
|
||||
'action': 'ADD_PRES_REAL',
|
||||
'activity_id': 'A10049327682',
|
||||
'activity_label': 'Restauration scolaire',
|
||||
'activity_type': 'RESTSCOL',
|
||||
'child_id': '613880',
|
||||
'day': '2023-01-06T00:00:00+01:00',
|
||||
'day_str': '2023-01-06',
|
||||
'hasPlace': None,
|
||||
'realPresence': 0,
|
||||
'scheduledPresence': 0,
|
||||
'status': 'WRITABLE',
|
||||
'status_color': 'white',
|
||||
'unit_id': 'A10049327683',
|
||||
},
|
||||
'disabled': False,
|
||||
'id': '613880:A10049327682:2023-01-06',
|
||||
'prefill': False,
|
||||
'text': 'Friday 6 January 2023',
|
||||
},
|
||||
{
|
||||
'details': {
|
||||
'absence': None,
|
||||
'action': 'ADD_PRES_PREVI',
|
||||
'activity_id': 'A10049327689',
|
||||
'activity_label': 'Accueil du matin',
|
||||
'activity_type': 'ACCMAT',
|
||||
'child_id': '613880',
|
||||
'day': '2023-01-09T00:00:00+01:00',
|
||||
'day_str': '2023-01-09',
|
||||
'hasPlace': None,
|
||||
'realPresence': 0,
|
||||
'scheduledPresence': 0,
|
||||
'status': 'WRITABLE',
|
||||
'status_color': 'white',
|
||||
'unit_id': 'A10049327690',
|
||||
},
|
||||
'disabled': False,
|
||||
'id': '613880:A10049327689:2023-01-09',
|
||||
'prefill': False,
|
||||
'text': 'Monday 9 January 2023',
|
||||
},
|
||||
{
|
||||
'details': {
|
||||
'absence': None,
|
||||
'action': 'ADD_PRES_PREVI',
|
||||
'activity_id': 'A10049327682',
|
||||
'activity_label': 'Restauration scolaire',
|
||||
'activity_type': 'RESTSCOL',
|
||||
'child_id': '613880',
|
||||
'day': '2023-01-09T00:00:00+01:00',
|
||||
'day_str': '2023-01-09',
|
||||
'hasPlace': None,
|
||||
'realPresence': 0,
|
||||
'scheduledPresence': 0,
|
||||
'status': 'WRITABLE',
|
||||
'status_color': 'white',
|
||||
'unit_id': 'A10049327683',
|
||||
},
|
||||
'disabled': False,
|
||||
'id': '613880:A10049327682:2023-01-09',
|
||||
'prefill': False,
|
||||
'text': 'Monday 9 January 2023',
|
||||
},
|
||||
{
|
||||
'details': {
|
||||
'absence': None,
|
||||
'action': 'ADD_PRES_PREVI',
|
||||
'activity_id': 'A10049327689',
|
||||
'activity_label': 'Accueil du matin',
|
||||
'activity_type': 'ACCMAT',
|
||||
'child_id': '613880',
|
||||
'day': '2023-01-10T00:00:00+01:00',
|
||||
'day_str': '2023-01-10',
|
||||
'hasPlace': None,
|
||||
'realPresence': 0,
|
||||
'scheduledPresence': 0,
|
||||
'status': 'WRITABLE',
|
||||
'status_color': 'white',
|
||||
'unit_id': 'A10049327690',
|
||||
},
|
||||
'disabled': False,
|
||||
'id': '613880:A10049327689:2023-01-10',
|
||||
'prefill': False,
|
||||
'text': 'Tuesday 10 January 2023',
|
||||
},
|
||||
{
|
||||
'details': {
|
||||
'absence': None,
|
||||
'action': 'DEL_PRES_PREVI',
|
||||
'activity_id': 'A10049327682',
|
||||
'activity_label': 'Restauration scolaire',
|
||||
'activity_type': 'RESTSCOL',
|
||||
'child_id': '613880',
|
||||
'day': '2023-01-10T00:00:00+01:00',
|
||||
'day_str': '2023-01-10',
|
||||
'hasPlace': None,
|
||||
'realPresence': 0,
|
||||
'scheduledPresence': 1,
|
||||
'status': 'WRITABLE',
|
||||
'status_color': 'green',
|
||||
'unit_id': 'A10049327683',
|
||||
},
|
||||
'disabled': False,
|
||||
'id': '613880:A10049327682:2023-01-10',
|
||||
'prefill': True,
|
||||
'text': 'Tuesday 10 January 2023',
|
||||
},
|
||||
{
|
||||
'details': {
|
||||
'absence': None,
|
||||
'action': 'DEL_PRES_PREVI',
|
||||
'activity_id': 'A10049327689',
|
||||
'activity_label': 'Accueil du matin',
|
||||
'activity_type': 'ACCMAT',
|
||||
'child_id': '613880',
|
||||
'day': '2023-01-12T00:00:00+01:00',
|
||||
'day_str': '2023-01-12',
|
||||
'hasPlace': None,
|
||||
'realPresence': 0,
|
||||
'scheduledPresence': 1,
|
||||
'status': 'WRITABLE',
|
||||
'status_color': 'green',
|
||||
'unit_id': 'A10049327690',
|
||||
},
|
||||
'disabled': False,
|
||||
'id': '613880:A10049327689:2023-01-12',
|
||||
'prefill': True,
|
||||
'text': 'Thursday 12 January 2023',
|
||||
},
|
||||
{
|
||||
'details': {
|
||||
'absence': None,
|
||||
'action': 'DEL_PRES_PREVI',
|
||||
'activity_id': 'A10049327682',
|
||||
'activity_label': 'Restauration scolaire',
|
||||
'activity_type': 'RESTSCOL',
|
||||
'child_id': '613880',
|
||||
'day': '2023-01-12T00:00:00+01:00',
|
||||
'day_str': '2023-01-12',
|
||||
'hasPlace': None,
|
||||
'realPresence': 0,
|
||||
'scheduledPresence': 1,
|
||||
'status': 'WRITABLE',
|
||||
'status_color': 'green',
|
||||
'unit_id': 'A10049327683',
|
||||
},
|
||||
'disabled': False,
|
||||
'id': '613880:A10049327682:2023-01-12',
|
||||
'prefill': True,
|
||||
'text': 'Thursday 12 January 2023',
|
||||
},
|
||||
{
|
||||
'details': {
|
||||
'absence': None,
|
||||
'action': 'DEL_PRES_PREVI',
|
||||
'activity_id': 'A10049327689',
|
||||
'activity_label': 'Accueil du matin',
|
||||
'activity_type': 'ACCMAT',
|
||||
'child_id': '613880',
|
||||
'day': '2023-01-13T00:00:00+01:00',
|
||||
'day_str': '2023-01-13',
|
||||
'hasPlace': None,
|
||||
'realPresence': 0,
|
||||
'scheduledPresence': 1,
|
||||
'status': 'WRITABLE',
|
||||
'status_color': 'green',
|
||||
'unit_id': 'A10049327690',
|
||||
},
|
||||
'disabled': False,
|
||||
'id': '613880:A10049327689:2023-01-13',
|
||||
'prefill': True,
|
||||
'text': 'Friday 13 January 2023',
|
||||
},
|
||||
{
|
||||
'details': {
|
||||
'absence': None,
|
||||
'action': 'ADD_PRES_PREVI',
|
||||
'activity_id': 'A10049327682',
|
||||
'activity_label': 'Restauration scolaire',
|
||||
'activity_type': 'RESTSCOL',
|
||||
'child_id': '613880',
|
||||
'day': '2023-01-13T00:00:00+01:00',
|
||||
'day_str': '2023-01-13',
|
||||
'hasPlace': None,
|
||||
'realPresence': 0,
|
||||
'scheduledPresence': 0,
|
||||
'status': 'WRITABLE',
|
||||
'status_color': 'white',
|
||||
'unit_id': 'A10049327683',
|
||||
},
|
||||
'disabled': False,
|
||||
'id': '613880:A10049327682:2023-01-13',
|
||||
'prefill': False,
|
||||
'text': 'Friday 13 January 2023',
|
||||
},
|
||||
]
|
||||
|
||||
|
||||
def test_read_child_agenda_not_linked_error(con, app):
|
||||
url = get_endpoint('read-child-agenda')
|
||||
|
||||
resp = app.get(url + '?NameID=local&child_id=613880&start_date=2022-09-01&end_date=2023-08-31')
|
||||
assert resp.json['err'] == 'not-linked'
|
||||
assert resp.json['err_desc'] == 'User not linked to family'
|
||||
|
||||
|
||||
def test_read_child_agenda_date_error(con, app):
|
||||
url = get_endpoint('read-child-agenda')
|
||||
Link.objects.create(resource=con, family_id='1312', name_id='local')
|
||||
|
||||
resp = app.get(url + '?NameID=local&child_id=613880&start_date=bad&end_date=2023-08-31', status=400)
|
||||
assert resp.json['err'] == 'bad-request'
|
||||
assert resp.json['err_desc'] == 'bad date format, should be YYYY-MM-DD'
|
||||
|
||||
resp = app.get(url + '?NameID=local&child_id=613880&start_date=2022-09-01&end_date=bad', status=400)
|
||||
assert resp.json['err'] == 'bad-request'
|
||||
assert resp.json['err_desc'] == 'bad date format, should be YYYY-MM-DD'
|
||||
|
||||
resp = app.get(
|
||||
url + '?NameID=local&child_id=613880&start_date=2023-09-01&end_date=2023-08-31', status=400
|
||||
)
|
||||
assert resp.json['err'] == 'bad-request'
|
||||
assert resp.json['err_desc'] == 'start_date should be before end_date'
|
||||
|
||||
resp = app.get(
|
||||
url + '?NameID=local&child_id=613880&start_date=2022-09-01&end_date=2024-08-31', status=400
|
||||
)
|
||||
assert resp.json['err'] == 'bad-request'
|
||||
assert resp.json['err_desc'] == 'start_date and end_date are in different reference year (2022 != 2023)'
|
||||
|
||||
|
||||
def test_update_child_agenda(activity_service, con, app):
|
||||
activity_service.add_soap_response(
|
||||
'getPersonScheduleList', get_xml_file('R_get_person_schedule_list.xml')
|
||||
)
|
||||
url = get_endpoint('update-child-agenda')
|
||||
Link.objects.create(resource=con, family_id='1312', name_id='local')
|
||||
|
||||
def request_check(request):
|
||||
assert request.numDossier == 1312
|
||||
assert len(request.unitPersonDayInfoList) == 4
|
||||
assert request.unitPersonDayInfoList[0].numPerson == 613880
|
||||
assert request.unitPersonDayInfoList[0].idAct == 'A10049327689'
|
||||
assert request.unitPersonDayInfoList[0].idUni == 'A10049327690'
|
||||
assert request.unitPersonDayInfoList[0].date == datetime.datetime(2023, 1, 5, 0, 0)
|
||||
assert request.unitPersonDayInfoList[0].action == 'ADD_ABSENCE'
|
||||
assert request.unitPersonDayInfoList[1].numPerson == 613880
|
||||
assert request.unitPersonDayInfoList[1].idAct == 'A10049327682'
|
||||
assert request.unitPersonDayInfoList[1].idUni == 'A10049327683'
|
||||
assert request.unitPersonDayInfoList[1].date == datetime.datetime(2023, 1, 6, 0, 0)
|
||||
assert request.unitPersonDayInfoList[1].action == 'ADD_PRES_REAL'
|
||||
assert request.unitPersonDayInfoList[2].numPerson == 613880
|
||||
assert request.unitPersonDayInfoList[2].idAct == 'A10049327682'
|
||||
assert request.unitPersonDayInfoList[2].idUni == 'A10049327683'
|
||||
assert request.unitPersonDayInfoList[2].date == datetime.datetime(2023, 1, 10, 0, 0)
|
||||
assert request.unitPersonDayInfoList[2].action == 'DEL_PRES_PREVI'
|
||||
assert request.unitPersonDayInfoList[3].numPerson == 613880
|
||||
assert request.unitPersonDayInfoList[3].idAct == 'A10049327682'
|
||||
assert request.unitPersonDayInfoList[3].idUni == 'A10049327683'
|
||||
assert request.unitPersonDayInfoList[3].date == datetime.datetime(2023, 1, 13, 0, 0)
|
||||
assert request.unitPersonDayInfoList[3].action == 'ADD_PRES_PREVI'
|
||||
|
||||
activity_service.add_soap_response(
|
||||
'updatePersonSchedule', get_xml_file('R_update_person_schedule.xml'), request_check=request_check
|
||||
)
|
||||
|
||||
params = {
|
||||
'child_id': '613880',
|
||||
'start_date': '2023-01-01',
|
||||
'end_date': '2023-01-15',
|
||||
'booking_list': [
|
||||
# '613880:A10049327689:2023-01-05', # remove this one
|
||||
'613880:A10049327682:2023-01-05',
|
||||
'613880:A10049327689:2023-01-06',
|
||||
# '613880:A10049327682:2023-01-10', # and this one
|
||||
'613880:A10049327689:2023-01-12',
|
||||
'613880:A10049327682:2023-01-12',
|
||||
'613880:A10049327689:2023-01-13',
|
||||
# but add:
|
||||
'613880:A10049327682:2023-01-06',
|
||||
'613880:A10049327682:2023-01-13',
|
||||
],
|
||||
}
|
||||
resp = app.post_json(url + '?NameID=local', params=params)
|
||||
assert resp.json == {
|
||||
'changes': [
|
||||
{
|
||||
'activity_id': 'A10049327682',
|
||||
'activity_label': 'Restauration scolaire',
|
||||
'booked': True,
|
||||
'day': '2023-01-06',
|
||||
},
|
||||
{
|
||||
'activity_id': 'A10049327682',
|
||||
'activity_label': 'Restauration scolaire',
|
||||
'booked': True,
|
||||
'day': '2023-01-13',
|
||||
},
|
||||
{
|
||||
'activity_id': 'A10049327689',
|
||||
'activity_label': 'Accueil du matin',
|
||||
'booked': False,
|
||||
'day': '2023-01-05',
|
||||
},
|
||||
{
|
||||
'activity_id': 'A10049327682',
|
||||
'activity_label': 'Restauration scolaire',
|
||||
'booked': False,
|
||||
'day': '2023-01-10',
|
||||
},
|
||||
],
|
||||
'count': 4,
|
||||
'err': 0,
|
||||
'updated': True,
|
||||
}
|
||||
|
||||
|
||||
def test_update_child_agenda_no_changes(activity_service, con, app):
|
||||
activity_service.add_soap_response(
|
||||
'getPersonScheduleList', get_xml_file('R_get_person_schedule_list.xml')
|
||||
)
|
||||
url = get_endpoint('update-child-agenda')
|
||||
Link.objects.create(resource=con, family_id='1312', name_id='local')
|
||||
|
||||
params = {
|
||||
'child_id': '613880',
|
||||
'start_date': '2023-01-01',
|
||||
'end_date': '2023-01-15',
|
||||
'booking_list': [
|
||||
'613880:A10049327689:2023-01-05',
|
||||
'613880:A10049327682:2023-01-05',
|
||||
'613880:A10049327689:2023-01-06',
|
||||
'613880:A10049327682:2023-01-10',
|
||||
'613880:A10049327689:2023-01-12',
|
||||
'613880:A10049327682:2023-01-12',
|
||||
'613880:A10049327689:2023-01-13',
|
||||
],
|
||||
}
|
||||
resp = app.post_json(url + '?NameID=local', params=params)
|
||||
assert resp.json == []
|
||||
|
||||
|
||||
def test_update_child_agenda_maelis_error(activity_service, con, app):
|
||||
activity_service.add_soap_response(
|
||||
'getPersonScheduleList', get_xml_file('R_get_person_schedule_list.xml')
|
||||
)
|
||||
url = get_endpoint('update-child-agenda')
|
||||
Link.objects.create(resource=con, family_id='1312', name_id='local')
|
||||
|
||||
activity_service.add_soap_response(
|
||||
'updatePersonSchedule', get_xml_file('R_update_person_schedule_error.xml')
|
||||
)
|
||||
|
||||
params = {
|
||||
'child_id': '613880',
|
||||
'start_date': '2023-01-01',
|
||||
'end_date': '2023-01-15',
|
||||
'booking_list': [
|
||||
'613880:A10049327682:2023-01-13',
|
||||
],
|
||||
}
|
||||
resp = app.post_json(url + '?NameID=local', params=params)
|
||||
assert resp.json['err'] == 'agenda-child-error'
|
||||
assert resp.json['err_desc'] == 'Foo ; Bar'
|
||||
|
||||
|
||||
def test_update_child_agenda_not_linked_error(con, app):
|
||||
url = get_endpoint('update-child-agenda')
|
||||
|
||||
params = {
|
||||
'child_id': '613880',
|
||||
'start_date': '2022-09-01',
|
||||
'end_date': '2023-08-31',
|
||||
'booking_list': [],
|
||||
}
|
||||
resp = app.post_json(url + '?NameID=local', params=params)
|
||||
assert resp.json['err'] == 'not-linked'
|
||||
assert resp.json['err_desc'] == 'User not linked to family'
|
||||
|
||||
|
||||
def test_update_child_agenda_date_error(con, app):
|
||||
url = get_endpoint('update-child-agenda')
|
||||
Link.objects.create(resource=con, family_id='1312', name_id='local')
|
||||
|
||||
params = {
|
||||
'child_id': '613880',
|
||||
'start_date': 'bad',
|
||||
'end_date': '2023-08-31',
|
||||
'booking_list': [],
|
||||
}
|
||||
resp = app.post_json(url + '?NameID=local', params=params, status=400)
|
||||
assert resp.json['err'] == 1
|
||||
assert resp.json['err_desc'] == "start_date: 'bad' does not match '^[0-9]{4}-[0-9]{2}-[0-9]{2}$'"
|
||||
|
||||
params = {
|
||||
'child_id': '613880',
|
||||
'start_date': '2022-09-01',
|
||||
'end_date': 'bad',
|
||||
'booking_list': [],
|
||||
}
|
||||
resp = app.post_json(url + '?NameID=local', params=params, status=400)
|
||||
assert resp.json['err'] == 1
|
||||
assert resp.json['err_desc'] == "end_date: 'bad' does not match '^[0-9]{4}-[0-9]{2}-[0-9]{2}$'"
|
||||
|
||||
params = {
|
||||
'child_id': '613880',
|
||||
'start_date': '2023-09-01',
|
||||
'end_date': '2023-08-31',
|
||||
'booking_list': [],
|
||||
}
|
||||
resp = app.post_json(url + '?NameID=local', params=params, status=400)
|
||||
assert resp.json['err'] == 'bad-request'
|
||||
assert resp.json['err_desc'] == 'start_date should be before end_date'
|
||||
|
||||
params = {
|
||||
'child_id': '613880',
|
||||
'start_date': '2022-09-01',
|
||||
'end_date': '2024-08-31',
|
||||
'booking_list': [],
|
||||
}
|
||||
resp = app.post_json(url + '?NameID=local', params=params, status=400)
|
||||
assert resp.json['err'] == 'bad-request'
|
||||
assert resp.json['err_desc'] == 'start_date and end_date are in different reference year (2022 != 2023)'
|
||||
|
|
Loading…
Reference in New Issue
Visiblement Sigec renvoie une réponse vide plutôt qu'une liste vide quand un enfant n'a pas d'inscription (ou de calendrier).
Je mettrais :
for result_data in result or []: