toulouse-maelis: new endpoint to get activities (#73730)
This commit is contained in:
parent
0be7e95b74
commit
39164f0467
|
@ -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
|
||||
|
@ -2534,6 +2535,107 @@ class ToulouseMaelis(BaseResource, HTTPResource):
|
|||
def read_activity_nature_list(self, request):
|
||||
return {'data': self.get_referential('ActivityNatureType')}
|
||||
|
||||
@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', 'V'):
|
||||
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'],
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
class Link(models.Model):
|
||||
resource = models.ForeignKey(ToulouseMaelis, on_delete=models.CASCADE)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
@ -5694,3 +5696,194 @@ def test_read_activity_nature_list(con, app):
|
|||
],
|
||||
}
|
||||
|
||||
|
||||
@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
|
||||
item4 = resp.json['data'][4]
|
||||
item4['activity']['openDayList'] = 'N/A'
|
||||
item4['unit']['calendList'] = 'N/A'
|
||||
assert item4 == {
|
||||
'id': 'A10053187065-A10053187085-A10053179604',
|
||||
'text': 'Vacances Hivers 2023, Semaine 1, ALEX JANY',
|
||||
'activity': {
|
||||
'openDayList': 'N/A',
|
||||
'activityPortail': {
|
||||
'code': None,
|
||||
'email': None,
|
||||
'idAct': 'A10053187065',
|
||||
'dateEnd': '2023-03-03T00:00:00+01:00',
|
||||
'libelle': 'Vacances Hivers 2023',
|
||||
'dateStart': '2023-02-20T00:00:00+01:00',
|
||||
'schoolYear': 2022,
|
||||
'activityType': {
|
||||
'code': 'LOI_VAC',
|
||||
'libelle': 'Loisirs - Vacances',
|
||||
'natureSpec': {'code': 'V', 'libelle': 'Vacances Enfants'},
|
||||
},
|
||||
'birthControl': 'B',
|
||||
'calendarMode': 'C',
|
||||
'dateEndPubli': None,
|
||||
'schoolControl': None,
|
||||
'dateStartPubli': None,
|
||||
'activityBusList': [],
|
||||
'activityPeriodList': [],
|
||||
'calendarGeneration': {'code': 'FORBIDDEN', 'value': 'I'},
|
||||
'weeklyCalendarActivityList': [
|
||||
{
|
||||
'yearCalendar': 2023,
|
||||
'dayWeekInfoList': [
|
||||
{'dayNum': 1, 'isOpen': True},
|
||||
{'dayNum': 2, 'isOpen': True},
|
||||
{'dayNum': 3, 'isOpen': True},
|
||||
{'dayNum': 4, 'isOpen': True},
|
||||
{'dayNum': 5, 'isOpen': True},
|
||||
{'dayNum': 6, 'isOpen': False},
|
||||
{'dayNum': 7, 'isOpen': False},
|
||||
],
|
||||
}
|
||||
],
|
||||
},
|
||||
'id': 'A10053187065',
|
||||
'text': 'Vacances Hivers 2023',
|
||||
},
|
||||
'unit': {
|
||||
'idUnit': 'A10053187085',
|
||||
'codeExt': None,
|
||||
'dateEnd': '2023-02-24T00:00:00+01:00',
|
||||
'libelle': 'Semaine 1',
|
||||
'numOrder': 0,
|
||||
'dateStart': '2023-02-20T00:00:00+01:00',
|
||||
'calendList': 'N/A',
|
||||
'birthDateEnd': '2020-12-31T00:00:00+01:00',
|
||||
'recordAbsence': 'N',
|
||||
'birthDateStart': '2011-01-01T00:00:00+01:00',
|
||||
'calendarLetter': 'B',
|
||||
'dateEndSubscribe': None,
|
||||
'dateStartSubscribe': None,
|
||||
'calendarPublication': 'L',
|
||||
'subscribePublication': 'E',
|
||||
'id': 'A10053187085',
|
||||
'text': 'Semaine 1',
|
||||
},
|
||||
'place': {
|
||||
'id': 'A10053179604',
|
||||
'lib': 'ALEX JANY',
|
||||
'lib2': None,
|
||||
'obs1': None,
|
||||
'obs2': None,
|
||||
'numTel': None,
|
||||
'adresse': {
|
||||
'num': 0,
|
||||
'town': None,
|
||||
'street1': None,
|
||||
'street2': None,
|
||||
'zipcode': None,
|
||||
'idStreet': None,
|
||||
},
|
||||
'activityPeriscolList': [],
|
||||
'text': 'ALEX JANY',
|
||||
},
|
||||
'criterias': {
|
||||
'nature': {'text': "Nature de l'activité", 'data': {'V': 'Vacances Enfants'}, 'order': ['V']},
|
||||
'type': {
|
||||
'text': "Type d'activité",
|
||||
'data': {'LOI_VAC': 'Loisirs - Vacances'},
|
||||
'order': ['LOI_VAC'],
|
||||
},
|
||||
'public': {
|
||||
'text': 'Public',
|
||||
'data': {'1': 'Enfant (3-11 ans)', '2': 'Ado (12-17 ans)'},
|
||||
'order': ['1', '2'],
|
||||
},
|
||||
'day': {
|
||||
'text': 'Jours',
|
||||
'data': {'1': 'Lundi', '2': 'Mardi', '3': 'Mercredi', '4': 'Jeudi', '5': 'Vendredi'},
|
||||
'order': ['1', '2', '3', '4', '5'],
|
||||
},
|
||||
},
|
||||
}
|
||||
assert resp.json['meta'] == {
|
||||
'reference_year': 2022,
|
||||
'all_criterias': {
|
||||
'nature': {
|
||||
'text': "Nature de l'activité",
|
||||
'data': {'P': 'Loisirs', 'V': 'Vacances Enfants'},
|
||||
'order': ['P', 'V'],
|
||||
},
|
||||
'type': {
|
||||
'text': "Type d'activité",
|
||||
'data': {'LOI_ADU': 'Loisirs Adultes', 'LOI_VAC': 'Loisirs - Vacances'},
|
||||
'order': ['LOI_VAC', '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', '1': 'Lundi', '3': 'Mercredi', '4': 'Jeudi', '5': 'Vendredi'},
|
||||
'order': ['1', '2', '3', '4', '5'],
|
||||
},
|
||||
},
|
||||
'all_criterias_order': ['nature', 'type', 'public', 'day'],
|
||||
}
|
||||
|
||||
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,
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue