Project

General

Profile

Développement #96866

source de données agenda, passer le nameid en lock_code pour les utilisateurs identifiés

Added by Valentin Deniaud about 2 months ago. Updated 26 days ago.

Status:
Solution déployée
Priority:
Normal
Target version:
-
Start date:
15 October 2024
Due date:
% Done:

0%

Estimated time:
Patch proposed:
No
Planning:
No

Description

Contexte, la prise de rdv backoffice depuis chrono (#70122).

Actuellement wcs passe :

'qs_data': {'lock_code': '{{ session_hash_id }}'},

Mais ce session_hash_id est interne à wcs.

Pour initier la prise de rdv depuis le BO chrono, on va permettre à un agent de cliquer sur un créneau, puis l'envoyer compléter le formulaire dans wcs, avec le champ « Créneau » pré-rempli, et le rendez-vous prébloqué.

Pour pouvoir conserver le préblocage automatique avec les sources de données agenda, on pourrait se baser sur le nameid qui est commun entre chrono et wcs, puisqu'on aura toujours affaire à un agent connecté.

Ça nécessiterait de remplacer le '{{ session_hash_id }}' par '{% firstof session_user_nameid session_hash_id %}' (à faire également dans la doc https://doc-publik.entrouvert.com/admin-fonctionnel/les-tutos/pre-reservation-dun-rendez-vous-ou-dun-evenement/).


Related issues

Related to w.c.s. - Développement #24635: Générer un identifiant pour un formdata dès la saisieNouveau19 June 2018

Actions
Related to Chrono - Développement #97539: api datetimes, accepter plusieurs lock_codeRejeté24 October 2024

Actions

Associated revisions

Revision 4e046505 (diff)
Added by Valentin Deniaud 27 days ago

data_sources: use agenda lock_code from submission_context (#96866)

History

#1

Updated by Benjamin Dauvergne about 2 months ago

Avant d'utiliser session_hash_id l'idée était d'avoir un identifiant unique associé au brouillon; à mon grand regret on a introduit un uuid que sur CardData; mais avoir un uuid a toujours ma préférence, si on a moyen d'avoir un identifiant unique au niveau brouillon, le processus pourrait être:
  • créer un brouillon en y configurant le créneau,
  • obtenir son uuid,
  • utiliser l'uuid pour pré-réserver le créneau,
  • envoyer l'agent sur le brouillon

L'avantage étant que ça marchera partout et que ça corrigera un effet de bord avec les lock code sur le hash du session_id qui est que si on a plusieurs brouillons et/ou formulaires sur un même agenda dans une même session, ça ne marche pas (chaque formulaire supprime les verrous de l'autre).

#2

Updated by Benjamin Dauvergne about 2 months ago

#3

Updated by Valentin Deniaud about 2 months ago

Benjamin Dauvergne a écrit :

le processus pourrait être:

Ça change pas mal ce qu'on a annoncé/imaginé pour ce dev mutualisé, en plus le sujet n'a pas l'air trivial et vu que j'ai une échéance j'aime autant rester sur le truc simple imaginé.

Aussi imaginons que je veuille masquer un champ si le formulaire est affiché dans le contexte de la réservation backoffice, c'est vachement plus direct de taper un truc à base de request.GET dans une condition d'affichage, plutôt que de réfléchir au fait qu'il faut dire à chrono de remplir une donnée calculée plutôt que directement le champ créneau (parfaitement possible juste moins simple à comprendre).

Mais avant tout ça je me rends compte que j'ai zéro plan pour migrer les usages existants, il y en a une bonne trentaine rien que sur le saas de prod, et n'importe quel changement ici les perturberait :/

#4

Updated by Valentin Deniaud about 2 months ago

Valentin Deniaud a écrit :

Mais avant tout ça je me rends compte que j'ai zéro plan pour migrer les usages existants, il y en a une bonne trentaine rien que sur le saas de prod, et n'importe quel changement ici les perturberait :/

À y réfléchir j'ai un plan pas si compliqué : permettre de passer plusieurs lock_code dans l'API /datetimes/, plutôt que ?lock_code={% firstof session_user_nameid session_hash_id %}, ?lock_code={{ session_user_nameid }}&lock_code={{session_hash_id }}, et les usages existants avec seulement session_hash_id dans les appels de réservation ne seront pas affectés.

#5

Updated by Benjamin Dauvergne about 2 months ago

Valentin Deniaud a écrit :

Ça change pas mal ce qu'on a annoncé/imaginé pour ce dev mutualisé, en plus le sujet n'a pas l'air trivial et vu que j'ai une échéance j'aime autant rester sur le truc simple imaginé.

Je ne sais pas, je fais juste l'historique sur la question.

Aussi imaginons que je veuille masquer un champ si le formulaire est affiché dans le contexte de la réservation backoffice, c'est vachement plus direct de taper un truc à base de request.GET dans une condition d'affichage, plutôt que de réfléchir au fait qu'il faut dire à chrono de remplir une donnée calculée plutôt que directement le champ créneau (parfaitement possible juste moins simple à comprendre).

Pour l'instant je ne vois pas bien comment deviner le champ à remplir quelque soit la méthode mais donc je suppose que ça devra être configuré à la main et qu'il faudra à chaque prévoir cet usage au niveau du formulaire en plus...

Sinon inventer un nouveau type d'identifiant de créneau qui intégrerait le lock_code (et prendrait le pas sur celui passé en paramètre), on peut même prévoir que le premier fill-slot avec un lock_code renvoie un tel identifiant. Ainsi on peut utiliser le lock_code qu'on veut, ensuite ce qu'envoie w.c.s. est ignoré. Pas besoin de changer les sources de donnée.

Mais avant tout ça je me rends compte que j'ai zéro plan pour migrer les usages existants, il y en a une bonne trentaine rien que sur le saas de prod, et n'importe quel changement ici les perturberait :/

Tu parles de quel usage existant ?

#6

Updated by Benjamin Dauvergne about 2 months ago

Autre idée qui ressemble plus à la tienne, pour ce cas d'usage, prévoir un champ calculé défini à "lock_code" et dans les sources de donnée utiliser "{% firstof form_var_lock_code session_hash_id %}" (et pré-remplir ce champ avec request.GET.lock_code).

#7

Updated by Valentin Deniaud about 2 months ago

Benjamin Dauvergne a écrit :

Pour l'instant je ne vois pas bien comment deviner le champ à remplir quelque soit la méthode mais donc je suppose que ça devra être configuré à la main et qu'il faudra à chaque prévoir cet usage au niveau du formulaire en plus...

Yep ça on l'a annoncé il faudra forcément modifier le formulaire, pas de magie à inventer, sinon on aurait fait payer plus cher.

Ce que je disais c'était simplement que certaines modifs à effectuer seront plus compréhensibles pour un admin fonctionnel si il s'agit de manipuler request.GET.

Mais avant tout ça je me rends compte que j'ai zéro plan pour migrer les usages existants, il y en a une bonne trentaine rien que sur le saas de prod, et n'importe quel changement ici les perturberait :/

Tu parles de quel usage existant ?

Le {{ session_hash_id }} envoyé dans les appels à fillslot, ça casserait avec la modif que je suggère en description (mais pas celle que je suggère dans #96866-4).

Autre idée qui ressemble plus à la tienne, pour ce cas d'usage, prévoir un champ calculé défini à "lock_code" et dans les sources de donnée utiliser "{% firstof form_var_lock_code session_hash_id %}" (et pré-remplir ce champ avec request.GET.lock_code).

Certes mais c'est un paramètre à passer à wcs en plus et sur le principe ça me dérange un peu d'avoir form_var_lock_code en dur dans le code.

#8

Updated by Benjamin Dauvergne about 2 months ago

Encore une autre idée qui me passe par la tête: regarder si on ne peut pas pousser le lock_code dans le submission_context à la création du brouillon, dans mon souvenir on pouvait y mettre un peu ce qu'on veut (mais j'ai peut-être un mauvais souvenir) via le paramètre "context" et ensuite c'est accessible via form_submission_context_lock_code.

Ainsi plus besoin de prévoir un champ en plus non plus.

#9

Updated by Benjamin Dauvergne about 2 months ago

Valentin Deniaud a écrit :

Valentin Deniaud a écrit :

Mais avant tout ça je me rends compte que j'ai zéro plan pour migrer les usages existants, il y en a une bonne trentaine rien que sur le saas de prod, et n'importe quel changement ici les perturberait :/

À y réfléchir j'ai un plan pas si compliqué : permettre de passer plusieurs lock_code dans l'API /datetimes/, plutôt que ?lock_code={% firstof session_user_nameid session_hash_id %}, ?lock_code={{ session_user_nameid }}&lock_code={{session_hash_id }}, et les usages existants avec seulement session_hash_id dans les appels de réservation ne seront pas affectés.

Le lock_code n'est pas passé dans l'URL mais dans le contenu du POST actuellement, la différence entre une réservation temporaire et définitive se fait sur la présence de "confirm_after_lock": true dans le même contenu du POST.

Donc je pense que si tu rajoutes un paramètre d'URL lock_code qui aurait précédence sur le paramètre du payload ça résout ton souci des usages existants, donc je résume:
1. modifier chrono pour MeetingDatetime renvoie un fillslot_url contenant un paramètre ?lock_code=... prédéfini à celui qui a été reçu
2. modifier MeetingsAgendaFillslot pour prendre le lock_code dans request.GET si et seulement si il y a un autre lock_code dans le payload (pour ne pas casser les usages existants qui n'utilisent pas encore lock_code mais en même temps faciliter la migration de ceux qui l'utilisent)
3. modifier la définition des sources de donnée dans w.c.s pour ?lock_code={% firstof form_submission_context_lock_code session_hash_id %}, ainsi pas besoin de verrouiller le champ, l'agent peut changer de créneau si il veut mais le créneau initialement choisi est garanti verrouillé pour ce formulaire, un nouveau verrou libérera le verrou initial,
4. pour initialiser une demande de rdv depuis l'agenda, permettre de choisir un formulaire et un des champs item (on l'appellera "rdv")
5. quand un agent demande un rdv sur ce créneau:
  • choisir un lock_code,
  • bloquer le créneau avec ce lock_code,
  • obtenir la description du créneau tel que renvoyé par meetingdatetimes dans "d"
  • créer un brouillon avec
    {
        "meta": {"backoffice_submission": true, "draft": true},
        "context": {"lock_code": <lock_code>},
        "data": {"rdv": d["id"], "rdv_display": d["text"], "rdv_structured": d}
    }

Et là j'ai l'impression qu'on est bon.

#10

Updated by Valentin Deniaud about 2 months ago

Benjamin Dauvergne a écrit :

Valentin Deniaud a écrit :

À y réfléchir j'ai un plan pas si compliqué : permettre de passer plusieurs lock_code dans l'API /datetimes/, plutôt que ?lock_code={% firstof session_user_nameid session_hash_id %}, ?lock_code={{ session_user_nameid }}&lock_code={{session_hash_id }}, et les usages existants avec seulement session_hash_id dans les appels de réservation ne seront pas affectés.

Le lock_code n'est pas passé dans l'URL mais dans le contenu du POST actuellement, la différence entre une réservation temporaire et définitive se fait sur la présence de "confirm_after_lock": true dans le même contenu du POST.

J'ai l'impression que tu réponds à côté, je parle des paramètres passés à datetimes dans la source de données wcs. Pour ne pas casser l'existant je propose de modifier MeetingDatetime pour accepter plusieurs lock code, tu proposes de modifier MeetingsAgendaFillslot pour en accepter deux et choisir lequel prendre, ça me paraît assez kif-kif vu d'ici je ne sais pas sur quoi baser le choix entre l'une ou l'autre.

1. modifier chrono pour MeetingDatetime renvoie un fillslot_url contenant un paramètre ?lock_code=... prédéfini à celui qui a été reçu

Pourquoi ça n'a pas été fait comme ça de base ? Ça paraît en effet plus pratique

4. pour initialiser une demande de rdv depuis l'agenda, permettre de choisir un formulaire et un des champs item (on l'appellera "rdv")

