diff --git a/src/tixlbase/models.py b/src/tixlbase/models.py index 1d0b980bc5..417c9a5269 100644 --- a/src/tixlbase/models.py +++ b/src/tixlbase/models.py @@ -444,7 +444,7 @@ class Question(models.Model): verbose_name_plural = _("Questions") def __str__(self): - return self.name + return self.question class Item(models.Model): @@ -513,7 +513,7 @@ class Item(models.Model): ) questions = models.ManyToManyField( Question, - related_name='questions', + related_name='items', verbose_name=_("Questions"), blank=True, help_text=_( diff --git a/src/tixlcontrol/templates/tixlcontrol/item/index.html b/src/tixlcontrol/templates/tixlcontrol/item/index.html index c26d7bddc9..88c31ded48 100644 --- a/src/tixlcontrol/templates/tixlcontrol/item/index.html +++ b/src/tixlcontrol/templates/tixlcontrol/item/index.html @@ -25,8 +25,9 @@ {% bootstrap_field form.tax_rate layout="horizontal" %}
- {% trans "Variations" %} + {% trans "Advanced settings" %} {% bootstrap_field form.properties layout="horizontal" %} + {% bootstrap_field form.questions layout="horizontal" %}
diff --git a/src/tixlcontrol/templates/tixlcontrol/items/base.html b/src/tixlcontrol/templates/tixlcontrol/items/base.html index 2c77ae621d..499d305f66 100644 --- a/src/tixlcontrol/templates/tixlcontrol/items/base.html +++ b/src/tixlcontrol/templates/tixlcontrol/items/base.html @@ -6,6 +6,7 @@
  • {% trans "Items" %}
  • {% trans "Categories" %}
  • {% trans "Properties" %}
  • +
  • {% trans "Questions" %}
  • {% block inside %} {% endblock %} diff --git a/src/tixlcontrol/templates/tixlcontrol/items/categories.html b/src/tixlcontrol/templates/tixlcontrol/items/categories.html index fb2a7848bc..f5168b54d0 100644 --- a/src/tixlcontrol/templates/tixlcontrol/items/categories.html +++ b/src/tixlcontrol/templates/tixlcontrol/items/categories.html @@ -24,6 +24,7 @@ {% trans "Item categories" %} + diff --git a/src/tixlcontrol/templates/tixlcontrol/items/question.html b/src/tixlcontrol/templates/tixlcontrol/items/question.html new file mode 100644 index 0000000000..a7877527b2 --- /dev/null +++ b/src/tixlcontrol/templates/tixlcontrol/items/question.html @@ -0,0 +1,28 @@ +{% extends "tixlcontrol/items/base.html" %} +{% load i18n %} +{% load bootstrap3 %} +{% block title %}{% trans "Question" %}{% endblock %} +{% block inside %} +

    {% trans "Question" %}

    +
    + {% csrf_token %} + {% if "success" in request.GET %} +
    + {% trans "Your changes have been saved." %} +
    + {% endif %} +
    + {% trans "General information" %} + {% bootstrap_field form.question layout="horizontal" %} + {% bootstrap_field form.type layout="horizontal" %} + {% bootstrap_field form.required layout="horizontal" %} +
    +
    +
    + +
    +
    +
    +{% endblock %} diff --git a/src/tixlcontrol/templates/tixlcontrol/items/question_delete.html b/src/tixlcontrol/templates/tixlcontrol/items/question_delete.html new file mode 100644 index 0000000000..0674c40f20 --- /dev/null +++ b/src/tixlcontrol/templates/tixlcontrol/items/question_delete.html @@ -0,0 +1,27 @@ +{% extends "tixlcontrol/items/base.html" %} +{% load i18n %} +{% load bootstrap3 %} +{% block title %}{% trans "Delete question" %}{% endblock %} +{% block inside %} +

    {% trans "Delete question" %}

    +
    + {% csrf_token %} +

    {% blocktrans %}Are you sure you want to the question {{ question }}?{% endblocktrans %}

    + {% if dependent|length > 0 %} +

    {% blocktrans %}All answers to the question given by the buyers of the following tickets will be permanently lost.{% endblocktrans %}

    + {% for item in dependent %} +
  • {{ item.name }}
  • + {% endfor %} + {% endif %} +
    +
    + + + {% trans "Cancel" %} + +
    +
    +
    +{% endblock %} diff --git a/src/tixlcontrol/templates/tixlcontrol/items/questions.html b/src/tixlcontrol/templates/tixlcontrol/items/questions.html new file mode 100644 index 0000000000..b655071be8 --- /dev/null +++ b/src/tixlcontrol/templates/tixlcontrol/items/questions.html @@ -0,0 +1,40 @@ +{% extends "tixlcontrol/items/base.html" %} +{% load i18n %} +{% block title %}{% trans "Questions" %}{% endblock %} +{% block inside %} +

    {% trans "Questions" %}

    + {% if "updated" in request.GET %} +
    + {% trans "Your changes have been saved." %} +
    + {% elif "created" in request.GET %} +
    + {% trans "A new question has been created." %} +
    + {% elif "deleted" in request.GET %} +
    + {% trans "The question has been deleted." %} +
    + {% endif %} +

    + {% trans "Create new question" %} +

    + + + + + + + + + + {% for q in questions %} + + + + + + {% endfor %} + +
    {% trans "Question" %}{% trans "Type" %}
    {{ q.question }}{{ q.get_type_display }}
    +{% endblock %} diff --git a/src/tixlcontrol/urls.py b/src/tixlcontrol/urls.py index cb1945eb27..2ee6de7343 100644 --- a/src/tixlcontrol/urls.py +++ b/src/tixlcontrol/urls.py @@ -19,16 +19,20 @@ urlpatterns += patterns( 'tixlcontrol.views', url(r'^$', 'event.index', name='event.index'), url(r'^settings$', event.EventUpdate.as_view(), name='event.settings'), - url(r'^items$', item.ItemList.as_view(), name='event.items'), + 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'^categories/$', item.CategoryList.as_view(), name='event.items.categories'), - url(r'^category/(?P\d+)/delete$', item.CategoryDelete.as_view(), name='event.items.categories.delete'), - url(r'^category/(?P\d+)/up$', item.category_move_up, name='event.items.categories.up'), - url(r'^category/(?P\d+)/down$', item.category_move_down, name='event.items.categories.down'), - url(r'^category/(?P\d+)/$', item.CategoryUpdate.as_view(), name='event.items.categories.edit'), - url(r'^category/add$', item.CategoryCreate.as_view(), name='event.items.categories.add'), - url(r'^properties$', item.PropertyList.as_view(), name='event.items.properties'), + 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'), + url(r'^categories/(?P\d+)/down$', item.category_move_down, name='event.items.categories.down'), + url(r'^categories/(?P\d+)/$', item.CategoryUpdate.as_view(), name='event.items.categories.edit'), + url(r'^categories/add$', item.CategoryCreate.as_view(), name='event.items.categories.add'), + url(r'^questions/$', item.QuestionList.as_view(), name='event.items.questions'), + url(r'^questions/(?P\d+)/delete$', item.QuestionDelete.as_view(), name='event.items.questions.delete'), + url(r'^questions/(?P\d+)/$', item.QuestionUpdate.as_view(), name='event.items.questions.edit'), + url(r'^questions/add$', item.QuestionCreate.as_view(), name='event.items.questions.add'), + url(r'^properties/$', item.PropertyList.as_view(), name='event.items.properties'), 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'), diff --git a/src/tixlcontrol/views/item.py b/src/tixlcontrol/views/item.py index 5d12e161b5..69ed2f150f 100644 --- a/src/tixlcontrol/views/item.py +++ b/src/tixlcontrol/views/item.py @@ -10,7 +10,7 @@ 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 +from tixlbase.models import Item, ItemCategory, Property, ItemVariation, PropertyValue, Question from tixlcontrol.permissions import EventPermissionRequiredMixin, event_permission_required from tixlcontrol.views.forms import TolerantFormsetModelForm @@ -315,12 +315,103 @@ class PropertyDelete(EventPermissionRequiredMixin, DeleteView): }) + '?deleted=true' +class QuestionList(ListView): + model = Question + context_object_name = 'questions' + template_name = 'tixlcontrol/items/questions.html' + + def get_queryset(self): + return self.request.event.questions.all() + + +class QuestionForm(forms.ModelForm): + + class Meta: + model = Question + localized_fields = '__all__' + fields = [ + 'question', + 'type', + 'required', + ] + + +class QuestionDelete(EventPermissionRequiredMixin, DeleteView): + model = Question + template_name = 'tixlcontrol/items/question_delete.html' + permission = 'can_change_items' + context_object_name = 'question' + + def get_object(self, queryset=None): + url = resolve(self.request.path_info) + return self.request.event.questions.get( + id=url.kwargs['question'] + ) + + 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.questions', kwargs={ + 'organizer': self.request.event.organizer.slug, + 'event': self.request.event.slug, + }) + '?deleted=true' + + +class QuestionUpdate(EventPermissionRequiredMixin, UpdateView): + model = Question + form_class = QuestionForm + template_name = 'tixlcontrol/items/question.html' + permission = 'can_change_items' + context_object_name = 'question' + + def get_object(self, queryset=None): + url = resolve(self.request.path_info) + return self.request.event.questions.get( + id=url.kwargs['question'] + ) + + def get_success_url(self): + return reverse('control:event.items.questions', kwargs={ + 'organizer': self.request.event.organizer.slug, + 'event': self.request.event.slug, + }) + '?updated=true' + + +class QuestionCreate(EventPermissionRequiredMixin, CreateView): + model = Question + form_class = QuestionForm + template_name = 'tixlcontrol/items/question.html' + permission = 'can_change_items' + context_object_name = 'question' + + def get_success_url(self): + return reverse('control:event.items.questions', 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 ItemUpdateFormGeneral(forms.ModelForm): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.fields['category'].queryset = self.instance.event.categories.all() self.fields['properties'].queryset = self.instance.event.properties.all() + self.fields['questions'].queryset = self.instance.event.questions.all() class Meta: model = Item @@ -334,6 +425,7 @@ class ItemUpdateFormGeneral(forms.ModelForm): 'default_price', 'tax_rate', 'properties', + 'questions', ]