Skip to content

Commit

Permalink
UI for creating and chacnging vouchers
Browse files Browse the repository at this point in the history
  • Loading branch information
raphaelm committed Feb 9, 2016
1 parent 61d3954 commit 6e22149
Show file tree
Hide file tree
Showing 11 changed files with 323 additions and 13 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.9 on 2016-02-09 09:59
from __future__ import unicode_literals

from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
('pretixbase', '0002_auto_20160209_0940'),
]

operations = [
migrations.AddField(
model_name='eventpermission',
name='can_change_vouchers',
field=models.BooleanField(default=True, verbose_name='Can change vouchers'),
),
]
31 changes: 31 additions & 0 deletions src/pretix/base/migrations/0004_auto_20160209_1023.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.9 on 2016-02-09 10:23
from __future__ import unicode_literals

import django.db.models.deletion
from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
('pretixbase', '0003_eventpermission_can_change_vouchers'),
]

operations = [
migrations.RemoveField(
model_name='voucher',
name='item',
),
migrations.AddField(
model_name='voucher',
name='item',
field=models.ForeignKey(default=None, help_text="This product is added to the user's cart if the voucher is redeemed.", on_delete=django.db.models.deletion.CASCADE, related_name='vouchers', to='pretixbase.Item', verbose_name='Product'),
preserve_default=False,
),
migrations.AlterField(
model_name='voucher',
name='price',
field=models.DecimalField(blank=True, decimal_places=2, help_text='If empty, the product will cost its normal price.', max_digits=10, null=True, verbose_name='Set product price to'),
),
]
4 changes: 4 additions & 0 deletions src/pretix/base/models/event.py
Original file line number Diff line number Diff line change
Expand Up @@ -237,6 +237,10 @@ class EventPermission(models.Model):
default=True,
verbose_name=_("Can change orders")
)
can_change_vouchers = models.BooleanField(
default=True,
verbose_name=_("Can change vouchers")
)

class Meta:
verbose_name = _("Event permission")
Expand Down
31 changes: 23 additions & 8 deletions src/pretix/base/models/vouchers.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,23 @@
import random

from django.db import models
from django.utils.translation import ugettext_lazy as _

from .base import LoggedModel
from .event import Event
from .items import Item
from .orders import CartPosition, OrderPosition


class Voucher(models.Model):
def generate_code():
charset = list('ABCDEFGHKLMNPQRSTUVWXYZ23456789')
while True:
code = "".join([random.choice(charset) for i in range(16)])
if not Voucher.objects.filter(code=code).exists():
return code


