forked from CGM_Public/pretix_original
Very basic quota control
This commit is contained in:
25
src/tixlbase/migrations/0018_auto_20141025_0908.py
Normal file
25
src/tixlbase/migrations/0018_auto_20141025_0908.py
Normal file
@@ -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'),
|
||||
),
|
||||
]
|
||||
@@ -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):
|
||||
"""
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
<li {% if "event.items.categories" in url_name %}class="active"{% endif %}><a href="{% url 'control:event.items.categories' organizer=request.event.organizer.slug event=request.event.slug %}">{% trans "Categories" %}</a></li>
|
||||
<li {% if "event.items.properties" in url_name %}class="active"{% endif %}><a href="{% url 'control:event.items.properties' organizer=request.event.organizer.slug event=request.event.slug %}">{% trans "Properties" %}</a></li>
|
||||
<li {% if "event.items.questions" in url_name %}class="active"{% endif %}><a href="{% url 'control:event.items.questions' organizer=request.event.organizer.slug event=request.event.slug %}">{% trans "Questions" %}</a></li>
|
||||
<li {% if "event.items.quotas" in url_name %}class="active"{% endif %}><a href="{% url 'control:event.items.quotas' organizer=request.event.organizer.slug event=request.event.slug %}">{% trans "Quotas" %}</a></li>
|
||||
</ul>
|
||||
{% block inside %}
|
||||
{% endblock %}
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
<button type="submit" class="btn btn-primary">
|
||||
{% trans "Confirm" %}
|
||||
</button>
|
||||
<a href="{% url "control:event.items.properties" organizer=request.event.organizer.slug event=request.event.slug %}" class="btn btn-default">
|
||||
<a href="{% url "control:event.items.questions" organizer=request.event.organizer.slug event=request.event.slug %}" class="btn btn-default">
|
||||
{% trans "Cancel" %}
|
||||
</a>
|
||||
</div>
|
||||
|
||||
27
src/tixlcontrol/templates/tixlcontrol/items/quota.html
Normal file
27
src/tixlcontrol/templates/tixlcontrol/items/quota.html
Normal file
@@ -0,0 +1,27 @@
|
||||
{% extends "tixlcontrol/items/base.html" %}
|
||||
{% load i18n %}
|
||||
{% load bootstrap3 %}
|
||||
{% block title %}{% trans "Quota" %}{% endblock %}
|
||||
{% block inside %}
|
||||
<h1>{% trans "Quota" %}</h1>
|
||||
<form action="" method="post" class="form-horizontal">
|
||||
{% csrf_token %}
|
||||
{% if "success" in request.GET %}
|
||||
<div class="alert alert-success">
|
||||
{% trans "Your changes have been saved." %}
|
||||
</div>
|
||||
{% endif %}
|
||||
<fieldset>
|
||||
<legend>{% trans "General information" %}</legend>
|
||||
{% bootstrap_field form.name layout="horizontal" %}
|
||||
{% bootstrap_field form.size layout="horizontal" %}
|
||||
</fieldset>
|
||||
<div class="form-group">
|
||||
<div class="col-sm-offset-2 col-sm-10">
|
||||
<button type="submit" class="btn btn-primary">
|
||||
{% trans "Save" %}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
{% endblock %}
|
||||
@@ -0,0 +1,27 @@
|
||||
{% extends "tixlcontrol/items/base.html" %}
|
||||
{% load i18n %}
|
||||
{% load bootstrap3 %}
|
||||
{% block title %}{% trans "Delete quota" %}{% endblock %}
|
||||
{% block inside %}
|
||||
<h1>{% trans "Delete quota" %}</h1>
|
||||
<form action="" method="post" class="form-horizontal">
|
||||
{% csrf_token %}
|
||||
<p>{% blocktrans %}Are you sure you want to delete the quota <strong>{{ quota }}</strong>?{% endblocktrans %}</p>
|
||||
{% if dependent|length > 0 %}
|
||||
<p>{% blocktrans %}The following items might be no longer available for sale:{% endblocktrans %}</p>
|
||||
{% for item in dependent %}
|
||||
<li><a href="{% url "control:event.item" organizer=request.event.organizer.slug event=request.event.slug item=item.pk %}">{{ item.name }}</a></li>
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
<div class="form-group">
|
||||
<div class="col-sm-offset-2 col-sm-10">
|
||||
<button type="submit" class="btn btn-primary">
|
||||
{% trans "Confirm" %}
|
||||
</button>
|
||||
<a href="{% url "control:event.items.quotas" organizer=request.event.organizer.slug event=request.event.slug %}" class="btn btn-default">
|
||||
{% trans "Cancel" %}
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
{% endblock %}
|
||||
44
src/tixlcontrol/templates/tixlcontrol/items/quotas.html
Normal file
44
src/tixlcontrol/templates/tixlcontrol/items/quotas.html
Normal file
@@ -0,0 +1,44 @@
|
||||
{% extends "tixlcontrol/items/base.html" %}
|
||||
{% load i18n %}
|
||||
{% block title %}{% trans "Quotas" %}{% endblock %}
|
||||
{% block inside %}
|
||||
<h1>{% trans "Quotas" %}</h1>
|
||||
{% if "updated" in request.GET %}
|
||||
<div class="alert alert-success">
|
||||
{% trans "Your changes have been saved." %}
|
||||
</div>
|
||||
{% elif "created" in request.GET %}
|
||||
<div class="alert alert-success">
|
||||
{% trans "A new quota has been created." %}
|
||||
</div>
|
||||
{% elif "deleted" in request.GET %}
|
||||
<div class="alert alert-success">
|
||||
{% trans "The quota has been deleted." %}
|
||||
</div>
|
||||
{% endif %}
|
||||
<p>
|
||||
<a href="{% url "control:event.items.quotas.add" organizer=request.event.organizer.slug event=request.event.slug %}" class="btn btn-default"><i class="fa fa-plus"></i> {% trans "Create a new quota" %}</a>
|
||||
</p>
|
||||
<table class="table table-hover">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>{% trans "Quota name" %}</th>
|
||||
<th>{% trans "Items" %}</th>
|
||||
<th>{% trans "Total capacity" %}</th>
|
||||
<th>{% trans "Capacity left" %}</th>
|
||||
<th></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for q in quotas %}
|
||||
<tr>
|
||||
<td><strong><a href="{% url "control:event.items.quotas.edit" organizer=request.event.organizer.slug event=request.event.slug quota=q.pk %}">{{ q.name }}</a></strong></td>
|
||||
<td></td>
|
||||
<td>{{ q.size }}</td>
|
||||
<td></td>
|
||||
<td class="text-right"><a href="{% url "control:event.items.quotas.delete" organizer=request.event.organizer.slug event=request.event.slug quota=q.pk %}" class="btn btn-danger btn-sm"><i class="fa fa-trash"></i></a></td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
{% endblock %}
|
||||
@@ -38,6 +38,11 @@ urlpatterns += patterns(
|
||||
url(r'^properties/(?P<property>\d+)/$', item.PropertyUpdate.as_view(), name='event.items.properties.edit'),
|
||||
url(r'^properties/(?P<property>\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<quota>\d+)/$', item.QuotaUpdate.as_view(), name='event.items.quotas.edit'),
|
||||
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'),
|
||||
)
|
||||
))
|
||||
)
|
||||
|
||||
@@ -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'
|
||||
|
||||
Reference in New Issue
Block a user