combine edit.html and transfer.html

This commit is contained in:
Lukas Bockstaller
2025-12-17 17:14:08 +01:00
parent 1deb867734
commit e226bfb8d5
6 changed files with 56 additions and 116 deletions
+28 -33
View File
@@ -34,8 +34,18 @@ from pretix.control.forms.widgets import Select2, Select2ItemVarQuota
class WaitingListEntryTransferForm(I18nModelForm): class WaitingListEntryTransferForm(I18nModelForm):
itemvar = ChoiceField()
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
self.instance = kwargs.get('instance', None)
initial = kwargs.get('initial', {})
if self.instance and self.instance.pk and 'itemvar' not in initial:
if self.instance.variation is not None:
initial['itemvar'] = f'{self.instance.item.pk}-{self.instance.variation.pk}'
else:
initial['itemvar'] = self.instance.item.pk
kwargs['initial'] = initial
super().__init__(*args, **kwargs) super().__init__(*args, **kwargs)
if self.event.has_subevents: if self.event.has_subevents:
@@ -51,34 +61,8 @@ class WaitingListEntryTransferForm(I18nModelForm):
} }
) )
self.fields['subevent'].widget.choices = self.fields['subevent'].choices self.fields['subevent'].widget.choices = self.fields['subevent'].choices
else:
class Meta: del self.fields['subevent']
model = WaitingListEntry
fields = [
'subevent',
]
field_classes = {
'subevent': SafeModelChoiceField,
}
class WaitingListEntryEditForm(I18nModelForm):
itemvar = ChoiceField()
def __init__(self, *args, **kwargs):
self.instance = kwargs.get('instance', None)
initial = kwargs.get('initial', {})
if self.instance and self.instance.pk and 'itemvar' not in initial:
if self.instance.variation is not None:
initial['itemvar'] = f'{self.instance.item.pk}-{self.instance.variation.pk}'
else:
initial['itemvar'] = self.instance.item.pk
kwargs['initial'] = initial
super().__init__(*args, **kwargs)
# Prevent the item field cleaning from complaining that it isn't populated
# the value for item is derived and populated during form.clean()
if self.event.settings.waiting_list_names_asked: if self.event.settings.waiting_list_names_asked:
self.fields['name_parts'] = NamePartsFormField( self.fields['name_parts'] = NamePartsFormField(
@@ -96,11 +80,11 @@ class WaitingListEntryEditForm(I18nModelForm):
choices = [] choices = []
items = self.event.items.prefetch_related('variations') items = self.event.items.prefetch_related('variations').prefetch_related('quotas')
for item in items: for item in items:
if not item.allow_waitinglist: if not item.allow_waitinglist | item.quotas.exists():
continue continue
if len(item.variations.all()) > 0: if len(item.variations.all()) > 0:
for v in item.variations.all(): for v in item.variations.all():
choices.append(( choices.append((
@@ -128,8 +112,10 @@ class WaitingListEntryEditForm(I18nModelForm):
self.fields['itemvar'].choices = choices self.fields['itemvar'].choices = choices
def clean(self): def clean(self):
itemvar = self.data.get('itemvar') if self.instance.voucher is not None:
self.add_error(None, _('A voucher for this waiting list entry was sent out already.'))
itemvar = self.data.get('itemvar')
if itemvar is None: if itemvar is None:
self.add_error('itemvar', _('Item and Variation are required')) self.add_error('itemvar', _('Item and Variation are required'))
else: else:
@@ -137,6 +123,14 @@ class WaitingListEntryEditForm(I18nModelForm):
if '-' in itemvar: if '-' in itemvar:
self.instance.variation = ItemVariation.objects.get(pk=itemvar.split('-')[1]) self.instance.variation = ItemVariation.objects.get(pk=itemvar.split('-')[1])
if not self.instance.item.allow_waitinglist:
self.add_error('itemvar', _('The selected product does not allow waiting list entries.'))
if self.instance.item and not self.instance.item.quotas.filter(subevent=self.data.get('subevent')).exists():
self.add_error('itemvar', _('The selected product is not on sale because there is no quota configured for it.'))
if self.instance.variation and not self.instance.variation.quotas.filter(subevent=self.data.get('subevent')).exists():
self.add_error('itemvar', _('The selected product is not on sale because there is no quota configured for it.'))
data = super().clean() data = super().clean()
return data return data
@@ -146,13 +140,14 @@ class WaitingListEntryEditForm(I18nModelForm):
'email', 'email',
'name_parts', 'name_parts',
'phone', 'phone',
'subevent',
] ]
field_classes = { field_classes = {
'subevent': SafeModelChoiceField,
'email': EmailField, 'email': EmailField,
'phone': PhoneNumberField, 'phone': PhoneNumberField,
} }
exclude = [ exclude = [
'subevent', # handled by EntryTransfer view
'voucher', # handled by the assign operation in the WaitingListActionView 'voucher', # handled by the assign operation in the WaitingListActionView
'priority' # handled via thumbs up/down 'priority' # handled via thumbs up/down
] ]
@@ -1,26 +0,0 @@
{% extends "pretixcontrol/event/base.html" %}
{% load i18n %}
{% load bootstrap3 %}
{% block title %}{% trans "Edit waiting list entry" %}{% endblock %}
{% block content %}
<h1>{% trans "Edit waiting list entry" %}</h1>
<form action="" method="post" class="form-horizontal">
{% csrf_token %}
{% bootstrap_field form.email layout="control" %}
{% if form.phone %}
{% bootstrap_field form.name_parts layout="control" %}
{% endif %}
{% if form.phone %}
{% bootstrap_field form.phone layout="control" %}
{% endif %}
{% bootstrap_field form.itemvar layout="control" %}
<div class="form-group submit-group">
<button type="submit" class="btn btn-primary btn-save">
{% trans "Submit" %}
</button>
</div>
</form>
{% endblock %}
@@ -268,14 +268,13 @@
data-toggle="tooltip" title="{% trans "Move to the end of the list" %}"> data-toggle="tooltip" title="{% trans "Move to the end of the list" %}">
<span class="fa fa-thumbs-down"></span> <span class="fa fa-thumbs-down"></span>
</button> </button>
{% if request.event.has_subevents %}
<a href="{% url "control:event.orders.waitinglist.transfer" organizer=request.event.organizer.slug event=request.event.slug entry=e.id %}" <a href="{% url "control:event.orders.waitinglist.transfer" organizer=request.event.organizer.slug event=request.event.slug entry=e.id %}"
class="btn btn-default btn-sm" title="{% trans "Transfer to other date" context "subevent" %}" class="btn btn-default btn-sm" title="{% trans "Transfer to other date" context "subevent" %}"
data-toggle="tooltip"> data-toggle="tooltip">
<i class="fa fa-calendar" aria-hidden="true"></i> <i class="fa fa-pencil" aria-hidden="true"></i>
</a> </a>
{% endif %}
<a href="{% url "control:event.orders.waitinglist.edit" organizer=request.event.organizer.slug event=request.event.slug entry=e.id %}" class="btn btn-default btn-sm"><i class="fa fa-pencil"></i></a>
<a href="{% url "control:event.orders.waitinglist.delete" organizer=request.event.organizer.slug event=request.event.slug entry=e.id %}?next={{ request.get_full_path|urlencode }}" class="btn btn-danger btn-sm"><i class="fa fa-trash"></i></a> <a href="{% url "control:event.orders.waitinglist.delete" organizer=request.event.organizer.slug event=request.event.slug entry=e.id %}?next={{ request.get_full_path|urlencode }}" class="btn btn-danger btn-sm"><i class="fa fa-trash"></i></a>
{% else %} {% else %}
<button class="btn btn-default btn-sm disabled"> <button class="btn btn-default btn-sm disabled">
@@ -7,10 +7,23 @@
<form action="" method="post" class="form-horizontal"> <form action="" method="post" class="form-horizontal">
{% csrf_token %} {% csrf_token %}
<p>{% blocktrans trimmed context "subevent" %} <p>{% blocktrans trimmed context "subevent" %}
Please select the date to which the following waiting list entry should be Please make the desired changes to the following waiting list entry: <strong>{{ entry }}</strong>
transferred: <strong>{{ entry }}</strong>?
{% endblocktrans %}</p> {% endblocktrans %}</p>
{% bootstrap_field form.subevent layout="control" %}
{% if form.subevent %}
{% bootstrap_field form.subevent layout="control" %}
{% endif %}
{% bootstrap_field form.email layout="control" %}
{% if form.phone %}
{% bootstrap_field form.name_parts layout="control" %}
{% endif %}
{% if form.phone %}
{% bootstrap_field form.phone layout="control" %}
{% endif %}
{% bootstrap_field form.itemvar layout="control" %}
<div class="form-group submit-group"> <div class="form-group submit-group">
<a href="{% url "control:event.orders.waitinglist" organizer=request.event.organizer.slug event=request.event.slug %}" class="btn btn-default btn-cancel"> <a href="{% url "control:event.orders.waitinglist" organizer=request.event.organizer.slug event=request.event.slug %}" class="btn btn-default btn-cancel">
{% trans "Cancel" %} {% trans "Cancel" %}
-2
View File
@@ -474,8 +474,6 @@ urlpatterns = [
re_path(r'^waitinglist/$', waitinglist.WaitingListView.as_view(), name='event.orders.waitinglist'), re_path(r'^waitinglist/$', waitinglist.WaitingListView.as_view(), name='event.orders.waitinglist'),
re_path(r'^waitinglist/action$', waitinglist.WaitingListActionView.as_view(), name='event.orders.waitinglist.action'), re_path(r'^waitinglist/action$', waitinglist.WaitingListActionView.as_view(), name='event.orders.waitinglist.action'),
re_path(r'^waitinglist/auto_assign$', waitinglist.AutoAssign.as_view(), name='event.orders.waitinglist.auto'), re_path(r'^waitinglist/auto_assign$', waitinglist.AutoAssign.as_view(), name='event.orders.waitinglist.auto'),
re_path(r'^waitinglist/(?P<entry>\d+)/edit$', waitinglist.EntryEdit.as_view(),
name='event.orders.waitinglist.edit'),
re_path(r'^waitinglist/(?P<entry>\d+)/delete$', waitinglist.EntryDelete.as_view(), re_path(r'^waitinglist/(?P<entry>\d+)/delete$', waitinglist.EntryDelete.as_view(),
name='event.orders.waitinglist.delete'), name='event.orders.waitinglist.delete'),
re_path(r'^waitinglist/(?P<entry>\d+)/transfer$', waitinglist.EntryTransfer.as_view(), re_path(r'^waitinglist/(?P<entry>\d+)/transfer$', waitinglist.EntryTransfer.as_view(),
+5 -44
View File
@@ -54,7 +54,7 @@ from pretix.base.models.waitinglist import WaitingListException
from pretix.base.services.waitinglist import assign_automatically from pretix.base.services.waitinglist import assign_automatically
from pretix.base.views.tasks import AsyncAction from pretix.base.views.tasks import AsyncAction
from pretix.control.forms.waitinglist import ( from pretix.control.forms.waitinglist import (
WaitingListEntryEditForm, WaitingListEntryTransferForm, WaitingListEntryTransferForm,
) )
from pretix.control.permissions import EventPermissionRequiredMixin from pretix.control.permissions import EventPermissionRequiredMixin
from pretix.control.views import PaginationMixin from pretix.control.views import PaginationMixin
@@ -401,43 +401,6 @@ class EntryDelete(EventPermissionRequiredMixin, CompatDeleteView):
'organizer': self.request.event.organizer.slug 'organizer': self.request.event.organizer.slug
}) })
class EntryEdit(EventPermissionRequiredMixin, UpdateView):
model = WaitingListEntry
template_name = 'pretixcontrol/waitinglist/edit.html'
permission = 'can_change_orders'
form_class = WaitingListEntryEditForm
context_object_name = 'entry'
def get_object(self, queryset=None):
return get_object_or_404(WaitingListEntry, pk=self.kwargs['entry'], event=self.request.event)
def get_context_data(self, **kwargs):
ctx = super().get_context_data(**kwargs)
return ctx
@transaction.atomic
def form_valid(self, form):
messages.success(self.request, _('The waitinglist entry has been updated.'))
if form.has_changed():
self.object.log_action(
'pretix.event.orders.waitinglist.changed', user=self.request.user, data={
k: form.cleaned_data.get(k) for k in form.changed_data
}
)
return super().form_valid(form)
def form_invalid(self, form):
messages.error(self.request, _('We could not save your changes. See below for details.'))
return super().form_invalid(form)
def get_success_url(self) -> str:
return reverse('control:event.orders.waitinglist', kwargs={
'event': self.request.event.slug,
'organizer': self.request.event.organizer.slug
})
class EntryTransfer(EventPermissionRequiredMixin, UpdateView): class EntryTransfer(EventPermissionRequiredMixin, UpdateView):
model = WaitingListEntry model = WaitingListEntry
template_name = 'pretixcontrol/waitinglist/transfer.html' template_name = 'pretixcontrol/waitinglist/transfer.html'
@@ -445,18 +408,16 @@ class EntryTransfer(EventPermissionRequiredMixin, UpdateView):
form_class = WaitingListEntryTransferForm form_class = WaitingListEntryTransferForm
context_object_name = 'entry' context_object_name = 'entry'
def dispatch(self, request, *args, **kwargs):
if not self.request.event.has_subevents:
raise Http404(_("This is not an event series."))
return super().dispatch(request, *args, **kwargs)
def get_object(self, queryset=None) -> WaitingListEntry: def get_object(self, queryset=None) -> WaitingListEntry:
return get_object_or_404(WaitingListEntry, pk=self.kwargs['entry'], event=self.request.event, voucher__isnull=True) return get_object_or_404(WaitingListEntry, pk=self.kwargs['entry'], event=self.request.event, voucher__isnull=True)
@transaction.atomic @transaction.atomic
def form_valid(self, form): def form_valid(self, form):
messages.success(self.request, _('The waitinglist entry has been transferred.'))
if form.has_changed(): if form.has_changed():
if 'subevent' in form.changed_data:
messages.success(self.request, _('The waitinglist entry has been transferred.'))
else:
messages.success(self.request, _('The waitinglist entry has been modified.'))
self.object.log_action( self.object.log_action(
'pretix.event.orders.waitinglist.changed', user=self.request.user, data={ 'pretix.event.orders.waitinglist.changed', user=self.request.user, data={
k: form.cleaned_data.get(k) for k in form.changed_data k: form.cleaned_data.get(k) for k in form.changed_data