admin_views.py 6.75 KB
Newer Older
1
2
3
import csv

from django.contrib.admin.views.decorators import staff_member_required
4
5
6
from django.http import HttpResponse, HttpResponseRedirect
from django.shortcuts import get_object_or_404
from django.urls import reverse
7
from django.utils import timezone
8
from django.utils.decorators import method_decorator
9
10
11
from django.utils.text import slugify
from django.utils.translation import pgettext_lazy
from django.utils.translation import ugettext_lazy as _
12
13
from django.views import View
from django.views.generic import DetailView, TemplateView
14
15
16
17
18

from events.decorators import organiser_only
from .models import Event, Registration


19
20
21
@method_decorator([staff_member_required, ], name='dispatch')
@method_decorator(organiser_only, name='dispatch')
class EventAdminDetails(DetailView):
22
    """
23
    Renders an overview of registrations for the specified event
24
    """
25
26
27
    template_name = 'events/admin/details.html'
    model = Event
    context_object_name = 'event'
28

29

30
31
32
@method_decorator([staff_member_required, ], name='dispatch')
@method_decorator(organiser_only, name='dispatch')
class EventRegistrationsExport(View):
33
    """
34
    View to export registrations
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
    template_name = 'events/admin/details.html'

    def get(self, request, pk):
        """
        Export the registration of a specified event

        :param request: the request object
        :param pk: the primary key of the event
        :return: A CSV containing all registrations for the event
        """
        event = get_object_or_404(Event, pk=pk)
        extra_fields = event.registrationinformationfield_set.all()
        registrations = event.registration_set.all()

        header_fields = (
            [_('Name'), _('Email'), _('Paid'), _('Present'),
             _('Status'), _('Phone number')] +
            [field.name for field in extra_fields] +
            [_('Date'), _('Date cancelled')])

        rows = []
        if event.price == 0:
            header_fields.remove(_('Paid'))
        for i, registration in enumerate(registrations):
            if registration.member:
                name = registration.member.get_full_name()
62
            else:
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
                name = registration.name
            status = pgettext_lazy('registration status',
                                   'registered').capitalize()
            cancelled = None
            if registration.date_cancelled:

                if registration.is_late_cancellation():
                    status = pgettext_lazy('registration status',
                                           'late cancellation').capitalize()
                else:
                    status = pgettext_lazy('registration status',
                                           'cancelled').capitalize()
                cancelled = timezone.localtime(registration.date_cancelled)

            elif registration.queue_position:
                status = pgettext_lazy('registration status', 'waiting')
            data = {
                _('Name'): name,
                _('Date'): timezone.localtime(registration.date),
                _('Present'): _('Yes') if registration.present else '',
                _('Phone number'): (registration.member.profile.phone_number
                                    if registration.member
                                    else ''),
                _('Email'): (registration.member.email
                             if registration.member
                             else ''),
                _('Status'): status,
                _('Date cancelled'): cancelled,
            }
            if event.price > 0:
                if registration.payment == registration.PAYMENT_CASH:
                    data[_('Paid')] = _('Cash')
                elif registration.payment == registration.PAYMENT_CARD:
                    data[_('Paid')] = _('Pin')
                else:
                    data[_('Paid')] = _('No')

            data.update({field['field'].name: field['value'] for field in
                         registration.information_fields})
            rows.append(data)

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

        rows = sorted(rows,
                      key=lambda row:
                      (row[_('Status')] == pgettext_lazy(
                          'registration status',
                          'late cancellation').capitalize(),
                       row[_('Date')]),
                      reverse=True,
                      )

        for row in rows:
            writer.writerow(row)

        response['Content-Disposition'] = (
            'attachment; filename="{}.csv"'.format(slugify(event.title)))
        return response


@method_decorator([staff_member_required, ], name='dispatch')
@method_decorator(organiser_only, name='dispatch')
class EventRegistrationEmailsExport(TemplateView):
128
129
130
    """
    Renders a page that outputs all email addresses of registered members
    for an event
131
132
    """
    template_name = 'events/admin/email_export.html'
133

134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        event = get_object_or_404(Event, pk=kwargs['pk'])
        registrations = event.registration_set.filter(
            date_cancelled=None)
        registrations = registrations[:event.max_participants]
        addresses = [r.member.email for r in registrations if r.member]
        no_addresses = [r.name for r in registrations if not r.member]
        context['event'] = event
        context['addresses'] = addresses
        context['no_addresses'] = no_addresses
        return context


@method_decorator([staff_member_required, ], name='dispatch')
@method_decorator(organiser_only, name='dispatch')
class EventRegistrationsMarkPresent(View):
151
    """
152
153
    Renders a page that outputs all email addresses of registered members
    for an event
154
    """
155
    template_name = 'events/admin/email_export.html'
156

157
158
159
    def get(self, request, pk):
        """
        Mark all registrations of an event as present
160

161
162
163
164
165
166
167
168
169
170
171
172
173
        :param request: the request object
        :param pk: the primary key of the event
        :return: HttpResponse 302 to the event admin page
        """
        event = get_object_or_404(Event, pk=pk)

        if event.max_participants is None:
            registrations_query = event.registration_set.filter(
                date_cancelled=None)
        else:
            registrations_query = (event.registration_set
                                   .filter(date_cancelled=None)
                                   .order_by('date')[:event.max_participants])
174

175
176
        event.registration_set.filter(pk__in=registrations_query).update(
            present=True, payment=Registration.PAYMENT_CASH)
177

178
179
        return HttpResponseRedirect(reverse('admin:events_event_details',
                                            args=[str(event.pk)]))