diff --git a/uncloud/uncloud_pay/migrations/0004_auto_20200227_1532.py b/uncloud/uncloud_pay/migrations/0004_auto_20200227_1532.py new file mode 100644 index 0000000..f26b498 --- /dev/null +++ b/uncloud/uncloud_pay/migrations/0004_auto_20200227_1532.py @@ -0,0 +1,31 @@ +# Generated by Django 3.0.3 on 2020-02-27 15:32 + +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_pay', '0003_auto_20200227_1414'), + ] + + operations = [ + migrations.AlterField( + model_name='bill', + name='owner', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL), + ), + migrations.AlterField( + model_name='order', + name='recurring_period', + field=models.CharField(choices=[('ONCE', 'Onetime'), ('YEAR', 'Per Year'), ('MONTH', 'Per Month'), ('MINUTE', 'Per Minute'), ('DAY', 'Per Day'), ('HOUR', 'Per Hour'), ('SECOND', 'Per Second')], default='MONTH', max_length=32), + ), + migrations.AlterField( + model_name='payment', + name='owner', + field=models.ForeignKey(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 c824a00..d7c4ff1 100644 --- a/uncloud/uncloud_pay/models.py +++ b/uncloud/uncloud_pay/models.py @@ -1,12 +1,23 @@ from django.db import models from django.contrib.auth import get_user_model from django.core.validators import MinValueValidator +from django.utils.translation import gettext_lazy as _ import uuid AMOUNT_MAX_DIGITS=10 AMOUNT_DECIMALS=2 +# See https://docs.djangoproject.com/en/dev/ref/models/fields/#field-choices-enum-types +class RecurringPeriod(models.TextChoices): + ONE_TIME = 'ONCE', _('Onetime') + PER_YEAR = 'YEAR', _('Per Year') + PER_MONTH = 'MONTH', _('Per Month') + PER_MINUTE = 'MINUTE', _('Per Minute') + PER_DAY = 'DAY', _('Per Day') + PER_HOUR = 'HOUR', _('Per Hour') + PER_SECOND = 'SECOND', _('Per Second') + class Bill(models.Model): owner = models.ForeignKey(get_user_model(), on_delete=models.CASCADE) @@ -31,7 +42,7 @@ class Order(models.Model): on_delete=models.CASCADE, editable=False) - creation_date = models.DateTimeField() + creation_date = models.DateTimeField(auto_now_add=True) starting_date = models.DateTimeField() ending_date = models.DateTimeField(blank=True, null=True) @@ -46,19 +57,8 @@ class Order(models.Model): one_time_price = models.FloatField(editable=False) recurring_period = models.CharField(max_length=32, - 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' - - ) + choices = RecurringPeriod.choices, + default = RecurringPeriod.PER_MONTH) # def amount(self): # amount = recurring_price @@ -133,7 +133,12 @@ class Product(models.Model): order = models.ForeignKey(Order, on_delete=models.CASCADE, - editable=False) + editable=False, + null=True) + + @property + def recurring_price(self, recurring_period=RecurringPeriod.PER_MONTH): + pass # To be implemented in child. class Meta: abstract = True diff --git a/uncloud/uncloud_pay/serializers.py b/uncloud/uncloud_pay/serializers.py index 040c78a..4065fbd 100644 --- a/uncloud/uncloud_pay/serializers.py +++ b/uncloud/uncloud_pay/serializers.py @@ -3,6 +3,7 @@ from rest_framework import serializers from .models import * from functools import reduce +from uncloud_vm.serializers import VMProductSerializer class BillSerializer(serializers.ModelSerializer): class Meta: @@ -20,11 +21,30 @@ class PaymentMethodSerializer(serializers.ModelSerializer): model = PaymentMethod fields = ['owner', 'primary', 'source', 'description'] +class ProductSerializer(serializers.Serializer): + vms = VMProductSerializer(many=True, required=False) + class meta: + fields = ['vms'] + + def create(self, validated_data): + pass + class OrderSerializer(serializers.ModelSerializer): + products = ProductSerializer(many=True) class Meta: model = Order fields = '__all__' + def create(self, validated_data): + products_data = validated_data.pop('products') + order = Order.objects.create(**validated_data) + for product_data in products_data: + print("spouik") + print(product_data) + pass # TODO + + return order + class UserSerializer(serializers.ModelSerializer): class Meta: model = get_user_model() diff --git a/uncloud/uncloud_pay/views.py b/uncloud/uncloud_pay/views.py index ea3cca7..c641991 100644 --- a/uncloud/uncloud_pay/views.py +++ b/uncloud/uncloud_pay/views.py @@ -42,7 +42,7 @@ class PaymentViewSet(viewsets.ReadOnlyModelViewSet): def get_queryset(self): return Payment.objects.filter(owner=self.request.user) -class OrderViewSet(viewsets.ReadOnlyModelViewSet): +class OrderViewSet(viewsets.ModelViewSet): serializer_class = OrderSerializer permission_classes = [permissions.IsAuthenticated] diff --git a/uncloud/uncloud_vm/migrations/0005_auto_20200227_1532.py b/uncloud/uncloud_vm/migrations/0005_auto_20200227_1532.py new file mode 100644 index 0000000..b49d6e4 --- /dev/null +++ b/uncloud/uncloud_vm/migrations/0005_auto_20200227_1532.py @@ -0,0 +1,30 @@ +# Generated by Django 3.0.3 on 2020-02-27 15:32 + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('uncloud_pay', '0004_auto_20200227_1532'), + ('uncloud_vm', '0004_vmsnapshotproduct'), + ] + + operations = [ + migrations.AddField( + model_name='vmproduct', + name='order', + field=models.ForeignKey(editable=False, null=True, on_delete=django.db.models.deletion.CASCADE, to='uncloud_pay.Order'), + ), + migrations.AddField( + model_name='vmproduct', + name='status', + field=models.CharField(choices=[('pending', 'Pending'), ('being_created', 'Being created'), ('active', 'Active'), ('deleted', 'Deleted')], default='pending', max_length=256), + ), + migrations.AlterField( + model_name='vmsnapshotproduct', + name='order', + field=models.ForeignKey(editable=False, null=True, on_delete=django.db.models.deletion.CASCADE, to='uncloud_pay.Order'), + ), + ] diff --git a/uncloud/uncloud_vm/models.py b/uncloud/uncloud_vm/models.py index 12d188e..2510837 100644 --- a/uncloud/uncloud_vm/models.py +++ b/uncloud/uncloud_vm/models.py @@ -2,7 +2,7 @@ from django.db import models from django.contrib.auth import get_user_model import uuid -from uncloud_pay.models import Product +from uncloud_pay.models import Product, RecurringPeriod class VMHost(models.Model): @@ -32,22 +32,25 @@ class VMHost(models.Model): ) -class VMProduct(models.Model): - uuid = models.UUIDField(primary_key=True, - default=uuid.uuid4, - editable=False) - owner = models.ForeignKey(get_user_model(), - on_delete=models.CASCADE, - editable=False) +class VMProduct(Product): vmhost = models.ForeignKey(VMHost, on_delete=models.CASCADE, editable=False, blank=True, null=True) + description = "Virtual Machine" cores = models.IntegerField() ram_in_gb = models.FloatField() + @property + def recurring_price(self, recurring_period=RecurringPeriod.PER_MONTH): + if recurring_period == RecurringPeriod.PER_MONTH: + # TODO: move magic numbers in variables + return self.cores * 3 + self.ram_in_gb * 2 + else: + raise Exception('Invalid recurring period for VM Product pricing.') + class VMWithOSProduct(VMProduct): pass