wallet refactoring one more step

This commit is contained in:
Sayyid Hamid Mahdavi 2025-10-25 14:47:32 +03:30
parent b89487653f
commit 2c5087ee02
5 changed files with 31 additions and 31 deletions

View file

@ -1,5 +1,5 @@
from django.contrib import admin
from .models import Transaction, Account, Category
from .models import Transaction, Account, Wallet
class TransactionAdmin(admin.ModelAdmin):
list_display = ['uuid', 'amount', 'created_at', 'updated_at', 'payer', 'payer_type', 'payee', 'payee_type', 'state', 'application']

View file

@ -18,11 +18,11 @@ class UserTransactionWalletFilter(django_filters.BaseInFilter, django_filters.UU
return queryset.filter(
Q(payer_account__owner_uuid=user.pk,
payer_account__owner_type=TypeChoices.USER,
payer_account__category_id__in=value,
payer_account__wallet_id__in=value,
) |
Q(payee_account__owner_uuid=user.pk,
payee_account__owner_type=TypeChoices.USER,
payee_account__category_id__in=value,
payee_account__wallet_id__in=value,
))
@ -38,7 +38,7 @@ class UserTransactionFilter(django_filters.FilterSet):
class AccountFilter(django_filters.FilterSet):
wallets = WalletUUIDFilter(field_name='category', required=True, lookup_expr='in')
wallet = WalletUUIDFilter(field_name='wallet', required=True, lookup_expr='in')
class Meta:
model = Account

View file

@ -27,7 +27,7 @@ class AccountQuerySet(models.QuerySet):
class Account(BaseModel):
owner_uuid = models.UUIDField(db_index=True, null=False)
category = models.ForeignKey('Category', on_delete=models.PROTECT, null=True)
wallet = models.ForeignKey('Wallet', on_delete=models.PROTECT, null=True)
owner_type = models.IntegerField(choices=TypeChoices.choices, db_index=True)
balance = models.BigIntegerField(_('balance'), default=0)
@ -42,15 +42,15 @@ class Account(BaseModel):
return owner
class CategoryQuerySet(models.QuerySet):
class WalletQuerySet(models.QuerySet):
pass
class Category(BaseModel):
class Wallet(BaseModel):
application = models.ForeignKey(oauth2_settings.APPLICATION_MODEL, on_delete=models.PROTECT, null=True)
label = models.CharField(_('label'), max_length=255)
currency = models.UUIDField(choices=CurrencyChoices.choices, db_index=True, default=CurrencyChoices.IRANIAN_RIAL)
objects = CategoryQuerySet.as_manager()
objects = WalletQuerySet.as_manager()
# TODO: move DRF functionalities to view or serializers
@ -126,11 +126,11 @@ class Transaction(BaseModel):
@cached_property
def payer_wallet(self):
return self.payer_account and self.payer_account.category_id
return self.payer_account and self.payer_account.wallet_id
@cached_property
def payee_wallet(self):
return self.payee_account and self.payee_account.category_id
return self.payee_account and self.payee_account.wallet_id
@cached_property
def payer(self):
@ -166,12 +166,12 @@ class Transaction(BaseModel):
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'])
self.payer_account.balance = F('balance') - self.amount
self.payer_account.save(update_fields=['balance'])
def deposit_to_payee_balance(self):
self.payee_wallet.balance = F('balance') + self.amount
self.payee_wallet.save(update_fields=['balance'])
self.payee_account.balance = F('balance') + self.amount
self.payee_account.save(update_fields=['balance'])
# TODO: refactor
def pay(self, payer_id=None, payer_type=None):
@ -231,15 +231,15 @@ class Transaction(BaseModel):
return self
def submit(self):
if not self.payer_wallet:
if not self.payer_account:
raise APIException('payer identification error')
if not self.payee_wallet:
if not self.payee_account:
raise APIException('payee identification error')
if not self.payer_wallet.category == self.payee_wallet.category:
if not self.payer_wallet == self.payee_wallet:
self.change_state(from_state=self.state, to_state=StateChoices.FAILED)
raise APIException('payer and payee wallet currency not equal')
raise APIException('payer and payee account currency not equal')
if not self.state == StateChoices.CREATED:
raise APIException('this transaction is not ready to pay')
@ -267,9 +267,9 @@ class Transaction(BaseModel):
return self
def get_role(self, entity):
if self.payer_wallet.owner_uuid == entity.uuid:
if self.payer_account.owner_uuid == entity.uuid:
return 1
elif self.payee_wallet.owner_uuid == entity.uuid:
elif self.payee_account.owner_uuid == entity.uuid:
return 2
else:
return 0
@ -282,8 +282,8 @@ class Transaction(BaseModel):
is_updated = False
if not self.details.get('payer_name'):
print('update payer')
if self.payer_wallet.owner_type == TypeChoices.USER:
payer_details: PublicUser = get_user_details(self.payer_wallet.owner_uuid)
if self.payer_account.owner_type == TypeChoices.USER:
payer_details: PublicUser = get_user_details(self.payer_account.owner_uuid)
self.details['payer_name'] = payer_details.first_name + payer_details.last_name
self.details['payer_avatar_url'] = payer_details.avatar
else:
@ -296,12 +296,12 @@ class Transaction(BaseModel):
if not self.details.get('payee_name'):
print('update payee')
if self.payee_wallet.owner_type == TypeChoices.USER:
payee_details: PublicUser = get_user_details(self.payee_wallet.owner_uuid)
if self.payee_account.owner_type == TypeChoices.USER:
payee_details: PublicUser = get_user_details(self.payee_account.owner_uuid)
self.details['payee_name'] = payee_details.first_name + payee_details.last_name
self.details['payee_avatar_url'] = payee_details.avatar
else:
payee_details = get_application_details(self.payee_id)
payee_details = get_application_details(self.payee_account.owner_uuid)
self.details['payee_name'] = payee_details.name
# TODO: get avatar from details

View file

@ -163,7 +163,7 @@ class TransferVerifySerializer(serializers.ModelSerializer):
class AccountSerializer(serializers.ModelSerializer):
class Meta:
model = Account
fields = ['balance', 'category']
fields = ['balance', 'wallet']
class ApplicationDepositSerializer(serializers.ModelSerializer):

View file

@ -8,11 +8,11 @@ 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.CategoryMyAccountBalanceView.as_view(), name='user_wallet_balance_api'),
# path('api/wallet/balance', user_views.WalletMyAccountBalanceView.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.CategoryMyAccountBalanceView.as_view(), name='user_wallet_balance_api'),
path('api/user/<category_uuid>/transactions/', user_views.CategoryTransactionListView.as_view(), name='transaction_list_api'),
# path('api/user/<category_uuid>/balance', user_views.WalletMyAccountBalanceView.as_view(), name='user_wallet_balance_api'),
path('api/user/<category_uuid>/transactions/', user_views.WalletTransactionListView.as_view(), name='transaction_list_api'),
]
application_urlpatterns = [
@ -32,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.CategoryTransactionListAPIView.as_view(), name='application_transaction_list_api'),
path('api/application/<category_uuid>/<uuid>/', application_views.CategoryTransactionDetailAPIView.as_view(), name='application_transaction_detail'),
path('api/application/<category_uuid>/', application_views.WalletTransactionListAPIView.as_view(), name='application_transaction_list_api'),
path('api/application/<category_uuid>/<uuid>/', application_views.WalletTransactionDetailAPIView.as_view(), name='application_transaction_detail'),
]