forked from CGM_Public/pretix_original
Compare commits
1 Commits
metrics_mi
...
migration-
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c285ee2d8c |
@@ -69,6 +69,10 @@ hidden_if_available integer **DEPRECATED*
|
||||
hidden_if_item_available integer The internal ID of a different item, or ``null``. If
|
||||
set, this item won't be shown publicly as long as this
|
||||
other item is available.
|
||||
hidden_if_item_available_mode string If ``hide`` (the default), this item is hidden in the shop
|
||||
if unavailable due to the ``hidden_if_item_available`` setting.
|
||||
If ``info``, the item is visible, but can't be purchased,
|
||||
and a note explaining the unavailability is displayed.
|
||||
require_voucher boolean If ``true``, this item can only be bought using a
|
||||
voucher that is specifically assigned to this item.
|
||||
hide_without_voucher boolean If ``true``, this item is only shown during the voucher
|
||||
@@ -239,6 +243,10 @@ meta_data object Values set fo
|
||||
The ``hidden_if_item_available`` attributes has been added, the ``hidden_if_available`` attribute has been
|
||||
deprecated.
|
||||
|
||||
.. versionchanged:: 2025.01
|
||||
|
||||
The ``hidden_if_item_available_mode`` attributes has been added.
|
||||
|
||||
Notes
|
||||
-----
|
||||
|
||||
@@ -308,6 +316,7 @@ Endpoints
|
||||
"available_until_mode": "hide",
|
||||
"hidden_if_available": null,
|
||||
"hidden_if_item_available": null,
|
||||
"hidden_if_item_available_mode": "hide",
|
||||
"require_voucher": false,
|
||||
"hide_without_voucher": false,
|
||||
"allow_cancel": true,
|
||||
@@ -459,6 +468,7 @@ Endpoints
|
||||
"available_until_mode": "hide",
|
||||
"hidden_if_available": null,
|
||||
"hidden_if_item_available": null,
|
||||
"hidden_if_item_available_mode": "hide",
|
||||
"require_voucher": false,
|
||||
"hide_without_voucher": false,
|
||||
"allow_cancel": true,
|
||||
@@ -589,6 +599,7 @@ Endpoints
|
||||
"available_until_mode": "hide",
|
||||
"hidden_if_available": null,
|
||||
"hidden_if_item_available": null,
|
||||
"hidden_if_item_available_mode": "hide",
|
||||
"require_voucher": false,
|
||||
"hide_without_voucher": false,
|
||||
"allow_cancel": true,
|
||||
@@ -705,6 +716,7 @@ Endpoints
|
||||
"available_until_mode": "hide",
|
||||
"hidden_if_available": null,
|
||||
"hidden_if_item_available": null,
|
||||
"hidden_if_item_available_mode": "hide",
|
||||
"require_voucher": false,
|
||||
"hide_without_voucher": false,
|
||||
"allow_cancel": true,
|
||||
@@ -855,6 +867,7 @@ Endpoints
|
||||
"available_until_mode": "hide",
|
||||
"hidden_if_available": null,
|
||||
"hidden_if_item_available": null,
|
||||
"hidden_if_item_available_mode": "hide",
|
||||
"require_voucher": false,
|
||||
"hide_without_voucher": false,
|
||||
"generate_tickets": null,
|
||||
|
||||
@@ -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',
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
# Generated by Django 4.2.16 on 2025-01-24 12:38
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
("pretixbase", "0276_item_hidden_if_item_available_mode"),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name="item",
|
||||
name="hidden_if_item_available_mode",
|
||||
field=models.CharField(default="hide", max_length=16),
|
||||
),
|
||||
]
|
||||
@@ -442,8 +442,12 @@ class Item(LoggedModel):
|
||||
UNAVAIL_MODE_INFO = "info"
|
||||
UNAVAIL_MODES = (
|
||||
(UNAVAIL_MODE_HIDDEN, _("Hide product if unavailable")),
|
||||
(UNAVAIL_MODE_INFO, _("Show info text if unavailable")),
|
||||
(UNAVAIL_MODE_INFO, _("Show product with info on why it’s unavailable")),
|
||||
)
|
||||
UNAVAIL_MODE_ICONS = {
|
||||
UNAVAIL_MODE_HIDDEN: 'eye-slash',
|
||||
UNAVAIL_MODE_INFO: 'info'
|
||||
}
|
||||
|
||||
MEDIA_POLICY_REUSE = 'reuse'
|
||||
MEDIA_POLICY_NEW = 'new'
|
||||
@@ -596,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,
|
||||
@@ -885,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
|
||||
|
||||
|
||||
@@ -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',
|
||||
@@ -646,18 +647,12 @@ class ItemUpdateForm(I18nModelForm):
|
||||
|
||||
self.fields['available_from_mode'].widget = ButtonGroupRadioSelect(
|
||||
choices=self.fields['available_from_mode'].choices,
|
||||
option_icons={
|
||||
Item.UNAVAIL_MODE_HIDDEN: 'eye-slash',
|
||||
Item.UNAVAIL_MODE_INFO: 'info'
|
||||
}
|
||||
option_icons=Item.UNAVAIL_MODE_ICONS
|
||||
)
|
||||
|
||||
self.fields['available_until_mode'].widget = ButtonGroupRadioSelect(
|
||||
choices=self.fields['available_until_mode'].choices,
|
||||
option_icons={
|
||||
Item.UNAVAIL_MODE_HIDDEN: 'eye-slash',
|
||||
Item.UNAVAIL_MODE_INFO: 'info'
|
||||
}
|
||||
option_icons=Item.UNAVAIL_MODE_ICONS
|
||||
)
|
||||
|
||||
self.fields['hide_without_voucher'].widget = ButtonGroupRadioSelect(
|
||||
@@ -672,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(
|
||||
@@ -853,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',
|
||||
@@ -970,18 +971,12 @@ class ItemVariationForm(I18nModelForm):
|
||||
|
||||
self.fields['available_from_mode'].widget = ButtonGroupRadioSelect(
|
||||
choices=self.fields['available_from_mode'].choices,
|
||||
option_icons={
|
||||
Item.UNAVAIL_MODE_HIDDEN: 'eye-slash',
|
||||
Item.UNAVAIL_MODE_INFO: 'info'
|
||||
}
|
||||
option_icons=Item.UNAVAIL_MODE_ICONS
|
||||
)
|
||||
|
||||
self.fields['available_until_mode'].widget = ButtonGroupRadioSelect(
|
||||
choices=self.fields['available_until_mode'].choices,
|
||||
option_icons={
|
||||
Item.UNAVAIL_MODE_HIDDEN: 'eye-slash',
|
||||
Item.UNAVAIL_MODE_INFO: 'info'
|
||||
}
|
||||
option_icons=Item.UNAVAIL_MODE_ICONS
|
||||
)
|
||||
|
||||
self.meta_fields = []
|
||||
|
||||
@@ -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" %}
|
||||
</fieldset>
|
||||
{% for v in formsets.values %}
|
||||
<fieldset>
|
||||
|
||||
@@ -2,5 +2,5 @@
|
||||
{% if mode == "hide" %}
|
||||
<span class="pull-right text-muted unavail-mode-indicator" data-toggle="tooltip" title="{% trans "Hide product if unavailable" %}. {% if f.variation %}{% trans "You can change this option in the variation settings." %}{% else %}{% trans "You can change this option in the product settings." %}{% endif %}"><span class="fa fa-eye-slash"></span></span>
|
||||
{% else %}
|
||||
<span class="pull-right text-muted unavail-mode-indicator" data-toggle="tooltip" title="{% trans "Show info text if unavailable" %}. {% if f.variation %}{% trans "You can change this option in the variation settings." %}{% else %}{% trans "You can change this option in the product settings." %}{% endif %}"><span class="fa fa-info-circle"></span></span>
|
||||
<span class="pull-right text-muted unavail-mode-indicator" data-toggle="tooltip" title="{% trans "Show product with info on why it’s unavailable" %}. {% if f.variation %}{% trans "You can change this option in the variation settings." %}{% else %}{% trans "You can change this option in the product settings." %}{% endif %}"><span class="fa fa-info-circle"></span></span>
|
||||
{% endif %}
|
||||
@@ -5,6 +5,10 @@
|
||||
<div class="col-md-2 col-sm-3 col-xs-6 availability-box unavailable">
|
||||
<p><small><a href="#voucher">{% trans "Enter a voucher code below to buy this product." %}</a></small></p>
|
||||
</div>
|
||||
{% elif item.current_unavailability_reason == 'hidden_if_item_available' %}
|
||||
<div class="col-md-2 col-sm-3 col-xs-6 availability-box unavailable">
|
||||
<p><small>{% trans "Not available yet." %}</small></p>
|
||||
</div>
|
||||
{% elif item.current_unavailability_reason == 'available_from' or var.current_unavailability_reason == 'available_from' %}
|
||||
<div class="col-md-2 col-sm-3 col-xs-6 availability-box unavailable">
|
||||
<p><small>{% trans "Not available yet." %}</small></p>
|
||||
|
||||
@@ -70,7 +70,7 @@ from pretix.base.models import (
|
||||
)
|
||||
from pretix.base.models.event import Event, SubEvent
|
||||
from pretix.base.models.items import (
|
||||
ItemAddOn, ItemBundle, SubEventItem, SubEventItemVariation,
|
||||
Item, ItemAddOn, ItemBundle, SubEventItem, SubEventItemVariation,
|
||||
)
|
||||
from pretix.base.services.placeholders import PlaceholderContext
|
||||
from pretix.base.services.quotas import QuotaAvailability
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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.'),
|
||||
|
||||
@@ -323,6 +323,7 @@ TEST_ITEM_RES = {
|
||||
"max_per_order": None,
|
||||
"hidden_if_available": None,
|
||||
"hidden_if_item_available": None,
|
||||
"hidden_if_item_available_mode": "hide",
|
||||
"checkin_attention": False,
|
||||
"checkin_text": None,
|
||||
"has_variations": False,
|
||||
|
||||
Reference in New Issue
Block a user