Coverage for api\views\ticket.py: 49%

55 statements  

« prev     ^ index     » next       coverage.py v7.10.7, created at 2025-10-13 15:18 +0200

1from api.models import Ticket 

2from api.serializers import TicketSerializer, OffreSerializer, EvenementSerializer 

3from rest_framework.permissions import IsAuthenticated 

4from api.serializers.ticket import PanierItemSerializer 

5from rest_framework import generics, status 

6from rest_framework.response import Response 

7 

8from authentication.permissions import IsAdmin 

9 

10 

11class TicketClientListView(generics.ListAPIView): 

12 """ 

13 Liste les tickets appartenant à l'utilisateur connecté. 

14 

15 Cette vue renvoie uniquement les tickets de l'utilisateur authentifié, 

16 triés par date d'achat (du plus ancien au plus récent). 

17 L'accès est restreint aux utilisateurs authentifiés. 

18 

19 :cvar serializer_class: Sérialiseur utilisé pour convertir les tickets en JSON. 

20 :type serializer_class: TicketSerializer 

21 :cvar permission_classes: Permissions requises pour accéder à la vue. 

22 :type permission_classes: list[rest_framework.permissions.BasePermission] 

23 """ 

24 

25 serializer_class = TicketSerializer 

26 permission_classes = [IsAuthenticated] 

27 

28 def get_queryset(self): 

29 """ 

30 Retourne les tickets de l'utilisateur actuellement connecté. 

31 

32 Cette méthode filtre le queryset des tickets pour ne conserver 

33 que ceux associés à `request.user` et les trie par `date_achat`. 

34 

35 :return: Liste des tickets de l'utilisateur connecté. 

36 :rtype: QuerySet[Ticket] 

37 """ 

38 return Ticket.objects.filter(client=self.request.user.client_profile).order_by("date_achat") 

39 

40class TicketListView(generics.ListAPIView): 

41 """ 

42 Liste les tickets. 

43 

44 Cette vue renvoie touts les tickets, 

45 triés par date d'achat (du plus ancien au plus récent). 

46 L'accès est restreint aux Administrateurs. 

47 

48 :cvar serializer_class: Sérialiseur utilisé pour convertir les tickets en JSON. 

49 :type serializer_class: TicketSerializer 

50 :cvar permission_classes: Permissions requises pour accéder à la vue. 

51 :type permission_classes: list[rest_framework.permissions.BasePermission] 

52 """ 

53 

54 serializer_class = TicketSerializer 

55 permission_classes = [IsAdmin] 

56 

57 def get_queryset(self): 

58 """ 

59 Retourne les tickets. 

60 

61 :return: Liste des tickets de l'utilisateur connecté. 

62 :rtype: QuerySet[Ticket] 

63 """ 

64 return Ticket.objects.all().order_by("date_achat") 

65 

66class TicketClientDetailView(generics.RetrieveAPIView): 

67 """ 

68 Récupère les détails d'un ticket spécifique appartenant à l'utilisateur connecté. 

69 

70 Cette vue permet à un utilisateur authentifié de voir les détails 

71 d'un ticket qu'il possède, identifié par son ID. 

72 L'accès est restreint aux utilisateurs authentifiés. 

73 

74 :cvar serializer_class: Sérialiseur utilisé pour convertir le ticket en JSON. 

75 :type serializer_class: TicketSerializer 

76 :cvar permission_classes: Permissions requises pour accéder à la vue. 

77 :type permission_classes: list[rest_framework.permissions.BasePermission] 

78 """ 

79 

80 serializer_class = TicketSerializer 

81 permission_classes = [IsAuthenticated] 

82 

83 def get_queryset(self): 

84 """ 

85 Retourne les tickets de l'utilisateur actuellement connecté. 

86 

87 Cette méthode filtre le queryset des tickets pour ne conserver 

88 que ceux associés à `request.user`. 

89 

90 :return: Liste des tickets de l'utilisateur connecté. 

91 :rtype: QuerySet[Ticket] 

92 """ 

93 return Ticket.objects.filter(client=self.request.user.client_profile) 

94 

95class TicketDetailView(generics.RetrieveAPIView): 

96 """ 

97 Récupère les détails d'un ticket. 

98 

99 Cette vue permet les détails 

100 L'accès est restreint aux administrateurs. 

101 

102 :cvar serializer_class: Sérialiseur utilisé pour convertir le ticket en JSON. 

103 :type serializer_class: TicketSerializer 

104 :cvar permission_classes: Permissions requises pour accéder à la vue. 

105 :type permission_classes: list[rest_framework.permissions.BasePermission] 

106 """ 

107 

108 serializer_class = TicketSerializer 

109 permission_classes = [IsAdmin] 

110 

111 def get_queryset(self): 

112 """ 

113 Retourne les tickets de l'utilisateur actuellement connecté. 

114 

115 Cette méthode filtre le queryset des tickets pour ne conserver 

116 que ceux associés à `request.user`. 

117 

118 :return: Liste des tickets de l'utilisateur connecté. 

119 :rtype: QuerySet[Ticket] 

120 """ 

121 return Ticket.objects.all() 

122 

123class TicketBatchCreateView(generics.GenericAPIView): 

124 """ 

125 Vue pour créer plusieurs tickets à partir du panier de l'utilisateur connecté. 

126 

127 Reçoit un tableau `items` contenant `offreId`, `evenementId` et `quantity`. 

128 Crée autant de tickets que possible pour chaque offre. 

129 """ 

130 permission_classes = [IsAuthenticated] 

131 serializer_class = PanierItemSerializer 

132 

133 def post(self, request, *args, **kwargs): 

134 items_data = request.data.get("items") 

135 if not items_data or not isinstance(items_data, list): 

136 return Response( 

137 {"detail": "Le champ 'items' est requis et doit être un tableau."}, 

138 status=status.HTTP_400_BAD_REQUEST 

139 ) 

140 

141 client_profile = getattr(request.user, 'client_profile', None) 

142 if not client_profile: 

143 return Response( 

144 {'detail': "Client introuvable."}, 

145 status=status.HTTP_400_BAD_REQUEST 

146 ) 

147 

148 tickets_created = [] 

149 tickets_uncreated = [] 

150 

151 for item_data in items_data: 

152 serializer = self.get_serializer(data=item_data) 

153 serializer.is_valid(raise_exception=True) 

154 

155 offre = serializer.validated_data['offre'] 

156 evenement = serializer.validated_data['evenement'] 

157 quantity = serializer.validated_data['quantity'] 

158 

159 for _ in range(quantity): 

160 if evenement.nb_place_restante >= offre.nb_personne: 

161 evenement.nb_place_restante -= offre.nb_personne 

162 evenement.save() 

163 ticket = Ticket( 

164 client=client_profile, 

165 evenement=evenement, 

166 offre=offre, 

167 statut='valide' 

168 ) 

169 ticket.save() 

170 tickets_created.append(ticket) 

171 

172 else: 

173 tickets_uncreated.append({ 

174 "offre": offre.libelle, 

175 "evenement": evenement.description, 

176 "reason": "Places insuffisantes" 

177 }) 

178 

179 serrialised_ticket = TicketSerializer(tickets_created, many=True) 

180 return Response( 

181 {"tickets": serrialised_ticket.data, "erreurs": tickets_uncreated}, 

182 status=status.HTTP_201_CREATED 

183 )