mirror of
https://github.com/pretix/pretix.git
synced 2026-05-03 14:54:04 +00:00
Added the option of unlimited quotas
This commit is contained in:
19
src/pretix/base/migrations/0002_auto_20151021_1412.py
Normal file
19
src/pretix/base/migrations/0002_auto_20151021_1412.py
Normal file
@@ -0,0 +1,19 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('pretixbase', '0001_initial'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='quota',
|
||||
name='size',
|
||||
field=models.PositiveIntegerField(help_text='Leave empty for an unlimited number of tickets.', verbose_name='Total capacity', blank=True, null=True),
|
||||
),
|
||||
]
|
||||
@@ -1,4 +1,5 @@
|
||||
from itertools import product
|
||||
import sys
|
||||
|
||||
from django.db import models
|
||||
from django.db.models import Q, Case, Count, Sum, When
|
||||
@@ -315,7 +316,8 @@ class Item(Versionable):
|
||||
if self.properties.count() > 0: # NOQA
|
||||
raise ValueError('Do not call this directly on items which have properties '
|
||||
'but call this on their ItemVariation objects')
|
||||
return min([q.availability() for q in self.quotas.all()])
|
||||
return min([q.availability() for q in self.quotas.all()],
|
||||
key=lambda s: (s[0], s[1] if s[1] is not None else sys.maxsize))
|
||||
|
||||
def check_restrictions(self):
|
||||
"""
|
||||
@@ -513,7 +515,8 @@ class ItemVariation(Versionable):
|
||||
|
||||
:returns: any of the return codes of :py:meth:`Quota.availability()`.
|
||||
"""
|
||||
return min([q.availability() for q in self.quotas.all()])
|
||||
return min([q.availability() for q in self.quotas.all()],
|
||||
key=lambda s: (s[0], s[1] if s[1] is not None else sys.maxsize))
|
||||
|
||||
def to_variation_dict(self):
|
||||
"""
|
||||
@@ -769,7 +772,9 @@ class Quota(Versionable):
|
||||
verbose_name=_("Name")
|
||||
)
|
||||
size = models.PositiveIntegerField(
|
||||
verbose_name=_("Total capacity")
|
||||
verbose_name=_("Total capacity"),
|
||||
null=True, blank=True,
|
||||
help_text=_("Leave empty for an unlimited number of tickets.")
|
||||
)
|
||||
items = VersionedManyToManyField(
|
||||
Item,
|
||||
@@ -810,6 +815,9 @@ class Quota(Versionable):
|
||||
and the second is the number of available tickets.
|
||||
"""
|
||||
size_left = self.size
|
||||
if size_left is None:
|
||||
return Quota.AVAILABILITY_OK, None
|
||||
|
||||
# TODO: Test for interference with old versions of Item-Quota-relations, etc.
|
||||
# TODO: Prevent corner-cases like people having ordered an item before it got
|
||||
# its first variationsadde
|
||||
|
||||
@@ -228,10 +228,11 @@ class Order(Versionable):
|
||||
else:
|
||||
# Use cached version
|
||||
quota = quota_cache[quota.identity]
|
||||
quota.cached_availability -= 1
|
||||
if quota.cached_availability < 0:
|
||||
# This quota is sold out/currently unavailable, so do not sell this at all
|
||||
raise Quota.QuotaExceededException(error_messages['unavailable'])
|
||||
if quota.cached_availability is not None:
|
||||
quota.cached_availability -= 1
|
||||
if quota.cached_availability < 0:
|
||||
# This quota is sold out/currently unavailable, so do not sell this at all
|
||||
raise Quota.QuotaExceededException(error_messages['unavailable'])
|
||||
except Quota.QuotaExceededException as e:
|
||||
return str(e)
|
||||
return True
|
||||
|
||||
@@ -104,7 +104,7 @@ def _add_items(event, items, session, expiry):
|
||||
quota_ok = i[2]
|
||||
for quota in quotas:
|
||||
avail = quota.availability()
|
||||
if avail[1] < i[2]:
|
||||
if avail[1] is not None and avail[1] < i[2]:
|
||||
# This quota is not available or less than i[2] items are left, so we have to
|
||||
# reduce the number of bought items
|
||||
if avail[0] != Quota.AVAILABILITY_OK:
|
||||
|
||||
@@ -2,8 +2,12 @@
|
||||
{% if availability.0 == 10 %}
|
||||
<span class="label label-warning">{% trans "Sold out (pending orders)" %}</span>
|
||||
{% elif availability.0 == 100 %}
|
||||
<span class="label label-success">{% blocktrans trimmed with num=availability.1 %}
|
||||
{{ num }} available{% endblocktrans %}</span>
|
||||
{% if availability.1 != None %}
|
||||
<span class="label label-success">{% blocktrans trimmed with num=availability.1 %}
|
||||
{{ num }} available{% endblocktrans %}</span>
|
||||
{% else %}
|
||||
<span class="label label-success">{% trans "Unlimited" %}</span>
|
||||
{% endif %}
|
||||
{% elif availability.0 == 20 %}
|
||||
<span class="label label-warning">{% trans "Sold out (or reserved)" %}</span>
|
||||
{% elif availability.0 == 0 %}
|
||||
|
||||
@@ -303,6 +303,19 @@ class QuotaTestCase(BaseQuotaTestCase):
|
||||
quota2.save()
|
||||
self.assertEqual(self.item1.check_quotas(), (Quota.AVAILABILITY_GONE, 0))
|
||||
|
||||
def test_unlimited(self):
|
||||
self.quota.items.add(self.item1)
|
||||
order = Order.objects.create(event=self.event, status=Order.STATUS_PAID,
|
||||
expires=now() + timedelta(days=3),
|
||||
total=2)
|
||||
OrderPosition.objects.create(order=order, item=self.item1, price=2)
|
||||
OrderPosition.objects.create(order=order, item=self.item1, price=2)
|
||||
self.assertEqual(self.item1.check_quotas(), (Quota.AVAILABILITY_GONE, 0))
|
||||
|
||||
self.quota.size = None
|
||||
self.quota.save()
|
||||
self.assertEqual(self.item1.check_quotas(), (Quota.AVAILABILITY_OK, None))
|
||||
|
||||
|
||||
class OrderTestCase(BaseQuotaTestCase):
|
||||
def setUp(self):
|
||||
|
||||
Reference in New Issue
Block a user