From b89487653f306792f94b74b2439cc209c4b56922 Mon Sep 17 00:00:00 2001 From: Sayyid Hamid Mahdavi Date: Sat, 25 Oct 2025 14:26:47 +0330 Subject: [PATCH] change wallet to account --- apps/wallet/admin.py | 4 +- apps/wallet/filters.py | 30 ++-- .../0013_rename_wallet_account_and_more.py | 18 +++ ...emove_transaction_payee_wallet_and_more.py | 24 +++ ...lter_transaction_payee_account_and_more.py | 24 +++ apps/wallet/models.py | 42 +++--- apps/wallet/serializers.py | 24 ++- apps/wallet/tests/application.py | 20 +-- apps/wallet/urls.py | 8 +- apps/wallet/views/application.py | 141 +++++++++--------- apps/wallet/views/user.py | 16 +- 11 files changed, 204 insertions(+), 147 deletions(-) create mode 100644 apps/wallet/migrations/0013_rename_wallet_account_and_more.py create mode 100644 apps/wallet/migrations/0014_remove_transaction_payee_wallet_and_more.py create mode 100644 apps/wallet/migrations/0015_alter_transaction_payee_account_and_more.py diff --git a/apps/wallet/admin.py b/apps/wallet/admin.py index c1b2165..185dbdd 100755 --- a/apps/wallet/admin.py +++ b/apps/wallet/admin.py @@ -1,5 +1,5 @@ from django.contrib import admin -from .models import Transaction, Wallet, Category +from .models import Transaction, Account, Category class TransactionAdmin(admin.ModelAdmin): list_display = ['uuid', 'amount', 'created_at', 'updated_at', 'payer', 'payer_type', 'payee', 'payee_type', 'state', 'application'] @@ -7,5 +7,5 @@ class TransactionAdmin(admin.ModelAdmin): list_filter = ['state'] admin.site.register(Transaction, TransactionAdmin) -admin.site.register(Wallet) +admin.site.register(Account) admin.site.register(Category) diff --git a/apps/wallet/filters.py b/apps/wallet/filters.py index 7908c0f..2267dff 100644 --- a/apps/wallet/filters.py +++ b/apps/wallet/filters.py @@ -3,33 +3,33 @@ from django.db import models from django.db.models import Q from .constans import TypeChoices -from .models import Transaction, Wallet +from .models import Transaction, Account -class CategoryUUIDFilter(django_filters.BaseInFilter, django_filters.UUIDFilter): +class WalletUUIDFilter(django_filters.BaseInFilter, django_filters.UUIDFilter): pass -class UserTransactionCategoryFilter(django_filters.BaseInFilter, django_filters.UUIDFilter): +class UserTransactionWalletFilter(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(payer_account__owner_uuid=user.pk, + payer_account__owner_type=TypeChoices.USER, + payer_account__category_id__in=value, ) | - Q(payee_wallet__owner_uuid=user.pk, - payee_wallet__owner_type=TypeChoices.USER, - payee_wallet__category_id__in=value, + Q(payee_account__owner_uuid=user.pk, + payee_account__owner_type=TypeChoices.USER, + payee_account__category_id__in=value, )) class UserTransactionFilter(django_filters.FilterSet): - 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') + payer = django_filters.UUIDFilter(field_name='payer_account__owner_uuid', lookup_expr='iexact') + payee = django_filters.UUIDFilter(field_name='payee_account__owner_uuid', lookup_expr='iexact') + wallets = UserTransactionWalletFilter(field_name='payee_account__wallet', required=True, lookup_expr='in') class Meta: model = Transaction @@ -37,10 +37,10 @@ class UserTransactionFilter(django_filters.FilterSet): } -class WalletFilter(django_filters.FilterSet): - wallets = CategoryUUIDFilter(field_name='category', required=True, lookup_expr='in') +class AccountFilter(django_filters.FilterSet): + wallets = WalletUUIDFilter(field_name='category', required=True, lookup_expr='in') class Meta: - model = Wallet + model = Account fields = { } diff --git a/apps/wallet/migrations/0013_rename_wallet_account_and_more.py b/apps/wallet/migrations/0013_rename_wallet_account_and_more.py new file mode 100644 index 0000000..03d8705 --- /dev/null +++ b/apps/wallet/migrations/0013_rename_wallet_account_and_more.py @@ -0,0 +1,18 @@ +# Generated by Django 5.1.7 on 2025-10-25 10:41 + +import django.db.models.deletion +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('wallet', '0012_remove_transaction__payee_id_and_more'), + ] + + operations = [ + migrations.RenameModel( + old_name='Wallet', + new_name='Account', + ), + ] diff --git a/apps/wallet/migrations/0014_remove_transaction_payee_wallet_and_more.py b/apps/wallet/migrations/0014_remove_transaction_payee_wallet_and_more.py new file mode 100644 index 0000000..07edca6 --- /dev/null +++ b/apps/wallet/migrations/0014_remove_transaction_payee_wallet_and_more.py @@ -0,0 +1,24 @@ +# Generated by Django 5.1.7 on 2025-10-25 10:42 + +import django.db.models.deletion +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('wallet', '0013_rename_wallet_account_and_more'), + ] + + operations = [ + migrations.RenameField( + model_name='transaction', + old_name='payee_wallet', + new_name='payee_account', + ), + migrations.RenameField( + model_name='transaction', + old_name='payer_wallet', + new_name='payer_account', + ), + ] diff --git a/apps/wallet/migrations/0015_alter_transaction_payee_account_and_more.py b/apps/wallet/migrations/0015_alter_transaction_payee_account_and_more.py new file mode 100644 index 0000000..c007baa --- /dev/null +++ b/apps/wallet/migrations/0015_alter_transaction_payee_account_and_more.py @@ -0,0 +1,24 @@ +# Generated by Django 5.1.7 on 2025-10-25 10:44 + +import django.db.models.deletion +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('wallet', '0014_remove_transaction_payee_wallet_and_more'), + ] + + operations = [ + migrations.AlterField( + model_name='transaction', + name='payee_account', + field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.PROTECT, related_name='payee_account_transactions', to='wallet.account'), + ), + migrations.AlterField( + model_name='transaction', + name='payer_account', + field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.PROTECT, related_name='payer_account_transactions', to='wallet.account'), + ), + ] diff --git a/apps/wallet/models.py b/apps/wallet/models.py index 1a40681..0b2cf86 100755 --- a/apps/wallet/models.py +++ b/apps/wallet/models.py @@ -22,16 +22,16 @@ class CurrencyChoices(models.TextChoices): IRANIAN_RIAL = '166ab7ce33b34799950d45035a9997d6', _('IRANIAN RIAL') # uuid without dash -class WalletQuerySet(models.QuerySet): +class AccountQuerySet(models.QuerySet): pass -class Wallet(BaseModel): +class Account(BaseModel): owner_uuid = models.UUIDField(db_index=True, null=False) category = models.ForeignKey('Category', on_delete=models.PROTECT, null=True) owner_type = models.IntegerField(choices=TypeChoices.choices, db_index=True) balance = models.BigIntegerField(_('balance'), default=0) - objects = WalletQuerySet.as_manager() + objects = AccountQuerySet.as_manager() def get_owner(self): if self.owner_type == TypeChoices.APPLICATION: @@ -85,7 +85,7 @@ class Category(BaseModel): class TransactionQuerySet(models.QuerySet): def available(self): - return self.select_related('payer_wallet', 'payee_wallet') + return self.select_related('payer_account', 'payee_account') class Transaction(BaseModel): @@ -94,11 +94,11 @@ class Transaction(BaseModel): state = models.IntegerField(choices=StateChoices.choices, default=StateChoices.CREATED) application = models.ForeignKey(oauth2_settings.APPLICATION_MODEL, on_delete=models.PROTECT, related_name='transactions', null=True) - payer_wallet = models.ForeignKey(Wallet, on_delete=models.PROTECT, null=True, - related_name='payer_wallet_transactions', + payer_account = models.ForeignKey(Account, on_delete=models.PROTECT, null=True, + related_name='payer_account_transactions', db_index=True) - payee_wallet = models.ForeignKey(Wallet, on_delete=models.PROTECT, null=True, - related_name='payee_wallet_transactions', + payee_account = models.ForeignKey(Account, on_delete=models.PROTECT, null=True, + related_name='payee_account_transactions', db_index=True) details = models.JSONField(null=True, blank=True, default=dict) @@ -119,34 +119,34 @@ class Transaction(BaseModel): # unique_together = ('application', 'detail_id',) def get_payer(self): - return self.payer_wallet.get_owner() + return self.payer_account.get_owner() def get_payee(self): - return self.payee_wallet.get_owner() + return self.payee_account.get_owner() @cached_property - def payer_wallet_category(self): - return self.payer_wallet and self.payer_wallet.category_id + def payer_wallet(self): + return self.payer_account and self.payer_account.category_id @cached_property - def payee_wallet_category(self): - return self.payee_wallet and self.payee_wallet.category_id + def payee_wallet(self): + return self.payee_account and self.payee_account.category_id @cached_property def payer(self): - return self.payer_wallet.owner_uuid + return self.payer_account.owner_uuid @cached_property def payer_type(self): - return self.payer_wallet.owner_type + return self.payer_account.owner_type @cached_property def payee(self): - return self.payee_wallet.owner_uuid + return self.payee_account.owner_uuid @cached_property def payee_type(self): - return self.payee_wallet.owner_type + return self.payee_account.owner_type def change_state(self, from_state, to_state, error_message=None, **data): if self.state == from_state: @@ -162,9 +162,9 @@ class Transaction(BaseModel): raise APIException(error_message) def withdraw_from_payer_balance(self): - payer_is_allowed_negative_balance = self.payer_wallet.owner_type == TypeChoices.APPLICATION.value and str( - self.payer_wallet.owner_uuid) in settings.ALLOWED_NEGATIVE_BALANCE_APPLICATIONS - if self.amount > self.payer_wallet.balance and not payer_is_allowed_negative_balance: + payer_is_allowed_negative_balance = self.payer_account.owner_type == TypeChoices.APPLICATION.value and str( + self.payer_account.owner_uuid) in settings.ALLOWED_NEGATIVE_BALANCE_APPLICATIONS + if self.amount > self.payer_account.balance and not payer_is_allowed_negative_balance: raise UnprocessableEntity('not enough balance') self.payer_wallet.balance = F('balance') - self.amount self.payer_wallet.save(update_fields=['balance']) diff --git a/apps/wallet/serializers.py b/apps/wallet/serializers.py index 9535997..e507ff5 100755 --- a/apps/wallet/serializers.py +++ b/apps/wallet/serializers.py @@ -5,7 +5,7 @@ from rest_framework import serializers from rest_framework.exceptions import APIException from .constans import TypeChoices -from .models import Transaction, Wallet +from .models import Transaction, Account from ..gooyal_oauth2.models import Application from ..users.models import User @@ -13,8 +13,8 @@ from ..users.models import User class TransactionSerializer(serializers.ModelSerializer): payee = serializers.UUIDField(read_only=True) payee_type = serializers.IntegerField(read_only=True) - payee_wallet = serializers.UUIDField(source='payee_wallet_category', read_only=True) - payer_wallet = serializers.UUIDField(source='payer_wallet_category', read_only=True) + # payee_wallet = serializers.UUIDField(source='payee_wallet_category', read_only=True) + # payer_wallet = serializers.UUIDField(source='payer_wallet_category', read_only=True) role = serializers.SerializerMethodField() class Meta: @@ -111,7 +111,7 @@ class WithdrawSerializer(serializers.ModelSerializer): return transaction -class WalletBalanceSerializer(serializers.ModelSerializer): +class AccountBalanceSerializer(serializers.ModelSerializer): instance_id = serializers.UUIDField(required=True) instance_type = serializers.ChoiceField(choices=TypeChoices.choices, required=True) @@ -160,22 +160,18 @@ class TransferVerifySerializer(serializers.ModelSerializer): #### Application -class WalletSerializer(serializers.ModelSerializer): +class AccountSerializer(serializers.ModelSerializer): class Meta: - model = Wallet + model = Account fields = ['balance', 'category'] -class BalanceSerializer(serializers.ModelSerializer): - class Meta: - model = Wallet - fields = ['balance', 'category'] class ApplicationDepositSerializer(serializers.ModelSerializer): uuid = serializers.UUIDField(required=False, validators=[]) payee = serializers.UUIDField(required=True) payee_type = serializers.IntegerField(required=True) - payee_wallet = serializers.UUIDField(source='payee_wallet_category', required=False) # TODO: required True - payer_wallet = serializers.UUIDField(source='payer_wallet_category', read_only=True) + # payee_wallet = serializers.UUIDField(source='payee_wallet', required=False) # TODO: required True + # payer_wallet = serializers.UUIDField(source='payer_wallet', read_only=True) amount = serializers.IntegerField(required=True, validators=[MinValueValidator(1)]) # TODO: details as fields @@ -204,8 +200,8 @@ class ApplicationWithdrawSerializer(serializers.ModelSerializer): uuid = serializers.UUIDField(required=False, validators=[]) payer = serializers.UUIDField(required=True) payer_type = serializers.IntegerField(required=True) - payer_wallet = serializers.UUIDField(source='payer_wallet_category',required=False) # TODO: required True - payee_wallet = serializers.UUIDField(source='payee_wallet_category', read_only=True) # TODO: required True + # payer_wallet = serializers.UUIDField(source='payer_wallet',required=False) # TODO: required True + # payee_wallet = serializers.UUIDField(source='payee_wallet', read_only=True) # TODO: required True amount = serializers.IntegerField(required=True, validators=[MinValueValidator(1)]) class Meta: diff --git a/apps/wallet/tests/application.py b/apps/wallet/tests/application.py index 368cafb..530ff80 100755 --- a/apps/wallet/tests/application.py +++ b/apps/wallet/tests/application.py @@ -8,7 +8,7 @@ from rest_framework.test import APITestCase, override_settings from apps.users.models import User from apps.wallet.constans import TypeChoices -from apps.wallet.models import Wallet +from apps.wallet.models import Account from apps.wallet.models import Category AccessToken = get_access_token_model() @@ -41,9 +41,9 @@ class ApplicationApiFlowsTests(APITestCase): def setUp(self): self.application_user, _ = User.objects.get_or_create(pk=self.application_uuid) self.payer_user, _ = User.objects.get_or_create(pk=self.payer_uuid) - self.application_wallet, _ = Wallet.objects.get_or_create(owner_uuid=self.application_uuid, owner_type=TypeChoices.APPLICATION, balance=300) - self.payee_wallet, _ = Wallet.objects.get_or_create(owner_uuid=self.payee_uuid, owner_type=TypeChoices.USER) - self.payer_wallet, _ = Wallet.objects.get_or_create(owner_uuid=self.payer_uuid, owner_type=TypeChoices.USER, balance=300) + self.application_wallet, _ = Account.objects.get_or_create(owner_uuid=self.application_uuid, owner_type=TypeChoices.APPLICATION, balance=300) + self.payee_wallet, _ = Account.objects.get_or_create(owner_uuid=self.payee_uuid, owner_type=TypeChoices.USER) + self.payer_wallet, _ = Account.objects.get_or_create(owner_uuid=self.payer_uuid, owner_type=TypeChoices.USER, balance=300) expire_datetime = timezone.now() + timedelta(seconds=3600) expire_datetime.isoformat() @@ -77,12 +77,12 @@ class ApplicationApiFlowsTests(APITestCase): ) self.wallet_category1, _ = Category.objects.get_or_create(application=self.application, uuid=self.wallet_category1_uuid) self.wallet_category2, _ = Category.objects.get_or_create(application=self.application, uuid=self.wallet_category2_uuid) - self.application_wallet1, _ = Wallet.objects.get_or_create(owner_uuid=self.application_uuid, owner_type=TypeChoices.APPLICATION, balance=300, category=self.wallet_category1) - self.application_wallet2, _ = Wallet.objects.get_or_create(owner_uuid=self.application_uuid, owner_type=TypeChoices.APPLICATION, balance=300, category=self.wallet_category2) - self.payee_wallet1, _ = Wallet.objects.get_or_create(owner_uuid=self.payee_uuid, owner_type=TypeChoices.USER, category=self.wallet_category1) - self.payee_wallet2, _ = Wallet.objects.get_or_create(owner_uuid=self.payee_uuid, owner_type=TypeChoices.USER, category=self.wallet_category2) - self.payer_wallet1, _ = Wallet.objects.get_or_create(owner_uuid=self.payer_uuid, owner_type=TypeChoices.USER, balance=300, category=self.wallet_category1) - self.payer_wallet2, _ = Wallet.objects.get_or_create(owner_uuid=self.payer_uuid, owner_type=TypeChoices.USER, balance=300, category=self.wallet_category2) + self.application_wallet1, _ = Account.objects.get_or_create(owner_uuid=self.application_uuid, owner_type=TypeChoices.APPLICATION, balance=300, category=self.wallet_category1) + self.application_wallet2, _ = Account.objects.get_or_create(owner_uuid=self.application_uuid, owner_type=TypeChoices.APPLICATION, balance=300, category=self.wallet_category2) + self.payee_wallet1, _ = Account.objects.get_or_create(owner_uuid=self.payee_uuid, owner_type=TypeChoices.USER, category=self.wallet_category1) + self.payee_wallet2, _ = Account.objects.get_or_create(owner_uuid=self.payee_uuid, owner_type=TypeChoices.USER, category=self.wallet_category2) + self.payer_wallet1, _ = Account.objects.get_or_create(owner_uuid=self.payer_uuid, owner_type=TypeChoices.USER, balance=300, category=self.wallet_category1) + self.payer_wallet2, _ = Account.objects.get_or_create(owner_uuid=self.payer_uuid, owner_type=TypeChoices.USER, balance=300, category=self.wallet_category2) def tearDown(self): super().tearDown() diff --git a/apps/wallet/urls.py b/apps/wallet/urls.py index 44f00b8..fa65f59 100644 --- a/apps/wallet/urls.py +++ b/apps/wallet/urls.py @@ -8,16 +8,16 @@ app_name = "wallet" user_urlpatterns = [ path('transactions/', user_views.TransactionListView.as_view(), name='user_transaction_list_page'), path('transactions/', 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/wallet/balance', user_views.CategoryMyAccountBalanceView.as_view(), name='user_wallet_balance_api'), path('api/transactions/', user_views.TransactionListAPIView.as_view(), name='transaction_list_api'), - # path('api/user//balance', user_views.CategoryMyWalletBalanceView.as_view(), name='user_wallet_balance_api'), + # path('api/user//balance', user_views.CategoryMyAccountBalanceView.as_view(), name='user_wallet_balance_api'), path('api/user//transactions/', user_views.CategoryTransactionListView.as_view(), name='transaction_list_api'), ] application_urlpatterns = [ - path('api/application/wallets', application_views.WalletListAPIView.as_view(), name='application_wallet_balance_api'), - path('api/application/user//wallets/', application_views.UserWalletListAPIView.as_view(), name='application_user_wallet_api'), + path('api/application/accounts/', application_views.AccountListAPIView.as_view(), name='application_accounts_balance_api'), + path('api/application/user//accounts/', application_views.UserAccountListAPIView.as_view(), name='application_user_account_api'), # path('api/application/', application_views.TransactionListAPIView.as_view(), name='application_transaction_list_api'), # path('api/application//', application_views.TransactionDetailAPIView.as_view(), name='application_transaction_detail'), diff --git a/apps/wallet/views/application.py b/apps/wallet/views/application.py index 6e7c246..53c99f8 100755 --- a/apps/wallet/views/application.py +++ b/apps/wallet/views/application.py @@ -11,10 +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.filters import AccountFilter, UserTransactionFilter +from apps.wallet.models import Transaction, Category, Account from apps.wallet.serializers import ApplicationDepositSerializer, ApplicationWithdrawSerializer, \ - TransactionSerializer, BalanceSerializer, WalletSerializer + TransactionSerializer, AccountSerializer from utils.exceptions import UnprocessableEntity from django.utils.translation import gettext_lazy as _ @@ -29,17 +29,13 @@ def get_application(request): return application -def get_wallet_category(request: Request): - pass - - -class WalletListAPIView(generics.ListAPIView): +class AccountListAPIView(generics.ListAPIView): ''' API for getting specified user or application balance. ''' - serializer_class = BalanceSerializer + serializer_class = AccountSerializer filter_backends = (DjangoFilterBackend,) - filterset_class = WalletFilter + filterset_class = AccountFilter permission_classes = [IsAuthenticatedOrTokenHasScope] required_scopes = ['wallet.application:get_balance'] @@ -51,9 +47,9 @@ class WalletListAPIView(generics.ListAPIView): category = None application = get_application(self.request) - wallet, created = Wallet.objects.get_or_create(owner_uuid=application.uuid, owner_type=TypeChoices.APPLICATION, + account, created = Account.objects.get_or_create(owner_uuid=application.uuid, owner_type=TypeChoices.APPLICATION, category=category) - return wallet + return account def get_queryset(self): category_uuid = self.kwargs.get('category_uuid') @@ -62,22 +58,22 @@ class WalletListAPIView(generics.ListAPIView): else: category = None application = get_application(self.request) - wallet, created = Wallet.objects.get_or_create(owner_uuid=application.uuid, owner_type=TypeChoices.APPLICATION, + wallet, created = Account.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() + return Account.objects.filter(owner_uuid=application.uuid, owner_type=TypeChoices.APPLICATION).all() -class UserWalletListAPIView(generics.ListAPIView): +class UserAccountListAPIView(generics.ListAPIView): ''' API for getting specified user wallet. ''' - serializer_class = WalletSerializer + serializer_class = AccountSerializer filter_backends = (DjangoFilterBackend,) - filterset_class = WalletFilter + filterset_class = AccountFilter permission_classes = [IsAuthenticatedOrTokenHasScope] required_scopes = ['wallet.application:get_user_balance'] - queryset = Wallet.objects.all() + queryset = Account.objects.all() def get_queryset(self): qs = super().get_queryset() @@ -88,7 +84,7 @@ class UserWalletListAPIView(generics.ListAPIView): 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, + wallet, created = Account.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() @@ -97,7 +93,7 @@ class TransactionDetailAPIView(generics.RetrieveAPIView): serializer_class = TransactionSerializer lookup_field = 'uuid' filter_backends = (DjangoFilterBackend,) - filterset_class = WalletFilter + filterset_class = AccountFilter permission_classes = [TokenHasScope] required_scopes = ['wallet.application:get_transaction_detail'] queryset = Transaction.objects.all() @@ -155,12 +151,12 @@ class CategoryTransactionDetailAPIView(generics.RetrieveAPIView): 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__category=category) | - Q(payee_wallet__owner_uuid=application.pk, - payee_wallet__owner_type=TypeChoices.APPLICATION, - payee_wallet__category=category) + Q(payer_account__owner_uuid=application.pk, + payer_account__owner_type=TypeChoices.APPLICATION, + payer_account__category=category) | + Q(payee_account__owner_uuid=application.pk, + payee_account__owner_type=TypeChoices.APPLICATION, + payee_account__category=category) ).all() @@ -182,12 +178,12 @@ class CategoryTransactionListAPIView(generics.ListAPIView): application = get_application(self.request) 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) + Q(payer_account__owner_uuid=application.pk, + payer_account__owner_type=TypeChoices.APPLICATION, + payer_account__category=category) | + Q(payee_account__owner_uuid=application.pk, + payee_account__owner_type=TypeChoices.APPLICATION, + payee_account__category=category) ).all() @@ -205,9 +201,9 @@ class DepositSubmitAPIView(generics.CreateAPIView): else: category = None application = get_application(self.request) - wallet, created = Wallet.objects.get_or_create(owner_uuid=application.uuid, owner_type=TypeChoices.APPLICATION, + payer_account, created = Account.objects.get_or_create(owner_uuid=application.uuid, owner_type=TypeChoices.APPLICATION, category=category) - return Transaction.objects.filter(application=application, payer_wallet=wallet).all() + return Transaction.objects.filter(application=application, payer_account=payer_account).all() def perform_create(self, serializer): # TODO: get_or_create instead of create if uuid given @@ -216,29 +212,29 @@ class DepositSubmitAPIView(generics.CreateAPIView): application = get_application(self.request) logger.debug(f"Application UUID: {application.uuid}") - payee_wallet_category_uuid = serializer.validated_data.pop('payee_wallet_category') - payee_wallet_category_uuid = payee_wallet_category_uuid and str(payee_wallet_category_uuid) + payee_wallet_uuid = serializer.validated_data.pop('payee_wallet') + payee_wallet_uuid = payee_wallet_uuid and str(payee_wallet_uuid) - payer_wallet_category_uuid = self.kwargs.get('category_uuid') + payer_wallet_uuid = self.kwargs.get('wallet_uuid') - if payer_wallet_category_uuid: - payer_wallet_category = get_object_or_404(Category.objects.all(), uuid=payer_wallet_category_uuid) + if payer_wallet_uuid: + payer_wallet = get_object_or_404(Category.objects.all(), uuid=payer_wallet_uuid) else: - payer_wallet_category = None + payer_wallet = None - payee_wallet_category = get_object_or_404(Category.objects.all(), uuid=payee_wallet_category_uuid) + payee_wallet = get_object_or_404(Category.objects.all(), uuid=payee_wallet_uuid) - if not (payee_wallet_category and payee_wallet_category.currency == payer_wallet_category.currency): + if not (payee_wallet and payee_wallet.currency == payer_wallet.currency): raise UnprocessableEntity('payer and payee wallet currency not equal') payee_id = serializer.validated_data.pop('payee') payee_type = serializer.validated_data.pop('payee_type') - payer_wallet, _ = Wallet.objects.get_or_create(owner_uuid=application.uuid, owner_type=TypeChoices.APPLICATION, - category=payer_wallet_category) - logger.debug(f"Payer wallet: {payer_wallet.uuid}") - payee_wallet, _ = Wallet.objects.get_or_create(owner_uuid=payee_id, owner_type=payee_type, - category=payee_wallet_category) - logger.debug(f"Payee wallet: {payee_wallet.uuid}") + payer_account, _ = Account.objects.get_or_create(owner_uuid=application.uuid, owner_type=TypeChoices.APPLICATION, + category=payer_wallet) + logger.debug(f"Payer account: {payer_account.uuid}") + payee_account, _ = Account.objects.get_or_create(owner_uuid=payee_id, owner_type=payee_type, + category=payee_wallet) + logger.debug(f"Payee account: {payee_account.uuid}") uuid = serializer.validated_data.pop('uuid', None) details = serializer.validated_data.get('details', {}) @@ -246,8 +242,8 @@ class DepositSubmitAPIView(generics.CreateAPIView): logger.debug(f"Transaction UUID: {uuid}, Reference ID: {reference_id}") transaction_params = { 'application': application, - 'payer_wallet': payer_wallet, - 'payee_wallet': payee_wallet, + 'payer_account': payer_account, + 'payee_account': payee_account, 'amount': serializer.validated_data.get('amount'), } if uuid: @@ -267,7 +263,6 @@ class DepositSubmitAPIView(generics.CreateAPIView): if instance.state == StateChoices.PENDING: return - # TODO: status code 200 if not created before if created or instance.state == StateChoices.CREATED: instance.submit() else: @@ -288,8 +283,8 @@ class DepositVerifyAPIView(generics.RetrieveAPIView): category = get_object_or_404(Category.objects.all(), uuid=category_uuid) else: category = None - wallet = Wallet.objects.get(owner_uuid=application.uuid, owner_type=TypeChoices.APPLICATION, category=category) - return Transaction.objects.filter(application=application, payer_wallet=wallet).all() + account = Account.objects.get(owner_uuid=application.uuid, owner_type=TypeChoices.APPLICATION, category=category) + return Transaction.objects.filter(application=application, payer_account=account).all() def retrieve(self, request, *args, **kwargs): instance = self.get_object() @@ -313,9 +308,9 @@ class WithdrawSubmitAPIView(generics.CreateAPIView): else: category = None application = get_application(self.request) - wallet, created = Wallet.objects.get_or_create(owner_uuid=application.uuid, owner_type=TypeChoices.APPLICATION, + payee_account, created = Account.objects.get_or_create(owner_uuid=application.uuid, owner_type=TypeChoices.APPLICATION, category=category) - return Transaction.objects.filter(application=application, wallet=wallet).all() + return Transaction.objects.filter(application=application, payee_account=payee_account).all() def perform_create(self, serializer): # TODO: get_or_create instead of create if uuid given @@ -324,29 +319,29 @@ class WithdrawSubmitAPIView(generics.CreateAPIView): application = get_application(self.request) logger.debug(f"Application UUID: {application.uuid}") - payer_wallet_category_uuid = serializer.validated_data.pop('payer_wallet_category') - payer_wallet_category_uuid = payer_wallet_category_uuid and str(payer_wallet_category_uuid) + payer_wallet_uuid = serializer.validated_data.pop('payer_wallet') + payer_wallet_uuid = payer_wallet_uuid and str(payer_wallet_uuid) - payee_wallet_category_uuid = self.kwargs.get('category_uuid') + payee_wallet_uuid = self.kwargs.get('category_uuid') - if payee_wallet_category_uuid: - payee_wallet_category = get_object_or_404(Category.objects.all(), uuid=payee_wallet_category_uuid) + if payee_wallet_uuid: + payee_wallet = get_object_or_404(Category.objects.all(), uuid=payee_wallet_uuid) else: - payee_wallet_category = None + payee_wallet = None - payer_wallet_category = get_object_or_404(Category.objects.all(), uuid=payer_wallet_category_uuid) + payer_wallet = get_object_or_404(Category.objects.all(), uuid=payer_wallet_uuid) - if not (payer_wallet_category and payer_wallet_category.currency == payee_wallet_category.currency): + if not (payer_wallet and payer_wallet.currency == payee_wallet.currency): raise UnprocessableEntity('payer and payee wallet currency not equal') payer_id = serializer.validated_data.pop('payer') payer_type = serializer.validated_data.pop('payer_type') - payee_wallet, _ = Wallet.objects.get_or_create(owner_uuid=application.uuid, owner_type=TypeChoices.APPLICATION, - category=payee_wallet_category) - logger.debug(f"Payee wallet: {payee_wallet.uuid}") - payer_wallet, _ = Wallet.objects.get_or_create(owner_uuid=payer_id, owner_type=payer_type, - category=payer_wallet_category) - logger.debug(f"Payer wallet: {payer_wallet.uuid}") + payee_account, _ = Account.objects.get_or_create(owner_uuid=application.uuid, owner_type=TypeChoices.APPLICATION, + category=payee_wallet) + logger.debug(f"Payee account: {payee_account.uuid}") + payer_account, _ = Account.objects.get_or_create(owner_uuid=payer_id, owner_type=payer_type, + category=payer_wallet) + logger.debug(f"Payer account: {payer_account.uuid}") uuid = serializer.validated_data.pop('uuid', None) @@ -355,8 +350,8 @@ class WithdrawSubmitAPIView(generics.CreateAPIView): logger.debug(f"Transaction UUID: {uuid}, Reference ID: {reference_id}") transaction_params = { 'application': application, - 'payer_wallet': payer_wallet, - 'payee_wallet': payee_wallet, + 'payer_account': payer_account, + 'payee_account': payee_account, 'amount': serializer.validated_data.get('amount'), } if uuid: @@ -398,8 +393,8 @@ class WithdrawVerifyAPIView(generics.RetrieveAPIView): category = get_object_or_404(Category.objects.all(), uuid=category_uuid) else: category = None - wallet = Wallet.objects.get(owner_uuid=application.uuid, owner_type=TypeChoices.APPLICATION, category=category) - return Transaction.objects.filter(application=application, payee_wallet=wallet).all() + payee_account = Account.objects.get(owner_uuid=application.uuid, owner_type=TypeChoices.APPLICATION, category=category) + return Transaction.objects.filter(application=application, payee_wallet=payee_account).all() def retrieve(self, request, *args, **kwargs): instance = self.get_object() diff --git a/apps/wallet/views/user.py b/apps/wallet/views/user.py index 753e710..3ca9470 100755 --- a/apps/wallet/views/user.py +++ b/apps/wallet/views/user.py @@ -13,9 +13,9 @@ from rest_framework.permissions import AllowAny from rest_framework.response import Response from apps.gooyal_oauth2.rest_framework import IsAuthenticatedOrTokenMatchesOASRequirements -from apps.wallet.models import Transaction, Category, Wallet +from apps.wallet.models import Transaction, Category, Account from apps.wallet.serializers import TransactionSerializer, DepositSerializer, WithdrawSerializer, \ - BalanceSerializer + AccountSerializer from ..constans import StateChoices, TypeChoices from ..filters import UserTransactionFilter from ..forms import TransactionActionForm @@ -31,12 +31,12 @@ def get_application(request): return application -class MyWalletBalanceView(generics.RetrieveAPIView): +class UserAccountBalanceView(generics.RetrieveAPIView): ''' API for getting authenticated user balance. ''' permission_classes = [IsAuthenticatedOrTokenHasScope] - serializer_class = BalanceSerializer + serializer_class = AccountSerializer required_scopes = ['wallet.wallet:get_balance'] def get_object(self): @@ -227,12 +227,12 @@ class TransactionDetailView(UpdateView): -class CategoryMyWalletBalanceView(generics.RetrieveAPIView): +class CategoryMyAccountBalanceView(generics.RetrieveAPIView): ''' API for getting authenticated user balance. ''' permission_classes = [IsAuthenticatedOrTokenHasScope] - serializer_class = BalanceSerializer + serializer_class = AccountSerializer required_scopes = ['wallet.wallet:get_balance'] def get_object(self): @@ -243,7 +243,7 @@ class CategoryMyWalletBalanceView(generics.RetrieveAPIView): else: category = None - wallet, created = Wallet.objects.get_or_create(owner_uuid=user.uuid, owner_type=TypeChoices.USER, + wallet, created = Account.objects.get_or_create(owner_uuid=user.uuid, owner_type=TypeChoices.USER, category=category) return wallet @@ -301,7 +301,7 @@ class CategoryTransactionListView(generics.ListAPIView): else: category = None - wallet, created = Wallet.objects.get_or_create(owner_uuid=user.uuid, owner_type=TypeChoices.USER, + wallet, created = Account.objects.get_or_create(owner_uuid=user.uuid, owner_type=TypeChoices.USER, category=category) return Transaction.objects.filter(Q(payee_wallet=wallet) |