api: ignore desks from other agendas in datetimes (#47645)

This commit is contained in:
Lauréline Guérin 2020-10-15 14:44:06 +02:00
parent c9ed2fad11
commit d98707aeae
No known key found for this signature in database
GPG Key ID: 1FAB9B9B4F93D473
2 changed files with 35 additions and 10 deletions

View File

@ -143,10 +143,23 @@ def get_all_slots(base_agenda, meeting_type, resources=None, unique=False):
}
# add exceptions from unavailability calendar
for time_period_exception in TimePeriodException.objects.filter(
unavailability_calendar__desks__agenda__in=agendas
).order_by('start_datetime', 'end_datetime'):
for desk in time_period_exception.unavailability_calendar.desks.all():
time_period_exception_queryset = (
TimePeriodException.objects.all()
.select_related('unavailability_calendar')
.prefetch_related(
Prefetch(
'unavailability_calendar__desks',
queryset=Desk.objects.filter(agenda__in=agendas),
to_attr='prefetched_desks',
)
)
.filter(unavailability_calendar__desks__agenda__in=agendas)
.order_by('start_datetime', 'end_datetime')
)
for time_period_exception in time_period_exception_queryset:
# unavailability calendar can be used in all desks;
# ignore desks outside of current agenda(s)
for desk in time_period_exception.unavailability_calendar.prefetched_desks:
if desk not in desks_exceptions:
desks_exceptions[desk] = IntervalSet()
desks_exceptions[desk].add(

View File

@ -4129,13 +4129,18 @@ def test_duration_on_booking_api_fillslots_response(app, user):
assert 'DTEND:20170520T004200Z' in ics
def test_unavailabilitycalendar_meetings_datetimes(app, user, meetings_agenda):
@pytest.mark.freeze_time('2017-05-21')
def test_unavailabilitycalendar_meetings_datetimes(app, user):
meetings_agenda = Agenda.objects.create(label='Meeting', kind='meetings', maximal_booking_delay=7)
desk = Desk.objects.create(agenda=meetings_agenda, label='desk 1')
meeting_type = MeetingType.objects.create(agenda=meetings_agenda, label='Meeting Type', duration=30)
TimePeriod.objects.create(
weekday=0, start_time=datetime.time(9, 0), end_time=datetime.time(18, 0), desk=desk,
)
app.authorization = ('Basic', ('john.doe', 'password'))
meeting_type = meetings_agenda.meetingtype_set.first()
desk = meetings_agenda.desk_set.first()
datetimes_url = '/api/agenda/%s/meetings/%s/datetimes/' % (meetings_agenda.slug, meeting_type.slug)
resp = app.get(datetimes_url)
assert len(resp.json['data']) == 144
assert len(resp.json['data']) == 18
# create an unvalailability calendar
unavailability_calendar = UnavailabilityCalendar.objects.create(label='foo holydays')
@ -4145,13 +4150,20 @@ def test_unavailabilitycalendar_meetings_datetimes(app, user, meetings_agenda):
end_datetime=make_aware(datetime.datetime(2017, 5, 22, 11, 0)),
)
unavailability_calendar.desks.add(desk)
# link unavailability calendar to a desk of another agenda
other_agenda = Agenda.objects.create(label='Meeting 2', kind='meetings', maximal_booking_delay=7)
other_desk = Desk.objects.create(agenda=other_agenda, label='desk 1')
unavailability_calendar.desks.add(other_desk)
unavailability_calendar2 = UnavailabilityCalendar.objects.create(label='bar holydays')
unavailability_calendar2.desks.add(desk)
# 2 slots are gone
resp2 = app.get(datetimes_url)
with CaptureQueriesContext(connection) as ctx:
resp2 = app.get(datetimes_url)
assert len(ctx.captured_queries) == 10
assert len(resp.json['data']) == len(resp2.json['data']) + 2
# add a standard desk exception
desk = meetings_agenda.desk_set.first()
TimePeriodException.objects.create(
desk=desk,
start_datetime=make_aware(datetime.datetime(2017, 5, 22, 11, 0)),