diff --git a/doc/development/api/restriction.rst b/doc/development/api/restriction.rst index 46bb287b7a..8d39733174 100644 --- a/doc/development/api/restriction.rst +++ b/doc/development/api/restriction.rst @@ -181,7 +181,7 @@ In our example, the implementation could look like this:: # Only take this restriction into consideration if it # is directly applied to this variation or if the item # has no variations - if len(v) != 0 and ('variation' not in v or v['variation'] not in applied_to): + if not v.empty() and ('variation' not in v or v['variation'] not in applied_to): continue if restriction.timeframe_from <= now() <= restriction.timeframe_to: diff --git a/src/pretixbase/models.py b/src/pretixbase/models.py index 8e10689a37..1f67e8f49b 100644 --- a/src/pretixbase/models.py +++ b/src/pretixbase/models.py @@ -12,7 +12,7 @@ import six from versions.models import Versionable as BaseVersionable from versions.models import VersionedForeignKey, VersionedManyToManyField, get_utc_now -from pretixbase.types import VariationDict +from .types import VariationDict class Versionable(BaseVersionable): @@ -703,6 +703,35 @@ class Item(Versionable): self._get_all_variations_cache = result return result + def get_all_available_variations(self): + from .signals import determine_availability + + variations = self.get_all_variations() + responses = determine_availability.send( + self.event, item=self, + variations=variations, context=None, + cache=self.event.get_cache() + ) + + for i, var in enumerate(variations): + var['available'] = var['variation'].active if 'variation' in var else True + if 'variation' in var: + if var['variation'].default_price: + var['price'] = var['variation'].default_price + else: + var['price'] = self.default_price + else: + var['price'] = self.default_price + + for receiver, response in responses: + if 'available' in response[i]: + var['available'] &= response[i]['available'] + if 'price' in response[i] and response[i]['price'] \ + and response[i]['price'] < var['price']: + var['price'] = response[i]['price'] + + return variations + class ItemVariation(Versionable): """ diff --git a/src/pretixbase/signals.py b/src/pretixbase/signals.py index e1c1dd95f9..99860e5c8f 100644 --- a/src/pretixbase/signals.py +++ b/src/pretixbase/signals.py @@ -2,7 +2,7 @@ import django.dispatch from django.apps import apps from django.dispatch.dispatcher import NO_RECEIVERS -from pretixbase.models import Event +from .models import Event class EventPluginSignal(django.dispatch.Signal): diff --git a/src/pretixbase/types.py b/src/pretixbase/types.py index c52f67dac8..34e2b6a3e9 100644 --- a/src/pretixbase/types.py +++ b/src/pretixbase/types.py @@ -5,7 +5,7 @@ class VariationDict(dict): returned by ``Item.get_all_variations()`` to avoid duplicate code in the code calling this method. """ - IGNORE_KEYS = ('variation', 'key') + IGNORE_KEYS = ('variation', 'key', 'available', 'price') def relevant_items(self) -> "list[(str, PropertyValue)]": """ @@ -60,6 +60,13 @@ class VariationDict(dict): else: return super().__eq__(other) + def empty(self): + """ + Returns true, if this VariationDict does not contain any "real" data like + references to PropertyValues, but only "metadata". + """ + return not next(self.relevant_items(), False) + def ordered_values(self) -> "list[ItemVariation]": """ Returns a list of values ordered by their keys @@ -72,6 +79,9 @@ class VariationDict(dict): ) ] + def __str__(self): + return " – ".join([v.value for v in self.ordered_values()]) + def copy(self) -> "VariationDict": """ Return a one-level deep copy of this object (create a new diff --git a/src/pretixplugins/timerestriction/signals.py b/src/pretixplugins/timerestriction/signals.py index 355d1b20e9..27568ae7f9 100644 --- a/src/pretixplugins/timerestriction/signals.py +++ b/src/pretixplugins/timerestriction/signals.py @@ -84,7 +84,7 @@ def availability_handler(sender, **kwargs): # Only take this restriction into consideration if it # is directly applied to this variation or if the item # has no variations - if len(v) != 0 and ('variation' not in v or v['variation'] not in applied_to): + if not v.empty() and ('variation' not in v or v['variation'] not in applied_to): continue if restriction.timeframe_from <= now() <= restriction.timeframe_to: diff --git a/src/pretixpresale/templates/pretixpresale/event/index.html b/src/pretixpresale/templates/pretixpresale/event/index.html index 82f7dc7b64..a3823c4ace 100644 --- a/src/pretixpresale/templates/pretixpresale/event/index.html +++ b/src/pretixpresale/templates/pretixpresale/event/index.html @@ -4,16 +4,37 @@ {% for tup in items_by_category %}
{{ item.short_description }}
+ {% if item.has_variations %} +{{ item.short_description }}
+{{ item.short_description }}
+