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

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

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


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

31

32
33
@method_decorator([staff_member_required, ], name='dispatch')
@method_decorator(organiser_only, name='dispatch')
34
class EventRegistrationsExport(View, PermissionRequiredMixin):
35
    """
36
    View to export registrations
37
    """
38
    template_name = 'events/admin/details.html'
39
    permission_required = 'events.change_event'
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

    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()
65
            else:
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
128
129
                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')
130
class EventRegistrationEmailsExport(TemplateView, PermissionRequiredMixin):
131
132
133
    """
    Renders a page that outputs all email addresses of registered members
    for an event
134
135
    """
    template_name = 'events/admin/email_export.html'
136
    permission_required = 'events.view_event'
137

138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
    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')
154
class EventRegistrationsMarkPresent(View, PermissionRequiredMixin):
155
    """
156
157
    Renders a page that outputs all email addresses of registered members
    for an event
158
    """
159
    template_name = 'events/admin/email_export.html'
160
    permission_required = 'events.change_registration'
161

162
163
164
    def get(self, request, pk):
        """
        Mark all registrations of an event as present
165

166
167
168
169
170
171
172
173
174
175
176
177
178
        :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])
179

180
181
        event.registration_set.filter(pk__in=registrations_query).update(
            present=True, payment=Registration.PAYMENT_CASH)
182

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