From 07184d6be0bbe4c63ee0bd5209dff7bf60a21d2c Mon Sep 17 00:00:00 2001 From: mahdavi Date: Tue, 13 Oct 2020 15:44:34 +0330 Subject: [PATCH] Withdraw and Deposit --- apps/transactions/serializers.py | 48 ++++++++++++++++++-------- apps/transactions/views.py | 59 ++++++++++++++++++++++++-------- gooyal_accounts/urls.py | 9 +++-- 3 files changed, 83 insertions(+), 33 deletions(-) diff --git a/apps/transactions/serializers.py b/apps/transactions/serializers.py index e73cd81..28fdfcf 100755 --- a/apps/transactions/serializers.py +++ b/apps/transactions/serializers.py @@ -46,18 +46,12 @@ class TransactionSerializer(serializers.ModelSerializer): return transaction -class ServiceTransactionSerializer(serializers.ModelSerializer): - # payer = PublicUserSerializer(required=True) - # payee = PublicUserSerializer(required=True) - user = PublicUserSerializer(required=False, write_only=True) +class DepositSerializer(serializers.ModelSerializer): uuid = serializers.UUIDField(required=True) - # application_client_id = serializers.IntegerField(required=False, read_only=True) - class Meta: model = Transaction fields = ( - 'user', 'uuid', 'payer', 'payee', @@ -70,16 +64,40 @@ class ServiceTransactionSerializer(serializers.ModelSerializer): # 'application_client_id' ) - read_only_fields = ['last_update', 'state', 'create', 'user'] # , 'detail_id'] #, 'application_client_id'] + read_only_fields = ['last_update', 'state', 'create', 'payer'] # , 'detail_id'] #, 'application_client_id'] + + def create(self, validated_data): + with atomic(): + try: + transaction = Transaction.objects.create_transaction(**validated_data) + transaction.submit() + except IntegrityError as e: + raise APIException('duplicate uuid') + + return transaction + + +class WithdrawSerializer(serializers.ModelSerializer): + uuid = serializers.UUIDField(required=True) + + class Meta: + model = Transaction + fields = ( + 'uuid', + 'payer', + 'payee', + "create", + "state", + 'amount', + 'delay', + 'last_update', + # 'detail_id', + # 'application_client_id' + ) + + read_only_fields = ['last_update', 'state', 'create', 'payee'] # , 'detail_id'] #, 'application_client_id'] def create(self, validated_data): - payer = validated_data.get('payer') - payee = validated_data.get('payee') - user = validated_data.pop('user') - - if user not in [payee, payer]: - raise APIException('user must be in payer or payee') - with atomic(): try: transaction = Transaction.objects.create_transaction(**validated_data) diff --git a/apps/transactions/views.py b/apps/transactions/views.py index b8a55ba..3a0a425 100755 --- a/apps/transactions/views.py +++ b/apps/transactions/views.py @@ -5,7 +5,7 @@ from rest_framework import generics, permissions from rest_framework.response import Response from apps.transactions.models import Transaction -from apps.transactions.serializers import TransactionSerializer, ServiceTransactionSerializer +from apps.transactions.serializers import TransactionSerializer, DepositSerializer, WithdrawSerializer from apps.users.constans import STATE_CHOICES @@ -80,31 +80,60 @@ class TransactionReceipt(generics.RetrieveAPIView): return Response(serializer.data) -# TODO: withdraw and deposit service - -class ServiceTransactionSubmit(generics.CreateAPIView): - permission_classes = [IsAuthenticatedOrTokenHasScope] - serializer_class = ServiceTransactionSerializer - required_scopes = ['transactions.transaction:submit'] +class DepositSubmit(generics.CreateAPIView): + permission_classes = [TokenHasScope] + serializer_class = DepositSerializer + required_scopes = ['transactions.deposit:submit'] def get_queryset(self): - # TODO: check if application_client_id is None application_client_id = get_application_client_id(self.request) return Transaction.objects.filter(application_client_id=application_client_id).all() def perform_create(self, serializer): - user = self.request.auth.application.user - serializer.save(user=user, application_client_id=get_application_client_id(self.request)) + payer = self.request.auth.application.user + serializer.save(payer=payer, application_client_id=get_application_client_id(self.request)) -class ServiceTransactionVerify(generics.RetrieveAPIView): - permission_classes = [IsAuthenticatedOrTokenHasScope] - serializer_class = ServiceTransactionSerializer +class DepositVerify(generics.RetrieveAPIView): + permission_classes = [TokenHasScope] + serializer_class = DepositSerializer lookup_field = 'uuid' - required_scopes = ['transactions.transaction:verify'] + required_scopes = ['transactions.deposit:verify'] + + def get_queryset(self): + application_client_id = get_application_client_id(self.request) + return Transaction.objects.filter(application_client_id=application_client_id).all() + + def retrieve(self, request, *args, **kwargs): + instance = self.get_object() + if instance.state == STATE_CHOICES.pending: + instance.verify() + + serializer = self.get_serializer(instance) + return Response(serializer.data) + + +class WithdrawSubmit(generics.CreateAPIView): + permission_classes = [TokenHasScope] + serializer_class = WithdrawSerializer + required_scopes = ['transactions.withdraw:submit'] + + def get_queryset(self): + application_client_id = get_application_client_id(self.request) + return Transaction.objects.filter(application_client_id=application_client_id).all() + + def perform_create(self, serializer): + payee = self.request.auth.application.user + serializer.save(payee=payee, application_client_id=get_application_client_id(self.request)) + + +class WithdrawVerify(generics.RetrieveAPIView): + permission_classes = [TokenHasScope] + serializer_class = WithdrawSerializer + lookup_field = 'uuid' + required_scopes = ['transactions.withdraw:verify'] def get_queryset(self): - # TODO: check if application_client_id is None application_client_id = get_application_client_id(self.request) return Transaction.objects.filter(application_client_id=application_client_id).all() diff --git a/gooyal_accounts/urls.py b/gooyal_accounts/urls.py index 73611e5..5363459 100644 --- a/gooyal_accounts/urls.py +++ b/gooyal_accounts/urls.py @@ -22,7 +22,7 @@ from django.contrib import admin # from apps.gooyal_oauth2.views.introspect import introspect_token from apps.transactions.views import TransactionList, TransactionDetail, TransactionPay, TransactionReceipt, \ - ServiceTransactionVerify, ServiceTransactionSubmit + WithdrawVerify, WithdrawSubmit, DepositSubmit, DepositVerify from apps.users.views import UserListView, UserDetailView, AccountView, RequestOTPView, ChangePasswordView, \ OTPLoginView, home from django.contrib.auth import urls as auth_urls @@ -50,8 +50,11 @@ urlpatterns = [ path('transactions/', TransactionDetail.as_view(), name='transaction_detail'), path('transactions//pay', TransactionPay.as_view(), name='transaction_pay'), - path('service-transactions/', ServiceTransactionSubmit.as_view(), name='service_transaction_submit'), - path('service-transactions//verify', ServiceTransactionVerify.as_view(), name='service_transaction_verify'), + path('deposit/', DepositSubmit.as_view(), name='deposit_submit'), + path('deposit//verify', DepositVerify.as_view(), name='deposit_verify'), + + path('withdraw/', WithdrawSubmit.as_view(), name='withdraw_submit'), + path('withdraw//verify', WithdrawVerify.as_view(), name='withdraw_verify'), ] urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)