mirror of
https://github.com/pretix/pretix.git
synced 2026-05-03 14:54:04 +00:00
Provide support for manipulting order status
This commit is contained in:
24
src/pretix/base/migrations/0022_auto_20150320_2239.py
Normal file
24
src/pretix/base/migrations/0022_auto_20150320_2239.py
Normal file
@@ -0,0 +1,24 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from django.db import models, migrations
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('pretixbase', '0021_auto_20150320_1622'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='order',
|
||||
name='payment_manual',
|
||||
field=models.BooleanField(verbose_name='Payment state was manually modified', default=False),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='order',
|
||||
name='status',
|
||||
field=models.CharField(verbose_name='Status', max_length=3, choices=[('n', 'pending'), ('p', 'paid'), ('e', 'expired'), ('c', 'cancelled'), ('r', 'refunded')]),
|
||||
),
|
||||
]
|
||||
@@ -1537,6 +1537,10 @@ class Order(Versionable):
|
||||
verbose_name=_("Payment information"),
|
||||
null=True, blank=True
|
||||
)
|
||||
payment_manual = models.BooleanField(
|
||||
verbose_name=_("Payment state was manually modified"),
|
||||
default=False
|
||||
)
|
||||
total = models.DecimalField(
|
||||
decimal_places=2, max_digits=10,
|
||||
verbose_name=_("Total amount")
|
||||
@@ -1590,7 +1594,7 @@ class Order(Versionable):
|
||||
return True
|
||||
return False # nothing there to modify
|
||||
|
||||
def mark_paid(self, provider, info, date=None):
|
||||
def mark_paid(self, provider=None, info=None, date=None, manual=None):
|
||||
"""
|
||||
Mark this order as paid. This clones the order object, sets the payment provider,
|
||||
info and date and returns the cloned order object.
|
||||
@@ -1604,9 +1608,11 @@ class Order(Versionable):
|
||||
:type date: datetime
|
||||
"""
|
||||
order = self.clone()
|
||||
order.payment_provider = provider
|
||||
order.payment_info = info
|
||||
order.payment_provider = provider or order.payment_provider
|
||||
order.payment_info = info or order.payment_info
|
||||
order.payment_date = date or now()
|
||||
if manual is not None:
|
||||
order.payment_manual = manual
|
||||
order.status = Order.STATUS_PAID
|
||||
order.save()
|
||||
return order
|
||||
|
||||
@@ -47,3 +47,10 @@ nav.navbar {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.btn-toolbar {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
.container-fluid > .alert:first-child {
|
||||
margin-top: 20px;
|
||||
}
|
||||
@@ -74,6 +74,13 @@
|
||||
</nav>
|
||||
<div id="page-wrapper">
|
||||
<div class="container-fluid">
|
||||
{% if messages %}
|
||||
{% for message in messages %}
|
||||
<div class="alert {{ message.tags }}">
|
||||
{{ message }}
|
||||
</div>
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
|
||||
{% block content %}
|
||||
{% endblock %}
|
||||
|
||||
32
src/pretix/control/templates/pretixcontrol/order/cancel.html
Normal file
32
src/pretix/control/templates/pretixcontrol/order/cancel.html
Normal file
@@ -0,0 +1,32 @@
|
||||
{% extends "pretixcontrol/event/base.html" %}
|
||||
{% load i18n %}
|
||||
{% block title %}
|
||||
{% trans "Cancel order" %}
|
||||
{% endblock %}
|
||||
{% block content %}
|
||||
<h1>
|
||||
{% trans "Cancel order" %}
|
||||
</h1>
|
||||
<p>{% blocktrans trimmed %}
|
||||
Do you really want to cancel this order? You cannot revert this action.
|
||||
{% endblocktrans %}</p>
|
||||
|
||||
<form method="post" href="">
|
||||
{% csrf_token %}
|
||||
<input type="hidden" name="status" value="c" />
|
||||
<div class="row checkout-button-row">
|
||||
<div class="col-md-4">
|
||||
<a class="btn btn-block btn-default btn-lg"
|
||||
href="{% url "control:event.order" event=request.event.slug organizer=request.event.organizer.slug code=order.code %}">
|
||||
{% trans "No, take me back" %}
|
||||
</a>
|
||||
</div>
|
||||
<div class="col-md-4 col-md-offset-4">
|
||||
<button class="btn btn-block btn-danger btn-lg" type="submit">
|
||||
{% trans "Yes, cancel order" %}
|
||||
</button>
|
||||
</div>
|
||||
<div class="clearfix"></div>
|
||||
</div>
|
||||
</form>
|
||||
{% endblock %}
|
||||
@@ -12,6 +12,27 @@
|
||||
{% endblocktrans %}
|
||||
{% include "pretixcontrol/orders/fragment_order_status.html" with order=order class="pull-right" %}
|
||||
</h1>
|
||||
{% if order.status == 'n' or order.status == 'p' %}
|
||||
<form action="{% url "control:event.order.transition" event=request.event.slug organizer=request.event.organizer.slug code=order.code %}"
|
||||
method="post">
|
||||
{% csrf_token %}
|
||||
<div class="btn-toolbar" role="toolbar">
|
||||
<div class="btn-group" role="group">
|
||||
{% if order.status == 'n' %}
|
||||
<button name="status" value="p" class="btn btn-default">{% trans "Mark as paid" %}</button>
|
||||
<a href="{% url "control:event.order.transition" event=request.event.slug organizer=request.event.organizer.slug code=order.code %}?status=c" class="btn btn-default">
|
||||
{% trans "Cancel order" %}
|
||||
</a>
|
||||
{% elif order.status == 'p' %}
|
||||
<button name="status" value="n" class="btn btn-default">{% trans "Mark as not paid" %}</button>
|
||||
<a href="{% url "control:event.order.transition" event=request.event.slug organizer=request.event.organizer.slug code=order.code %}?status=r" class="btn btn-default">
|
||||
{% trans "Refund order" %}
|
||||
</a>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
{% endif %}
|
||||
<div class="panel panel-primary items">
|
||||
<div class="panel-heading">
|
||||
<h3 class="panel-title">
|
||||
@@ -86,6 +107,11 @@
|
||||
</h3>
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
{% if order.payment_manual %}
|
||||
<div class="alert alert-info">
|
||||
{% trans "The payment state of this order was manually modified." %}
|
||||
</div>
|
||||
{% endif %}
|
||||
{{ payment }}
|
||||
{% if order.status == 'n' %}
|
||||
<p>{% blocktrans trimmed with date=order.expires %}
|
||||
|
||||
@@ -46,6 +46,8 @@ urlpatterns = [
|
||||
url(r'^quotas/(?P<quota>[0-9a-f-]+)/delete$', item.QuotaDelete.as_view(),
|
||||
name='event.items.quotas.delete'),
|
||||
url(r'^quotas/add$', item.QuotaCreate.as_view(), name='event.items.quotas.add'),
|
||||
url(r'^orders/(?P<code>[0-9A-Z]+)/transition$', orders.OrderTransition.as_view(),
|
||||
name='event.order.transition'),
|
||||
url(r'^orders/(?P<code>[0-9A-Z]+)/$', orders.OrderDetail.as_view(), name='event.order'),
|
||||
url(r'^orders/$', orders.OrderList.as_view(), name='event.orders'),
|
||||
])),
|
||||
|
||||
@@ -1,5 +1,10 @@
|
||||
from itertools import groupby
|
||||
from django.contrib import messages
|
||||
from django.core.urlresolvers import reverse
|
||||
from django.db.models import Q
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
from django.http import HttpResponse
|
||||
from django.shortcuts import redirect, render
|
||||
from django.utils.functional import cached_property
|
||||
from django.views.generic import ListView, DetailView
|
||||
|
||||
@@ -21,11 +26,9 @@ class OrderList(EventPermissionRequiredMixin, ListView):
|
||||
).select_related("user")
|
||||
|
||||
|
||||
class OrderDetail(EventPermissionRequiredMixin, DetailView):
|
||||
model = Order
|
||||
class OrderView(DetailView):
|
||||
context_object_name = 'order'
|
||||
template_name = 'pretixcontrol/order/index.html'
|
||||
permission = 'can_view_orders'
|
||||
model = Order
|
||||
|
||||
def get_object(self, queryset=None):
|
||||
return Order.objects.current.get(
|
||||
@@ -33,6 +36,15 @@ class OrderDetail(EventPermissionRequiredMixin, DetailView):
|
||||
code=self.kwargs['code'].upper()
|
||||
)
|
||||
|
||||
@cached_property
|
||||
def order(self):
|
||||
return self.get_object()
|
||||
|
||||
|
||||
class OrderDetail(EventPermissionRequiredMixin, OrderView):
|
||||
template_name = 'pretixcontrol/order/index.html'
|
||||
permission = 'can_view_orders'
|
||||
|
||||
@cached_property
|
||||
def payment_provider(self):
|
||||
responses = register_payment_providers.send(self.request.event)
|
||||
@@ -85,3 +97,51 @@ class OrderDetail(EventPermissionRequiredMixin, DetailView):
|
||||
'total': self.object.total,
|
||||
'payment_fee': self.object.payment_fee,
|
||||
}
|
||||
|
||||
|
||||
class OrderTransition(EventPermissionRequiredMixin, OrderView):
|
||||
permission = 'can_view_orders'
|
||||
|
||||
def post(self, *args, **kwargs):
|
||||
to = self.request.POST.get('status', '')
|
||||
if self.order.status == 'n' and to == 'p':
|
||||
self.order.mark_paid(manual=True)
|
||||
messages.success(self.request, _('The order has been marked as paid.'))
|
||||
elif self.order.status == 'n' and to == 'c':
|
||||
order = self.order.clone()
|
||||
order.status = Order.STATUS_CANCELLED
|
||||
order.save()
|
||||
messages.success(self.request, _('The order has been cancelled.'))
|
||||
elif self.order.status == 'p' and to == 'n':
|
||||
order = self.order.clone()
|
||||
order.status = Order.STATUS_PENDING
|
||||
order.payment_manual = True
|
||||
order.save()
|
||||
messages.success(self.request, _('The order has been marked as not paid.'))
|
||||
return redirect(reverse(
|
||||
'control:event.order',
|
||||
kwargs={
|
||||
'event': self.request.event.slug,
|
||||
'organizer': self.request.event.organizer.slug,
|
||||
'code': self.order.code,
|
||||
}
|
||||
))
|
||||
|
||||
def get(self, *args, **kwargs):
|
||||
to = self.request.GET.get('status', '')
|
||||
if self.order.status == 'n' and to == 'c':
|
||||
return render(self.request, 'pretixcontrol/order/cancel.html', {
|
||||
'order': self.order,
|
||||
})
|
||||
elif self.order.status == 'p' and to == 'r':
|
||||
messages.error(self.request, _('Refunding orders is not yet implemented.'))
|
||||
return redirect(reverse(
|
||||
'control:event.order',
|
||||
kwargs={
|
||||
'event': self.request.event.slug,
|
||||
'organizer': self.request.event.organizer.slug,
|
||||
'code': self.order.code,
|
||||
}
|
||||
))
|
||||
else:
|
||||
return HttpResponse(status=405)
|
||||
|
||||
Reference in New Issue
Block a user