Le problème c'est que j'aimerais pouvoir supporter un formulaire plus complexe, qui propose par exemple choix de l'agenda -> choix du type de rdv -> choix du rdv, donc c'est 3 champs à configurer dans chrono.

J'ai l'impression que tu imagines un truc assez chiadé avec appel à wcs pour la liste des formulaires puis du javascript pour afficher les champs possibles, perso ce serait plutôt juste des champs texte simple dans lesquels on met manuellement des identifiants.

Mais honnêtement je ne suis pas encore convaincu par l'approche à base de brouillon, si j'essaye de résumer :
  • Avec redirection :
    • Configuration dans chrono : renseigner l'URL du formulaire de réservation
    • Après la sélection d'un créneau dans chrono : redirection vers le formulaire avec agenda, type de rdv, créneau choisi, url de l'agenda en paramètres d'URL
    • Adaptations nécessaires : préremplir les champs avec request.GET. Si les champs ne sont pas sur la première page, préremplir des données calculées avec request.GET.
    • Gestion du lock_code : utilisation de session_user_nameid
  • Avec brouillon :
    • Configuration dans chrono : renseigner le slug du formulaire de réservation, et les identifiants des champs agenda (optionnel), type de rdv (optionnel), créneau
    • Après la sélection d'un créneau dans chrono : appel webservice de création d'un brouillon, redirection vers le formulaire avec l'url de l'agenda en paramètre d'URL
    • Adaptations nécessaires : aucunes, c'est le principal avantage. Si éventuellement on veut afficher/cacher un champ selon qu'on est en contexte de réservation depuis chrono, il faut créer des données calculées et indiquer leurs identifiants côté chrono, et on basera les conditions dessus.
    • Gestion du lock_code : génération dans chrono et passage dans submission_context au moment de créer le brouillon
