diff --git a/src/pretix/base/migrations/0065_auto_20170707_0920.py b/src/pretix/base/migrations/0065_auto_20170707_0920.py new file mode 100644 index 0000000000..472640cfbc --- /dev/null +++ b/src/pretix/base/migrations/0065_auto_20170707_0920.py @@ -0,0 +1,30 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.11.2 on 2017-07-07 09:20 +from __future__ import unicode_literals + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('pretixbase', '0064_auto_20170703_0912'), + ] + + operations = [ + migrations.AddField( + model_name='event', + name='comment', + field=models.TextField(blank=True, null=True, verbose_name='Internal comment'), + ), + migrations.AlterField( + model_name='event', + name='presale_end', + field=models.DateTimeField(blank=True, help_text='Optional. No products will be sold after this date.', null=True, verbose_name='End of presale'), + ), + migrations.AlterField( + model_name='event', + name='presale_start', + field=models.DateTimeField(blank=True, help_text='Optional. No products will be sold before this date.', null=True, verbose_name='Start of presale'), + ), + ] diff --git a/src/pretix/base/models/event.py b/src/pretix/base/models/event.py index aa3fc979b8..4348bfd7b9 100644 --- a/src/pretix/base/models/event.py +++ b/src/pretix/base/models/event.py @@ -112,6 +112,10 @@ class Event(LoggedModel): null=True, blank=True, verbose_name=_("Plugins"), ) + comment = models.TextField( + verbose_name=_("Internal comment"), + null=True, blank=True + ) class Meta: verbose_name = _("Event") diff --git a/src/pretix/control/forms/event.py b/src/pretix/control/forms/event.py index 6a1e32050b..92373b539f 100644 --- a/src/pretix/control/forms/event.py +++ b/src/pretix/control/forms/event.py @@ -697,3 +697,15 @@ class TicketSettingsForm(SettingsForm): val = cleaned_data.get(k) if v._required and (val is None or val == ""): self.add_error(k, _('This field is required.')) + + +class CommentForm(I18nModelForm): + class Meta: + model = Event + fields = ['comment'] + widgets = { + 'comment': forms.Textarea(attrs={ + 'rows': 3, + 'class': 'helper-width-100', + }), + } diff --git a/src/pretix/control/logdisplay.py b/src/pretix/control/logdisplay.py index 8e1a3582b3..dec62c1d46 100644 --- a/src/pretix/control/logdisplay.py +++ b/src/pretix/control/logdisplay.py @@ -76,6 +76,7 @@ def _display_order_changed(event: Event, logentry: LogEntry): @receiver(signal=logentry_display, dispatch_uid="pretixcontrol_logentry_display") def pretixcontrol_logentry_display(sender: Event, logentry: LogEntry, **kwargs): plains = { + 'pretix.event.comment': _('The event\'s internal comment has been updated.'), 'pretix.event.order.modified': _('The order details have been modified.'), 'pretix.event.order.unpaid': _('The order has been marked as unpaid.'), 'pretix.event.order.resend': _('The link to the order detail page has been resent to the user.'), diff --git a/src/pretix/control/templates/pretixcontrol/event/index.html b/src/pretix/control/templates/pretixcontrol/event/index.html index af1e9c73c0..6f0455c1ac 100644 --- a/src/pretix/control/templates/pretixcontrol/event/index.html +++ b/src/pretix/control/templates/pretixcontrol/event/index.html @@ -1,12 +1,13 @@ {% extends "pretixcontrol/event/base.html" %} {% load i18n %} {% load eventurl %} +{% load bootstrap3 %} {% load staticfiles %} {% block title %}{{ request.event.name }}{% endblock %} {% block content %} -

- {{ request.event.name }} -

+

+ {{ request.event.name }} +

{% if actions|length > 0 %}
@@ -19,10 +20,12 @@
  • + class="btn btn-default btn-xs pull-right"> {% trans "Hide message" %} - {{ action.datetime|date:"SHORT_DATETIME_FORMAT" }} + {{ action.datetime|date:"SHORT_DATETIME_FORMAT" }} +

    {{ action.display|safe }}
  • @@ -57,6 +60,28 @@

     

    +
    +
    +

    + {% trans "Internal comment" %} +

    +
    +
    +
    + {% csrf_token %} +
    + {% bootstrap_field comment_form.comment layout="horizontal" show_help=True show_label=False horizontal_field_class="col-md-12" %} +
    +

    +
    + +

    +
    +
    +

    @@ -74,8 +99,8 @@ {% if log.user %} {% if log.user.is_superuser %} + data-toggle="tooltip" + title="{% trans "This change was performed by a pretix administrator." %}"> {% else %} diff --git a/src/pretix/control/urls.py b/src/pretix/control/urls.py index b6c4daac27..bf281cf91b 100644 --- a/src/pretix/control/urls.py +++ b/src/pretix/control/urls.py @@ -55,6 +55,8 @@ urlpatterns = [ url(r'^requiredactions/$', event.EventActions.as_view(), name='event.requiredactions'), url(r'^requiredactions/(?P\d+)/discard$', event.EventActionDiscard.as_view(), name='event.requiredaction.discard'), + url(r'^comment/$', event.EventComment.as_view(), + name='event.comment'), url(r'^settings/$', event.EventUpdate.as_view(), name='event.settings'), url(r'^settings/plugins$', event.EventPlugins.as_view(), name='event.settings.plugins'), url(r'^settings/permissions$', event.EventPermissions.as_view(), name='event.settings.permissions'), diff --git a/src/pretix/control/views/dashboards.py b/src/pretix/control/views/dashboards.py index 7d9be19b1f..38dbf0ea27 100644 --- a/src/pretix/control/views/dashboards.py +++ b/src/pretix/control/views/dashboards.py @@ -13,6 +13,7 @@ from django.utils.translation import ugettext_lazy as _ from pretix.base.models import ( Item, Order, OrderPosition, Voucher, WaitingListEntry, ) +from pretix.control.forms.event import CommentForm from pretix.control.signals import ( event_dashboard_widgets, user_dashboard_widgets, ) @@ -239,6 +240,7 @@ def event_index(request, organizer, event): 'widgets': rearrange(widgets), 'logs': qs[:5], 'actions': a_qs[:5] if can_change_orders else [], + 'comment_form': CommentForm(initial={'comment': request.event.comment}) } for a in ctx['actions']: diff --git a/src/pretix/control/views/event.py b/src/pretix/control/views/event.py index 3baa699c6c..0ca1b8a345 100644 --- a/src/pretix/control/views/event.py +++ b/src/pretix/control/views/event.py @@ -8,7 +8,9 @@ from django.contrib.contenttypes.models import ContentType from django.core.files import File from django.core.urlresolvers import reverse from django.db import transaction -from django.http import HttpResponse, HttpResponseBadRequest, JsonResponse +from django.http import ( + HttpResponse, HttpResponseBadRequest, HttpResponseNotAllowed, JsonResponse, +) from django.shortcuts import get_object_or_404, redirect from django.utils import translation from django.utils.formats import date_format @@ -28,7 +30,7 @@ from pretix.base.services import tickets from pretix.base.services.invoices import build_preview_invoice_pdf from pretix.base.signals import event_live_issues, register_ticket_outputs from pretix.control.forms.event import ( - DisplaySettingsForm, EventSettingsForm, EventUpdateForm, + CommentForm, DisplaySettingsForm, EventSettingsForm, EventUpdateForm, InvoiceSettingsForm, MailSettingsForm, PaymentSettingsForm, ProviderForm, TicketSettingsForm, ) @@ -757,3 +759,29 @@ class EventActionDiscard(EventPermissionRequiredMixin, View): 'organizer': self.request.event.organizer.slug, 'event': self.request.event.slug }) + + +class EventComment(EventPermissionRequiredMixin, View): + permission = 'can_change_event_settings' + + def post(self, *args, **kwargs): + form = CommentForm(self.request.POST) + if form.is_valid(): + self.request.event.comment = form.cleaned_data.get('comment') + self.request.event.save() + self.request.event.log_action('pretix.event.comment', user=self.request.user, data={ + 'new_comment': form.cleaned_data.get('comment') + }) + messages.success(self.request, _('The comment has been updated.')) + else: + messages.error(self.request, _('Could not update the comment.')) + return redirect(self.get_success_url()) + + def get(self, *args, **kwargs): + return HttpResponseNotAllowed(['POST']) + + def get_success_url(self) -> str: + return reverse('control:event.index', kwargs={ + 'organizer': self.request.event.organizer.slug, + 'event': self.request.event.slug + }) diff --git a/src/pretix/control/views/orders.py b/src/pretix/control/views/orders.py index dcf8284ec2..6405d7bc53 100644 --- a/src/pretix/control/views/orders.py +++ b/src/pretix/control/views/orders.py @@ -181,7 +181,9 @@ class OrderComment(OrderView): if form.is_valid(): self.order.comment = form.cleaned_data.get('comment') self.order.save() - self.order.log_action('pretix.event.order.comment', user=self.request.user) + self.order.log_action('pretix.event.order.comment', user=self.request.user, data={ + 'new_comment': form.cleaned_data.get('comment') + }) messages.success(self.request, _('The comment has been updated.')) else: messages.error(self.request, _('Could not update the comment.')) diff --git a/src/tests/control/test_permissions.py b/src/tests/control/test_permissions.py index 32fd32f20d..147914d55f 100644 --- a/src/tests/control/test_permissions.py +++ b/src/tests/control/test_permissions.py @@ -31,6 +31,7 @@ superuser_urls = [ event_urls = [ "", + "comment/", "settings/", "settings/plugins", "settings/payment", @@ -157,6 +158,7 @@ event_permission_urls = [ ("can_change_event_settings", "settings/display", 200), ("can_change_event_settings", "settings/invoice", 200), ("can_change_event_settings", "settings/invoice/preview", 200), + ("can_change_event_settings", "comment/", 405), # Lists are currently not access-controlled # ("can_change_items", "items/", 200), ("can_change_items", "items/add", 200),