Skip to content

Commit

Permalink
Merge pull request #666 from CTPUG/feature/add_ticket_types_to_profile
Browse files Browse the repository at this point in the history
Feature/add ticket types to profile
  • Loading branch information
drnlm committed Jun 28, 2023
2 parents 1a55f9b + bd179f7 commit 5517825
Show file tree
Hide file tree
Showing 7 changed files with 119 additions and 51 deletions.
6 changes: 6 additions & 0 deletions docs/settings.rst
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,12 @@ Wafer's settings
It should return a boolean result.
The default function checks for a Quicket ticket.

``WAFER_USER_TICKET_TYPES``
A function which returns a list of ticket types associated with a user.
This is intende to help track remote vs in-person tickets and similar cases.
It should return a list of ticket type descriptions.
The default function returns the types of any Quicket tickets associated with the user.

``WAFER_VIDEO``
A boolean flag.
When ``True``, the default talk submission form will ask for a video
Expand Down
3 changes: 3 additions & 0 deletions wafer/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -291,6 +291,9 @@
WAFER_REGISTRATION_MODE = 'ticket'
# WAFER_USER_IS_REGISTERED should return a boolean, when passed a Django user.
WAFER_USER_IS_REGISTERED = 'wafer.tickets.models.user_is_registered'
# If using 'ticket' registration, WAFER_USER_TICKET_TYPES should return
# the ticket types associated with the user as a list
WAFER_USER_TICKET_TYPES = 'wafer.tickets.models.get_user_ticket_types'

# Allow registered and anonymous users to see registered users
WAFER_PUBLIC_ATTENDEE_LIST = True
Expand Down
7 changes: 7 additions & 0 deletions wafer/tickets/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,4 +25,11 @@ def __str__(self):


def user_is_registered(user):
"""This function assumes that all ticket types are equally valid for
determining the registration status"""
return Ticket.objects.filter(user=user).exists()


def get_user_ticket_types(user):
"""This returns the distinct ticket types associaated with a user"""
return set([x.type for x in Ticket.objects.filter(user=user)])
29 changes: 29 additions & 0 deletions wafer/tickets/tests/test_helpers.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
from django.test import TestCase

from wafer.tests.utils import create_user
from wafer.tickets.views import import_ticket
from wafer.tickets.models import Ticket, TicketType, user_is_registered, get_user_ticket_types


class TicketsHelperFunctionTests(TestCase):
"""Test the helper functions"""

def setUp(self):
self.user_email = "user2@example.com"
self.user = create_user("User Foo 2", email=self.user_email)

def test_user_is_registered(self):
self.assertFalse(user_is_registered(self.user))
import_ticket(77777, "Individual", self.user_email)
# Check the we are now registered
self.assertTrue(user_is_registered(self.user))

def test_get_user_ticket_types(self):
import_ticket(77777, "Individual", self.user_email)
ticket_type = TicketType.objects.get(name="Individual")
self.assertEqual(get_user_ticket_types(self.user), set([ticket_type]))
# Buy a second ticket with a different type
import_ticket(888888, "Corp", self.user_email)
type2 = TicketType.objects.get(name="Corp")
self.assertEqual(get_user_ticket_types(self.user), set([ticket_type, type2]))

8 changes: 8 additions & 0 deletions wafer/tickets/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,15 @@ def import_ticket(ticket_barcode, ticket_type, email):
try:
user = UserModel.objects.get(email=email, ticket=None)
except UserModel.DoesNotExist:
# We didn't get a user without a ticket - maybe an unknown email,
# a duplicate ticket (batch purchase) or a new ticket type the user
# acquired. We only want to associate the ticket in the last case.
user = None
if UserModel.objects.filter(email=email).count() == 1:
# We have a unique user with this email, so check if this is a ticket
# type that isn't associated with the user
if not UserModel.objects.filter(email=email, ticket__type=type_).exists():
user = UserModel.objects.get(email=email)
except UserModel.MultipleObjectsReturned:
# We're can't uniquely identify the user to associate this ticket
# with, so leave it for them to figure out via the 'claim ticket'
Expand Down
4 changes: 4 additions & 0 deletions wafer/users/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,10 @@ def is_registered(self):
is_registered = import_string(settings.WAFER_USER_IS_REGISTERED)
return is_registered(self.user)

def ticket_types(self):
ticket_types = import_string(settings.WAFER_USER_TICKET_TYPES)
return [x.name for x in ticket_types(self.user)]

is_registered.boolean = True


