Re-added the ability to restrict a product sale by time

This commit is contained in:
Raphael Michel
2015-12-06 18:18:54 +01:00
parent 4a1122a862
commit e70485e7fb
9 changed files with 149 additions and 22 deletions

View File

@@ -0,0 +1,24 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('pretixbase', '0004_auto_20151024_0848'),
]
operations = [
migrations.AddField(
model_name='item',
name='available_from',
field=models.DateTimeField(null=True, help_text='This product will not be sold before the given date.', blank=True, verbose_name='Available from'),
),
migrations.AddField(
model_name='item',
name='available_until',
field=models.DateTimeField(null=True, help_text='This product will not be sold after the given date.', blank=True, verbose_name='Available to'),
),
]

View File

@@ -1,6 +1,5 @@
import sys
from datetime import datetime
from decimal import Decimal
from itertools import product
from django.db import models
@@ -8,7 +7,7 @@ from django.db.models import Q, Case, Count, Sum, When
from django.utils.functional import cached_property
from django.utils.timezone import now
from django.utils.translation import ugettext_lazy as _
from typing import List, Tuple, Union
from typing import List, Tuple
from versions.models import VersionedForeignKey, VersionedManyToManyField
from pretix.base.i18n import I18nCharField, I18nTextField
@@ -98,6 +97,10 @@ class Item(Versionable):
:type admission: bool
:param picture: A product picture to be shown next to the product description.
:type picture: File
:param available_from: The date this product goes on sale
:type available_from: datetime
:param available_until: The date until when the product is on sale
:type available_until: datetime
"""
@@ -152,6 +155,16 @@ class Item(Versionable):
null=True, blank=True,
upload_to=itempicture_upload_to
)
available_from = models.DateTimeField(
verbose_name=_("Available from"),
null=True, blank=True,
help_text=_('This product will not be sold before the given date.')
)
available_until = models.DateTimeField(
verbose_name=_("Available until"),
null=True, blank=True,
help_text=_('This product will not be sold after the given date.')
)
class Meta:
verbose_name = _("Product")
@@ -171,6 +184,19 @@ class Item(Versionable):
if self.event:
self.event.get_cache().clear()
def is_available(self) -> bool:
"""
Returns whether this item is available according to its ``active`` flag
and its ``available_from`` and ``available_until`` fields
"""
if not self.active:
return False
if self.available_from and self.available_from > now():
return False
if self.available_until and self.available_until < now():
return False
return True
def get_all_variations(self, use_cache: bool=False) -> List[VariationDict]:
"""
This method returns a list containing all variations of this

View File

@@ -93,7 +93,7 @@ def _add_items(event: Event, items: List[Tuple[str, Optional[str], int]],
# Fetch all quotas. If there are no quotas, this item is not allowed to be sold.
quotas = list(item.quotas.all()) if variation is None else list(variation.quotas.all())
if len(quotas) == 0 or not item.active:
if len(quotas) == 0 or not item.is_available():
err = err or error_messages['unavailable']
continue

View File

@@ -137,6 +137,8 @@ class ItemFormGeneral(VersionedModelForm):
'picture',
'default_price',
'tax_rate',
'available_from',
'available_until',
]

View File

@@ -18,6 +18,11 @@
{% bootstrap_field form.default_price layout="horizontal" %}
{% bootstrap_field form.tax_rate layout="horizontal" %}
</fieldset>
<fieldset>
<legend>{% trans "Availability" %}</legend>
{% bootstrap_field form.available_from layout="horizontal" %}
{% bootstrap_field form.available_until layout="horizontal" %}
</fieldset>
<div class="form-group submit-group">
<button type="submit" class="btn btn-primary btn-save">
{% trans "Save" %}

View File

@@ -1,6 +1,7 @@
import sys
from django.db.models import Count
from django.db.models import Q, Count
from django.utils.timezone import now
from django.views.generic import TemplateView
from pretix.presale.views import CartMixin, EventViewMixin
@@ -13,7 +14,9 @@ class EventIndex(EventViewMixin, CartMixin, TemplateView):
context = super().get_context_data(**kwargs)
# Fetch all items
items = self.request.event.items.all().filter(
active=True
Q(active=True)
& Q(Q(available_from__isnull=True) | Q(available_from__lte=now()))
& Q(Q(available_until__isnull=True) | Q(available_until__gte=now()))
).select_related(
'category', # for re-grouping
).prefetch_related(