diff --git a/uncloud/uncloud/settings.py b/uncloud/uncloud/settings.py index 899de1b..179ff0b 100644 --- a/uncloud/uncloud/settings.py +++ b/uncloud/uncloud/settings.py @@ -60,6 +60,7 @@ INSTALLED_APPS = [ 'django.contrib.messages', 'django.contrib.staticfiles', 'rest_framework', + 'uncloud_pay', 'uncloud_auth', 'uncloud_vm', 'opennebula' diff --git a/uncloud/uncloud/urls.py b/uncloud/uncloud/urls.py index 1e4c9d0..79958c5 100644 --- a/uncloud/uncloud/urls.py +++ b/uncloud/uncloud/urls.py @@ -19,14 +19,19 @@ from django.urls import path, include from rest_framework import routers from uncloud_vm import views as vmviews +from uncloud_pay import views as payviews from opennebula import views as oneviews router = routers.DefaultRouter() # user / regular urls -router.register(r'vm/snapshot', apiviews.VMSnapshotView, basename='VMSnapshot') +router.register(r'vm/snapshot', vmviews.VMSnapshotProductView, basename='VMSnapshot') router.register(r'vm/vm', vmviews.VMProductViewSet, basename='vmproduct') +# Pay +router.register(r'bill', payviews.BillViewSet, basename='bill') +router.register(r'payment', payviews.PaymentViewSet, basename='payment') + # admin/staff urls router.register(r'admin/vmhost', vmviews.VMHostViewSet) router.register(r'admin/opennebula', oneviews.VMViewSet, basename='opennebula') diff --git a/uncloud/uncloud_pay/migrations/0001_initial.py b/uncloud/uncloud_pay/migrations/0001_initial.py new file mode 100644 index 0000000..6e57c59 --- /dev/null +++ b/uncloud/uncloud_pay/migrations/0001_initial.py @@ -0,0 +1,56 @@ +# Generated by Django 3.0.3 on 2020-02-27 10:50 + +from django.conf import settings +import django.core.validators +from django.db import migrations, models +import django.db.models.deletion +import uuid + + +class Migration(migrations.Migration): + + initial = True + + dependencies = [ + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ] + + operations = [ + migrations.CreateModel( + name='Bill', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('creation_date', models.DateTimeField()), + ('starting_date', models.DateTimeField()), + ('ending_date', models.DateTimeField()), + ('due_date', models.DateField()), + ('paid', models.BooleanField(default=False)), + ('valid', models.BooleanField(default=True)), + ('owner', models.ForeignKey(editable=False, on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)), + ], + ), + migrations.CreateModel( + name='Payment', + fields=[ + ('uuid', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)), + ('amount', models.DecimalField(decimal_places=2, default=0.0, max_digits=10, validators=[django.core.validators.MinValueValidator(0)])), + ('source', models.CharField(choices=[('wire', 'Wire Transfer'), ('strip', 'Stripe'), ('voucher', 'Voucher'), ('referral', 'Referral'), ('unknown', 'Unknown')], default='unknown', max_length=256)), + ('timestamp', models.DateTimeField(editable=False)), + ('owner', models.ForeignKey(editable=False, on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)), + ], + ), + migrations.CreateModel( + name='Order', + fields=[ + ('uuid', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)), + ('creation_date', models.DateTimeField()), + ('starting_date', models.DateTimeField()), + ('ending_date', models.DateTimeField(blank=True, null=True)), + ('recurring_price', models.FloatField(editable=False)), + ('one_time_price', models.FloatField(editable=False)), + ('recurring_period', models.CharField(choices=[('onetime', 'Onetime'), ('per_year', 'Per Year'), ('per_month', 'Per Month'), ('per_week', 'Per Week'), ('per_day', 'Per Day'), ('per_hour', 'Per Hour'), ('per_minute', 'Per Minute'), ('per_second', 'Per Second')], default='onetime', max_length=32)), + ('bill', models.ManyToManyField(blank=True, editable=False, null=True, to='uncloud_pay.Bill')), + ('owner', models.ForeignKey(editable=False, on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)), + ], + ), + ] diff --git a/uncloud/uncloud_pay/models.py b/uncloud/uncloud_pay/models.py index 831710b..71653fa 100644 --- a/uncloud/uncloud_pay/models.py +++ b/uncloud/uncloud_pay/models.py @@ -1,8 +1,11 @@ from django.db import models from django.contrib.auth import get_user_model +from django.core.validators import MinValueValidator -# Create your models here. +import uuid +AMOUNT_MAX_DIGITS=10 +AMOUNT_DECIMALS=2 class Bill(models.Model): owner = models.ForeignKey(get_user_model(), @@ -35,7 +38,6 @@ class Order(models.Model): null=True) bill = models.ManyToManyField(Bill, - on_delete=models.CASCADE, editable=False, blank=True, null=True) @@ -77,6 +79,8 @@ class Payment(models.Model): amount = models.DecimalField( default=0.0, + max_digits=AMOUNT_MAX_DIGITS, + decimal_places=AMOUNT_DECIMALS, validators=[MinValueValidator(0)]) source = models.CharField(max_length=256, diff --git a/uncloud/uncloud_pay/serializers.py b/uncloud/uncloud_pay/serializers.py new file mode 100644 index 0000000..e11544b --- /dev/null +++ b/uncloud/uncloud_pay/serializers.py @@ -0,0 +1,12 @@ +from rest_framework import serializers +from .models import Bill, Payment + +class BillSerializer(serializers.ModelSerializer): + class Meta: + model = Bill + fields = ['user', 'amount'] + +class PaymentSerializer(serializers.ModelSerializer): + class Meta: + model = Payment + fields = ['user', 'amount', 'source', 'timestamp'] diff --git a/uncloud/uncloud_pay/views.py b/uncloud/uncloud_pay/views.py index b52a2b6..8fc02ea 100644 --- a/uncloud/uncloud_pay/views.py +++ b/uncloud/uncloud_pay/views.py @@ -1,55 +1,46 @@ from django.shortcuts import render +from rest_framework import viewsets, permissions -# Create your views here. +from .models import Bill, Payment +from .serializers import BillSerializer, PaymentSerializer # to be implemented -class BalanceViewSet(viewsets.ModelViewSet): +class BalanceViewSet(viewsets.ViewSet): # here we return a number # number = sum(payments) - sum(bills) - bills = Bills.objects.filter(owner=self.request.user) - payments = Payment.objects.filter(owner=self.request.user) + #bills = Bill.objects.filter(owner=self.request.user) + #payments = Payment.objects.filter(owner=self.request.user) # sum_paid = sum([ amount for amount payments..,. ]) # you get the picture # sum_to_be_paid = sum([ amount for amount bills..,. ]) # you get the picture + pass -class Bills(viewset.ModelViewSet): - def unpaid(self, request): - return Bills.objects.filter(owner=self.request.user, paid=False) - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +class BillViewSet(viewsets.ModelViewSet): serializer_class = BillSerializer permission_classes = [permissions.IsAuthenticated] http_method_names = ['get'] def get_queryset(self): - return self.request.user.get_bills() + return Bill.objects.filter(owner=self.request.user) + + def unpaid(self, request): + return Bill.objects.filter(owner=self.request.user, paid=False) + +class PaymentViewSet(viewsets.ModelViewSet): + serializer_class = PaymentSerializer + permission_classes = [permissions.IsAuthenticated] + http_method_names = ['get', 'post'] + + def get_queryset(self): + return Payment.objects.filter(user=self.request.user) + + def create(self, request): + serializer = self.get_serializer(data=request.data) + serializer.is_valid(raise_exception=True) + serializer.save(user=request.user,timestamp=datetime.now()) + + headers = self.get_success_headers(serializer.data) + return Response(serializer.data, status=status.HTTP_201_CREATED, headers=headers) diff --git a/uncloud/uncloud_vm/migrations/0004_vmsnapshotproduct.py b/uncloud/uncloud_vm/migrations/0004_vmsnapshotproduct.py new file mode 100644 index 0000000..13840b5 --- /dev/null +++ b/uncloud/uncloud_vm/migrations/0004_vmsnapshotproduct.py @@ -0,0 +1,33 @@ +# Generated by Django 3.0.3 on 2020-02-27 10:50 + +from django.conf import settings +from django.db import migrations, models +import django.db.models.deletion +import uuid + + +class Migration(migrations.Migration): + + dependencies = [ + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ('uncloud_pay', '0001_initial'), + ('uncloud_vm', '0003_auto_20200225_2028'), + ] + + operations = [ + migrations.CreateModel( + name='VMSnapshotProduct', + fields=[ + ('uuid', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)), + ('status', models.CharField(choices=[('pending', 'Pending'), ('being_created', 'Being created'), ('active', 'Active'), ('deleted', 'Deleted')], default='pending', max_length=256)), + ('gb_ssd', models.FloatField(editable=False)), + ('gb_hdd', models.FloatField(editable=False)), + ('vm_uuid', models.UUIDField()), + ('order', models.ForeignKey(editable=False, on_delete=django.db.models.deletion.CASCADE, to='uncloud_pay.Order')), + ('owner', models.ForeignKey(editable=False, on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)), + ], + options={ + 'abstract': False, + }, + ), + ] diff --git a/uncloud/uncloud_vm/serializers.py b/uncloud/uncloud_vm/serializers.py index d5549ad..232e954 100644 --- a/uncloud/uncloud_vm/serializers.py +++ b/uncloud/uncloud_vm/serializers.py @@ -1,7 +1,7 @@ from django.contrib.auth import get_user_model from rest_framework import serializers -from .models import VMHost, VMProduct +from .models import VMHost, VMProduct, VMSnapshotProduct class VMHostSerializer(serializers.HyperlinkedModelSerializer): class Meta: diff --git a/uncloud/uncloud_vm/views.py b/uncloud/uncloud_vm/views.py index aabf8c5..55b607f 100644 --- a/uncloud/uncloud_vm/views.py +++ b/uncloud/uncloud_vm/views.py @@ -9,7 +9,7 @@ from rest_framework.response import Response from .models import VMHost, VMProduct. VMSnapshotProduct from uncloud_pay.models import Order -from .serializers import VMHostSerializer, VMProductSerializer +from .serializers import VMHostSerializer, VMProductSerializer, VMSnapshotProductSerializer class VMHostViewSet(viewsets.ModelViewSet): serializer_class = VMHostSerializer @@ -40,12 +40,11 @@ class VMSnapshotProductViewSet(viewsets.ModelViewSet): return VMSnapshotProduct.objects.filter(owner=self.request.user) def create(self, request): - serializer = VMProductSerializer(data=request.data, context={'request': request}) serializer.is_valid(raise_exception=True) # Create order - order = Order() + #order = Order() serializer.save(owner=request.user)