Coverage for website/sales/api/v2/views.py: 68.87%
84 statements
« prev ^ index » next coverage.py v7.6.7, created at 2025-08-14 10:31 +0000
« prev ^ index » next coverage.py v7.6.7, created at 2025-08-14 10:31 +0000
1from django.db.models import Q
3from oauth2_provider.contrib.rest_framework import IsAuthenticatedOrTokenHasScope
4from rest_framework.exceptions import PermissionDenied
5from rest_framework.generics import GenericAPIView
6from rest_framework.permissions import DjangoModelPermissionsOrAnonReadOnly
7from rest_framework.response import Response
8from rest_framework.schemas.openapi import AutoSchema
10from sales import services
11from sales.api.v2.admin.serializers.order import OrderListSerializer
12from sales.api.v2.admin.views import (
13 OrderDetailView,
14 OrderListView,
15 ShiftDetailView,
16 ShiftListView,
17)
18from sales.api.v2.serializers.user_order import UserOrderSerializer
19from sales.api.v2.serializers.user_shift import UserShiftSerializer
20from sales.models.order import Order
21from sales.models.shift import Shift
22from thaliawebsite.api.v2.permissions import IsAuthenticatedOrTokenHasScopeForMethod
25class UserShiftListView(ShiftListView):
26 serializer_class = UserShiftSerializer
27 # queryset = SelfOrderPeriod.objects.all()
28 permission_classes = [
29 IsAuthenticatedOrTokenHasScope,
30 DjangoModelPermissionsOrAnonReadOnly,
31 ]
32 required_scopes = ["sales:read"]
35class UserShiftDetailView(ShiftDetailView):
36 serializer_class = UserShiftSerializer
37 # queryset = SelfOrderPeriod.objects.all()
38 permission_classes = [
39 IsAuthenticatedOrTokenHasScope,
40 DjangoModelPermissionsOrAnonReadOnly,
41 ]
42 required_scopes = ["sales:read"]
45class UserOrderListView(OrderListView):
46 permission_classes = [
47 IsAuthenticatedOrTokenHasScopeForMethod,
48 ]
49 required_scopes_per_method = {
50 "GET": ["sales:read"],
51 "POST": ["sales:order"],
52 }
53 method_serializer_classes = {
54 ("GET",): OrderListSerializer,
55 ("POST",): UserOrderSerializer,
56 }
58 def create(self, request, *args, **kwargs):
59 shift = Shift.objects.get(pk=kwargs["pk"])
60 if not shift.user_orders_allowed: 60 ↛ 61line 60 didn't jump to line 61 because the condition on line 60 was never true
61 raise PermissionDenied
62 return super().create(request, *args, **kwargs)
64 def perform_create(self, serializer):
65 serializer.save(
66 payer_id=self.request.member.pk, created_by_id=self.request.member.pk
67 )
69 def get_queryset(self):
70 queryset = super().get_queryset()
71 return queryset.filter(
72 Q(payer=self.request.member) | Q(created_by=self.request.member)
73 )
76class UserOrderDetailView(OrderDetailView):
77 serializer_class = UserOrderSerializer
78 permission_classes = [
79 IsAuthenticatedOrTokenHasScopeForMethod,
80 ]
81 required_scopes_per_method = {
82 "GET": ["sales:read"],
83 "PATCH": ["sales:order"],
84 "PUT": ["sales:order"],
85 "DELETE": ["sales:order"],
86 }
88 def get_queryset(self):
89 queryset = super().get_queryset()
90 return queryset.filter(
91 Q(payer=self.request.member) | Q(created_by=self.request.member)
92 )
94 def update(self, request, *args, **kwargs):
95 if not self.get_object().shift.user_orders_allowed:
96 raise PermissionDenied
97 if self.get_object().payment:
98 raise PermissionDenied
99 return super().update(request, *args, **kwargs)
101 def partial_update(self, request, *args, **kwargs):
102 if not self.get_object().shift.user_orders_allowed:
103 raise PermissionDenied
104 if self.get_object().payment:
105 raise PermissionDenied
106 return super().partial_update(request, *args, **kwargs)
108 def destroy(self, request, *args, **kwargs):
109 if not self.get_object().shift.user_orders_allowed:
110 raise PermissionDenied
111 if self.get_object().payment:
112 raise PermissionDenied
115class OrderClaimView(GenericAPIView):
116 """Claims an order to be paid by the current user."""
118 class OrderClaimViewSchema(AutoSchema):
119 def get_request_serializer(self, path, method):
120 # This endpoint does not expect any content in the request body.
121 return None
123 queryset = Order.objects.all()
124 serializer_class = UserOrderSerializer
125 schema = OrderClaimViewSchema(operation_id_base="claimOrder")
126 permission_classes = [IsAuthenticatedOrTokenHasScope]
127 required_scopes = ["sales:order"]
129 def patch(self, request, *args, **kwargs):
130 if request.member is None: 130 ↛ 131line 130 didn't jump to line 131 because the condition on line 130 was never true
131 raise PermissionDenied(
132 detail="You need to be a member to pay for an order."
133 )
135 order = self.get_object()
136 if order.payment:
137 raise PermissionDenied(detail="This order was already paid for.")
139 if order.payer is not None and order.payer != request.member:
140 raise PermissionDenied(detail="This order is not yours.")
142 order.payer = request.member
143 order.save()
145 if order.age_restricted and not services.is_adult(request.member):
146 raise PermissionDenied(
147 "The age restrictions on this order do not allow you to pay for this order."
148 )
150 serializer = self.get_serializer(order)
151 return Response(serializer.data)