Wider usage of the settings framework (#17)

This commit is contained in:
Raphael Michel
2015-04-01 11:54:56 +02:00
parent 42b4189703
commit cd0e1cb520
9 changed files with 198 additions and 101 deletions
+1 -1
View File
@@ -88,7 +88,7 @@ class EventAdmin(admin.ModelAdmin):
inlines = [EventPermissionInline] inlines = [EventPermissionInline]
list_display = ('name', 'slug', 'organizer', 'date_from') list_display = ('name', 'slug', 'organizer', 'date_from')
search_fields = ('name', 'slug') search_fields = ('name', 'slug')
list_filter = ('date_from', 'locale', 'currency') list_filter = ('date_from', 'currency')
class PropertyValueInline(admin.StackedInline): class PropertyValueInline(admin.StackedInline):
+2 -2
View File
@@ -33,7 +33,7 @@ class LocaleMiddleware(BaseLocaleMiddleware):
if request.user.is_authenticated(): if request.user.is_authenticated():
tzname = request.user.timezone tzname = request.user.timezone
if hasattr(request, 'event'): if hasattr(request, 'event'):
tzname = request.event.timezone tzname = request.event.settings.timezone
if tzname: if tzname:
try: try:
timezone.activate(pytz.timezone(tzname)) 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: def get_language_from_event(request) -> str:
if hasattr(request, 'event'): if hasattr(request, 'event'):
lang_code = request.event.locale lang_code = request.event.settings.locale
try: try:
return get_supported_language_variant(lang_code) return get_supported_language_variant(lang_code)
except LookupError: except LookupError:
@@ -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',
),
]
+1 -44
View File
@@ -362,32 +362,16 @@ class Event(Versionable):
:param slug: A short, alphanumeric, all-lowercase name for use in URLs. The slug has to :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. be unique among the events of the same organizer.
:type slug: str :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 :param currency: The currency of all prices and payments of this event
:type currency: str :type currency: str
:param date_from: The datetime this event starts :param date_from: The datetime this event starts
:type date_from: datetime :type date_from: datetime
:param date_to: The datetime this event ends :param date_to: The datetime this event ends
:type date_to: datetime :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. :param presale_start: No tickets will be sold before this date.
:type presale_start: datetime :type presale_start: datetime
:param presale_end: No tickets will be sold before this date. :param presale_end: No tickets will be sold before this date.
:type presale_end: datetime :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 :param plugins: A comma-separated list of plugin names that are active for this
event. event.
:type plugins: str :type plugins: str
@@ -412,29 +396,12 @@ class Event(Versionable):
) )
permitted = models.ManyToManyField(User, through='EventPermission', permitted = models.ManyToManyField(User, through='EventPermission',
related_name="events",) 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, currency = models.CharField(max_length=10,
verbose_name=_("Default currency"), verbose_name=_("Default currency"),
default=settings.DEFAULT_CURRENCY) default=settings.DEFAULT_CURRENCY)
date_from = models.DateTimeField(verbose_name=_("Event start time")) date_from = models.DateTimeField(verbose_name=_("Event start time"))
date_to = models.DateTimeField(null=True, blank=True, date_to = models.DateTimeField(null=True, blank=True,
verbose_name=_("Event end time")) 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( presale_end = models.DateTimeField(
null=True, blank=True, null=True, blank=True,
verbose_name=_("End of presale"), verbose_name=_("End of presale"),
@@ -445,16 +412,6 @@ class Event(Versionable):
verbose_name=_("Start of presale"), verbose_name=_("Start of presale"),
help_text=_("No products will be sold before this date."), 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( plugins = models.TextField(
null=True, blank=True, null=True, blank=True,
verbose_name=_("Plugins"), verbose_name=_("Plugins"),
@@ -498,7 +455,7 @@ class Event(Versionable):
to the current locale and to the ``show_times`` setting. Returns an empty string to the current locale and to the ``show_times`` setting. Returns an empty string
if ``show_date_to`` is ``False``. 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 ""
return _date( return _date(
self.date_to, self.date_to,
+9 -1
View File
@@ -37,6 +37,14 @@ DEFAULTS = {
'default': None, 'default': None,
'type': datetime, 'type': datetime,
}, },
'timezone': {
'default': settings.TIME_ZONE,
'type': str
},
'locale': {
'default': settings.LANGUAGE_CODE,
'type': str
},
'show_date_to': { 'show_date_to': {
'default': 'True', 'default': 'True',
'type': bool 'type': bool
@@ -50,7 +58,7 @@ DEFAULTS = {
'type': bool 'type': bool
}, },
'last_order_modification_date': { 'last_order_modification_date': {
'default': 'None', 'default': None,
'type': datetime 'type': datetime
}, },
'mail_from': { 'mail_from': {
@@ -2,42 +2,52 @@
{% load i18n %} {% load i18n %}
{% load bootstrap3 %} {% load bootstrap3 %}
{% block inside %} {% block inside %}
<form action="" method="post" class="form-horizontal"> <form action="" method="post" class="form-horizontal">
{% if "success" in request.GET %} {% if "success" in request.GET %}
<div class="alert alert-success"> <div class="alert alert-success">
{% trans "Your changes have been saved." %} {% trans "Your changes have been saved." %}
</div> </div>
{% endif %} {% endif %}
{% csrf_token %} {% csrf_token %}
<fieldset> <fieldset>
<legend>{% trans "General information" %}</legend> <legend>{% trans "General information" %}</legend>
{% bootstrap_field form.name layout="horizontal" %} {% bootstrap_field form.name layout="horizontal" %}
{% bootstrap_field form.slug layout="horizontal" %} {% bootstrap_field form.slug layout="horizontal" %}
{% bootstrap_field form.date_from layout="horizontal" %} {% bootstrap_field form.date_from layout="horizontal" %}
{% bootstrap_field form.date_to layout="horizontal" %} {% bootstrap_field form.date_to layout="horizontal" %}
{% bootstrap_field form.currency layout="horizontal" %} {% bootstrap_field form.currency layout="horizontal" %}
</fieldset> </fieldset>
<fieldset> <fieldset>
<legend>{% trans "Display settings" %}</legend> <legend>{% trans "Display settings" %}</legend>
{% bootstrap_field form.locale layout="horizontal" %} {% bootstrap_field sform.locale layout="horizontal" %}
{% bootstrap_field form.timezone layout="horizontal" %} {% bootstrap_field sform.timezone layout="horizontal" %}
{% bootstrap_field form.show_date_to layout="horizontal" %} {% bootstrap_field sform.show_date_to layout="horizontal" %}
{% bootstrap_field form.show_times layout="horizontal" %} {% bootstrap_field sform.show_times layout="horizontal" %}
</fieldset> </fieldset>
<fieldset> <fieldset>
<legend>{% trans "Presale settings" %}</legend> <legend>{% trans "Timeline" %}</legend>
{% bootstrap_field form.presale_start layout="horizontal" %} {% bootstrap_field form.presale_start layout="horizontal" %}
{% bootstrap_field form.presale_end layout="horizontal" %} {% bootstrap_field form.presale_end layout="horizontal" %}
</fieldset> {% bootstrap_field sform.payment_term_days layout="horizontal" %}
<fieldset> {% bootstrap_field sform.payment_term_last layout="horizontal" %}
<legend>{% trans "Payment settings" %}</legend> {% bootstrap_field sform.last_order_modification_date layout="horizontal" %}
{% bootstrap_field form.payment_term_days layout="horizontal" %} </fieldset>
{% bootstrap_field form.payment_term_last layout="horizontal" %} <fieldset>
</fieldset> <legend>{% trans "Order process settings" %}</legend>
<div class="form-group submit-group"> {% bootstrap_field sform.reservation_time layout="horizontal" %}
{% bootstrap_field sform.max_items_per_order layout="horizontal" %}
{% bootstrap_field sform.user_mail_required layout="horizontal" %}
{% bootstrap_field sform.attendee_names_asked layout="horizontal" %}
{% bootstrap_field sform.attendee_names_required layout="horizontal" %}
</fieldset>
<fieldset>
<legend>{% trans "E-Mail settings" %}</legend>
{% bootstrap_field sform.mail_from layout="horizontal" %}
</fieldset>
<div class="form-group submit-group">
<button type="submit" class="btn btn-primary btn-save"> <button type="submit" class="btn btn-primary btn-save">
{% trans "Save" %} {% trans "Save" %}
</button> </button>
</div> </div>
</form> </form>
{% endblock %} {% endblock %}
+97 -13
View File
@@ -1,4 +1,5 @@
from collections import OrderedDict from collections import OrderedDict
from django.conf import settings
from django.shortcuts import render, redirect from django.shortcuts import render, redirect
from django.utils.functional import cached_property from django.utils.functional import cached_property
from django.views.generic.edit import UpdateView from django.views.generic.edit import UpdateView
@@ -17,10 +18,6 @@ from pretix.control.permissions import EventPermissionRequiredMixin
class EventUpdateForm(VersionedModelForm): class EventUpdateForm(VersionedModelForm):
timezone = forms.ChoiceField(
choices=((a, a) for a in common_timezones),
label=_("Default timezone"),
)
def clean_slug(self): def clean_slug(self):
return self.instance.slug return self.instance.slug
@@ -35,35 +32,122 @@ class EventUpdateForm(VersionedModelForm):
fields = [ fields = [
'name', 'name',
'slug', 'slug',
'locale',
'timezone',
'currency', 'currency',
'date_from', 'date_from',
'date_to', 'date_to',
'show_date_to',
'show_times',
'presale_start', 'presale_start',
'presale_end', '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): class EventUpdate(EventPermissionRequiredMixin, UpdateView):
model = Event model = Event
form_class = EventUpdateForm form_class = EventUpdateForm
template_name = 'pretixcontrol/event/settings.html' template_name = 'pretixcontrol/event/settings.html'
permission = 'can_change_settings' permission = 'can_change_settings'
def get_object(self, queryset=None) -> Event: @cached_property
def object(self) -> Event:
return self.request.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: def get_success_url(self) -> str:
return reverse('control:event.settings', kwargs={ return reverse('control:event.settings', kwargs={
'organizer': self.get_object().organizer.slug, 'organizer': self.object.organizer.slug,
'event': self.get_object().slug, 'event': self.object.slug,
}) + '?success=true' }) + '?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): class EventPlugins(EventPermissionRequiredMixin, TemplateView, SingleObjectMixin):
model = Event model = Event
@@ -33,7 +33,7 @@
{% trans "Login" %}</a> {% trans "Login" %}</a>
{% endif %} {% endif %}
</div> </div>
<h1>{{ event.name }} <small>{{ event.date_from|date }}{% if event.show_date_to %} {{ event.date_to|date }}{% endif %}</small></h1> <h1>{{ event.name }} <small>{{ event.date_from|date }}{% if event.settings.show_date_to %} {{ event.date_to|date }}{% endif %}</small></h1>
</div> </div>
{% if messages %} {% if messages %}
{% for message in messages %} {% for message in messages %}
+4 -4
View File
@@ -1,4 +1,4 @@
from datetime import timedelta from datetime import timedelta, datetime
from django.contrib import messages from django.contrib import messages
from django.core.urlresolvers import reverse from django.core.urlresolvers import reverse
from django.db import transaction from django.db import transaction
@@ -394,9 +394,9 @@ class OrderConfirm(EventViewMixin, CartDisplayMixin, EventLoginRequiredMixin, Ch
total = sum([c.price for c in cartpos]) total = sum([c.price for c in cartpos])
payment_fee = self.payment_provider.calculate_fee(total) payment_fee = self.payment_provider.calculate_fee(total)
total += payment_fee total += payment_fee
expires = [dt + timedelta(days=self.request.event.payment_term_days)] expires = [dt + timedelta(days=self.request.event.settings.get('payment_term_days', as_type=int))]
if self.request.event.payment_term_last: if self.request.event.settings.get('payment_term_last'):
expires.append(self.request.event.payment_term_last) expires.append(self.request.event.settings.get('payment_term_last', as_type=datetime))
order = Order.objects.create( order = Order.objects.create(
status=Order.STATUS_PENDING, status=Order.STATUS_PENDING,
event=self.request.event, event=self.request.event,