diff --git a/goodtimes/services.py b/goodtimes/services.py index b177220..5a4abc0 100644 --- a/goodtimes/services.py +++ b/goodtimes/services.py @@ -7,7 +7,12 @@ from django.template.loader import render_to_string from django.shortcuts import get_object_or_404 from smtplib import SMTPException from accounts.models import IAmPrincipal, IAmPrincipalOtp, IAmPrincipalType -from manage_referrals.models import GoodTimeCoins, ReferralRecord +from manage_referrals.models import ( + GoodTimeCoins, + ReferralRecord, + ReferralRecordReward, + ReferralTracking, +) from manage_subscriptions.models import PrincipalSubscription, Subscription from manage_wallets.models import TransactionStatus, Wallet, Transaction from goodtimes.utils import CapacityError, RandomGenerator @@ -218,14 +223,17 @@ class PaymentProcessingService: def _handle_success(self): with transaction.atomic(): self._create_principal_subscription() - self._update_wallet() + self._update_transaction_success() self._credit_referral_reward_if_applicable() def _credit_referral_reward_if_applicable(self): # Step 1: Check for an existing, completed referral record referral_record = ReferralRecord.objects.filter( - referred_principal_id=self.principal_id, is_completed=True + active=True, + deleted=False, + referred_principal_id=self.principal_id, + is_completed=True, ).first() if referral_record: @@ -236,22 +244,34 @@ class PaymentProcessingService: principal=referral_record.referrer_principal, end_date__gte=today, cancelled=False, + deleted=False, ) .order_by("-end_date") .first() ) if active_subscription: - # Step 3: Credit Good Time Coin - # Assume a method exists to credit the coin, adjust as needed self._credit_good_time_coin(referral_record.referrer_principal) + # Here's where you call _update_reward + self._update_reward( + referral_record=referral_record, + active_subscription=active_subscription, + create_subscription_method=self._create_principal_subscription, + has_active_subscription=True, + ) + else: + # If there is no active subscription, still need to update reward without active_subscription + self._update_reward( + referral_record=referral_record, + active_subscription=None, + create_subscription_method=self._create_principal_subscription, + has_active_subscription=False, + ) def _credit_good_time_coin(self, referrer_principal): - # Assuming functionality to credit coin exists, implement or call here. - # This could involve updating a wallet model, creating a transaction, etc. - print( - f"Crediting a Good Time Coin to {referrer_principal}'s wallet" - ) # Placeholder + wallet, created = Wallet.objects.get_or_create(principal=referrer_principal) + wallet.coins += 1 + wallet.save() def _handle_failure(self): # Implement any necessary logic to handle a failed payment @@ -267,7 +287,7 @@ class PaymentProcessingService: last_date = today + timedelta(days=int(subscription_days)) # Create PrincipalSubscription instance - PrincipalSubscription.objects.create( + referred_principal_subscription_id = PrincipalSubscription.objects.create( principal=self.transaction.principal, # Assuming transaction has a foreign key to principal subscription=subscription, is_paid=True, @@ -277,21 +297,32 @@ class PaymentProcessingService: stripe_customer_id=self.customer_id, # Use the customer_id from the instance variable ) - def _update_wallet(self): - # Retrieve the current value of Good Time Coin and update the wallet accordingly - # good_time_coin_value = ( - # GoodTimeCoins.objects.filter( - # deleted=False, - # ) - # .last() - # .value_in_pound - # ) + return referred_principal_subscription_id.id - wallet, created = Wallet.objects.get_or_create( - principal=self.transaction.principal + def _update_reward( + self, + referral_record, + active_subscription, + create_subscription_method, + has_active_subscription, + ): + # Check if the referrer has an active subscription and get its ID if it exists + referrer_subscription_id = ( + active_subscription.id if active_subscription else None + ) + + # Create a new subscription for the referred principal + referred_subscription_id = create_subscription_method() + + # Create or update the ReferralTracking record + ReferralTracking.objects.create( + referral_record=referral_record, + defaults={ + "referrer_subscription_id": referrer_subscription_id, + "referred_subscription_id": referred_subscription_id, + "is_referrer_subscribed": has_active_subscription, + }, ) - wallet.coins += 1 - wallet.save() def _update_transaction_success(self): self.transaction.transaction_status = TransactionStatus.SUCCESS diff --git a/goodtimes/urls.py b/goodtimes/urls.py index a04a9f4..ef5551b 100644 --- a/goodtimes/urls.py +++ b/goodtimes/urls.py @@ -42,7 +42,7 @@ urlpatterns = [ path("api/referrals/", include("manage_referrals.api.urls")), path("wallet/", include("manage_wallets.urls")), - # path('api/wallet/', include("manage_wallets.api.urls")), + path('api/wallet/', include("manage_wallets.api.urls")), path("communications/", include("manage_communications.urls")), # path('api/communications/', include("manage_communications.api.urls")), diff --git a/manage_referrals/admin.py b/manage_referrals/admin.py index e0d4ce1..f3cedc0 100644 --- a/manage_referrals/admin.py +++ b/manage_referrals/admin.py @@ -1,5 +1,5 @@ from django.contrib import admin -from .models import ReferralCode, ReferralRecord, ReferralRecordReward +from .models import ReferralCode, ReferralRecord, ReferralRecordReward, ReferralTracking class ReferralCodeAdmin(admin.ModelAdmin): @@ -85,3 +85,47 @@ class ReferralRecordRewardAdmin(admin.ModelAdmin): admin.site.register(ReferralRecordReward, ReferralRecordRewardAdmin) + + +class ReferralTrackingAdmin(admin.ModelAdmin): + list_display = ( + "referral_record", + "referrer_subscription_id", + "referred_subscription_id", + "is_referrer_subscribed", + "ip_address", + "user_agent", + "device_model", + ) + list_filter = ("is_referrer_subscribed", "referral_record") + search_fields = ( + "referrer_subscription_id", + "referred_subscription_id", + "ip_address", + ) + + # Customize form fields + fieldsets = ( + ( + None, + { + "fields": ( + "referral_record", + "referrer_subscription_id", + "referred_subscription_id", + "is_referrer_subscribed", + ) + }, + ), + ( + "Advanced options", + { + "classes": ("collapse",), + "fields": ("ip_address", "user_agent", "device_model"), + }, + ), + ) + + +# Register your models here. +admin.site.register(ReferralTracking, ReferralTrackingAdmin) diff --git a/manage_referrals/models.py b/manage_referrals/models.py index f421b2a..e54488b 100644 --- a/manage_referrals/models.py +++ b/manage_referrals/models.py @@ -153,8 +153,8 @@ class ReferralTracking(BaseModel): default=False, help_text="is referrer subscribed at the time of referred subscription", ) - ip_address = models.GenericIPAddressField() - user_agent = models.CharField(max_length=255) + ip_address = models.GenericIPAddressField(blank=True, null=True) + user_agent = models.CharField(max_length=255, blank=True, null=True) device_model = models.CharField(max_length=100, blank=True, null=True) class Meta: diff --git a/manage_wallets/api/serializers.py b/manage_wallets/api/serializers.py index cf6a21a..eb07885 100644 --- a/manage_wallets/api/serializers.py +++ b/manage_wallets/api/serializers.py @@ -7,39 +7,33 @@ from manage_wallets import models class WalletSerializer(serializers.ModelSerializer): class Meta: model = models.Wallet - exclude = [ - "principal", - "id", - "active", - "deleted", - "created_on", - "modified_on", - "created_by", - "modified_by", + fields = [ + "balance", + "deposit", + "earnings", + "coins", + "withdrawal_balance", ] + class TransactionSerializer(serializers.ModelSerializer): class Meta: model = models.Transaction fields = "__all__" -# class MerchantDepositSerializer(serializers.Serializer): -# principal_type = serializers.CharField() -# field = serializers.CharField() -# amount = serializers.DecimalField(max_digits=14, decimal_places=2) - - class MerchantDepositSerializer(serializers.Serializer): principal_type = serializers.CharField() - field = serializers.ChoiceField(choices=[ - ('player_balance', 'Player Balance'), - ('merchant_balance', 'Merchant Balance'), - ('player_deposit', 'Player Deposit'), - ('merchant_deposit', 'Merchant Deposit'), - ('player_bonus', 'Player Bonus'), - ('merchant_bonus', 'Merchant Bonus'), - ('player_winning', 'Player Winning'), - ('merchant_commission', 'Merchant Commission'), - ]) + field = serializers.ChoiceField( + choices=[ + ("player_balance", "Player Balance"), + ("merchant_balance", "Merchant Balance"), + ("player_deposit", "Player Deposit"), + ("merchant_deposit", "Merchant Deposit"), + ("player_bonus", "Player Bonus"), + ("merchant_bonus", "Merchant Bonus"), + ("player_winning", "Player Winning"), + ("merchant_commission", "Merchant Commission"), + ] + ) amount = serializers.DecimalField(max_digits=14, decimal_places=2) diff --git a/manage_wallets/api/urls.py b/manage_wallets/api/urls.py index 76b2d34..933074b 100644 --- a/manage_wallets/api/urls.py +++ b/manage_wallets/api/urls.py @@ -9,7 +9,7 @@ urlpatterns = [ path('webhook-test/', views.StripeWebhookTest.as_view(), name='webhook_test'), path('postman-test/', views.TestWebhookAPI.as_view(), name='postman_test'), path('postman-test-withdraw/', views.TestWebhookAPIWithdraw.as_view(), name='postman_test_withdraw'), - path('check/', views.CheckWallet.as_view(), name='check_wallet'), + path('get-wallet/', views.GetWallet.as_view(), name='get_wallet'), path('is-merchant/', views.IsMerchant.as_view(), name='is_merchant'), path('transactions/', views.TransactionView.as_view(), name='transactions'), path('merchant-deposit/', views.MerchantDeposit.as_view(), name='merchant_deposit'), diff --git a/manage_wallets/api/views.py b/manage_wallets/api/views.py index 116447c..c12493e 100644 --- a/manage_wallets/api/views.py +++ b/manage_wallets/api/views.py @@ -13,6 +13,7 @@ from manage_wallets import models from django.conf import settings from . import serializers from goodtimes.utils import ApiResponse + # from PayTm import Checksum, check # from Paytm_Python.paytmchecksum import PaytmChecksum # from paytmchecksum import PaytmChecksum @@ -136,7 +137,7 @@ class StripeWebhookTest(APIView): return ApiResponse.success(**intent_response) -class CheckWallet(APIView): +class GetWallet(APIView): authentication_classes = [JWTAuthentication] permission_classes = [IsAuthenticated] model = models.Wallet @@ -149,12 +150,16 @@ class CheckWallet(APIView): # Serialize the wallet data serializer = serializers.WalletSerializer(wallet_obj) - return Response({"success": True, "data": serializer.data}) + return ApiResponse.success( + status=status.HTTP_200_OK, + message=constants.SUCCESS, + data=serializer.data, + ) except Exception as e: # Handle any exceptions and return an error response error_response = { - "status": status.HTTP_500_INTERNAL_SERVER_ERROR, - "message": constants.INTERNAL_SERVER_ERROR, + "status": status.HTTP_400_BAD_REQUEST, + "message": constants.FAILURE, "errors": str(e), } return ApiResponse.error(**error_response)