diff --git a/chrono/agendas/migrations/0155_event_triggers.py b/chrono/agendas/migrations/0155_event_triggers.py new file mode 100644 index 00000000..337aa3ef --- /dev/null +++ b/chrono/agendas/migrations/0155_event_triggers.py @@ -0,0 +1,18 @@ +import os + +from django.db import migrations + +with open( + os.path.join( + os.path.dirname(os.path.realpath(__file__)), '..', 'sql', 'event_booked_places_and_full_triggers.sql' + ) +) as sql_file: + sql_forwards = sql_file.read() + + +class Migration(migrations.Migration): + dependencies = [ + ('agendas', '0154_partial_booking_fields'), + ] + + operations = [migrations.RunSQL(sql=sql_forwards, reverse_sql=migrations.RunSQL.noop)] diff --git a/chrono/agendas/sql/event_booked_places_and_full_triggers.sql b/chrono/agendas/sql/event_booked_places_and_full_triggers.sql index 7afdae71..3d3534eb 100644 --- a/chrono/agendas/sql/event_booked_places_and_full_triggers.sql +++ b/chrono/agendas/sql/event_booked_places_and_full_triggers.sql @@ -13,6 +13,14 @@ BEGIN WHERE b.event_id = NEW.id AND b.cancellation_datetime IS NULL; END IF; + -- for events agenda with partial bookings, event is never full + PERFORM 1 FROM agendas_agenda a WHERE a.id = NEW.agenda_id AND a.partial_bookings IS TRUE; + IF FOUND THEN + NEW.almost_full = false; + NEW.full = false; + RETURN NEW; + END IF; + -- update almost_full field IF (NEW.booked_places >= NEW.places * 0.9) THEN NEW.almost_full = true; diff --git a/tests/test_agendas.py b/tests/test_agendas.py index f5e01f6f..4cd1c98e 100644 --- a/tests/test_agendas.py +++ b/tests/test_agendas.py @@ -2779,7 +2779,10 @@ def test_recurring_events_display(freezer): ) -def test_event_triggered_fields(): +@pytest.mark.parametrize('partial_bookings', [True, False]) +def test_event_triggered_fields(partial_bookings): + full_flags_true_value = not (partial_bookings) + # alter event pk sequence to have a bigint with connection.cursor() as cursor: cursor.execute("SELECT nextval('agendas_event_id_seq')") @@ -2787,7 +2790,7 @@ def test_event_triggered_fields(): if row[0] < 2**31: cursor.execute("ALTER SEQUENCE agendas_event_id_seq RESTART WITH %s;" % 2**31) - agenda = Agenda.objects.create(label='Agenda', kind='events') + agenda = Agenda.objects.create(label='Agenda', kind='events', partial_bookings=partial_bookings) event = Event.objects.create( agenda=agenda, start_datetime=now() + datetime.timedelta(days=10), places=10, label='Event' ) @@ -2826,30 +2829,30 @@ def test_event_triggered_fields(): event.refresh_from_db() assert event.booked_places == 9 assert event.booked_waiting_list_places == 0 - assert event.almost_full is True + assert event.almost_full == full_flags_true_value assert event.full is False Booking.objects.create(event=event) event.refresh_from_db() assert event.booked_places == 10 assert event.booked_waiting_list_places == 0 - assert event.almost_full is True - assert event.full is True + assert event.almost_full == full_flags_true_value + assert event.full == full_flags_true_value # cancel bookings for other event: no impact event2.booking_set.filter(cancellation_datetime__isnull=True).first().cancel() event.refresh_from_db() assert event.booked_places == 10 assert event.booked_waiting_list_places == 0 - assert event.almost_full is True - assert event.full is True + assert event.almost_full == full_flags_true_value + assert event.full == full_flags_true_value # cancel bookings event.booking_set.filter(cancellation_datetime__isnull=True).first().cancel() event.refresh_from_db() assert event.booked_places == 9 assert event.booked_waiting_list_places == 0 - assert event.almost_full is True + assert event.almost_full == full_flags_true_value assert event.full is False event.booking_set.filter(cancellation_datetime__isnull=True).first().cancel() event.refresh_from_db() @@ -2874,8 +2877,8 @@ def test_event_triggered_fields(): event.refresh_from_db() assert event.booked_places == 10 assert event.booked_waiting_list_places == 0 - assert event.almost_full is True - assert event.full is True + assert event.almost_full == full_flags_true_value + assert event.full == full_flags_true_value # with a waiting list event.waiting_list_places = 5 @@ -2883,7 +2886,7 @@ def test_event_triggered_fields(): event.refresh_from_db() assert event.booked_places == 10 assert event.booked_waiting_list_places == 0 - assert event.almost_full is True + assert event.almost_full == full_flags_true_value assert event.full is False # add bookings for other event: no impact @@ -2892,7 +2895,7 @@ def test_event_triggered_fields(): event.refresh_from_db() assert event.booked_places == 10 assert event.booked_waiting_list_places == 0 - assert event.almost_full is True + assert event.almost_full == full_flags_true_value assert event.full is False # add bookings @@ -2900,30 +2903,30 @@ def test_event_triggered_fields(): event.refresh_from_db() assert event.booked_places == 10 assert event.booked_waiting_list_places == 1 - assert event.almost_full is True + assert event.almost_full == full_flags_true_value assert event.full is False for _ in range(1, 5): Booking.objects.create(event=event, in_waiting_list=True) event.refresh_from_db() assert event.booked_places == 10 assert event.booked_waiting_list_places == 5 - assert event.almost_full is True - assert event.full is True + assert event.almost_full == full_flags_true_value + assert event.full == full_flags_true_value # cancel bookings for other event: no impact event2.booking_set.filter(in_waiting_list=True, cancellation_datetime__isnull=True).first().cancel() event.refresh_from_db() assert event.booked_places == 10 assert event.booked_waiting_list_places == 5 - assert event.almost_full is True - assert event.full is True + assert event.almost_full == full_flags_true_value + assert event.full == full_flags_true_value # cancel bookings event.booking_set.filter(in_waiting_list=True, cancellation_datetime__isnull=True).first().cancel() event.refresh_from_db() assert event.booked_places == 10 assert event.booked_waiting_list_places == 4 - assert event.almost_full is True + assert event.almost_full == full_flags_true_value assert event.full is False # update waiting list places @@ -2932,21 +2935,21 @@ def test_event_triggered_fields(): event.refresh_from_db() assert event.booked_places == 10 assert event.booked_waiting_list_places == 4 - assert event.almost_full is True - assert event.full is True + assert event.almost_full == full_flags_true_value + assert event.full == full_flags_true_value # delete bookings event.booking_set.filter(in_waiting_list=True, cancellation_datetime__isnull=True).first().delete() event.refresh_from_db() assert event.booked_places == 10 assert event.booked_waiting_list_places == 3 - assert event.almost_full is True + assert event.almost_full == full_flags_true_value assert event.full is False event.booking_set.filter(in_waiting_list=False, cancellation_datetime__isnull=True).first().delete() event.refresh_from_db() assert event.booked_places == 9 assert event.booked_waiting_list_places == 3 - assert event.almost_full is True + assert event.almost_full == full_flags_true_value assert event.full is False event.booking_set.filter(in_waiting_list=False, cancellation_datetime__isnull=True).first().delete() event.refresh_from_db()