196 lines
6.8 KiB
Python
196 lines
6.8 KiB
Python
from rest_framework import status
|
|
from rest_framework.views import APIView
|
|
from django.conf import settings
|
|
from manage_referrals.models import ReferralCode, ReferralRecord, ReferralRecordReward
|
|
from django.shortcuts import get_object_or_404
|
|
from goodtimes import constants
|
|
from django.db import transaction
|
|
from goodtimes.utils import ApiResponse
|
|
from manage_wallets.models import WithdrawalRequest
|
|
from .serializers import (
|
|
ReferralCodeSerializer,
|
|
ReferralRecordRewardSerializer,
|
|
ReferralRecordSerializer,
|
|
)
|
|
from rest_framework.permissions import IsAuthenticated
|
|
from rest_framework_simplejwt.authentication import JWTAuthentication
|
|
from rest_framework.response import Response
|
|
|
|
|
|
class ReferralCodeViews(APIView):
|
|
authentication_classes = [JWTAuthentication]
|
|
permission_classes = [IsAuthenticated]
|
|
model = ReferralCode
|
|
serializer = ReferralCodeSerializer
|
|
|
|
def get(self, request, *args, **kwargs):
|
|
referral_obj = self.model.filter_referral_code(principal=request.user)
|
|
|
|
serializer_obj = self.serializer(referral_obj, many=True)
|
|
|
|
success_message = {
|
|
"status": status.HTTP_200_OK,
|
|
"message": constants.SUCCESS,
|
|
"data": serializer_obj.data,
|
|
}
|
|
return ApiResponse.success(**success_message)
|
|
|
|
|
|
class ReferralRecordViews(APIView):
|
|
authentication_classes = [JWTAuthentication]
|
|
permission_classes = [IsAuthenticated]
|
|
model = ReferralRecord
|
|
serializer = ReferralRecordSerializer
|
|
|
|
def get(self, request, *args, **kwargs):
|
|
referral_obj = self.model.filter_invite_records(referrer_principal=request.user)
|
|
|
|
serializer_obj = self.serializer(referral_obj, many=True)
|
|
success_message = {
|
|
"status": status.HTTP_200_OK,
|
|
"message": constants.SUCCESS,
|
|
"data": {"count": referral_obj.count(), "record": serializer_obj.data},
|
|
}
|
|
return ApiResponse.success(**success_message)
|
|
|
|
|
|
class RewardListView(APIView):
|
|
authentication_classes = [JWTAuthentication]
|
|
permission_classes = [IsAuthenticated]
|
|
model = ReferralRecordReward
|
|
serializer = ReferralRecordRewardSerializer
|
|
|
|
def get(self, request):
|
|
# Filter rewards based on specified conditions
|
|
current_principal = (
|
|
request.user
|
|
) # Adjust based on how user is linked to principal
|
|
|
|
# Filter rewards based on the authenticated referrer
|
|
rewards_query = ReferralRecordReward.objects.filter(
|
|
referral_record__referrer_principal=current_principal,
|
|
sell=False,
|
|
deleted=False,
|
|
active=True,
|
|
)
|
|
# Serialize the results
|
|
rewards_serializer = ReferralRecordRewardSerializer(rewards_query, many=True)
|
|
# Get the count of unredeemed rewards
|
|
unredeemed_count = rewards_query.count()
|
|
success_message = {
|
|
"status": status.HTTP_200_OK,
|
|
"message": constants.SUCCESS,
|
|
"data": {
|
|
"reward_count": unredeemed_count,
|
|
"rewards": rewards_serializer.data,
|
|
},
|
|
}
|
|
return ApiResponse.success(**success_message)
|
|
|
|
|
|
class RedeemRewardView(APIView):
|
|
authentication_classes = [JWTAuthentication]
|
|
permission_classes = [IsAuthenticated]
|
|
|
|
def patch(self, request, unique_token):
|
|
# Retrieve the reward using the unique token
|
|
try:
|
|
reward = ReferralRecordReward.objects.get(
|
|
unique_token=unique_token, sell=False
|
|
)
|
|
except ReferralRecordReward.DoesNotExist:
|
|
return ApiResponse.error(
|
|
status=status.HTTP_404_NOT_FOUND,
|
|
message=constants.FAILURE,
|
|
errors="No unsold token found.",
|
|
)
|
|
|
|
# Check if a withdrawal request already exists for this token
|
|
if WithdrawalRequest.objects.filter(token=unique_token).exists():
|
|
return ApiResponse.error(
|
|
status=status.HTTP_400_BAD_REQUEST,
|
|
message=constants.FAILURE,
|
|
errors="A withdrawal request for this token already exists.",
|
|
)
|
|
|
|
with transaction.atomic():
|
|
# Create a new withdrawal request
|
|
WithdrawalRequest.objects.create(
|
|
principal=request.user, token=unique_token, coins=1, amount=reward.value
|
|
)
|
|
|
|
# Update reward to mark it as sold
|
|
reward.sell = True
|
|
reward.save()
|
|
|
|
return ApiResponse.success(
|
|
status=status.HTTP_200_OK,
|
|
message=constants.SUCCESS,
|
|
data="Token sold successfully.",
|
|
)
|
|
|
|
|
|
class RedeemSelectedRewardsView(APIView):
|
|
authentication_classes = [JWTAuthentication]
|
|
permission_classes = [IsAuthenticated]
|
|
|
|
def patch(self, request):
|
|
# Extract the number of tokens from the request data
|
|
num_tokens_to_sell = request.data.get("num_tokens", None)
|
|
|
|
if num_tokens_to_sell is None:
|
|
return ApiResponse.error(
|
|
status=status.HTTP_400_BAD_REQUEST,
|
|
message=constants.FAILURE,
|
|
errors="Number of tokens to sell is required.",
|
|
)
|
|
|
|
try:
|
|
num_tokens_to_sell = int(num_tokens_to_sell)
|
|
except ValueError:
|
|
return ApiResponse.error(
|
|
status=status.HTTP_400_BAD_REQUEST,
|
|
message=constants.FAILURE,
|
|
errors="Invalid number of tokens.",
|
|
)
|
|
|
|
# Retrieve the rewards for the authenticated user
|
|
rewards = ReferralRecordReward.objects.filter(
|
|
referral_record__referrer_principal=request.user, sell=False
|
|
).order_by(
|
|
"id"
|
|
) # FIFO method
|
|
|
|
if rewards.count() < num_tokens_to_sell:
|
|
return ApiResponse.error(
|
|
status=status.HTTP_404_NOT_FOUND,
|
|
message=constants.FAILURE,
|
|
errors="Not enough unsold rewards available.",
|
|
)
|
|
|
|
# Select the required number of rewards
|
|
rewards_to_sell = rewards[:num_tokens_to_sell]
|
|
total_value = sum(reward.value for reward in rewards_to_sell)
|
|
total_coins = sum(reward.coins for reward in rewards_to_sell)
|
|
tokens = ",".join(str(reward.unique_token) for reward in rewards_to_sell)
|
|
|
|
with transaction.atomic():
|
|
# Create a new withdrawal request
|
|
withdrawal_request = WithdrawalRequest.objects.create(
|
|
principal=request.user,
|
|
coins=total_coins,
|
|
amount=total_value,
|
|
token=tokens,
|
|
)
|
|
|
|
# Update each reward to mark it as sold
|
|
for reward in rewards_to_sell:
|
|
reward.sell = True
|
|
reward.save()
|
|
|
|
return ApiResponse.success(
|
|
status=status.HTTP_200_OK,
|
|
message=constants.SUCCESS,
|
|
data="Selected tokens sold successfully.",
|
|
)
|