forked from uncloud/uncloud
implement balance getting
This commit is contained in:
parent
1b06d8ee03
commit
6c15d2086e
7 changed files with 53 additions and 65 deletions
|
@ -75,6 +75,7 @@ router.register(r'v2/net/wireguardvpnsizes', netviews.WireGuardVPNSizes, basenam
|
|||
# Payment related
|
||||
router.register(r'v2/payment/credit-card', payviews.CreditCardViewSet, basename='credit-card')
|
||||
router.register(r'v2/payment/payment', payviews.PaymentViewSet, basename='payment')
|
||||
router.register(r'v2/payment/balance', payviews.BalanceViewSet, basename='payment-balance')
|
||||
|
||||
|
||||
urlpatterns = [
|
||||
|
|
|
@ -68,16 +68,6 @@ class Currency(models.TextChoices):
|
|||
# USD = 'USD', _('US Dollar')
|
||||
|
||||
|
||||
def get_balance_for_user(user):
|
||||
bills = reduce(
|
||||
lambda acc, entry: acc + entry.total,
|
||||
Bill.objects.filter(owner=user),
|
||||
0)
|
||||
payments = reduce(
|
||||
lambda acc, entry: acc + entry.amount,
|
||||
Payment.objects.filter(owner=user),
|
||||
0)
|
||||
return payments - bills
|
||||
|
||||
###
|
||||
# Stripe
|
||||
|
|
23
uncloud_pay/selectors.py
Normal file
23
uncloud_pay/selectors.py
Normal file
|
@ -0,0 +1,23 @@
|
|||
from django.utils import timezone
|
||||
from django.db import transaction
|
||||
|
||||
from .models import *
|
||||
|
||||
def get_payments_for_user(user):
|
||||
payments = [ payment.amount for payment in Payment.objects.filter(owner=user) ]
|
||||
|
||||
return sum(payments)
|
||||
|
||||
def get_spendings_for_user(user):
|
||||
orders = Order.objects.filter(owner=user)
|
||||
|
||||
amount = 0
|
||||
for order in orders:
|
||||
amount += order.one_time_price
|
||||
amount += order.recurring_price * order.count_used(when=timezone.now())
|
||||
|
||||
return amount
|
||||
|
||||
@transaction.atomic
|
||||
def get_balance_for_user(user):
|
||||
return get_payments_for_user(user) - get_spendings_for_user(user)
|
|
@ -5,6 +5,7 @@ from django.utils.translation import gettext_lazy as _
|
|||
|
||||
from .models import *
|
||||
import uncloud_pay.stripe as uncloud_stripe
|
||||
from uncloud import AMOUNT_DECIMALS, AMOUNT_MAX_DIGITS
|
||||
|
||||
###
|
||||
# 2020-12 Checked code
|
||||
|
@ -32,29 +33,13 @@ class PaymentSerializer(serializers.ModelSerializer):
|
|||
|
||||
return data
|
||||
|
||||
class BalanceSerializer(serializers.Serializer):
|
||||
balance = serializers.DecimalField(max_digits=AMOUNT_MAX_DIGITS, decimal_places=AMOUNT_DECIMALS)
|
||||
|
||||
|
||||
################################################################################
|
||||
# Unchecked code
|
||||
|
||||
###
|
||||
# Payments and Payment Methods.
|
||||
|
||||
|
||||
class UpdatePaymentMethodSerializer(serializers.ModelSerializer):
|
||||
class Meta:
|
||||
model = PaymentMethod
|
||||
fields = ['description', 'primary']
|
||||
|
||||
class ChargePaymentMethodSerializer(serializers.Serializer):
|
||||
amount = serializers.DecimalField(max_digits=10, decimal_places=2)
|
||||
|
||||
class CreatePaymentMethodSerializer(serializers.ModelSerializer):
|
||||
please_visit = serializers.CharField(read_only=True)
|
||||
|
||||
class Meta:
|
||||
model = PaymentMethod
|
||||
fields = ['source', 'description', 'primary', 'please_visit']
|
||||
|
||||
|
||||
###
|
||||
# Orders & Products.
|
||||
|
|
|
@ -1,30 +0,0 @@
|
|||
{% extends 'uncloud/base.html' %}
|
||||
|
||||
{% block header %}
|
||||
<style>
|
||||
#content {
|
||||
width: 400px;
|
||||
margin: auto;
|
||||
}
|
||||
</style>
|
||||
{% endblock %}
|
||||
|
||||
{% block body %}
|
||||
<div id="content">
|
||||
<h1>Your credit cards registered with Stripe</h1>
|
||||
|
||||
<!-- Stripe form and messages -->
|
||||
<span id="message"></span>
|
||||
|
||||
<p>List of stripe credit cards:
|
||||
<ul>
|
||||
{% for card in cards %}
|
||||
<li>{{ card.brand }} ending in {{ card.last4 }} expiring
|
||||
{{ card.year }}-{{ card.month }}
|
||||
{% endfor %}
|
||||
|
||||
</ul>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
{% endblock %}
|
|
@ -21,17 +21,17 @@
|
|||
terms of my agreement with you.
|
||||
</p>
|
||||
|
||||
<!-- Stripe form and messages -->
|
||||
<span id="message"></span>
|
||||
|
||||
<div id="card-element"></div>
|
||||
<button type='button' id="card-button"> Save
|
||||
</button>
|
||||
|
||||
<button type='button' id="card-button">Save</button>
|
||||
<div id="ungleichmessage">The card will be registered with stripe.</div>
|
||||
|
||||
<div id="goback" style="display: none;">
|
||||
<a href="{% url 'uncloudindex' %}">Go back to main page</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<!-- Enable Stripe from UI elements - standard code -->
|
||||
<script>
|
||||
var stripe = Stripe('{{ stripe_pk }}');
|
||||
|
@ -42,11 +42,13 @@
|
|||
|
||||
var cardButton = document.getElementById('card-button');
|
||||
var messageContainer = document.getElementById('message');
|
||||
var backmessage = document.getElementById('goback');
|
||||
var clientSecret = '{{ client_secret }}';
|
||||
|
||||
cardButton.addEventListener('click', function(ev) {
|
||||
document.getElementById("ungleichmessage").innerHTML
|
||||
= "Registering card with Stripe, please wait ..."
|
||||
= "Registering card with Stripe, please wait ...";
|
||||
|
||||
|
||||
stripe.confirmCardSetup(
|
||||
clientSecret,
|
||||
|
@ -64,8 +66,12 @@
|
|||
// Return to API on success.
|
||||
document.getElementById("ungleichmessage").innerHTML
|
||||
= "Registered credit card with Stripe."
|
||||
|
||||
backmessage.style.display = "block";
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
});
|
||||
</script>
|
||||
{% endblock %}
|
||||
|
|
|
@ -24,12 +24,15 @@ import logging
|
|||
|
||||
from .models import *
|
||||
from .serializers import *
|
||||
from .selectors import *
|
||||
|
||||
from datetime import datetime
|
||||
from vat_validator import sanitize_vat
|
||||
import uncloud_pay.stripe as uncloud_stripe
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
###
|
||||
# 2020-12 checked code
|
||||
|
||||
|
@ -75,6 +78,16 @@ class PaymentViewSet(viewsets.ModelViewSet):
|
|||
def get_queryset(self):
|
||||
return Payment.objects.filter(owner=self.request.user)
|
||||
|
||||
class BalanceViewSet(viewsets.ViewSet):
|
||||
permission_classes = [permissions.IsAuthenticated]
|
||||
|
||||
def list(self, request):
|
||||
serializer = BalanceSerializer(data={
|
||||
'balance': get_balance_for_user(self.request.user)
|
||||
})
|
||||
serializer.is_valid()
|
||||
return Response(serializer.data)
|
||||
|
||||
|
||||
###
|
||||
# Payments and Payment Methods.
|
||||
|
|
Loading…
Reference in a new issue