Coverage for apps/rewards/serializers.py: 38%
56 statements
« prev ^ index » next coverage.py v6.4.4, created at 2023-09-28 16:13 -0600
« prev ^ index » next coverage.py v6.4.4, created at 2023-09-28 16:13 -0600
1from django.utils import timezone
2from rest_framework import serializers
4from apps.organizations.serializers import BasicOrganizationSerializer, OrganizationUploadPolymorphicSerializer
5from apps.users.models import Employee, Fan, SuperUser
6from base.serializers import ToRepresentationMixin
8from .models import Reward, RewardClaim
11class RewardSerializer(ToRepresentationMixin):
12 """
13 Serializer for Reward
14 """
16 REPRESENTATION_FIELDS = [
17 ("image", OrganizationUploadPolymorphicSerializer, False),
18 ("organization", BasicOrganizationSerializer, False),
19 ]
21 claimed_amount = serializers.SerializerMethodField()
22 can_be_claimed = serializers.SerializerMethodField()
23 times_claimed = serializers.SerializerMethodField()
25 class Meta:
26 model = Reward
27 read_only_fields = [
28 "random_slug",
29 "claimed_amount",
30 "can_be_claimed",
31 "times_claimed",
32 ]
33 fields = read_only_fields + [
34 "organization",
35 "name",
36 "image",
37 "description",
38 "value",
39 "points_required",
40 "total_number_of_claims",
41 "total_number_of_claims_per_fan",
42 "status",
43 "valid_from",
44 "valid_to",
45 ]
47 def get_times_claimed(self, instance):
48 user = self.context.get("request").user
50 if isinstance(user, Fan):
51 return instance.claims.filter(fan=user).count()
53 return 0
55 def get_claimed_amount(self, instance):
56 return instance.claimed_amount
58 def get_can_be_claimed(self, instance):
59 user = self.context.get("request").user
60 today = timezone.datetime.today().date()
62 if instance.valid_from > today or instance.valid_to < today:
63 return False
65 if user.is_anonymous or isinstance(user, (Employee, SuperUser)):
66 return False
68 if instance.total_number_of_claims_per_fan is not None:
69 if user.rewards.filter(reward=instance).count() >= instance.total_number_of_claims_per_fan:
70 return False
72 if instance.total_number_of_claims is not None:
73 if instance.claims.count() >= instance.total_number_of_claims:
74 return False
76 if isinstance(user, Fan):
77 fan_balance = user.organization_balance(instance.organization)
78 if fan_balance < instance.points_required:
79 return False
81 return True
84class RewardClaimSerializer(ToRepresentationMixin):
85 """
86 Serializer for RewardClaim
87 """
89 REPRESENTATION_FIELDS = [("reward", RewardSerializer, False)]
91 class Meta:
92 model = RewardClaim
93 read_only_fields = ["random_slug"]
94 fields = read_only_fields + ["reward", "fan"]
96 def validate(self, attrs):
97 fan = attrs.get("fan")
98 reward = attrs.get("reward")
100 if reward.total_number_of_claims is not None:
101 if (reward.total_number_of_claims - reward.claimed_amount) == 0:
102 raise serializers.ValidationError("There are no more claims available for this reward")
104 fan_balance = fan.organization_balance(reward.organization)
106 if fan_balance < reward.points_required:
107 raise serializers.ValidationError("Yo don't have enough points for this reward")
109 return attrs