Add UpdateUserWalletView and CustomUserByWalletBalanceSerializer for wallet balance updates
All checks were successful
Build and Push Docker Images / Build and Push Docker Images (push) Successful in 2m12s

This commit is contained in:
i701 2025-04-05 20:53:06 +05:00
parent d67794df62
commit b87dcfaf26
Signed by: i701
GPG Key ID: 54A0DA1E26D8E587
8 changed files with 95 additions and 16 deletions

View File

@ -73,6 +73,15 @@ class CustomReadOnlyUserByIDCardSerializer(serializers.ModelSerializer):
fields = ("id_card",) fields = ("id_card",)
class CustomUserByWalletBalanceSerializer(serializers.ModelSerializer):
"""serializer for the user object"""
class Meta: # type: ignore
model = User
# fields = "__all__"
fields = ("wallet_balance",)
class UserSerializer(serializers.ModelSerializer): class UserSerializer(serializers.ModelSerializer):
"""serializer for the user object""" """serializer for the user object"""

View File

@ -17,6 +17,7 @@ from .views import (
ListCreateIslandView, ListCreateIslandView,
RetrieveUpdateDestroyIslandView, RetrieveUpdateDestroyIslandView,
filter_user, filter_user,
UpdateUserWalletView,
) )
@ -29,6 +30,9 @@ urlpatterns = [
path("tokens/", KnoxTokenListApiView.as_view(), name="knox_tokens"), path("tokens/", KnoxTokenListApiView.as_view(), name="knox_tokens"),
# path("auth/", CustomAuthToken.as_view()), # path("auth/", CustomAuthToken.as_view()),
path("users/", ListUserView.as_view(), name="users"), path("users/", ListUserView.as_view(), name="users"),
path(
"update-wallet/<int:pk>/", UpdateUserWalletView.as_view(), name="update-wallet"
),
path("users/<int:pk>/", UserDetailAPIView.as_view(), name="user-detail"), path("users/<int:pk>/", UserDetailAPIView.as_view(), name="user-detail"),
path("users/filter/", filter_user, name="filter-users"), path("users/filter/", filter_user, name="filter-users"),
path("healthcheck/", healthcheck, name="healthcheck"), path("healthcheck/", healthcheck, name="healthcheck"),

View File

@ -11,7 +11,11 @@ from rest_framework.response import Response
from rest_framework import status from rest_framework import status
from rest_framework.exceptions import ValidationError from rest_framework.exceptions import ValidationError
from rest_framework.decorators import api_view, permission_classes from rest_framework.decorators import api_view, permission_classes
from api.serializers import AtollSerializer, IslandSerializer from api.serializers import (
AtollSerializer,
IslandSerializer,
CustomUserByWalletBalanceSerializer,
)
# knox imports # knox imports
from knox.views import LoginView as KnoxLoginView from knox.views import LoginView as KnoxLoginView
@ -44,6 +48,25 @@ class ErrorMessages:
INVALID_ACCOUNT = "Please enter a valid account number." INVALID_ACCOUNT = "Please enter a valid account number."
class UpdateUserWalletView(generics.UpdateAPIView):
# Create user API view
serializer_class = CustomUserByWalletBalanceSerializer
permission_classes = (permissions.IsAuthenticated,)
queryset = User.objects.all()
def update(self, request, *args, **kwargs):
wallet_balance = request.data.get("wallet_balance")
if not wallet_balance:
return Response(
{"message": "wallet_balance is required."},
status=status.HTTP_400_BAD_REQUEST,
)
user = self.get_object()
user.wallet_balance = wallet_balance
user.save()
return Response({"message": "Wallet balance updated successfully."})
class CreateUserView(generics.CreateAPIView): class CreateUserView(generics.CreateAPIView):
# Create user API view # Create user API view
serializer_class = UserSerializer serializer_class = UserSerializer

View File

@ -9,3 +9,17 @@ class PaymentSerializer(serializers.ModelSerializer):
class Meta: class Meta:
model = Payment model = Payment
fields = "__all__" fields = "__all__"
class UpdatePaymentSerializer(serializers.ModelSerializer):
class Meta:
model = Payment
fields = [
"paid",
"paid_at",
"method",
]
paid = serializers.BooleanField(required=True, allow_null=True)
paid_at = serializers.DateTimeField(required=True, allow_null=True)
method = serializers.ChoiceField(choices=Payment.PAYMENT_TYPES, required=True)

View File

@ -1,9 +1,19 @@
# billing/urls.py # billing/urls.py
from django.urls import path from django.urls import path
from .views import ListCreatePaymentView, VerifyPaymentView, PaymentDetailAPIView from .views import (
ListCreatePaymentView,
VerifyPaymentView,
PaymentDetailAPIView,
UpdatePaymentAPIView,
)
urlpatterns = [ urlpatterns = [
path("payment/", ListCreatePaymentView.as_view(), name="create-payment"), path("payment/", ListCreatePaymentView.as_view(), name="create-payment"),
path("payment/<str:pk>/", PaymentDetailAPIView.as_view(), name="retrieve-payment"), path("payment/<str:pk>/", PaymentDetailAPIView.as_view(), name="retrieve-payment"),
path(
"payment/<str:pk>/update/",
UpdatePaymentAPIView.as_view(),
name="update-payment",
),
path("verify-payment/", VerifyPaymentView.as_view(), name="verify-payment"), path("verify-payment/", VerifyPaymentView.as_view(), name="verify-payment"),
] ]

View File

@ -10,7 +10,7 @@ from rest_framework.response import Response
from api.mixins import StaffEditorPermissionMixin from api.mixins import StaffEditorPermissionMixin
from .models import Device, Payment from .models import Device, Payment
from .serializers import PaymentSerializer from .serializers import PaymentSerializer, UpdatePaymentSerializer
class InsufficientFundsError(Exception): class InsufficientFundsError(Exception):
@ -75,6 +75,21 @@ class PaymentDetailAPIView(StaffEditorPermissionMixin, generics.RetrieveAPIView)
lookup_field = "pk" lookup_field = "pk"
class UpdatePaymentAPIView(StaffEditorPermissionMixin, generics.UpdateAPIView):
queryset = Payment.objects.select_related("user").all()
serializer_class = UpdatePaymentSerializer
lookup_field = "pk"
def update(self, request, *args, **kwargs):
instance = self.get_object()
devices = instance.devices.all()
serializer = self.get_serializer(instance, data=request.data, partial=False)
serializer.is_valid(raise_exception=True)
self.perform_update(serializer)
devices.update(is_active=True, expiry_date=instance.expires_at)
return Response(serializer.data)
class VerifyPaymentView(StaffEditorPermissionMixin, generics.UpdateAPIView): class VerifyPaymentView(StaffEditorPermissionMixin, generics.UpdateAPIView):
serializer_class = PaymentSerializer serializer_class = PaymentSerializer
queryset = Payment.objects.all() queryset = Payment.objects.all()

View File

@ -1,11 +1,14 @@
from rest_framework import serializers from rest_framework import serializers
from .models import Device from .models import Device
from api.serializers import CustomReadOnlyUserSerializer from api.serializers import CustomReadOnlyUserSerializer
class CreateDeviceSerializer(serializers.ModelSerializer): class CreateDeviceSerializer(serializers.ModelSerializer):
class Meta: class Meta:
model = Device model = Device
fields = ["name", "mac"] fields = ["name", "mac"]
class DeviceSerializer(serializers.ModelSerializer): class DeviceSerializer(serializers.ModelSerializer):
class Meta: class Meta:
model = Device model = Device
@ -14,7 +17,8 @@ class DeviceSerializer(serializers.ModelSerializer):
class ReadOnlyDeviceSerializer(serializers.ModelSerializer): class ReadOnlyDeviceSerializer(serializers.ModelSerializer):
user = CustomReadOnlyUserSerializer(read_only=True) user = CustomReadOnlyUserSerializer(read_only=True)
class Meta: #type: ignore
class Meta: # type: ignore
depth = 2 depth = 2
model = Device model = Device
fields = "__all__" fields = "__all__"

View File

@ -3,7 +3,7 @@
"venv": ".venv", "venv": ".venv",
"reportMissingImports": "error", "reportMissingImports": "error",
"include": ["src"], "include": ["src"],
"typeCheckingMode": "off",
"exclude": [ "exclude": [
"council-api/**/migrations", "council-api/**/migrations",
"**/__pycache__", "**/__pycache__",