Skip to content

Commit

Permalink
Merge pull request #725 from drnlm/feature/more_ticket_info
Browse files Browse the repository at this point in the history
Feature/more ticket info
  • Loading branch information
drnlm authored Oct 7, 2024
2 parents edd70c1 + f507636 commit 1c315d3
Show file tree
Hide file tree
Showing 5 changed files with 188 additions and 4 deletions.
14 changes: 13 additions & 1 deletion wafer/locale/django.pot
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2024-10-05 20:23+0000\n"
"POT-Creation-Date: 2024-10-06 10:25+0000\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <[email protected]>\n"
Expand Down Expand Up @@ -1237,6 +1237,18 @@ msgstr ""
msgid "Sign up / Log In"
msgstr ""

#: wafer/tickets/admin.py:10
msgid "ticket claimed"
msgstr ""

#: wafer/tickets/admin.py:15
msgid "Ticket has been claimed"
msgstr ""

#: wafer/tickets/admin.py:16
msgid "Ticket is unclaimed"
msgstr ""

#: wafer/tickets/forms.py:18
msgid "Claim"
msgstr ""
Expand Down
56 changes: 53 additions & 3 deletions wafer/tickets/admin.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,56 @@
from django.contrib import admin
from django.db import models
from django.utils.translation import gettext_lazy as _
from reversion.admin import VersionAdmin

from wafer.tickets.models import Ticket, TicketType
from wafer.tickets.models import Ticket, TicketType, TicketTypeTag

admin.site.register(Ticket)
admin.site.register(TicketType)

class ClaimedFilter(admin.SimpleListFilter):
title = _('ticket claimed')
parameter_name = 'claimed'

def lookups(self, request, model_admins):
return (
('yes', _('Ticket has been claimed')),
('no', _('Ticket is unclaimed'))
)

def queryset(self, request, queryset):
if self.value() == 'yes':
return queryset.filter(user__isnull=False)
elif self.value() == 'no':
return queryset.filter(user__isnull=True)
return queryset

class TicketTypeTagAdmin(VersionAdmin):
pass


# We don't use the versioned admin here, as these are usually created and
# updated by external triggers and we don't currently version that
class TicketTypeAdmin(admin.ModelAdmin):
list_display = ('name', 'get_tags', 'get_ticket_count')
list_filter = ('tags',)

def get_queryset(self, request):
qs = super().get_queryset(request)
qs = qs.annotate(
ticket_count_annotation=models.Count('ticket', distinct=True),
)
return qs

def get_ticket_count(self, obj):
return obj.ticket_count_annotation

get_ticket_count.short_description = 'total purchased'
get_ticket_count.admin_order_field = 'ticket_count_annotation'


class TicketAdmin(admin.ModelAdmin):
list_filter = (ClaimedFilter, 'type')


admin.site.register(Ticket, TicketAdmin)
admin.site.register(TicketType, TicketTypeAdmin)
admin.site.register(TicketTypeTag, TicketTypeTagAdmin)
32 changes: 32 additions & 0 deletions wafer/tickets/migrations/0004_tickettypetag_tickettype_tags.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
# Generated by Django 5.0.9 on 2024-10-05 15:38

from django.db import migrations, models


class Migration(migrations.Migration):
dependencies = [
("tickets", "0003_longer_email_field"),
]

operations = [
migrations.CreateModel(
name="TicketTypeTag",
fields=[
(
"id",
models.AutoField(
auto_created=True,
primary_key=True,
serialize=False,
verbose_name="ID",
),
),
("name", models.CharField(max_length=75)),
],
),
migrations.AddField(
model_name="tickettype",
name="tags",
field=models.ManyToManyField(to="tickets.tickettypetag"),
),
]
20 changes: 20 additions & 0 deletions wafer/tickets/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,35 @@
from django.conf import settings


class TicketTypeTag(models.Model):
"""Tags that can be added to a TicketType.
For example 'online', 'sponsor'.
"""

MAX_NAME_LENGTH = 75
name = models.CharField(max_length=MAX_NAME_LENGTH)

def __str__(self):
return self.name


class TicketType(models.Model):

MAX_NAME_LENGTH = 255

name = models.CharField(max_length=MAX_NAME_LENGTH)

tags = models.ManyToManyField(TicketTypeTag)

def __str__(self):
return self.name

def get_tags(self):
return ', '.join([x.name for x in self.tags.all().order_by('name')])

get_tags.short_description = 'tags'


class Ticket(models.Model):
barcode = models.IntegerField(primary_key=True)
Expand Down
70 changes: 70 additions & 0 deletions wafer/tickets/tests/test_admin_helpers.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
from django.contrib.admin.sites import AdminSite

from django.test import TestCase, RequestFactory

from wafer.tickets.models import TicketType, TicketTypeTag, Ticket
from wafer.tickets.admin import TicketTypeAdmin

from wafer.tests.utils import create_user

class TicketTypeAdminTests(TestCase):

def setUp(self):
self.user_emails = ["user%[email protected]" % num for num in range(5)]
# create some tags
self.tag_z = TicketTypeTag.objects.create(name='tag z')
self.tag_a = TicketTypeTag.objects.create(name='tag a')
self.tag_d = TicketTypeTag.objects.create(name='tag d')
# Create some type
self.type_sponsor = TicketType.objects.create(name='Sponsor')
self.type_student = TicketType.objects.create(name='Student')
self.admin_model = TicketTypeAdmin(model=TicketType, admin_site=AdminSite())

self.admin_user = create_user('ticket_admin', superuser=True)
self.request_factory = RequestFactory()


def test_tags(self):
"""Test that get_tags works as expected"""
# Add tags
self.type_sponsor.tags.add(self.tag_z)
self.type_sponsor.tags.add(self.tag_a)

self.type_student.tags.add(self.tag_d)
self.type_student.tags.add(self.tag_z)
self.type_student.tags.add(self.tag_a)

self.assertEqual(self.type_sponsor.get_tags(), 'tag a, tag z')
self.assertEqual(self.type_student.get_tags(), 'tag a, tag d, tag z')

def test_ticket_counts(self):
"""Test the get_count query on the admin model"""

# Buy some tickets
Ticket.objects.create(email=self.user_emails[0], type=self.type_sponsor,
barcode='1234')
Ticket.objects.create(email=self.user_emails[1], type=self.type_sponsor,
barcode='2345')
Ticket.objects.create(email=self.user_emails[2], type=self.type_sponsor,
barcode='3456')

request = self.request_factory.get("/")
request.user = self.admin_user
qs = self.admin_model.get_queryset(request)
self.assertEqual(self.admin_model.get_ticket_count(qs[0]), 3)
self.assertEqual(self.admin_model.get_ticket_count(qs[1]), 0)

Ticket.objects.create(email=self.user_emails[3], type=self.type_student,
barcode='4321')
ticket5 = Ticket.objects.create(email=self.user_emails[4], type=self.type_student,
barcode='1111')

qs = self.admin_model.get_queryset(request)
self.assertEqual(self.admin_model.get_ticket_count(qs[0]), 3)
self.assertEqual(self.admin_model.get_ticket_count(qs[1]), 2)

ticket5.delete()

qs = self.admin_model.get_queryset(request)
self.assertEqual(self.admin_model.get_ticket_count(qs[0]), 3)
self.assertEqual(self.admin_model.get_ticket_count(qs[1]), 1)

0 comments on commit 1c315d3

Please sign in to comment.