toulouse-maelis: new endpoint to get activities (#73730)
gitea-wip/passerelle/pipeline/pr-main This commit looks good Details
gitea/passerelle/pipeline/head Something is wrong with the build of this commit Details

This commit is contained in:
Nicolas Roche 2023-01-23 15:10:14 +01:00
parent acef792d8d
commit 8c2330fdc6
3 changed files with 217 additions and 0 deletions

View File

@ -14,6 +14,7 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
import base64
import copy
import datetime
from operator import itemgetter
from urllib.parse import urljoin
@ -2163,6 +2164,107 @@ class ToulouseMaelis(BaseResource, HTTPResource):
response = self.call('Family', 'presubscribeSchoolSibling', **post_data)
return {'data': serialize_object(response)}
@endpoint(
display_category='Inscriptions',
description="Catalogue des activités loisir",
name='read-activity-list',
perm='can_access',
parameters={
'ref_date': {
'description': "Date de référence, utilisée pour déduire l'année scolaire",
'type': 'date',
},
},
)
def read_activity_list(self, request, ref_date):
reference_year = utils.get_reference_year_from_date(ref_date)
labels = {
'nature': "Nature de l'activité",
'type': "Type d'activité",
'public': 'Public',
'day': 'Jours',
}
day_names = ['Lundi', 'Mardi', 'Mercredi', 'Jeudi', 'Vendredi', 'Samedi', 'Dimanche']
all_criterias = {key: {'text': value, 'data': {}} for key, value in labels.items()}
criterias = {key: {'text': value, 'data': {}} for key, value in labels.items()}
catalogs = self.get_referential('ActivityCatalog', id=reference_year)
activities = catalogs[0]['data'] if catalogs else []
def add_criteria(label_key, criteria_key, criteria_value):
criterias[label_key]['data'][criteria_key] = criteria_value
if criteria_key not in all_criterias[label_key]['data']:
all_criterias[label_key]['data'][criteria_key] = criteria_value
def update_criterias_order_field(criterias_dict, label_keys=None):
if not label_keys:
label_keys = criterias_dict.keys()
for label_key in label_keys:
if label_key in ('public', 'day'):
criterias_dict[label_key]['order'] = sorted(x for x in criterias_dict[label_key]['data'])
else:
criterias_dict[label_key]['order'] = [
x[0]
for x in sorted(criterias_dict[label_key]['data'].items(), key=lambda x: x[1].lower())
]
data = []
for activity in activities:
if activity['activityPortail']['activityType']['natureSpec']['code'] not in ('P', 'L', 'S'):
continue
activity['id'] = activity['activityPortail']['idAct']
activity['text'] = activity['activityPortail']['libelle']
activity_type = activity['activityPortail']['activityType']
activity_nature = activity_type['natureSpec']
for label_key in criterias:
criterias[label_key]['data'] = {}
add_criteria('nature', activity_nature['code'], activity_nature['libelle'])
add_criteria('type', activity_type['code'], activity_type['libelle'])
if activity['activityPortail']['weeklyCalendarActivityList']:
for day in activity['activityPortail']['weeklyCalendarActivityList'][0]['dayWeekInfoList']:
if day['isOpen']:
add_criteria('day', str(day['dayNum']), day_names[day['dayNum'] - 1])
update_criterias_order_field(criterias, ['nature', 'type', 'day'])
for unit in activity.pop('unitPortailList'):
unit['id'] = unit['idUnit']
unit['text'] = unit['libelle']
criterias['public']['data'] = {}
for key, value in utils.get_public_criterias(
datetime.date.today(), unit['birthDateStart'], unit['birthDateEnd']
):
add_criteria('public', key, value)
update_criterias_order_field(criterias, ['public'])
for place in unit.pop('placeList'):
place['id'] = place['id']
place['text'] = place['lib2'] or place['lib']
data.append(
{
'id': '%s-%s-%s' % (activity['id'], unit['id'], place['id']),
'text': '%s, %s, %s' % (activity['text'], unit['text'], place['text']),
'activity': activity,
'unit': unit,
'place': place,
'criterias': copy.deepcopy(criterias),
}
)
update_criterias_order_field(all_criterias)
return {
'data': data,
'meta': {
'reference_year': reference_year,
'all_criterias': all_criterias,
'all_criterias_order': ['nature', 'type', 'public', 'day'],
},
}
@endpoint(
display_category='Inscriptions',
description="Catalogue des activités d'une personne",

View File

@ -13,6 +13,11 @@
# 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 math import inf
from dateutil.relativedelta import relativedelta
from django.utils.dateparse import parse_date
json_date_format = '%Y-%m-%d'
@ -21,3 +26,25 @@ def get_reference_year_from_date(some_date):
# between january and august, reference year is the year just before
return some_date.year - 1
return some_date.year
def get_public_criterias(today, start_dob, end_dob):
publics_txt = [
'Petit enfant (- de 3 ans)',
'Enfant (3-11 ans)',
'Ado (12-17 ans)',
'Jeune (18-25 ans)',
'Adulte (26-59 ans)',
'Sénior (60 ans et plus)',
]
ages = [0, 3, 12, 18, 26, 60, 62]
data = []
max_age = relativedelta(today, parse_date(start_dob[:10])).years if start_dob else inf
min_age = relativedelta(today, parse_date(end_dob[:10])).years if end_dob else 0
for i in range(0, len(ages) - 1):
for age in range(ages[i], ages[i + 1] - 1):
if min_age <= age <= max_age:
data.append((str(i), publics_txt[i]))
break
return data

View File

@ -21,10 +21,12 @@ from unittest import mock
import pytest
import responses
from django.utils.dateparse import parse_date
from requests.exceptions import ConnectionError
from zeep import Settings
from passerelle.contrib.toulouse_maelis.models import Link, Referential, ToulouseMaelis
from passerelle.contrib.toulouse_maelis.utils import get_public_criterias, json_date_format
from passerelle.utils.jsonresponse import APIError
from passerelle.utils.soap import SOAPError
from tests.utils import FakedResponse, ResponsesSoap, generic_endpoint_url, setup_access_rights
@ -4693,6 +4695,92 @@ def test_create_child_school_pre_registration_with_sibling(family_service, con,
assert resp.json['data']['derogComment'] == 'SERGHEI3 LISA'
@pytest.mark.parametrize(
'start_dob, end_dob, expected',
[
(
None,
None,
[
'Petit enfant (- de 3 ans)',
'Enfant (3-11 ans)',
'Ado (12-17 ans)',
'Jeune (18-25 ans)',
'Adulte (26-59 ans)',
'Sénior (60 ans et plus)',
],
),
('2011-01-01', '2020-12-31', ['Enfant (3-11 ans)', 'Ado (12-17 ans)']),
('2011-01-01', '2015-12-31', ['Enfant (3-11 ans)', 'Ado (12-17 ans)']),
('1900-01-01', '1963-01-01', ['Sénior (60 ans et plus)']),
('1963-01-02', '1997-01-01', ['Adulte (26-59 ans)']),
('1997-01-02', '2005-01-01', ['Jeune (18-25 ans)']),
('2005-01-02', '2011-01-01', ['Ado (12-17 ans)']),
('2011-01-02', '2020-01-01', ['Enfant (3-11 ans)']),
('2020-01-02', '2023-01-01', ['Petit enfant (- de 3 ans)']),
],
)
def test_get_public_criterias(start_dob, end_dob, expected):
today = parse_date('2023-01-01')
result = get_public_criterias(today, start_dob, end_dob)
assert expected == [x[1] for x in result]
def test_read_activity_list(con, app, freezer):
freezer.move_to('2023-01-01 12:00')
url = get_endpoint('read-activity-list')
params = {'ref_date': datetime.date.today().strftime(json_date_format)}
resp = app.get(url, params=params)
assert resp.json['err'] == 0
item = resp.json['data'][0]
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',
'activity': 'N/A',
'unit': 'N/A',
'place': 'N/A',
'criterias': {
'nature': {'text': "Nature de l'activité", 'data': {'P': 'Loisirs'}, 'order': ['P']},
'type': {'text': "Type d'activité", 'data': {'LOI_ADU': 'Loisirs Adultes'}, 'order': ['LOI_ADU']},
'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'],
},
'day': {'text': 'Jours', 'data': {'2': 'Mardi'}, 'order': ['2']},
},
}
resp = app.get(url + '?ref_date=1970-01-01')
assert resp.json == {
'data': [],
'meta': {
'reference_year': 1969,
'all_criterias': {
'nature': {'text': "Nature de l'activité", 'data': {}, 'order': []},
'type': {'text': "Type d'activité", 'data': {}, 'order': []},
'public': {'text': 'Public', 'data': {}, 'order': []},
'day': {'text': 'Jours', 'data': {}, 'order': []},
},
'all_criterias_order': ['nature', 'type', 'public', 'day'],
},
'err': 0,
}
def test_get_person_activity_list(activity_service, con, app):
def request_check(request):
assert request.yearSchool == 2022