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

1from django.db.models import Q 

2 

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 

9 

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 

23 

24 

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"] 

33 

34 

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"] 

43 

44 

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 } 

57 

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) 

63 

64 def perform_create(self, serializer): 

65 serializer.save( 

66 payer_id=self.request.member.pk, created_by_id=self.request.member.pk 

67 ) 

68 

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 ) 

74 

75 

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 } 

87 

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 ) 

93 

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) 

100 

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) 

107 

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 

113 

114 

115class OrderClaimView(GenericAPIView): 

116 """Claims an order to be paid by the current user.""" 

117 

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 

122 

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"] 

128 

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 ) 

134 

135 order = self.get_object() 

136 if order.payment: 

137 raise PermissionDenied(detail="This order was already paid for.") 

138 

139 if order.payer is not None and order.payer != request.member: 

140 raise PermissionDenied(detail="This order is not yours.") 

141 

142 order.payer = request.member 

143 order.save() 

144 

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 ) 

149 

150 serializer = self.get_serializer(order) 

151 return Response(serializer.data)