forked from CGM_Public/pretix_original
Isolate cart sessions
This commit is contained in:
@@ -6,6 +6,7 @@ from django.db.models import Count, Prefetch, Q
|
||||
from django.http import FileResponse, Http404, JsonResponse
|
||||
from django.shortcuts import get_object_or_404, redirect
|
||||
from django.utils import translation
|
||||
from django.utils.crypto import get_random_string
|
||||
from django.utils.functional import cached_property
|
||||
from django.utils.timezone import now
|
||||
from django.utils.translation import ugettext as _
|
||||
@@ -39,9 +40,13 @@ class CartActionMixin:
|
||||
def get_error_url(self):
|
||||
return self.get_next_url()
|
||||
|
||||
@cached_property
|
||||
def cart_session(self):
|
||||
return cart_session(self.request)
|
||||
|
||||
@cached_property
|
||||
def invoice_address(self):
|
||||
iapk = self.request.session.get('invoice_address_{}'.format(self.request.event.pk))
|
||||
iapk = self.cart_session.get('invoice_address')
|
||||
if not iapk:
|
||||
return InvoiceAddress()
|
||||
|
||||
@@ -124,19 +129,49 @@ class CartActionMixin:
|
||||
return items
|
||||
|
||||
|
||||
def create_empty_cart_id(request):
|
||||
current_id = request.session.get('current_cart_event_{}'.format(request.event.pk))
|
||||
if current_id and current_id in request.session.get('carts', {}):
|
||||
del request.session['carts'][current_id]
|
||||
del request.session['current_cart_event_{}'.format(request.event.pk)]
|
||||
return get_or_create_cart_id(request)
|
||||
|
||||
|
||||
def get_or_create_cart_id(request):
|
||||
current_id = request.session.get('current_cart_event_{}'.format(request.event.pk))
|
||||
if current_id and current_id in request.session.get('carts', {}):
|
||||
return current_id
|
||||
else:
|
||||
while True:
|
||||
new_id = get_random_string(length=32)
|
||||
if not CartPosition.objects.filter(cart_id=new_id).exists():
|
||||
break
|
||||
|
||||
if 'carts' not in request.session:
|
||||
request.session['carts'] = {}
|
||||
request.session['carts'][new_id] = {}
|
||||
request.session['current_cart_event_{}'.format(request.event.pk)] = new_id
|
||||
return new_id
|
||||
|
||||
|
||||
def cart_session(request):
|
||||
request.session.modified = True
|
||||
return request.session['carts'][get_or_create_cart_id(request)]
|
||||
|
||||
|
||||
class CartRemove(EventViewMixin, CartActionMixin, AsyncAction, View):
|
||||
task = remove_cart_position
|
||||
known_errortypes = ['CartError']
|
||||
|
||||
def get_success_message(self, value):
|
||||
if CartPosition.objects.filter(cart_id=self.request.session.session_key).exists():
|
||||
if CartPosition.objects.filter(cart_id=get_or_create_cart_id(self.request)).exists():
|
||||
return _('Your cart has been updated.')
|
||||
else:
|
||||
return _('Your cart is now empty.')
|
||||
|
||||
def post(self, request, *args, **kwargs):
|
||||
if 'id' in request.POST:
|
||||
return self.do(self.request.event.id, request.POST.get('id'), self.request.session.session_key, translation.get_language())
|
||||
return self.do(self.request.event.id, request.POST.get('id'), get_or_create_cart_id(self.request), translation.get_language())
|
||||
else:
|
||||
if 'ajax' in self.request.GET or 'ajax' in self.request.POST:
|
||||
return JsonResponse({
|
||||
@@ -154,7 +189,7 @@ class CartClear(EventViewMixin, CartActionMixin, AsyncAction, View):
|
||||
return _('Your cart is now empty.')
|
||||
|
||||
def post(self, request, *args, **kwargs):
|
||||
return self.do(self.request.event.id, self.request.session.session_key, translation.get_language())
|
||||
return self.do(self.request.event.id, get_or_create_cart_id(self.request), translation.get_language())
|
||||
|
||||
|
||||
class CartAdd(EventViewMixin, CartActionMixin, AsyncAction, View):
|
||||
@@ -167,7 +202,7 @@ class CartAdd(EventViewMixin, CartActionMixin, AsyncAction, View):
|
||||
def post(self, request, *args, **kwargs):
|
||||
items = self._items_from_post_data()
|
||||
if items:
|
||||
return self.do(self.request.event.id, items, self.request.session.session_key, translation.get_language(),
|
||||
return self.do(self.request.event.id, items, get_or_create_cart_id(self.request), translation.get_language(),
|
||||
self.invoice_address.pk)
|
||||
else:
|
||||
if 'ajax' in self.request.GET or 'ajax' in self.request.POST:
|
||||
@@ -299,7 +334,7 @@ class RedeemView(NoSearchIndexViewMixin, EventViewMixin, TemplateView):
|
||||
|
||||
redeemed_in_carts = CartPosition.objects.filter(
|
||||
Q(voucher=self.voucher) & Q(event=request.event) &
|
||||
(Q(expires__gte=now()) | Q(cart_id=request.session.session_key))
|
||||
(Q(expires__gte=now()) | Q(cart_id=get_or_create_cart_id(request)))
|
||||
)
|
||||
v_avail = self.voucher.max_usages - self.voucher.redeemed - redeemed_in_carts.count()
|
||||
if v_avail < 1:
|
||||
@@ -337,7 +372,7 @@ class AnswerDownload(EventViewMixin, View):
|
||||
answid = kwargs.get('answer')
|
||||
answer = get_object_or_404(
|
||||
QuestionAnswer,
|
||||
cartposition__cart_id=self.request.session.session_key,
|
||||
cartposition__cart_id=get_or_create_cart_id(self.request),
|
||||
id=answid
|
||||
)
|
||||
if not answer.file:
|
||||
|
||||
Reference in New Issue
Block a user