Repository: dotkom/onlineweb4

Issue:
Removing users from event gives the wrong name in popup
<!-- If this is a security issue or information leakage (having access to something you (probably) shouldn't), please send an email rather than opening a public issue. -->

## What kind of an issue is this?

- Bug report


## What is the expected behaviour?
The the popup shows the name of the person you are removing, when removing multiple people at once

## What is the current behaviour?
The popup shows the name of the first person you removed in the current session
<!-- if this is a bug report -->


## How do you reproduce this problem? 
Remove a person from an event, then remove another and observe the popup
<!-- if this is a bug report -->
<!-- provide steps to reproduce this problem, preferably in a bullet point list -->


## Other information
I have a screenshot, but it contains sensitive person-info
<!-- include screenshots if appropriate -->
<!-- add labels you see fit. please do not exaggerate. -->



Discussion:
Also as in https://github.com/dotkom/onlineweb4/issues/2121 the page is just horrible to work with, with everything moving around everywhere when resizing, and should be fixed.

Resolving patch:
diff --git a/apps/events/dashboard/utils.py b/apps/events/dashboard/utils.py
--- a/apps/events/dashboard/utils.py
+++ b/apps/events/dashboard/utils.py
@@ -2,7 +2,7 @@
 from django.urls import reverse
 
 from apps.authentication.models import OnlineUser as User
-from apps.events.models import Attendee
+from apps.events.models import Attendee, Event
 
 
 def _get_attendee(attendee_id):
@@ -12,35 +12,33 @@ def _get_attendee(attendee_id):
         return None
 
 
-def event_ajax_handler(event, request):
-    action = request.POST['action']
+def event_ajax_handler(event: Event, request):
+    action = request.POST.get('action')
     administrating_user = request.user
+    attendee_id = request.POST.get('attendee_id')
+    user_id = request.POST.get('user_id')
 
     if action == 'attended':
-        attendee = _get_attendee(request.POST['attendee_id'])
+        attendee = _get_attendee(attendee_id)
         if not attendee:
-            return {'message': 'Fant ingen påmeldte med oppgitt ID (%s).' % request.POST['attendee_id'],
-                    'status': 400}
+            return {'message': f'Fant ingen påmeldte med oppgitt ID ({attendee_id}).', 'status': 400}
         return handle_attended(attendee)
     elif action == 'paid':
-        attendee = _get_attendee(request.POST['attendee_id'])
+        attendee = _get_attendee(attendee_id)
         if not attendee:
-            return {'message': 'Fant ingen påmeldte med oppgitt ID (%s).' % request.POST['attendee_id'],
-                    'status': 400}
+            return {'message': f'Fant ingen påmeldte med oppgitt ID ({attendee_id}).', 'status': 400}
         return handle_paid(attendee)
     elif action == 'add_attendee':
-        return handle_add_attendee(event, request.POST['user_id'])
+        return handle_add_attendee(event, user_id)
     elif action == 'remove_attendee':
-        return handle_remove_attendee(event, request.POST['attendee_id'], administrating_user)
+        return handle_remove_attendee(event, attendee_id, administrating_user)
     else:
         raise NotImplementedError
 
 
-def handle_attended(attendee):
+def handle_attended(attendee: Attendee):
     """
     Toggle attending-status of an attendee between attending and not attending
-    :param attendee_id: ID of attendee wanted to toggle
-    :return:
     """
     attendee.attended = not attendee.attended
     attendee.save()
@@ -48,11 +46,9 @@ def handle_attended(attendee):
     return {'message': 'OK', 'status': 200}
 
 
-def handle_paid(attendee):
+def handle_paid(attendee: Attendee):
     """
     Toggle paid status of an attendee between paid and not paid
-    :param attendee_id: ID of attendee wanted to toggle
-    :return:
     """
     attendee.paid = not attendee.paid
     attendee.save()
@@ -60,81 +56,58 @@ def handle_paid(attendee):
     return {'message': 'OK', 'status': 200}
 
 
-def handle_add_attendee(event, user_id):
-    resp = {}
+def _get_attendee_data(attendee_qs):
+    attendees = []
+
+    for number, a in enumerate(attendee_qs):
+        attendees.append({
+            'number': number + 1,
+            'id': a.id,
+            'first_name': a.user.first_name,
+            'last_name': a.user.last_name,
+            'paid': a.paid,
+            'extras': str(a.extras),
+            'attended': a.attended,
+            'link': reverse('dashboard_attendee_details', kwargs={'attendee_id': a.id})
+        })
+
+    return attendees
+
+
+def _get_event_context(event: Event, response={}):
+    response['attendees'] = _get_attendee_data(event.attendance_event.attending_attendees_qs)
+    response['waitlist'] = _get_attendee_data(event.attendance_event.waitlist_qs)
+
+    return response
+
+
+def handle_add_attendee(event: Event, user_id: int):
+    resp = _get_event_context(event)
     if event.attendance_event.number_of_seats_taken >= event.attendance_event.max_capacity:
         if not event.attendance_event.waitlist:
-            return 'Det er ingen ledige plasser på %s.' % event.title
+            return {'message': f'Det er ingen ledige plasser på {event.title}.', 'status': 400, **resp}
 
     user = User.objects.filter(pk=user_id)
     if user.count() != 1:
-        return 'Fant ingen bruker med oppgitt ID (%s).' % user_id
+        return {'message': f'Fant ingen bruker med oppgitt ID ({user_id}).', 'status': 400, **resp}
     user = user[0]
     if Attendee.objects.filter(user=user, event=event.attendance_event).count() != 0:
-        return '%s er allerede påmeldt %s.' % (user.get_full_name(), event.title)
+        return {'message': f'{user} er allerede påmeldt {event.title}.', 'status': 400, **resp}
 
     attendee = Attendee(user=user, event=event.attendance_event)
     attendee.save()
 
-    resp['message'] = '%s ble meldt på %s' % (user.get_full_name(), event)
-    resp['attendees'] = []
+    resp = _get_event_context(event, resp)
+    return {'message': f'{user} ble meldt på {event}', 'status': 200, **resp}
 
-    for number, a in enumerate(attendee.event.attending_attendees_qs):
-        resp['attendees'].append({
-            'number': number+1,
-            'id': a.id,
-            'first_name': a.user.first_name,
-            'last_name': a.user.last_name,
-            'paid': a.paid,
-            'extras': str(a.extras),
-            'attended': a.attended,
-            'link': reverse('dashboard_attendee_details', kwargs={'attendee_id': a.id})
-        })
-    resp['waitlist'] = []
-    for number, a in enumerate(attendee.event.waitlist_qs):
-        resp['waitlist'].append({
-            'number': number+1,
-            'id': a.id,
-            'first_name': a.user.first_name,
-            'last_name': a.user.last_name,
-            'paid': a.paid,
-            'extras': str(a.extras),
-            'attended': a.attended,
-            'link': reverse('dashboard_attendee_details', kwargs={'attendee_id': a.id})
-        })
-    return resp
 
-
-def handle_remove_attendee(event, attendee_id, admin_user):
-    resp = {}
+def handle_remove_attendee(event: Event, attendee_id: int, admin_user: User):
+    resp = _get_event_context(event)
     attendee = Attendee.objects.filter(pk=attendee_id)
     if attendee.count() != 1:
-        return 'Fant ingen påmeldte med oppgitt ID (%s).' % attendee_id
+        return {'message': f'Fant ingen påmeldte med oppgitt ID ({attendee_id}).', 'status': 400, **resp}
     attendee = attendee[0]
     attendee.unattend(admin_user)
-    resp['message'] = '%s ble fjernet fra %s' % (attendee.user.get_full_name(), attendee.event)
-    resp['attendees'] = []
-    for number, a in enumerate(attendee.event.attending_attendees_qs):
-        resp['attendees'].append({
-            'number': number+1,
-            'id': a.id,
-            'first_name': a.user.first_name,
-            'last_name': a.user.last_name,
-            'paid': a.paid,
-            'extras': str(a.extras),
-            'attended': a.attended,
-            'link': reverse('dashboard_attendee_details', kwargs={'attendee_id': a.id})
-        })
-    resp['waitlist'] = []
-    for number, a in enumerate(attendee.event.waitlist_qs):
-        resp['waitlist'].append({
-            'number': number+1,
-            'id': a.id,
-            'first_name': a.user.first_name,
-            'last_name': a.user.last_name,
-            'paid': a.paid,
-            'extras': str(a.extras),
-            'attended': a.attended,
-            'link': reverse('dashboard_attendee_details', kwargs={'attendee_id': a.id})
-        })
-    return resp
+
+    resp = _get_event_context(event, resp)
+    return {'message': f'{attendee.user} ble fjernet fra {attendee.event}', 'status': 200, **resp}


Test patch: