toulouse-maelis: add direction to activity data (#86068) #449
|
@ -179,13 +179,14 @@ class ToulouseMaelis(BaseResource, HTTPResource):
|
|||
id_key = item['activityPortail']['idAct']
|
||||
text = item['activityPortail'].get('libelle2') or item['activityPortail']['libelle'] or ''
|
||||
text = text.strip()
|
||||
service = self.get_referential_item_data('Service', item['activityPortail'].get('idService'))
|
||||
self.referential.update_or_create(
|
||||
resource_id=self.id,
|
||||
referential_name='Activity',
|
||||
item_id=id_key,
|
||||
defaults={
|
||||
'item_text': text,
|
||||
'item_data': dict({'id': id_key, 'text': text}, **item),
|
||||
'item_data': dict({'id': id_key, 'text': text, 'service': service}, **item),
|
||||
'updated': last_update,
|
||||
},
|
||||
)
|
||||
|
@ -259,6 +260,14 @@ class ToulouseMaelis(BaseResource, HTTPResource):
|
|||
if referential_name in ['Direct', 'Service']:
|
||||
id_key, text_key = 'id', 'lib1'
|
||||
self.update_referential(referential_name, data, id_key, text_key)
|
||||
|
||||
# add Direct data on Service entries
|
||||
for service in self.referential.filter(referential_name='Service'):
|
||||
service.item_data['direction'] = self.get_referential_item_data(
|
||||
'Direct', service.item_data['idDir']
|
||||
)
|
||||
service.save()
|
||||
|
||||
self.update_catalog_referential()
|
||||
|
||||
def update_ape_referentials(self):
|
||||
|
@ -406,7 +415,7 @@ class ToulouseMaelis(BaseResource, HTTPResource):
|
|||
self.trigger_subscriptions_cron()
|
||||
self.update_referentials()
|
||||
|
||||
def get_referential(self, referential_name, id=None, q=None, limit=None, distinct=True):
|
||||
def get_referential(self, referential_name, id=None, q=None, limit=None, distinct=True, **kwargs):
|
||||
if id is not None:
|
||||
queryset = self.referential.filter(referential_name=referential_name, item_id=id)
|
||||
else:
|
||||
|
@ -414,6 +423,9 @@ class ToulouseMaelis(BaseResource, HTTPResource):
|
|||
if q:
|
||||
queryset = queryset.filter(item_unaccent_text__icontains=simplify(q))
|
||||
|
||||
if kwargs:
|
||||
queryset = queryset.filter(**kwargs)
|
||||
|
||||
if distinct:
|
||||
queryset = queryset.distinct('resource', 'referential_name', 'item_text')
|
||||
|
||||
|
@ -435,6 +447,12 @@ class ToulouseMaelis(BaseResource, HTTPResource):
|
|||
self.logger.warning("No '%s' key into Maelis '%s' referential", key, referential_name)
|
||||
return key if default == 'key' else None
|
||||
|
||||
def get_referential_item_data(self, referential_name, key):
|
||||
try:
|
||||
return self.referential.get(referential_name=referential_name, item_id=key).item_data
|
||||
except Referential.DoesNotExist:
|
||||
return None
|
||||
|
||||
def get_link(self, NameID):
|
||||
try:
|
||||
return self.link_set.get(name_id=NameID)
|
||||
|
@ -865,6 +883,9 @@ class ToulouseMaelis(BaseResource, HTTPResource):
|
|||
if nature_filter_codes:
|
||||
if not activity_nature or activity_nature['code'] not in nature_filter_codes:
|
||||
continue
|
||||
item['activity']['service'] = self.get_referential_item_data(
|
||||
'Service', item['activity'].get('idService')
|
||||
)
|
||||
activities.append(item)
|
||||
data['catalogueActivityList'] = activities
|
||||
return data
|
||||
|
@ -1042,6 +1063,20 @@ class ToulouseMaelis(BaseResource, HTTPResource):
|
|||
def read_dietcode_list(self, request, id=None, q=None, limit=None, distinct=True):
|
||||
return {'data': self.get_referential('DietCode', id, q, limit, distinct)}
|
||||
|
||||
@endpoint(
|
||||
display_category='Inscriptions',
|
||||
description='Lister les directions de la ville',
|
||||
name='read-direction-list',
|
||||
parameters={
|
||||
'id': {'description': 'Identifiant de l’enregistrement'},
|
||||
'q': {'description': 'Recherche en texte intégral'},
|
||||
'limit': {'description': 'Nombre maximal de résultats; doit être inférieur à 20.'},
|
||||
'distinct': {'description': 'Ne pas inclure les valeurs dupliquées'},
|
||||
},
|
||||
)
|
||||
def read_direction_list(self, request, id=None, q=None, limit=None, distinct=True):
|
||||
return {'data': self.get_referential('Direct', id, q, limit, distinct)}
|
||||
|
||||
@endpoint(
|
||||
display_category='Famille',
|
||||
description='Lister les pièces jointes',
|
||||
|
@ -1068,7 +1103,7 @@ class ToulouseMaelis(BaseResource, HTTPResource):
|
|||
},
|
||||
)
|
||||
def read_organ_list(self, request, id=None, q=None, limit=None, distinct=True):
|
||||
return {'data': self.get_referential('Organ')}
|
||||
return {'data': self.get_referential('Organ', id, q, limit, distinct)}
|
||||
|
||||
@endpoint(
|
||||
display_category='Famille',
|
||||
|
@ -1138,7 +1173,25 @@ class ToulouseMaelis(BaseResource, HTTPResource):
|
|||
},
|
||||
)
|
||||
def read_rl_indicator_list(self, request, id=None, q=None, limit=None, distinct=True):
|
||||
return {'data': self.get_referential('RLIndicator')}
|
||||
return {'data': self.get_referential('RLIndicator', id, q, limit, distinct)}
|
||||
|
||||
@endpoint(
|
||||
display_category='Inscriptions',
|
||||
description='Lister les services de la ville',
|
||||
name='read-service-list',
|
||||
parameters={
|
||||
'id': {'description': 'Identifiant de l’enregistrement'},
|
||||
'q': {'description': 'Recherche en texte intégral'},
|
||||
'limit': {'description': 'Nombre maximal de résultats; doit être inférieur à 20.'},
|
||||
'distinct': {'description': 'Ne pas inclure les valeurs dupliquées'},
|
||||
'direction_id': {'description': 'Numéro de la direction sur laquelle filtrer'},
|
||||
},
|
||||
)
|
||||
def read_service_list(self, request, id=None, q=None, limit=None, distinct=True, direction_id=None):
|
||||
kwargs = {}
|
||||
if direction_id:
|
||||
kwargs['item_data__idDir'] = direction_id
|
||||
return {'data': self.get_referential('Service', id, q, limit, distinct, **kwargs)}
|
||||
|
||||
@endpoint(
|
||||
display_category='Famille',
|
||||
|
@ -3316,26 +3369,6 @@ class ToulouseMaelis(BaseResource, HTTPResource):
|
|||
groups[group['id']] = types
|
||||
return {'data': data, 'meta': groups}
|
||||
|
||||
@endpoint(
|
||||
display_category='Inscriptions',
|
||||
description='Lister les directions de la ville',
|
||||
name='read-direction-list',
|
||||
)
|
||||
def read_direction_list(self, request):
|
||||
return {'data': self.get_referential('Direct')}
|
||||
|
||||
@endpoint(
|
||||
display_category='Inscriptions',
|
||||
description='Lister les services de la ville',
|
||||
name='read-service-list',
|
||||
parameters={'direction_id': {'description': 'Numéro de la direction sur laquelle filtrer'}},
|
||||
)
|
||||
def read_service_list(self, request, direction_id=None):
|
||||
queryset = self.referential.filter(referential_name='Service')
|
||||
if direction_id:
|
||||
queryset = queryset.filter(item_data__idDir=direction_id)
|
||||
return {'data': [x.item_data for x in queryset]}
|
||||
|
||||
@endpoint(
|
||||
display_category='Inscriptions',
|
||||
description='Lister les indicateurs pour les activités petite enfance',
|
||||
|
@ -4049,6 +4082,7 @@ class ToulouseMaelis(BaseResource, HTTPResource):
|
|||
item['unit_id'] = item['unit_ids'].get(code_psu)
|
||||
if item['libelle2']:
|
||||
item['text'] = item['libelle2']
|
||||
item['service'] = self.get_referential_item_data('Service', item.get('idService'))
|
||||
return {'data': nurseries}
|
||||
|
||||
@endpoint(
|
||||
|
@ -4105,6 +4139,7 @@ class ToulouseMaelis(BaseResource, HTTPResource):
|
|||
'id': '%s:%s:%s' % (item['activity_id'], item['unit_id'], item['place_id']),
|
||||
'text': unit['libelle'],
|
||||
'unit': unit,
|
||||
'service': self.get_referential_item_data('Service', item.get('idService')),
|
||||
},
|
||||
}
|
||||
)
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
<code>CRECHCO</code><libelle>Crèche collective</libelle>
|
||||
</activityType>
|
||||
<idActivity>M10000000004</idActivity><libelle>CC BOULE DE GOMME</libelle>
|
||||
<idService>A10049329043</idService>
|
||||
<idService>A10049327627</idService>
|
||||
<manager1>
|
||||
<lastname>SARRIMANE</lastname><firstname>Valerie</firstname><phone>05 61 62 08 49</phone><poste>ASSO</poste>
|
||||
</manager1>
|
||||
|
@ -234,7 +234,7 @@
|
|||
<libelle>Crèche collective</libelle>
|
||||
</activityType>
|
||||
<idActivity>M10000000001</idActivity>
|
||||
<idService>A10049327627</idService>
|
||||
<idService>A10049329043</idService>
|
||||
<libelle>CC AMIDONNIERS</libelle>
|
||||
<manager1>
|
||||
<lastname>THOMAS</lastname>
|
||||
|
|
|
@ -96,6 +96,7 @@
|
|||
</activityType>
|
||||
<typInsPortal>I</typInsPortal>
|
||||
<paiementPortal>I</paiementPortal>
|
||||
<idService>A10049329051</idService>
|
||||
</activity>
|
||||
<unitInfoList>
|
||||
<idUnit>A10053187241</idUnit>
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
<ServiceBean>
|
||||
<id>A10049329042</id>
|
||||
<lib1>CCAS</lib1>
|
||||
<idDir>A10049327620</idDir>
|
||||
<idDir>plop</idDir>
|
||||
</ServiceBean>
|
||||
<ServiceBean>
|
||||
<id>A10049329043</id>
|
||||
|
|
|
@ -1077,7 +1077,28 @@ def test_read_csp_list(con, app):
|
|||
]
|
||||
|
||||
|
||||
def test_read_direct_list(con, app):
|
||||
def test_read_dietcode_list(con, app):
|
||||
url = get_endpoint('read-dietcode-list')
|
||||
resp = app.get(url)
|
||||
assert resp.json['err'] == 0
|
||||
assert resp.json['data'] == [
|
||||
{'id': 'STD', 'code': 'STD', 'text': '1- REPAS STANDARD', 'libelle': '1- REPAS STANDARD'},
|
||||
{'id': 'RSP', 'code': 'RSP', 'text': '2- RÉGIME SANS PORC', 'libelle': '2- RÉGIME SANS PORC'},
|
||||
{'id': 'RSV', 'code': 'RSV', 'text': '3- RÉGIME SANS VIANDE', 'libelle': '3- RÉGIME SANS VIANDE'},
|
||||
{
|
||||
'id': 'PAI',
|
||||
'code': 'PAI',
|
||||
'text': "4- PROTOCOLE D'ACCUEIL INDIVIDUALISÉ",
|
||||
'libelle': "4- PROTOCOLE D'ACCUEIL INDIVIDUALISÉ",
|
||||
},
|
||||
{'id': 'BB', 'code': 'BB', 'text': 'REPAS BEBE', 'libelle': 'REPAS BEBE'},
|
||||
{'id': 'MSP', 'code': 'MSP', 'text': 'REPAS MOYEN SANS PORC', 'libelle': 'REPAS MOYEN SANS PORC'},
|
||||
{'id': 'MSV', 'code': 'MSV', 'text': 'REPAS MOYEN SANS VIANDE', 'libelle': 'REPAS MOYEN SANS VIANDE'},
|
||||
{'id': 'MST', 'code': 'MST', 'text': 'REPAS MOYEN STANDARD', 'libelle': 'REPAS MOYEN STANDARD'},
|
||||
]
|
||||
|
||||
|
||||
def test_read_direction_list(con, app):
|
||||
url = get_endpoint('read-direction-list')
|
||||
resp = app.get(url)
|
||||
assert resp.json['err'] == 0
|
||||
|
@ -1106,27 +1127,6 @@ def test_read_direct_list(con, app):
|
|||
]
|
||||
|
||||
|
||||
def test_read_dietcode_list(con, app):
|
||||
url = get_endpoint('read-dietcode-list')
|
||||
resp = app.get(url)
|
||||
assert resp.json['err'] == 0
|
||||
assert resp.json['data'] == [
|
||||
{'id': 'STD', 'code': 'STD', 'text': '1- REPAS STANDARD', 'libelle': '1- REPAS STANDARD'},
|
||||
{'id': 'RSP', 'code': 'RSP', 'text': '2- RÉGIME SANS PORC', 'libelle': '2- RÉGIME SANS PORC'},
|
||||
{'id': 'RSV', 'code': 'RSV', 'text': '3- RÉGIME SANS VIANDE', 'libelle': '3- RÉGIME SANS VIANDE'},
|
||||
{
|
||||
'id': 'PAI',
|
||||
'code': 'PAI',
|
||||
'text': "4- PROTOCOLE D'ACCUEIL INDIVIDUALISÉ",
|
||||
'libelle': "4- PROTOCOLE D'ACCUEIL INDIVIDUALISÉ",
|
||||
},
|
||||
{'id': 'BB', 'code': 'BB', 'text': 'REPAS BEBE', 'libelle': 'REPAS BEBE'},
|
||||
{'id': 'MSP', 'code': 'MSP', 'text': 'REPAS MOYEN SANS PORC', 'libelle': 'REPAS MOYEN SANS PORC'},
|
||||
{'id': 'MSV', 'code': 'MSV', 'text': 'REPAS MOYEN SANS VIANDE', 'libelle': 'REPAS MOYEN SANS VIANDE'},
|
||||
{'id': 'MST', 'code': 'MST', 'text': 'REPAS MOYEN STANDARD', 'libelle': 'REPAS MOYEN STANDARD'},
|
||||
]
|
||||
|
||||
|
||||
def test_read_document_list(con, app):
|
||||
url = get_endpoint('read-document-list')
|
||||
resp = app.get(url)
|
||||
|
@ -1292,6 +1292,12 @@ def test_read_service_list(con, app):
|
|||
'lib2': None,
|
||||
'text': 'Accueil de loisirs',
|
||||
'idDir': 'A10049327624',
|
||||
'direction': {
|
||||
'id': 'A10049327624',
|
||||
'lib1': 'DEL',
|
||||
'lib2': 'Direction enfance et loisirs',
|
||||
'text': 'DEL',
|
||||
},
|
||||
},
|
||||
{
|
||||
'id': 'A10049329048',
|
||||
|
@ -1299,6 +1305,12 @@ def test_read_service_list(con, app):
|
|||
'lib2': None,
|
||||
'text': 'Accueils jeunes et centres sociaux',
|
||||
'idDir': 'A10049327627',
|
||||
'direction': {
|
||||
'id': 'A10049327627',
|
||||
'lib1': 'DSCS ACC JEUNES',
|
||||
'lib2': 'Direction des solidarités et de la cohésion sociale accueil',
|
||||
'text': 'DSCS ACC JEUNES',
|
||||
},
|
||||
},
|
||||
{
|
||||
'id': 'A10049329054',
|
||||
|
@ -1306,9 +1318,51 @@ def test_read_service_list(con, app):
|
|||
'lib2': None,
|
||||
'text': 'Activités numériques',
|
||||
'idDir': 'A10049327627',
|
||||
'direction': {
|
||||
'id': 'A10049327627',
|
||||
'lib1': 'DSCS ACC JEUNES',
|
||||
'lib2': 'Direction des solidarités et de la cohésion sociale accueil',
|
||||
'text': 'DSCS ACC JEUNES',
|
||||
},
|
||||
},
|
||||
{'id': 'A10049329049', 'lib1': 'Ateliers', 'lib2': None, 'text': 'Ateliers', 'idDir': 'A10049327621'},
|
||||
{'id': 'A10049329042', 'lib1': 'CCAS', 'lib2': None, 'text': 'CCAS', 'idDir': 'A10049327620'},
|
||||
{
|
||||
'id': 'A10049329049',
|
||||
'lib1': 'Ateliers',
|
||||
'lib2': None,
|
||||
'text': 'Ateliers',
|
||||
'idDir': 'A10049327621',
|
||||
'direction': {
|
||||
'id': 'A10049327621',
|
||||
'lib1': 'DASC',
|
||||
'lib2': "Direction de l'action socioculturelle",
|
||||
'text': 'DASC',
|
||||
},
|
||||
},
|
||||
{
|
||||
'id': 'A10049329042',
|
||||
'lib1': 'CCAS',
|
||||
'lib2': None,
|
||||
'text': 'CCAS',
|
||||
'idDir': 'plop',
|
||||
'direction': None,
|
||||
},
|
||||
]
|
||||
|
||||
resp = app.get(url + '?id=A10049329043')
|
||||
assert resp.json['data'] == [
|
||||
{
|
||||
'id': 'A10049329043',
|
||||
'lib1': 'Accueil de loisirs',
|
||||
'lib2': None,
|
||||
'text': 'Accueil de loisirs',
|
||||
'idDir': 'A10049327624',
|
||||
'direction': {
|
||||
'id': 'A10049327624',
|
||||
'lib1': 'DEL',
|
||||
'lib2': 'Direction enfance et loisirs',
|
||||
'text': 'DEL',
|
||||
},
|
||||
}
|
||||
]
|
||||
|
||||
resp = app.get(url + '?direction_id=A10049327624')
|
||||
|
@ -1319,6 +1373,12 @@ def test_read_service_list(con, app):
|
|||
'lib2': None,
|
||||
'text': 'Accueil de loisirs',
|
||||
'idDir': 'A10049327624',
|
||||
'direction': {
|
||||
'id': 'A10049327624',
|
||||
'lib1': 'DEL',
|
||||
'lib2': 'Direction enfance et loisirs',
|
||||
'text': 'DEL',
|
||||
},
|
||||
},
|
||||
{
|
||||
'id': 'A10049329044',
|
||||
|
@ -1326,6 +1386,12 @@ def test_read_service_list(con, app):
|
|||
'lib2': None,
|
||||
'text': 'Convoyages',
|
||||
'idDir': 'A10049327624',
|
||||
'direction': {
|
||||
'id': 'A10049327624',
|
||||
'lib1': 'DEL',
|
||||
'lib2': 'Direction enfance et loisirs',
|
||||
'text': 'DEL',
|
||||
},
|
||||
},
|
||||
{
|
||||
'id': 'A10049329045',
|
||||
|
@ -1333,6 +1399,12 @@ def test_read_service_list(con, app):
|
|||
'lib2': None,
|
||||
'text': 'Séjours vacances',
|
||||
'idDir': 'A10049327624',
|
||||
'direction': {
|
||||
'id': 'A10049327624',
|
||||
'lib1': 'DEL',
|
||||
'lib2': 'Direction enfance et loisirs',
|
||||
'text': 'DEL',
|
||||
},
|
||||
},
|
||||
]
|
||||
|
||||
|
@ -6664,6 +6736,19 @@ def test_read_activity_list(con, app, freezer):
|
|||
)
|
||||
|
||||
item = resp.json['data'][5]
|
||||
assert item['activity']['service'] == {
|
||||
'id': 'A10049329051',
|
||||
'lib1': 'Sorties',
|
||||
'lib2': None,
|
||||
'text': 'Sorties',
|
||||
'idDir': 'A10049327621',
|
||||
'direction': {
|
||||
'id': 'A10049327621',
|
||||
'lib1': 'DASC',
|
||||
'lib2': "Direction de l'action socioculturelle",
|
||||
'text': 'DASC',
|
||||
},
|
||||
}
|
||||
item['activity'] = 'N/A'
|
||||
item['unit'] = 'N/A'
|
||||
item['place'] = 'N/A'
|
||||
|
@ -6842,11 +6927,24 @@ def test_get_person_activity_list(activity_service, con, app):
|
|||
'blocNoteList': [],
|
||||
'coderegie': None,
|
||||
'idActivity': 'A10053187087',
|
||||
'idService': None,
|
||||
'idService': 'A10049329051',
|
||||
'libelle1': 'Vacances Ete 2023',
|
||||
'libelle2': None,
|
||||
'paiementPortal': 'I',
|
||||
'typInsPortal': 'I',
|
||||
'service': {
|
||||
'id': 'A10049329051',
|
||||
'lib1': 'Sorties',
|
||||
'lib2': None,
|
||||
'text': 'Sorties',
|
||||
'idDir': 'A10049327621',
|
||||
'direction': {
|
||||
'id': 'A10049327621',
|
||||
'lib1': 'DASC',
|
||||
'lib2': "Direction de l'action socioculturelle",
|
||||
'text': 'DASC',
|
||||
},
|
||||
},
|
||||
},
|
||||
'id': 'A10053187087',
|
||||
'incompleteFamilyFile': False,
|
||||
|
@ -7319,10 +7417,23 @@ def test_get_person_catalog_geojson(activity_service, con, app):
|
|||
'blocNoteList': [],
|
||||
'coderegie': None,
|
||||
'idActivity': 'A10053187087',
|
||||
'idService': None,
|
||||
'idService': 'A10049329051',
|
||||
'libelle1': 'Vacances ' 'Ete 2023',
|
||||
'libelle2': None,
|
||||
'paiementPortal': 'I',
|
||||
'service': {
|
||||
'id': 'A10049329051',
|
||||
'lib1': 'Sorties',
|
||||
'lib2': None,
|
||||
'text': 'Sorties',
|
||||
'idDir': 'A10049327621',
|
||||
'direction': {
|
||||
'id': 'A10049327621',
|
||||
'lib1': 'DASC',
|
||||
'lib2': "Direction de l'action socioculturelle",
|
||||
'text': 'DASC',
|
||||
},
|
||||
},
|
||||
'typInsPortal': 'I',
|
||||
},
|
||||
'incompleteFamilyFile': False,
|
||||
|
@ -10543,8 +10654,21 @@ def test_read_nursery_list(con, app):
|
|||
{'idUnit': 'M10053212403', 'libelle': 'CC AMIDONNIERS - Occasionnels', 'typeAcc': 'OCCASIONAL'},
|
||||
],
|
||||
'idActivity': 'M10000000001',
|
||||
'idService': 'A10049327627',
|
||||
'idService': 'A10049329043',
|
||||
'activityType': {'code': 'CRECHCO', 'libelle': 'Crèche collective'},
|
||||
'service': {
|
||||
'id': 'A10049329043',
|
||||
'lib1': 'Accueil de loisirs',
|
||||
'lib2': None,
|
||||
'text': 'Accueil de loisirs',
|
||||
'idDir': 'A10049327624',
|
||||
'direction': {
|
||||
'id': 'A10049327624',
|
||||
'lib1': 'DEL',
|
||||
'lib2': 'Direction enfance et loisirs',
|
||||
'text': 'DEL',
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
resp = app.get(url, params={'service_ids': 'A10049329048,A10049327627'})
|
||||
|
@ -10612,7 +10736,7 @@ def test_get_nursery_geojson(con, app):
|
|||
},
|
||||
],
|
||||
'idActivity': 'M10000000001',
|
||||
'idService': 'A10049327627',
|
||||
'idService': 'A10049329043',
|
||||
'activityType': {'code': 'CRECHCO', 'libelle': 'Crèche collective'},
|
||||
'activity_id': 'M10000000001',
|
||||
'place_id': 'M10053212401',
|
||||
|
@ -10622,6 +10746,19 @@ def test_get_nursery_geojson(con, app):
|
|||
'libelle': 'CC AMIDONNIERS - Réguliers',
|
||||
'typeAcc': 'REGULAR',
|
||||
},
|
||||
'service': {
|
||||
'id': 'A10049329043',
|
||||
'lib1': 'Accueil de loisirs',
|
||||
'lib2': None,
|
||||
'text': 'Accueil de loisirs',
|
||||
'idDir': 'A10049327624',
|
||||
'direction': {
|
||||
'id': 'A10049327624',
|
||||
'lib1': 'DEL',
|
||||
'lib2': 'Direction enfance et loisirs',
|
||||
'text': 'DEL',
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue