agendas: reimplement min/max_booking_datetime based on minimal_booking_time (#56284)
This commit is contained in:
parent
ddc52a4116
commit
dbd62e3f3f
|
@ -643,31 +643,27 @@ class Agenda(models.Model):
|
|||
if self.maximal_booking_delay is None:
|
||||
return None
|
||||
|
||||
# compute middle of today with localtime
|
||||
# 28 Mar 2021 12:00 +01:00
|
||||
t = localtime(now()).replace(hour=12, minute=0)
|
||||
# reference is now, in local timezone
|
||||
t = localtime(now())
|
||||
|
||||
# advance of self.maximal_booking_delay - 1 days
|
||||
# 28 Mar 2021 12:00 +01:00 == 28 Mars 2021 13:00 +02:00 as DST happend on 28 Mar 2021.
|
||||
# add delay
|
||||
t += datetime.timedelta(days=self.maximal_booking_delay)
|
||||
|
||||
# move to midnight of the day before, DST happen between 2h/3h so it
|
||||
# always exists because +/- timedelta does not move the timezone, only
|
||||
# localtime() does it.
|
||||
# 27 Mar 2021 12:00 +01:00 == 28 Mars 2021 01:00 +02:00
|
||||
return localtime(t).replace(hour=0, minute=0, second=0, microsecond=0)
|
||||
# replace time if needed
|
||||
if self.minimal_booking_time:
|
||||
t = datetime.datetime.combine(t.date(), self.minimal_booking_time, tzinfo=t.tzinfo)
|
||||
# t could not exist, recompute it as an existing datetime by converting to UTC then to localtime
|
||||
return localtime(t.astimezone(utc))
|
||||
|
||||
@functional.cached_property
|
||||
def min_booking_datetime(self):
|
||||
if self.minimal_booking_delay is None:
|
||||
return None
|
||||
|
||||
# compute middle of today with localtime
|
||||
# 28 Mar 2021 12:00 +01:00
|
||||
t = localtime(now()).replace(hour=12, minute=0)
|
||||
# reference is now, in local timezone
|
||||
t = localtime(now())
|
||||
|
||||
# advance of self.minimal_booking_delay - 1 days
|
||||
# 28 Mar 2021 12:00 +01:00 == 28 Mars 2021 13:00 +02:00 as DST happend on 28 Mar 2021.
|
||||
# add delay
|
||||
if settings.WORKING_DAY_CALENDAR is not None and self.minimal_booking_delay_in_working_days:
|
||||
source_class = import_string(settings.WORKING_DAY_CALENDAR)
|
||||
calendar = source_class()
|
||||
|
@ -675,11 +671,11 @@ class Agenda(models.Model):
|
|||
else:
|
||||
t += datetime.timedelta(days=self.minimal_booking_delay)
|
||||
|
||||
# move to midnight of the day before, DST happen between 2h/3h so it
|
||||
# always exists because +/- timedelta does not move the timezone, only
|
||||
# localtime() does it.
|
||||
# 27 Mar 2021 12:00 +01:00 == 28 Mars 2021 01:00 +02:00
|
||||
return localtime(t).replace(hour=0, minute=0, second=0, microsecond=0)
|
||||
# replace time if needed
|
||||
if self.minimal_booking_time:
|
||||
t = datetime.datetime.combine(t.date(), self.minimal_booking_time, tzinfo=t.tzinfo)
|
||||
# t could not exist, recompute it as an existing datetime by converting to UTC then to localtime
|
||||
return localtime(t.astimezone(utc))
|
||||
|
||||
def get_open_events(
|
||||
self,
|
||||
|
|
|
@ -613,7 +613,7 @@ def test_add_agenda(app, user, settings):
|
|||
agenda = Agenda.objects.get(slug='foo-events')
|
||||
assert agenda.edit_role == edit_group
|
||||
assert agenda.view_role == view_group
|
||||
assert agenda.min_booking_datetime.date() == datetime.date(2021, 7, 12)
|
||||
assert agenda.min_booking_datetime == localtime(now()).replace(day=12)
|
||||
assert agenda.minimal_booking_time is None
|
||||
assert agenda.category == category_a
|
||||
assert agenda.events_type == events_type
|
||||
|
|
|
@ -36,7 +36,7 @@ from chrono.agendas.models import (
|
|||
UnavailabilityCalendar,
|
||||
VirtualMember,
|
||||
)
|
||||
from chrono.utils.timezone import localtime, make_aware, now
|
||||
from chrono.utils.timezone import localtime, make_aware, make_naive, now
|
||||
|
||||
pytestmark = pytest.mark.django_db
|
||||
|
||||
|
@ -268,6 +268,158 @@ def test_agenda_maximal_booking_delay(freezer):
|
|||
assert agenda.max_booking_datetime == make_aware(datetime.datetime(2021, 11, 2, 0, 0, 0))
|
||||
|
||||
|
||||
def delay_parameter_to_label(argvalue):
|
||||
if isinstance(argvalue, str):
|
||||
return argvalue
|
||||
return repr(argvalue)
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
'current_time,min_booking_datetime',
|
||||
[
|
||||
('2021-07-09T08:00:00+02:00', datetime.datetime(2021, 7, 13, 8)),
|
||||
('2021-03-18T07:00:00+01:00', datetime.datetime(2021, 3, 22, 7)),
|
||||
# summer DST change on sunday 28th
|
||||
('2021-03-25T01:30:00+01:00', datetime.datetime(2021, 3, 29, 1, 30)),
|
||||
('2021-03-25T02:30:00+01:00', datetime.datetime(2021, 3, 29, 2, 30)),
|
||||
('2021-03-25T03:30:00+01:00', datetime.datetime(2021, 3, 29, 3, 30)),
|
||||
('2021-03-28T01:30:00+01:00', datetime.datetime(2021, 4, 1, 1, 30)),
|
||||
('2021-03-28T03:30:00+02:00', datetime.datetime(2021, 4, 1, 3, 30)),
|
||||
# winter DST change on sunday 31th
|
||||
('2021-10-29T01:30:00+02:00', datetime.datetime(2021, 11, 2, 1, 30)),
|
||||
('2021-10-29T02:30:00+02:00', datetime.datetime(2021, 11, 2, 2, 30)),
|
||||
('2021-10-29T02:30:00+02:00', datetime.datetime(2021, 11, 2, 2, 30)),
|
||||
('2021-10-31T01:30:00+02:00', datetime.datetime(2021, 11, 4, 1, 30)),
|
||||
('2021-10-31T02:30:00+02:00', datetime.datetime(2021, 11, 4, 2, 30)),
|
||||
('2021-10-31T02:30:00+01:00', datetime.datetime(2021, 11, 4, 2, 30)),
|
||||
('2021-10-31T03:30:00+01:00', datetime.datetime(2021, 11, 4, 3, 30)),
|
||||
],
|
||||
ids=delay_parameter_to_label,
|
||||
)
|
||||
def test_agenda_minimal_booking_delay_no_minimal_booking_time(freezer, current_time, min_booking_datetime):
|
||||
freezer.move_to(current_time)
|
||||
agenda = Agenda.objects.create(label='Agenda', minimal_booking_delay=4, minimal_booking_time=None)
|
||||
assert make_naive(agenda.min_booking_datetime) == min_booking_datetime
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
'current_time,min_booking_datetime',
|
||||
[
|
||||
('2021-07-09T08:00:00+02:00', datetime.datetime(2021, 7, 16, 8)),
|
||||
('2021-03-18T07:00:00+01:00', datetime.datetime(2021, 3, 24, 7)),
|
||||
# summer DST change on sunday 28th
|
||||
('2021-03-25T01:30:00+01:00', datetime.datetime(2021, 3, 31, 1, 30)),
|
||||
('2021-03-25T02:30:00+01:00', datetime.datetime(2021, 3, 31, 2, 30)),
|
||||
('2021-03-25T03:30:00+01:00', datetime.datetime(2021, 3, 31, 3, 30)),
|
||||
('2021-03-28T01:30:00+01:00', datetime.datetime(2021, 4, 1, 1, 30)),
|
||||
('2021-03-28T03:30:00+02:00', datetime.datetime(2021, 4, 1, 3, 30)),
|
||||
# winter DST change on sunday 31th
|
||||
('2021-10-29T01:30:00+02:00', datetime.datetime(2021, 11, 5, 1, 30)),
|
||||
('2021-10-29T02:30:00+02:00', datetime.datetime(2021, 11, 5, 2, 30)),
|
||||
('2021-10-29T02:30:00+02:00', datetime.datetime(2021, 11, 5, 2, 30)),
|
||||
('2021-10-31T01:30:00+02:00', datetime.datetime(2021, 11, 5, 1, 30)),
|
||||
('2021-10-31T02:30:00+02:00', datetime.datetime(2021, 11, 5, 2, 30)),
|
||||
('2021-10-31T02:30:00+01:00', datetime.datetime(2021, 11, 5, 2, 30)),
|
||||
('2021-10-31T03:30:00+01:00', datetime.datetime(2021, 11, 5, 3, 30)),
|
||||
],
|
||||
ids=delay_parameter_to_label,
|
||||
)
|
||||
def test_agenda_minimal_booking_delay_in_working_days_no_minimal_booking_time(
|
||||
settings, freezer, current_time, min_booking_datetime
|
||||
):
|
||||
settings.WORKING_DAY_CALENDAR = 'workalendar.europe.France'
|
||||
freezer.move_to(current_time)
|
||||
agenda = Agenda.objects.create(
|
||||
label='Agenda',
|
||||
minimal_booking_delay=4,
|
||||
minimal_booking_time=None,
|
||||
minimal_booking_delay_in_working_days=True,
|
||||
)
|
||||
assert make_naive(agenda.min_booking_datetime) == min_booking_datetime
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
'current_time,min_booking_datetime',
|
||||
[
|
||||
('2021-07-09T08:00:00+02:00', datetime.datetime(2021, 7, 13, 8)),
|
||||
('2021-03-18T07:00:00+01:00', datetime.datetime(2021, 3, 22, 8)),
|
||||
# summer DST change on sunday
|
||||
('2021-03-25T02:30:00+01:00', datetime.datetime(2021, 3, 29, 8)),
|
||||
('2021-03-25T03:30:00+01:00', datetime.datetime(2021, 3, 29, 8)),
|
||||
# winter DST change on sunday
|
||||
('2021-10-29T01:30:00+02:00', datetime.datetime(2021, 11, 2, 8)),
|
||||
('2021-10-29T02:30:00+02:00', datetime.datetime(2021, 11, 2, 8)),
|
||||
('2021-10-29T02:30:00+02:00', datetime.datetime(2021, 11, 2, 8)),
|
||||
('2021-10-31T01:30:00+02:00', datetime.datetime(2021, 11, 4, 8)),
|
||||
('2021-10-31T02:30:00+02:00', datetime.datetime(2021, 11, 4, 8)),
|
||||
('2021-10-31T02:30:00+01:00', datetime.datetime(2021, 11, 4, 8)),
|
||||
('2021-10-31T03:30:00+01:00', datetime.datetime(2021, 11, 4, 8)),
|
||||
],
|
||||
ids=delay_parameter_to_label,
|
||||
)
|
||||
def test_agenda_minimal_booking_delay_minimal_booking_time_at_8(freezer, current_time, min_booking_datetime):
|
||||
freezer.move_to(current_time)
|
||||
agenda = Agenda.objects.create(
|
||||
label='Agenda', minimal_booking_delay=4, minimal_booking_time=datetime.time(8)
|
||||
)
|
||||
assert make_naive(agenda.min_booking_datetime) == min_booking_datetime
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
'current_time,max_booking_datetime',
|
||||
[
|
||||
('2021-07-09T08:00:00+02:00', datetime.datetime(2021, 7, 13, 8)),
|
||||
('2021-03-18T07:00:00+01:00', datetime.datetime(2021, 3, 22, 7)),
|
||||
# summer DST change on sunday 28th
|
||||
('2021-03-25T01:30:00+01:00', datetime.datetime(2021, 3, 29, 1, 30)),
|
||||
('2021-03-25T02:30:00+01:00', datetime.datetime(2021, 3, 29, 2, 30)),
|
||||
('2021-03-25T03:30:00+01:00', datetime.datetime(2021, 3, 29, 3, 30)),
|
||||
('2021-03-28T01:30:00+01:00', datetime.datetime(2021, 4, 1, 1, 30)),
|
||||
('2021-03-28T03:30:00+02:00', datetime.datetime(2021, 4, 1, 3, 30)),
|
||||
# winter DST change on sunday 31th
|
||||
('2021-10-29T01:30:00+02:00', datetime.datetime(2021, 11, 2, 1, 30)),
|
||||
('2021-10-29T02:30:00+02:00', datetime.datetime(2021, 11, 2, 2, 30)),
|
||||
('2021-10-29T02:30:00+02:00', datetime.datetime(2021, 11, 2, 2, 30)),
|
||||
('2021-10-31T01:30:00+02:00', datetime.datetime(2021, 11, 4, 1, 30)),
|
||||
('2021-10-31T02:30:00+02:00', datetime.datetime(2021, 11, 4, 2, 30)),
|
||||
('2021-10-31T02:30:00+01:00', datetime.datetime(2021, 11, 4, 2, 30)),
|
||||
('2021-10-31T03:30:00+01:00', datetime.datetime(2021, 11, 4, 3, 30)),
|
||||
],
|
||||
ids=delay_parameter_to_label,
|
||||
)
|
||||
def test_agenda_maximal_booking_delay_no_minimal_booking_time(freezer, current_time, max_booking_datetime):
|
||||
freezer.move_to(current_time)
|
||||
agenda = Agenda.objects.create(label='Agenda', maximal_booking_delay=4, minimal_booking_time=None)
|
||||
assert make_naive(agenda.max_booking_datetime) == max_booking_datetime
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
'current_time,max_booking_datetime',
|
||||
[
|
||||
('2021-07-09T08:00:00+02:00', datetime.datetime(2021, 7, 13, 8)),
|
||||
('2021-03-18T07:00:00+01:00', datetime.datetime(2021, 3, 22, 8)),
|
||||
# summer DST change on sunday
|
||||
('2021-03-25T02:30:00+01:00', datetime.datetime(2021, 3, 29, 8)),
|
||||
('2021-03-25T03:30:00+01:00', datetime.datetime(2021, 3, 29, 8)),
|
||||
# winter DST change on sunday
|
||||
('2021-10-29T01:30:00+02:00', datetime.datetime(2021, 11, 2, 8)),
|
||||
('2021-10-29T02:30:00+02:00', datetime.datetime(2021, 11, 2, 8)),
|
||||
('2021-10-29T02:30:00+02:00', datetime.datetime(2021, 11, 2, 8)),
|
||||
('2021-10-31T01:30:00+02:00', datetime.datetime(2021, 11, 4, 8)),
|
||||
('2021-10-31T02:30:00+02:00', datetime.datetime(2021, 11, 4, 8)),
|
||||
('2021-10-31T02:30:00+01:00', datetime.datetime(2021, 11, 4, 8)),
|
||||
('2021-10-31T03:30:00+01:00', datetime.datetime(2021, 11, 4, 8)),
|
||||
],
|
||||
ids=delay_parameter_to_label,
|
||||
)
|
||||
def test_agenda_maximal_booking_delay_minimal_booking_time_at_8(freezer, current_time, max_booking_datetime):
|
||||
freezer.move_to(current_time)
|
||||
agenda = Agenda.objects.create(
|
||||
label='Agenda', maximal_booking_delay=4, minimal_booking_time=datetime.time(8)
|
||||
)
|
||||
assert make_naive(agenda.max_booking_datetime) == max_booking_datetime
|
||||
|
||||
|
||||
@pytest.mark.parametrize('with_prefetch', [True, False])
|
||||
def test_agenda_is_available_for_simple_management(settings, with_prefetch):
|
||||
settings.EXCEPTIONS_SOURCES = {
|
||||
|
|
Loading…
Reference in New Issue