diff --git a/uncloud/uncloud/settings.py b/uncloud/uncloud/settings.py index 614cd25..05c4f35 100644 --- a/uncloud/uncloud/settings.py +++ b/uncloud/uncloud/settings.py @@ -61,6 +61,7 @@ INSTALLED_APPS = [ 'django.contrib.staticfiles', 'rest_framework', 'uncloud_api', + '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_api/admin.py b/uncloud/uncloud_api/admin.py index d242668..03246ec 100644 --- a/uncloud/uncloud_api/admin.py +++ b/uncloud/uncloud_api/admin.py @@ -1,6 +1,4 @@ from django.contrib import admin -from .models import Product, Feature - #admin.site.register(Product) #admin.site.register(Feature) diff --git a/uncloud/uncloud_api/migrations/0002_vmsnapshotproduct_vm_uuid.py b/uncloud/uncloud_api/migrations/0002_vmsnapshotproduct_vm_uuid.py deleted file mode 100644 index b35317e..0000000 --- a/uncloud/uncloud_api/migrations/0002_vmsnapshotproduct_vm_uuid.py +++ /dev/null @@ -1,19 +0,0 @@ -# Generated by Django 3.0.3 on 2020-02-25 18:16 - -from django.db import migrations, models -import uuid - - -class Migration(migrations.Migration): - - dependencies = [ - ('uncloud_api', '0001_initial'), - ] - - operations = [ - migrations.AddField( - model_name='vmsnapshotproduct', - name='vm_uuid', - field=models.UUIDField(default=uuid.uuid4, editable=False), - ), - ] diff --git a/uncloud/uncloud_api/migrations/0003_auto_20200225_1950.py b/uncloud/uncloud_api/migrations/0003_auto_20200225_1950.py deleted file mode 100644 index be7624c..0000000 --- a/uncloud/uncloud_api/migrations/0003_auto_20200225_1950.py +++ /dev/null @@ -1,36 +0,0 @@ -# Generated by Django 3.0.3 on 2020-02-25 19:50 - -from django.conf import settings -from django.db import migrations, models -import django.db.models.deletion - - -class Migration(migrations.Migration): - - dependencies = [ - migrations.swappable_dependency(settings.AUTH_USER_MODEL), - ('uncloud_api', '0002_vmsnapshotproduct_vm_uuid'), - ] - - operations = [ - migrations.AlterField( - model_name='vmsnapshotproduct', - name='gb_hdd', - field=models.FloatField(editable=False), - ), - migrations.AlterField( - model_name='vmsnapshotproduct', - name='gb_ssd', - field=models.FloatField(editable=False), - ), - migrations.AlterField( - model_name='vmsnapshotproduct', - name='owner', - field=models.ForeignKey(editable=False, on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL), - ), - migrations.AlterField( - model_name='vmsnapshotproduct', - name='vm_uuid', - field=models.UUIDField(), - ), - ] diff --git a/uncloud/uncloud_api/migrations/__init__.py b/uncloud/uncloud_api/migrations/__init__.py deleted file mode 100644 index e69de29..0000000 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_api/migrations/0001_initial.py b/uncloud/uncloud_vm/migrations/0004_vmsnapshotproduct.py similarity index 57% rename from uncloud/uncloud_api/migrations/0001_initial.py rename to uncloud/uncloud_vm/migrations/0004_vmsnapshotproduct.py index 67bdd2e..13840b5 100644 --- a/uncloud/uncloud_api/migrations/0001_initial.py +++ b/uncloud/uncloud_vm/migrations/0004_vmsnapshotproduct.py @@ -1,4 +1,4 @@ -# Generated by Django 3.0.3 on 2020-02-23 17:12 +# Generated by Django 3.0.3 on 2020-02-27 10:50 from django.conf import settings from django.db import migrations, models @@ -8,10 +8,10 @@ import uuid class Migration(migrations.Migration): - initial = True - dependencies = [ migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ('uncloud_pay', '0001_initial'), + ('uncloud_vm', '0003_auto_20200225_2028'), ] operations = [ @@ -20,9 +20,11 @@ class Migration(migrations.Migration): 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()), - ('gb_hdd', models.FloatField()), - ('owner', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)), + ('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 4f2f9f4..cb87e9d 100644 --- a/uncloud/uncloud_vm/views.py +++ b/uncloud/uncloud_vm/views.py @@ -7,7 +7,7 @@ from rest_framework import viewsets, permissions from rest_framework.response import Response from .models import VMHost, VMProduct -from .serializers import VMHostSerializer, VMProductSerializer +from .serializers import VMHostSerializer, VMProductSerializer, VMSnapshotProductSerializer class VMHostViewSet(viewsets.ModelViewSet): serializer_class = VMHostSerializer @@ -49,13 +49,13 @@ class VMSnapshotProductView(viewsets.ViewSet): def list(self, request): queryset = VMSnapshotProduct.objects.filter(owner=request.user) - serializer = VMSnapshotSerializer(queryset, many=True, context={'request': request}) + serializer = VMSnapshotProductSerializer(queryset, many=True, context={'request': request}) return Response(serializer.data) def retrieve(self, request, pk=None): queryset = VMSnapshotProduct.objects.filter(owner=request.user) vm = get_object_or_404(queryset, pk=pk) - serializer = VMSnapshotSerializer(vm, context={'request': request}) + serializer = VMSnapshotProductSerializer(vm, context={'request': request}) return Response(serializer.data) def create(self, request):