Coverage for events/views/checkin.py: 23%

75 statements  

« prev     ^ index     » next       coverage.py v6.4.4, created at 2022-11-02 14:35 -0600

1import datetime 

2from rest_framework.decorators import action 

3from rest_framework.exceptions import ValidationError 

4from rest_framework.mixins import ListModelMixin as List 

5from rest_framework.response import Response 

6from rest_framework.viewsets import GenericViewSet 

7from app.pusher import PusherClient 

8from app.settings.base import FRONTEND_DOMAIN 

9from app.twilio import TwilioClient 

10from app.utils import get_image_from_data_url 

11from ..models import StationCheckIn, Participant 

12from ..serializers import MakeCheckInSerializer 

13 

14 

15class CheckInViewSet(GenericViewSet, List): 

16 def get_queryset(self): 

17 return StationCheckIn.objects.filter(team__members__user=self.request.user) 

18 

19 def partial_update(self, request, *args, **kwargs): 

20 checkin_instance = self.get_object() 

21 station = checkin_instance.station 

22 

23 if station.challenge.status != station.challenge.Status.CURRENT: 

24 raise ValidationError("Challenge not active") 

25 if checkin_instance.has_checkin: 

26 raise ValidationError("Already Scanned QR") 

27 if station.type_of != station.StationCheckInType.MEDIA: 

28 raise ValidationError("This checkin is not allowed") 

29 

30 participant = Participant.objects.get( 

31 user=request.user, event=station.challenge.event 

32 ) 

33 

34 file = request.data.get("checkin_media") 

35 if request.data.get("base64") == "true": 

36 file = get_image_from_data_url(file) 

37 data = {"checkin_media": file, "participant": participant.random_slug} 

38 

39 serializer = MakeCheckInSerializer(checkin_instance, data, partial=True) 

40 serializer.is_valid(True) 

41 checkin_instance = serializer.save() 

42 

43 mcs = station.challenge.event.participants.filter(is_master_of_ceremony=True) 

44 twilio = TwilioClient() 

45 approve_url = f"{FRONTEND_DOMAIN}/challenges/{station.challenge.random_slug}" 

46 for member in mcs: 

47 if member.user.phone is not None: 

48 twilio.send_message( 

49 body=f"{checkin_instance.team.name} just checked in on {station.name}. APPROVAL NEEDED. " 

50 f"Go to: {approve_url}", 

51 to=member.user.phone.as_e164, 

52 ) 

53 

54 pusher = PusherClient() 

55 pusher.update_challenge_detail(station.challenge) 

56 pusher.update_event_detail(station.challenge.event) 

57 

58 data = { 

59 "success": True, 

60 "station": checkin_instance.station.name, 

61 "random_slug": checkin_instance.random_slug, 

62 "datetime": checkin_instance.checkin_timestamp.strftime( 

63 "%b %d, %Y at %H:%M" 

64 ), 

65 } 

66 

67 return Response(data) 

68 

69 @action(methods=["POST"], detail=True) 

70 def approve(self, request, pk): 

71 checkin = StationCheckIn.objects.get(random_slug=pk) 

72 participant = self._validate_approval(checkin) 

73 

74 checkin.is_approved = True 

75 checkin.approve_timestamp = datetime.datetime.now() 

76 checkin.approved_by = participant 

77 checkin.save() 

78 

79 return Response() 

80 

81 @action(methods=["POST"], detail=True) 

82 def reject(self, request, pk): 

83 checkin = StationCheckIn.objects.get(random_slug=pk) 

84 self._validate_approval(checkin) 

85 

86 checkin.participant = None 

87 checkin.has_checkin = False 

88 checkin.checkin_timestamp = None 

89 checkin.checkin_media = None 

90 checkin.save() 

91 

92 members = checkin.team.members.all() 

93 twilio = TwilioClient() 

94 challenge_url = f"{FRONTEND_DOMAIN}/challenges/{checkin.station.challenge.random_slug}" 

95 for member in members: 

96 if member.user.phone is not None: 

97 twilio.send_message( 

98 body=f"Your checkin for {checkin.station.name} is rejected, please checkin again on {challenge_url} or call the Master of Ceremonies", 

99 to=member.user.phone.as_e164, 

100 ) 

101 

102 return Response() 

103 

104 def _validate_approval(self, checkin): 

105 if not checkin.has_checkin: 

106 raise ValidationError("Invalid CheckIn") 

107 try: 

108 return Participant.objects.get( 

109 user=self.request.user, 

110 event=checkin.station.challenge.event, 

111 is_master_of_ceremony=True, 

112 ) 

113 except Participant.DoesNotExist: 

114 raise ValidationError("You can't approve this CheckIn")