Bug #53313
Quand un filtrage par date est appliqué l'exclusion des rendez-vous est mal faite
0%
Description
Actuellement les rendez-vous déjà bookés sont filtrés ainsi :
booked_events = ( Event.objects.filter( agenda__in=agenda_ids, start_datetime__gte=used_min_datetime start_datetime__lte=used_max_datetime + meeting_duration_td, )
i.e. pour un intervalle visé [used_min_datetime, used_max_datetime]
et une durée de rendez-vous meeting_duration_td
on va considérer les rendez-vous commençant dans l'intervalle [used_min_datetime, used_max_datetime + meeting_duration_td]
, or cela ignore les rendez-vous commençant avant pour les mêmes agendas mais qui intersecte l'intervalle visé. Ces rendez-vous peuvent être d'une durée maximale max(mt.duration for mt in agenda.iter_meetingtypes())
, c'est donc elle qui devrait être prise en compte pour agrandir l'intervalle vers sont début, par contre il ne devrait pas être nécessaire d'augmenter l'intervalle vers sa fin, car si event.start_datetime
est supérieur à used_max_datetime
on est certain qu'il n'interfère pas.
Je propose donc d'introduire un Agenda.get_max_meeting_duration()
et de définir l'intervalle de recherche des évènements déjà booké (par rapport à leur start_datetime
) à
[used_min_datetime - max_meeting_duration_td, used_max_datetime]
avec
max_meeting_duration_td = datetime.timedelta(minutes=agenda.get_max_meeting_duration()
.
Au passage je met en cache Agenda.iter_meetingtypes()
pour éviter de le requêter plusieurs fois.
Le test introduit retourne 6 rendez-vous disponibles au lieu de 3 sans ce patch. J'ai aussi corrigé une typo timestamp
-> timestamp()
au passage (je peux en faire un autre ticket).
PS: problème observé en voulant ajouter du filtrage dans l'appel get_all_slots()
du endpoint fillslot
pour en diminuer le coût car actuellement on liste tous les slots possibles alors qu'on ne devrait chercher que les intersections avec l'intervalle des rendez-vous qu'on essaye de prendre. En ajoutant start/end_datetime à cet endroit ça a tout de suite cassé des tests; ce changement sera éventuellement proposé dans un autre ticket.
Fichiers
Révisions associées
agenda: add get_max_meeting_duration method (#53313)
tests: add test overlapping events with filtered dates (#53313)
api: change date filtering of already booked meetings (#53313)
For a researsing slots in an interval of
[min, max]
overlapping events should be considered if
event.start_datetime \in [min - agenda.max_duration_meeting_types, max]
as the implicit event.end_datetime cannot be superior to:
event.start_datetime + agenda.max_meeting_types_duration
and the formal condition for an overlapping event is :
event.start_datetime < max && event.end_datetime > min
Historique
Mis à jour par Benjamin Dauvergne il y a environ 3 ans
- Fichier 0001-api-fix-typo-in-gel_all_slots-53313.patch 0001-api-fix-typo-in-gel_all_slots-53313.patch ajouté
- Fichier 0002-agenda-add-get_max_meeting_duration-method-53313.patch 0002-agenda-add-get_max_meeting_duration-method-53313.patch ajouté
- Fichier 0003-tests-add-test-overlapping-events-with-filtered-date.patch 0003-tests-add-test-overlapping-events-with-filtered-date.patch ajouté
- Fichier 0004-api-change-date-filtering-of-already-booked-meetings.patch 0004-api-change-date-filtering-of-already-booked-meetings.patch ajouté
- Tracker changé de Bug à Development
- Statut changé de Nouveau à Solution proposée
- Patch proposed changé de Non à Oui
Mis à jour par Benjamin Dauvergne il y a environ 3 ans
Le filtrage est aussi modifié pour les Event liés aux ressources et pour un même excluded_user_external_id.
Mis à jour par Lauréline Guérin il y a environ 3 ans
dans start_datetime__gte=used_min_datetime - max_meeting_duration_td
, plutôt que de prendre le max duration, on ne pourrait pas utiliser un F field pour utiliser la duration propre à l'event sélectionné ?
Mis à jour par Benjamin Dauvergne il y a environ 3 ans
Lauréline Guerin a écrit :
dans
start_datetime__gte=used_min_datetime - max_meeting_duration_td
, plutôt que de prendre le max duration, on ne pourrait pas utiliser un F field pour utiliser la duration propre à l'event sélectionné ?
J'ai la vague intuition que ce sera ce sera plus coûteux1 (jointure sur la totalité de la table comme la db ne peut pas prévoir ce qui rentrera ou pas dans le filtre) en diminuant le nombre d'event considérés qu'à la marge, genre mon filtre retourne 10 events en bordure de période et ton filtre plus précis n'en retourne que 5, ça n'est pas un gain suffisant pour justifier la jointure, de plus le cas d'agenda rempli de rendez-vous de taille différentes ne me semble pas la règle donc je pense que c'est suffisant d'être correct mais pas forcément précis lors des requêtes.
PS: en ne filtrant que sur start_datetime avec une valeur fixe on est quasi sûr de faire un indexscan.
Mis à jour par Lauréline Guérin il y a environ 3 ans
- Statut changé de Solution proposée à Solution validée
Mis à jour par Benjamin Dauvergne il y a environ 3 ans
- Statut changé de Solution validée à Résolu (à déployer)
commit 6c9518f4d6e2c93f31f45edf0d1987e5e3f0becb Author: Benjamin Dauvergne <bdauvergne@entrouvert.com> Date: Wed Apr 21 10:45:26 2021 +0200 api: change date filtering of already booked meetings (#53313) For a researsing slots in an interval of [min, max] overlapping events should be considered if event.start_datetime \in [min - agenda.max_duration_meeting_types, max] as the implicit event.end_datetime cannot be superior to: event.start_datetime + agenda.max_meeting_types_duration and the formal condition for an overlapping event is : event.start_datetime < max && event.end_datetime > min commit 10a9c80f9a5b77fbbbf4b885eb3ba040f3459c1f Author: Benjamin Dauvergne <bdauvergne@entrouvert.com> Date: Wed Apr 21 10:44:31 2021 +0200 tests: add test overlapping events with filtered dates (#53313) commit 3952fe604bc82fa9b2b2810f660f06946b0d5a4f Author: Benjamin Dauvergne <bdauvergne@entrouvert.com> Date: Wed Apr 21 11:44:32 2021 +0200 agenda: add get_max_meeting_duration method (#53313) commit 0bb2ca36763024177b7e3b64e8c9eaf4d530a86b Author: Benjamin Dauvergne <bdauvergne@entrouvert.com> Date: Wed Apr 21 10:16:11 2021 +0200 api: fix typo in gel_all_slots() (#53313)
Mis à jour par Frédéric Péters il y a environ 3 ans
- Statut changé de Résolu (à déployer) à Solution déployée
api: fix typo in gel_all_slots() (#53313)