Coverage for events/serializers.py: 63%

173 statements  

« prev     ^ index     » next       coverage.py v6.4.4, created at 2022-10-14 16:23 -0500

1from rest_framework import serializers 

2from users.models import User 

3from .models import Event, Challenge, Team, Score, Participant, StationCheckIn, Station 

4 

5 

6class TeamScoreSerializer(serializers.ModelSerializer): 

7 class Meta: 

8 model = Team 

9 fields = ["random_slug", "name", "total_score"] 

10 extra_kwargs = { 

11 "total_score": {"read_only": True}, 

12 } 

13 

14 

15class ChallengeSerializer(serializers.ModelSerializer): 

16 score = serializers.SerializerMethodField(read_only=True) 

17 

18 class Meta: 

19 model = Challenge 

20 fields = ["random_slug", "event", "name", "status", "score", "type_of"] 

21 extra_kwargs = {"status": {"read_only": True}} 

22 

23 def get_score(self, challenge): 

24 try: 

25 participant = Participant.objects.get( 

26 event=challenge.event, user=self.context.get("user") 

27 ) 

28 score = challenge.scores.get(team=participant.team) 

29 return score.score 

30 except (Participant.DoesNotExist, Score.DoesNotExist): 

31 return None 

32 

33 

34class EventSerializer(serializers.ModelSerializer): 

35 owner = serializers.CharField(source="owner.name", read_only=True) 

36 is_master_of_ceremony = serializers.SerializerMethodField(read_only=True) 

37 

38 class Meta: 

39 model = Event 

40 fields = [ 

41 "random_slug", 

42 "name", 

43 "date", 

44 "image", 

45 "owner", 

46 "is_master_of_ceremony", 

47 ] 

48 

49 def get_is_master_of_ceremony(self, event): 

50 try: 

51 participant = Participant.objects.get( 

52 event=event, user=self.context.get("user") 

53 ) 

54 return participant.is_master_of_ceremony 

55 except Participant.DoesNotExist: 

56 return None 

57 

58 

59class ParticipantDetailSerializer(serializers.ModelSerializer): 

60 event = EventSerializer(read_only=True) 

61 invited_by = serializers.CharField(source="invited_by.email", read_only=True) 

62 

63 class Meta: 

64 model = Participant 

65 fields = ["random_slug", "event", "is_master_of_ceremony", "rsvp", "invited_by"] 

66 

67 

68class ParticipantSerializer(serializers.ModelSerializer): 

69 email = serializers.EmailField(source="user.email") 

70 

71 class Meta: 

72 model = Participant 

73 fields = ["random_slug", "email", "event", "is_master_of_ceremony"] 

74 

75 def create(self, validated_data): 

76 email = validated_data.get("user").get("email") 

77 user, _ = User.objects.get_or_create(email=email) 

78 validated_data["user"] = user 

79 participant, _ = Participant.objects.get_or_create(**validated_data) 

80 return participant 

81 

82 

83class TeamSerializer(serializers.ModelSerializer): 

84 members = ParticipantSerializer(many=True, read_only=True) 

85 

86 class Meta: 

87 model = Team 

88 fields = ["random_slug", "name", "members", "event"] 

89 extra_kwargs = {"event": {"write_only": True}} 

90 

91 

92class EventDisplaySerializer(EventSerializer): 

93 challenges = ChallengeSerializer(many=True, read_only=True) 

94 teams = serializers.SerializerMethodField(read_only=True) 

95 my_team = serializers.SerializerMethodField(read_only=True) 

96 

97 class Meta: 

98 model = Event 

99 fields = [ 

100 "random_slug", 

101 "name", 

102 "challenges", 

103 "teams", 

104 "date", 

105 "my_team", 

106 "is_master_of_ceremony", 

107 ] 

108 

109 def get_teams(self, instance): 

110 teams = instance.teams.all() 

111 serializer = TeamScoreSerializer(teams, many=True) 

112 data = serializer.data 

113 return sorted(data, key=lambda item: item["total_score"], reverse=True) 

114 

115 def get_my_team(self, instance): 

116 try: 

117 participant = instance.participants.get(user=self.context.get("user")) 

118 return participant.team.random_slug if participant.team else None 

119 except Participant.DoesNotExist: 

120 return None 

121 

122 

123class EventDetailSerializer(EventDisplaySerializer): 

124 participants = serializers.SerializerMethodField(read_only=True) 

125 teams = TeamSerializer(many=True, read_only=True) 

126 

127 class Meta(EventDisplaySerializer.Meta): 

128 fields = ["random_slug", "name", "challenges", "participants", "teams", "date"] 

129 

130 def get_participants(self, instance): 

131 participants = instance.participants.filter(team__isnull=True) 

132 serializer = ParticipantSerializer(participants, many=True) 

133 return serializer.data 

134 

135 

136class SimpleTeamSerializer(serializers.ModelSerializer): 

137 class Meta: 

138 model = Team 

139 fields = ["random_slug", "name"] 

140 read_only_fields = fields 

