caluire-axel: get_agenda_full endpoint (#55551)

This commit is contained in:
Lauréline Guérin 2021-07-15 11:45:18 +02:00
parent 3222eee85e
commit 7716ad46b1
No known key found for this signature in database
GPG Key ID: 1FAB9B9B4F93D473
2 changed files with 268 additions and 42 deletions

View File

@ -686,6 +686,55 @@ class CaluireAxel(BaseResource):
)
return {'data': bookings}
def _get_child_agenda(self, request, NameID, idpersonne, start_date, end_date, full=False):
link = self.get_link(NameID)
start_date, end_date, reference_year = self.get_start_and_end_dates(start_date, end_date)
child_data = self.get_child_data(link.family_id, idpersonne)
if child_data is None:
raise APIError('Child not found', err_code='not-found')
activities_data = self.get_child_activities(idpersonne, reference_year)
bookings = []
for activity in activities_data.get('ACTIVITE', []):
activity_id = activity['IDENTACTIVITE']
activity_label = activity['LIBELLEACTIVITE']
if activity_id.startswith('CJ') and not full:
# mercredi or vacances: ignore it
continue
bookings += self.get_bookings(
idpersonne,
activity_id,
start_date,
end_date,
activity_label=activity_label,
ignore_wednesday=not (full),
ignore_weekend=True,
)
# sort bookings
activity_types = ['matin', 'midi', 'soir', 'mercredi', 'vacances']
bookings = [
(
b['details']['JOURDATE'],
activity_types.index(b['details']['activity_type']),
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 {
'data': bookings,
'extra_data': {
'start_date': start_date,
'end_date': end_date,
'school_year': '%s/%s' % (reference_year, reference_year + 1),
},
}
@endpoint(
display_category=_('Schooling'),
display_order=6,
@ -699,46 +748,22 @@ class CaluireAxel(BaseResource):
},
)
def get_agenda_periscolaire(self, request, NameID, idpersonne, start_date, end_date):
link = self.get_link(NameID)
start_date, end_date, reference_year = self.get_start_and_end_dates(start_date, end_date)
return self._get_child_agenda(request, NameID, idpersonne, start_date, end_date)
child_data = self.get_child_data(link.family_id, idpersonne)
if child_data is None:
raise APIError('Child not found', err_code='not-found')
activities_data = self.get_child_activities(idpersonne, reference_year)
bookings = []
for activity in activities_data.get('ACTIVITE', []):
activity_id = activity['IDENTACTIVITE']
activity_label = activity['LIBELLEACTIVITE']
if activity_id.startswith('CJ'):
# mercredi or vacances: ignore it
continue
bookings += self.get_bookings(
idpersonne,
activity_id,
start_date,
end_date,
activity_label=activity_label,
ignore_wednesday=True,
ignore_weekend=True,
)
# sort bookings
activity_types = ['matin', 'midi', 'soir']
bookings = [
(
b['details']['JOURDATE'],
activity_types.index(b['details']['activity_type']),
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 {'data': bookings}
@endpoint(
display_category=_('Schooling'),
display_order=7,
description=_("Get full agenda for a child"),
perm='can_access',
parameters={
'NameID': {'description': _('Publik ID')},
'idpersonne': {'description': _('Child ID')},
'start_date': {'description': _('Start date of the period')},
'end_date': {'description': _('End date of the period')},
},
)
def get_agenda_full(self, request, NameID, idpersonne, start_date, end_date):
return self._get_child_agenda(request, NameID, idpersonne, start_date, end_date, full=True)
def set_bookings(self, child_id, activity_id, start_date, end_date, booking_list):
agenda = self.get_bookings(child_id, activity_id, start_date, end_date)
@ -807,7 +832,7 @@ class CaluireAxel(BaseResource):
@endpoint(
display_category=_('Schooling'),
display_order=7,
display_order=8,
description=_("Set agenda for a child"),
perm='can_access',
parameters={
@ -886,7 +911,7 @@ class CaluireAxel(BaseResource):
@endpoint(
display_category=_('Schooling'),
display_order=7,
display_order=9,
description=_("Set activity agenda for a child with a typical week"),
perm='can_access',
parameters={

View File

@ -125,7 +125,7 @@ def activities_full():
'ENTREE': '2020-09-02',
'SORTIE': '2021-08-31',
'IDENTACTIVITE': 'CJ1',
'LIBELLEACTIVITE': 'Des vacances', # ignored
'LIBELLEACTIVITE': 'Des vacances',
},
{
'ENTREE': '2020-09-02',
@ -1552,6 +1552,207 @@ def test_get_agenda_periscolaire_endpoint_wrong_code(app, resource, family_data,
assert resp.json['err'] == 'agenda-code-error-%s' % code
def test_get_agenda_full_endpoint_axel_error(app, resource, family_data):
Link.objects.create(resource=resource, name_id='yyy', family_id='XXX', person_id='42')
with mock.patch('passerelle.contrib.caluire_axel.schemas.get_famille_individus') as operation:
operation.side_effect = AxelError('FooBar')
resp = app.get(
'/caluire-axel/test/get_agenda_full?NameID=yyy&idpersonne=50632&start_date=2020-09-01&end_date=2021-08-31'
)
assert resp.json['err_desc'] == "Axel error: FooBar"
assert resp.json['err'] == 'error'
filepath = os.path.join(os.path.dirname(__file__), 'data/caluire_axel/family_info.xml')
with open(filepath) as xml:
content = xml.read()
with mock_data(content, 'GetFamilleIndividus'):
with mock.patch('passerelle.contrib.caluire_axel.schemas.get_list_activites') as operation:
operation.side_effect = AxelError('FooBar')
resp = app.get(
'/caluire-axel/test/get_agenda_full?NameID=yyy&idpersonne=50632&start_date=2020-09-01&end_date=2021-08-31'
)
assert resp.json['err_desc'] == "Axel error: FooBar"
assert resp.json['err'] == 'error'
filepath = os.path.join(os.path.dirname(__file__), 'data/caluire_axel/activities_info.xml')
with open(filepath) as xml:
content = xml.read()
with mock_data(content, 'GetListActivites'):
with mock.patch(
'passerelle.contrib.caluire_axel.models.CaluireAxel.get_family_data',
return_value=family_data,
):
with mock.patch('passerelle.contrib.caluire_axel.schemas.get_agenda') as operation:
operation.side_effect = AxelError('FooBar')
resp = app.get(
'/caluire-axel/test/get_agenda_full?NameID=yyy&idpersonne=50632&start_date=2020-09-01&end_date=2021-08-31'
)
assert resp.json['err_desc'] == "Axel error: FooBar"
assert resp.json['err'] == 'error'
@pytest.mark.parametrize('value', ['foo', '20/01/2020', '2020'])
def test_get_agenda_full_endpoint_bad_date_format(app, resource, value):
Link.objects.create(resource=resource, name_id='yyy', family_id='XXX', person_id='42')
resp = app.get(
'/caluire-axel/test/get_agenda_full?NameID=yyy&idpersonne=50632&start_date=%s&end_date=2021-08-31'
% value,
status=400,
)
assert resp.json['err_desc'] == "bad date format, should be YYYY-MM-DD"
assert resp.json['err'] == 'bad-request'
resp = app.get(
'/caluire-axel/test/get_agenda_full?NameID=yyy&idpersonne=50632&start_date=2020-09-01&end_date=%s'
% value,
status=400,
)
assert resp.json['err_desc'] == "bad date format, should be YYYY-MM-DD"
assert resp.json['err'] == 'bad-request'
def test_get_agenda_full_endpoint_no_result(app, resource):
resp = app.get(
'/caluire-axel/test/get_agenda_full?NameID=yyy&idpersonne=50632&start_date=2020-09-01&end_date=2021-08-31'
)
assert resp.json['err_desc'] == "Person not found"
assert resp.json['err'] == 'not-found'
Link.objects.create(resource=resource, name_id='yyy', family_id='XXX', person_id='42')
filepath = os.path.join(os.path.dirname(__file__), 'data/caluire_axel/family_info.xml')
with open(filepath) as xml:
content = xml.read()
with mock_data(content, 'GetFamilleIndividus'):
resp = app.get(
'/caluire-axel/test/get_agenda_full?NameID=yyy&idpersonne=zzz&start_date=2020-09-01&end_date=2021-08-31'
)
assert resp.json['err_desc'] == "Child not found"
assert resp.json['err'] == 'not-found'
def test_get_agenda_full_endpoint_date_error(app, resource):
Link.objects.create(resource=resource, name_id='yyy', family_id='XXX', person_id='42')
filepath = os.path.join(os.path.dirname(__file__), 'data/caluire_axel/family_info.xml')
with open(filepath) as xml:
content = xml.read()
with mock_data(content, 'GetFamilleIndividus'):
resp = app.get(
'/caluire-axel/test/get_agenda_full?NameID=yyy&idpersonne=50632&start_date=2021-05-31&end_date=2021-05-30',
status=400,
)
assert resp.json['err_desc'] == "start_date should be before end_date"
assert resp.json['err'] == 'bad-request'
resp = app.get(
'/caluire-axel/test/get_agenda_full?NameID=yyy&idpersonne=50632&start_date=2021-09-01&end_date=2022-09-01',
status=400,
)
assert (
resp.json['err_desc'] == "start_date and end_date are in different reference year (2021 != 2022)"
)
assert resp.json['err'] == 'bad-request'
def test_get_agenda_full_endpoint(app, resource, family_data, activities_full):
Link.objects.create(resource=resource, name_id='yyy', family_id='XXX', person_id='42')
content = '''<PORTAIL>
<GETAGENDA>
<CODE>7</CODE>
<JOUR>
<JOURDATE>26/10/2020</JOURDATE>
<MATIN>.</MATIN>
<MIDI></MIDI>
<APRESMIDI></APRESMIDI>
<FERME>N</FERME>
</JOUR>
<JOUR>
<JOURDATE>27/10/2020</JOURDATE>
<MATIN>.</MATIN>
<MIDI></MIDI>
<APRESMIDI></APRESMIDI>
<FERME>N</FERME>
</JOUR>
<JOUR>
<JOURDATE>28/10/2020</JOURDATE>
<MATIN>.</MATIN>
<MIDI></MIDI>
<APRESMIDI></APRESMIDI>
<FERME>N</FERME>
</JOUR>
<JOUR>
<JOURDATE>29/10/2020</JOURDATE>
<MATIN>.</MATIN>
<MIDI></MIDI>
<APRESMIDI></APRESMIDI>
<FERME>N</FERME>
</JOUR>
<JOUR>
<JOURDATE>30/10/2020</JOURDATE>
<MATIN>.</MATIN>
<MIDI></MIDI>
<APRESMIDI></APRESMIDI>
<FERME>N</FERME>
</JOUR>
<JOUR>
<JOURDATE>31/10/2020</JOURDATE>
<MATIN>.</MATIN>
<MIDI></MIDI>
<APRESMIDI></APRESMIDI>
<FERME>N</FERME>
</JOUR>
<JOUR>
<JOURDATE>01/11/2020</JOURDATE>
<MATIN>.</MATIN>
<MIDI></MIDI>
<APRESMIDI></APRESMIDI>
<FERME>N</FERME>
</JOUR>
</GETAGENDA>
</PORTAIL>'''
with mock_data(content, 'GetAgenda'):
with mock.patch(
'passerelle.contrib.caluire_axel.models.CaluireAxel.get_family_data',
return_value=family_data,
):
with mock.patch(
'passerelle.contrib.caluire_axel.models.CaluireAxel.get_child_activities',
return_value=activities_full,
):
resp = app.get(
'/caluire-axel/test/get_agenda_full?NameID=yyy&idpersonne=50632&start_date=2020-09-01&end_date=2021-08-31'
)
assert len(resp.json['data']) == 30
assert resp.json['data'][0]['id'] == '50632:ACCMAT:2020-10-26'
assert resp.json['data'][1]['id'] == '50632:ECOLELEM:2020-10-26'
assert resp.json['data'][2]['id'] == '50632:ETUDES:2020-10-26'
assert resp.json['data'][3]['id'] == '50632:GARDERIES:2020-10-26'
assert resp.json['data'][4]['id'] == '50632:CJ MER:2020-10-26'
assert resp.json['data'][5]['id'] == '50632:CJ1:2020-10-26'
assert resp.json['data'][6]['id'] == '50632:ACCMAT:2020-10-27'
assert resp.json['data'][7]['id'] == '50632:ECOLELEM:2020-10-27'
assert resp.json['data'][8]['id'] == '50632:ETUDES:2020-10-27'
assert resp.json['data'][9]['id'] == '50632:GARDERIES:2020-10-27'
assert resp.json['data'][10]['id'] == '50632:CJ MER:2020-10-27'
assert resp.json['data'][11]['id'] == '50632:CJ1:2020-10-27'
assert resp.json['data'][12]['id'] == '50632:ACCMAT:2020-10-28'
assert resp.json['data'][13]['id'] == '50632:ECOLELEM:2020-10-28'
assert resp.json['data'][14]['id'] == '50632:ETUDES:2020-10-28'
assert resp.json['data'][15]['id'] == '50632:GARDERIES:2020-10-28'
assert resp.json['data'][16]['id'] == '50632:CJ MER:2020-10-28'
assert resp.json['data'][17]['id'] == '50632:CJ1:2020-10-28'
assert resp.json['data'][18]['id'] == '50632:ACCMAT:2020-10-29'
assert resp.json['data'][19]['id'] == '50632:ECOLELEM:2020-10-29'
assert resp.json['data'][20]['id'] == '50632:ETUDES:2020-10-29'
assert resp.json['data'][21]['id'] == '50632:GARDERIES:2020-10-29'
assert resp.json['data'][22]['id'] == '50632:CJ MER:2020-10-29'
assert resp.json['data'][23]['id'] == '50632:CJ1:2020-10-29'
assert resp.json['data'][24]['id'] == '50632:ACCMAT:2020-10-30'
assert resp.json['data'][25]['id'] == '50632:ECOLELEM:2020-10-30'
assert resp.json['data'][26]['id'] == '50632:ETUDES:2020-10-30'
assert resp.json['data'][27]['id'] == '50632:GARDERIES:2020-10-30'
assert resp.json['data'][28]['id'] == '50632:CJ MER:2020-10-30'
assert resp.json['data'][29]['id'] == '50632:CJ1:2020-10-30'
@freezegun.freeze_time('2020-09-01')
def test_set_agenda_endpoint_axel_error(app, resource, family_data, activities, booking_params):
Link.objects.create(resource=resource, name_id='yyy', family_id='XXX', person_id='42')