Coverage for apps/campaigns/serializers/employee.py: 64%
113 statements
« prev ^ index » next coverage.py v6.4.4, created at 2023-09-28 12:04 -0600
« prev ^ index » next coverage.py v6.4.4, created at 2023-09-28 12:04 -0600
1from django.db import transaction
2from django.utils import timezone
3from rest_framework import serializers
4from rest_polymorphic.serializers import PolymorphicSerializer
6from apps.organizations.serializers import BasicOrganizationSerializer, OrganizationImageSerializer
7from apps.users.serializers import UserSerializer
8from base.serializers import ToRepresentationMixin
10from ..models import (
11 Campaign,
12 GeolocationCampaign,
13 QuizzCampaign,
14 QuizzCampaignQuestion,
15 QuizzCampaignQuestionAnswer,
16 SubmitCampaign,
17 VideoCampaign,
18)
20CAMPAIGN_BASE_READ_ONLY_FIELDS = ["random_slug", "created_at", "slug"]
21CAMPAIGN_BASE_FIELDS = [
22 "organization",
23 "company_name",
24 "name",
25 "short_description",
26 "description",
27 "valid_from",
28 "valid_to",
29 "image",
30 "value",
31 "status",
32 "author",
33 "total_number_of_claims",
34 "total_number_of_claims_per_fan",
35]
38class CampaignClaimHistogramSerializer(serializers.Serializer):
39 """
40 Serializer for Campaign Claim histogram
41 """
43 date = serializers.DateField()
44 times_claimed = serializers.IntegerField()
47class CampaignStatsSerializer(ToRepresentationMixin):
48 """
49 Serializer for Campaign Statistics
50 """
52 REPRESENTATION_FIELDS = [
53 ("organization", BasicOrganizationSerializer, False),
54 ("company_name", BasicOrganizationSerializer, False),
55 ("image", OrganizationImageSerializer, False),
56 ("author", UserSerializer, False),
57 ]
59 class Meta:
60 model = Campaign
61 read_only_fields = CAMPAIGN_BASE_READ_ONLY_FIELDS
62 fields = (
63 read_only_fields
64 + CAMPAIGN_BASE_FIELDS
65 + ["number_of_fans_who_participated", "total_times_claimed", "times_claimed_last_week"]
66 )
68 number_of_fans_who_participated = serializers.SerializerMethodField()
69 total_times_claimed = serializers.SerializerMethodField()
70 times_claimed_last_week = serializers.SerializerMethodField()
72 def get_number_of_fans_who_participated(self, instance):
73 return instance.participants.values("fan").distinct().count()
75 def get_total_times_claimed(self, instance):
76 return instance.participants.count()
78 def get_times_claimed_last_week(self, instance):
79 today = timezone.datetime.today().date()
80 dates = [(today - timezone.timedelta(days=i)) for i in range(7, -1, -1)]
81 data = [
82 {
83 "date": date.strftime("%Y-%m-%d"),
84 "times_claimed": instance.participants.filter(created_at__date=date).count(),
85 }
86 for date in dates
87 ]
88 return CampaignClaimHistogramSerializer(data, many=True).data
91class BaseCampaignSerializer(ToRepresentationMixin):
92 """
93 Base Campaign Serializer
94 """
96 REPRESENTATION_FIELDS = [
97 ("organization", BasicOrganizationSerializer, False),
98 ("company_name", BasicOrganizationSerializer, False),
99 ("image", OrganizationImageSerializer, False),
100 ("author", UserSerializer, False),
101 ]
104class EmployeeVideoCampaignSerializer(BaseCampaignSerializer):
105 """
106 Serializer for VideoCampaign
107 """
109 class Meta:
110 model = VideoCampaign
111 read_only_fields = CAMPAIGN_BASE_READ_ONLY_FIELDS
112 fields = read_only_fields + CAMPAIGN_BASE_FIELDS + ["video_link", "watch_seconds_for_completion"]
113 extra_kwargs = {"author": {"required": False}}
116class EmployeeGeolocationCampaignSerializer(BaseCampaignSerializer):
117 """
118 Serializer for Geolocation Campaign
119 """
121 class Meta:
122 model = GeolocationCampaign
123 read_only_fields = CAMPAIGN_BASE_READ_ONLY_FIELDS
124 fields = read_only_fields + CAMPAIGN_BASE_FIELDS + ["address", "latitude", "longitude", "radius"]
125 extra_kwargs = {"author": {"required": False}}
128class EmployeeSubmitCampaignSerializer(BaseCampaignSerializer):
129 """
130 Serializer for Submit Campaign
131 """
133 class Meta:
134 model = SubmitCampaign
135 read_only_fields = CAMPAIGN_BASE_READ_ONLY_FIELDS
136 fields = read_only_fields + CAMPAIGN_BASE_FIELDS + ["is_approved"]
137 extra_kwargs = {"author": {"required": False}}
140class EmployeeQuizzCampaignQuestionAnswerSerializer(serializers.ModelSerializer):
141 """
142 Serializer for Quizz Campaign Question Answer
143 """
145 class Meta:
146 model = QuizzCampaignQuestionAnswer
147 read_only_fields = ["random_slug"]
148 fields = read_only_fields + ["quizz_campaign_question", "answer", "is_correct", "order"]
149 extra_kwargs = {"quizz_campaign_question": {"required": False, "write_only": True}}
152class EmployeeQuizzCampaignQuestionSerializer(serializers.ModelSerializer):
153 """
154 Serializer for Quiz Campaign Question
155 """
157 answers = EmployeeQuizzCampaignQuestionAnswerSerializer(many=True)
159 class Meta:
160 model = QuizzCampaignQuestion
161 read_only_fields = ["random_slug"]
162 fields = read_only_fields + ["quizz_campaign", "question", "type_of", "answers"]
163 extra_kwargs = {"quizz_campaign": {"required": False, "write_only": True}}
165 def create(self, validated_data):
166 with transaction.atomic():
167 answers = validated_data.pop("answers", [])
169 quizz_campaign = super().create(validated_data)
171 for answer in answers:
172 answer["quizz_campaign_question"] = quizz_campaign
173 quizz_campaign_question_answer_serializer = EmployeeQuizzCampaignQuestionAnswerSerializer(answer)
174 quizz_campaign_question_answer_serializer.create(answer)
176 return quizz_campaign
178 def update(self, instance, validated_data):
179 with transaction.atomic():
180 answers = validated_data.pop("answers", [])
182 quizz_campaign = super().update(instance, validated_data)
184 if answers:
185 quizz_campaign.answers.all().delete()
186 for answer in answers:
187 answer["quizz_campaign_question"] = quizz_campaign
188 quizz_campaign_question_answer_serializer = EmployeeQuizzCampaignQuestionAnswerSerializer(answer)
189 quizz_campaign_question_answer_serializer.create(answer)
191 return quizz_campaign
194class EmployeeQuizzCampaignSerializer(BaseCampaignSerializer):
195 """
196 Serializer for Quizz Campaign
197 """
199 questions = EmployeeQuizzCampaignQuestionSerializer(many=True)
201 class Meta:
202 model = QuizzCampaign
203 read_only_fields = CAMPAIGN_BASE_READ_ONLY_FIELDS
204 fields = read_only_fields + CAMPAIGN_BASE_FIELDS + ["correct_answers_for_approval", "questions"]
205 extra_kwargs = {"author": {"required": False}}
207 def create(self, validated_data):
208 with transaction.atomic():
209 questions = validated_data.pop("questions", [])
211 quizz_campaign = super().create(validated_data)
213 for question in questions:
214 question["quizz_campaign"] = quizz_campaign
215 quizz_campaign_question_serializer = EmployeeQuizzCampaignQuestionSerializer(question)
216 quizz_campaign_question_serializer.create(question)
218 return quizz_campaign
220 def update(self, instance, validated_data):
221 with transaction.atomic():
222 questions = validated_data.pop("questions", [])
224 quizz_campaign = super().update(instance, validated_data)
226 if questions:
227 quizz_campaign.questions.all().delete()
228 for question in questions:
229 question["quizz_campaign"] = quizz_campaign
230 quizz_campaign_question_serializer = EmployeeQuizzCampaignQuestionSerializer(question)
231 quizz_campaign_question_serializer.create(question)
233 return quizz_campaign
236class EmployeeCampaignPolymorphicSerializer(PolymorphicSerializer):
237 """
238 Polymorphic serializer for Campaign objects
239 """
241 model_serializer_mapping = {
242 VideoCampaign: EmployeeVideoCampaignSerializer,
243 GeolocationCampaign: EmployeeGeolocationCampaignSerializer,
244 SubmitCampaign: EmployeeSubmitCampaignSerializer,
245 QuizzCampaign: EmployeeQuizzCampaignSerializer,
246 }