""" Payment forms with validation """
from django import forms
from accounts.models import User
from organisations.models import Organisation
from cobalt.settings import (
AUTO_TOP_UP_MIN_AMT,
AUTO_TOP_UP_MAX_AMT,
GLOBAL_CURRENCY_SYMBOL,
)
from .models import (
TRANSACTION_TYPE,
MemberTransaction,
OrganisationTransaction,
PaymentStatic,
OrganisationSettlementFees,
)
from django.core.exceptions import ValidationError
# class TestTransaction(forms.Form):
# """ Temporary - will be removed """
#
# amount = forms.DecimalField(label="Amount", max_digits=8, decimal_places=2)
# description = forms.CharField(label="Description", max_length=100)
# organisation = forms.ModelChoiceField(queryset=Organisation.objects.all())
# type = forms.ChoiceField(label="Transaction Type", choices=TRANSACTION_TYPE)
# url = forms.CharField(label="URL", max_length=100, required=False)
[docs]
class MemberTransfer(forms.Form):
"""M2M transfer form"""
transfer_to = forms.ModelChoiceField(queryset=User.objects.all())
amount = forms.DecimalField(label="Amount", max_digits=8, decimal_places=2)
description = forms.CharField(label="Description", max_length=80)
# We need the logged in user to check the balance, add a parameter
def __init__(self, *args, **kwargs):
self.user = kwargs.pop("user", None)
super().__init__(*args, **kwargs)
[docs]
class MemberTransferOrg(forms.Form):
"""Org to Member transfer form"""
transfer_to = forms.ModelChoiceField(queryset=User.objects.all())
amount = forms.DecimalField(label="Amount", max_digits=8, decimal_places=2)
description = forms.CharField(label="Description", max_length=80)
# We need the balance to take it as a parameter
def __init__(self, *args, **kwargs):
self.balance = kwargs.pop("balance", 0.0)
super().__init__(*args, **kwargs)
[docs]
def clean_amount(self):
"""check the balance is sufficient for the payment"""
amount = self.cleaned_data["amount"]
if amount > self.balance:
raise ValidationError("Insufficient funds")
return amount
[docs]
class ManualTopup(forms.Form):
"""Manual top up form"""
CARD_CHOICES = [
("Existing", "Use Registered Card"),
("Another", "Use Another Card"),
]
amount = forms.DecimalField(label="Amount", max_digits=8, decimal_places=2)
card_choice = forms.ChoiceField(
label="Card Option", choices=CARD_CHOICES, required=False
)
# We need the balance to take it as a parameter
def __init__(self, *args, **kwargs):
self.balance = kwargs.pop("balance", 0.0)
super().__init__(*args, **kwargs)
[docs]
def clean(self):
"""validation for the amount field"""
cleaned_data = super(ManualTopup, self).clean()
if cleaned_data.get("amount"):
amount = self.cleaned_data["amount"]
if amount < AUTO_TOP_UP_MIN_AMT:
txt = "Insufficient amount. Minimum is %s%s" % (
GLOBAL_CURRENCY_SYMBOL,
AUTO_TOP_UP_MIN_AMT,
)
self._errors["amount"] = txt
raise forms.ValidationError(txt)
if amount > AUTO_TOP_UP_MAX_AMT - self.balance:
txt = "Too large. Maximum balance is %s%s" % (
GLOBAL_CURRENCY_SYMBOL,
AUTO_TOP_UP_MAX_AMT,
)
self._errors["amount"] = txt
raise forms.ValidationError(txt)
else:
self._errors["amount"] = "Please enter a value"
return self.cleaned_data
[docs]
class StripeRefund(forms.Form):
"""Allow admins to make Stripe refunds"""
amount = forms.DecimalField(label="Refund", max_digits=8, decimal_places=2)
description = forms.CharField(max_length=80)
def __init__(self, *args, **kwargs):
self.payment_amount = kwargs.pop("payment_amount", 0.0)
super().__init__(*args, **kwargs)
[docs]
def clean(self):
"""validation for the amount field"""
cleaned_data = super(StripeRefund, self).clean()
if cleaned_data.get("amount"):
amount = self.cleaned_data["amount"]
if amount < 0.0:
raise forms.ValidationError("Amount cannot be negative")
if amount > self.payment_amount:
raise forms.ValidationError("Too large. Refund is more than was paid.")
else:
raise forms.ValidationError("Please enter a value")
return self.cleaned_data