mirror of
https://github.com/pretix/pretix.git
synced 2026-05-05 15:14:04 +00:00
Add quick-start assistant for new users (#833)
* First draft for quick-setup * Add payment * Fix stripe w/o connect * cols * Add tests
This commit is contained in:
@@ -9,7 +9,9 @@ from django.utils.timezone import get_current_timezone_name
|
||||
from django.utils.translation import pgettext_lazy, ugettext_lazy as _
|
||||
from django_countries import Countries
|
||||
from django_countries.fields import LazyTypedChoiceField
|
||||
from i18nfield.forms import I18nFormField, I18nTextarea
|
||||
from i18nfield.forms import (
|
||||
I18nForm, I18nFormField, I18nFormSetMixin, I18nTextarea, I18nTextInput,
|
||||
)
|
||||
from pytz import common_timezones, timezone
|
||||
|
||||
from pretix.base.forms import I18nModelForm, PlaceholderValidator, SettingsForm
|
||||
@@ -21,6 +23,7 @@ from pretix.control.forms import (
|
||||
SplitDateTimePickerWidget,
|
||||
)
|
||||
from pretix.multidomain.urlreverse import build_absolute_uri
|
||||
from pretix.plugins.banktransfer.payment import BankTransfer
|
||||
from pretix.presale.style import get_fonts
|
||||
|
||||
|
||||
@@ -362,6 +365,8 @@ class EventSettingsForm(SettingsForm):
|
||||
)
|
||||
imprint_url = forms.URLField(
|
||||
label=_("Imprint URL"),
|
||||
help_text=_("This should point e.g. to a part of your website that has your contact details and legal "
|
||||
"information."),
|
||||
required=False,
|
||||
)
|
||||
confirm_text = I18nFormField(
|
||||
@@ -375,7 +380,7 @@ class EventSettingsForm(SettingsForm):
|
||||
contact_mail = forms.EmailField(
|
||||
label=_("Contact address"),
|
||||
required=False,
|
||||
help_text=_("Public email address for contacting the organizer")
|
||||
help_text=_("We'll show this publicly to allow attendees to contact you.")
|
||||
)
|
||||
cancel_allow_user = forms.BooleanField(
|
||||
label=_("Allow users to cancel unpaid orders"),
|
||||
@@ -1039,3 +1044,118 @@ class EventDeleteForm(forms.Form):
|
||||
code='slug_wrong',
|
||||
)
|
||||
return slug
|
||||
|
||||
|
||||
class QuickSetupForm(I18nForm):
|
||||
show_quota_left = forms.BooleanField(
|
||||
label=_("Show number of tickets left"),
|
||||
help_text=_("Publicly show how many tickets of a certain type are still available."),
|
||||
required=False
|
||||
)
|
||||
waiting_list_enabled = forms.BooleanField(
|
||||
label=_("Waiting list"),
|
||||
help_text=_("Once a ticket is sold out, people can add themselves to a waiting list. As soon as a ticket "
|
||||
"becomes available again, it will be reserved for the first person on the waiting list and this "
|
||||
"person will receive an email notification with a voucher that can be used to buy a ticket."),
|
||||
required=False
|
||||
)
|
||||
ticket_download = forms.BooleanField(
|
||||
label=_("Ticket downloads"),
|
||||
help_text=_("Your customers will be able to download their tickets in PDF format."),
|
||||
required=False
|
||||
)
|
||||
attendee_names_required = forms.BooleanField(
|
||||
label=_("Require all attendees to fill in their names"),
|
||||
help_text=_("By default, we will ask for names but not require them. You can turn this off completely in the "
|
||||
"settings."),
|
||||
required=False
|
||||
)
|
||||
imprint_url = forms.URLField(
|
||||
label=_("Imprint URL"),
|
||||
help_text=_("This should point e.g. to a part of your website that has your contact details and legal "
|
||||
"information."),
|
||||
required=False,
|
||||
)
|
||||
contact_mail = forms.EmailField(
|
||||
label=_("Contact address"),
|
||||
required=False,
|
||||
help_text=_("We'll show this publicly to allow attendees to contact you.")
|
||||
)
|
||||
total_quota = forms.IntegerField(
|
||||
label=_("Total capacity"),
|
||||
min_value=0,
|
||||
widget=forms.NumberInput(
|
||||
attrs={
|
||||
'placeholder': '∞'
|
||||
}
|
||||
),
|
||||
required=False
|
||||
)
|
||||
payment_stripe__enabled = forms.BooleanField(
|
||||
label=_("Payment via Stripe"),
|
||||
help_text=_("Stripe is an online payments processor supporting credit cards and lots of other payment options. "
|
||||
"To accept payments via Stripe, you will need to set up an account with them, which takes less "
|
||||
"than five minutes using their simple interface."),
|
||||
required=False
|
||||
)
|
||||
payment_banktransfer__enabled = forms.BooleanField(
|
||||
label=_("Payment by bank transfer"),
|
||||
help_text=_("Your customers will be instructed to wire the money to your account. You can then import your "
|
||||
"bank statements to process the payments within pretix, or mark them as paid manually."),
|
||||
required=False
|
||||
)
|
||||
payment_banktransfer_bank_details = BankTransfer.form_field(required=False)
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
self.obj = kwargs.pop('event', None)
|
||||
self.locales = self.obj.settings.get('locales') if self.obj else kwargs.pop('locales', None)
|
||||
kwargs['locales'] = self.locales
|
||||
super().__init__(*args, **kwargs)
|
||||
if not self.obj.settings.payment_stripe_connect_client_id:
|
||||
del self.fields['payment_stripe__enabled']
|
||||
self.fields['payment_banktransfer_bank_details'].required = False
|
||||
|
||||
|
||||
class QuickSetupProductForm(I18nForm):
|
||||
name = I18nFormField(
|
||||
max_length=255,
|
||||
label=_("Product name"),
|
||||
widget=I18nTextInput
|
||||
)
|
||||
default_price = forms.DecimalField(
|
||||
label=_("Price (optional)"),
|
||||
max_digits=7, decimal_places=2, required=False,
|
||||
localize=True,
|
||||
widget=forms.TextInput(
|
||||
attrs={
|
||||
'placeholder': _('Free')
|
||||
}
|
||||
),
|
||||
)
|
||||
quota = forms.IntegerField(
|
||||
label=_("Quantity available"),
|
||||
min_value=0,
|
||||
widget=forms.NumberInput(
|
||||
attrs={
|
||||
'placeholder': '∞'
|
||||
}
|
||||
),
|
||||
initial=100,
|
||||
required=False
|
||||
)
|
||||
|
||||
|
||||
class BaseQuickSetupProductFormSet(I18nFormSetMixin, forms.BaseFormSet):
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
event = kwargs.pop('event', None)
|
||||
if event:
|
||||
kwargs['locales'] = event.settings.get('locales')
|
||||
super().__init__(*args, **kwargs)
|
||||
|
||||
|
||||
QuickSetupProductFormSet = formset_factory(
|
||||
QuickSetupProductForm,
|
||||
formset=BaseQuickSetupProductFormSet,
|
||||
can_order=False, can_delete=True, extra=0
|
||||
)
|
||||
|
||||
@@ -40,6 +40,7 @@
|
||||
<script type="text/javascript" src="{% static "pretixcontrol/js/ui/question.js" %}"></script>
|
||||
<script type="text/javascript" src="{% static "pretixcontrol/js/ui/mail.js" %}"></script>
|
||||
<script type="text/javascript" src="{% static "pretixcontrol/js/ui/typeahead.js" %}"></script>
|
||||
<script type="text/javascript" src="{% static "pretixcontrol/js/ui/quicksetup.js" %}"></script>
|
||||
<script type="text/javascript" src="{% static "pretixbase/js/asynctask.js" %}"></script>
|
||||
<script type="text/javascript" src="{% static "pretixbase/js/asyncdownload.js" %}"></script>
|
||||
<script type="text/javascript" src="{% static "colorpicker/bootstrap-colorpicker.js" %}"></script>
|
||||
|
||||
@@ -0,0 +1,198 @@
|
||||
{% extends "pretixcontrol/event/base.html" %}
|
||||
{% load i18n %}
|
||||
{% load bootstrap3 %}
|
||||
{% load formset_tags %}
|
||||
{% block title %}{{ request.event.name }}{% endblock %}
|
||||
{% block content %}
|
||||
<div class="quick-setup-step">
|
||||
<div class="quick-icon">
|
||||
<span class="fa fa-fw fa-check-circle text-success"></span>
|
||||
</div>
|
||||
<div class="quick-content">
|
||||
|
||||
<h2>{% trans "Congratulations!" %}</h2>
|
||||
<p>
|
||||
<strong>{% trans "You just created an event!" %}</strong>
|
||||
</p>
|
||||
<p>
|
||||
{% blocktrans trimmed %}
|
||||
You can scroll down and create your first ticket products quickly, or you can use the navigation
|
||||
on the left to modify the settings of your event in much more detail.
|
||||
{% endblocktrans %}
|
||||
</p>
|
||||
<div class="clearfix"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<form action="" method="post" class="form-horizontal">
|
||||
{% csrf_token %}
|
||||
<fieldset class="quick-setup-step">
|
||||
<div class="quick-icon">
|
||||
<span class="fa fa-fw fa-ticket text-muted"></span>
|
||||
</div>
|
||||
<div class="quick-content">
|
||||
<legend>{% trans "Create ticket types" %}</legend>
|
||||
<div class="formset" data-formset data-formset-prefix="{{ formset.prefix }}">
|
||||
{{ formset.management_form }}
|
||||
{% bootstrap_formset_errors formset %}
|
||||
<div class="row hidden-sm hidden-xs" data-formset-form>
|
||||
<div class="col-md-6">
|
||||
<strong>{% trans "Ticket name" %}</strong>
|
||||
</div>
|
||||
<div class="col-md-3">
|
||||
<strong>{% trans "Price (optional)" %}</strong>
|
||||
</div>
|
||||
<div class="col-md-2">
|
||||
<strong>{% trans "Capacity (optional)" %}</strong>
|
||||
</div>
|
||||
</div>
|
||||
<div data-formset-body id="ticket-type-formset">
|
||||
{% for iform in formset %}
|
||||
<div class="row question-option-row" data-formset-form>
|
||||
<div class="sr-only">
|
||||
{{ iform.id }}
|
||||
{% bootstrap_field iform.DELETE form_group_class="" layout="inline" %}
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
{% bootstrap_form_errors iform %}
|
||||
{% bootstrap_field iform.name layout='inline' form_group_class="" %}
|
||||
</div>
|
||||
<div class="col-md-3">
|
||||
{% bootstrap_field iform.default_price addon_after=request.event.currency layout='inline' form_group_class="" %}
|
||||
</div>
|
||||
<div class="col-md-2">
|
||||
{% bootstrap_field iform.quota layout='inline' form_group_class="" %}
|
||||
</div>
|
||||
<div class="col-md-1 text-right">
|
||||
<button type="button" class="btn btn-danger" data-formset-delete-button>
|
||||
<i class="fa fa-trash"></i></button>
|
||||
</div>
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
<script type="form-template" data-formset-empty-form>
|
||||
{% escapescript %}
|
||||
<div class="row question-option-row" data-formset-form>
|
||||
<div class="sr-only">
|
||||
{{ formset.empty_form.id }}
|
||||
{% bootstrap_field formset.empty_form.DELETE form_group_class="" layout="inline" %}
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
{% bootstrap_field formset.empty_form.name layout='inline' form_group_class="" %}
|
||||
</div>
|
||||
<div class="col-md-3">
|
||||
{% bootstrap_field formset.empty_form.default_price addon_after=request.event.currency layout='inline' form_group_class="" %}
|
||||
</div>
|
||||
<div class="col-md-2">
|
||||
{% bootstrap_field formset.empty_form.quota layout='inline' form_group_class="" %}
|
||||
</div>
|
||||
<div class="col-md-1 text-right">
|
||||
<button type="button" class="btn btn-danger" data-formset-delete-button>
|
||||
<i class="fa fa-trash"></i></button>
|
||||
</div>
|
||||
</div>
|
||||
{% endescapescript %}
|
||||
</script>
|
||||
<div class="row question-option-row helper-width-100">
|
||||
<div class="col-md-6">
|
||||
<button type="button" class="btn btn-default" data-formset-add>
|
||||
<i class="fa fa-plus"></i> {% trans "Add a new ticket type" %}</button>
|
||||
</div>
|
||||
<div class="col-md-3">
|
||||
</div>
|
||||
<div class="col-md-3 form-inline form-quicksetup-total-capacity">
|
||||
<strong>{% trans "Total capacity:" %}</strong>
|
||||
<span id="total-capacity"></span>
|
||||
{% bootstrap_field form.total_quota layout="inline" field_class="sr-only" %}
|
||||
<a href="#" data-toggle="tooltip" title="{% trans 'You can set a limit on the total number of tickets sold for your event, regardless of the ticket type.' %}" id="total-capacity-edit">
|
||||
<span class="fa fa-edit"></span>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<p> </p>
|
||||
<p class="bigger">
|
||||
{% blocktrans trimmed %}
|
||||
If you want to use more advanced features like non-admission products, product variations, custom
|
||||
quotas, add-on products or want to modify your ticket types in more detail, you can later do so
|
||||
in the "Products" section in the navigation. Don't worry, you can change everything you input here.
|
||||
{% endblocktrans %}
|
||||
</p>
|
||||
<p> </p>
|
||||
</div>
|
||||
</fieldset>
|
||||
<fieldset class="quick-setup-step">
|
||||
<div class="quick-icon">
|
||||
<span class="fa fa-fw fa-wrench text-muted"></span>
|
||||
</div>
|
||||
<div class="quick-content">
|
||||
<legend>{% trans "Features" %}</legend>
|
||||
<p class="bigger">
|
||||
{% blocktrans trimmed %}
|
||||
We recommend that you take some time to go through the "Settings" part of your event, but if
|
||||
you're in a hurry and want to get started quickly, here's a short version:
|
||||
{% endblocktrans %}
|
||||
</p>
|
||||
{% bootstrap_field form.ticket_download layout="control" label_class="sr-only" field_class="col-md-12" %}
|
||||
{% bootstrap_field form.waiting_list_enabled layout="control" label_class="sr-only" field_class="col-md-12" %}
|
||||
{% bootstrap_field form.show_quota_left layout="control" label_class="sr-only" field_class="col-md-12" %}
|
||||
{% bootstrap_field form.attendee_names_required layout="control" label_class="sr-only" field_class="col-md-12" %}
|
||||
<p> </p>
|
||||
</div>
|
||||
</fieldset>
|
||||
<fieldset class="quick-setup-step" id="quick-setup-step-payment">
|
||||
<div class="quick-icon">
|
||||
<span class="fa fa-fw fa-money text-muted"></span>
|
||||
</div>
|
||||
<div class="quick-content">
|
||||
<legend>{% trans "Payment" %}</legend>
|
||||
<p class="bigger">
|
||||
{% blocktrans trimmed %}
|
||||
pretix supports a
|
||||
<a href="https://pretix.eu/about/en/features/payment" target="_blank">wide range of payment
|
||||
providers</a> allowing you to choose the payment methods that fit your workflow best.
|
||||
Here are just two of them as examples, you can add more in the "Settings" part of your event.
|
||||
{% endblocktrans %}
|
||||
</p>
|
||||
{% bootstrap_field form.payment_banktransfer__enabled layout="control" label_class="sr-only" field_class="col-md-12" %}
|
||||
<div data-display-dependency="#id_payment_banktransfer__enabled">
|
||||
{% bootstrap_field form.payment_banktransfer_bank_details layout="control" %}
|
||||
</div>
|
||||
{% if form.payment_stripe__enabled %}
|
||||
{% bootstrap_field form.payment_stripe__enabled layout="control" label_class="sr-only" field_class="col-md-12" %}
|
||||
<div data-display-dependency="#id_payment_stripe__enabled">
|
||||
<div class="alert alert-info">
|
||||
{% blocktrans trimmed %}
|
||||
After you saved this page, we will redirect you to Stripe to create or connect an account
|
||||
there. Once you completed this, you will be taken back to pretix.
|
||||
{% endblocktrans %}
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
<p> </p>
|
||||
</div>
|
||||
</fieldset>
|
||||
<fieldset class="quick-setup-step">
|
||||
<div class="quick-icon">
|
||||
<span class="fa fa-fw fa-envelope text-muted"></span>
|
||||
</div>
|
||||
<div class="quick-content">
|
||||
<legend>{% trans "Getting in touch with you" %}</legend>
|
||||
<p class="bigger">
|
||||
{% blocktrans trimmed %}
|
||||
In case something goes wrong or is unclear, we strongly suggest that you provide ways for your
|
||||
attendees to contact you:
|
||||
{% endblocktrans %}
|
||||
</p>
|
||||
{% bootstrap_field form.contact_mail layout="control" %}
|
||||
{% bootstrap_field form.imprint_url layout="control" %}
|
||||
</div>
|
||||
</fieldset>
|
||||
<div class="form-group submit-group">
|
||||
<button type="submit" class="btn btn-primary btn-save">
|
||||
{% trans "Save" %}
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
{% endblock %}
|
||||
@@ -73,6 +73,7 @@ urlpatterns = [
|
||||
name='event.requiredaction.discard'),
|
||||
url(r'^comment/$', event.EventComment.as_view(),
|
||||
name='event.comment'),
|
||||
url(r'^quickstart/$', event.QuickSetupView.as_view(), name='event.quick'),
|
||||
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'),
|
||||
|
||||
@@ -220,20 +220,11 @@ def welcome_wizard_widget(sender, **kwargs):
|
||||
|
||||
if not sender.items.exists():
|
||||
ctx.update({
|
||||
'subtitle': _('Get started by creating a product'),
|
||||
'text': _('The first thing you need for selling tickets to your event is one or more "products" your '
|
||||
'participants can choose from. A product can be a ticket or anything else that you want to sell, '
|
||||
'e.g. additional merchandise in form of t-shirts.'),
|
||||
'button_text': _('Create a first product'),
|
||||
'button_url': reverse('control:event.items.add', kwargs=kwargs)
|
||||
})
|
||||
elif not sender.quotas.exists():
|
||||
ctx.update({
|
||||
'subtitle': _('Create quotas that apply to your products'),
|
||||
'text': _('Your tickets will only be available for sale if you create a matching quota, i.e. if you tell '
|
||||
'pretix how many tickets it should sell for your event.'),
|
||||
'button_text': _('Create a first quota'),
|
||||
'button_url': reverse('control:event.items.quotas.add', kwargs=kwargs)
|
||||
'subtitle': _('Get started with our setup tool'),
|
||||
'text': _('To start selling tickets, you need to create products or quotas. The fastest way to create '
|
||||
'this is to use our setup tool.'),
|
||||
'button_text': _('Set up event'),
|
||||
'button_url': reverse('control:event.quick', kwargs=kwargs)
|
||||
})
|
||||
else:
|
||||
return []
|
||||
|
||||
@@ -41,13 +41,15 @@ from pretix.base.templatetags.money import money_filter
|
||||
from pretix.control.forms.event import (
|
||||
CommentForm, DisplaySettingsForm, EventDeleteForm, EventMetaValueForm,
|
||||
EventSettingsForm, EventUpdateForm, InvoiceSettingsForm, MailSettingsForm,
|
||||
PaymentSettingsForm, ProviderForm, TaxRuleForm, TaxRuleLineFormSet,
|
||||
PaymentSettingsForm, ProviderForm, QuickSetupForm,
|
||||
QuickSetupProductFormSet, TaxRuleForm, TaxRuleLineFormSet,
|
||||
TicketSettingsForm, WidgetCodeForm,
|
||||
)
|
||||
from pretix.control.permissions import EventPermissionRequiredMixin
|
||||
from pretix.control.signals import nav_event_settings
|
||||
from pretix.helpers.urls import build_absolute_uri
|
||||
from pretix.multidomain.urlreverse import get_domain
|
||||
from pretix.plugins.stripe.payment import StripeSettingsHolder
|
||||
from pretix.presale.style import regenerate_css
|
||||
|
||||
from . import CreateView, PaginationMixin, UpdateView
|
||||
@@ -1120,3 +1122,154 @@ class WidgetSettings(EventSettingsViewMixin, EventPermissionRequiredMixin, FormV
|
||||
domain = '%s:%d' % (domain, siteurlsplit.port)
|
||||
ctx['urlprefix'] = '%s://%s' % (siteurlsplit.scheme, domain)
|
||||
return ctx
|
||||
|
||||
|
||||
class QuickSetupView(FormView):
|
||||
template_name = 'pretixcontrol/event/quick_setup.html'
|
||||
permission = 'can_change_event_settings'
|
||||
form_class = QuickSetupForm
|
||||
|
||||
def dispatch(self, request, *args, **kwargs):
|
||||
if request.event.items.exists() or request.event.quotas.exists():
|
||||
messages.info(request, _('Your event is not empty, you need to set it up manually.'))
|
||||
return redirect(reverse('control:event.index', kwargs={
|
||||
'organizer': request.event.organizer.slug,
|
||||
'event': request.event.slug
|
||||
}))
|
||||
return super().dispatch(request, *args, **kwargs)
|
||||
|
||||
def get_form_kwargs(self):
|
||||
kwargs = super().get_form_kwargs()
|
||||
kwargs['event'] = self.request.event
|
||||
return kwargs
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
ctx = super().get_context_data()
|
||||
ctx['formset'] = self.formset
|
||||
return ctx
|
||||
|
||||
def get_initial(self):
|
||||
return {
|
||||
'waiting_list_enabled': True,
|
||||
'ticket_download': True,
|
||||
'contact_mail': self.request.event.settings.contact_mail,
|
||||
'imprint_url': self.request.event.settings.imprint_url,
|
||||
}
|
||||
|
||||
def post(self, request, *args, **kwargs):
|
||||
form = self.get_form()
|
||||
if form.is_valid() and self.formset.is_valid():
|
||||
return self.form_valid(form)
|
||||
else:
|
||||
return self.form_invalid(form)
|
||||
|
||||
@transaction.atomic
|
||||
def form_valid(self, form):
|
||||
plugins_active = self.request.event.get_plugins()
|
||||
if form.cleaned_data['ticket_download']:
|
||||
if 'pretix.plugins.ticketoutputpdf' not in plugins_active:
|
||||
self.request.event.log_action('pretix.event.plugins.enabled', user=self.request.user,
|
||||
data={'plugin': 'pretix.plugins.ticketoutputpdf'})
|
||||
plugins_active.append('pretix.plugins.ticketoutputpdf')
|
||||
self.request.event.settings.ticket_download = True
|
||||
self.request.event.settings.ticketoutput_pdf__enabled = True
|
||||
|
||||
if form.cleaned_data['payment_banktransfer__enabled']:
|
||||
if 'pretix.plugins.banktransfer' not in plugins_active:
|
||||
self.request.event.log_action('pretix.event.plugins.enabled', user=self.request.user,
|
||||
data={'plugin': 'pretix.plugins.banktransfer'})
|
||||
plugins_active.append('pretix.plugins.banktransfer')
|
||||
self.request.event.settings.payment_banktransfer__enabled = True
|
||||
self.request.event.settings.payment_banktransfer_bank_details = form.cleaned_data['payment_banktransfer_bank_details']
|
||||
|
||||
if form.cleaned_data.get('payment_stripe__enabled', None):
|
||||
if 'pretix.plugins.stripe' not in plugins_active:
|
||||
self.request.event.log_action('pretix.event.plugins.enabled', user=self.request.user,
|
||||
data={'plugin': 'pretix.plugins.stripe'})
|
||||
plugins_active.append('pretix.plugins.stripe')
|
||||
|
||||
self.request.event.settings.show_quota_left = form.cleaned_data['show_quota_left']
|
||||
self.request.event.settings.waiting_list_enabled = form.cleaned_data['waiting_list_enabled']
|
||||
self.request.event.settings.attendee_names_required = form.cleaned_data['attendee_names_required']
|
||||
self.request.event.settings.contact_mail = form.cleaned_data['contact_mail']
|
||||
self.request.event.settings.imprint_url = form.cleaned_data['imprint_url']
|
||||
self.request.event.log_action('pretix.event.settings', user=self.request.user, data={
|
||||
k: self.request.event.settings.get(k) for k in form.changed_data
|
||||
})
|
||||
|
||||
items = []
|
||||
category = None
|
||||
tax_rule = self.request.event.tax_rules.first()
|
||||
if any(f not in self.formset.deleted_forms for f in self.formset):
|
||||
category = self.request.event.categories.create(
|
||||
name=LazyI18nString.from_gettext(ugettext('Tickets'))
|
||||
)
|
||||
category.log_action('pretix.event.category.added', data={'name': ugettext('Tickets')},
|
||||
user=self.request.user)
|
||||
|
||||
for i, f in enumerate(self.formset):
|
||||
if f in self.formset.deleted_forms:
|
||||
continue
|
||||
|
||||
item = self.request.event.items.create(
|
||||
name=f.cleaned_data['name'],
|
||||
category=category,
|
||||
active=True,
|
||||
default_price=f.cleaned_data['default_price'] or 0,
|
||||
tax_rule=tax_rule,
|
||||
admission=True,
|
||||
position=i,
|
||||
)
|
||||
item.log_action('pretix.event.item.added', user=self.request.user, data=dict(f.cleaned_data))
|
||||
if f.cleaned_data['quota'] or not form.cleaned_data['total_quota']:
|
||||
quota = self.request.event.quotas.create(
|
||||
name=str(f.cleaned_data['name']),
|
||||
size=f.cleaned_data['quota'],
|
||||
)
|
||||
quota.log_action('pretix.event.quota.added', user=self.request.user, data=dict(f.cleaned_data))
|
||||
quota.items.add(item)
|
||||
items.append(item)
|
||||
|
||||
if form.cleaned_data['total_quota']:
|
||||
quota = self.request.event.quotas.create(
|
||||
name=ugettext('Tickets'),
|
||||
size=form.cleaned_data['total_quota']
|
||||
)
|
||||
quota.log_action('pretix.event.quota.added', user=self.request.user, data={
|
||||
'name': ugettext('Tickets'),
|
||||
'size': quota.size
|
||||
})
|
||||
quota.items.add(*items)
|
||||
|
||||
self.request.event.plugins = ",".join(plugins_active)
|
||||
self.request.event.save()
|
||||
messages.success(self.request, _('Your changes have been saved. You can now go on with looking at the details '
|
||||
'or take your event live to start selling!'))
|
||||
|
||||
if form.cleaned_data.get('payment_stripe__enabled', False):
|
||||
self.request.session['payment_stripe_oauth_enable'] = True
|
||||
return redirect(StripeSettingsHolder(self.request.event).get_connect_url(self.request))
|
||||
|
||||
return redirect(reverse('control:event.index', kwargs={
|
||||
'organizer': self.request.event.organizer.slug,
|
||||
'event': self.request.event.slug,
|
||||
}))
|
||||
|
||||
@cached_property
|
||||
def formset(self):
|
||||
return QuickSetupProductFormSet(
|
||||
data=self.request.POST if self.request.method == "POST" else None,
|
||||
event=self.request.event,
|
||||
initial=[
|
||||
{
|
||||
'name': LazyI18nString.from_gettext(ugettext('Regular ticket')),
|
||||
'default_price': Decimal('35.00'),
|
||||
'quota': 100,
|
||||
},
|
||||
{
|
||||
'name': LazyI18nString.from_gettext(ugettext('Reduced ticket')),
|
||||
'default_price': Decimal('29.00'),
|
||||
'quota': 50,
|
||||
},
|
||||
]
|
||||
)
|
||||
|
||||
@@ -208,10 +208,16 @@ class EventWizard(SessionWizardView):
|
||||
event.settings.set('locale', basics_data['locale'])
|
||||
event.settings.set('locales', foundation_data['locales'])
|
||||
|
||||
return redirect(reverse('control:event.settings', kwargs={
|
||||
'organizer': event.organizer.slug,
|
||||
'event': event.slug,
|
||||
}) + '?congratulations=1')
|
||||
if (copy_data and copy_data['copy_from_event']) or event.has_subevents:
|
||||
return redirect(reverse('control:event.settings', kwargs={
|
||||
'organizer': event.organizer.slug,
|
||||
'event': event.slug,
|
||||
}) + '?congratulations=1')
|
||||
else:
|
||||
return redirect(reverse('control:event.quick', kwargs={
|
||||
'organizer': event.organizer.slug,
|
||||
'event': event.slug,
|
||||
}) + '?congratulations=1')
|
||||
|
||||
|
||||
class SlugRNG(OrganizerPermissionRequiredMixin, View):
|
||||
|
||||
@@ -14,9 +14,9 @@ class BankTransfer(BasePaymentProvider):
|
||||
identifier = 'banktransfer'
|
||||
verbose_name = _('Bank transfer')
|
||||
|
||||
@property
|
||||
def settings_form_fields(self):
|
||||
form_field = I18nFormField(
|
||||
@staticmethod
|
||||
def form_field(**kwargs):
|
||||
return I18nFormField(
|
||||
label=_('Bank account details'),
|
||||
widget=I18nTextarea,
|
||||
help_text=_('Include everything that your customers need to send you a bank transfer payment. Within SEPA '
|
||||
@@ -30,10 +30,14 @@ class BankTransfer(BasePaymentProvider):
|
||||
'Account owner: John Doe\n'
|
||||
'Name of Bank: Professional Banking Institute Ltd., London'
|
||||
)
|
||||
}}
|
||||
}},
|
||||
**kwargs
|
||||
)
|
||||
|
||||
@property
|
||||
def settings_form_fields(self):
|
||||
d = OrderedDict(
|
||||
list(super().settings_form_fields.items()) + [('bank_details', form_field)]
|
||||
list(super().settings_form_fields.items()) + [('bank_details', self.form_field())]
|
||||
)
|
||||
d.move_to_end('bank_details', last=False)
|
||||
d.move_to_end('_enabled', last=False)
|
||||
|
||||
@@ -51,25 +51,31 @@ class StripeSettingsHolder(BasePaymentProvider):
|
||||
super().__init__(event)
|
||||
self.settings = SettingsSandbox('payment', 'stripe', event)
|
||||
|
||||
def get_connect_url(self, request):
|
||||
request.session['payment_stripe_oauth_event'] = request.event.pk
|
||||
if 'payment_stripe_oauth_token' not in request.session:
|
||||
request.session['payment_stripe_oauth_token'] = get_random_string(32)
|
||||
return (
|
||||
"https://connect.stripe.com/oauth/authorize?response_type=code&client_id={}&state={}"
|
||||
"&scope=read_write&redirect_uri={}"
|
||||
).format(
|
||||
self.settings.connect_client_id,
|
||||
request.session['payment_stripe_oauth_token'],
|
||||
urlquote(build_global_uri('plugins:stripe:oauth.return')),
|
||||
)
|
||||
|
||||
def settings_content_render(self, request):
|
||||
if self.settings.connect_client_id and not self.settings.secret_key:
|
||||
# Use Stripe connect
|
||||
if not self.settings.connect_user_id:
|
||||
request.session['payment_stripe_oauth_event'] = request.event.pk
|
||||
if 'payment_stripe_oauth_token' not in request.session:
|
||||
request.session['payment_stripe_oauth_token'] = get_random_string(32)
|
||||
|
||||
return (
|
||||
"<p>{}</p>"
|
||||
"<a href='https://connect.stripe.com/oauth/authorize?response_type=code&client_id={}&state={}"
|
||||
"&scope=read_write&redirect_uri={}' class='btn btn-primary btn-lg'>{}</a>"
|
||||
"<a href='{}' class='btn btn-primary btn-lg'>{}</a>"
|
||||
).format(
|
||||
_('To accept payments via Stripe, you will need an account at Stripe. By clicking on the '
|
||||
'following button, you can either create a new Stripe account connect pretix to an existing '
|
||||
'one.'),
|
||||
self.settings.connect_client_id,
|
||||
request.session['payment_stripe_oauth_token'],
|
||||
urlquote(build_global_uri('plugins:stripe:oauth.return')),
|
||||
self.get_connect_url(request),
|
||||
_('Connect with Stripe')
|
||||
)
|
||||
else:
|
||||
|
||||
@@ -93,6 +93,10 @@ def oauth_return(request, *args, **kwargs):
|
||||
event.settings.payment_stripe_connect_user_id = data['stripe_user_id']
|
||||
event.settings.payment_stripe_connect_user_name = account['business_name']
|
||||
|
||||
if request.session.get('payment_stripe_oauth_enable', False):
|
||||
event.settings.payment_stripe__enabled = True
|
||||
del request.session['payment_stripe_oauth_enable']
|
||||
|
||||
return redirect(reverse('control:event.settings.payment.provider', kwargs={
|
||||
'organizer': event.organizer.slug,
|
||||
'event': event.slug,
|
||||
|
||||
@@ -206,15 +206,19 @@ var form_handlers = function (el) {
|
||||
dependency.on("change", update);
|
||||
});
|
||||
|
||||
$("input[data-display-dependency]").each(function () {
|
||||
$("div[data-display-dependency], input[data-display-dependency]").each(function () {
|
||||
var dependent = $(this),
|
||||
dependency = $($(this).attr("data-display-dependency")),
|
||||
update = function (ev) {
|
||||
var enabled = (dependency.attr("type") === 'checkbox' || dependency.attr("type") === 'radio') ? dependency.prop('checked') : !!dependency.val();
|
||||
var $toggling = dependent;
|
||||
if (dependent.tagName === "input") {
|
||||
$toggling = dependent.closest('.form-group');
|
||||
}
|
||||
if (ev) {
|
||||
dependent.closest('.form-group').slideToggle(enabled);
|
||||
$toggling.stop().slideToggle(enabled);
|
||||
} else {
|
||||
dependent.closest('.form-group').toggle(enabled);
|
||||
$toggling.stop().toggle(enabled);
|
||||
}
|
||||
};
|
||||
update();
|
||||
|
||||
50
src/pretix/static/pretixcontrol/js/ui/quicksetup.js
Normal file
50
src/pretix/static/pretixcontrol/js/ui/quicksetup.js
Normal file
@@ -0,0 +1,50 @@
|
||||
$(function () {
|
||||
"use strict";
|
||||
|
||||
var ticket_type_quota_calculation = function () {
|
||||
var sum = 0;
|
||||
$("#ticket-type-formset div[data-formset-form]").each(function () {
|
||||
if (!$(this).find("input[name$=DELETE]").prop("checked")) {
|
||||
var val = $(this).find("input[name$=quota]").val();
|
||||
if (val === "") {
|
||||
sum = "∞";
|
||||
} else if (sum !== "∞") {
|
||||
sum += parseInt(val);
|
||||
}
|
||||
}
|
||||
});
|
||||
$("#total-capacity").text(sum);
|
||||
};
|
||||
|
||||
var toggle_payment = function () {
|
||||
var any = false;
|
||||
$("#ticket-type-formset div[data-formset-form]").each(function () {
|
||||
if (!$(this).find("input[name$=DELETE]").prop("checked")) {
|
||||
var val = $(this).find("input[name$=default_price]").val();
|
||||
if (/.*[1-9].*/.test(val)) {
|
||||
any = true;
|
||||
}
|
||||
}
|
||||
});
|
||||
if ($("#quick-setup-step-payment:visible").length && !any) {
|
||||
$("#quick-setup-step-payment").stop().slideUp();
|
||||
} else if (!$("#quick-setup-step-payment:visible").length && any) {
|
||||
$("#quick-setup-step-payment").stop().slideDown();
|
||||
}
|
||||
};
|
||||
|
||||
$("#ticket-type-formset").bind("formAdded", ticket_type_quota_calculation);
|
||||
$("#ticket-type-formset").on("change keyup keydown keypress", "input", function () {
|
||||
ticket_type_quota_calculation();
|
||||
toggle_payment();
|
||||
});
|
||||
ticket_type_quota_calculation();
|
||||
toggle_payment();
|
||||
|
||||
$("#total-capacity-edit").click(function () {
|
||||
$("#id_total_quota").val(parseInt($("#total-capacity").text()));
|
||||
$("#total-capacity").hide();
|
||||
$("#id_total_quota").closest("div").removeClass("sr-only");
|
||||
$("#total-capacity-edit").hide();
|
||||
});
|
||||
});
|
||||
@@ -281,3 +281,18 @@ table td > .checkbox input[type="checkbox"] {
|
||||
.panel-title .radio {
|
||||
margin-left: 20px;
|
||||
}
|
||||
|
||||
.form-quicksetup-total-capacity {
|
||||
height: 34px;
|
||||
strong {
|
||||
line-height: 34px;
|
||||
}
|
||||
}
|
||||
.form-horizontal [data-formset] .form-quicksetup-total-capacity .form-group {
|
||||
margin: 0;
|
||||
width: auto;
|
||||
}
|
||||
.form-quicksetup-total-capacity .form-control {
|
||||
width: 100px;
|
||||
display: inline;
|
||||
}
|
||||
|
||||
@@ -128,6 +128,10 @@ h1 .btn-sm {
|
||||
padding-top: 20px;
|
||||
}
|
||||
|
||||
p.bigger {
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.helper-display-block {
|
||||
display: block !important;
|
||||
}
|
||||
@@ -468,7 +472,33 @@ body.loading #wrapper {
|
||||
text-decoration: none;
|
||||
}
|
||||
}
|
||||
.quick-setup-step {
|
||||
clear: both;
|
||||
.quick-icon {
|
||||
float: left;
|
||||
width: 100px;
|
||||
|
||||
.fa-ticket, .fa-check-circle {
|
||||
margin-top: -20px;
|
||||
}
|
||||
.fa-wrench {
|
||||
margin-top: -30px;
|
||||
}
|
||||
.fa-money, .fa-envelope {
|
||||
margin-top: -40px;
|
||||
}
|
||||
}
|
||||
.quick-icon .fa {
|
||||
font-size: 100px;
|
||||
line-height: 170px;
|
||||
display: block;
|
||||
}
|
||||
.quick-content {
|
||||
margin-left: 160px;
|
||||
padding-top: 5px;
|
||||
overflow: hidden;
|
||||
}
|
||||
}
|
||||
.thank-you {
|
||||
margin-bottom: 25px;
|
||||
|
||||
@@ -503,6 +533,16 @@ body.loading #wrapper {
|
||||
}
|
||||
}
|
||||
}
|
||||
@media (max-width: $screen-md-max) {
|
||||
.quick-setup-step {
|
||||
.quick-icon {
|
||||
display: none;
|
||||
}
|
||||
.quick-content {
|
||||
margin-left: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
@media (max-width: $screen-sm-max) {
|
||||
.thank-you {
|
||||
text-align: center;
|
||||
|
||||
@@ -11,7 +11,10 @@ class SoupTest(TestCase):
|
||||
def post_doc(self, *args, **kwargs):
|
||||
kwargs['follow'] = True
|
||||
response = self.client.post(*args, **kwargs)
|
||||
return BeautifulSoup(response.rendered_content, "lxml")
|
||||
try:
|
||||
return BeautifulSoup(response.rendered_content, "lxml")
|
||||
except AttributeError:
|
||||
return BeautifulSoup(response.content, "lxml")
|
||||
|
||||
|
||||
def extract_form_fields(soup):
|
||||
@@ -36,7 +39,7 @@ def extract_form_fields(soup):
|
||||
|
||||
# textareas
|
||||
for textarea in soup.findAll('textarea'):
|
||||
data[textarea['name']] = textarea.string or ''
|
||||
data[textarea['name']] = textarea.text or ''
|
||||
|
||||
# select fields
|
||||
for select in soup.find_all('select'):
|
||||
|
||||
@@ -48,6 +48,151 @@ class EventsTest(SoupTest):
|
||||
self.assertNotIn("31C3", tabletext)
|
||||
self.assertNotIn("MRMCD14", tabletext)
|
||||
|
||||
def test_quick_setup_later(self):
|
||||
self.event1.quotas.create(name='foo', size=2)
|
||||
resp = self.client.get('/control/event/%s/%s/quickstart/' % (self.orga1.slug, self.event1.slug))
|
||||
self.assertRedirects(resp, '/control/event/%s/%s/' % (self.orga1.slug, self.event1.slug))
|
||||
|
||||
def test_quick_setup_total_quota(self):
|
||||
doc = self.get_doc('/control/event/%s/%s/quickstart/' % (self.orga1.slug, self.event1.slug))
|
||||
doc.select("[name=show_quota_left]")[0]['checked'] = "checked"
|
||||
doc.select("[name=ticket_download]")[0]['checked'] = "checked"
|
||||
doc.select("[name=contact_mail]")[0]['value'] = "test@example.org"
|
||||
doc.select("[name=payment_banktransfer__enabled]")[0]['checked'] = "checked"
|
||||
doc.select("[name*=payment_banktransfer_bank_details]")[0].contents[0].replace_with("Foo")
|
||||
doc.select("[name=total_quota]")[0]['value'] = "300"
|
||||
doc.select("[name=form-TOTAL_FORMS]")[0]['value'] = "2"
|
||||
doc.select("[name=form-INITIAL_FORMS]")[0]['value'] = "2"
|
||||
doc.select("[name=form-MIN_NUM_FORMS]")[0]['value'] = "0"
|
||||
doc.select("[name=form-MAX_NUM_FORMS]")[0]['value'] = "1000"
|
||||
doc.select("[name=form-0-name_0]")[0]['value'] = "Normal ticket"
|
||||
doc.select("[name=form-0-default_price]")[0]['value'] = "13.90"
|
||||
doc.select("[name=form-0-quota]")[0]['value'] = ""
|
||||
doc.select("[name=form-1-name_0]")[0]['value'] = "Reduced ticket"
|
||||
doc.select("[name=form-1-default_price]")[0]['value'] = "13.20"
|
||||
doc.select("[name=form-1-quota]")[0]['value'] = ""
|
||||
|
||||
doc = self.post_doc('/control/event/%s/%s/quickstart/' % (self.orga1.slug, self.event1.slug),
|
||||
extract_form_fields(doc.select('.container-fluid form')[0]))
|
||||
assert len(doc.select(".alert-success")) > 0
|
||||
self.event1.refresh_from_db()
|
||||
self.event1.settings.flush()
|
||||
assert self.event1.settings.show_quota_left
|
||||
assert self.event1.settings.contact_mail == "test@example.org"
|
||||
assert self.event1.settings.ticket_download
|
||||
assert self.event1.settings.ticketoutput_pdf__enabled
|
||||
assert self.event1.settings.payment_banktransfer__enabled
|
||||
assert self.event1.settings.get('payment_banktransfer_bank_details', as_type=LazyI18nString).localize('en') == "Foo"
|
||||
assert 'pretix.plugins.banktransfer' in self.event1.plugins
|
||||
assert self.event1.items.count() == 2
|
||||
i = self.event1.items.first()
|
||||
assert str(i.name) == "Normal ticket"
|
||||
assert i.default_price == Decimal('13.90')
|
||||
i = self.event1.items.last()
|
||||
assert str(i.name) == "Reduced ticket"
|
||||
assert i.default_price == Decimal('13.20')
|
||||
assert self.event1.quotas.count() == 1
|
||||
q = self.event1.quotas.first()
|
||||
assert q.name == 'Tickets'
|
||||
assert q.size == 300
|
||||
assert q.items.count() == 2
|
||||
|
||||
def test_quick_setup_single_quota(self):
|
||||
doc = self.get_doc('/control/event/%s/%s/quickstart/' % (self.orga1.slug, self.event1.slug))
|
||||
doc.select("[name=show_quota_left]")[0]['checked'] = "checked"
|
||||
doc.select("[name=ticket_download]")[0]['checked'] = "checked"
|
||||
doc.select("[name=contact_mail]")[0]['value'] = "test@example.org"
|
||||
doc.select("[name=payment_banktransfer__enabled]")[0]['checked'] = "checked"
|
||||
doc.select("[name*=payment_banktransfer_bank_details]")[0].contents[0].replace_with("Foo")
|
||||
doc.select("[name=total_quota]")[0]['value'] = ""
|
||||
doc.select("[name=form-TOTAL_FORMS]")[0]['value'] = "2"
|
||||
doc.select("[name=form-INITIAL_FORMS]")[0]['value'] = "2"
|
||||
doc.select("[name=form-MIN_NUM_FORMS]")[0]['value'] = "0"
|
||||
doc.select("[name=form-MAX_NUM_FORMS]")[0]['value'] = "1000"
|
||||
doc.select("[name=form-0-name_0]")[0]['value'] = "Normal ticket"
|
||||
doc.select("[name=form-0-default_price]")[0]['value'] = "13.90"
|
||||
doc.select("[name=form-0-quota]")[0]['value'] = "100"
|
||||
doc.select("[name=form-1-name_0]")[0]['value'] = "Reduced ticket"
|
||||
doc.select("[name=form-1-default_price]")[0]['value'] = "13.20"
|
||||
doc.select("[name=form-1-quota]")[0]['value'] = "50"
|
||||
|
||||
doc = self.post_doc('/control/event/%s/%s/quickstart/' % (self.orga1.slug, self.event1.slug),
|
||||
extract_form_fields(doc.select('.container-fluid form')[0]))
|
||||
assert len(doc.select(".alert-success")) > 0
|
||||
self.event1.refresh_from_db()
|
||||
self.event1.settings.flush()
|
||||
assert self.event1.settings.show_quota_left
|
||||
assert self.event1.settings.contact_mail == "test@example.org"
|
||||
assert self.event1.settings.ticket_download
|
||||
assert self.event1.settings.ticketoutput_pdf__enabled
|
||||
assert self.event1.settings.payment_banktransfer__enabled
|
||||
assert self.event1.settings.get('payment_banktransfer_bank_details', as_type=LazyI18nString).localize('en') == "Foo"
|
||||
assert 'pretix.plugins.banktransfer' in self.event1.plugins
|
||||
assert self.event1.items.count() == 2
|
||||
i = self.event1.items.first()
|
||||
assert str(i.name) == "Normal ticket"
|
||||
assert i.default_price == Decimal('13.90')
|
||||
i = self.event1.items.last()
|
||||
assert str(i.name) == "Reduced ticket"
|
||||
assert i.default_price == Decimal('13.20')
|
||||
assert self.event1.quotas.count() == 2
|
||||
q = self.event1.quotas.first()
|
||||
assert q.name == 'Normal ticket'
|
||||
assert q.size == 100
|
||||
assert q.items.count() == 1
|
||||
q = self.event1.quotas.last()
|
||||
assert q.name == 'Reduced ticket'
|
||||
assert q.size == 50
|
||||
assert q.items.count() == 1
|
||||
|
||||
def test_quick_setup_dual_quota(self):
|
||||
doc = self.get_doc('/control/event/%s/%s/quickstart/' % (self.orga1.slug, self.event1.slug))
|
||||
doc.select("[name=show_quota_left]")[0]['checked'] = "checked"
|
||||
doc.select("[name=ticket_download]")[0]['checked'] = "checked"
|
||||
doc.select("[name=contact_mail]")[0]['value'] = "test@example.org"
|
||||
doc.select("[name=payment_banktransfer__enabled]")[0]['checked'] = "checked"
|
||||
doc.select("[name*=payment_banktransfer_bank_details]")[0].contents[0].replace_with("Foo")
|
||||
doc.select("[name=total_quota]")[0]['value'] = "120"
|
||||
doc.select("[name=form-TOTAL_FORMS]")[0]['value'] = "2"
|
||||
doc.select("[name=form-INITIAL_FORMS]")[0]['value'] = "2"
|
||||
doc.select("[name=form-MIN_NUM_FORMS]")[0]['value'] = "0"
|
||||
doc.select("[name=form-MAX_NUM_FORMS]")[0]['value'] = "1000"
|
||||
doc.select("[name=form-0-name_0]")[0]['value'] = "Normal ticket"
|
||||
doc.select("[name=form-0-default_price]")[0]['value'] = "13.90"
|
||||
doc.select("[name=form-0-quota]")[0]['value'] = "100"
|
||||
doc.select("[name=form-1-name_0]")[0]['value'] = "Reduced ticket"
|
||||
doc.select("[name=form-1-default_price]")[0]['value'] = "13.20"
|
||||
doc.select("[name=form-1-quota]")[0]['value'] = "50"
|
||||
|
||||
doc = self.post_doc('/control/event/%s/%s/quickstart/' % (self.orga1.slug, self.event1.slug),
|
||||
extract_form_fields(doc.select('.container-fluid form')[0]))
|
||||
assert len(doc.select(".alert-success")) > 0
|
||||
self.event1.refresh_from_db()
|
||||
self.event1.settings.flush()
|
||||
assert self.event1.settings.show_quota_left
|
||||
assert self.event1.settings.contact_mail == "test@example.org"
|
||||
assert self.event1.settings.ticket_download
|
||||
assert self.event1.settings.ticketoutput_pdf__enabled
|
||||
assert self.event1.settings.payment_banktransfer__enabled
|
||||
assert self.event1.settings.get('payment_banktransfer_bank_details', as_type=LazyI18nString).localize('en') == "Foo"
|
||||
assert 'pretix.plugins.banktransfer' in self.event1.plugins
|
||||
assert self.event1.items.count() == 2
|
||||
i = self.event1.items.first()
|
||||
assert str(i.name) == "Normal ticket"
|
||||
assert i.default_price == Decimal('13.90')
|
||||
i = self.event1.items.last()
|
||||
assert str(i.name) == "Reduced ticket"
|
||||
assert i.default_price == Decimal('13.20')
|
||||
assert self.event1.quotas.count() == 3
|
||||
q = self.event1.quotas.first()
|
||||
assert q.name == 'Normal ticket'
|
||||
assert q.size == 100
|
||||
assert q.items.count() == 1
|
||||
q = self.event1.quotas.last()
|
||||
assert q.name == 'Tickets'
|
||||
assert q.size == 120
|
||||
assert q.items.count() == 2
|
||||
|
||||
def test_settings(self):
|
||||
doc = self.get_doc('/control/event/%s/%s/settings/' % (self.orga1.slug, self.event1.slug))
|
||||
doc.select("[name=date_to_0]")[0]['value'] = "2013-12-30"
|
||||
|
||||
Reference in New Issue
Block a user