Add Reusable Media Exchange to Checkin API

This commit is contained in:
Martin Gross
2026-04-27 14:37:51 +02:00
committed by Raphael Michel
parent 93469d33e5
commit 744eab1765
13 changed files with 103 additions and 6 deletions

View File

@@ -192,6 +192,11 @@ class CheckinListSimulatorForm(forms.Form):
initial=True,
required=False,
)
media_exchange_supported = forms.BooleanField(
label=_("Support for media exchange"),
initial=True,
required=False,
)
gate = SafeModelChoiceField(
label=_('Gate'),
empty_label=_('All gates'),

View File

@@ -636,6 +636,7 @@ class OrganizerSettingsForm(SettingsForm):
'cookie_consent_dialog_button_yes',
'cookie_consent_dialog_button_no',
'reusable_media_active',
'reusable_media_usage_enforced',
'reusable_media_type_barcode',
'reusable_media_type_barcode_identifier_length',
'reusable_media_type_nfc_uid',

View File

@@ -35,6 +35,7 @@
{% bootstrap_field form.gate layout="control" %}
{% bootstrap_field form.ignore_unpaid layout="control" %}
{% bootstrap_field form.questions_supported layout="control" %}
{% bootstrap_field form.media_exchange_supported layout="control" %}
<div class="row">
<div class="col-md-9 col-md-offset-3">
<button type="submit" class="btn btn-primary">
@@ -54,6 +55,8 @@
<span class="fa fa-check-circle"></span>
{% elif result.status == "incomplete" %}
<span class="fa fa-question-circle"></span>
{% elif result.status == "exchange" %}
<span class="fa fa-recycle"></span>
{% elif result.status == "error" %}
{% if result.reason == "already_redeemed" %}
<span class="fa fa-warning"></span>
@@ -79,6 +82,14 @@
</li>
{% endfor %}
</ul>
{% elif result.status == "exchange" %}
<h3 class="nomargin-top">{% trans "Media exchange required" %}</h3>
<p>
{% blocktrans trimmed with media_policy=media_policies|getitem:result.media_policy media_type=media_types|getitem:result.media_type %}
This ticket needs to be exchanged into a <strong>{{ media_type }}</strong> re-usable media.
<strong>{{ media_policy }}</strong>.
{% endblocktrans %}
</p>
{% elif result.status == "error" %}
<h3 class="nomargin-top">{{ reason_labels|getitem:result.reason }}</h3>
{% if result.reason_explanation %}

View File

@@ -222,6 +222,7 @@
<fieldset>
<legend>{% trans "Reusable media" %}</legend>
{% bootstrap_field sform.reusable_media_active layout="control" %}
{% bootstrap_field sform.reusable_media_usage_enforced layout="control" %}
<div data-display-dependency="#{{ sform.reusable_media_active.id_for_label }}">
<div class="panel panel-default">

View File

@@ -50,7 +50,7 @@ from i18nfield.strings import LazyI18nString
from pretix.api.views.checkin import _redeem_process
from pretix.base.media import MEDIA_TYPES
from pretix.base.models import Checkin, LogEntry, Order, OrderPosition
from pretix.base.models import Checkin, LogEntry, Order, OrderPosition, Item
from pretix.base.models.checkin import CheckinList
from pretix.base.models.orders import PrintLog
from pretix.base.permissions import AnyPermissionOf
@@ -532,6 +532,8 @@ class CheckInListSimulator(EventPermissionRequiredMixin, FormView):
checkinlist=self.list,
result=self.result,
reason_labels=dict(Checkin.REASONS),
media_policies=dict(Item.MEDIA_POLICIES),
media_types=dict(MEDIA_TYPES),
)
def form_valid(self, form):
@@ -551,6 +553,7 @@ class CheckInListSimulator(EventPermissionRequiredMixin, FormView):
pdf_data=False,
questions_supported=form.cleaned_data["questions_supported"],
canceled_supported=False,
media_exchange_supported=form.cleaned_data["media_exchange_supported"],
request=self.request, # this is not clean, but we need it in the serializers for URL generation
legacy_url_support=False,
simulate=True,