diff --git a/src/pretix/api/serializers/order.py b/src/pretix/api/serializers/order.py index f402e7fc99..9fa6b5ce92 100644 --- a/src/pretix/api/serializers/order.py +++ b/src/pretix/api/serializers/order.py @@ -1416,6 +1416,7 @@ class OrderCreateSerializer(I18nAwareModelSerializer): qa = QuotaAvailability() qa.queue(*[q for q, d in quota_diff_for_locking.items() if d > 0]) qa.compute() + v_avail = {} # These are not technically correct as diff use due to the time offset applied above, so let's prevent accidental # use further down @@ -1445,11 +1446,13 @@ class OrderCreateSerializer(I18nAwareModelSerializer): voucher_usage[v] += 1 if voucher_usage[v] > 0: - redeemed_in_carts = CartPosition.objects.filter( - Q(voucher=pos_data['voucher']) & Q(event=self.context['event']) & Q(expires__gte=now_dt) - ).exclude(pk__in=[cp.pk for cp in delete_cps]) - v_avail = v.max_usages - v.redeemed - redeemed_in_carts.count() - if v_avail < voucher_usage[v]: + if v not in v_avail: + v.refresh_from_db(fields=['redeemed']) + redeemed_in_carts = CartPosition.objects.filter( + Q(voucher=v) & Q(event=self.context['event']) & Q(expires__gte=now_dt) + ).exclude(pk__in=[cp.pk for cp in delete_cps]) + v_avail[v] = v.max_usages - v.redeemed - redeemed_in_carts.count() + if v_avail[v] < voucher_usage[v]: errs[i]['voucher'] = [ 'The voucher has already been used the maximum number of times.' ] diff --git a/src/pretix/base/services/orders.py b/src/pretix/base/services/orders.py index ba3e199b98..8fe2d3f1a5 100644 --- a/src/pretix/base/services/orders.py +++ b/src/pretix/base/services/orders.py @@ -727,8 +727,6 @@ def _check_positions(event: Event, now_dt: datetime, time_machine_now_dt: dateti _check_date(event, time_machine_now_dt) products_seen = Counter() - q_avail = Counter() - v_avail = Counter() v_usages = Counter() v_budget = {} deleted_positions = set() @@ -793,6 +791,9 @@ def _check_positions(event: Event, now_dt: datetime, time_machine_now_dt: dateti shared_lock_objects=[event] ) + q_avail = Counter() + v_avail = Counter() + # Check maximum order size limit = min(int(event.settings.max_items_per_order), settings.PRETIX_MAX_ORDER_SIZE) if sum(1 for cp in sorted_positions if not cp.addon_to) > limit: