Coverage for events/serializers/__init__.py: 58%

182 statements  

« prev     ^ index     » next       coverage.py v6.4.4, created at 2023-03-30 17:01 -0600

1from .checkin import MakeCheckInSerializer, StationCheckInSerializer, StationCheckInDetailSerializer 

2 

3import datetime 

4from rest_framework import serializers 

5from users.models import User 

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

7 

8 

9class ChallengeSerializer(serializers.ModelSerializer): 

10 score = serializers.SerializerMethodField(read_only=True) 

11 

12 class Meta: 

13 model = Challenge 

14 fields = ["random_slug", "event", "name", "status", "score", "type_of", "start_date", "end_date"] 

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

16 

17 def get_score(self, challenge): 

18 try: 

19 participant = Participant.objects.get(event=challenge.event, user=self.context.get("user")) 

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

21 return score.score 

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

23 return None 

24 

25 

26class EventSerializer(serializers.ModelSerializer): 

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

28 is_master_of_ceremony = serializers.SerializerMethodField(read_only=True) 

29 

30 class Meta: 

31 model = Event 

32 fields = [ 

33 "random_slug", 

34 "name", 

35 "date", 

36 "image", 

37 "owner", 

38 "is_master_of_ceremony", 

39 "image", 

40 ] 

41 

42 def get_is_master_of_ceremony(self, event): 

43 try: 

44 participant = Participant.objects.get(event=event, user=self.context.get("user")) 

45 return participant.is_master_of_ceremony 

46 except Participant.DoesNotExist: 

47 return None 

48 

49 

50class ParticipantDetailSerializer(serializers.ModelSerializer): 

51 event = EventSerializer(read_only=True) 

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

53 

54 class Meta: 

55 model = Participant 

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

57 

58 

59class ParticipantSerializer(serializers.ModelSerializer): 

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

61 full_name = serializers.SerializerMethodField() 

62 

63 class Meta: 

64 model = Participant 

65 fields = ["random_slug", "email", "event", "is_master_of_ceremony", "full_name"] 

66 

67 def create(self, validated_data): 

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

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

70 validated_data["user"] = user 

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

72 return participant 

73 

74 def get_full_name(self, instance): 

75 return f"{instance.user.first_name} {instance.user.last_name}" 

76 

77 

78class TeamScoreSerializer(serializers.ModelSerializer): 

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

80 

81 class Meta: 

82 model = Team 

83 fields = ["random_slug", "name", "total_score", "members"] 

84 extra_kwargs = { 

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

86 } 

87 

88 

89class TeamSerializer(serializers.ModelSerializer): 

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

91 

92 class Meta: 

93 model = Team 

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

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

96 

97 

98class EventDisplaySerializer(EventSerializer): 

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

100 teams = serializers.SerializerMethodField(read_only=True) 

101 my_team = serializers.SerializerMethodField(read_only=True) 

102 

103 class Meta: 

104 model = Event 

105 fields = [ 

106 "random_slug", 

107 "name", 

108 "challenges", 

109 "teams", 

110 "date", 

111 "my_team", 

112 "is_master_of_ceremony", 

113 "image", 

114 ] 

115 

116 def get_teams(self, instance): 

117 teams = instance.teams.all() 

118 serializer = TeamScoreSerializer(teams, many=True) 

119 data = serializer.data 

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

121 

122 def get_my_team(self, instance): 

123 try: 

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

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

126 except Participant.DoesNotExist: 

127 return None 

128 

129 

130class EventDetailSerializer(EventDisplaySerializer): 

131 participants = serializers.SerializerMethodField(read_only=True) 

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

133 

134 class Meta(EventDisplaySerializer.Meta): 

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

136 

137 def get_participants(self, instance): 

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

139 serializer = ParticipantSerializer(participants, many=True) 

140 return serializer.data 

141 

142 

143class SimpleTeamSerializer(serializers.ModelSerializer): 

