Allow quota-level vouchers for hidden products (#1123)

* Changes in checks

* Backwards-compatible implementation

* Add test

* Fix voucher bulk form
This commit is contained in:
Raphael Michel
2019-07-07 13:36:04 +02:00
committed by GitHub
parent 5180b5e48b
commit ca1c387a41
13 changed files with 69 additions and 14 deletions

View File

@@ -0,0 +1,26 @@
# Generated by Django 2.2.1 on 2019-07-07 10:10
from django.db import migrations, models
def set_show_hidden_items(apps, schema_editor):
Voucher = apps.get_model('pretixbase', 'Voucher')
Voucher.objects.filter(quota__isnull=False).update(show_hidden_items=False)
class Migration(migrations.Migration):
dependencies = [
('pretixbase', '0124_seat_seat_guid'),
]
operations = [
migrations.AddField(
model_name='voucher',
name='show_hidden_items',
field=models.BooleanField(default=True),
),
migrations.RunPython(
set_show_hidden_items,
migrations.RunPython.noop,
)
]

View File

@@ -171,12 +171,11 @@ def filter_available(qs, channel='web', voucher=None, allow_addons=False):
qs = qs.filter(q)
vouchq = Q(hide_without_voucher=False)
if voucher:
if voucher and voucher.show_hidden_items:
if voucher.item_id:
vouchq |= Q(pk=voucher.item_id)
qs = qs.filter(pk=voucher.item_id)
vouchq = Q(pk=voucher.item_id)
elif voucher.quota_id:
qs = qs.filter(quotas__in=[voucher.quota_id])
vouchq = Q(quotas__in=[voucher.quota_id])
return qs.filter(vouchq)
@@ -343,7 +342,7 @@ class Item(LoggedModel):
verbose_name=_('This product will only be shown if a voucher matching the product is redeemed.'),
default=False,
help_text=_('This product will be hidden from the event page until the user enters a voucher '
'code that is specifically tied to this product (and not via a quota).')
'that unlocks this product.')
)
require_bundling = models.BooleanField(
verbose_name=_('Only sell this product as part of a bundle'),

View File

@@ -176,6 +176,10 @@ class Voucher(LoggedModel):
help_text=_("The text entered in this field will not be visible to the user and is available for your "
"convenience.")
)
show_hidden_items = models.BooleanField(
verbose_name=_("Shows hidden products that match this voucher"),
default=True
)
objects = ScopedManager(organizer='event__organizer')

View File

@@ -225,10 +225,7 @@ class CartManager:
def _check_item_constraints(self, op):
if isinstance(op, self.AddOperation) or isinstance(op, self.ExtendOperation):
if op.item.require_voucher and op.voucher is None:
raise CartError(error_messages['voucher_required'])
if op.item.hide_without_voucher and (op.voucher is None or op.voucher.item is None or op.voucher.item.pk != op.item.pk):
if (op.item.require_voucher or op.item.hide_without_voucher) and (op.voucher is None or not op.voucher.show_hidden_items):
raise CartError(error_messages['voucher_required'])
if not op.item.is_available() or (op.variation and not op.variation.active):

View File

@@ -505,9 +505,9 @@ def _check_positions(event: Event, now_dt: datetime, positions: List[CartPositio
err = err or error_messages['voucher_required']
break
if cp.item.hide_without_voucher and (cp.voucher is None or cp.voucher.item is None
or cp.voucher.item.pk != cp.item.pk):
if cp.item.hide_without_voucher and (cp.voucher is None or not cp.voucher.show_hidden_items or not cp.voucher.applies_to(cp.item.pk, cp.variation.pk)):
delete(cp)
cp.delete()
err = error_messages['voucher_required']
break