Skip to content

Commit 41a5f96

Browse files
authored
Add "My Orders" view in eventyay-common (#637)
1 parent f7fae85 commit 41a5f96

File tree

6 files changed

+174
-1
lines changed

6 files changed

+174
-1
lines changed
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
from django import forms
2+
3+
from pretix.base.models import Event
4+
5+
6+
class UserOrderFilterForm(forms.Form):
7+
event = forms.ModelChoiceField(
8+
queryset=None,
9+
required=False,
10+
label="Event",
11+
widget=forms.Select(attrs={'class': 'form-control'}),
12+
empty_label="Select an Event"
13+
)
14+
15+
def __init__(self, *args, **kwargs):
16+
user = kwargs.pop('user', None) # Get the user from the kwargs
17+
super().__init__(*args, **kwargs)
18+
19+
if user:
20+
# Query distinct events based on the user's orders
21+
events = Event.objects.filter(orders__email__iexact=user.email).distinct()
22+
self.fields['event'].queryset = events

src/pretix/eventyay_common/navigation.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,12 @@ def get_global_navigation(request: HttpRequest) -> List[Dict[str, Any]]:
1515
if not url:
1616
return []
1717
nav = [
18+
{
19+
"label": _("My Orders"),
20+
"url": reverse("eventyay_common:orders"),
21+
"active": "events" in url.url_name,
22+
"icon": "shopping-cart",
23+
},
1824
{
1925
"label": _("My Events"),
2026
"url": reverse("eventyay_common:events"),
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
{% load i18n %}
2+
{% load bootstrap3 %}
3+
{% if order.status == "n" %}
4+
{% if order.require_approval %}
5+
<span class="label label-warning {{ class }}">
6+
<span class="fa fa-question-circle"></span>
7+
{% trans "Approval pending" %}
8+
</span>
9+
{% else %}
10+
<span data-toggle="tooltip" title="{{ order.expires|date:"SHORT_DATETIME_FORMAT" }}"
11+
class="label label-warning {{ class }}">
12+
<span class="fa fa-money"></span>
13+
{% trans "Pending" %}
14+
</span>
15+
{% endif %}
16+
{% elif order.status == "p" %}
17+
{% if order.count_positions == 0 %}
18+
<span class="label label-info {{ class }}">
19+
<span class="fa fa-times"></span>
20+
{% trans "Canceled (paid fee)" %}
21+
</span>
22+
{% else %}
23+
<span class="label label-success {{ class }}">
24+
<span class="fa fa-check"></span>
25+
{% trans "Paid" %}
26+
</span>
27+
{% endif %}
28+
{% elif order.status == "e" %} {# expired #}
29+
<span class="label label-danger {{ class }}">
30+
<span class="fa fa-clock-o"></span>
31+
{% trans "Expired" %}</span>
32+
{% elif order.status == "c" %}
33+
<span class="label label-danger {{ class }}">
34+
<span class="fa fa-times"></span>
35+
{% trans "Canceled" %}
36+
</span>
37+
{% endif %}
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
{% extends "eventyay_common/base.html" %}
2+
{% load i18n %}
3+
{% load bootstrap3 %}
4+
{% load eventurl %}
5+
{% load money %}
6+
{% block title %}{% trans "My Orders" %}{% endblock %}
7+
8+
{% block content %}
9+
<h1>{% trans "My Orders" %}</h1>
10+
<div class="row filter-form">
11+
<form action="" method="get">
12+
<div class="col-md-3 col-xs-6">
13+
<!-- Add the event filter here -->
14+
{% bootstrap_field filter_form.event layout='inline' %}
15+
</div>
16+
<div class="col-md-2 col-xs-6">
17+
<button type="submit" class="btn btn-primary">
18+
<span class="fa fa-filter"></span>
19+
</button>
20+
</div>
21+
</form>
22+
</div>
23+
<div class="table-responsive">
24+
<table class="table table-condensed table-hover table-quotas">
25+
<thead>
26+
<tr>
27+
<th>{{ _('Order Code') }}</th>
28+
<th>{{ _('Event') }}</th>
29+
<th>{{ _('Date') }}</th>
30+
<th>{{ _('Order total') }}</th>
31+
<th>{{ _('Status') }}</th>
32+
</tr>
33+
</thead>
34+
<tbody>
35+
{% for order in order_list %}
36+
<tr>
37+
<td>
38+
<a href="{% abseventurl order.event 'presale:event.order' order=order.code secret=order.secret %}">
39+
{{ order.code }}
40+
</a>
41+
</td>
42+
<td>{{ order.event.name }}</td>
43+
<td>{{ order.datetime|date:"SHORT_DATETIME_FORMAT" }}</td>
44+
<td>
45+
{{ order.total|money:order.event.currency }}
46+
</td>
47+
<td>
48+
{% include "eventyay_common/orders/fragment_order_status.html" with order=order event=order.event %}
49+
</td>
50+
</tr>
51+
{% empty %}
52+
<tr>
53+
<td colspan="5" class="text-center">{{ _('You have no orders.') }}</td>
54+
</tr>
55+
{% endfor %}
56+
</tbody>
57+
</table>
58+
</div>
59+
{% endblock %}

src/pretix/eventyay_common/urls.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
1-
from django.urls import include, re_path as url
1+
from django.urls import include, path, re_path as url
22

33
from pretix.eventyay_common.views import (
44
account, dashboards, event, organizer, team,
55
)
6+
from pretix.eventyay_common.views.orders import MyOrdersView
67

78
app_name = 'eventyay_common'
89

@@ -26,5 +27,6 @@
2627
url(r'^settings/$', event.EventUpdate.as_view(), name='event.update'),
2728
url(r'^video-access/$', event.VideoAccessAuthenticator.as_view(), name='event.create_access_to_video'),
2829
])),
30+
path('orders/', MyOrdersView.as_view(), name='orders'),
2931
url(r'^account/$', account.AccountSettings.as_view(), name='account'),
3032
]
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
from logging import getLogger
2+
3+
from django.views.generic.list import ListView
4+
from django.db.models import Q
5+
from django.shortcuts import redirect
6+
7+
from pretix.base.models import Order
8+
from ..forms.filters import UserOrderFilterForm
9+
10+
11+
logger = getLogger(__name__)
12+
13+
14+
class MyOrdersView(ListView):
15+
template_name = 'eventyay_common/orders/orders.html'
16+
paginate_by = 20
17+
18+
def get_queryset(self):
19+
user = self.request.user
20+
qs = Order.objects.filter(
21+
Q(email__iexact=user.email)
22+
).select_related('event').order_by('-datetime')
23+
24+
# Filter by event if provided
25+
filter_form = UserOrderFilterForm(self.request.GET, user=user)
26+
if filter_form.is_valid():
27+
event = filter_form.cleaned_data['event']
28+
if event:
29+
qs = qs.filter(event=event)
30+
31+
return qs
32+
33+
def get_context_data(self, **kwargs):
34+
ctx = super().get_context_data(**kwargs)
35+
ctx['filter_form'] = UserOrderFilterForm(self.request.GET, user=self.request.user)
36+
return ctx
37+
38+
def get(self, request, *args, **kwargs):
39+
filter_form = UserOrderFilterForm(self.request.GET, user=self.request.user)
40+
# If filter form is invalid, strip the 'event' from URL and redirect to this new URL.
41+
if not filter_form.is_valid():
42+
new_url_query = request.GET.copy()
43+
new_url_query.pop('event', None)
44+
new_url = request.path + '?' + new_url_query.urlencode()
45+
logger.info('To redirect to "%s" because the filter values are invalid.', new_url)
46+
return redirect(new_url)
47+
return super().get(request, *args, **kwargs)

0 commit comments

Comments
 (0)