mirror of
https://github.com/pretix/pretix.git
synced 2026-05-05 15:14:04 +00:00
Add sub-events and relative date settings (#503)
* Data model * little crud * SubEventItemForm etc * Drop SubEventItem.active, quota editor * Fix failing tests * First frontend stuff * Addons form stuff * Quota calculation * net price display on EventIndex * Add tests, solve some bugs * Correct quota selection in more places, consolidate pricing logic * Fix failing quota tests * Fix TypeError * Add tests for checkout * Fixed a bug in QuotaForm * Prevent immutable cart if a quota was removed from an item * Add tests for pricing * Handle waiting list * Filter in check-in list * Fixed import lost in rebase * Fix waiting list widget * Voucher management * Voucher redemption * Fix broken tests * Add subevents to OrderChangeManager * Create a subevent during event creation * Fix bulk voucher creation * Introduce subevent.active * Copy from for subevents * Show active in list * ICal download for subevents * Check start and end of presale * Failing tests / show cart logic * Test * Rebase migrations * REST API integration of sub-events * Integrate quota calculation into the traditional quota form * Make subevent argument to add_position optional * Log-display foo * pretixdroid and subevents * Filter by subevent * Add more tests * Some mor tests * Rebase fixes * More tests * Relative dates * Restrict selection in relative datetime widgets * Filter subevent list * Re-label has_subevents * Rebase fixes, subevents in calendar view * Performance and caching issues * Refactor calendar templates * Permission tests * Calendar fixes and month selection * subevent selection * Rename subevents to dates * Add tests for calendar views
This commit is contained in:
@@ -10,6 +10,7 @@ from pytz import common_timezones, timezone
|
||||
|
||||
from pretix.base.forms import I18nModelForm, PlaceholderValidator, SettingsForm
|
||||
from pretix.base.models import Event, Organizer
|
||||
from pretix.base.reldate import RelativeDateField, RelativeDateTimeField
|
||||
from pretix.control.forms import ExtFileField
|
||||
|
||||
|
||||
@@ -20,6 +21,15 @@ class EventWizardFoundationForm(forms.Form):
|
||||
widget=forms.CheckboxSelectMultiple,
|
||||
help_text=_('Choose all languages that your event should be available in.')
|
||||
)
|
||||
has_subevents = forms.BooleanField(
|
||||
label=_("This is an event series"),
|
||||
help_text=_('Only recommended for advanced users. If this feature is enabled, this will not only be a '
|
||||
'single event but a series of very similar events that are handled within a single shop. '
|
||||
'The single events inside the series can only differ in date, time, location, prices and '
|
||||
'quotas, but not in other settings, and buying tickets across multiple of these events at '
|
||||
'the same time is possible. You cannot change this setting for this event later.'),
|
||||
required=False,
|
||||
)
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
self.user = kwargs.pop('user')
|
||||
@@ -72,10 +82,15 @@ class EventWizardBasicsForm(I18nModelForm):
|
||||
def __init__(self, *args, **kwargs):
|
||||
self.organizer = kwargs.pop('organizer')
|
||||
self.locales = kwargs.get('locales')
|
||||
self.has_subevents = kwargs.pop('has_subevents')
|
||||
kwargs.pop('user')
|
||||
super().__init__(*args, **kwargs)
|
||||
self.initial['timezone'] = get_current_timezone_name()
|
||||
self.fields['locale'].choices = [(a, b) for a, b in settings.LANGUAGES if a in self.locales]
|
||||
self.fields['location'].widget.attrs['rows'] = '3'
|
||||
if self.has_subevents:
|
||||
del self.fields['presale_start']
|
||||
del self.fields['presale_end']
|
||||
|
||||
def clean(self):
|
||||
data = super().clean()
|
||||
@@ -125,11 +140,12 @@ class EventWizardCopyForm(forms.Form):
|
||||
def __init__(self, *args, **kwargs):
|
||||
kwargs.pop('organizer')
|
||||
kwargs.pop('locales')
|
||||
has_subevents = kwargs.pop('has_subevents')
|
||||
self.user = kwargs.pop('user')
|
||||
super().__init__(*args, **kwargs)
|
||||
self.fields['copy_from_event'] = forms.ModelChoiceField(
|
||||
label=_("Copy configuration from"),
|
||||
queryset=EventWizardCopyForm.copy_from_queryset(self.user),
|
||||
queryset=EventWizardCopyForm.copy_from_queryset(self.user).filter(has_subevents=has_subevents),
|
||||
widget=forms.RadioSelect,
|
||||
empty_label=_('Do not copy'),
|
||||
required=False
|
||||
@@ -195,15 +211,15 @@ class EventSettingsForm(SettingsForm):
|
||||
presale_start_show_date = forms.BooleanField(
|
||||
label=_("Show start date"),
|
||||
help_text=_("Show the presale start date before presale has started."),
|
||||
widget=forms.CheckboxInput(attrs={'data-display-dependency': '#id_presale_start'}),
|
||||
widget=forms.CheckboxInput,
|
||||
required=False
|
||||
)
|
||||
last_order_modification_date = forms.DateTimeField(
|
||||
last_order_modification_date = RelativeDateTimeField(
|
||||
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."),
|
||||
"answers to questions. If you use the event series feature and an order contains tickest for "
|
||||
"multiple event dates, the earliest date will be used."),
|
||||
required=False,
|
||||
widget=forms.DateTimeInput(attrs={'class': 'datetimepicker'}),
|
||||
)
|
||||
timezone = forms.ChoiceField(
|
||||
choices=((a, a) for a in common_timezones),
|
||||
@@ -327,12 +343,12 @@ class PaymentSettingsForm(SettingsForm):
|
||||
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.DateField(
|
||||
payment_term_last = RelativeDateField(
|
||||
label=_('Last date of payments'),
|
||||
help_text=_("The last date any payments are accepted. This has precedence over the number of "
|
||||
"days configured above."),
|
||||
"days configured above. If you use the event series feature and an order contains tickets for "
|
||||
"multiple dates, the earliest date will be used."),
|
||||
required=False,
|
||||
widget=forms.DateInput(attrs={'class': 'datepickerfield'})
|
||||
)
|
||||
payment_term_weekdays = forms.BooleanField(
|
||||
label=_('Only end payment terms on weekdays'),
|
||||
@@ -364,8 +380,10 @@ class PaymentSettingsForm(SettingsForm):
|
||||
def clean(self):
|
||||
cleaned_data = super().clean()
|
||||
payment_term_last = cleaned_data.get('payment_term_last')
|
||||
print(payment_term_last)
|
||||
if payment_term_last and self.obj.presale_end:
|
||||
if payment_term_last < self.obj.presale_end.date():
|
||||
print(payment_term_last, payment_term_last.datetime(self.obj), self.obj.presale_end.date())
|
||||
if payment_term_last.datetime(self.obj) < self.obj.presale_end.date():
|
||||
self.add_error(
|
||||
'payment_term_last',
|
||||
_('The last payment date cannot be before the end of presale.'),
|
||||
@@ -392,6 +410,8 @@ class ProviderForm(SettingsForm):
|
||||
v._required = v.one_required
|
||||
v.one_required = False
|
||||
v.widget.enabled_locales = self.locales
|
||||
elif isinstance(v, (RelativeDateTimeField, RelativeDateField)):
|
||||
v.set_event(self.obj)
|
||||
|
||||
def clean(self):
|
||||
cleaned_data = super().clean()
|
||||
@@ -658,12 +678,12 @@ class TicketSettingsForm(SettingsForm):
|
||||
help_text=_("Use pretix to generate tickets for the user to download and print out."),
|
||||
required=False
|
||||
)
|
||||
ticket_download_date = forms.DateTimeField(
|
||||
ticket_download_date = RelativeDateTimeField(
|
||||
label=_("Download date"),
|
||||
help_text=_("Ticket download will be offered after this date."),
|
||||
required=True,
|
||||
widget=forms.DateTimeInput(attrs={'class': 'datetimepicker',
|
||||
'data-display-dependency': '#id_ticket_download'}),
|
||||
help_text=_("Ticket download will be offered after this date. If you use the event series feature and an order "
|
||||
"contains tickets for multiple event dates, download of all tickets will be available if at least "
|
||||
"one of the event dates allows it."),
|
||||
required=False,
|
||||
)
|
||||
ticket_download_addons = forms.BooleanField(
|
||||
label=_("Offer to download tickets separately for add-on products"),
|
||||
|
||||
Reference in New Issue
Block a user