144 class Meta: 

145 model = Team 

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

147 read_only_fields = fields 

148 

149 

150# class StationCheckInDetailSerializer(serializers.ModelSerializer): 

151# class Meta: 

152# model = StationCheckIn 

153# fields = ["team", "participant", "has_checkin", "updated_at"] 

154 

155 

156class StationSerializer(serializers.ModelSerializer): 

157 check_in = serializers.SerializerMethodField(read_only=True) 

158 

159 class Meta: 

160 model = Station 

161 fields = ["name", "hint", "type_of", "check_in"] 

162 

163 def get_check_in(self, station): 

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

165 event = station.challenge.event 

166 

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

168 team = participant.team 

169 if team: 

170 try: 

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

172 return StationCheckInSerializer(check_in).data 

173 except StationCheckIn.DoesNotExist: 

174 return None 

175 return None 

176 

177 

178class ChallengeDetailSerializer(serializers.ModelSerializer): 

179 event = EventSerializer(read_only=True) 

180 finished = serializers.SerializerMethodField(read_only=True) 

181 unfinished = serializers.SerializerMethodField(read_only=True) 

182 teams_count = serializers.SerializerMethodField(read_only=True) 

183 is_master_of_ceremony = serializers.SerializerMethodField(read_only=True) 

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

185 my_team = serializers.SerializerMethodField(read_only=True) 

186 

187 class Meta: 

188 model = Challenge 

189 fields = [ 

190 "random_slug", 

191 "name", 

192 "objective", 

193 "event", 

194 "is_master_of_ceremony", 

195 "teams_count", 

196 "finished", 

197 "unfinished", 

198 "type_of", 

199 "status", 

200 "stations", 

201 "my_team", 

202 "start_date", 

203 "end_date", 

204 ] 

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

206 

207 def get_finished(self, challenge): 

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

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

210 positions = [] 

211 for i in range(max_position): 

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

213 for s in scores: 

214 team = SimpleTeamSerializer(s.team) 

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

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

217 return positions 

218 

219 def get_unfinished(self, challenge): 

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

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

222 

223 def get_teams_count(self, challenge): 

224 return challenge.event.teams.count() 

225 

226 def get_is_master_of_ceremony(self, challenge): 

227 participant = Participant.objects.get(event=challenge.event, user=self.context.get("user")) 

228 return participant.is_master_of_ceremony 

229 

230 def get_my_team(self, instance): 

231 try: 

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

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

234 except Participant.DoesNotExist: 

235 return None 

236 

237 def to_representation(self, instance): 

238 representation = super(ChallengeDetailSerializer, self).to_representation(instance) 

239 stations = representation.pop("stations") 

240 stations = sorted(stations, key=self._get_station_key) 

241 representation["stations"] = stations 

242 return representation 

243 

244 def _get_station_key(self, item): 

245 from django.utils import timezone 

246 

247 check_in = item.get("check_in") 

248 if check_in: 

249 slug = check_in.get("random_slug") 

250 instance = StationCheckIn.objects.get(pk=slug) 

251 return instance.checkin_timestamp if instance.checkin_timestamp else timezone.now() 

252 

253 return timezone.now() + timezone.timedelta(minutes=1) 

254 

255 

256class SaveScoresSerializer(serializers.Serializer): 

257 challenge = serializers.CharField(write_only=True) 

258 positions = serializers.ListField(write_only=True) 

259 

260 class Meta: 

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

262 

263 def save(self, **kwargs): 

264 challenge = Challenge.objects.get(random_slug=self.validated_data.get("challenge")) 

265 

266 slugs = [] 

267 position = 1 

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

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

270 

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

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

273 for team in item: 

274 random_slug = team.get("random_slug") 

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

276 Score.objects.update_or_create( 

277 challenge=challenge, 

278 team=team, 

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

280 ) 

281 slugs.append(random_slug) 

282 position += 1 

283 

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