141 

142 

143class StationCheckInDetailSerializer(serializers.ModelSerializer): 

144 class Meta: 

145 model = StationCheckIn 

146 fields = ["team", "participant", "has_checkin", "updated_at"] 

147 

148 

149class StationSerializer(serializers.ModelSerializer): 

150 check_in = serializers.SerializerMethodField(read_only=True) 

151 

152 class Meta: 

153 model = Station 

154 fields = ["name", "hint", "check_in"] 

155 

156 def get_check_in(self, station): 

157 user = self.context.get("user") 

158 event = station.challenge.event 

159 

160 participant = user.participants.get(event=event) 

161 team = participant.team 

162 if team: 

163 try: 

164 check_in = team.check_ins.get(station=station) 

165 return StationCheckInSerializer(check_in).data 

166 except StationCheckIn.DoesNotExist: 

167 return None 

168 return None 

169 

170 

171class ChallengeDetailSerializer(serializers.ModelSerializer): 

172 event = EventSerializer(read_only=True) 

173 finished = serializers.SerializerMethodField(read_only=True) 

174 unfinished = serializers.SerializerMethodField(read_only=True) 

175 teams_count = serializers.SerializerMethodField(read_only=True) 

176 is_master_of_ceremony = serializers.SerializerMethodField(read_only=True) 

177 stations = StationSerializer(many=True, read_only=True) 

178 

179 class Meta: 

180 model = Challenge 

181 fields = [ 

182 "random_slug", 

183 "name", 

184 "objective", 

185 "event", 

186 "is_master_of_ceremony", 

187 "teams_count", 

188 "finished", 

189 "unfinished", 

190 "type_of", 

191 "status", 

192 "stations", 

193 ] 

194 extra_kwargs = {"status": {"read_only": True}} 

195 

196 def get_finished(self, challenge): 

197 scores = challenge.scores.order_by("position") 

198 max_position = max([s.position for s in scores] + [0]) 

199 positions = [] 

200 for i in range(max_position): 

201 positions.append({"teams": [], "points": None}) 

202 for s in scores: 

203 team = SimpleTeamSerializer(s.team) 

204 positions[s.position - 1]["teams"].append(team.data) 

205 positions[s.position - 1]["points"] = s.score 

206 return positions 

207 

208 def get_unfinished(self, challenge): 

209 qs = challenge.event.teams.exclude(scores__challenge=challenge) 

210 return SimpleTeamSerializer(qs, many=True).data 

211 

212 def get_teams_count(self, challenge): 

213 return challenge.event.teams.count() 

214 

215 def get_is_master_of_ceremony(self, challenge): 

216 participant = Participant.objects.get( 

217 event=challenge.event, user=self.context.get("user") 

218 ) 

219 return participant.is_master_of_ceremony 

220 

221 

222class SaveScoresSerializer(serializers.Serializer): 

223 challenge = serializers.CharField(write_only=True) 

224 positions = serializers.ListField(write_only=True) 

225 

226 class Meta: 

227 fields = ["challenge", "positions"] 

228 

229 def save(self, **kwargs): 

230 challenge = Challenge.objects.get( 

231 random_slug=self.validated_data.get("challenge") 

232 ) 

233 

234 slugs = [] 

235 position = 1 

236 total_teams = challenge.event.teams.count() 

237 scores = [i + 1 for i in range(total_teams)] 

238 

239 for item in self.validated_data.get("positions"): 

240 score = [scores.pop() for i in range(len(item))] 

241 for team in item: 

242 random_slug = team.get("random_slug") 

243 team = Team.objects.get(random_slug=random_slug) 

244 Score.objects.update_or_create( 

245 challenge=challenge, 

246 team=team, 

247 defaults={"position": position, "score": sum(score) / len(score)}, 

248 ) 

249 slugs.append(random_slug) 

250 position += 1 

251 

252 challenge.scores.exclude(team__random_slug__in=slugs).delete() 

253 

254 # if challenge.scores.count() == total_teams and challenge.status == Challenge.Status.CURRENT: 

255 # challenge.status = Challenge.Status.PAST 

256 # challenge.save() 

257 # next_challenge = challenge.next_challenge 

258 # if next_challenge is not None: 

259 # next_challenge.status = Challenge.Status.CURRENT 

260 # next_challenge.save() 

261 

262 

263class StationCheckInSerializer(serializers.ModelSerializer): 

264 participant = serializers.SerializerMethodField(read_only=True) 

265 date = serializers.SerializerMethodField(read_only=True) 

266 time = serializers.SerializerMethodField(read_only=True) 

267 

268 class Meta: 

269 model = StationCheckIn 

270 fields = ["has_checkin", "date", "time", "participant"] 

271 

272 def get_participant(self, station): 

273 if station.participant is not None: 

274 return station.participant.user.name 

275 

276 def get_date(self, station): 

277 return station.updated_at.strftime("%d/%m/%y") 

278 

279 def get_time(self, station): 

280 return station.updated_at.strftime("%H:%M")