misc: fix timeslot computation to work across daylight saving time (#19089)

This commit is contained in:
Frédéric Péters 2017-09-29 23:08:44 +02:00 committed by Thomas NOEL
parent 5fce9e5193
commit a6f108efd9
2 changed files with 27 additions and 3 deletions

View File

@ -28,7 +28,7 @@ from django.utils.dates import WEEKDAYS
from django.utils.encoding import force_text
from django.utils.formats import date_format, get_format
from django.utils.text import slugify
from django.utils.timezone import localtime, now, make_aware
from django.utils.timezone import localtime, now, make_aware, make_naive
from django.utils.translation import ugettext_lazy as _
from jsonfield import JSONField
@ -187,8 +187,10 @@ class TimePeriod(models.Model):
def get_time_slots(self, min_datetime, max_datetime, meeting_type):
duration = datetime.timedelta(minutes=meeting_type.duration)
min_datetime = make_naive(min_datetime)
max_datetime = make_naive(max_datetime)
real_min_datetime = localtime(min_datetime) + datetime.timedelta(
real_min_datetime = min_datetime + datetime.timedelta(
days=self.weekday - min_datetime.weekday())
if real_min_datetime < min_datetime:
real_min_datetime += datetime.timedelta(days=7)
@ -207,7 +209,7 @@ class TimePeriod(models.Model):
if event_datetime > max_datetime:
break
yield TimeSlot(start_datetime=event_datetime, meeting_type=meeting_type, desk=self.desk)
yield TimeSlot(start_datetime=make_aware(event_datetime), meeting_type=meeting_type, desk=self.desk)
event_datetime = end_time

View File

@ -304,6 +304,28 @@ def test_booking_api_meeting(app, meetings_agenda, user):
assert resp.json['err'] == 0
assert Booking.objects.count() == 2
def test_booking_api_meeting_across_daylight_saving_time(app, meetings_agenda, user):
meetings_agenda.maximal_booking_delay = 365
meetings_agenda.save()
agenda_id = meetings_agenda.slug
meeting_type = MeetingType.objects.get(agenda=meetings_agenda)
resp = app.get('/api/agenda/meetings/%s/datetimes/' % meeting_type.id)
event_index = 26 * 18
event_id = resp.json['data'][event_index]['id']
assert event_id[-4:] == resp.json['data'][2*18]['id'][-4:]
assert urlparse.urlparse(resp.json['data'][event_index]['api']['fillslot_url']
).path == '/api/agenda/%s/fillslot/%s/' % (meetings_agenda.slug, event_id)
app.authorization = ('Basic', ('john.doe', 'password'))
resp_booking = app.post('/api/agenda/%s/fillslot/%s/' % (agenda_id, event_id))
assert Booking.objects.count() == 1
assert resp_booking.json['datetime'][:16] == localtime(Booking.objects.all()[0].event.start_datetime
).isoformat()[:16]
resp = app.get('/api/agenda/meetings/%s/datetimes/' % meeting_type.id)
assert resp.json['data'][event_index]['disabled']
def test_booking_api_meeting_different_durations_book_short(app, meetings_agenda, user):
agenda_id = meetings_agenda.id
meeting_type = MeetingType.objects.get(agenda=meetings_agenda)