class Voucher(LoggedModel):
event = models.ForeignKey(
Event,
on_delete=models.CASCADE,
Expand All @@ -15,7 +26,7 @@ class Voucher(models.Model):
)
code = models.CharField(
verbose_name=_("Voucher code"),
max_length=255
max_length=255, default=generate_code
)
valid_until = models.DateTimeField(
blank=True, null=True,
Expand All @@ -38,9 +49,10 @@ class Voucher(models.Model):
)
price = models.DecimalField(
verbose_name=_("Set product price to"),
decimal_places=2, max_digits=10, null=True, blank=True
decimal_places=2, max_digits=10, null=True, blank=True,
help_text=_('If empty, the product will cost its normal price.')
)
item = models.ManyToManyField(
item = models.ForeignKey(
Item, related_name='vouchers',
verbose_name=_("Product"),
help_text=_(
Expand All @@ -53,16 +65,19 @@ class Meta:
verbose_name_plural = _("Vouchers")
unique_together = (("event", "code"),)

def __str__(self):
return self.code

def save(self, *args, **kwargs):
self.code = self.code.upper()
super().save(*args, **kwargs)

def is_ordered(self) -> int:
return OrderPosition.objects.current.filter(
voucher=self.voucher
return OrderPosition.objects.filter(
voucher=self
).exists()

def is_in_cart(self) -> int:
return CartPosition.objects.current.filter(
voucher=self.voucher
return CartPosition.objects.filter(
voucher=self
).count()
14 changes: 14 additions & 0 deletions src/pretix/control/forms/vouchers.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
from pretix.base.forms import I18nModelForm
from pretix.base.models import Voucher


class VoucherForm(I18nModelForm):
class Meta:
model = Voucher
localized_fields = '__all__'
fields = [
'code', 'valid_until', 'block_quota', 'allow_ignore_quota', 'price', 'item'
]

def _get_validation_exclusions(self):
return []
17 changes: 13 additions & 4 deletions src/pretix/control/templates/pretixcontrol/event/base.html
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
{% block nav %}
<li>
<a href="{% url 'control:event.index' organizer=request.event.organizer.slug event=request.event.slug %}"
{% if url_name == "event.index" %}class="active"{% endif %}>
{% if url_name == "event.index" %}class="active"{% endif %}>
<i class="fa fa-dashboard fa-fw"></i>
{% trans "Dashboard" %}
</a>
Expand Down Expand Up @@ -52,7 +52,7 @@
{% if request.eventperm.can_change_permissions %}
<li>
<a href="{% url 'control:event.settings.permissions' organizer=request.event.organizer.slug event=request.event.slug %}"
{% if "event.settings.permissions" == url_name %}class="active"{% endif %}>
{% if "event.settings.permissions" == url_name %}class="active"{% endif %}>
{% trans "Permissions" %}
</a>
</li>
Expand Down Expand Up @@ -110,19 +110,28 @@
</li>
<li>
<a href="{% url 'control:event.orders.overview' organizer=request.event.organizer.slug event=request.event.slug %}"
{% if url_name == "event.orders.overview" %}class="active"{% endif %}>
{% if url_name == "event.orders.overview" %}class="active"{% endif %}>
{% trans "Overview" %}
</a>
</li>
<li>
<a href="{% url 'control:event.orders.export' organizer=request.event.organizer.slug event=request.event.slug %}"
{% if url_name == "event.orders.export" %}class="active"{% endif %}>
{% if url_name == "event.orders.export" %}class="active"{% endif %}>
{% trans "Export" %}
</a>
</li>
</ul>
</li>
{% endif %}
{% if request.eventperm.can_change_vouchers %}
<li>
<a href="{% url 'control:event.vouchers' organizer=request.event.organizer.slug event=request.event.slug %}"
{% if url_name == "event.vouchers" %}class="active"{% endif %}>
<i class="fa fa-tags fa-fw"></i>
{% trans "Vouchers" %}
</a>
</li>
{% endif %}
{% for nav in nav_event %}
<li>
<a href="{{ nav.url }}" {% if nav.active %}class="active"{% endif %}>
Expand Down
26 changes: 26 additions & 0 deletions src/pretix/control/templates/pretixcontrol/vouchers/delete.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
{% extends "pretixcontrol/items/base.html" %}
{% load i18n %}
{% load bootstrap3 %}
{% block title %}{% trans "Delete voucher" %}{% endblock %}
{% block inside %}
<h1>{% trans "Delete voucher" %}</h1>
<form action="" method="post" class="form-horizontal">
{% csrf_token %}
{% if not allowed %}
<p>{% trans "You can not delete this voucher after it has been redeemed" %}</p>
{% else %}
<p>{% blocktrans %}Are you sure you want to delete the voucher
<strong>{{ voucher }}</strong>?{% endblocktrans %}</p>
{% endif %}
<div class="form-group submit-group">
<a href="{% url "control:event.vouchers" organizer=request.event.organizer.slug event=request.event.slug %}" class="btn btn-default btn-cancel">
{% trans "Cancel" %}
</a>
{% if allowed %}
<button type="submit" class="btn btn-danger btn-save">
{% trans "Delete" %}
</button>
{% endif %}
</div>
</form>
{% endblock %}
25 changes: 25 additions & 0 deletions src/pretix/control/templates/pretixcontrol/vouchers/detail.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
{% extends "pretixcontrol/items/base.html" %}
{% load i18n %}
{% load bootstrap3 %}
{% block title %}{% trans "Voucher" %}{% endblock %}
{% block inside %}
<h1>{% trans "Voucher" %}</h1>
<form action="" method="post" class="form-horizontal">
{% csrf_token %}
{% bootstrap_form_errors form %}
<fieldset>
<legend>{% trans "Voucher details" %}</legend>
{% bootstrap_field form.code layout="horizontal" %}
{% bootstrap_field form.valid_until layout="horizontal" %}
{% bootstrap_field form.block_quota layout="horizontal" %}
{% bootstrap_field form.allow_ignore_quota layout="horizontal" %}
{% bootstrap_field form.price layout="horizontal" %}
{% bootstrap_field form.item layout="horizontal" %}
</fieldset>
<div class="form-group submit-group">
<button type="submit" class="btn btn-primary btn-save">
{% trans "Save" %}
</button>
</div>
</form>
{% endblock %}
40 changes: 40 additions & 0 deletions src/pretix/control/templates/pretixcontrol/vouchers/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
{% extends "pretixcontrol/items/base.html" %}
{% load i18n %}
{% block title %}{% trans "Vouchers" %}{% endblock %}
{% block inside %}
<h1>{% trans "Vouchers" %}</h1>
<p>
<a href="{% url "control:event.vouchers.add" organizer=request.event.organizer.slug event=request.event.slug %}"
class="btn btn-default"><i class="fa fa-plus"></i> {% trans "Create a new voucher" %}</a>
</p>
<div class="table-responsive">
<table class="table table-hover table-quotas">
<thead>
<tr>
<th>{% trans "Voucher code" %}</th>
<th>{% trans "Is redeemed" %}</th>
<th>{% trans "Expiry" %}</th>
<th>{% trans "Product" %}</th>
<th></th>
</tr>
</thead>
<tbody>
{% for v in vouchers %}
<tr>
<td>
<strong><a href="
{% url "control:event.voucher" organizer=request.event.organizer.slug event=request.event.slug voucher=v.id %}">{{ v.code }}</a></strong>
</td>
<td>{% if v.is_ordered %}{% trans "Yes" %}{% else %}{% trans "No" %}{% endif %}</td>
<td>{{ v.valid_until|date }}</td>
<td>{{ v.item }}</td>
<td class="text-right">
<a href="{% url "control:event.voucher.delete" organizer=request.event.organizer.slug event=request.event.slug voucher=v.id %}" class="btn btn-danger btn-sm"><i class="fa fa-trash"></i></a>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
{% include "pretixcontrol/pagination.html" %}
{% endblock %}
7 changes: 6 additions & 1 deletion src/pretix/control/urls.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
from django.conf.urls import include, url

from pretix.control.views import (
auth, event, item, main, orders, organizer, user,
auth, event, item, main, orders, organizer, user, vouchers,
)

urlpatterns = [
Expand Down Expand Up @@ -54,6 +54,11 @@
url(r'^quotas/(?P<quota>\d+)/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'^vouchers/$', vouchers.VoucherList.as_view(), name='event.vouchers'),
url(r'^vouchers/(?P<voucher>\d+)/$', vouchers.VoucherUpdate.as_view(), name='event.voucher'),
url(r'^vouchers/(?P<voucher>\d+)/delete$', vouchers.VoucherDelete.as_view(),
name='event.voucher.delete'),
url(r'^vouchers/add$', vouchers.VoucherCreate.as_view(), name='event.vouchers.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]+)/extend$', orders.OrderExtend.as_view(),
Expand Down

0 comments on commit 6e22149

Please sign in to comment.