Refs #654 -- Writable API methods for waiting list entries (#885)

* Refs #654 -- Writable API methods for waiting list entries

* Update test_waitinglist.py
This commit is contained in:
Raphael Michel
2018-04-29 14:28:32 +02:00
committed by GitHub
parent 32a89d3895
commit 6f30ecb365
9 changed files with 599 additions and 14 deletions

View File

@@ -1,3 +1,5 @@
from rest_framework.exceptions import ValidationError
from pretix.api.serializers.i18n import I18nAwareModelSerializer
from pretix.base.models import WaitingListEntry
@@ -7,3 +9,27 @@ class WaitingListSerializer(I18nAwareModelSerializer):
class Meta:
model = WaitingListEntry
fields = ('id', 'created', 'email', 'voucher', 'item', 'variation', 'locale', 'subevent')
read_only_fields = ('id', 'created', 'voucher')
def validate(self, data):
data = super().validate(data)
event = self.context['event']
full_data = self.to_internal_value(self.to_representation(self.instance)) if self.instance else {}
full_data.update(data)
WaitingListEntry.clean_duplicate(full_data.get('email'), full_data.get('item'), full_data.get('variation'),
full_data.get('subevent'), self.instance.pk if self.instance else None)
WaitingListEntry.clean_itemvar(event, full_data.get('item'), full_data.get('variation'))
WaitingListEntry.clean_subevent(event, full_data.get('subevent'))
if 'item' in data or 'variation' in data:
availability = (
full_data.get('variation').check_quotas(count_waitinglist=True, subevent=full_data.get('subevent'))
if full_data.get('variation')
else full_data.get('item').check_quotas(count_waitinglist=True, subevent=full_data.get('subevent'))
)
if availability[0] == 100:
raise ValidationError("This product is currently available.")
return data

View File

@@ -1,10 +1,14 @@
import django_filters
from django_filters.rest_framework import DjangoFilterBackend, FilterSet
from rest_framework import viewsets
from rest_framework.decorators import detail_route
from rest_framework.exceptions import PermissionDenied, ValidationError
from rest_framework.filters import OrderingFilter
from rest_framework.response import Response
from pretix.api.serializers.waitinglist import WaitingListSerializer
from pretix.base.models import WaitingListEntry
from pretix.base.models import TeamAPIToken, WaitingListEntry
from pretix.base.models.waitinglist import WaitingListException
class WaitingListFilter(FilterSet):
@@ -18,7 +22,7 @@ class WaitingListFilter(FilterSet):
fields = ['item', 'variation', 'email', 'locale', 'has_voucher', 'subevent']
class WaitingListViewSet(viewsets.ReadOnlyModelViewSet):
class WaitingListViewSet(viewsets.ModelViewSet):
serializer_class = WaitingListSerializer
queryset = WaitingListEntry.objects.none()
filter_backends = (DjangoFilterBackend, OrderingFilter)
@@ -26,6 +30,53 @@ class WaitingListViewSet(viewsets.ReadOnlyModelViewSet):
ordering_fields = ('id', 'created', 'email', 'item')
filter_class = WaitingListFilter
permission = 'can_view_orders'
write_permission = 'can_change_orders'
def get_queryset(self):
return self.request.event.waitinglistentries.all()
def get_serializer_context(self):
ctx = super().get_serializer_context()
ctx['event'] = self.request.event
return ctx
def perform_create(self, serializer):
serializer.save(event=self.request.event)
serializer.instance.log_action(
'pretix.event.orders.waitinglist.added',
user=self.request.user,
api_token=(self.request.auth if isinstance(self.request.auth, TeamAPIToken) else None),
)
def perform_update(self, serializer):
if serializer.instance.voucher:
raise PermissionDenied('This entry can not be changed as it has already been assigned a voucher.')
serializer.save(event=self.request.event)
serializer.instance.log_action(
'pretix.event.orders.waitinglist.changed',
user=self.request.user,
api_token=(self.request.auth if isinstance(self.request.auth, TeamAPIToken) else None),
)
def perform_destroy(self, instance):
if instance.voucher:
raise PermissionDenied('This entry can not be deleted as it has already been assigned a voucher.')
instance.log_action(
'pretix.event.orders.waitinglist.deleted',
user=self.request.user,
api_token=(self.request.auth if isinstance(self.request.auth, TeamAPIToken) else None),
)
super().perform_destroy(instance)
@detail_route(methods=['POST'])
def send_voucher(self, *args, **kwargs):
try:
self.get_object().send_voucher(
user=self.request.user,
api_token=(self.request.auth if isinstance(self.request.auth, TeamAPIToken) else None),
)
except WaitingListException as e:
raise ValidationError(str(e))
else:
return Response(status=204)