Expand Down
113 changes: 62 additions & 51 deletions wafer/users/templates/wafer.users/profile.html
Original file line number Diff line number Diff line change
Expand Up @@ -26,26 +26,28 @@
{% endif %}
</div>
<div class="col-md-10">
{% if can_edit %}
<ul class="float-end btn-group btn-group-vertical profile-links">
<li><a href="{% url 'wafer_user_edit' object.username %}" class="btn btn-secondary">{% trans 'Edit Account' %}</a></li>
<li><a href="{% url 'wafer_user_edit_profile' object.username %}" class="btn btn-secondary">{% trans 'Edit Profile' %}</a></li>
{% if WAFER_REGISTRATION_OPEN %}
{% if WAFER_REGISTRATION_MODE == 'ticket' and not profile.is_registered %}
{% url 'wafer_ticket_claim' as register_url %}
{% endif %}
{% if WAFER_REGISTRATION_MODE == 'custom' %}
{% url 'register' as register_url %}
{% endif %}
{% if register_url %}
<li><a href="{{ register_url }}" class="btn btn-secondary">{% if profile.is_registered %}{% trans 'Update registration' context "conference" %}{% else %}{% trans 'Register' context "conference" %}{% endif %}</a></li>
{% endif %}
{% endif %}
{% if WAFER_TALKS_OPEN %}
<li><a href="{% url 'wafer_talk_submit' %}" class="btn btn-secondary">{% trans 'Submit Talk Proposal' %}</a></li>
{% endif %}
</ul>
{% endif %}
{% block side_menu %}
{% if can_edit %}
<ul class="float-end btn-group btn-group-vertical profile-links">
<li><a href="{% url 'wafer_user_edit' object.username %}" class="btn btn-secondary">{% trans 'Edit Account' %}</a></li>
<li><a href="{% url 'wafer_user_edit_profile' object.username %}" class="btn btn-secondary">{% trans 'Edit Profile' %}</a></li>
{% if WAFER_REGISTRATION_OPEN %}
{% if WAFER_REGISTRATION_MODE == 'ticket' and not profile.is_registered %}
{% url 'wafer_ticket_claim' as register_url %}
{% endif %}
{% if WAFER_REGISTRATION_MODE == 'custom' %}
{% url 'register' as register_url %}
{% endif %}
{% if register_url %}
<li><a href="{{ register_url }}" class="btn btn-secondary">{% if profile.is_registered %}{% trans 'Update registration' context "conference" %}{% else %}{% trans 'Register' context "conference" %}{% endif %}</a></li>
{% endif %}
{% endif %}
{% if WAFER_TALKS_OPEN %}
<li><a href="{% url 'wafer_talk_submit' %}" class="btn btn-secondary">{% trans 'Submit Talk Proposal' %}</a></li>
{% endif %}
</ul>
{% endif %}
{% endblock side_menu %}
{% spaceless %}
<h1>
{% if profile.homepage %}
Expand All @@ -56,20 +58,22 @@ <h1>
</a>
{% endif %}
</h1>
{% if profile.twitter_handle %}
<p>
<a href="https://twitter.com/{{ profile.twitter_handle }}" class="twitter-follow-button" data-bs-show-count="false">
{% blocktrans with handle=profile.twitter_handle %}Follow @{{ handle }}{% endblocktrans %}
</a>
</p>
{% endif %}
{% if profile.github_username %}
<p>
<a href="https://github.com/{{ profile.github_username }}">
{% blocktrans with username=profile.github_username %}GitHub: {{ username }}{% endblocktrans %}
</a>
</p>
{% endif %}
{% block social %}
{% if profile.twitter_handle %}
<p>
<a href="https://twitter.com/{{ profile.twitter_handle }}" class="twitter-follow-button" data-bs-show-count="false">
{% blocktrans with handle=profile.twitter_handle %}Follow @{{ handle }}{% endblocktrans %}
</a>
</p>
{% endif %}
{% if profile.github_username %}
<p>
<a href="https://github.com/{{ profile.github_username }}">
{% blocktrans with username=profile.github_username %}GitHub: {{ username }}{% endblocktrans %}
</a>
</p>
{% endif %}
{% endblock social %}
{% endspaceless %}
</div>
</div>
Expand All @@ -80,23 +84,30 @@ <h1>
{% endif %}
{% if can_edit %}
{% if profile.pending_talks.exists or profile.accepted_talks.exists or profile.provisional_talks.exists%}
{% if profile.is_registered %}
<div class="alert alert-success">
{% blocktrans trimmed %}
Registered
{% endblocktrans %}
</div>
{% else %}
<div class="alert alert-danger">
{% blocktrans trimmed %}
<strong>WARNING:</strong>
Talk proposal submitted, but speaker hasn't registered to attend.
{% endblocktrans %}
{% if WAFER_REGISTRATION_OPEN %}
{% trans "Register now!" %}
{% endif %}
</div>
{% endif %}
{% block speaker_registered %}
{% if profile.is_registered %}
<div class="alert alert-success">
{% blocktrans trimmed %}
Registered
{% endblocktrans %}
</div>
{% else %}
<div class="alert alert-danger">
{% blocktrans trimmed %}
<strong>WARNING:</strong>
Talk proposal submitted, but speaker hasn't registered to attend.
{% endblocktrans %}
{% if WAFER_REGISTRATION_OPEN %}
{% trans "Register now!" %}
{% endif %}
</div>
{% endif %}
{% if WAFER_REGISTRATION_MODE == 'ticket' and profile.is_registered %}
<p>Tickets:
{{ profile.ticket_types }}
</p>
{% endif %}
{% endblock speaker_registered %}
{% endif %}
{% endif %}
{# Accepted talks are globally visible #}
Expand Down

0 comments on commit 5517825

Please sign in to comment.