views.py 7.5 KB
Newer Older
Thom Wiggers's avatar
Thom Wiggers committed
1 2 3 4
import csv
from datetime import timedelta

from django.http import HttpResponse
5 6
from django.shortcuts import render, get_object_or_404, redirect
from django.contrib import messages
Thom Wiggers's avatar
Thom Wiggers committed
7
from django.contrib.admin.views.decorators import staff_member_required
8
from django.contrib.auth.decorators import permission_required, login_required
Thom Wiggers's avatar
Thom Wiggers committed
9 10
from django.utils import timezone
from django.utils.text import slugify
11
from django.utils.translation import ugettext_lazy as _
Thom Wiggers's avatar
Thom Wiggers committed
12

13
from .models import Event, Registration
14
from .forms import FieldsForm
Thom Wiggers's avatar
Thom Wiggers committed
15 16 17 18 19 20 21 22 23 24 25 26 27 28 29


@staff_member_required
@permission_required('events.change_event')
def admin_details(request, event_id):
    event = get_object_or_404(Event, pk=event_id)
    n = event.max_participants
    registrations = list(event.registration_set.filter(date_cancelled=None))
    cancellations = event.registration_set.exclude(date_cancelled=None)
    return render(request, 'events/admin/details.html', {
        'event': event,
        'registrations': registrations[:n],
        'waiting': registrations[n:] if n else [],
        'cancellations': cancellations,
    })
Thom Wiggers's avatar
Thom Wiggers committed
30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84


@staff_member_required
@permission_required('events.change_event')
def export(request, event_id):
    event = get_object_or_404(Event, pk=event_id)
    extra_fields = event.registrationinformationfield_set.all()
    registrations = event.registration_set.all()

    header_fields = (
        ['name', 'date', 'email'] + [field.name for field in extra_fields] +
        ['present', 'paid', 'status', 'date_cancelled'])

    rows = []
    capacity = event.max_participants
    for i, registration in enumerate(registrations):
        if registration.member:
            name = registration.member.get_full_name()
        else:
            name = registration.name
        status = 'registered'
        cancelled = None
        if registration.date_cancelled:
            if capacity is not None:
                capacity += 1
            status = 'cancelled'
            cancelled = timezone.localtime(registration.date_cancelled)
        elif capacity and i >= capacity:
            status = 'waiting'
        data = {
            'name': name,
            'date': timezone.localtime(registration.date),
            'paid': registration.paid,
            'present': registration.present,
            'email': (registration.member.user.email
                      if registration.member
                      else ''),
            'status': status,
            'date_cancelled': cancelled,
        }
        data.update({field['field'].name: field['value'] for field in
                     registration.registration_information()})
        rows.append(data)

    response = HttpResponse(content_type='text/csv')
    writer = csv.DictWriter(response, header_fields)
    writer.writeheader()

    def order(item):
        if item['status'] == 'cancelled':
            return item['date'] + timedelta(days=10000)
        elif item['status'] == 'registered':
            return item['date'] - timedelta(days=10000)
        else:
            return item['date']
85

Thom Wiggers's avatar
Thom Wiggers committed
86 87 88 89 90 91
    for row in sorted(rows, key=order):
        writer.writerow(row)

    response['Content-Disposition'] = (
        'attachment; filename="{}.csv"'.format(slugify(event.title)))
    return response
Luuk Scholten's avatar
Luuk Scholten committed
92 93 94 95 96 97 98 99 100 101 102


def index(request):
    upcoming_activity = Event.objects.filter(
        published=True,
        end__gte=timezone.now()
    ).order_by('end').first()

    return render(request, 'events/index.html', {
        'upcoming_activity': upcoming_activity
    })
103 104 105 106 107 108 109


def event(request, event_id):
    event = get_object_or_404(
        Event.objects.filter(published=True),
        pk=event_id
    )
110 111
    registrations = event.registration_set.filter(
        date_cancelled=None)[:event.max_participants]
112 113 114 115 116 117 118 119

    context = {
        'event': event,
        'registrations': registrations,
        'user': request.user,
    }

    if event.max_participants:
120
        perc = 100.0 * len(registrations) / event.max_participants
121 122 123 124 125 126 127 128
        context['registration_percentage'] = perc

    try:
        registration = Registration.objects.get(
            event=event,
            member=request.user.member
        )
        context['registration'] = registration
129
    except Registration.DoesNotExist:
130 131 132
        pass

    return render(request, 'events/event.html', context)
133 134 135 136 137 138 139 140 141


@login_required
def registration(request, event_id, action=None):
    event = get_object_or_404(
        Event.objects.filter(published=True),
        pk=event_id
    )

142 143
    if (event.status != Event.REGISTRATION_NOT_NEEDED and
            request.user.member.current_membership is not None):
144
        try:
145
            obj = Registration.objects.get(
146 147 148 149
                event=event,
                member=request.user.member
            )
        except Registration.DoesNotExist:
150
            obj = None
151 152 153 154

        success_message = None
        error_message = None
        show_fields = False
155 156 157 158
        if action == 'register' and (
            event.status == Event.REGISTRATION_OPEN or
            event.status == Event.REGISTRATION_OPEN_NO_CANCEL
        ):
159 160 161
            if event.has_fields():
                show_fields = True

162 163 164 165 166 167 168 169 170 171 172
            if obj is None:
                obj = Registration()
                obj.event = event
                obj.member = request.user.member
            elif obj.date_cancelled is not None:
                if obj.is_late_cancellation():
                    error_message = _("You cannot re-register anymore since "
                                      "you've cancelled after the deadline.")
                else:
                    obj.date = timezone.now()
                    obj.date_cancelled = None
173 174 175 176
            else:
                error_message = _("You were already registered.")

            if error_message is None:
177
                success_message = _("Registration successful.")
178 179
        elif (action == 'update'
              and event.has_fields()
180 181 182
              and obj is not None
              and (event.status == Event.REGISTRATION_OPEN or
                   event.status == Event.REGISTRATION_OPEN_NO_CANCEL)):
183
            show_fields = True
184 185
            success_message = _("Registration successfully updated.")
        elif action == 'cancel':
186 187 188 189 190 191 192
            if (obj is not None and
                    obj.date_cancelled is None):
                # Note that this doesn't remove the values for the
                # information fields that the user entered upon registering.
                # But this is regarded as a feature, not a bug. Especially
                # since the values will still appear in the backend.
                obj.date_cancelled = timezone.now()
193
                success_message = _("Registration successfully cancelled.")
194 195 196 197
            else:
                error_message = _("You were not registered for this event.")

        if show_fields:
198 199 200
            if request.POST:
                form = FieldsForm(request.POST, registration=obj)
                if form.is_valid():
201
                    obj.save()
202 203 204 205 206 207 208 209 210 211 212 213 214 215
                    form_field_values = form.field_values()
                    for field in form_field_values:
                        field['field'].set_value_for(obj,
                                                     field['value'])
            else:
                form = FieldsForm(registration=obj)
                context = {'event': event, 'form': form, 'action': action}
                return render(request, 'events/event_fields.html', context)

        if success_message is not None:
            messages.success(request, success_message)
        elif error_message is not None:
            messages.error(request, error_message)
        obj.save()
216 217

    return redirect(event)