From 0c6326270c57c7e044a67599c21a06904aefb74a Mon Sep 17 00:00:00 2001 From: Raphael Michel Date: Mon, 13 Oct 2014 21:52:19 +0200 Subject: [PATCH] Basic restriction control --- src/tixlcontrol/signals.py | 6 ++ .../templates/tixlcontrol/item/base.html | 1 + .../tixlcontrol/item/restrictions.html | 41 ++++++++ src/tixlcontrol/urls.py | 1 + src/tixlcontrol/views/item.py | 98 +++++++++++++++---- src/tixlplugins/timerestriction/signals.py | 37 +++++++ 6 files changed, 164 insertions(+), 20 deletions(-) create mode 100644 src/tixlcontrol/signals.py create mode 100644 src/tixlcontrol/templates/tixlcontrol/item/restrictions.html 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" %}

+
+ {% csrf_token %} + {% for set in formsets %} +
+ {{ set.title }} +
+
+ {{ set.formset.management_form }} + {% for f in set.formset %} +
+ {% bootstrap_form f layout="horizontal" %} +
+ {% endfor %} +
+ + +
+
+ {% endfor %} +
+
+ +
+
+
+ +{% 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', + }