#11

Updated by Benjamin Dauvergne about 2 months ago

Valentin Deniaud a écrit :

J'ai l'impression que tu réponds à côté, je parle des paramètres passés à datetimes dans la source de données wcs. Pour ne pas casser l'existant je propose de modifier MeetingDatetime pour accepter plusieurs lock code, tu proposes de modifier MeetingsAgendaFillslot pour en accepter deux et choisir lequel prendre, ça me paraît assez kif-kif vu d'ici je ne sais pas sur quoi baser le choix entre l'une ou l'autre.

Ok donc tu verrouilles ton créneau sur le nameid de l'agent, tu configures l'appel à datetimes pour qu'il passe ?lock_code=nameid&lock_code=session_hash_id; le créneau en question va être montré disponible.

Le souci va être ensuite dans l'appel à fillslot entre la page1 et la page2 pour la maintenance du verrou, il va recevoir fillslot={{ session_hash_id }} et ça ne va pas marcher car le créneau est déjà verrouillé avec un code différent, le nameid.

1. modifier chrono pour MeetingDatetime renvoie un fillslot_url contenant un paramètre ?lock_code=... prédéfini à celui qui a été reçu

Pourquoi ça n'a pas été fait comme ça de base ? Ça paraît en effet plus pratique

Parce que dans les workflows ne s'attendant pas à fonctionner avec des verrous l'appel fillslot dans le 1er statut du workflow aurait créé un verrou au lieu de réserver le créneau il fallait un design qui n'impacte pas les appels fillslot existant. L'adaptation consistant à ajouter des appels fillslot payload={lock_code=...} entre les pages puis un appels fillslot payload={lock_code=.., confirm_after_lock=true} en 1er statut du workflow.

