diff --git a/src/pretix/base/models/vouchers.py b/src/pretix/base/models/vouchers.py index ced25aa82..34991aa5b 100644 --- a/src/pretix/base/models/vouchers.py +++ b/src/pretix/base/models/vouchers.py @@ -25,7 +25,7 @@ def _generate_random_code(prefix=None): def generate_code(prefix=None): while True: code = _generate_random_code(prefix=prefix) - if not Voucher.objects.filter(code=code).exists(): + if not Voucher.objects.filter(code__iexact=code).exists(): return code @@ -278,11 +278,9 @@ class Voucher(LoggedModel): if old_instance.quota: quotas.add(old_instance.quota) elif old_instance.variation: - quotas |= set(old_instance.variation.quotas.filter( - subevent=old_instance.subevent)) + quotas |= set(old_instance.variation.quotas.filter(subevent=old_instance.subevent)) elif old_instance.item: - quotas |= set(old_instance.item.quotas.filter( - subevent=old_instance.subevent)) + quotas |= set(old_instance.item.quotas.filter(subevent=old_instance.subevent)) return quotas @staticmethod @@ -313,7 +311,7 @@ class Voucher(LoggedModel): @staticmethod def clean_voucher_code(data, event, pk): - if 'code' in data and Voucher.objects.filter(Q(code=data['code']) & Q(event=event) & ~Q(pk=pk)).exists(): + if 'code' in data and Voucher.objects.filter(Q(code__iexact=data['code']) & Q(event=event) & ~Q(pk=pk)).exists(): raise ValidationError(_('A voucher with this code already exists.')) def save(self, *args, **kwargs): diff --git a/src/pretix/base/services/cart.py b/src/pretix/base/services/cart.py index 94cdb481d..58debd723 100644 --- a/src/pretix/base/services/cart.py +++ b/src/pretix/base/services/cart.py @@ -295,7 +295,7 @@ class CartManager: if i.get('voucher'): try: - voucher = self.event.vouchers.get(code=i.get('voucher').strip()) + voucher = self.event.vouchers.get(code__iexact=i.get('voucher').strip()) except Voucher.DoesNotExist: raise CartError(error_messages['voucher_invalid']) else: diff --git a/src/pretix/control/forms/vouchers.py b/src/pretix/control/forms/vouchers.py index 6b85ea1d7..633e24651 100644 --- a/src/pretix/control/forms/vouchers.py +++ b/src/pretix/control/forms/vouchers.py @@ -2,6 +2,7 @@ import copy from django import forms from django.core.exceptions import ValidationError +from django.db.models.functions import Lower from django.utils.translation import ugettext_lazy as _ from pretix.base.forms import I18nModelForm @@ -164,7 +165,10 @@ class VoucherBulkForm(VoucherForm): def clean(self): data = super().clean() - if Voucher.objects.filter(code__in=data['codes'], event=self.instance.event).exists(): + vouchers = self.instance.event.vouchers.annotate( + code_lower=Lower('code') + ).filter(code_lower__in=[c.lower() for c in data['codes']]) + if vouchers.exists(): raise ValidationError(_('A voucher with one of these codes already exists.')) return data diff --git a/src/pretix/presale/views/cart.py b/src/pretix/presale/views/cart.py index a41e4b914..47cb656fa 100644 --- a/src/pretix/presale/views/cart.py +++ b/src/pretix/presale/views/cart.py @@ -399,7 +399,7 @@ class RedeemView(NoSearchIndexViewMixin, EventViewMixin, TemplateView): if v: v = v.strip() try: - self.voucher = Voucher.objects.get(code=v, event=request.event) + self.voucher = Voucher.objects.get(code__iexact=v, event=request.event) if self.voucher.redeemed >= self.voucher.max_usages: err = error_messages['voucher_redeemed'] if self.voucher.valid_until is not None and self.voucher.valid_until < now(): diff --git a/src/pretix/presale/views/widget.py b/src/pretix/presale/views/widget.py index 5b61ebc52..a7d62eac5 100644 --- a/src/pretix/presale/views/widget.py +++ b/src/pretix/presale/views/widget.py @@ -238,7 +238,7 @@ class WidgetAPIProductList(View): self.voucher = None if 'voucher' in request.GET: try: - self.voucher = request.event.vouchers.get(code=request.GET.get('voucher').strip()) + self.voucher = request.event.vouchers.get(code__iexact=request.GET.get('voucher').strip()) if self.voucher.redeemed >= self.voucher.max_usages: data['error'] = error_messages['voucher_redeemed'] fail = True