diff --git a/src/tixlbase/migrations/0018_auto_20141025_0908.py b/src/tixlbase/migrations/0018_auto_20141025_0908.py
new file mode 100644
index 000000000..822052920
--- /dev/null
+++ b/src/tixlbase/migrations/0018_auto_20141025_0908.py
@@ -0,0 +1,25 @@
+# -*- coding: utf-8 -*-
+from __future__ import unicode_literals
+
+from django.db import models, migrations
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('tixlbase', '0017_auto_20141017_2148'),
+ ]
+
+ operations = [
+ migrations.AddField(
+ model_name='quota',
+ name='event',
+ field=models.ForeignKey(to='tixlbase.Event', default=1, verbose_name='Event', related_name='quotas'),
+ preserve_default=False,
+ ),
+ migrations.AlterField(
+ model_name='cartposition',
+ name='datetime',
+ field=models.DateTimeField(verbose_name='Date'),
+ ),
+ ]
diff --git a/src/tixlbase/models.py b/src/tixlbase/models.py
index bf722867d..111509c1d 100644
--- a/src/tixlbase/models.py
+++ b/src/tixlbase/models.py
@@ -750,6 +750,12 @@ class Quota(models.Model):
implementation specific and are considered private. It is planned that they
are being used as a fallback solution if redis is not available.
"""
+ event = models.ForeignKey(
+ Event,
+ on_delete=models.CASCADE,
+ related_name="quotas",
+ verbose_name=_("Event"),
+ )
name = models.CharField(
max_length=200,
verbose_name=_("Name")
@@ -780,6 +786,9 @@ class Quota(models.Model):
verbose_name = _("Quota")
verbose_name_plural = _("Quotas")
+ def __str__(self):
+ return self.name
+
class Order(models.Model):
"""
diff --git a/src/tixlcontrol/templates/tixlcontrol/items/base.html b/src/tixlcontrol/templates/tixlcontrol/items/base.html
index 499d305f6..c636133df 100644
--- a/src/tixlcontrol/templates/tixlcontrol/items/base.html
+++ b/src/tixlcontrol/templates/tixlcontrol/items/base.html
@@ -7,6 +7,7 @@
{% trans "Categories" %}
{% trans "Properties" %}
{% trans "Questions" %}
+ {% trans "Quotas" %}
{% block inside %}
{% endblock %}
diff --git a/src/tixlcontrol/templates/tixlcontrol/items/question_delete.html b/src/tixlcontrol/templates/tixlcontrol/items/question_delete.html
index 0674c40f2..98763ceac 100644
--- a/src/tixlcontrol/templates/tixlcontrol/items/question_delete.html
+++ b/src/tixlcontrol/templates/tixlcontrol/items/question_delete.html
@@ -18,7 +18,7 @@
-
+
{% trans "Cancel" %}
diff --git a/src/tixlcontrol/templates/tixlcontrol/items/quota.html b/src/tixlcontrol/templates/tixlcontrol/items/quota.html
new file mode 100644
index 000000000..a7d14bd81
--- /dev/null
+++ b/src/tixlcontrol/templates/tixlcontrol/items/quota.html
@@ -0,0 +1,27 @@
+{% extends "tixlcontrol/items/base.html" %}
+{% load i18n %}
+{% load bootstrap3 %}
+{% block title %}{% trans "Quota" %}{% endblock %}
+{% block inside %}
+ {% trans "Quota" %}
+
+{% endblock %}
diff --git a/src/tixlcontrol/templates/tixlcontrol/items/quota_delete.html b/src/tixlcontrol/templates/tixlcontrol/items/quota_delete.html
new file mode 100644
index 000000000..85e997cda
--- /dev/null
+++ b/src/tixlcontrol/templates/tixlcontrol/items/quota_delete.html
@@ -0,0 +1,27 @@
+{% extends "tixlcontrol/items/base.html" %}
+{% load i18n %}
+{% load bootstrap3 %}
+{% block title %}{% trans "Delete quota" %}{% endblock %}
+{% block inside %}
+ {% trans "Delete quota" %}
+
+{% endblock %}
diff --git a/src/tixlcontrol/templates/tixlcontrol/items/quotas.html b/src/tixlcontrol/templates/tixlcontrol/items/quotas.html
new file mode 100644
index 000000000..7d3ec2568
--- /dev/null
+++ b/src/tixlcontrol/templates/tixlcontrol/items/quotas.html
@@ -0,0 +1,44 @@
+{% extends "tixlcontrol/items/base.html" %}
+{% load i18n %}
+{% block title %}{% trans "Quotas" %}{% endblock %}
+{% block inside %}
+ {% trans "Quotas" %}
+ {% if "updated" in request.GET %}
+
+ {% trans "Your changes have been saved." %}
+
+ {% elif "created" in request.GET %}
+
+ {% trans "A new quota has been created." %}
+
+ {% elif "deleted" in request.GET %}
+
+ {% trans "The quota has been deleted." %}
+
+ {% endif %}
+
+ {% trans "Create a new quota" %}
+
+
+
+
+ | {% trans "Quota name" %} |
+ {% trans "Items" %} |
+ {% trans "Total capacity" %} |
+ {% trans "Capacity left" %} |
+ |
+
+
+
+ {% for q in quotas %}
+
+ | {{ q.name }} |
+ |
+ {{ q.size }} |
+ |
+ |
+
+ {% endfor %}
+
+
+{% endblock %}
diff --git a/src/tixlcontrol/urls.py b/src/tixlcontrol/urls.py
index a87b82926..ce0f9cdf4 100644
--- a/src/tixlcontrol/urls.py
+++ b/src/tixlcontrol/urls.py
@@ -38,6 +38,11 @@ urlpatterns += patterns(
url(r'^properties/(?P\d+)/$', item.PropertyUpdate.as_view(), name='event.items.properties.edit'),
url(r'^properties/(?P\d+)/delete$', item.PropertyDelete.as_view(), name='event.items.properties.delete'),
url(r'^properties/add$', item.PropertyCreate.as_view(), name='event.items.properties.add'),
+ url(r'^quotas/$', item.QuotaList.as_view(), name='event.items.quotas'),
+ url(r'^quotas/(?P\d+)/$', item.QuotaUpdate.as_view(), name='event.items.quotas.edit'),
+ url(r'^quotas/(?P\d+)/delete$', item.QuotaDelete.as_view(),
+ name='event.items.quotas.delete'),
+ url(r'^quotas/add$', item.QuotaCreate.as_view(), name='event.items.quotas.add'),
)
))
)
diff --git a/src/tixlcontrol/views/item.py b/src/tixlcontrol/views/item.py
index 1dd6b2fc5..835ccf51b 100644
--- a/src/tixlcontrol/views/item.py
+++ b/src/tixlcontrol/views/item.py
@@ -10,7 +10,9 @@ from django import forms
from django.shortcuts import redirect
from django.forms.models import inlineformset_factory
-from tixlbase.models import Item, ItemCategory, Property, ItemVariation, PropertyValue, Question
+from tixlbase.models import (
+ Item, ItemCategory, Property, ItemVariation, PropertyValue, Question, Quota
+)
from tixlcontrol.permissions import EventPermissionRequiredMixin, event_permission_required
from tixlcontrol.views.forms import TolerantFormsetModelForm
from tixlcontrol.signals import restriction_formset
@@ -406,6 +408,97 @@ class QuestionCreate(EventPermissionRequiredMixin, CreateView):
return super().form_valid(form)
+class QuotaList(ListView):
+ model = Quota
+ context_object_name = 'quotas'
+ template_name = 'tixlcontrol/items/quotas.html'
+
+ def get_queryset(self):
+ return Quota.objects.filter(
+ event=self.request.event
+ )
+
+
+class QuotaForm(forms.ModelForm):
+
+ class Meta:
+ model = Quota
+ localized_fields = '__all__'
+ fields = [
+ 'name',
+ 'size',
+ ]
+
+
+class QuotaCreate(EventPermissionRequiredMixin, CreateView):
+ model = Quota
+ form_class = QuotaForm
+ template_name = 'tixlcontrol/items/quota.html'
+ permission = 'can_change_items'
+ context_object_name = 'quota'
+
+ def get_success_url(self):
+ return reverse('control:event.items.quotas', kwargs={
+ 'organizer': self.request.event.organizer.slug,
+ 'event': self.request.event.slug,
+ }) + '?created=true'
+
+ def form_valid(self, form):
+ form.instance.event = self.request.event
+ return super().form_valid(form)
+
+
+class QuotaUpdate(EventPermissionRequiredMixin, UpdateView):
+ model = Quota
+ form_class = QuotaForm
+ template_name = 'tixlcontrol/items/quota.html'
+ permission = 'can_change_items'
+ context_object_name = 'quota'
+
+ def get_object(self, queryset=None):
+ url = resolve(self.request.path_info)
+ return self.request.event.quotas.get(
+ id=url.kwargs['quota']
+ )
+
+ def get_success_url(self):
+ return reverse('control:event.items.quotas', kwargs={
+ 'organizer': self.request.event.organizer.slug,
+ 'event': self.request.event.slug,
+ }) + '?updated=true'
+
+
+class QuotaDelete(EventPermissionRequiredMixin, DeleteView):
+ model = Quota
+ template_name = 'tixlcontrol/items/quota_delete.html'
+ permission = 'can_change_items'
+ context_object_name = 'quota'
+
+ def get_object(self, queryset=None):
+ url = resolve(self.request.path_info)
+ return self.request.event.quotas.get(
+ id=url.kwargs['quota']
+ )
+
+ def get_context_data(self, *args, **kwargs):
+ context = super().get_context_data(*args, **kwargs)
+ context['dependent'] = list(self.get_object().items.all())
+ return context
+
+ def delete(self, request, *args, **kwargs):
+ self.object = self.get_object()
+ self.object.items.update(category=None)
+ success_url = self.get_success_url()
+ self.object.delete()
+ return HttpResponseRedirect(success_url)
+
+ def get_success_url(self):
+ return reverse('control:event.items.quotas', kwargs={
+ 'organizer': self.request.event.organizer.slug,
+ 'event': self.request.event.slug,
+ }) + '?deleted=true'
+
+
class ItemDetailMixin(SingleObjectMixin):
model = Item
context_object_name = 'item'