Développement #54332
Permettre l'inscription à toutes les récurrences d'un évènement récurrent
0%
Description
Cas d'usage Publik Famille, s'inscrire en début d'année aux activités.
Exemple, la restauration scolaire, il y aura 4 évènements, lundi, mardi, jeudi, vendredi, définis sur un agenda. Il faut pouvoir :- Récupérer ces 4 évènements, qui actuellement ne sont pas exposés dans l'API (on ne voit que les récurrences et pas les évènements qui les définissent)
- Supporter l'inscription à genre 3 évènements parmi les 4
- Supporter également des bornes temporelles, ce qui nuance un poil le « toutes » du titre (inscription toute l'année mais que jusqu'en mai)
Ce ticket remplace #50145 (dont la lecture n'est pas nécessaire, c'est juste moi qui digresse).
Files
Associated revisions
api: allow booking all recurrences of recurring events (#54332)
History
Updated by Valentin Deniaud over 3 years ago
- File 0002-api-allow-booking-all-recurrences-of-recurring-event.patch 0002-api-allow-booking-all-recurrences-of-recurring-event.patch added
- File 0001-agendas-change-annotate_queryset-queries-54332.patch 0001-agendas-change-annotate_queryset-queries-54332.patch added
- Status changed from Nouveau to Solution proposée
- Patch proposed changed from No to Yes
0001, préliminaire parce que les annotations booked_places_count posées par Event.annotate_queryset ne peuvent pas être réutilisées par d'autres requêtes. Donc réécriture sous forme de SubQuery et là ça passe.
Ensuite :- Choix d'écrire de nouvelles vues API plutôt que d'aller bricoler dans Datetimes et Fillslot.
- La manière dont la liste d'attente est gérée (certaines inscriptions peuvent se retrouver en liste d'attente et pas d'autres) a été vue avec StephG, c'est le comportement attendu.
- La manière dont sont gérés les évènements full est un cas limite sur lequel il ne faut pas trop s'étendre je pense, en pratique les évènements seront dimensionnés en fonction de la demande.
- Choix de ne pas avoir d'api fillslot liée à un évènement, exit {{ form_var_event_api_fillslot_url }}. Car dans les cas qui nous intéressent, on aura toujours plein d'évènements à réserver en même temps (accueil lundi/mardi/jeudi matin/midi/soir, 9 évènements).
- La réponse de /recurring_fillslots/ est pas ouf, à mon avis on va tout gérer à partir de user_external_id, donc on pourrait autant ne pas retourner les APIs qui se basent sur le booking primaire.
On peut discuter de tout ça ici ou attendre et faire évoluer l'API en fonction des besoins, en tout cas je trouverais ça bien de ne pas l'annoncer dans les notes de mise à jour pour se réserver la possibilité d'introduire les changements qui nous intéressent sans devoir gérer la rétro-compatibilité.
Updated by Lauréline Guérin over 3 years ago
On peut discuter de tout ça ici ou attendre et faire évoluer l'API en fonction des besoins, en tout cas je trouverais ça bien de ne pas l'annoncer dans les notes de mise à jour pour se réserver la possibilité d'introduire les changements qui nous intéressent sans devoir gérer la rétro-compatibilité.
Dans ce cas, pourquoi ne pas masquer cette nouvelle fonctionnalité derrière un setting ? (feature flag)
J'ai quelques questions:
Pourquoi fillslots avec un s ? Est-ce que tu penses qu'on aura besoin de réserver plusieurs events récurrents en même temps ? Genre la cantine + l'accueil du matin ?
On a un ticket pour supprimer cette fonctionnalité (réservation multiple), si on pouvait éviter d'en rajouter ça serait top.
Pourquoi tout lier à une réservation primaire ? Cela veut dire qu'on ne pourra pas annuler juste un jour ? Les résa non primaires ne sont pas annulables unitairement via l'API. Or, on devrait pouvoir en début d'année scolaire poser une réservation semaine type, et par la suite faire des ajustements unitaires.
Le système résa primaire/secondaire, c'est plutôt pour la réservation de plusieurs places par une même personne à un événement donné il me semble. (et peut-être dans le cas d'une réservation mulptiple, mais on aimerait le supprimer)
Updated by Valentin Deniaud over 3 years ago
Lauréline Guerin a écrit :
pourquoi ne pas masquer cette nouvelle fonctionnalité derrière un setting ? (feature flag)
Oui bonne idée je vais faire ça.
Pourquoi fillslots avec un s ?
Pour être cohérent avec le code de la réservation multiple qui parle aussi de fillslots.
Est-ce que tu penses qu'on aura besoin de réserver plusieurs events récurrents en même temps ? Genre la cantine + l'accueil du matin ?
C'est ce que j'indiquais brièvement par
on aura toujours plein d'évènements à réserver en même temps (accueil lundi/mardi/jeudi matin/midi/soir, 9 évènements)
Exemple concret, démarche sur l'instance Publik Famille https://demarches.famille.publik.love/backoffice/forms/21/ (pas encore reliée à un agenda, donc) tu as une page du formulaire qui propose de réserver jusqu'à 13 évènements d'un coup.
On a un ticket pour supprimer cette fonctionnalité (réservation multiple), si on pouvait éviter d'en rajouter ça serait top.
Je ne vois vraiment pas comment faire autrement mais je veux bien des idées.
Pourquoi tout lier à une réservation primaire ?
Oui j'avais de gros doutes aussi sur l'utilité, je vais virer ça. Mais l'API devrait alors imposer que user_external_id soit posé je pense, sinon on peut se retrouver avec des réservations perdues dans la nature.
Updated by Lauréline Guérin over 3 years ago
on aura toujours plein d'évènements à réserver en même temps (accueil lundi/mardi/jeudi matin/midi/soir, 9 évènements)
Exemple concret, démarche sur l'instance Publik Famille https://demarches.famille.publik.love/backoffice/forms/21/ (pas encore reliée à un agenda, donc) tu as une page du formulaire qui propose de réserver jusqu'à 13 évènements d'un coup.
w.c.s. sait gérer plusieurs appels :) On pourrait avoir 3 appels seulement, un par event: matin, midi, soir.
Updated by Valentin Deniaud over 3 years ago
Lauréline Guerin a écrit :
w.c.s. sait gérer plusieurs appels :)
C'est à dire mettre 3 actions webservice ou il y a un truc plus avancé ?
On pourrait avoir 3 appels seulement, un par event: matin, midi, soir.
Je ne comprends pas, il y aura bien 13 events distincts dans l'agenda. Tu imagines peut-être un event matin tous les jours, un event midi tous les jours sauf mercredi et pareil pour le soir, mais ce n'est pas la direction prise par ce ticket, parce qu'il n'y a rien pour dire « cet event récurrent, on ne réserve que les récurrences du mardi ». Tu voudrais changer ça ?
Updated by Lauréline Guérin over 3 years ago
Ha oui zut, on ne peut pas définir un événement "cantine" tous les jours le lundi, mardi, jeudi et vendredi ?
On doit passer par 4 événements distincts ?
Updated by Valentin Deniaud over 3 years ago
Lauréline Guerin a écrit :
Ha oui zut, on ne peut pas définir un événement "cantine" tous les jours le lundi, mardi, jeudi et vendredi ?
Si pas de problème au moment de la définition, c'est #50560.
Mais à partir d'un tel évènement, on a pas la granularité de dire les jours qu'on veut réserver à l'intérieur. Je me disais que besoin de granularité -> explosion de l'évènement en quatre. Cette piste me paraissait vraiment plus simple donc je n'ai pas réfléchi à l'autre, mais je peux essayer.
Updated by Lauréline Guérin over 3 years ago
Ca serait dommage d'avoir un événement qu'on peut définir sur plusieurs jours de la semaine, mais ne pas pouvoir faire de réservation de semaine type dessus
Piste pour simplifier: est-ce que la définition d'un tel événement ne pourrait pas en fait générer autant d'events que de jours cochés ?
Updated by Valentin Deniaud over 3 years ago
Lauréline Guerin a écrit :
Piste pour simplifier: est-ce que la définition d'un tel événement ne pourrait pas en fait générer autant d'events que de jours cochés ?
À quel niveau ? Dans le retour de l'API qui liste les évènements réservables ou même plus en amont dans le manager ?
Updated by Lauréline Guérin over 3 years ago
Dans la définition de l'événement dans l'interface: ne créer en DB que des events sur un seul jour de la semaine.
Si je comprends bien le code de la vue recurring_fillslots, ça ne fonctionne que si toutes les récurrences ont été créées en DB ? On est sûr que ça sera tout le temps le cas ?
Updated by Valentin Deniaud over 3 years ago
Lauréline Guerin a écrit :
Dans la définition de l'événement dans l'interface: ne créer en DB que des events sur un seul jour de la semaine.
Pas bien compris :/ un évènement récurrent ça ne crée que des évènements normaux, pas d'autres évènements récurrents.
Si je comprends bien le code de la vue recurring_fillslots, ça ne fonctionne que si toutes les récurrences ont été créées en DB ? On est sûr que ça sera tout le temps le cas ?
Oui, cf get_open_recurring_events
et les tests, # recurring events without recurrence_end_date are not bookable
.
En tout cas je suis d'accord avec
Ca serait dommage d'avoir un événement qu'on peut définir sur plusieurs jours de la semaine, mais ne pas pouvoir faire de réservation de semaine type dessus
je vais regarder ce que je peux faire, sans garantie de ne pas tomber sur un truc bloquant.
Updated by Lauréline Guérin over 3 years ago
Oui, cf get_open_recurring_events et les tests, # recurring events without recurrence_end_date are not bookable.
Donc pour le cas où on a un event recurrent avec une fin de récurrence, toutes les occurences sont en DB, on est bon.
Par contre dans l'autre cas (pas de fin de récurrence), les occurrences sont créées lorsqu'on en a besoin (visualisation de l'agenda par exemple); on pourrait alors tomber sur un cas ou seulement la moitié des occurences existent en DB sur la période demandée pour la réservation en masse. C'est bancal non ?
Pas bien compris :/ un évènement récurrent ça ne crée que des évènements normaux, pas d'autres évènements récurrents.
Je récapitule :)
Si j'ai bien compris, avec le widget de création d'event récurrent avancé, on pourrait définir un event "cantine" à 12H lundi, mardi, jeudi, vendredi. Ce qui crée 1 event récurrent en DB.
Le endpoint recurring_fillslots tel qu'il est là tout de suite, ne peut pas gérer une réservation en masse de cet event cantine si on doit exclure des jours: réserve tous les midis de l'année sauf le vendredi.
Soit on pourrait simplifier les données;
Au lieu d'avoir 1 event "cantine" à 12H lundi, mardi, jeudi, vendredi, lors de la configuration avancée de cet event, créer en DB 1 event "cantine" à 12H lundi, 1 event "cantine" à 12H mardi, 1 event "cantine" à 12H jeudi, 1 event "cantine" à 12H vendredi.
(un peu comme on fait avec les TimePeriod il me semble)
=> alors on pourrait réserver tous les lundi, mardi et jeudi sans soucis.
Mais je suppose que ça poserait problème si on veut éditer l'event d'origine, et, mettons, changer l'horaire de la cantine, passer à 11H45 lundi, mardi, jeudi, vendredi ?
Soit on fait en sort de pouvoir gérer ce cas avec recurring_fillslots;
On pourrait prendre en paramètre un event récurrent + un filtre à appliquer.
Par exemple: je réserve la cantine, toutes les occurences qui matchent "lundi, mardi, jeudi"
Dans tous les cas, je préfèrerais que le endpoint recurring_fillslots s'appelle recurring_fillslot (sans s) et ne prenne en param qu'un seul event
(à cause de #40395)
Peut-être qu'un ou plusieurs avis supplémentaires pourraient aider ?
Updated by Valentin Deniaud over 3 years ago
Lauréline Guerin a écrit :
on pourrait alors tomber sur un cas ou seulement la moitié des occurences existent en DB sur la période demandée pour la réservation en masse. C'est bancal non ?
Si on veut, ça rejoint #51360 et c'est très théorique, je propose d'en discuter plus tard/à un autre endroit.
Mais je suppose que ça poserait problème si on veut éditer l'event d'origine, et, mettons, changer l'horaire de la cantine, passer à 11H45 lundi, mardi, jeudi, vendredi ?
Yep.
Soit on fait en sort de pouvoir gérer ce cas avec recurring_fillslots;
On pourrait prendre en paramètre un event récurrent + un filtre à appliquer.
Par exemple: je réserve la cantine, toutes les occurences qui matchent "lundi, mardi, jeudi"
On est d'accord, c'est la piste que je proposais d'explorer.
La première chose à éclaircir à mon avis c'est la conception du formulaire : tel que c'est fait maintenant on récupère la liste des évènements récurrents réservables, et on réserve ceux qu'on veut sans se poser plus de question.
Là typiquement on récupère « Matin tous les jours » et « Midi LMJV », comment on indique que les jours réservables ne sont pas les mêmes entre les deux ? On risque de se retrouver avec pas mal de choses hardcodées au lieu d'une jolie source de donnée à base de gabarit.
Dans tous les cas, je préfèrerais que le endpoint recurring_fillslots s'appelle recurring_fillslot (sans s) et ne prenne en param qu'un seul event
(à cause de #40395)
Tu pourrais développer ce « à cause de » ?
Je trouve qu'ici on est quoiqu'on fasse sur de la réservation multiple. C'est à dire qu'on aura beau passer un seul slug, les points soulevés dans #40395 sur les annulations et sur la gestion de la liste d'attente s'appliquent tout autant, vu que derrière ce slug on va réserver plein d'évènements. Il y aussi un « complique les évolutions », mais ça c'est parce que fillslot est une méthode fourre-tout, on est pas non plus dans ce cas.
Pour l'instant le seul inconvénient que je vois c'est qu'on perd le gabarit {{ event_api_fillslot_url }} et qu'on doit forcément écrire une URL à la main.
(à noter que ça n'est pas incompatible avec le point d'avant, on pourrait avoir les deux et donc passer dans ce cas d'usage de 3 appels WS à un seul)
Updated by Lauréline Guérin over 3 years ago
La première chose à éclaircir à mon avis c'est la conception du formulaire : tel que c'est fait maintenant on récupère la liste des évènements récurrents réservables, et on réserve ceux qu'on veut sans se poser plus de question.
Là typiquement on récupère « Matin tous les jours » et « Midi LMJV », comment on indique que les jours réservables ne sont pas les mêmes entre les deux ? On risque de se retrouver avec pas mal de choses hardcodées au lieu d'une jolie source de donnée à base de gabarit.
Je ne comprends pas. Un usecase courant, c'est de pouvoir définir une "semaine type", par exemple lors de l'inscription de ton enfant à la cantine, pouvoir dire "il mangera toute l'année lundi mardi jeudi mais pas vendredi".
On est dans le cas où on ne s'inscrit pas à tous les jours réservables.
Tu pourrais développer ce « à cause de » ?
actuellement on a dans fillslots agenda.event_set.filter(slug__in=slots)
le ticket #40395 voudrait simplifier ça, et ne permettre que agenda.event_set.filter(slug=slot)
(garder /api/agenda/<agenda_slug>/fillslot/<event_slug>/
et supprimer /api/agenda/<agenda_slug>/fillslots/ + 'params={'slots': 'event1,event2,event3'}
là tu fais recurring_events = agenda.get_open_recurring_events().filter(slug__in=payload['slots'])
=> peut-être qu'on préfèrerait avoir une url en /api/agenda/<agenda_slug>/recurring_fillslot/<event_slug>/
au lieu de api/agenda/<agenda_slug>/recurring_fillslots/
Updated by Valentin Deniaud over 3 years ago
Lauréline Guerin a écrit :
Je ne comprends pas.
Je réfléchissais juste à voix haute sur ce dont il y aurait besoin côté formulaire pour exposer le choix des jours à réserver pour un évènement.
Un usecase courant, c'est de pouvoir définir une "semaine type", par exemple lors de l'inscription de ton enfant à la cantine, pouvoir dire "il mangera toute l'année lundi mardi jeudi mais pas vendredi".
OK donc on avait peut-être pas le même cas d'usage en tête, moi je me base vraiment sur le formulaire Publik Famille que j'ai pointé plus haut : granularité à la tranche de la journée près, genre tous les jours sauf le vendredi après-midi .
Actuellement (scénario des 13 évènements) il n'y a rien à faire, c'est un appel WS qui les récupère et on alimente un champ liste à choix multiple et hop.
Si on a trois évènements matin/midi/soir, il va falloir un peu plus bricoler. Je me demandais notamment si le retour de l'API devrait avertir des jours sélectionnables, tous les jours pour matin, Lundi/Mardi/Jeudi/Vendredi pour midi/soir.
Mais même avant ça : j'appelle le WS, je récupère trois évènements matin/midi/soir. Et là je ne sais même pas comment les présenter pour qu'on puisse ensuite choisir genre « le midi de tel jour »...
Une piste ça peut être de se ramener aux 13 évènements, genre à partir des 3 l'API génère et expose les 13. Sinon, il y a moyen que ça appelle un nouveau widget...
le ticket #40395 voudrait simplifier ça
Parce que la méthode fillslot fait 300 lignes, mais dans le cadre d'une vue à part entre slug=
et slug__in=
le différentiel de complexité est pas si ouf non ?
peut-être qu'on préfèrerait avoir une url en
/api/agenda/<agenda_slug>/recurring_fillslot/<event_slug>/
au lieu deapi/agenda/<agenda_slug>/recurring_fillslots/
Oui et on retombe sur ce que j'écrivais, que cette URL est bien pratique grâce au gabarit. Si c'est bien le seul point, il faut peser le pour et le contre, perso je trouve ça dommage mais sans que ça contrebalance le bonus de rapidité d'avoir un seul appel à faire.
Updated by Valentin Deniaud over 3 years ago
- Status changed from Solution proposée to Information nécessaire
Nouveau résumé, à partir du cas d'usage https://demarches.famille.publik.love/backoffice/forms/21/ (accueil midi et soir LMJV et accueil matin LMMJV). Il faut pouvoir réserver n'importe quelle combinaison genre « matin LM et midi JV ».
Proposition actuelle :- Créer 13 évènements récurrents distincts dans l'agenda, soit un pour chaque tranche réservable.
- Introduire une API qui expose tous les évènements récurrents d'un agenda.
- Dans le formulaire, alimenter un champs liste à choix multiple grâce à cette API.
- Le besoin est rempli, l'usager peut sélectionner la combinaison qu'il veut.
- Introduire une API pour réserver un ou plusieurs évènements récurrents, on peut alors passer en un coup les évènements cochés par l'usager (potentiellement 13).
Premier problème, avoir 13 évènements dans chrono c'est pas terrible sachant qu'on pourrait en avoir 3.
Nécessité donc d'une seconde proposition, ça demande un ajout à l'API de réservation pour pouvoir indiquer des jours réservables pour un évènement récurrent donné, ça devrait le faire. Par contre- Introduire une API qui expose tous les évènements récurrents d'un agenda.
n'est plus suffisant car il faut pouvoir distinguer le seul évènement qui est réservable le mercredi des deux autres.
Idée, cette API pourrait éclater les évènements en jours réservables : ça exposerait des évènements avec des slug genre accueil-midi:monday, accueil-midi:tuesday, accueil-midi:thursday, accueil-midi:friday. Et ça marcherait comme une lettre à la poste pour la réservation ensuite, 13 cases à cocher et potentiellement 13 slugs à passer lors de la réservation.
Deuxième problème, on ne voudrait pas permettre de passer plusieurs slugs à la réservation. Et là je manque d'imagination, concrètement ça donnerait quoi côté démarche ?
Updated by Lauréline Guérin over 3 years ago
Premier problème, avoir 13 évènements dans chrono c'est pas terrible sachant qu'on pourrait en avoir 3.
Clairement, devoir se restreindre à ne définir que des événements "unitaires" (sur un seul jour de la semaine), à cause de restrictions de l'API, alors qu'on a le moyen de faire un paramétrage avancé d'un event récurrent sympa, c'est dommage.
Je proposais de splitter cet event en plusieurs events unitaires à la validation du formulaire de paramétrage avancé pour simplifier, mais ça serait dommage d'en arriver là.
Idée, cette API pourrait éclater les évènements en jours réservables : ça exposerait des évènements avec des slug genre accueil-midi:monday, accueil-midi:tuesday, accueil-midi:thursday, accueil-midi:friday. Et ça marcherait comme une lettre à la poste pour la réservation ensuite, 13 cases à cocher et potentiellement 13 slugs à passer lors de la réservation.
Ca marcherait oui
Deuxième problème, on ne voudrait pas permettre de passer plusieurs slugs à la réservation. Et là je manque d'imagination, concrètement ça donnerait quoi côté démarche ?
Le soucis de l'API fillslots (réservation multiple) qui accepte plusieurs events en entrée, c'est qu'on va créer une réservation primaire et n secondaires; seule la primaire sera modifiable via l'API et l'UI, en impactant toutes ses secondaires, bien que les secondaires ne portent pas nécessairement sur le même event que la primaire.
D'où la volonté de supprimer cette réservation multiple avec #40395
Deuxième problème, on ne voudrait pas permettre de passer plusieurs slugs à la réservation. Et là je manque d'imagination, concrètement ça donnerait quoi côté démarche ?
Je me dis que tant que l'API de réservation en masse ne génère que des réservations primaires, ça ne poserait pas de problème de passer plusieurs slugs.
Si on devait se restreindre à faire des appels unitaires (un par slug), je pense que le workflow de la démarche serait capable de le faire (à confirmer)
Question: il se passe quoi si on fait une première réservation en masse, en envoyant lundi/mardi sur un intervalle de dates, puis qu'on refait une réservation en masse avec cette fois seulement mardi ? Est-ce que les lundi sont bien annulés ?
Updated by Valentin Deniaud over 3 years ago
- File 0002-api-allow-booking-all-recurrences-of-recurring-event.patch 0002-api-allow-booking-all-recurrences-of-recurring-event.patch added
- File 0001-agendas-change-annotate_queryset-queries-54332.patch 0001-agendas-change-annotate_queryset-queries-54332.patch added
- Status changed from Information nécessaire to Solution proposée
Revoici donc une version implémentant l'idée d'éclater les évènements en plusieurs jours, et permettant de passer plusieurs slugs à la réservation en oubliant toutes les histoires de résa primaire/secondaire, à la place on impose la présence de user_external_id. Présence aussi d'un feature flag qui désactive les nouveaux endpoints par défaut. Basé sur #50560 qui est quasi validé.
Question: il se passe quoi si on fait une première réservation en masse, en envoyant lundi/mardi sur un intervalle de dates, puis qu'on refait une réservation en masse avec cette fois seulement mardi ? Est-ce que les lundi sont bien annulés ?
Non mais je suis d'accord que ça devrait fonctionner comme ça. Je propose néanmoins de gérer ça dans un autre ticket car pas si simple (il faut que le code tolère de réserver un évènement full si l'usager a déjà une résa, et histoire de liste d'attente à gérer également).
Updated by Benjamin Dauvergne over 3 years ago
J'ai essayé de relire mais je ne comprends rien à l'implémentation des récurrences. Pour moi la relecture par Laureline suffit.
Updated by Lauréline Guérin over 3 years ago
- Status changed from Solution proposée to Solution validée
allez.
Updated by Valentin Deniaud over 3 years ago
- Status changed from Solution validée to Résolu (à déployer)
commit 4fb6581e8d73637403a11f1759d54151e0a6d6fa Author: Valentin Deniaud <vdeniaud@entrouvert.com> Date: Tue Mar 2 14:05:13 2021 +0100 api: allow booking all recurrences of recurring events (#54332) commit dcc4b44a67d6ce799e357a6edb2b3582cb9fe29a Author: Valentin Deniaud <vdeniaud@entrouvert.com> Date: Mon Mar 1 16:35:42 2021 +0100 agendas: change annotate_queryset queries (#54332)
Updated by Frédéric Péters over 3 years ago
- Status changed from Résolu (à déployer) to Solution déployée
agendas: change annotate_queryset queries (#54332)