'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 |
---|