'How to deduct funds from users withdrawals in Django Rest Framework

I am building a logistics web application using DRF and i want to set users to withdrawal certain amount, let's say a users withdraw $200, i want the users to get $180 this means minus $20 from each withdrawals, but when i tried using the API, i am getting $220 instead of $180, which means my code is returning a plus sign for withdrawals instead of negative sign.

Below is the codes from my Models

 class UserWallet(models.Model):
    wallet_id = models.UUIDField(unique=True, default=uuid.uuid4)
    user = models.OneToOneField("accounts.User", on_delete=models.CASCADE, related_name="wallet")
    currency = models.CharField(max_length=10, default="NGN")
    created_at = models.DateTimeField(default=timezone.now)

    def get_balance(self):
        query = (Q(status="success") | Q(status="processing")) & Q(wallet=self)
        balance = WalletTransaction.objects.filter(
            query).aggregate(Sum('amount'))
        return balance

    def to_dict(self):
        balance = self.get_balance()["amount__sum"]
        return {
            "wallet_id": self.wallet_id,
            "balance": f"{balance:.2f}" if balance else "0.00",
            "currency": self.currency,
            "currency_symbol": "₦"
        }

    def get_earnings(self):
        total = WalletTransaction.objects.filter(
            wallet=self, status="success", transaction_type="payment").aggregate(Sum('amount'))
        return total

    def get_withdrawals(self):
        total = WalletTransaction.objects.filter(
            wallet=self, status="success", transaction_type="withdrawal").aggregate(Sum('amount'))
        return total

    def get_transfers(self):
        total = WalletTransaction.objects.filter(
            wallet=self, status="success", transaction_type="transfer").aggregate(Sum('amount'))
        return total

    def get_deposits(self):
        total = WalletTransaction.objects.filter(
            wallet=self, status="success", transaction_type="deposit").aggregate(Sum('amount'))
        return total

Codes from the Views

@api_view(["POST"])
@transaction.atomic
def initialize_transaction(request):
    payload = request.data
    user = request.user
    wallet = UserWallet.objects.get(user=user)
    if payload["transaction_type"] == "deposit":
        ser = DepositSerializer(data=request.data)
        if not ser.is_valid():
            return ApiResponse(message=error_to_string(ser.errors), data=ser.errors, status_code=400).response()
        transaction = WalletTransaction.objects.create(
            wallet=wallet,
            amount=payload["amount"],
            description="WALLET TOP UP",
            transaction_type="deposit"
        )
        return Response({
            "status": True,
            "data": {
                "email": user.email,
                "amount": payload["amount"],
                "reference": transaction.reference
            }
        })
    
    if payload['transaction_type'] == "transfer":
        ser = TransferSerializer(data=request.data, context={"request": request})
        if not ser.is_valid():
            return ApiResponse(message=error_to_string(ser.errors), data=ser.errors, status_code=400).response()
        transaction = WalletTransaction.objects.create(
            wallet=wallet,
            amount=ser.validated_data["amount"]*-1,
            description=payload['description'],
            transaction_type="transfer",
            extras=payload
        )
        otp = OTP.generate_otp(wallet)
        task.otp_mail(request.user.email, {"code": otp})
        data = {
            "transaction_id": transaction.transaction_id,
        }
        return ApiResponse(data=data, message="otp sent").response()
    
    if payload['transaction_type'] == "withdrawal":
        ser = WithdrawSerializer(data=request.data, context={"request": request})
        if not ser.is_valid():
            return ApiResponse(message=error_to_string(ser.errors), data=ser.errors, status_code=400).response()
        payload['bank'] = ser.validated_data['bank'].json()
        transaction = WalletTransaction.objects.create(
            wallet=wallet,
            amount=ser.validated_data["amount"]*-1,
            description=payload['description'],
            transaction_type="withdrawal",
            extras=payload
        )
        otp = OTP.generate_otp(wallet)
        task.otp_mail(request.user.email, {"code": otp})
        data = {
            "transaction_id": transaction.transaction_id,
        }
        return ApiResponse(data=data, message="otp sent").response()
    
    return ApiResponse(status_code=400, message="Invalid TransactionType").response()


Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source