Allow to modify answers for pending orders

This commit is contained in:
Raphael Michel
2015-03-14 13:32:56 +01:00
parent a0b9e9a5f9
commit 197fbbd180
13 changed files with 252 additions and 101 deletions

View File

@@ -1,6 +1,9 @@
from datetime import datetime
from itertools import groupby
from django.contrib import messages
from django.core.urlresolvers import reverse
from django.shortcuts import redirect
from django.utils.timezone import now
from django.utils.translation import ugettext_lazy as _
from django.utils.functional import cached_property
from django.views.generic import TemplateView
@@ -8,6 +11,7 @@ from django.http import HttpResponseNotFound, HttpResponseForbidden
from pretix.base.models import Order, OrderPosition
from pretix.base.signals import register_payment_providers
from pretix.presale.views import EventViewMixin, EventLoginRequiredMixin, CartDisplayMixin
from pretix.presale.views.checkout import QuestionsViewMixin
class OrderDetailMixin:
@@ -34,46 +38,6 @@ class OrderDetails(EventViewMixin, EventLoginRequiredMixin, OrderDetailMixin,
return HttpResponseNotFound(_('Unknown order code or order does belong to another user.'))
return super().get(request, *args, **kwargs)
def itemlist_cartlike(self):
"""
Returns the list of ordered items a format compatible to the
CardDisplayMixin, so we can reuse template code
"""
cartpos = OrderPosition.objects.current.filter(
order=self.order,
).order_by(
'item', 'variation'
).select_related(
'item', 'variation'
).prefetch_related(
'variation__values', 'variation__values__prop',
'item__questions'
)
# Group items of the same variation
# We do this by list manipulations instead of a GROUP BY query, as
# Django is unable to join related models in a .values() query
def keyfunc(pos):
if (pos.item.admission and self.request.event.settings.attendee_names_asked == 'True') \
or pos.item.questions.all():
return pos.id, "", "", ""
return "", pos.item_id, pos.variation_id, pos.price
positions = []
for k, g in groupby(sorted(list(cartpos), key=keyfunc), key=keyfunc):
g = list(g)
group = g[0]
group.count = len(g)
group.total = group.count * group.price
positions.append(group)
return {
'positions': positions,
'raw': cartpos,
'total': self.order.total,
'payment_fee': self.order.payment_fee,
}
@cached_property
def payment_provider(self):
responses = register_payment_providers.send(self.request.event)
@@ -96,6 +60,55 @@ class OrderDetails(EventViewMixin, EventLoginRequiredMixin, OrderDetailMixin,
return ctx
class OrderModify(EventViewMixin, EventLoginRequiredMixin, OrderDetailMixin,
QuestionsViewMixin, TemplateView):
template_name = "pretixpresale/event/order_modify.html"
@cached_property
def positions(self):
return list(self.order.positions.order_by(
'item', 'variation'
).select_related(
'item', 'variation'
).prefetch_related(
'variation__values', 'variation__values__prop',
'item__questions', 'answers'
))
def post(self, request, *args, **kwargs):
self.request = request
self.kwargs = kwargs
if not self.order:
return HttpResponseNotFound(_('Unknown order code or order does belong to another user.'))
if not self.order.can_modify_answers:
return HttpResponseForbidden(_('You cannot modify this order'))
failed = not self.save()
if failed:
messages.error(self.request,
_("We had difficulties processing your input. Please review the errors below."))
return self.get(*args, **kwargs)
return redirect(reverse('presale:event.order', kwargs={
'event': self.request.event.slug,
'organizer': self.request.event.organizer.slug,
'order': self.order.code,
}))
def get(self, request, *args, **kwargs):
self.request = request
self.kwargs = kwargs
if not self.order:
return HttpResponseNotFound(_('Unknown order code or order does belong to another user.'))
if not self.order.can_modify_answers:
return HttpResponseForbidden(_('You cannot modify this order'))
return super().get(request, *args, **kwargs)
def get_context_data(self, **kwargs):
ctx = super().get_context_data(**kwargs)
ctx['order'] = self.order
ctx['forms'] = self.forms
return ctx
class OrderCancel(EventViewMixin, EventLoginRequiredMixin, OrderDetailMixin,
TemplateView):
template_name = "pretixpresale/event/order_cancel.html"
@@ -104,7 +117,7 @@ class OrderCancel(EventViewMixin, EventLoginRequiredMixin, OrderDetailMixin,
self.kwargs = kwargs
if not self.order:
return HttpResponseNotFound(_('Unknown order code or order does belong to another user.'))
if self.order.status != Order.STATUS_PENDING:
if self.order.status not in (Order.STATUS_PENDING, Order.STATUS_EXPIRED):
return HttpResponseForbidden(_('You cannot cancel this order'))
order = self.order.clone()
order.status = Order.STATUS_CANCELLED
@@ -119,7 +132,7 @@ class OrderCancel(EventViewMixin, EventLoginRequiredMixin, OrderDetailMixin,
self.kwargs = kwargs
if not self.order:
return HttpResponseNotFound(_('Unknown order code or order does belong to another user.'))
if self.order.status != Order.STATUS_PENDING:
if self.order.status not in (Order.STATUS_PENDING, Order.STATUS_EXPIRED):
return HttpResponseForbidden(_('You cannot cancel this order'))
return super().get(request, *args, **kwargs)