From 4d761e1044635ff67f6694c22fb71bb2fbca1329 Mon Sep 17 00:00:00 2001 From: Valentin Deniaud Date: Thu, 13 Oct 2022 15:49:11 +0200 Subject: [PATCH 3/7] agendas: add date field to time period (#70185) --- .../0140_add_timeperiod_date_field.py | 50 +++++++++++++++++++ chrono/agendas/models.py | 12 ++++- tests/test_time_periods.py | 29 +++++++++++ 3 files changed, 89 insertions(+), 2 deletions(-) create mode 100644 chrono/agendas/migrations/0140_add_timeperiod_date_field.py diff --git a/chrono/agendas/migrations/0140_add_timeperiod_date_field.py b/chrono/agendas/migrations/0140_add_timeperiod_date_field.py new file mode 100644 index 00000000..a4c42862 --- /dev/null +++ b/chrono/agendas/migrations/0140_add_timeperiod_date_field.py @@ -0,0 +1,50 @@ +# Generated by Django 2.2.26 on 2022-10-13 13:46 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('agendas', '0139_auto_20220726_1017'), + ] + + operations = [ + migrations.AlterModelOptions( + name='timeperiod', + options={'ordering': ['weekday', 'date', 'start_time']}, + ), + migrations.AddField( + model_name='timeperiod', + name='date', + field=models.DateField(null=True, verbose_name='Date'), + ), + migrations.AlterField( + model_name='timeperiod', + name='weekday', + field=models.IntegerField( + choices=[ + (0, 'Monday'), + (1, 'Tuesday'), + (2, 'Wednesday'), + (3, 'Thursday'), + (4, 'Friday'), + (5, 'Saturday'), + (6, 'Sunday'), + ], + null=True, + verbose_name='Week day', + ), + ), + migrations.AddConstraint( + model_name='timeperiod', + constraint=models.CheckConstraint( + check=models.Q( + models.Q(('date__isnull', True), ('weekday__isnull', False)), + models.Q(('date__isnull', False), ('weekday__isnull', True)), + _connector='OR', + ), + name='date_xor_weekday', + ), + ), + ] diff --git a/chrono/agendas/models.py b/chrono/agendas/models.py index 2ece19a3..a839687a 100644 --- a/chrono/agendas/models.py +++ b/chrono/agendas/models.py @@ -1103,13 +1103,14 @@ WEEK_CHOICES = [ class TimePeriod(models.Model): - weekday = models.IntegerField(_('Week day'), choices=WEEKDAYS_LIST) + weekday = models.IntegerField(_('Week day'), choices=WEEKDAYS_LIST, null=True) weekday_indexes = ArrayField( models.IntegerField(choices=WEEK_CHOICES), verbose_name=_('Repeat'), blank=True, null=True, ) + date = models.DateField(_('Date'), null=True) start_time = models.TimeField(_('Start')) end_time = models.TimeField(_('End')) desk = models.ForeignKey('Desk', on_delete=models.CASCADE, null=True) @@ -1118,7 +1119,14 @@ class TimePeriod(models.Model): ) class Meta: - ordering = ['weekday', 'start_time'] + ordering = ['weekday', 'date', 'start_time'] + constraints = [ + models.CheckConstraint( + check=Q(date__isnull=True, weekday__isnull=False) + | Q(date__isnull=False, weekday__isnull=True), + name='date_xor_weekday', + ) + ] def __str__(self): label = force_str(WEEKDAYS[self.weekday]) diff --git a/tests/test_time_periods.py b/tests/test_time_periods.py index 50748e8c..0cf542d0 100644 --- a/tests/test_time_periods.py +++ b/tests/test_time_periods.py @@ -1,6 +1,7 @@ import datetime import pytest +from django.db import IntegrityError, transaction from django.db.models import Q from django.test import override_settings from django.utils.encoding import force_str @@ -391,3 +392,31 @@ def test_timeperiod_weekday_indexes(): events = get_events(datetime.datetime(2022, 5, 1), datetime.datetime(2022, 6, 1)) assert events[0].timetuple()[:5] == (2022, 5, 30, 22, 0) assert len(events) == 1 + + +def test_time_period_check_constraint(): + TimePeriod.objects.create( + weekday=0, start_time=datetime.time(hour=1, minute=0), end_time=datetime.time(hour=2, minute=0) + ) + TimePeriod.objects.create( + date=datetime.date.today(), + start_time=datetime.time(hour=1, minute=0), + end_time=datetime.time(hour=2, minute=0), + ) + + # missing weekday or date + with pytest.raises(IntegrityError): + with transaction.atomic(): + TimePeriod.objects.create( + start_time=datetime.time(hour=1, minute=0), end_time=datetime.time(hour=2, minute=0) + ) + + # both weekday and date + with pytest.raises(IntegrityError): + with transaction.atomic(): + TimePeriod.objects.create( + weekday=0, + date=datetime.date.today(), + start_time=datetime.time(hour=1, minute=0), + end_time=datetime.time(hour=2, minute=0), + ) -- 2.35.1