some cleanups
This commit is contained in:
parent
413a5497e4
commit
c925100fd6
10 changed files with 269 additions and 68 deletions
|
|
@ -0,0 +1,17 @@
|
|||
# Generated by Django 5.1.7 on 2025-10-23 09:31
|
||||
|
||||
from django.db import migrations
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('gooyal_oauth2', '0006_accesstoken_token_checksum_refreshtoken_token_family_and_more'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.RemoveField(
|
||||
model_name='application',
|
||||
name='balance',
|
||||
),
|
||||
]
|
||||
|
|
@ -21,7 +21,7 @@ class OAUTHLoginRequestForm(forms.ModelForm):
|
|||
fields = ['agreement']
|
||||
|
||||
|
||||
class AccountUpdateForm(forms.ModelForm):
|
||||
class Meta:
|
||||
model = UserModel
|
||||
fields = ['iban']
|
||||
# class AccountUpdateForm(forms.ModelForm):
|
||||
# class Meta:
|
||||
# model = UserModel
|
||||
# fields = ['iban']
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
# Generated by Django 5.1.7 on 2025-10-23 09:31
|
||||
|
||||
from django.db import migrations
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('users', '0006_alter_user_balance'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.RemoveField(
|
||||
model_name='user',
|
||||
name='balance',
|
||||
),
|
||||
migrations.RemoveField(
|
||||
model_name='user',
|
||||
name='iban',
|
||||
),
|
||||
migrations.RemoveField(
|
||||
model_name='user',
|
||||
name='iban_verified',
|
||||
),
|
||||
]
|
||||
|
|
@ -13,7 +13,8 @@ from rest_framework import generics
|
|||
|
||||
from apps.gooyal_oauth2.rest_framework import IsAuthenticatedOrTokenMatchesOASRequirements
|
||||
from apps.gooyal_oauth2.validators import OAuth2Validator
|
||||
from apps.users.forms import OAUTHLoginRequestForm, AccountUpdateForm
|
||||
from apps.users.forms import OAUTHLoginRequestForm
|
||||
# from apps.users.forms import AccountUpdateForm
|
||||
from apps.users.models import User, OAuthCode
|
||||
|
||||
UserModel = get_user_model()
|
||||
|
|
@ -95,7 +96,7 @@ class AccountDetailView(DetailView):
|
|||
class AccountUpdateView(UpdateView):
|
||||
model = User
|
||||
template_name = 'users/account_update.html'
|
||||
form_class = AccountUpdateForm
|
||||
# form_class = AccountUpdateForm
|
||||
|
||||
def get_success_url(self):
|
||||
messages.success(self.request, 'عملیات انجام شد.')
|
||||
|
|
|
|||
|
|
@ -1,15 +1,46 @@
|
|||
import django_filters
|
||||
from django.db import models
|
||||
from django.db.models import Q
|
||||
|
||||
from .constans import TypeChoices
|
||||
from .models import Transaction, Wallet
|
||||
|
||||
from .models import Transaction
|
||||
|
||||
class CategoryUUIDFilter(django_filters.BaseInFilter, django_filters.UUIDFilter):
|
||||
pass
|
||||
|
||||
|
||||
class UserTransactionCategoryFilter(django_filters.BaseInFilter, django_filters.UUIDFilter):
|
||||
def filter(self, queryset, value):
|
||||
request = self.parent.request
|
||||
user = request.user
|
||||
|
||||
return queryset.filter(
|
||||
Q(payer_wallet__owner_uuid=user.pk,
|
||||
payer_wallet__owner_type=TypeChoices.USER,
|
||||
payer_wallet__category_id__in=value,
|
||||
) |
|
||||
Q(payee_wallet__owner_uuid=user.pk,
|
||||
payee_wallet__owner_type=TypeChoices.USER,
|
||||
payee_wallet__category_id__in=value,
|
||||
))
|
||||
|
||||
|
||||
class UserTransactionFilter(django_filters.FilterSet):
|
||||
payer_id = django_filters.UUIDFilter(field_name='payer_wallet__owner_uuid', lookup_expr='iexact')
|
||||
payee_id = django_filters.UUIDFilter(field_name='payee_wallet__owner_uuid', lookup_expr='iexact')
|
||||
payer = django_filters.UUIDFilter(field_name='payer_wallet__owner_uuid', lookup_expr='iexact')
|
||||
payee = django_filters.UUIDFilter(field_name='payee_wallet__owner_uuid', lookup_expr='iexact')
|
||||
wallets = UserTransactionCategoryFilter(field_name='payee_wallet__category', required=True, lookup_expr='in')
|
||||
|
||||
class Meta:
|
||||
model = Transaction
|
||||
fields = {
|
||||
}
|
||||
|
||||
|
||||
class WalletFilter(django_filters.FilterSet):
|
||||
wallets = CategoryUUIDFilter(field_name='category', required=True, lookup_expr='in')
|
||||
|
||||
class Meta:
|
||||
model = Wallet
|
||||
fields = {
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,29 @@
|
|||
# Generated by Django 5.1.7 on 2025-10-23 09:31
|
||||
|
||||
from django.db import migrations
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('wallet', '0011_category_currency'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.RemoveField(
|
||||
model_name='transaction',
|
||||
name='_payee_id',
|
||||
),
|
||||
migrations.RemoveField(
|
||||
model_name='transaction',
|
||||
name='_payee_type',
|
||||
),
|
||||
migrations.RemoveField(
|
||||
model_name='transaction',
|
||||
name='_payer_id',
|
||||
),
|
||||
migrations.RemoveField(
|
||||
model_name='transaction',
|
||||
name='_payer_type',
|
||||
),
|
||||
]
|
||||
|
|
@ -160,6 +160,10 @@ class TransferVerifySerializer(serializers.ModelSerializer):
|
|||
|
||||
|
||||
#### Application
|
||||
class WalletSerializer(serializers.ModelSerializer):
|
||||
class Meta:
|
||||
model = Wallet
|
||||
fields = ['balance', 'category']
|
||||
|
||||
class BalanceSerializer(serializers.ModelSerializer):
|
||||
class Meta:
|
||||
|
|
|
|||
|
|
@ -8,37 +8,23 @@ app_name = "wallet"
|
|||
user_urlpatterns = [
|
||||
path('transactions/', user_views.TransactionListView.as_view(), name='user_transaction_list_page'),
|
||||
path('transactions/<pk>', user_views.TransactionDetailView.as_view(), name='user_transaction_detail_page'),
|
||||
path('api/wallet/balance', user_views.CategoryMyWalletBalanceView.as_view(), name='user_wallet_balance_api'),
|
||||
path('api/transactions/', user_views.CategoryTransactionListView.as_view(), name='transaction_list_api'),
|
||||
# path('api/wallet/balance', user_views.CategoryMyWalletBalanceView.as_view(), name='user_wallet_balance_api'),
|
||||
path('api/transactions/', user_views.TransactionListAPIView.as_view(), name='transaction_list_api'),
|
||||
|
||||
path('api/user/<category_uuid>/balance', user_views.CategoryMyWalletBalanceView.as_view(), name='user_wallet_balance_api'),
|
||||
# path('api/user/<category_uuid>/balance', user_views.CategoryMyWalletBalanceView.as_view(), name='user_wallet_balance_api'),
|
||||
path('api/user/<category_uuid>/transactions/', user_views.CategoryTransactionListView.as_view(), name='transaction_list_api'),
|
||||
|
||||
|
||||
# path('api/transactions/<uuid>', TransactionDetail.as_view(), name='transaction_detail_api'),
|
||||
# path('api/transactions/<uuid>/pay', TransactionPay.as_view(), name='transaction_pay_api'),
|
||||
# path('api/transactions/<uuid>/receipt', TransactionReceipt.as_view(), name='transaction_receipt_api'),
|
||||
# #
|
||||
# path('api/deposit/', DepositSubmit.as_view(), name='deposit_submit_api'),
|
||||
# path('api/deposit/<uuid>/verify', DepositVerify.as_view(), name='deposit_verify_api'),
|
||||
# #
|
||||
# path('api/withdraw/', WithdrawSubmit.as_view(), name='withdraw_submit_api'),
|
||||
# path('api/withdraw/<uuid>/verify', WithdrawVerify.as_view(), name='withdraw_verify_api'),
|
||||
|
||||
# path('api/get_balance/', application_views.WalletBalanceView.as_view(), name='wallet_balance'),
|
||||
|
||||
]
|
||||
|
||||
application_urlpatterns = [
|
||||
path('api/application/balance', application_views.BalanceAPIView.as_view(), name='application_wallet_balance_api'),
|
||||
path('api/application/user_balance/<uuid>', application_views.UserBalanceAPIView.as_view(), name='application_user_wallet_balance_api'),
|
||||
path('api/application/', application_views.TransactionListAPIView.as_view(), name='application_transaction_list_api'),
|
||||
path('api/application/<uuid>/', application_views.TransactionDetailAPIView.as_view(), name='application_transaction_detail'),
|
||||
path('api/application/wallets', application_views.WalletListAPIView.as_view(), name='application_wallet_balance_api'),
|
||||
path('api/application/user/<user_uuid>/wallets/', application_views.UserWalletListAPIView.as_view(), name='application_user_wallet_api'),
|
||||
|
||||
# path('api/application/', application_views.TransactionListAPIView.as_view(), name='application_transaction_list_api'),
|
||||
# path('api/application/<uuid>/', application_views.TransactionDetailAPIView.as_view(), name='application_transaction_detail'),
|
||||
|
||||
|
||||
|
||||
path('api/application/<category_uuid>/balance', application_views.BalanceAPIView.as_view(), name='application_wallet_balance_api'),
|
||||
path('api/application/<category_uuid>/user/<uuid>/balance', application_views.UserBalanceAPIView.as_view(), name='application_user_wallet_balance_api'),
|
||||
# path('api/application/<category_uuid>/wallet', application_views.BalanceAPIView.as_view(), name='application_wallet_balance_api'),
|
||||
# path('api/application/<category_uuid>/user/<user_uuid>/wallet', application_views.UserBalanceAPIView.as_view(), name='application_user_wallet_balance_api'),
|
||||
|
||||
path('api/application/<category_uuid>/deposit/', application_views.DepositSubmitAPIView.as_view(), name='application_deposit_submit_api'),
|
||||
path('api/application/<category_uuid>/deposit/<uuid>/verify', application_views.DepositVerifyAPIView.as_view(), name='application_deposit_verify_api'),
|
||||
|
|
@ -46,8 +32,8 @@ application_urlpatterns = [
|
|||
path('api/application/<category_uuid>/withdraw/', application_views.WithdrawSubmitAPIView.as_view(), name='application_withdraw_submit_api'),
|
||||
path('api/application/<category_uuid>/withdraw/<uuid>/verify', application_views.WithdrawVerifyAPIView.as_view(), name='application_withdraw_verify_api'),
|
||||
|
||||
path('api/application/<category_uuid>/', application_views.TransactionListAPIView.as_view(), name='application_transaction_list_api'),
|
||||
path('api/application/<category_uuid>/<uuid>/', application_views.TransactionDetailAPIView.as_view(), name='application_transaction_detail'),
|
||||
path('api/application/<category_uuid>/', application_views.CategoryTransactionListAPIView.as_view(), name='application_transaction_list_api'),
|
||||
path('api/application/<category_uuid>/<uuid>/', application_views.CategoryTransactionDetailAPIView.as_view(), name='application_transaction_detail'),
|
||||
|
||||
]
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
import logging
|
||||
|
||||
from django.db.models import Q
|
||||
from django_filters.rest_framework import DjangoFilterBackend
|
||||
from oauth2_provider.contrib.rest_framework import TokenHasScope, IsAuthenticatedOrTokenHasScope
|
||||
from rest_framework import generics, permissions, mixins
|
||||
from rest_framework.exceptions import APIException
|
||||
|
|
@ -10,9 +11,10 @@ from rest_framework.response import Response
|
|||
|
||||
from apps.users.models import User
|
||||
from apps.wallet.constans import TypeChoices, StateChoices
|
||||
from apps.wallet.filters import WalletFilter, UserTransactionFilter
|
||||
from apps.wallet.models import Transaction, Category, Wallet
|
||||
from apps.wallet.serializers import ApplicationDepositSerializer, ApplicationWithdrawSerializer, \
|
||||
TransactionSerializer, BalanceSerializer
|
||||
TransactionSerializer, BalanceSerializer, WalletSerializer
|
||||
from utils.exceptions import UnprocessableEntity
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
|
|
@ -31,12 +33,14 @@ def get_wallet_category(request: Request):
|
|||
pass
|
||||
|
||||
|
||||
class BalanceAPIView(generics.RetrieveAPIView):
|
||||
class WalletListAPIView(generics.ListAPIView):
|
||||
'''
|
||||
API for getting specified user or application balance.
|
||||
'''
|
||||
permission_classes = [TokenHasScope]
|
||||
serializer_class = BalanceSerializer
|
||||
filter_backends = (DjangoFilterBackend,)
|
||||
filterset_class = WalletFilter
|
||||
permission_classes = [IsAuthenticatedOrTokenHasScope]
|
||||
required_scopes = ['wallet.application:get_balance']
|
||||
|
||||
def get_object(self):
|
||||
|
|
@ -51,62 +55,140 @@ class BalanceAPIView(generics.RetrieveAPIView):
|
|||
category=category)
|
||||
return wallet
|
||||
|
||||
def get_queryset(self):
|
||||
category_uuid = self.kwargs.get('category_uuid')
|
||||
if category_uuid:
|
||||
category = get_object_or_404(Category.objects.all(), uuid=category_uuid)
|
||||
else:
|
||||
category = None
|
||||
application = get_application(self.request)
|
||||
wallet, created = Wallet.objects.get_or_create(owner_uuid=application.uuid, owner_type=TypeChoices.APPLICATION,
|
||||
category=category)
|
||||
return Wallet.objects.filter(owner_uuid=application.uuid, owner_type=TypeChoices.APPLICATION).all()
|
||||
|
||||
class UserBalanceAPIView(generics.RetrieveAPIView):
|
||||
|
||||
class UserWalletListAPIView(generics.ListAPIView):
|
||||
'''
|
||||
API for getting specified user or application balance.
|
||||
API for getting specified user wallet.
|
||||
'''
|
||||
serializer_class = WalletSerializer
|
||||
filter_backends = (DjangoFilterBackend,)
|
||||
filterset_class = WalletFilter
|
||||
permission_classes = [IsAuthenticatedOrTokenHasScope]
|
||||
serializer_class = BalanceSerializer
|
||||
required_scopes = ['wallet.application:get_user_balance']
|
||||
|
||||
def get_object(self):
|
||||
queryset = Wallet.objects.all()
|
||||
|
||||
def get_queryset(self):
|
||||
qs = super().get_queryset()
|
||||
category_uuid = self.kwargs.get('category_uuid')
|
||||
user_uuid = self.kwargs.get('user_uuid')
|
||||
if category_uuid:
|
||||
category = get_object_or_404(Category.objects.all(), uuid=category_uuid)
|
||||
else:
|
||||
category = None
|
||||
user, created = User.objects.get_or_create(uuid=self.kwargs.get('uuid'))
|
||||
wallet, created = Wallet.objects.get_or_create(owner_uuid=user_uuid, owner_type=TypeChoices.USER,
|
||||
category=category)
|
||||
return qs.filter(owner_uuid=user_uuid, owner_type=TypeChoices.USER).all()
|
||||
|
||||
|
||||
class TransactionDetailAPIView(generics.RetrieveAPIView):
|
||||
serializer_class = TransactionSerializer
|
||||
lookup_field = 'uuid'
|
||||
filter_backends = (DjangoFilterBackend,)
|
||||
filterset_class = WalletFilter
|
||||
permission_classes = [TokenHasScope]
|
||||
required_scopes = ['wallet.application:get_transaction_detail']
|
||||
queryset = Transaction.objects.all()
|
||||
|
||||
def get_queryset(self):
|
||||
qs = super().get_queryset()
|
||||
|
||||
application = get_application(self.request)
|
||||
return Transaction.objects.filter(Q(application=application) |
|
||||
Q(payer_wallet__owner_uuid=application.pk,
|
||||
payer_wallet__owner_type=TypeChoices.APPLICATION,
|
||||
) |
|
||||
Q(payee_wallet__owner_uuid=application.pk,
|
||||
payee_wallet__owner_type=TypeChoices.APPLICATION,
|
||||
)
|
||||
).all()
|
||||
|
||||
|
||||
class TransactionListAPIView(generics.ListAPIView):
|
||||
serializer_class = TransactionSerializer
|
||||
lookup_field = 'uuid'
|
||||
filter_backends = (DjangoFilterBackend,)
|
||||
filterset_class = UserTransactionFilter
|
||||
permission_classes = [IsAuthenticatedOrTokenHasScope]
|
||||
required_scopes = ['wallet.application:get_transaction_list']
|
||||
queryset = Transaction.objects.all()
|
||||
|
||||
def get_queryset(self):
|
||||
qs = super().get_queryset()
|
||||
|
||||
application = get_application(self.request)
|
||||
return qs.filter(Q(application=application) |
|
||||
Q(payer_wallet__owner_uuid=application.pk,
|
||||
payer_wallet__owner_type=TypeChoices.APPLICATION) |
|
||||
Q(payee_wallet__owner_uuid=application.pk,
|
||||
payee_wallet__owner_type=TypeChoices.APPLICATION,
|
||||
)
|
||||
).all()
|
||||
|
||||
class CategoryTransactionDetailAPIView(generics.RetrieveAPIView):
|
||||
permission_classes = [TokenHasScope]
|
||||
serializer_class = TransactionSerializer
|
||||
lookup_field = 'uuid'
|
||||
required_scopes = ['wallet.application:get_transaction_detail']
|
||||
queryset = Transaction.objects.all()
|
||||
|
||||
def get_queryset(self):
|
||||
qs = super().get_queryset()
|
||||
|
||||
category_uuid = self.kwargs.get('category_uuid')
|
||||
if category_uuid:
|
||||
category = get_object_or_404(Category.objects.all(), uuid=category_uuid)
|
||||
else:
|
||||
category = None
|
||||
|
||||
user_uuid = self.kwargs.get('uuid')
|
||||
user, created = User.objects.get_or_create(uuid=user_uuid)
|
||||
application = get_application(self.request)
|
||||
wallet, created = Wallet.objects.get_or_create(owner_uuid=user_uuid, owner_type=TypeChoices.USER,
|
||||
category=category)
|
||||
return wallet
|
||||
|
||||
|
||||
class TransactionDetailAPIView(generics.RetrieveAPIView):
|
||||
permission_classes = [TokenHasScope]
|
||||
serializer_class = TransactionSerializer
|
||||
lookup_field = 'uuid'
|
||||
required_scopes = ['wallet.application:get_transaction_detail']
|
||||
|
||||
def get_queryset(self):
|
||||
# TODO: what about category
|
||||
application = get_application(self.request)
|
||||
return Transaction.objects.filter(Q(application=application) |
|
||||
Q(payer_wallet__owner_uuid=application.pk,
|
||||
payer_wallet__owner_type=TypeChoices.APPLICATION) |
|
||||
payer_wallet__owner_type=TypeChoices.APPLICATION,
|
||||
payer_wallet__category=category) |
|
||||
Q(payee_wallet__owner_uuid=application.pk,
|
||||
payee_wallet__owner_type=TypeChoices.APPLICATION)
|
||||
payee_wallet__owner_type=TypeChoices.APPLICATION,
|
||||
payee_wallet__category=category)
|
||||
).all()
|
||||
|
||||
|
||||
class TransactionListAPIView(generics.ListAPIView):
|
||||
class CategoryTransactionListAPIView(generics.ListAPIView):
|
||||
permission_classes = [TokenHasScope]
|
||||
serializer_class = TransactionSerializer
|
||||
lookup_field = 'uuid'
|
||||
required_scopes = ['wallet.application:get_transaction_list']
|
||||
queryset = Transaction.objects.all()
|
||||
|
||||
def get_queryset(self):
|
||||
# TODO: what about category?
|
||||
qs = super().get_queryset()
|
||||
|
||||
category_uuid = self.kwargs.get('category_uuid')
|
||||
if category_uuid:
|
||||
category = get_object_or_404(Category.objects.all(), uuid=category_uuid)
|
||||
else:
|
||||
category = None
|
||||
|
||||
application = get_application(self.request)
|
||||
return Transaction.objects.filter(Q(application=application) |
|
||||
Q(payer_wallet__owner_uuid=application.pk,
|
||||
payer_wallet__owner_type=TypeChoices.APPLICATION) |
|
||||
Q(payee_wallet__owner_uuid=application.pk,
|
||||
payee_wallet__owner_type=TypeChoices.APPLICATION)
|
||||
).all()
|
||||
return qs.filter(Q(application=application) |
|
||||
Q(payer_wallet__owner_uuid=application.pk,
|
||||
payer_wallet__owner_type=TypeChoices.APPLICATION,
|
||||
payer_wallet__category=category) |
|
||||
Q(payee_wallet__owner_uuid=application.pk,
|
||||
payee_wallet__owner_type=TypeChoices.APPLICATION,
|
||||
payee_wallet__category=category)
|
||||
).all()
|
||||
|
||||
|
||||
# from application to another entity
|
||||
|
|
|
|||
|
|
@ -249,6 +249,32 @@ class CategoryMyWalletBalanceView(generics.RetrieveAPIView):
|
|||
|
||||
|
||||
# this is application create invoice view
|
||||
class TransactionListAPIView(generics.ListAPIView):
|
||||
'''
|
||||
GET: API for getting list of transactions for authenticated user
|
||||
POST: API for creating transaction for transferring funds from authenticated user to application owner. (deprecated)
|
||||
args:
|
||||
- user: authenticated user
|
||||
|
||||
'''
|
||||
permission_classes = [IsAuthenticatedOrTokenMatchesOASRequirements]
|
||||
serializer_class = TransactionSerializer
|
||||
required_alternate_scopes = {
|
||||
"GET": [['wallet.user:transaction_list']],
|
||||
# "POST": [['wallet.invoice:create']],
|
||||
}
|
||||
|
||||
filter_backends = (DjangoFilterBackend,)
|
||||
filterset_class = UserTransactionFilter
|
||||
queryset = Transaction.objects.all()
|
||||
|
||||
# TODO: redundant
|
||||
def get_queryset(self):
|
||||
user = self.request.user
|
||||
return Transaction.objects.filter(Q(payee_wallet__owner_uuid=user.uuid) |
|
||||
Q(payer_wallet__owner_uuid=user.uuid)).all()
|
||||
|
||||
|
||||
class CategoryTransactionListView(generics.ListAPIView):
|
||||
'''
|
||||
GET: API for getting list of transactions for authenticated user
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue