Projet

Général

Profil

Bug #49616

maelis: retourner le catalogue des activités

Ajouté par Nicolas Roche il y a plus de 3 ans. Mis à jour il y a plus de 3 ans.

Statut:
Fermé
Priorité:
Normal
Assigné à:
Version cible:
-
Début:
18 décembre 2020
Echéance:
% réalisé:

0%

Temps estimé:
Patch proposed:
Oui
Planning:
Non

Description

Endpoint pour récupérer l'ensemble du catalogue à présenter sur le portail à tous les usagers.


Fichiers

0001-maelis-add-a-catalog-endpoint-49616.patch (6,67 ko) 0001-maelis-add-a-catalog-endpoint-49616.patch Nicolas Roche, 18 décembre 2020 20:42
0001-maelis-add-subscribed-status-to-activity_list-endpoi.patch (25,4 ko) 0001-maelis-add-subscribed-status-to-activity_list-endpoi.patch Nicolas Roche, 22 décembre 2020 15:20
0001-maelis-add-endpoints-for-activities-units-and-places.patch (26,5 ko) 0001-maelis-add-endpoints-for-activities-units-and-places.patch Nicolas Roche, 24 décembre 2020 08:31
0001-maelis-add-endpoints-for-activities-units-and-places.patch (28,5 ko) 0001-maelis-add-endpoints-for-activities-units-and-places.patch Nicolas Roche, 24 décembre 2020 12:39
0001-maelis-add-endpoints-for-activities-units-and-places.patch (28,4 ko) 0001-maelis-add-endpoints-for-activities-units-and-places.patch Nicolas Roche, 24 décembre 2020 14:40
0006-maelis-add-places-endpoint-49616.patch (6,36 ko) 0006-maelis-add-places-endpoint-49616.patch Nicolas Roche, 03 janvier 2021 23:51
0005-maelis-add-units-endpoint-49616.patch (6,38 ko) 0005-maelis-add-units-endpoint-49616.patch Nicolas Roche, 03 janvier 2021 23:51
0004-maelis-add-activities-endpoint-49616.patch (7,84 ko) 0004-maelis-add-activities-endpoint-49616.patch Nicolas Roche, 03 janvier 2021 23:51
0003-maelis-add-booking-status-to-get_catalog-result-4961.patch (8,96 ko) 0003-maelis-add-booking-status-to-get_catalog-result-4961.patch Nicolas Roche, 03 janvier 2021 23:51
0002-maelis-add-a-get_catalog-function-49616.patch (8,19 ko) 0002-maelis-add-a-get_catalog-function-49616.patch Nicolas Roche, 03 janvier 2021 23:51
0001-maelis-factorize-child-info-endpoint-49616.patch (2,56 ko) 0001-maelis-factorize-child-info-endpoint-49616.patch Nicolas Roche, 03 janvier 2021 23:51
0001-maelis-factorize-child-info-endpoint-49616.patch (2,56 ko) 0001-maelis-factorize-child-info-endpoint-49616.patch Nicolas Roche, 05 janvier 2021 19:30
0002-maelis-add-child-activities-endpoint-49616.patch (123 ko) 0002-maelis-add-child-activities-endpoint-49616.patch Nicolas Roche, 05 janvier 2021 19:30
0001-maelis-factorize-child-info-endpoint-49616.patch (2,56 ko) 0001-maelis-factorize-child-info-endpoint-49616.patch Nicolas Roche, 06 janvier 2021 16:28
0002-maelis-add-child-activities-endpoint-49616.patch (128 ko) 0002-maelis-add-child-activities-endpoint-49616.patch Nicolas Roche, 06 janvier 2021 16:28
catalog.json (2,86 ko) catalog.json Nicolas Roche, 06 janvier 2021 16:28

Révisions associées

Révision ece9f1e1 (diff)
Ajouté par Nicolas Roche il y a plus de 3 ans

maelis: factorize child-info endpoint (#49616)

Révision 7098b10e (diff)
Ajouté par Nicolas Roche il y a plus de 3 ans

maelis: add child-activities endpoint (#49616)

Historique

#2

Mis à jour par Nicolas Roche il y a plus de 3 ans

Bien que ce endpoint pourrait aussi servir dans une source de donnée w.c.s., ici son premier usage envisagé est l'affichage du catalogue dans combo.

(pour une source de donnée w.c.s. qui servirait au formulaire d'inscription il vaudrait mieux utiliser le endpoint activity_list déjà présent, qui n'expose que les activités proposées à un enfant donné).

1.

         parameters={
             'queryDate': {'description': _('Optional querying date (YYYY-MM-DD)')}

J'ai mis la date en paramètre dans l'idée de faire des tests de non régression sur le calcul de la date. Mais en fait avec SOAP je ne vois pas comment faire. Je l'ai laissée parce que ça me paraît quand même bien de pouvoir se baser sur un appel entièrement reproductible.

2.

        if date.strftime('%m-%d') >= '05-01':
            # start displaying next year activities on may
            school_year = date.year
        else:
            school_year = date.year - 1

Discuté avec Brice : vers la fin de l'année scolaire, les familles vont vouloir s'inscrire aux activité de l'année suivante.
Par ailleurs la date de basculement d'une année à l'autre ne nous est pas connue et pourrait faire que les activités qui ont lieu pendant les vacances soient ajoutées au catalogue de la prochaine année scolaire.

Il y aura peut-être un bug si l'on veut s’inscrire en mai pour une activité en juin qui n'est plus proposé l'année suivante.
Comme ça complique pas mal le code : il faut faire 2 appels puis merger les 2 catalogues, je propose quand même cette approche "naïve"
(dans l'idée que sinon cela reviendrait à faire de la logique "métier" dans le connecteur alors que se serait plutôt à remonter à Maélis).

3.

            r = self.call('ActivityService?wsdl', 'readActivityList',
                          schoolyear=school_year,
                # we must ask for booking days because maelis restrict activities on dates
                # event if we do not want them here.
                          dateStartCalend="1970-01-01",
                          dateEndCalend="2099-12-31")

Discuté avec les techniciens de Maélis : en principe à défaut de ne rien pouvoir mettre, je devrais passer dateStartCalend = dateEndCalend = 1970-01-01 afin de ne pas être pollué par les agendas (les journées réservables pour chaque activité).
Stéphane leur a fait passer ma trace qui montre que si je met 1970 alors je reçoit un catalogue vide.
À ce propos, on ne pourrais pas leur ouvrir l'accès à https://dev.entrouvert.org/projects/parsifal-mairie-de-toulouse ? Ce serait plus simple pour communiquer.

4.

cache.set(cache_key, data, 300)

J'ai mis du cache parce que le catalogue met longtemps à descendre.
Cependant je n'ai rien pour l'invalider (ce qui n'est pas bien me dira Thomas).

#3

Mis à jour par Nicolas Roche il y a plus de 3 ans

Vu que le ticket lié se précise et qu'il faut plutôt exposer le catalogue d'un enfant j'ai finalement remplacé le endpoint activity-list,
pour que ce endpoint puisse à la fois servir pour afficher le catalogue et aussi de source de donnée.

Je l'ai décliné en 3 endpoints pour également récupérer les unité et les lieux en source de donnée.

J'ai ajouter un champ qui permet de savoir s'il faut intégrer l'objet dans la source de donnée,
suivant que l'enfant peut ou ne peut pas l'utiliser pour une nouvelle inscription.

#4

Mis à jour par Frédéric Péters il y a plus de 3 ans

def normalize_catalog(activity):
    # we must ask for booking days because maelis restrict activities on dates
    # but we do not want them here.
    if activity.get('openDayList'):
        del activity['openDayList']

Le commentaire apporte surtout de la confusion, on passe du temps à se dire qu'il est mal placé à parler d'une interrogation à Maelis. (si je comprends il est là pour dire qu'on se retrouve avec openDayList dans les attributs parce qu'il a fallu ceci/cela, mettons qu'on s'en fout).

                # we must ask for booking days because maelis restrict activities on dates
                # event if we do not want them here.

sans doute even et pas event, vu le domaine on va se retrouver à se demander si c'est vraiment une typo ou si il y a une notion d'événements pas encore vues, épargnons-nous ça.

mark_subscibed_pre

Typo.

Globalement, pas fan de ce nommage des endpoints sous forme "xxx-list" qu'on ne retrouve pas dans nos autres connecteurs, mais passons.

Pas fan non plus des normalize_xxx() dont je ne ne perçois pas nécessairement le sens : pourquoi get_units() ne renvoie pas directement les infos dans le format normalisé, plutôt qu'attendre des consommateurs qu'ils appellent normalize_unit() sur ce qui aura été retourné ? (pareil pour normalize_place, peut-être d'autres).

Au-delà du connecteur il y aura grand bénéfice à inclure sur la page wiki parlant du connecteur le glossaire Maelis, pour avoir une référence sur ce que signifient units/places/etc.

#5

Mis à jour par Nicolas Roche il y a plus de 3 ans

Remarques prises en compte :
  • En mettant une même date de début et de fin dans le future, je récupère le même catalogue sans les calendrier (point 3 dans mon premier message).
  • J'ai renommé les endpoint en activities, units et places (j'ai ajouté un 's' et retiré '-list')
  • J'ai fait la normalisation (et le tri) d'un bloc avant la mise en cache.
  • J'ai ajouté un glossaire sur le wiki (et je réalise que je disposes d'informations codifiés à exposer dans les div).

Aussi, j'ai corrigé l'algorithme de filtrage sur le statut réservé.

#7

Mis à jour par Nicolas Roche il y a plus de 3 ans

En mettant une même date de début et de fin dans le future, je récupère le même catalogue sans les calendrier (point 3 dans mon premier message).

En fait non, je me suis fais avoir par le cache.
J'ai mis la date du jour en début et en fin car cela me retourne le même contenu (en attendant une réponse définitive dans #49703).

#8

Mis à jour par Serghei Mihai (congés, retour 15/05) il y a plus de 3 ans

Tu peux me traiter de pénible, mais je pense encore qu'il faut séparer l'ajout des endpojts units et places dans des commits différents.
Sur la forme:

activities = self.get_catalog(NameID=NameID, childID=childID, queryDate=queryDate)

tu peux faire simplement:

activities = self.get_catalog(NameID, childID, queryDate)

car les paramètres sont passés dans le même ordre que les arguments attendus par la fonction, en plus ils ont des noms explicites.

#9

Mis à jour par Nicolas Roche il y a plus de 3 ans

0001 : je vide le endpoint child-info de son corps pour pouvoir le réutiliser
(il me semble plus propre de ne pas appeler un endpoint depuis un autre endpoint)

0002 : correspond à la description données dans https://dev.entrouvert.org/issues/49616#note-2
à ceci près que j'ai mis le cache également sur le childID s'il est fourni,
et que j'ai réduit le cache à 3 secondes dans l'idée de juste couvrir l'affiche d'une page (qui passerait plusieurs fois par là).

0003: je rajoute le statut 'inscrit' ou 'pas inscrit' à chaque noeuds.
L'idée c'est de pouvoir ne proposer que les activités, unités et lieux où l'enfant n'est pas encore inscrit dans le catalogue
(ou l'inverse si l'on affiche veut aussi gérer les dés-inscriptions).

0004: liste des activité suivant un statut 'subscribeables' ou 'unsubscribeables' (ou pas).
Cela permet par exemple d'afficher le catalogue (voici une cellule JSON au cas où pour tester) :
URL: {{passerelle_url}}maelis/test/activities?NameID={{user_nameid}}&childID={{enfant_id}}&subscribingStatus=subscribeables

{% if not json.err %}
<h2>Activités auxquelles l'enfant peut s'inscire</h2>
<div>
  <ul>
    {% for activite in json.data %}
    <div class="maelis-activity" 
         activity-code="{{ activite.activityPortail.activityType.code }}">
      <li>
        {{ activite.activityPortail.label }}
        <ul>
          {% for unite in activite.unitPortailList %}
          <div class="maelis-unit" 
               consumer-codes="{% for tarif in unite.consoTarifList %}{{ tarif.conso.code }}{% endfor %}">
            <li>
              {{ unite.label }}
              <ul>
                {% for place in unite.placeList %}
                <div class="maelis-place" label="{{ place.lib }}">
                  <li>
                    <a href="https://wcs.dev.publik.love/tests/inscription-maelis/?childID={{ enfant_id }}&activityID={{ activite.activityPortail.idAct }}&unitID={{ unite.idUnit }}&placeID={{ place.id }}">
                      {{ place.lib }}
                    </a>
                  </li>
                </div>
                {% endfor %}
              </ul>
            </li>
          </div>
          {% endfor %}
        </ul>
    </div>
    {% endfor %}
  </ul>
</div>
{% else %}
{{ json.err_desc|default:"erreur inconnue" }}
{% endif %}

0005: liste des unités relatives à une activité suivant le même statut 'subscribeables' ou 'unsubscribeables' (ou pas).
Cela permet d'avoir une source de donnée pour choisir ou valider les champs pré-remplis d'une démarche
(je dis cela mais en fait je n'ai pas encore réussit à l'utiliser dans ce second cas).
Par exemple :
URL: {{passerelle_url}}maelis/test/units?NameID={{ form_user_nameid }}&childID={{ request.GET.childID }}&activityID={{ request.GET.activityID }}&subscribingStatus=subscribeables

0006: liste des lieux : idem un cran plus bas.
ex URL: {{passerelle_url}}maelis/test/places?NameID={{ form_user_nameid }}&childID={{ request.GET.childID }}&activityID={{ request.GET.activityID }}&unitID={{ request.GET.unitID }}&subscribingStatus=not-subscribed

Dans l'ensemble ces patchs représentent une vue théorique des endpoints délivrants le catalogue et les sources de données requises pour permettre l'inscription.
Ils devront nécessairement être corrigés car les webservices ne semblent pas répondre comme je l'attend.
Néanmoins, en attendant d'avoir des réponses à #49703, #49744, #49745, et #49803, ils nous permettraient de proposer en recette une première base de travaille pour avancer sur la présentation du catalogue (#48113) et la démarche d'inscription (#49636).

#10

Mis à jour par Nicolas Roche il y a plus de 3 ans

  • Statut changé de Solution proposée à En cours

Vu avec Thomas : retourner une liste qui aplatît l'arborescence via un unique endpoint activities.

#11

Mis à jour par Nicolas Roche il y a plus de 3 ans

J'essaye de fournir la cellule JSON qui fait les {% regroup %} asap.

#12

Mis à jour par Frédéric Péters il y a plus de 3 ans

J'essaye de fournir la cellule JSON qui fait les {% regroup %} asap.

Je lis cette phrase et pour moi elle expose que ça ne va pas.

Je me base toujours sur une capture d'écran vue qui ressemblait à :

 Des sortes de groupement :         A     B     C
 D'autres sortes de groupement :    a     b     c     d

 Activité 1        Activité 2           Activité 3         Activité 4
 Activité 5        Activité 6           Activité 7         Activité 8
 ...

Je vois ça et pour moi ce que ça crie c'est :

  • un endpoint pour avoir la première série de groupements (catégories ? lieux ? whatever)
  • un autre pour la seconde série
  • un autre pour avoir toutes les activités (c'est ce que le patch donne)

Et l'affichage ce sera

  <ul>{% for group1 in groups1 %}<li><a>{{ group1 }}</li>{% endfor %}</ul>
  <ul>{% for group2 in groups2 %}<li><a>{{ group2 }}</li>{% endfor %}</ul>
  <div class="activites">
    {% for activite in activites %}
    <div class="activite activite-group1-{{activite.groupement1} activite-group2-{{activite.groupement2}}">
      {{activite.whatever}}
      ...
    </div>
    {% endfor %}
  </div>
  <script>du javascript pour que ça se clique et s'affiche et se cache</script>

Bref pour moi il ne faut pas faire de la logique dans les gabarits à base de {% regroup %} qui donne des trucs illisibles mais utiliser des endpoints supplémentaires.

~~

Aussi,

  • "Optional querying date", mais le code fait une APIError s'il n'y a pas de date ? (alors que c'est noté optionnel ?).
  • subscribed, not-subscribed or None, mais None ce n'est pas une vraie valeur et si aucune valeur n'est passée ça fait APIError
    • mais on n'était pas sur vouloir un affichage unique reprenant toutes les activités, subscribed or not ?

(tout ça mais rapidement faudra du code dans le dépôt pour avoir du truc live qui puisse être exploité pour avancer sur la présentation etc.)

#13

Mis à jour par Frédéric Péters il y a plus de 3 ans

  • Statut changé de Solution proposée à Solution validée

Mais on s'en fout de toute façon on jettera tout (#49703#note-12).

#14

Mis à jour par Nicolas Roche il y a plus de 3 ans

Merci Fred !

L'idée de n'avoir qu'une seule source de donnée qui utilise les 3 identifiants d'activité, unité et de place
c'était pour réussir à l'utiliser également dans un formulaire (pour valider les valeurs préremplies et afficher un libellé compréhensible).

Ci-joint une cellule proto-json moche mais qui fait l'affichage.

Par contre je n'arrive toujours pas à utiliser la source de donnée dans le formulaire.
J'ai un champ "activite" qui ne passe pas la validation :
  • datasource : {{ passerelle_url }}maelis/test/child-activities?NameID={{ form_user_nameid }}&childID={{ request.GET.childID }}&subscribingStatus=not-subscribed
  • préremplissage : {{ request.GET.activityID }}

A la validation de la page, la source de donnée des activité renvoit une liste vide,
à priori parce que request.GET.activityID n'est plus disponible.
J'ai essayé sans succès childID={% firstof request.GET.activityID request.GET.childID form_var_enfant_raw %}

Comme je n'ai rien à proposer de valable pour le formulaire, j'hésite à pousser.

#15

Mis à jour par Frédéric Péters il y a plus de 3 ans

  • Statut changé de Solution proposée à Solution validée

c'était pour réussir à l'utiliser également dans un formulaire (pour valider les valeurs préremplies et afficher un libellé compréhensible).

Je ne comprends pas. Et je ne vois pas ce qu'un formulaire vient faire ici alors que je parlais de la cellule ?

à priori parce que request.GET.activityID n'est plus disponible.

Clairement lors d'un POST vers /plop/ il n'y a pas de request.GET.activityID. Il ne faut pas utiliser de request.GET dans une source de données, ça ne peut pas marcher.

J'ai essayé sans succès childID={% firstof request.GET.activityID form_var_enfant_raw %}

Mais l'enfant est un activityID ?

C'est vraiment confus pour moi tout ça.

(et je valide toujours parce que tout sera de toute façon à effacer, cf point précédent)

#16

Mis à jour par Nicolas Roche il y a plus de 3 ans

  • Statut changé de Solution validée à Résolu (à déployer)

Effet démo inverse : j'ai demandé à Thomas de regarder et ça c'est mis à fonctionner tout seul (il est vraiment fort Thomas avec ses yeux).

{{passerelle_url}}maelis/test/child-activities?NameID={{ form_user_nameid }}&childID={% firstof request.GET.childID form_var_enfant_raw  %}&subscribingStatus=not-subscribed

commit 7098b10e0b25a03fa81da4b34ba2956ad8ee7201
Author: Nicolas ROCHE <nroche@entrouvert.com>
Date:   Tue Jan 5 18:45:10 2021 +0100

    maelis: add child-activities endpoint (#49616)

commit ece9f1e17a3c6abcb6ed3800f56e1542a7c54db9
Author: Nicolas ROCHE <nroche@entrouvert.com>
Date:   Sun Jan 3 18:58:02 2021 +0100

    maelis: factorize child-info endpoint (#49616)
#17

Mis à jour par Nicolas Roche il y a plus de 3 ans

Pardon, j'avais relâché la contrainte sur feedparser pour jouer les tests localement.

commit c9a4c48458c325268b2aaa51176e52beeaa9fec4
Author: Nicolas ROCHE <nroche@entrouvert.com>
Date:   Wed Jan 6 17:39:14 2021 +0100

    tox.ini: revert error on last commit that relax feedparser constraint

#18

Mis à jour par Frédéric Péters il y a plus de 3 ans

  • Statut changé de Résolu (à déployer) à Solution déployée

Formats disponibles : Atom PDF