forked from CGM_Public/pretix_original
Add unlimited_items_per_order-flag to Sales Channels (#1508)
* Add unlimited_items_per_order-flag to Sales Channels * Test for unlimited_items_per_order Sales Channels-flag * Fix test
This commit is contained in:
committed by
Raphael Michel
parent
fd7ad3cb16
commit
0474651070
@@ -53,6 +53,14 @@ class SalesChannel:
|
|||||||
"""
|
"""
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
@property
|
||||||
|
def unlimited_items_per_order(self) -> bool:
|
||||||
|
"""
|
||||||
|
If this property is ``True``, purchases made using this sales channel are not limited to the maximum amount of
|
||||||
|
items defined in the event settings.
|
||||||
|
"""
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
def get_all_sales_channels():
|
def get_all_sales_channels():
|
||||||
global _ALL_CHANNELS
|
global _ALL_CHANNELS
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ from django.utils.timezone import make_aware, now
|
|||||||
from django.utils.translation import pgettext_lazy, ugettext as _
|
from django.utils.translation import pgettext_lazy, ugettext as _
|
||||||
from django_scopes import scopes_disabled
|
from django_scopes import scopes_disabled
|
||||||
|
|
||||||
|
from pretix.base.channels import get_all_sales_channels
|
||||||
from pretix.base.i18n import language
|
from pretix.base.i18n import language
|
||||||
from pretix.base.models import (
|
from pretix.base.models import (
|
||||||
CartPosition, Event, InvoiceAddress, Item, ItemBundle, ItemVariation, Seat,
|
CartPosition, Event, InvoiceAddress, Item, ItemBundle, ItemVariation, Seat,
|
||||||
@@ -218,13 +219,14 @@ class CartManager:
|
|||||||
})
|
})
|
||||||
|
|
||||||
def _check_max_cart_size(self):
|
def _check_max_cart_size(self):
|
||||||
cartsize = self.positions.filter(addon_to__isnull=True).count()
|
if not get_all_sales_channels()[self._sales_channel].unlimited_items_per_order:
|
||||||
cartsize += sum([op.count for op in self._operations if isinstance(op, self.AddOperation) and not op.addon_to])
|
cartsize = self.positions.filter(addon_to__isnull=True).count()
|
||||||
cartsize -= len([1 for op in self._operations if isinstance(op, self.RemoveOperation) if
|
cartsize += sum([op.count for op in self._operations if isinstance(op, self.AddOperation) and not op.addon_to])
|
||||||
not op.position.addon_to_id])
|
cartsize -= len([1 for op in self._operations if isinstance(op, self.RemoveOperation) if
|
||||||
if cartsize > int(self.event.settings.max_items_per_order):
|
not op.position.addon_to_id])
|
||||||
# TODO: i18n plurals
|
if cartsize > int(self.event.settings.max_items_per_order):
|
||||||
raise CartError(_(error_messages['max_items']) % (self.event.settings.max_items_per_order,))
|
# TODO: i18n plurals
|
||||||
|
raise CartError(_(error_messages['max_items']) % (self.event.settings.max_items_per_order,))
|
||||||
|
|
||||||
def _check_item_constraints(self, op):
|
def _check_item_constraints(self, op):
|
||||||
if isinstance(op, self.AddOperation) or isinstance(op, self.ExtendOperation):
|
if isinstance(op, self.AddOperation) or isinstance(op, self.ExtendOperation):
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ from django.views import View
|
|||||||
from django.views.decorators.csrf import csrf_exempt
|
from django.views.decorators.csrf import csrf_exempt
|
||||||
from django.views.generic import TemplateView
|
from django.views.generic import TemplateView
|
||||||
|
|
||||||
|
from pretix.base.channels import get_all_sales_channels
|
||||||
from pretix.base.models import ItemVariation, Quota, SeatCategoryMapping
|
from pretix.base.models import ItemVariation, Quota, SeatCategoryMapping
|
||||||
from pretix.base.models.event import SubEvent
|
from pretix.base.models.event import SubEvent
|
||||||
from pretix.base.models.items import ItemBundle
|
from pretix.base.models.items import ItemBundle
|
||||||
@@ -119,7 +120,10 @@ def get_grouped_items(event, subevent=None, voucher=None, channel='web', require
|
|||||||
item.available_variations = [v for v in item.available_variations
|
item.available_variations = [v for v in item.available_variations
|
||||||
if v.pk == voucher.variation_id]
|
if v.pk == voucher.variation_id]
|
||||||
|
|
||||||
max_per_order = item.max_per_order or int(event.settings.max_items_per_order)
|
if get_all_sales_channels()[channel].unlimited_items_per_order:
|
||||||
|
max_per_order = sys.maxsize
|
||||||
|
else:
|
||||||
|
max_per_order = item.max_per_order or int(event.settings.max_items_per_order)
|
||||||
|
|
||||||
if item.hidden_if_available:
|
if item.hidden_if_available:
|
||||||
q = item.hidden_if_available.availability(_cache=quota_cache)
|
q = item.hidden_if_available.availability(_cache=quota_cache)
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ from datetime import timedelta
|
|||||||
from decimal import Decimal
|
from decimal import Decimal
|
||||||
|
|
||||||
from bs4 import BeautifulSoup
|
from bs4 import BeautifulSoup
|
||||||
|
from django.dispatch import receiver
|
||||||
from django.test import TestCase
|
from django.test import TestCase
|
||||||
from django.utils.timezone import now
|
from django.utils.timezone import now
|
||||||
from django_countries.fields import Country
|
from django_countries.fields import Country
|
||||||
@@ -21,6 +22,7 @@ from pretix.base.models.items import (
|
|||||||
from pretix.base.services.cart import (
|
from pretix.base.services.cart import (
|
||||||
CartError, CartManager, error_messages, update_tax_rates,
|
CartError, CartManager, error_messages, update_tax_rates,
|
||||||
)
|
)
|
||||||
|
from pretix.base.signals import register_sales_channels
|
||||||
from pretix.testutils.scope import classscope
|
from pretix.testutils.scope import classscope
|
||||||
from pretix.testutils.sessions import get_cart_session_key
|
from pretix.testutils.sessions import get_cart_session_key
|
||||||
|
|
||||||
@@ -29,7 +31,15 @@ class FoobarSalesChannel(SalesChannel):
|
|||||||
identifier = "bar"
|
identifier = "bar"
|
||||||
verbose_name = "Foobar"
|
verbose_name = "Foobar"
|
||||||
icon = "home"
|
icon = "home"
|
||||||
testmode_supported = True
|
testmode_supported = False
|
||||||
|
unlimited_items_per_order = True
|
||||||
|
|
||||||
|
|
||||||
|
@receiver(register_sales_channels, dispatch_uid="test_cart_register_sales_channels")
|
||||||
|
def base_sales_channels(sender, **kwargs):
|
||||||
|
return (
|
||||||
|
FoobarSalesChannel(),
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class CartTestMixin:
|
class CartTestMixin:
|
||||||
@@ -816,6 +826,23 @@ class CartTest(CartTestMixin, TestCase):
|
|||||||
with scopes_disabled():
|
with scopes_disabled():
|
||||||
self.assertEqual(CartPosition.objects.filter(cart_id=self.session_key, event=self.event).count(), 1)
|
self.assertEqual(CartPosition.objects.filter(cart_id=self.session_key, event=self.event).count(), 1)
|
||||||
|
|
||||||
|
def test_max_items_unlimited_sales_channel(self):
|
||||||
|
with scopes_disabled():
|
||||||
|
CartPosition.objects.create(
|
||||||
|
event=self.event, cart_id=self.session_key, item=self.ticket,
|
||||||
|
price=23, expires=now() + timedelta(minutes=10)
|
||||||
|
)
|
||||||
|
self.event.settings.max_items_per_order = 5
|
||||||
|
response = self.client.post('/%s/%s/cart/add' % (self.orga.slug, self.event.slug), {
|
||||||
|
'item_%d' % self.ticket.id: '5',
|
||||||
|
}, follow=True, PRETIX_SALES_CHANNEL=FoobarSalesChannel)
|
||||||
|
self.assertRedirects(response, '/%s/%s/?require_cookie=true' % (self.orga.slug, self.event.slug),
|
||||||
|
target_status_code=200)
|
||||||
|
doc = BeautifulSoup(response.rendered_content, "lxml")
|
||||||
|
self.assertNotIn('more than', doc.select('.alert-danger')[0].text)
|
||||||
|
with scopes_disabled():
|
||||||
|
self.assertEqual(CartPosition.objects.filter(cart_id=self.session_key, event=self.event).count(), 1)
|
||||||
|
|
||||||
def test_max_per_item_failed(self):
|
def test_max_per_item_failed(self):
|
||||||
self.ticket.max_per_order = 2
|
self.ticket.max_per_order = 2
|
||||||
self.ticket.save()
|
self.ticket.save()
|
||||||
|
|||||||
Reference in New Issue
Block a user