Projet

Général

Profil

Bug #53313

Quand un filtrage par date est appliqué l'exclusion des rendez-vous est mal faite

Ajouté par Benjamin Dauvergne il y a environ 3 ans. Mis à jour il y a environ 3 ans.

Statut:
Fermé
Priorité:
Normal
Assigné à:
Catégorie:
-
Version cible:
-
Début:
21 avril 2021
Echéance:
% réalisé:

0%

Temps estimé:
Patch proposed:
Oui
Planning:
Non

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

Révision 0bb2ca36 (diff)
Ajouté par Benjamin Dauvergne il y a environ 3 ans

api: fix typo in gel_all_slots() (#53313)

Révision 3952fe60 (diff)
Ajouté par Benjamin Dauvergne il y a environ 3 ans

agenda: add get_max_meeting_duration method (#53313)

Révision 10a9c80f (diff)
Ajouté par Benjamin Dauvergne il y a environ 3 ans

tests: add test overlapping events with filtered dates (#53313)

Révision 6c9518f4 (diff)
Ajouté par Benjamin Dauvergne il y a environ 3 ans

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

#2

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.

#3

Mis à jour par Benjamin Dauvergne il y a environ 3 ans

  • Description mis à jour (diff)
#4

Mis à jour par Benjamin Dauvergne il y a environ 3 ans

  • Tracker changé de Development à Bug
#5

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é ?

#6

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.

#7

Mis à jour par Lauréline Guérin il y a environ 3 ans

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

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)
#9

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

Formats disponibles : Atom PDF