diff --git a/apps/gooyal_oauth2/models.py b/apps/gooyal_oauth2/models.py
index 1ce7ad3..d620904 100644
--- a/apps/gooyal_oauth2/models.py
+++ b/apps/gooyal_oauth2/models.py
@@ -5,6 +5,8 @@ from oauth2_provider.models import AbstractApplication, AbstractAccessToken, Abs
import uuid
from django.utils.translation import gettext_lazy as _
+from apps.wallet.constans import TypeChoices
+
class AccessToken(AbstractAccessToken):
id = None
@@ -25,6 +27,14 @@ class Application(AbstractApplication):
class Meta:
abstract = False
+ @property
+ def instance_id(self):
+ return self.pk
+
+ @property
+ def instance_type(self):
+ return TypeChoices.APPLICATION
+
class Grant(AbstractGrant):
id = None
diff --git a/apps/users/models.py b/apps/users/models.py
index e94e608..97e408b 100644
--- a/apps/users/models.py
+++ b/apps/users/models.py
@@ -12,6 +12,7 @@ import string
import base64
import hashlib
+from apps.wallet.constans import TypeChoices
class UserManager(BaseUserManager):
@@ -75,6 +76,14 @@ class User(AbstractUser):
def __str__(self):
return str(self.username or self.pk)
+ @property
+ def instance_id(self):
+ return self.pk
+
+ @property
+ def instance_type(self):
+ return TypeChoices.APPLICATION
+
# TODO: user redis instead.
# TODO: create a queryset
diff --git a/apps/wallet/application_views.py b/apps/wallet/application_views.py
deleted file mode 100755
index ede6018..0000000
--- a/apps/wallet/application_views.py
+++ /dev/null
@@ -1,74 +0,0 @@
-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, mixins
-from rest_framework.permissions import AllowAny
-from rest_framework.response import Response
-from rest_framework.viewsets import GenericViewSet, ModelViewSet
-
-from apps.gooyal_oauth2.rest_framework import IsAuthenticatedOrTokenMatchesOASRequirements, \
- IsAuthenticatedOrActionMatchesOASRequirements
-from apps.wallet.models import Transaction
-from apps.wallet.serializers import TransactionSerializer, DepositSerializer, WithdrawSerializer, WalletSerializer
-from .constans import StateChoices
-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 ApplicationWalletBalanceView(generics.RetrieveAPIView):
- '''
- API for getting authenticated user balance.
- '''
- permission_classes = [TokenHasScope]
- serializer_class = WalletSerializer
- required_scopes = ['wallet.application:get_balance']
-
- def get_object(self):
- return self.request.user
-
- def retrieve(self, request, *args, **kwargs):
- return super().retrieve(request, *args, **kwargs)
-
-
-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)
-
-
diff --git a/apps/wallet/constans.py b/apps/wallet/constans.py
index 73d8545..3531ce6 100644
--- a/apps/wallet/constans.py
+++ b/apps/wallet/constans.py
@@ -5,7 +5,7 @@ from django.utils.translation import gettext_lazy as _
class StateChoices(IntegerChoices):
CREATED = 1 , _('created')
DELAYED = 2 , _('delayed') # delayed as user wish
- PENDING = 3 , _('pending') # wait for external service response
+ PENDING = 3 , _('pending') # wait for external service response (or action)
INCOMPLETE = 4 , _('incomplete') # started and wait for internal progress to complete
SUCCESS = 5 , _('success')
FAILED = 6 , _('failed')
diff --git a/apps/wallet/migrations/0005_remove_transaction_detail_transaction_details_and_more.py b/apps/wallet/migrations/0005_remove_transaction_detail_transaction_details_and_more.py
new file mode 100644
index 0000000..01ae594
--- /dev/null
+++ b/apps/wallet/migrations/0005_remove_transaction_detail_transaction_details_and_more.py
@@ -0,0 +1,33 @@
+# Generated by Django 5.0.6 on 2024-08-11 10:40
+
+import django.core.validators
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('wallet', '0004_remove_transaction_payee_remove_transaction_payer_and_more'),
+ ]
+
+ operations = [
+ migrations.RemoveField(
+ model_name='transaction',
+ name='detail',
+ ),
+ migrations.AddField(
+ model_name='transaction',
+ name='details',
+ field=models.JSONField(blank=True, default=dict, null=True),
+ ),
+ migrations.AlterField(
+ model_name='transaction',
+ name='amount',
+ field=models.PositiveBigIntegerField(validators=[django.core.validators.MinValueValidator(1)], verbose_name='amount'),
+ ),
+ migrations.AlterField(
+ model_name='transaction',
+ name='delay',
+ field=models.PositiveIntegerField(blank=True, default=0),
+ ),
+ ]
diff --git a/apps/wallet/models.py b/apps/wallet/models.py
index 2c68398..ceefd00 100755
--- a/apps/wallet/models.py
+++ b/apps/wallet/models.py
@@ -193,4 +193,4 @@ class Transaction(models.Model):
return self
def __str__(self):
- return f"{self.get_payer()} -> {self.get_payee()} ({self.uuid}): {self.amount}"
+ return f"{self.get_payer()} -> {self.get_payee()} ({self.uuid}): {self.amount} - {self.get_state_display()}"
diff --git a/apps/wallet/serializers.py b/apps/wallet/serializers.py
index b9cd5ae..4bfa9c1 100755
--- a/apps/wallet/serializers.py
+++ b/apps/wallet/serializers.py
@@ -3,6 +3,7 @@ from django.db.transaction import atomic
from rest_framework import serializers
from rest_framework.exceptions import APIException
+from .constans import TypeChoices
from .models import Transaction
from ..users.models import User
@@ -10,6 +11,7 @@ from ..users.models import User
class TransactionSerializer(serializers.ModelSerializer):
payee_id = serializers.UUIDField(read_only=True)
payee_type = serializers.UUIDField(read_only=True)
+
class Meta:
model = Transaction
fields = ('uuid',
@@ -92,7 +94,55 @@ class WithdrawSerializer(serializers.ModelSerializer):
return transaction
-class WalletSerializer(serializers.ModelSerializer):
+class MyWalletSerializer(serializers.ModelSerializer):
class Meta:
- model=User
+ model = User
fields = ['balance']
+
+
+class WalletBalanceSerializer(serializers.ModelSerializer):
+ instance_id = serializers.UUIDField(required=True)
+ instance_type = serializers.ChoiceField(choices=TypeChoices.choices, required=True)
+
+ class Meta:
+ model = User
+ fields = ['balance', 'instance_id', 'instance_type']
+
+
+class TransferSubmitSerializer(serializers.ModelSerializer):
+ class Meta:
+ model = Transaction
+ fields = ('uuid',
+ 'payer_id',
+ 'payer_type',
+ 'payee_id',
+ 'payee_type',
+ "created_at",
+ "state",
+ 'amount',
+ # 'delay',
+ 'updated_at',
+ 'details',
+ )
+
+ read_only_fields = ['uuid', 'updated_at', 'state', 'created_at']
+
+
+class TransferVerifySerializer(serializers.ModelSerializer):
+ class Meta:
+ model = Transaction
+ fields = ('uuid',
+ 'payer_id',
+ 'payer_type',
+ 'payee_id',
+ 'payee_type',
+ "created_at",
+ "state",
+ 'amount',
+ # 'delay',
+ 'updated_at',
+ 'details',
+ )
+
+ read_only_fields = ['uuid', 'payer_id', 'payer_type', 'payee_id', 'payee_type', 'updated_at', 'state',
+ 'amount', 'created_at']
diff --git a/apps/wallet/urls.py b/apps/wallet/urls.py
index f780ed9..0c73da6 100644
--- a/apps/wallet/urls.py
+++ b/apps/wallet/urls.py
@@ -1,28 +1,30 @@
from django.urls import path
-from .application_views import ApplicationWalletBalanceView
-from .views import TransactionList, TransactionDetail, TransactionPay, TransactionReceipt, \
- WithdrawVerify, WithdrawSubmit, DepositSubmit, DepositVerify, TransactionListView, TransactionDetailView, \
- WalletBalanceView
+from .views import application as application_views
+from .views import user as user_views
app_name = "wallet"
urlpatterns = [
- path('transactions/', TransactionListView.as_view(), name='transaction_list'),
- path('transactions/