4. pour initialiser une demande de rdv depuis l'agenda, permettre de choisir un formulaire et un des champs item (on l'appellera "rdv")

Le problème c'est que j'aimerais pouvoir supporter un formulaire plus complexe, qui propose par exemple choix de l'agenda -> choix du type de rdv -> choix du rdv, donc c'est 3 champs à configurer dans chrono.

C'est du paramétrage supplémentaire pour la création du brouillon, si tu ne veux pas faire d'IHM tu peux, le paramétrage ça peut juste être "slug-du-formulaire varname_du_champ_rdv champ1=valeur1 champ2=valeur2". Dans tous les cas ça me paraît moins pédestre que devoir introduire du paramétrage de pré-remplissage et des champs calculés dans tous les formulaires, jusqu'à ce que tout ça évolue.

J'ai l'impression que tu imagines un truc assez chiadé avec appel à wcs pour la liste des formulaires puis du javascript pour afficher les champs possibles, perso ce serait plutôt juste des champs texte simple dans lesquels on met manuellement des identifiants.

Je comprends mais on peut faire moche et simple, et puis joli et compliqué ensuite. Rien n'empêche de faire comme tu dis en mode brouillon avec des champs textes, le paramétrage des champs supplémentaires ça peut être une boite de texte avec une paire clé=valeur par ligne ou du json. La configuration minimale c'est de rentrer le slug du formulaire et le varname du champ rendez-vous.

Mais honnêtement je ne suis pas encore convaincu par l'approche à base de brouillon, si j'essaye de résumer :
  • Avec redirection :
    • Configuration dans chrono : renseigner l'URL du formulaire de réservation
    • Après la sélection d'un créneau dans chrono : redirection vers le formulaire avec agenda, type de rdv, créneau choisi, url de l'agenda en paramètres d'URL
    • Adaptations nécessaires : préremplir les champs avec request.GET. Si les champs ne sont pas sur la première page, préremplir des données calculées avec request.GET.

Et pré-remplir les suivants champs avec les champs calculés précédemment initialisés.

  • Gestion du lock_code : utilisation de session_user_nameid

Ça ne marche pas, voir plus haut, les appels à fillslot ne sauront pas quoi envoyé entre nameid ou session_hash_id.

  • Avec brouillon :
    • Configuration dans chrono : renseigner le slug du formulaire de réservation, et les identifiants des champs agenda (optionnel), type de rdv (optionnel), créneau
    • Après la sélection d'un créneau dans chrono : appel webservice de création d'un brouillon, redirection vers le formulaire avec l'url de l'agenda en paramètre d'URL
    • Adaptations nécessaires : aucunes, c'est le principal avantage. Si éventuellement on veut afficher/cacher un champ selon qu'on est en contexte de réservation depuis chrono, il faut créer des données calculées et indiquer leurs identifiants côté chrono, et on basera les conditions dessus.

Je suis d'avis de ne rien essayer de cacher, si l'agent veut changer de créneau ça ne me semble pas un souci pour ce cas d'usage. La problématique est identique avec une simple redirection, n'en parlons pas ici ça ne change rien au problème.

  • Gestion du lock_code : génération dans chrono et passage dans submission_context au moment de créer le brouillon
#12

Updated by Valentin Deniaud about 1 month ago

Benjamin Dauvergne a écrit :

Ok donc tu verrouilles ton créneau sur le nameid de l'agent

Non, je réfléchis dans le contexte actuel où tous les appels à fillslot sont faits avec session_hash_id. Permettre à datetimes de prendre en compte plusieurs lock_code c'est 1/ ne pas casser l'existant 2/ permettre la nouvelle utilisation par nameid (ou submission_context, le problème est le même).

Pourquoi ça n'a pas été fait comme ça de base ? Ça paraît en effet plus pratique

Parce que dans les workflows ne s'attendant pas à fonctionner avec des verrous l'appel fillslot dans le 1er statut du workflow aurait créé un verrou au lieu de réserver le créneau il fallait un design qui n'impacte pas les appels fillslot existant.

OK donc je préfère assez mon idée qui est invisible vs ce que tu proposes qui modifie ce qui est renvoyé.

#13

Updated by Benjamin Dauvergne about 1 month ago

Valentin Deniaud a écrit :

OK donc je préfère assez mon idée qui est invisible vs ce que tu proposes qui modifie ce qui est renvoyé.

Ton idée demande de modifier les appels à fillslot aussi, sinon ils ne fonctionneront pas, le même lock_code doit être envoyé à datetimes et tous les fillslot.

#14

Updated by Valentin Deniaud about 1 month ago

Invisible dans le sens où rien ne change pour les usages existants, il n'y a pas un truc en plus qui est renvoyé par chrono. Mais on est vraiment sur du détail.

#15

Updated by Benjamin Dauvergne about 1 month ago

Ok.

#16

Updated by Valentin Deniaud about 1 month ago

  • Assignee set to Valentin Deniaud
#17

Updated by Robot Gitea about 1 month ago

  • Status changed from Nouveau to En cours

Valentin Deniaud (vdeniaud) a ouvert une pull request sur Gitea concernant cette demande :

#18

Updated by Valentin Deniaud about 1 month ago

#19

Updated by Valentin Deniaud about 1 month ago

Bon forcément je me suis emmêlé les pinceaux, quand j'écrivais

Valentin Deniaud a écrit :

Mais avant tout ça je me rends compte que j'ai zéro plan pour migrer les usages existants, il y en a une bonne trentaine rien que sur le saas de prod, et n'importe quel changement ici les perturberait :/

Je parlais du changement pour utiliser le nameid de l'agent, qui se serait appliqué tout le temps.

Avec submission_context aucun problème, la variable ne sera présente qu'en saisie backoffice depuis chrono, on peut faire au plus simple ici (et ne rien toucher aux API chrono).

#20

Updated by Robot Gitea about 1 month ago

  • Status changed from En cours to Solution proposée
#21

Updated by Robot Gitea 27 days ago

  • Status changed from Solution proposée to Solution validée

Frédéric Péters (fpeters) a approuvé une pull request sur Gitea concernant cette demande :

#22

Updated by Robot Gitea 27 days ago

  • Status changed from Solution validée to Résolu (à déployer)

Valentin Deniaud (vdeniaud) a mergé une pull request sur Gitea concernant cette demande :

#23

Updated by Benjamin Dauvergne 27 days ago

Valentin Deniaud a écrit :

Avec submission_context aucun problème, la variable ne sera présente qu'en saisie backoffice depuis chrono, on peut faire au plus simple ici (et ne rien toucher aux API chrono).

Je me disais bien que ça m'arrivait de dire un truc sensé.

#24

Updated by Transition automatique 26 days ago

  • Status changed from Résolu (à déployer) to Solution déployée

Also available in: Atom PDF