toulouse-maelis: add service criteria to catalog (#77084)
gitea/passerelle/pipeline/head This commit looks good Details

This commit is contained in:
Nicolas Roche 2023-05-10 18:53:20 +02:00 committed by Nicolas Roche
parent 8df0c9ec11
commit d176d9fc4b
3 changed files with 337 additions and 11 deletions

View File

@ -352,12 +352,12 @@ class ToulouseMaelis(BaseResource, HTTPResource):
return [x.item_data for x in queryset]
def get_referential_value(self, referential_name, key):
def get_referential_value(self, referential_name, key, default='key'):
try:
return self.referential.get(referential_name=referential_name, item_id=key).item_text
except Referential.DoesNotExist:
self.logger.warning("No '%s' key into Maelis '%s' referential", key, referential_name)
return key
return key if default == 'key' else None
def get_link(self, NameID):
try:
@ -2734,6 +2734,7 @@ class ToulouseMaelis(BaseResource, HTTPResource):
def read_activity_list(self, request, ref_date=None):
reference_year = utils.get_reference_year_from_date(ref_date or now())
labels = {
'service': 'Service',
'nature': "Nature de l'activité",
'type': "Type de l'activité",
'public': 'Public',
@ -2763,6 +2764,8 @@ class ToulouseMaelis(BaseResource, HTTPResource):
activities = catalogs[0]['data'] if catalogs else []
def add_criteria(label_key, criteria_key, criteria_value):
if not criteria_value:
return
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
@ -2789,19 +2792,23 @@ class ToulouseMaelis(BaseResource, HTTPResource):
activity['text'] = (
activity['activityPortail']['libelle2'] or activity['activityPortail']['libelle']
)
service_id = activity['activityPortail']['idService']
service_text = self.get_referential_value('Service', service_id, default=None)
activity['activityPortail']['idService_text'] = service_text
for label_key in criterias:
criterias[label_key]['data'] = {}
add_criteria('nature', activity_nature['code'], activity_nature['libelle'])
type_value = activity_type['libelle'].split('-')[0].strip()
add_criteria('type', slugify(type_value), type_value)
add_criteria('service', service_id, service_text)
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'])
update_criterias_order_field(criterias, ['service', 'nature', 'type', 'day'])
for unit in activity.pop('unitPortailList'):
unit['id'] = unit['idUnit']
@ -2839,7 +2846,7 @@ class ToulouseMaelis(BaseResource, HTTPResource):
'meta': {
'reference_year': reference_year,
'all_criterias': all_criterias,
'all_criterias_order': ['nature', 'type', 'public', 'day', 'place'],
'all_criterias_order': ['service', 'nature', 'type', 'public', 'day', 'place'],
},
}

View File

@ -6,6 +6,7 @@
<activityPortail>
<idAct>A10051141965</idAct>
<libelle>Vitrail Fusing 1/2 Je Adultes 2022/2023 - Mardi 14h-17h</libelle>
<idService>A10049329051</idService>
<dateStart>2022-09-01T00:00:00+02:00</dateStart>
<dateEnd>2023-06-30T00:00:00+02:00</dateEnd>
<birthControl>N</birthControl>
@ -624,6 +625,247 @@
</placeList>
</unitPortailList>
</activityUnitPlacePortailList>
<activityUnitPlacePortailList>
<activityPortail>
<idAct>A10056514645</idAct>
<libelle>TEST ECOLE DES SPORTS 22/23 SEMESTRE 2 - MULTIACTIVITES</libelle>
<blocNoteList>
<note>Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Maecenas porttitor congue massa. Fusce posuere, magna sed pulvinar ultricies, purus lectus malesuada libero, sit amet commodo magna eros quis</note>
<numIndex>1</numIndex>
</blocNoteList>
<dateStart>2023-02-01T00:00:00+01:00</dateStart>
<dateEnd>2023-06-30T00:00:00+02:00</dateEnd>
<birthControl>B</birthControl>
<schoolYear>2022</schoolYear>
<calendarGeneration>
<code>FORBIDDEN</code>
<value>I</value>
</calendarGeneration>
<calendarMode>C</calendarMode>
<activityType>
<code>1-AAQ</code>
<libelle>Activités Aquatiques 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>false</isOpen>
</dayWeekInfoList>
<dayWeekInfoList>
<dayNum>2</dayNum>
<isOpen>false</isOpen>
</dayWeekInfoList>
<dayWeekInfoList>
<dayNum>3</dayNum>
<isOpen>true</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>
</weeklyCalendarActivityList>
</activityPortail>
<openDayList>2023-02-01T00:00:00+01:00</openDayList>
<openDayList>2023-02-08T00:00:00+01:00</openDayList>
<openDayList>2023-02-15T00:00:00+01:00</openDayList>
<openDayList>2023-02-22T00:00:00+01:00</openDayList>
<openDayList>2023-03-01T00:00:00+01:00</openDayList>
<openDayList>2023-03-08T00:00:00+01:00</openDayList>
<openDayList>2023-03-15T00:00:00+01:00</openDayList>
<openDayList>2023-03-22T00:00:00+01:00</openDayList>
<openDayList>2023-03-29T00:00:00+02:00</openDayList>
<openDayList>2023-04-05T00:00:00+02:00</openDayList>
<openDayList>2023-04-12T00:00:00+02:00</openDayList>
<openDayList>2023-04-19T00:00:00+02:00</openDayList>
<openDayList>2023-04-26T00:00:00+02:00</openDayList>
<openDayList>2023-05-03T00:00:00+02:00</openDayList>
<openDayList>2023-05-10T00:00:00+02:00</openDayList>
<openDayList>2023-05-17T00:00:00+02:00</openDayList>
<openDayList>2023-05-24T00:00:00+02:00</openDayList>
<openDayList>2023-05-31T00:00:00+02:00</openDayList>
<openDayList>2023-06-07T00:00:00+02:00</openDayList>
<openDayList>2023-06-14T00:00:00+02:00</openDayList>
<openDayList>2023-06-21T00:00:00+02:00</openDayList>
<openDayList>2023-06-28T00:00:00+02:00</openDayList>
<unitPortailList>
<idUnit>A10056514650</idUnit>
<libelle>MERCREDI - 13h45/17h - 8/15Ans</libelle>
<dateStart>2023-02-01T00:00:00+01:00</dateStart>
<dateEnd>2023-06-30T00:00:00+02:00</dateEnd>
<birthDateStart>2008-01-01T00:00:00+01:00</birthDateStart>
<birthDateEnd>2015-12-31T00:00:00+01:00</birthDateEnd>
<calendarLetter>B</calendarLetter>
<subscribePublication>E</subscribePublication>
<numOrder>0</numOrder>
<calendarPublication>N</calendarPublication>
<recordAbsence>O</recordAbsence>
<placeList>
<id>A10053179757</id>
<lib>ARGOULETS</lib>
<adresse>
<num>0</num>
</adresse>
<startHour>13:45</startHour>
<endHour>17:00</endHour>
<capacityInfo>
<controlOK>true</controlOK>
</capacityInfo>
</placeList>
</unitPortailList>
<unitPortailList>
<idUnit>A10056514648</idUnit>
<libelle>MERCREDI - 14h/16h30 - 10/15Ans</libelle>
<dateStart>2023-02-01T00:00:00+01:00</dateStart>
<dateEnd>2023-06-30T00:00:00+02:00</dateEnd>
<birthDateStart>2008-01-01T00:00:00+01:00</birthDateStart>
<birthDateEnd>2013-12-31T00:00:00+01:00</birthDateEnd>
<calendarLetter>C</calendarLetter>
<subscribePublication>E</subscribePublication>
<numOrder>0</numOrder>
<calendarPublication>N</calendarPublication>
<recordAbsence>O</recordAbsence>
<placeList>
<id>A10053179876</id>
<lib>LA RAMEE</lib>
<adresse>
<num>0</num>
</adresse>
<startHour>14:00</startHour>
<endHour>16:30</endHour>
<capacityInfo>
<controlOK>true</controlOK>
</capacityInfo>
</placeList>
</unitPortailList>
<unitPortailList>
<idUnit>A10056514649</idUnit>
<libelle>MERCREDI - 15h30/17h - 8/15Ans</libelle>
<dateStart>2023-02-01T00:00:00+01:00</dateStart>
<dateEnd>2023-06-30T00:00:00+02:00</dateEnd>
<birthDateStart>2008-01-01T00:00:00+01:00</birthDateStart>
<birthDateEnd>2015-12-31T00:00:00+01:00</birthDateEnd>
<calendarLetter>F</calendarLetter>
<subscribePublication>E</subscribePublication>
<numOrder>0</numOrder>
<calendarPublication>N</calendarPublication>
<recordAbsence>O</recordAbsence>
<placeList>
<id>A10053179757</id>
<lib>ARGOULETS</lib>
<adresse>
<num>0</num>
</adresse>
<startHour>15:30</startHour>
<endHour>17:00</endHour>
<capacityInfo>
<controlOK>true</controlOK>
</capacityInfo>
</placeList>
</unitPortailList>
</activityUnitPlacePortailList>
<activityUnitPlacePortailList>
<activityPortail>
<idAct>A10056517594</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>A10056517595</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>

View File

@ -5972,12 +5972,29 @@ def test_read_activity_list(activity_service, con, app):
activity_service.add_soap_response('readActivityList', get_xml_file('R_read_activity_list.xml'))
url = get_endpoint('read-activity-list')
con.loisir_nature_codes = '4,L,, S '
con.loisir_nature_codes = '1,4,L,, S '
con.save()
params = {'ref_date': '2023-01-01'}
resp = app.get(url, params=params)
assert resp.json['err'] == 0
assert len(resp.json['data']) == 4
assert len(resp.json['data']) == 8
assert [
(
x['id'],
x['activity']['activityPortail']['idService'],
x['activity']['activityPortail']['idService_text'],
)
for x in resp.json['data']
] == [
('A10051141965-A10051141966-A10053179226', 'A10049329051', 'Sorties'),
('A10051141965-A10051141968-A10053179226', 'A10049329051', 'Sorties'),
('A10051141965-A10051141970-A10053179226', 'A10049329051', 'Sorties'),
('A10051141965-A10051141990-A10053179227', 'A10049329051', 'Sorties'),
('A10056514645-A10056514650-A10053179757', None, None),
('A10056514645-A10056514648-A10053179876', None, None),
('A10056514645-A10056514649-A10053179757', None, None),
('A10056517594-A10056517595-A10056517597', 'plop', None),
]
item = resp.json['data'][0]
item['activity'] = 'N/A'
item['unit'] = 'N/A'
@ -5991,6 +6008,11 @@ def test_read_activity_list(activity_service, con, app):
'unit': 'N/A',
'place': 'N/A',
'criterias': {
'service': {
'text': 'Service',
'data': {'A10049329051': 'Sorties'},
'order': ['A10049329051'],
},
'nature': {'text': "Nature de l'activité", 'data': {'4': 'ART PLASTIQUE'}, 'order': ['4']},
'type': {
'text': "Type de l'activité",
@ -6017,6 +6039,59 @@ def test_read_activity_list(activity_service, con, app):
'day': {'text': 'Jours', 'data': {'2': 'Mardi'}, 'order': ['2']},
},
}
assert resp.json['meta'] == {
'reference_year': 2022,
'all_criterias': {
'service': {'text': 'Service', 'data': {'A10049329051': 'Sorties'}, 'order': ['A10049329051']},
'nature': {
'text': "Nature de l'activité",
'data': {'4': 'ART PLASTIQUE', '1': 'Activités Régulières'},
'order': ['1', '4'],
},
'type': {
'text': "Type de l'activité",
'data': {
'activite-reguliere': 'ACTIVITE REGULIERE',
'activites-aquatiques-activite-reguliere': 'Activités Aquatiques Activité Réguliére',
'activite-pedestre-activite-reguliere': 'Activité Pédestre Activité régulière',
},
'order': [
'activite-reguliere',
'activite-pedestre-activite-reguliere',
'activites-aquatiques-activite-reguliere',
],
},
'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', '3': 'Mercredi', '1': 'Lundi', '4': 'Jeudi', '5': 'Vendredi'},
'order': ['1', '2', '3', '4', '5'],
},
'place': {
'text': 'Lieu',
'data': {
'A10053179226': 'Centre Culturel ALBAN MINVILLE',
'A10053179227': 'Un autre centre culturel',
'A10053179757': 'ARGOULETS',
'A10053179876': 'LA RAMEE',
'A10056517597': 'TERRITOIRE OUEST',
},
'order': ['A10053179757', 'A10053179226', 'A10053179876', 'A10056517597', 'A10053179227'],
},
},
'all_criterias_order': ['service', 'nature', 'type', 'public', 'day', 'place'],
}
# make sure activities have a single place defined
for item in resp.json['data']:
@ -6032,13 +6107,14 @@ def test_read_activity_list(activity_service, con, app):
'meta': {
'reference_year': 2022,
'all_criterias': {
'service': {'text': 'Service', 'data': {}, 'order': []},
'nature': {'text': "Nature de l'activité", 'data': {}, 'order': []},
'type': {'text': "Type de l'activité", 'data': {}, 'order': []},
'public': {'text': 'Public', 'data': {}, 'order': []},
'day': {'text': 'Jours', 'data': {}, 'order': []},
'place': {'text': 'Lieu', 'data': {}, 'order': []},
},
'all_criterias_order': ['nature', 'type', 'public', 'day', 'place'],
'all_criterias_order': ['service', 'nature', 'type', 'public', 'day', 'place'],
},
'err': 0,
}
@ -6072,7 +6148,7 @@ def test_read_activity_list_cache(mocked_get, con, app):
)
resp = app.get(url, params=params)
assert resp.json['err'] == 0
assert len(resp.json['data']) == 4
assert len(resp.json['data']) == 8
assert [x.item_id for x in Referential.objects.filter(referential_name='ActivityCatalog')] == [
'1969',
@ -6084,7 +6160,7 @@ def test_read_activity_list_cache(mocked_get, con, app):
mocked_post.side_effect = ReadTimeout('timeout')
resp = app.get(url, params=params)
assert resp.json['err'] == 0
assert len(resp.json['data']) == 4
assert len(resp.json['data']) == 8
@mock.patch('passerelle.utils.Request.get')
@ -6099,8 +6175,9 @@ def test_read_activity_list_no_nature(mocked_post, mocked_get, con, app):
def mocked_reply(referential_name, id=None):
queryset = con.referential.filter(referential_name=referential_name, item_id=id)
data = [x.item_data for x in queryset]
activity = data[0]['data'][0]
activity['activityPortail']['activityType'] = None
for item in data[0]['data']:
activity = item
activity['activityPortail']['activityType'] = None
return data
with mock.patch('passerelle.contrib.toulouse_maelis.models.ToulouseMaelis.get_referential') as mocked_ref: