accounts/apps/wallet/views.py
2022-09-27 18:03:16 +03:30

218 lines
7.6 KiB
Python
Executable file

from django.contrib import messages
from django.contrib.auth.decorators import login_required
from django.db.models import Q
from django.urls import reverse
from django.utils.decorators import method_decorator
from django.views.generic import DetailView, ListView, UpdateView
from oauth2_provider.contrib.rest_framework import TokenHasScope, IsAuthenticatedOrTokenHasScope
from rest_framework import generics, permissions
from rest_framework.response import Response
from apps.gooyal_oauth2.rest_framework import IsAuthenticatedOrTokenMatchesOASRequirements
from apps.wallet.models import Transaction
from apps.wallet.serializers import TransactionSerializer, DepositSerializer, WithdrawSerializer, WalletSerializer
from .constans import STATE_CHOICES
from .forms import TransactionActionForm
from django.utils.translation import gettext_lazy as _
def get_application(request):
try:
application = request.auth.application
except:
application = None
return application
class DefaultWalletBalanceView(generics.RetrieveAPIView):
permission_classes = [permissions.IsAuthenticated, IsAuthenticatedOrTokenHasScope]
serializer_class = WalletSerializer
required_scopes = ['wallet.wallet:get_balance']
def get_object(self):
return self.request.user
# TODO: this is user invoice create view
# class TransactionList(generics.ListCreateAPIView):
# permission_classes = [IsAuthenticatedOrTokenMatchesOASRequirements]
# serializer_class = TransactionSerializer
# required_alternate_scopes = {
# "GET": [['wallet.transaction:list']],
# "POST": [['wallet.invoice:create']],
# }
#
# def get_queryset(self):
# user = self.request.user
# return Transaction.objects.filter(Q(payee=user) | Q(payer=user)).all()
#
# def perform_create(self, serializer):
# user = self.request.user
# serializer.save(payee=user, application=get_application(self.request))
# this is application create invoice view
class TransactionList(generics.ListCreateAPIView):
permission_classes = [IsAuthenticatedOrTokenMatchesOASRequirements]
serializer_class = TransactionSerializer
required_alternate_scopes = {
"GET": [['wallet.transaction:list']],
"POST": [['wallet.invoice:create']],
}
def get_queryset(self):
user = self.request.user
return Transaction.objects.filter(Q(payee=user) | Q(payer=user)).all()
def perform_create(self, serializer):
payer = self.request.user
payee = self.request.auth.application.user
serializer.save(payer=payer, payee=payee, application=get_application(self.request))
class TransactionDetail(generics.RetrieveAPIView):
permission_classes = [permissions.IsAuthenticated, IsAuthenticatedOrTokenHasScope]
serializer_class = TransactionSerializer
lookup_field = 'uuid'
required_scopes = ['wallet.transaction:retrieve']
def get_queryset(self):
user = self.request.user
return Transaction.objects.filter(Q(payee=user) | Q(payer=user) | Q(payer__isnull=True)).all()
class TransactionPay(generics.RetrieveAPIView):
permission_classes = [permissions.IsAuthenticated, IsAuthenticatedOrTokenHasScope]
serializer_class = TransactionSerializer
lookup_field = 'uuid'
required_scopes = ['wallet.invoice:pay']
def get_queryset(self):
user = self.request.user
return Transaction.objects.filter(Q(payer=user) | Q(payer__isnull=True)).all()
def retrieve(self, request, *args, **kwargs):
instance = self.get_object()
instance.pay(payer=self.request.user)
serializer = self.get_serializer(instance)
return Response(serializer.data)
class TransactionReceipt(generics.RetrieveAPIView):
permission_classes = [permissions.IsAuthenticated, IsAuthenticatedOrTokenHasScope]
serializer_class = TransactionSerializer
lookup_field = 'uuid'
required_scopes = ['wallet.invoice:receipt']
def get_queryset(self):
user = self.request.user
return Transaction.objects.filter(payer=user).all()
def retrieve(self, request, *args, **kwargs):
instance = self.get_object()
instance.receipt()
serializer = self.get_serializer(instance)
return Response(serializer.data)
class DepositSubmit(generics.CreateAPIView):
permission_classes = [TokenHasScope]
serializer_class = DepositSerializer
required_scopes = ['wallet.deposit:submit']
def get_queryset(self):
application = get_application(self.request)
return Transaction.objects.filter(application=application).all()
def perform_create(self, serializer):
payer = self.request.auth.application.user
serializer.save(payer=payer, application=get_application(self.request))
class DepositVerify(generics.RetrieveAPIView):
permission_classes = [TokenHasScope]
serializer_class = DepositSerializer
lookup_field = 'uuid'
required_scopes = ['wallet.deposit:verify']
def get_queryset(self):
application = get_application(self.request)
return Transaction.objects.filter(application=application).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 = ['wallet.withdraw:submit']
def get_queryset(self):
application = get_application(self.request)
return Transaction.objects.filter(application=application).all()
def perform_create(self, serializer):
payee = self.request.auth.application.user
serializer.save(payee=payee, application=get_application(self.request))
class WithdrawVerify(generics.RetrieveAPIView):
permission_classes = [TokenHasScope]
serializer_class = WithdrawSerializer
lookup_field = 'uuid'
required_scopes = ['wallet.withdraw:verify']
def get_queryset(self):
application = get_application(self.request)
return Transaction.objects.filter(application=application).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)
@method_decorator(login_required, name='dispatch')
class TransactionListView(ListView):
model = Transaction
template_name = 'wallet/transaction_list.html'
def get_queryset(self):
user = self.request.user
return Transaction.objects.filter(Q(payee=user) | Q(payer=user)).all()
@method_decorator(login_required, name='dispatch')
class TransactionDetailView(UpdateView):
model = Transaction
form_class = TransactionActionForm
template_name = 'wallet/transaction_detail.html'
def get_queryset(self):
user = self.request.user
return Transaction.objects.filter(Q(payee=user) | Q(payer=user) | Q(payer__isnull=True)).all()
def get_success_url(self):
return reverse('wallet:transaction_detail', kwargs={'pk': self.get_object().pk})
def form_valid(self, form):
transaction: Transaction = form.instance
if 'pay' in self.request.POST:
result = transaction.pay(payer=self.request.user)
messages.error(self.request, _('success.'))
if 'receipt' in self.request.POST:
result = transaction.receipt()
messages.error(self.request, _('success.'))
return super().form_valid(form)