From c6879f5ed11543356e439d93105dc3cfb4cabe2e Mon Sep 17 00:00:00 2001 From: Mira Weller Date: Thu, 23 Jan 2025 12:49:35 +0100 Subject: [PATCH] Implement hidden_if_item_available_mode option --- src/pretix/api/serializers/item.py | 2 +- src/pretix/base/models/items.py | 7 +++++++ src/pretix/control/forms/item.py | 7 +++++++ src/pretix/control/templates/pretixcontrol/item/index.html | 2 +- .../pretixpresale/event/fragment_availability.html | 4 ++++ src/pretix/presale/views/event.py | 6 +++--- src/pretix/static/pretixpresale/js/widget/widget.js | 1 + 7 files changed, 24 insertions(+), 5 deletions(-) diff --git a/src/pretix/api/serializers/item.py b/src/pretix/api/serializers/item.py index 7133776f8..21b7d07ec 100644 --- a/src/pretix/api/serializers/item.py +++ b/src/pretix/api/serializers/item.py @@ -272,7 +272,7 @@ class ItemSerializer(SalesChannelMigrationMixin, I18nAwareModelSerializer): 'require_voucher', 'hide_without_voucher', 'allow_cancel', 'require_bundling', 'min_per_order', 'max_per_order', 'checkin_attention', 'checkin_text', 'has_variations', 'variations', 'addons', 'bundles', 'original_price', 'require_approval', 'generate_tickets', - 'show_quota_left', 'hidden_if_available', 'hidden_if_item_available', 'allow_waitinglist', + 'show_quota_left', 'hidden_if_available', 'hidden_if_item_available', 'hidden_if_item_available_mode', 'allow_waitinglist', 'issue_giftcard', 'meta_data', 'require_membership', 'require_membership_types', 'require_membership_hidden', 'grant_membership_type', 'grant_membership_duration_like_event', 'grant_membership_duration_days', diff --git a/src/pretix/base/models/items.py b/src/pretix/base/models/items.py index b3a51dff7..35deab286 100644 --- a/src/pretix/base/models/items.py +++ b/src/pretix/base/models/items.py @@ -600,6 +600,11 @@ class Item(LoggedModel): "be a short period in which both products are visible while all tickets of the referenced " "product are reserved, but not yet sold.") ) + hidden_if_item_available_mode = models.CharField( + choices=UNAVAIL_MODES, + default=UNAVAIL_MODE_HIDDEN, + max_length=16, + ) require_voucher = models.BooleanField( verbose_name=_('This product can only be bought using a voucher.'), default=False, @@ -889,6 +894,8 @@ class Item(LoggedModel): return 'available_from' elif subevent_item and subevent_item.available_until and subevent_item.available_until < now_dt: return 'available_until' + elif self.hidden_if_item_available and self._dependency_available: + return 'hidden_if_item_available' else: return None diff --git a/src/pretix/control/forms/item.py b/src/pretix/control/forms/item.py index 29652baa9..f1a218c67 100644 --- a/src/pretix/control/forms/item.py +++ b/src/pretix/control/forms/item.py @@ -476,6 +476,7 @@ class ItemCreateForm(I18nModelForm): 'show_quota_left', 'hidden_if_available', 'hidden_if_item_available', + 'hidden_if_item_available_mode', 'require_bundling', 'require_membership', 'grant_membership_type', @@ -666,6 +667,11 @@ class ItemUpdateForm(I18nModelForm): attrs={'data-checkbox-dependency': '#id_require_voucher'} ) + self.fields['hidden_if_item_available_mode'].widget = ButtonGroupRadioSelect( + choices=self.fields['hidden_if_item_available_mode'].choices, + option_icons=Item.UNAVAIL_MODE_ICONS + ) + if self.instance.hidden_if_available_id: self.fields['hidden_if_available'].queryset = self.event.quotas.all() self.fields['hidden_if_available'].help_text = format_html( @@ -847,6 +853,7 @@ class ItemUpdateForm(I18nModelForm): 'show_quota_left', 'hidden_if_available', 'hidden_if_item_available', + 'hidden_if_item_available_mode', 'issue_giftcard', 'require_membership', 'require_membership_types', diff --git a/src/pretix/control/templates/pretixcontrol/item/index.html b/src/pretix/control/templates/pretixcontrol/item/index.html index abea1a90a..6aa712436 100644 --- a/src/pretix/control/templates/pretixcontrol/item/index.html +++ b/src/pretix/control/templates/pretixcontrol/item/index.html @@ -172,7 +172,7 @@ {% if form.hidden_if_available %} {% bootstrap_field form.hidden_if_available layout="control" horizontal_field_class="col-md-7" %} {% endif %} - {% bootstrap_field form.hidden_if_item_available layout="control" horizontal_field_class="col-md-7" %} + {% bootstrap_field form.hidden_if_item_available visibility_field=form.hidden_if_item_available_mode layout="control_with_visibility" %} {% for v in formsets.values %}
diff --git a/src/pretix/presale/templates/pretixpresale/event/fragment_availability.html b/src/pretix/presale/templates/pretixpresale/event/fragment_availability.html index 62a391d61..bd9f326ce 100644 --- a/src/pretix/presale/templates/pretixpresale/event/fragment_availability.html +++ b/src/pretix/presale/templates/pretixpresale/event/fragment_availability.html @@ -5,6 +5,10 @@ +{% elif item.current_unavailability_reason == 'hidden_if_item_available' %} +
+

{% trans "Not available yet." %}

+
{% elif item.current_unavailability_reason == 'available_from' or var.current_unavailability_reason == 'available_from' %}

{% trans "Not available yet." %}

diff --git a/src/pretix/presale/views/event.py b/src/pretix/presale/views/event.py index 06b9128b2..23994310e 100644 --- a/src/pretix/presale/views/event.py +++ b/src/pretix/presale/views/event.py @@ -302,14 +302,14 @@ def get_grouped_items(event, *, channel: SalesChannel, subevent=None, voucher=No if item.hidden_if_item_available: if item.hidden_if_item_available.has_variations: - dependency_available = any( + item._dependency_available = any( var.check_quotas(subevent=subevent, _cache=quota_cache, include_bundled=True)[0] == Quota.AVAILABILITY_OK for var in item.hidden_if_item_available.available_variations ) else: q = item.hidden_if_item_available.check_quotas(subevent=subevent, _cache=quota_cache, include_bundled=True) - dependency_available = q[0] == Quota.AVAILABILITY_OK - if dependency_available: + item._dependency_available = q[0] == Quota.AVAILABILITY_OK + if item._dependency_available and item.hidden_if_item_available_mode == Item.UNAVAIL_MODE_HIDDEN: item._remove = True continue diff --git a/src/pretix/static/pretixpresale/js/widget/widget.js b/src/pretix/static/pretixpresale/js/widget/widget.js index 92e76af03..bd737a25e 100644 --- a/src/pretix/static/pretixpresale/js/widget/widget.js +++ b/src/pretix/static/pretixpresale/js/widget/widget.js @@ -38,6 +38,7 @@ var strings = { 'unavailable_available_from': django.pgettext('widget', 'Not yet available'), 'unavailable_available_until': django.pgettext('widget', 'Not available anymore'), 'unavailable_active': django.pgettext('widget', 'Currently not available'), + 'unavailable_hidden_if_item_available': django.pgettext('widget', 'Not yet available'), 'order_min': django.pgettext('widget', 'minimum amount to order: %s'), 'exit': django.pgettext('widget', 'Close ticket shop'), 'loading_error': django.pgettext('widget', 'The ticket shop could not be loaded.'),