diff --git a/src/pretix/base/migrations/0016_voucher_variation.py b/src/pretix/base/migrations/0016_voucher_variation.py new file mode 100644 index 0000000000..d303b80a01 --- /dev/null +++ b/src/pretix/base/migrations/0016_voucher_variation.py @@ -0,0 +1,21 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.9.2 on 2016-03-20 10:14 +from __future__ import unicode_literals + +import django.db.models.deletion +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('pretixbase', '0015_auto_20160312_1924'), + ] + + operations = [ + migrations.AddField( + model_name='voucher', + name='variation', + field=models.ForeignKey(blank=True, help_text='This variation of the product select above is being used.', null=True, on_delete=django.db.models.deletion.CASCADE, related_name='vouchers', to='pretixbase.ItemVariation', verbose_name='Product variation'), + ), + ] diff --git a/src/pretix/base/models/items.py b/src/pretix/base/models/items.py index b204adb697..739762210e 100644 --- a/src/pretix/base/models/items.py +++ b/src/pretix/base/models/items.py @@ -493,17 +493,18 @@ class Quota(LoggedModel): def count_blocking_vouchers(self) -> int: from pretix.base.models import Voucher return Voucher.objects.filter( - item__quotas__in=[self], - block_quota=True, - redeemed=False + Q(item__quotas__in=[self]) & + Q(block_quota=True) & + Q(redeemed=False) & + self._position_lookup ).count() def count_in_cart(self) -> int: from pretix.base.models import CartPosition return CartPosition.objects.filter( - Q(expires__gte=now()) - & self._position_lookup + Q(expires__gte=now()) & + self._position_lookup ).count() def count_orders(self) -> dict: diff --git a/src/pretix/base/models/vouchers.py b/src/pretix/base/models/vouchers.py index 2b4cba1215..2d1b57759a 100644 --- a/src/pretix/base/models/vouchers.py +++ b/src/pretix/base/models/vouchers.py @@ -5,7 +5,7 @@ from django.utils.translation import ugettext_lazy as _ from .base import LoggedModel from .event import Event -from .items import Item +from .items import Item, ItemVariation from .orders import CartPosition, OrderPosition @@ -63,6 +63,14 @@ class Voucher(LoggedModel): "This product is added to the user's cart if the voucher is redeemed." ) ) + variation = models.ForeignKey( + ItemVariation, related_name='vouchers', + null=True, blank=True, + verbose_name=_("Product variation"), + help_text=_( + "This variation of the product select above is being used." + ) + ) class Meta: verbose_name = _("Voucher") diff --git a/src/pretix/base/services/cart.py b/src/pretix/base/services/cart.py index 5bb207282c..cd29d46528 100644 --- a/src/pretix/base/services/cart.py +++ b/src/pretix/base/services/cart.py @@ -153,7 +153,7 @@ def _add_voucher(event: Event, voucher: str, expiry: datetime, cart_id: str): raise CartError(error_messages['unavailable']) CartPosition.objects.create( - event=event, item=v.item, variation=None, + event=event, item=v.item, variation=v.variation, price=v.price if v.price is not None else v.item.default_price, expires=expiry, cart_id=cart_id, voucher=v ) diff --git a/src/pretix/control/forms/vouchers.py b/src/pretix/control/forms/vouchers.py index 728ddfbbc6..156e979b24 100644 --- a/src/pretix/control/forms/vouchers.py +++ b/src/pretix/control/forms/vouchers.py @@ -1,18 +1,57 @@ +from django import forms +from django.utils.translation import ugettext_lazy as _ + from pretix.base.forms import I18nModelForm -from pretix.base.models import Voucher +from pretix.base.models import Item, ItemVariation, Voucher class VoucherForm(I18nModelForm): + itemvar = forms.ChoiceField( + label=_("Product"), + help_text=_( + "This product is added to the user's cart if the voucher is redeemed." + ) + ) + class Meta: model = Voucher localized_fields = '__all__' fields = [ - 'code', 'valid_until', 'block_quota', 'allow_ignore_quota', 'price', 'item' + 'code', 'valid_until', 'block_quota', 'allow_ignore_quota', 'price' ] def __init__(self, *args, **kwargs): + instance = kwargs.get('instance') + initial = kwargs.get('initial') + if instance: + try: + if instance.variation: + initial['itemvar'] = '%d-%d' % (instance.item.pk, instance.variation.pk) + elif instance.item: + initial['itemvar'] = str(instance.item.pk) + except Item.DoesNotExist: + pass super().__init__(*args, **kwargs) - self.fields['item'].queryset = self.instance.event.items.all() + choices = [] + for i in self.instance.event.items.prefetch_related('variations').all(): + variations = list(i.variations.all()) + if variations: + for v in variations: + choices.append(('%d-%d' % (i.pk, v.pk), '%s – %s' % (i.name, v.value))) + else: + choices.append((str(i.pk), i.name)) + self.fields['itemvar'].choices = choices - def _get_validation_exclusions(self): - return [] + def save(self, commit=True): + if '-' in self.cleaned_data['itemvar']: + itemid, varid = self.cleaned_data['itemvar'].split('-') + else: + itemid, varid = self.cleaned_data['itemvar'], None + self.instance.item = Item.objects.get(pk=itemid, event=self.instance.event) + if varid: + self.instance.variation = ItemVariation.objects.get(pk=varid, item=self.instance.item) + else: + self.instance.variation = None + super().save(commit) + + return ['item'] diff --git a/src/pretix/control/templates/pretixcontrol/vouchers/detail.html b/src/pretix/control/templates/pretixcontrol/vouchers/detail.html index fc9ee5b1bb..adfc6db546 100644 --- a/src/pretix/control/templates/pretixcontrol/vouchers/detail.html +++ b/src/pretix/control/templates/pretixcontrol/vouchers/detail.html @@ -19,7 +19,7 @@ {% bootstrap_field form.block_quota layout="horizontal" %} {% bootstrap_field form.allow_ignore_quota layout="horizontal" %} {% bootstrap_field form.price layout="horizontal" %} - {% bootstrap_field form.item layout="horizontal" %} + {% bootstrap_field form.itemvar layout="horizontal" %}