feat(wallet): implement wallet transaction model, views, and serializers for fund management

This commit is contained in:
2025-07-25 14:38:34 +05:00
parent f8c91e8f14
commit 1554829b9a
11 changed files with 256 additions and 52 deletions
+66 -8
View File
@@ -15,11 +15,17 @@ from api.tasks import add_new_devices_to_omada
from apibase.env import BASE_DIR, env
import logging
from .models import Device, Payment, Topup
from .serializers import PaymentSerializer, UpdatePaymentSerializer, TopupSerializer
from .filters import PaymentFilter, TopupFilter
from .models import Device, Payment, Topup, WalletTransaction
from .serializers import (
PaymentSerializer,
UpdatePaymentSerializer,
TopupSerializer,
WalletTransactionSerializer,
)
from .filters import PaymentFilter, TopupFilter, WalletTransactionFilter
from dataclasses import dataclass, asdict
from typing import Optional
from api.models import User
env.read_env(os.path.join(BASE_DIR, ".env"))
@@ -161,7 +167,6 @@ class VerifyPaymentView(StaffEditorPermissionMixin, generics.UpdateAPIView):
lookup_field = "pk"
def update(self, request, *args, **kwargs):
# TODO: Fix check for success payment
payment = self.get_object()
data = request.data
user = request.user
@@ -193,9 +198,16 @@ class VerifyPaymentView(StaffEditorPermissionMixin, generics.UpdateAPIView):
)
else:
self.process_wallet_payment(
user,
user, # type: ignore
payment,
)
return Response(
{
"status": True,
"message": "Payment verified successfully using wallet.",
},
status=status.HTTP_400_BAD_REQUEST,
)
if method == "TRANSFER":
data = {
"benefName": f"{user.first_name} {user.last_name}", # type: ignore
@@ -250,7 +262,7 @@ class VerifyPaymentView(StaffEditorPermissionMixin, generics.UpdateAPIView):
status=status.HTTP_400_BAD_REQUEST,
)
def process_wallet_payment(self, user, payment):
def process_wallet_payment(self, user: User, payment: Payment):
print("processing wallet payment...")
print(user, payment.amount)
@@ -259,7 +271,9 @@ class VerifyPaymentView(StaffEditorPermissionMixin, generics.UpdateAPIView):
payment.method = "WALLET"
payment.save()
user.wallet_balance -= payment.amount
user.deduct_wallet_funds(
payment.amount, "Wallet payment for devices", payment.id
)
user.save()
return True
@@ -473,7 +487,11 @@ class VerifyTopupPaymentAPIView(StaffEditorPermissionMixin, generics.UpdateAPIVi
topup_verification_response = self.verify_transfer_topup(data, topup_instance)
print("Topup verification response:", topup_verification_response)
if topup_verification_response.success:
user.wallet_balance += topup_instance.amount # type: ignore
user.add_wallet_funds( # type: ignore
topup_instance.amount,
f"Topup of {topup_instance.amount} MVR",
topup_instance.id,
)
user.save()
topup_instance.status = "PAID"
topup_instance.save()
@@ -533,3 +551,43 @@ class CancelTopupView(StaffEditorPermissionMixin, generics.UpdateAPIView):
instance.status = "CANCELLED"
instance.save()
return super().update(request, *args, **kwargs)
class ListWalletTransactionView(StaffEditorPermissionMixin, generics.ListAPIView):
serializer_class = WalletTransactionSerializer
queryset = WalletTransaction.objects.all().select_related("user")
filter_backends = [DjangoFilterBackend]
filterset_fields = "__all__"
filterset_class = WalletTransactionFilter
def get_queryset(self):
queryset = super().get_queryset()
if getattr(self.request.user, "is_admin") or self.request.user.is_superuser:
return queryset
return queryset.filter(user=self.request.user)
def list(self, request, *args, **kwargs):
queryset = self.filter_queryset(self.get_queryset())
all_transations = request.query_params.get(
"all_transations", "false"
).lower() in [
"true",
"1",
"yes",
]
if (
request.user.is_authenticated
and getattr(request.user, "is_admin")
and bool(all_transations)
):
pass
else:
queryset = queryset.filter(user=request.user)
page = self.paginate_queryset(queryset)
if page is not None:
serializer = self.get_serializer(page, many=True)
return self.get_paginated_response(serializer.data)
serializer = self.get_serializer(queryset, many=True)
return Response(serializer.data)