From 86f44f10c2a6a159452a3f59df47d9e5315a1b09 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Laur=C3=A9line=20Gu=C3=A9rin?= <zebuline@entrouvert.com>
Date: Mon, 14 Feb 2022 11:26:03 +0100
Subject: [PATCH 3/3] manager: display cancelled bookings on check page
 (#61068)

---
 .../templates/chrono/manager_event_check.html | 15 ++++++-
 chrono/manager/views.py                       | 12 +++---
 tests/manager/test_event.py                   | 41 +++++++++++++++----
 3 files changed, 54 insertions(+), 14 deletions(-)

diff --git a/chrono/manager/templates/chrono/manager_event_check.html b/chrono/manager/templates/chrono/manager_event_check.html
index 4627e47..56ab4c8 100644
--- a/chrono/manager/templates/chrono/manager_event_check.html
+++ b/chrono/manager/templates/chrono/manager_event_check.html
@@ -66,7 +66,15 @@
       {% for result in results %}
         <tr class="booking">
         {% if result.kind == 'booking' %}
-          {% with result as booking %}{% include "chrono/manager_event_check_booking_fragment.html" %}{% endwith %}
+          {% if result.cancellation_datetime is None %}
+            {% with result as booking %}{% include "chrono/manager_event_check_booking_fragment.html" %}{% endwith %}
+          {% else %}
+              <td class="booking-username main-list">{{ result.get_user_block }}</td>
+              <td class="booking-status">({% trans "Cancelled" %})</td>
+              {% if not event.checked or not agenda.disable_check_update %}
+              <td class="booking-actions"></td>
+              {% endif %}
+          {% endif %}
         {% elif result.kind == 'subscription' %}
           <td class="booking-username main-list">{{ result.get_user_block }}</td>
           <td class="booking-status">({% trans "Not booked" %})</td>
@@ -90,7 +98,10 @@
     <table class="main check-bookings">
       <tbody>
         {% for booking in waiting %}
-        <tr><td class="booking-username waiting">{{ booking.get_user_block }}{% if booking.places_count > 1 %} ({{ booking.places_count }} {% trans "places" %}){% endif %}</td></tr>
+        <tr>
+          <td class="booking-username waiting">{{ booking.get_user_block }}{% if booking.places_count > 1 %} ({{ booking.places_count }} {% trans "places" %}){% endif %}</td>
+          <td>{% if booking.cancellation_datetime %}({% trans "Cancelled" %}){% endif %}</td>
+        </tr>
         {% endfor %}
       </tbody>
     </table>
diff --git a/chrono/manager/views.py b/chrono/manager/views.py
index 497783d..d114e14 100644
--- a/chrono/manager/views.py
+++ b/chrono/manager/views.py
@@ -2075,17 +2075,19 @@ class EventCheckView(ViewableAgendaMixin, DetailView):
         event = self.object
 
         # booking base queryset
+        booking_qs_kwargs = {}
+        if not self.agenda.cancelled_bookings_on_check_page:
+            booking_qs_kwargs = {'cancellation_datetime__isnull': True}
         booked_qs = event.booking_set.filter(
-            cancellation_datetime__isnull=True, in_waiting_list=False, primary_booking__isnull=True
+            in_waiting_list=False, primary_booking__isnull=True, **booking_qs_kwargs
         )
         booked_qs = booked_qs.annotate(
-            places_count=Value(1)
-            + Count('secondary_booking_set', filter=Q(cancellation_datetime__isnull=True))
+            places_count=Value(1) + Count('secondary_booking_set', filter=Q(**booking_qs_kwargs))
         )
 
         # waiting list queryset
         waiting_qs = event.booking_set.filter(
-            cancellation_datetime__isnull=True, in_waiting_list=True, primary_booking__isnull=True
+            in_waiting_list=True, primary_booking__isnull=True, **booking_qs_kwargs
         ).order_by('user_last_name', 'user_first_name')
         waiting_qs = waiting_qs.annotate(
             places_count=Value(1)
@@ -2117,7 +2119,7 @@ class EventCheckView(ViewableAgendaMixin, DetailView):
         results = []
         booked_without_status = False
         for booking in booked_filterset.qs:
-            if booking.user_was_present is None:
+            if booking.cancellation_datetime is None and booking.user_was_present is None:
                 booked_without_status = True
             booking.form = BookingAbsenceReasonForm(
                 agenda=self.agenda, initial={'reason': booking.user_absence_reason}
diff --git a/tests/manager/test_event.py b/tests/manager/test_event.py
index 594f35c..91d3ea2 100644
--- a/tests/manager/test_event.py
+++ b/tests/manager/test_event.py
@@ -1268,7 +1268,7 @@ def test_event_check(app, admin_user):
         event=event, user_external_id='user:5', user_first_name='User', user_last_name='05'
     )
     booking6 = Booking.objects.create(
-        event=event, user_external_id='user:6', user_first_name='User', user_last_name='Cancelled'
+        event=event, user_external_id='user:6', user_first_name='User', user_last_name='12 Cancelled'
     )
     booking6.cancel()
     booking7 = Booking.objects.create(
@@ -1279,6 +1279,14 @@ def test_event_check(app, admin_user):
         in_waiting_list=True,
     )
     booking8 = Booking.objects.create(
+        event=event,
+        user_external_id='user:8',
+        user_first_name='User',
+        user_last_name='Waiting and Cancelled',
+        in_waiting_list=True,
+    )
+    booking8.cancel()
+    booking9 = Booking.objects.create(
         event=event,
         user_external_id='user:1',
         user_first_name='User',
@@ -1295,7 +1303,7 @@ def test_event_check(app, admin_user):
     )
     Subscription.objects.create(
         agenda=agenda,
-        user_external_id='user:8',
+        user_external_id='user:9',
         user_first_name='Subscription',
         user_last_name='43',
         date_start=now(),
@@ -1303,7 +1311,7 @@ def test_event_check(app, admin_user):
     )
     Subscription.objects.create(
         agenda=agenda,
-        user_external_id='user:9',
+        user_external_id='user:10',
         user_first_name='Subscription',
         user_last_name='14',
         date_start=now(),
@@ -1364,12 +1372,32 @@ def test_event_check(app, admin_user):
         < resp.text.index('Waiting List (1/5)')
         < resp.text.index('User Waiting')
     )
-    assert 'User Cancelled' not in resp
+    assert 'User 12 Cancelled' not in resp
+    assert 'User Waiting and Cancelled' not in resp
     assert 'Subscription Waiting' not in resp
     assert 'Subscription 42' not in resp
     assert 'Subscription too soon' not in resp
     assert 'Subscription too late' not in resp
 
+    agenda.cancelled_bookings_on_check_page = True
+    agenda.save()
+    resp = app.get('/manage/agendas/%s/events/%s/check' % (agenda.pk, event.pk))
+    assert (
+        resp.text.index('Bookings (6/10)')
+        < resp.text.index('User 01')
+        < resp.text.index('User 05')
+        < resp.text.index('User 12 Cancelled')
+        < resp.text.index('Subscription 14')
+        < resp.text.index('(Not booked)')
+        < resp.text.index('User 17')
+        < resp.text.index('User 35')
+        < resp.text.index('User 42')
+        < resp.text.index('Subscription 43')
+        < resp.text.index('Waiting List (1/5)')
+        < resp.text.index('User Waiting')
+        < resp.text.index('User Waiting and Cancelled')
+    )
+
     agenda.booking_user_block_template = '{{ booking.user_name }} Foo Bar'
     agenda.save()
     resp = app.get('/manage/agendas/%s/events/%s/check' % (agenda.pk, event.pk))
@@ -1404,12 +1432,12 @@ def test_event_check(app, admin_user):
 
     # secondary booking
     app.post(
-        '/manage/agendas/%s/bookings/%s/presence' % (agenda.pk, booking8.pk),
+        '/manage/agendas/%s/bookings/%s/presence' % (agenda.pk, booking9.pk),
         params={'csrfmiddlewaretoken': token},
         status=404,
     )
     app.post(
-        '/manage/agendas/%s/bookings/%s/absence' % (agenda.pk, booking8.pk),
+        '/manage/agendas/%s/bookings/%s/absence' % (agenda.pk, booking9.pk),
         params={'csrfmiddlewaretoken': token},
         status=404,
     )
@@ -1442,7 +1470,6 @@ def test_event_check(app, admin_user):
     resp = app.get('/manage/agendas/%s/events/%s/' % (agenda.pk, event.pk))
     assert '/manage/agendas/%s/events/%s/check' % (agenda.pk, event.pk) not in resp
     app.get('/manage/agendas/%s/events/%s/check' % (agenda.pk, event.pk), status=404)
-    event.cancellation_datetime = None
 
 
 def test_event_checked(app, admin_user):
-- 
2.34.1

