diff --git a/src/tixlcontrol/signals.py b/src/tixlcontrol/signals.py
new file mode 100644
index 000000000..2d660d986
--- /dev/null
+++ b/src/tixlcontrol/signals.py
@@ -0,0 +1,6 @@
+from tixlbase.signals import EventPluginSignal
+
+
+restriction_formset = EventPluginSignal(
+ providing_args=["item"]
+)
diff --git a/src/tixlcontrol/templates/tixlcontrol/item/base.html b/src/tixlcontrol/templates/tixlcontrol/item/base.html
index 6f388a890..df9e136eb 100644
--- a/src/tixlcontrol/templates/tixlcontrol/item/base.html
+++ b/src/tixlcontrol/templates/tixlcontrol/item/base.html
@@ -6,6 +6,7 @@
{% block inside %}
{% endblock %}
diff --git a/src/tixlcontrol/templates/tixlcontrol/item/restrictions.html b/src/tixlcontrol/templates/tixlcontrol/item/restrictions.html
new file mode 100644
index 000000000..eb0e3d079
--- /dev/null
+++ b/src/tixlcontrol/templates/tixlcontrol/item/restrictions.html
@@ -0,0 +1,41 @@
+{% extends "tixlcontrol/item/base.html" %}
+{% load i18n %}
+{% load bootstrap3 %}
+{% load formset_tags %}
+{% block inside %}
+ {% trans "Restrictions" %}
+
+
+{% endblock %}
diff --git a/src/tixlcontrol/urls.py b/src/tixlcontrol/urls.py
index fdd058507..a87b82926 100644
--- a/src/tixlcontrol/urls.py
+++ b/src/tixlcontrol/urls.py
@@ -23,6 +23,7 @@ urlpatterns += patterns(
url(r'^items/$', item.ItemList.as_view(), name='event.items'),
url(r'^items/(?P- \d+)/$', item.ItemUpdateGeneral.as_view(), name='event.item'),
url(r'^items/(?P
- \d+)/variations$', item.ItemVariations.as_view(), name='event.item.variations'),
+ url(r'^items/(?P
- \d+)/restrictions$', item.ItemRestrictions.as_view(), name='event.item.restrictions'),
url(r'^categories/$', item.CategoryList.as_view(), name='event.items.categories'),
url(r'^categories/(?P\d+)/delete$', item.CategoryDelete.as_view(), name='event.items.categories.delete'),
url(r'^categories/(?P\d+)/up$', item.category_move_up, name='event.items.categories.up'),
diff --git a/src/tixlcontrol/views/item.py b/src/tixlcontrol/views/item.py
index 5d90d65f3..0f520e985 100644
--- a/src/tixlcontrol/views/item.py
+++ b/src/tixlcontrol/views/item.py
@@ -13,6 +13,7 @@ from django.forms.models import inlineformset_factory
from tixlbase.models import Item, ItemCategory, Property, ItemVariation, PropertyValue, Question
from tixlcontrol.permissions import EventPermissionRequiredMixin, event_permission_required
from tixlcontrol.views.forms import TolerantFormsetModelForm
+from tixlcontrol.signals import restriction_formset
class ItemList(ListView):
@@ -405,6 +406,20 @@ class QuestionCreate(EventPermissionRequiredMixin, CreateView):
return super().form_valid(form)
+class ItemDetailMixin(SingleObjectMixin):
+ model = Item
+ context_object_name = 'item'
+
+ def get_object(self, queryset=None):
+ if not hasattr(self, 'object') or not self.object:
+ url = resolve(self.request.path_info)
+ self.item = self.request.event.items.get(
+ id=url.kwargs['item']
+ )
+ self.object = self.item
+ return self.object
+
+
class ItemUpdateFormGeneral(forms.ModelForm):
def __init__(self, *args, **kwargs):
@@ -429,18 +444,10 @@ class ItemUpdateFormGeneral(forms.ModelForm):
]
-class ItemUpdateGeneral(EventPermissionRequiredMixin, UpdateView):
- model = Item
+class ItemUpdateGeneral(ItemDetailMixin, EventPermissionRequiredMixin, UpdateView):
form_class = ItemUpdateFormGeneral
template_name = 'tixlcontrol/item/index.html'
permission = 'can_change_items'
- context_object_name = 'item'
-
- def get_object(self, queryset=None):
- url = resolve(self.request.path_info)
- return self.request.event.items.get(
- id=url.kwargs['item']
- )
def get_success_url(self):
return reverse('control:event.item', kwargs={
@@ -461,10 +468,8 @@ class ItemVariationForm(forms.ModelForm):
]
-class ItemVariations(EventPermissionRequiredMixin, TemplateView, SingleObjectMixin):
+class ItemVariations(ItemDetailMixin, EventPermissionRequiredMixin, TemplateView):
- model = Item
- context_object_name = 'item'
permission = 'can_change_items'
def __init__(self, *args, **kwargs):
@@ -618,14 +623,6 @@ class ItemVariations(EventPermissionRequiredMixin, TemplateView, SingleObjectMix
form.save()
return self.render_to_response(context)
- def get_object(self, queryset=None):
- if not self.item:
- url = resolve(self.request.path_info)
- self.item = self.request.event.items.get(
- id=url.kwargs['item']
- )
- return self.item
-
def get_template_names(self):
if self.dimension == 1:
return ['tixlcontrol/item/variations_1d.html']
@@ -639,3 +636,64 @@ class ItemVariations(EventPermissionRequiredMixin, TemplateView, SingleObjectMix
context['forms'] = self.forms
context['properties'] = self.properties
return context
+
+
+class ItemRestrictions(ItemDetailMixin, EventPermissionRequiredMixin, TemplateView):
+
+ permission = 'can_change_items'
+ template_name = 'tixlcontrol/item/restrictions.html'
+
+ def get_formsets(self):
+ responses = restriction_formset.send(self.object.event, item=self.object)
+ formsets = []
+ for receiver, response in responses:
+ response['formset'] = response['formsetclass'](
+ self.request.POST if self.request.method == 'POST' else None,
+ queryset=response['queryset'],
+ prefix=response['prefix'],
+ )
+ formsets.append(response)
+ return formsets
+
+ def main(self, request, *args, **kwargs):
+ self.object = self.get_object()
+ self.request = request
+ self.formsets = self.get_formsets()
+
+ def get(self, request, *args, **kwargs):
+ self.main(request, *args, **kwargs)
+ context = self.get_context_data(object=self.object)
+ return self.render_to_response(context)
+
+ def post(self, request, *args, **kwargs):
+ self.main(request, *args, **kwargs)
+ valid = True
+ for f in self.formsets:
+ valid &= f['formset'].is_valid()
+ if valid:
+ for f in self.formsets:
+ for form in f['formset']:
+ if 'DELETE' in form.cleaned_data and form.cleaned_data['DELETE'] is True:
+ if form.instance.pk is None:
+ continue
+ form.instance.delete()
+ else:
+ form.instance.event = request.event
+ form.instance.item = self.object
+ form.instance.save()
+ return redirect(self.get_success_url())
+ else:
+ context = self.get_context_data(object=self.object)
+ return self.render_to_response(context)
+
+ def get_context_data(self, *args, **kwargs):
+ context = super().get_context_data(*args, **kwargs)
+ context['formsets'] = self.formsets
+ return context
+
+ def get_success_url(self):
+ return reverse('control:event.item.restrictions', kwargs={
+ 'organizer': self.request.event.organizer.slug,
+ 'event': self.request.event.slug,
+ 'item': self.object.pk
+ }) + '?success=true'
diff --git a/src/tixlplugins/timerestriction/signals.py b/src/tixlplugins/timerestriction/signals.py
index 7d6a09bb5..0ab411d00 100644
--- a/src/tixlplugins/timerestriction/signals.py
+++ b/src/tixlplugins/timerestriction/signals.py
@@ -1,7 +1,11 @@
from django.dispatch import receiver
from django.utils.timezone import now
+from django.utils.translation import ugettext_lazy as _
+from django import forms
+from django.forms.models import modelformset_factory
from tixlbase.signals import determine_availability
+from tixlcontrol.signals import restriction_formset
from .models import TimeRestriction
@@ -105,3 +109,36 @@ def availability_handler(sender, **kwargs):
)
return variations
+
+
+class TimeRestrictionForm(forms.ModelForm):
+ class Meta:
+ model = TimeRestriction
+ localized_fields = '__all__'
+ fields = [
+ 'timeframe_from',
+ 'timeframe_to',
+ 'price',
+ ]
+
+
+@receiver(restriction_formset)
+def formset_handler(sender, **kwargs):
+ # Handle the signal's input arguments
+ item = kwargs['item']
+
+ formset = modelformset_factory(
+ TimeRestriction,
+ form=TimeRestrictionForm,
+ can_order=False,
+ can_delete=True,
+ extra=0,
+ )
+ queryset = TimeRestriction.objects.filter(item=item)
+
+ return {
+ 'title': _('Restriction by time'),
+ 'formsetclass': formset,
+ 'queryset': queryset,
+ 'prefix': 'timerestriction',
+ }