From bf1e9d47d0219bbe0563b805f21bb8ef51fe9323 Mon Sep 17 00:00:00 2001 From: Maarten van den Berg Date: Mon, 21 Jan 2019 08:52:31 +0100 Subject: [PATCH] Fix #1111 -- Duplicate voucher warning (#1142) Adds a new method to Voucher that selects all distinct orders containing a position where the Voucher has been used, and changes the Voucher detail view to use this method for the warning. --- src/pretix/base/models/vouchers.py | 9 +++++ .../pretixcontrol/vouchers/detail.html | 6 +-- src/tests/control/test_vouchers.py | 40 ++++++++++++++++++- 3 files changed, 51 insertions(+), 4 deletions(-) diff --git a/src/pretix/base/models/vouchers.py b/src/pretix/base/models/vouchers.py index 61104be6e5..6049e0ebf3 100644 --- a/src/pretix/base/models/vouchers.py +++ b/src/pretix/base/models/vouchers.py @@ -13,6 +13,7 @@ from ..decimal import round_decimal from .base import LoggedModel from .event import Event, SubEvent from .items import Item, ItemVariation, Quota +from .orders import Order def _generate_random_code(prefix=None): @@ -380,3 +381,11 @@ class Voucher(LoggedModel): return p.quantize(Decimal('1') / 10 ** places, ROUND_HALF_UP) return p return original_price + + def distinct_orders(self): + """ + Return the list of orders where this voucher has been used. + Each order will appear at most once. + """ + + return Order.objects.filter(all_positions__voucher__in=[self]).distinct() diff --git a/src/pretix/control/templates/pretixcontrol/vouchers/detail.html b/src/pretix/control/templates/pretixcontrol/vouchers/detail.html index fa5461382f..ff7e613e2f 100644 --- a/src/pretix/control/templates/pretixcontrol/vouchers/detail.html +++ b/src/pretix/control/templates/pretixcontrol/vouchers/detail.html @@ -9,9 +9,9 @@
{% trans "This voucher already has been used. It is not recommended to modify it." %} diff --git a/src/tests/control/test_vouchers.py b/src/tests/control/test_vouchers.py index 60908a1667..59e7bf1e8b 100644 --- a/src/tests/control/test_vouchers.py +++ b/src/tests/control/test_vouchers.py @@ -1,11 +1,13 @@ import datetime +import decimal import json from django.utils.timezone import now from tests.base import SoupTest, extract_form_fields from pretix.base.models import ( - Event, Item, ItemVariation, Organizer, Quota, Team, User, Voucher, + Event, Item, ItemVariation, Order, OrderPosition, Organizer, Quota, Team, + User, Voucher, ) @@ -517,3 +519,39 @@ class VoucherFormTest(SoupTest): 'block_quota': 'on', 'subevent': se1.pk }, expected_failure=True) + + def test_order_warning_deduplication(self): + shirt_voucher = Voucher.objects.create( + event=self.event, item=self.shirt, price_mode='set', value=0.0, max_usages=100 + ) + + shirt_order = Order.objects.create( + code='DEDUP', event=self.event, email='dummy@dummy.test', + status=Order.STATUS_PAID, + datetime=now(), expires=now() + datetime.timedelta(days=10), + total=0, locale='en' + ) + + OrderPosition.objects.create( + order=shirt_order, + item=self.shirt, + variation=self.shirt_red, + price=decimal.Decimal("0"), + voucher=shirt_voucher + ) + + OrderPosition.objects.create( + order=shirt_order, + item=self.shirt, + variation=self.shirt_blue, + price=decimal.Decimal("0"), + voucher=shirt_voucher + ) + + shirt_voucher.redeemed = 2 + shirt_voucher.save() + + doc = self.get_doc('/control/event/%s/%s/vouchers/%s/' % (self.orga.slug, self.event.slug, shirt_voucher.pk)) + + assert len(doc.select('.alert-warning ul li')) == 1 # Check that there's exactly 1 item in the warning list + assert doc.text.count('Order DEDUP') == 1 # Check that the order is listed exactly once