Replace Item.hidden_if_available with relationship to other Item (#3686)

* draft

* Implementation that is closer to old one

* Fix tests

* Add tests

* Update src/pretix/control/forms/item.py

Co-authored-by: Richard Schreiber <schreiber@rami.io>

* Review notes

---------

Co-authored-by: Richard Schreiber <schreiber@rami.io>
This commit is contained in:
Raphael Michel
2023-11-06 13:26:32 +01:00
committed by GitHub
parent 3d68c83907
commit 3af2342d7b
15 changed files with 235 additions and 54 deletions

View File

@@ -127,52 +127,77 @@ def get_grouped_items(event, subevent=None, voucher=None, channel='web', require
else:
prefetch_membership_types = []
prefetch_var = Prefetch(
'variations',
to_attr='available_variations',
queryset=ItemVariation.objects.using(settings.DATABASE_REPLICA).annotate(
subevent_disabled=Exists(
SubEventItemVariation.objects.filter(
Q(disabled=True) | Q(available_from__gt=now()) | Q(available_until__lt=now()),
variation_id=OuterRef('pk'),
subevent=subevent,
)
),
).filter(
variation_q,
active=True,
sales_channels__contains=channel,
quotas__isnull=False,
subevent_disabled=False
).prefetch_related(
*prefetch_membership_types,
Prefetch('quotas',
to_attr='_subevent_quotas',
queryset=event.quotas.using(settings.DATABASE_REPLICA).filter(
subevent=subevent))
).distinct()
)
prefetch_quotas = Prefetch(
'quotas',
to_attr='_subevent_quotas',
queryset=event.quotas.using(settings.DATABASE_REPLICA).filter(subevent=subevent)
)
prefetch_bundles = Prefetch(
'bundles',
queryset=ItemBundle.objects.using(settings.DATABASE_REPLICA).prefetch_related(
Prefetch('bundled_item',
queryset=event.items.using(settings.DATABASE_REPLICA).select_related(
'tax_rule').prefetch_related(
Prefetch('quotas',
to_attr='_subevent_quotas',
queryset=event.quotas.using(settings.DATABASE_REPLICA).filter(
subevent=subevent)),
)),
Prefetch('bundled_variation',
queryset=ItemVariation.objects.using(
settings.DATABASE_REPLICA
).select_related('item', 'item__tax_rule').filter(item__event=event).prefetch_related(
Prefetch('quotas',
to_attr='_subevent_quotas',
queryset=event.quotas.using(settings.DATABASE_REPLICA).filter(
subevent=subevent)),
)),
)
)
items = base_qs.using(settings.DATABASE_REPLICA).filter_available(channel=channel, voucher=voucher, allow_addons=allow_addons).select_related(
'category', 'tax_rule', # for re-grouping
'hidden_if_available',
).prefetch_related(
*prefetch_membership_types,
Prefetch('quotas',
to_attr='_subevent_quotas',
queryset=event.quotas.using(settings.DATABASE_REPLICA).filter(subevent=subevent)),
Prefetch('bundles',
queryset=ItemBundle.objects.using(settings.DATABASE_REPLICA).prefetch_related(
Prefetch('bundled_item',
queryset=event.items.using(settings.DATABASE_REPLICA).select_related('tax_rule').prefetch_related(
Prefetch('quotas',
to_attr='_subevent_quotas',
queryset=event.quotas.using(settings.DATABASE_REPLICA).filter(subevent=subevent)),
)),
Prefetch('bundled_variation',
queryset=ItemVariation.objects.using(
settings.DATABASE_REPLICA
).select_related('item', 'item__tax_rule').filter(item__event=event).prefetch_related(
Prefetch('quotas',
to_attr='_subevent_quotas',
queryset=event.quotas.using(settings.DATABASE_REPLICA).filter(subevent=subevent)),
)),
)),
Prefetch('variations', to_attr='available_variations',
queryset=ItemVariation.objects.using(settings.DATABASE_REPLICA).annotate(
subevent_disabled=Exists(
SubEventItemVariation.objects.filter(
Q(disabled=True) | Q(available_from__gt=now()) | Q(available_until__lt=now()),
variation_id=OuterRef('pk'),
subevent=subevent,
)
),
).filter(
variation_q,
active=True,
sales_channels__contains=channel,
quotas__isnull=False,
subevent_disabled=False
).prefetch_related(
*prefetch_membership_types,
Prefetch('quotas',
to_attr='_subevent_quotas',
queryset=event.quotas.using(settings.DATABASE_REPLICA).filter(subevent=subevent))
).distinct()),
Prefetch(
'hidden_if_item_available',
queryset=event.items.annotate(
has_variations=Count('variations'),
).prefetch_related(
prefetch_var,
prefetch_quotas,
prefetch_bundles,
)
),
prefetch_quotas,
prefetch_var,
prefetch_bundles,
).annotate(
quotac=Count('quotas'),
has_variations=Count('variations'),
@@ -256,6 +281,19 @@ def get_grouped_items(event, subevent=None, voucher=None, channel='web', require
item._remove = True
continue
if item.hidden_if_item_available:
if item.hidden_if_item_available.has_variations:
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._remove = True
continue
if item.require_membership and item.require_membership_hidden:
if not memberships or not any([m.membership_type in item.require_membership_types.all() for m in memberships]):
item._remove = True