diff --git a/src/pretix/base/admin.py b/src/pretix/base/admin.py index 862c5afbe3..9650075933 100644 --- a/src/pretix/base/admin.py +++ b/src/pretix/base/admin.py @@ -88,7 +88,7 @@ class EventAdmin(admin.ModelAdmin): inlines = [EventPermissionInline] list_display = ('name', 'slug', 'organizer', 'date_from') search_fields = ('name', 'slug') - list_filter = ('date_from', 'locale', 'currency') + list_filter = ('date_from', 'currency') class PropertyValueInline(admin.StackedInline): diff --git a/src/pretix/base/middleware.py b/src/pretix/base/middleware.py index 0bd64d3927..8f26e4fef3 100644 --- a/src/pretix/base/middleware.py +++ b/src/pretix/base/middleware.py @@ -33,7 +33,7 @@ class LocaleMiddleware(BaseLocaleMiddleware): if request.user.is_authenticated(): tzname = request.user.timezone if hasattr(request, 'event'): - tzname = request.event.timezone + tzname = request.event.settings.timezone if tzname: try: timezone.activate(pytz.timezone(tzname)) @@ -72,7 +72,7 @@ def get_language_from_session_or_cookie(request) -> str: def get_language_from_event(request) -> str: if hasattr(request, 'event'): - lang_code = request.event.locale + lang_code = request.event.settings.locale try: return get_supported_language_variant(lang_code) except LookupError: diff --git a/src/pretix/base/migrations/0023_auto_20150401_0954.py b/src/pretix/base/migrations/0023_auto_20150401_0954.py new file mode 100644 index 0000000000..e5fca2a59b --- /dev/null +++ b/src/pretix/base/migrations/0023_auto_20150401_0954.py @@ -0,0 +1,38 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals + +from django.db import models, migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('pretixbase', '0022_auto_20150320_2239'), + ] + + operations = [ + migrations.RemoveField( + model_name='event', + name='locale', + ), + migrations.RemoveField( + model_name='event', + name='payment_term_days', + ), + migrations.RemoveField( + model_name='event', + name='payment_term_last', + ), + migrations.RemoveField( + model_name='event', + name='show_date_to', + ), + migrations.RemoveField( + model_name='event', + name='show_times', + ), + migrations.RemoveField( + model_name='event', + name='timezone', + ), + ] diff --git a/src/pretix/base/models.py b/src/pretix/base/models.py index 2e63908f02..cae4f386b0 100644 --- a/src/pretix/base/models.py +++ b/src/pretix/base/models.py @@ -362,32 +362,16 @@ class Event(Versionable): :param slug: A short, alphanumeric, all-lowercase name for use in URLs. The slug has to be unique among the events of the same organizer. :type slug: str - :param locale: This events default locale - :type locale: str - :param timezone: The timezone this event takes place in (or is being described in) - :type timezone: str :param currency: The currency of all prices and payments of this event :type currency: str :param date_from: The datetime this event starts :type date_from: datetime :param date_to: The datetime this event ends :type date_to: datetime - :param show_date_to: If ``False``, the ``date_to`` value will not be shown to the - user and the event will be listed only with it's start date. - :type show_date_to: bool - :param show_times: If ``False``, ``date_from`` and ``date_to`` will only be displayed - as dates, without a time of day. - :type show_times: bool :param presale_start: No tickets will be sold before this date. :type presale_start: datetime :param presale_end: No tickets will be sold before this date. :type presale_end: datetime - :param payment_term_days: The number of days in which an order has to be - paid after it has been submitted. - :type payment_term_days: int - :param payment_term_last: The day all orders must be paid by, no matter when - the order was placed. - :type payment_term_last: datetime :param plugins: A comma-separated list of plugin names that are active for this event. :type plugins: str @@ -412,29 +396,12 @@ class Event(Versionable): ) permitted = models.ManyToManyField(User, through='EventPermission', related_name="events",) - locale = models.CharField(max_length=10, - choices=settings.LANGUAGES, - verbose_name=_("Default locale"), - default=settings.LANGUAGE_CODE) - timezone = models.CharField(max_length=100, - default=settings.TIME_ZONE, - verbose_name=_('Default timezone')) currency = models.CharField(max_length=10, verbose_name=_("Default currency"), default=settings.DEFAULT_CURRENCY) date_from = models.DateTimeField(verbose_name=_("Event start time")) date_to = models.DateTimeField(null=True, blank=True, verbose_name=_("Event end time")) - show_date_to = models.BooleanField( - default=True, - verbose_name=_("Show event end date"), - help_text=_("If disabled, only event's start date will be displayed to the public."), - ) - show_times = models.BooleanField( - default=True, - verbose_name=_("Show dates with time"), - help_text=_("If disabled, the event's start and end date will be displayed without the time of day."), - ) presale_end = models.DateTimeField( null=True, blank=True, verbose_name=_("End of presale"), @@ -445,16 +412,6 @@ class Event(Versionable): verbose_name=_("Start of presale"), help_text=_("No products will be sold before this date."), ) - payment_term_days = models.PositiveIntegerField( - default=14, - verbose_name=_("Payment term in days"), - help_text=_("The number of days after placing an order the user has to pay to preserve his reservation."), - ) - payment_term_last = models.DateTimeField( - null=True, blank=True, - verbose_name=_("Last date of payments"), - help_text=_("The last date any payments are accepted. This has precedence over the number of days configured above.") - ) plugins = models.TextField( null=True, blank=True, verbose_name=_("Plugins"), @@ -498,7 +455,7 @@ class Event(Versionable): to the current locale and to the ``show_times`` setting. Returns an empty string if ``show_date_to`` is ``False``. """ - if not self.show_date_to: + if not self.settings.get('show_date_to', as_type=bool): return "" return _date( self.date_to, diff --git a/src/pretix/base/settings.py b/src/pretix/base/settings.py index 8d6bf9b969..f4ae80e014 100644 --- a/src/pretix/base/settings.py +++ b/src/pretix/base/settings.py @@ -37,6 +37,14 @@ DEFAULTS = { 'default': None, 'type': datetime, }, + 'timezone': { + 'default': settings.TIME_ZONE, + 'type': str + }, + 'locale': { + 'default': settings.LANGUAGE_CODE, + 'type': str + }, 'show_date_to': { 'default': 'True', 'type': bool @@ -50,7 +58,7 @@ DEFAULTS = { 'type': bool }, 'last_order_modification_date': { - 'default': 'None', + 'default': None, 'type': datetime }, 'mail_from': { diff --git a/src/pretix/control/templates/pretixcontrol/event/settings.html b/src/pretix/control/templates/pretixcontrol/event/settings.html index cce15645ef..c77f4a23c5 100644 --- a/src/pretix/control/templates/pretixcontrol/event/settings.html +++ b/src/pretix/control/templates/pretixcontrol/event/settings.html @@ -2,42 +2,52 @@ {% load i18n %} {% load bootstrap3 %} {% block inside %} -
{% endblock %} diff --git a/src/pretix/control/views/event.py b/src/pretix/control/views/event.py index 738308c862..c556e93e1c 100644 --- a/src/pretix/control/views/event.py +++ b/src/pretix/control/views/event.py @@ -1,4 +1,5 @@ from collections import OrderedDict +from django.conf import settings from django.shortcuts import render, redirect from django.utils.functional import cached_property from django.views.generic.edit import UpdateView @@ -17,10 +18,6 @@ from pretix.control.permissions import EventPermissionRequiredMixin class EventUpdateForm(VersionedModelForm): - timezone = forms.ChoiceField( - choices=((a, a) for a in common_timezones), - label=_("Default timezone"), - ) def clean_slug(self): return self.instance.slug @@ -35,35 +32,122 @@ class EventUpdateForm(VersionedModelForm): fields = [ 'name', 'slug', - 'locale', - 'timezone', 'currency', 'date_from', 'date_to', - 'show_date_to', - 'show_times', 'presale_start', 'presale_end', - 'payment_term_days', - 'payment_term_last', ] +class EventSettingsForm(SettingsForm): + show_date_to = forms.BooleanField( + label=_("Show event end date"), + help_text=_("If disabled, only event's start date will be displayed to the public."), + required=False + ) + show_times = forms.BooleanField( + label=_("Show dates with time"), + help_text=_("If disabled, the event's start and end date will be displayed without the time of day."), + required=False + ) + payment_term_days = forms.IntegerField( + label='Payment term in days', + help_text=_("The number of days after placing an order the user has to pay to preserve his reservation."), + ) + payment_term_last = forms.DateTimeField( + label='Last date of payments', + help_text=_("The last date any payments are accepted. This has precedence over the number of " + "days configured above."), + required=False + ) + last_order_modification_date = forms.DateTimeField( + label='Last date of modifications', + help_text=_("The last date users can modify details of their orders, such as attendee names or " + "answers to questions."), + required=False + ) + timezone = forms.ChoiceField( + choices=((a, a) for a in common_timezones), + label=_("Default timezone"), + ) + locale = forms.ChoiceField( + choices=settings.LANGUAGES, + label=_("Default locale"), + ) + user_mail_required = forms.BooleanField( + label=_("Require e-mail adresses"), + help_text=_("Require all customers to provide an e-mail address."), + required=False + ) + attendee_names_asked = forms.BooleanField( + label=_("Ask for attendee names"), + help_text=_("Ask for a name for all tickets which include admission to the event."), + required=False + ) + attendee_names_required = forms.BooleanField( + label=_("Require attendee names"), + help_text=_("Require customers to fill in the names of all attendees."), + required=False + ) + max_items_per_order = forms.IntegerField( + min_value=1, + label=_("Maximum number of items per order") + ) + reservation_time = forms.IntegerField( + min_value=0, + label=_("Reservation period"), + help_text=_("The number of minutes the items in a user's card are reserved for this user."), + ) + mail_from = forms.EmailField( + label=_("Sender address"), + help_text=_("Sender address for outgoing e-mails") + ) + + class EventUpdate(EventPermissionRequiredMixin, UpdateView): model = Event form_class = EventUpdateForm template_name = 'pretixcontrol/event/settings.html' permission = 'can_change_settings' - def get_object(self, queryset=None) -> Event: + @cached_property + def object(self) -> Event: return self.request.event + def get_object(self, queryset=None) -> Event: + return self.object + + @cached_property + def sform(self): + return EventSettingsForm( + obj=self.object, + prefix='settings', + data=self.request.POST if self.request.method == 'POST' else None + ) + + def get_context_data(self, *args, **kwargs) -> dict: + context = super().get_context_data(*args, **kwargs) + context['sform'] = self.sform + return context + + def form_valid(self, form): + self.sform.save() + return super().form_valid(form) + def get_success_url(self) -> str: return reverse('control:event.settings', kwargs={ - 'organizer': self.get_object().organizer.slug, - 'event': self.get_object().slug, + 'organizer': self.object.organizer.slug, + 'event': self.object.slug, }) + '?success=true' + def post(self, request, *args, **kwargs): + form = self.get_form() + if form.is_valid() and self.sform.is_valid(): + return self.form_valid(form) + else: + return self.form_invalid(form) + class EventPlugins(EventPermissionRequiredMixin, TemplateView, SingleObjectMixin): model = Event diff --git a/src/pretix/presale/templates/pretixpresale/event/base.html b/src/pretix/presale/templates/pretixpresale/event/base.html index 9c34b6e7fb..31bcef3be0 100644 --- a/src/pretix/presale/templates/pretixpresale/event/base.html +++ b/src/pretix/presale/templates/pretixpresale/event/base.html @@ -33,7 +33,7 @@ {% trans "Login" %} {% endif %} -