diff --git a/src/pretix/base/models/orders.py b/src/pretix/base/models/orders.py index 32df75113c..9cfa9b026e 100644 --- a/src/pretix/base/models/orders.py +++ b/src/pretix/base/models/orders.py @@ -495,6 +495,9 @@ class OrderPosition(AbstractPosition): def save(self, *args, **kwargs): if self.tax_rate is None: self._calculate_tax() + if self.pk is None: + while OrderPosition.objects.filter(secret=self.secret).exists(): + self.secret = generate_position_secret() return super().save(*args, **kwargs) diff --git a/src/tests/base/test_models.py b/src/tests/base/test_models.py index 0c9d5b5f53..ecf0276736 100644 --- a/src/tests/base/test_models.py +++ b/src/tests/base/test_models.py @@ -577,6 +577,16 @@ class OrderTestCase(BaseQuotaTestCase): variation=None, price=23) assert self.order.can_user_cancel is False + def test_no_duplicate_position_secret(self): + item1 = Item.objects.create(event=self.event, name="Ticket", default_price=23, + admission=True, allow_cancel=False) + p1 = OrderPosition.objects.create(order=self.order, item=item1, secret='ABC', + variation=None, price=23) + p2 = OrderPosition.objects.create(order=self.order, item=item1, secret='ABC', + variation=None, price=23) + assert p1.secret != p2.secret + assert self.order.can_user_cancel is False + class ItemCategoryTest(TestCase): """