From b31aa72f8405f72a4a00b86072d3f8bf8dc52996 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timoth=C3=A9e=20Floure?= Date: Tue, 3 Mar 2020 10:14:56 +0100 Subject: [PATCH] Allow to select billing period when registering VM --- uncloud/uncloud_pay/models.py | 4 ++++ uncloud/uncloud_vm/models.py | 4 +++- uncloud/uncloud_vm/serializers.py | 12 +++++++++++- uncloud/uncloud_vm/views.py | 10 +++++++--- 4 files changed, 25 insertions(+), 5 deletions(-) diff --git a/uncloud/uncloud_pay/models.py b/uncloud/uncloud_pay/models.py index 52e5281..f4bd4f0 100644 --- a/uncloud/uncloud_pay/models.py +++ b/uncloud/uncloud_pay/models.py @@ -299,5 +299,9 @@ class Product(models.Model): def setup_fee(self): return 0 + @property + def recurring_period(self): + return self.order.recurring_period + class Meta: abstract = True diff --git a/uncloud/uncloud_vm/models.py b/uncloud/uncloud_vm/models.py index c32f3a5..7732964 100644 --- a/uncloud/uncloud_vm/models.py +++ b/uncloud/uncloud_vm/models.py @@ -47,9 +47,11 @@ class VMProduct(Product): ram_in_gb = models.FloatField() def recurring_price(self, recurring_period=RecurringPeriod.PER_MONTH): + # TODO: move magic numbers in variables if recurring_period == RecurringPeriod.PER_MONTH: - # TODO: move magic numbers in variables return self.cores * 3 + self.ram_in_gb * 2 + elif recurring_period == RecurringPeriod.PER_HOUR: + return self.cores * 4.0/(30 * 24) + self.ram_in_gb * 3.0/(30* 24) else: raise Exception('Invalid recurring period for VM Product pricing.') diff --git a/uncloud/uncloud_vm/serializers.py b/uncloud/uncloud_vm/serializers.py index 4257a03..daf36ab 100644 --- a/uncloud/uncloud_vm/serializers.py +++ b/uncloud/uncloud_vm/serializers.py @@ -2,6 +2,7 @@ from django.contrib.auth import get_user_model from rest_framework import serializers from .models import VMHost, VMProduct, VMSnapshotProduct +from uncloud_pay.models import RecurringPeriod class VMHostSerializer(serializers.HyperlinkedModelSerializer): class Meta: @@ -10,10 +11,19 @@ class VMHostSerializer(serializers.HyperlinkedModelSerializer): class VMProductSerializer(serializers.HyperlinkedModelSerializer): + # TODO: move this to VMProduct. + allowed_recurring_periods=list(filter( + lambda pair: pair[0] in [RecurringPeriod.PER_MONTH, RecurringPeriod.PER_HOUR], + RecurringPeriod.choices)) + + # Custom field used at creation (= ordering) only. + recurring_period = serializers.ChoiceField( + choices=allowed_recurring_periods) + class Meta: model = VMProduct fields = ['uuid', 'order', 'owner', 'status', 'name', \ - 'cores', 'ram_in_gb'] + 'cores', 'ram_in_gb', 'recurring_period'] read_only_fields = ['uuid', 'order', 'owner', 'status'] class VMSnapshotProductSerializer(serializers.ModelSerializer): diff --git a/uncloud/uncloud_vm/views.py b/uncloud/uncloud_vm/views.py index 5de904c..107f23e 100644 --- a/uncloud/uncloud_vm/views.py +++ b/uncloud/uncloud_vm/views.py @@ -32,19 +32,23 @@ class VMProductViewSet(ProductViewSet): # if something goes wrong. @transaction.atomic def create(self, request): + # Extract serializer data. + serializer = VMProductSerializer(data=request.data, context={'request': request}) + serializer.is_valid(raise_exception=True) + order_recurring_period = serializer.validated_data.pop("recurring_period") + # Create base order. order = Order.objects.create( - recurring_period=RecurringPeriod.PER_MONTH, + recurring_period=order_recurring_period, owner=request.user ) order.save() # Create VM. - serializer = VMProductSerializer(data=request.data, context={'request': request}) - serializer.is_valid(raise_exception=True) vm = serializer.save(owner=request.user, order=order) # Add Product record to order (VM is mutable, allows to keep history in order). + # XXX: Move this to some kind of on_create hook in parent Product class? order.add_record(vm.setup_fee, vm.recurring_price(order.recurring_period), vm.description)