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

1from django.utils import timezone 

2from rest_framework import serializers 

3 

4from apps.organizations.serializers import BasicOrganizationSerializer, OrganizationUploadPolymorphicSerializer 

5from apps.users.models import Employee, Fan, SuperUser 

6from base.serializers import ToRepresentationMixin 

7 

8from .models import Reward, RewardClaim 

9 

10 

11class RewardSerializer(ToRepresentationMixin): 

12 """ 

13 Serializer for Reward 

14 """ 

15 

16 REPRESENTATION_FIELDS = [ 

17 ("image", OrganizationUploadPolymorphicSerializer, False), 

18 ("organization", BasicOrganizationSerializer, False), 

19 ] 

20 

21 claimed_amount = serializers.SerializerMethodField() 

22 can_be_claimed = serializers.SerializerMethodField() 

23 times_claimed = serializers.SerializerMethodField() 

24 

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 ] 

46 

47 def get_times_claimed(self, instance): 

48 user = self.context.get("request").user 

49 

50 if isinstance(user, Fan): 

51 return instance.claims.filter(fan=user).count() 

52 

53 return 0 

54 

55 def get_claimed_amount(self, instance): 

56 return instance.claimed_amount 

57 

58 def get_can_be_claimed(self, instance): 

59 user = self.context.get("request").user 

60 today = timezone.datetime.today().date() 

61 

62 if instance.valid_from > today or instance.valid_to < today: 

63 return False 

64 

65 if user.is_anonymous or isinstance(user, (Employee, SuperUser)): 

66 return False 

67 

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 

71 

72 if instance.total_number_of_claims is not None: 

73 if instance.claims.count() >= instance.total_number_of_claims: 

74 return False 

75 

76 if isinstance(user, Fan): 

77 fan_balance = user.organization_balance(instance.organization) 

78 if fan_balance < instance.points_required: 

79 return False 

80 

81 return True 

82 

83 

84class RewardClaimSerializer(ToRepresentationMixin): 

85 """ 

86 Serializer for RewardClaim 

87 """ 

88 

89 REPRESENTATION_FIELDS = [("reward", RewardSerializer, False)] 

90 

91 class Meta: 

92 model = RewardClaim 

93 read_only_fields = ["random_slug"] 

94 fields = read_only_fields + ["reward", "fan"] 

95 

96 def validate(self, attrs): 

97 fan = attrs.get("fan") 

98 reward = attrs.get("reward") 

99 

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") 

103 

104 fan_balance = fan.organization_balance(reward.organization) 

105 

106 if fan_balance < reward.points_required: 

107 raise serializers.ValidationError("Yo don't have enough points for this reward") 

108 

109 return attrs