Add naive GenericServiceProduct
This commit is contained in:
		
					parent
					
						
							
								83a0ca0e4e
							
						
					
				
			
			
				commit
				
					
						c57780fb4d
					
				
			
		
					 6 changed files with 146 additions and 5 deletions
				
			
		| 
						 | 
					@ -44,6 +44,8 @@ router.register(r'vm/vm', vmviews.VMProductViewSet, basename='vmproduct')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Services
 | 
					# Services
 | 
				
			||||||
router.register(r'service/matrix', serviceviews.MatrixServiceProductViewSet, basename='matrixserviceproduct')
 | 
					router.register(r'service/matrix', serviceviews.MatrixServiceProductViewSet, basename='matrixserviceproduct')
 | 
				
			||||||
 | 
					router.register(r'service/generic', serviceviews.GenericServiceProductViewSet, basename='genericserviceproduct')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Net
 | 
					# Net
 | 
				
			||||||
router.register(r'net/vpn', netviews.VPNNetworkViewSet, basename='vpnnet')
 | 
					router.register(r'net/vpn', netviews.VPNNetworkViewSet, basename='vpnnet')
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,8 +1,9 @@
 | 
				
			||||||
import uuid
 | 
					import uuid
 | 
				
			||||||
 | 
					
 | 
				
			||||||
from django.db import models
 | 
					from django.db import models
 | 
				
			||||||
from uncloud_pay.models import Product, RecurringPeriod
 | 
					from uncloud_pay.models import Product, RecurringPeriod, AMOUNT_MAX_DIGITS, AMOUNT_DECIMALS
 | 
				
			||||||
from uncloud_vm.models import VMProduct, VMDiskImageProduct
 | 
					from uncloud_vm.models import VMProduct, VMDiskImageProduct
 | 
				
			||||||
 | 
					from django.core.validators import MinValueValidator
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class MatrixServiceProduct(Product):
 | 
					class MatrixServiceProduct(Product):
 | 
				
			||||||
    monthly_managment_fee = 20
 | 
					    monthly_managment_fee = 20
 | 
				
			||||||
| 
						 | 
					@ -33,3 +34,30 @@ class MatrixServiceProduct(Product):
 | 
				
			||||||
    @property
 | 
					    @property
 | 
				
			||||||
    def one_time_price(self):
 | 
					    def one_time_price(self):
 | 
				
			||||||
        return 30
 | 
					        return 30
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class GenericServiceProduct(Product):
 | 
				
			||||||
 | 
					    custom_description = models.TextField()
 | 
				
			||||||
 | 
					    custom_recurring_price = models.DecimalField(default=0.0,
 | 
				
			||||||
 | 
					            max_digits=AMOUNT_MAX_DIGITS,
 | 
				
			||||||
 | 
					            decimal_places=AMOUNT_DECIMALS,
 | 
				
			||||||
 | 
					            validators=[MinValueValidator(0)])
 | 
				
			||||||
 | 
					    custom_one_time_price = models.DecimalField(default=0.0,
 | 
				
			||||||
 | 
					            max_digits=AMOUNT_MAX_DIGITS,
 | 
				
			||||||
 | 
					            decimal_places=AMOUNT_DECIMALS,
 | 
				
			||||||
 | 
					            validators=[MinValueValidator(0)])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @property
 | 
				
			||||||
 | 
					    def recurring_price(self):
 | 
				
			||||||
 | 
					        return self.custom_recurring_price
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @property
 | 
				
			||||||
 | 
					    def description(self):
 | 
				
			||||||
 | 
					        return self.custom_description
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @property
 | 
				
			||||||
 | 
					    def one_time_price(self):
 | 
				
			||||||
 | 
					        return self.custom_one_time_price
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @staticmethod
 | 
				
			||||||
 | 
					    def allowed_recurring_periods():
 | 
				
			||||||
 | 
					        return RecurringPeriod.choices
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,5 +1,5 @@
 | 
				
			||||||
from rest_framework import serializers
 | 
					from rest_framework import serializers
 | 
				
			||||||
from .models import MatrixServiceProduct
 | 
					from .models import *
 | 
				
			||||||
from uncloud_vm.serializers import ManagedVMProductSerializer
 | 
					from uncloud_vm.serializers import ManagedVMProductSerializer
 | 
				
			||||||
from uncloud_vm.models import VMProduct
 | 
					from uncloud_vm.models import VMProduct
 | 
				
			||||||
from uncloud_pay.models import RecurringPeriod
 | 
					from uncloud_pay.models import RecurringPeriod
 | 
				
			||||||
| 
						 | 
					@ -15,3 +15,14 @@ class MatrixServiceProductSerializer(serializers.ModelSerializer):
 | 
				
			||||||
        model = MatrixServiceProduct
 | 
					        model = MatrixServiceProduct
 | 
				
			||||||
        fields = ['uuid', 'order', 'owner', 'status', 'vm', 'domain', 'recurring_period']
 | 
					        fields = ['uuid', 'order', 'owner', 'status', 'vm', 'domain', 'recurring_period']
 | 
				
			||||||
        read_only_fields = ['uuid', 'order', 'owner', 'status']
 | 
					        read_only_fields = ['uuid', 'order', 'owner', 'status']
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class GenericServiceProductSerializer(serializers.ModelSerializer):
 | 
				
			||||||
 | 
					    # Custom field used at creation (= ordering) only.
 | 
				
			||||||
 | 
					    recurring_period = serializers.ChoiceField(
 | 
				
			||||||
 | 
					            choices=GenericServiceProduct.allowed_recurring_periods())
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    class Meta:
 | 
				
			||||||
 | 
					        model = GenericServiceProduct
 | 
				
			||||||
 | 
					        fields = ['uuid', 'order', 'owner', 'status', 'custom_recurring_price',
 | 
				
			||||||
 | 
					                'custom_description', 'custom_one_time_price', 'recurring_period']
 | 
				
			||||||
 | 
					        read_only_fields = ['uuid', 'order', 'owner', 'status']
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,9 +1,10 @@
 | 
				
			||||||
from rest_framework import viewsets, permissions
 | 
					from rest_framework import viewsets, permissions
 | 
				
			||||||
from rest_framework.response import Response
 | 
					from rest_framework.response import Response
 | 
				
			||||||
from django.db import transaction
 | 
					from django.db import transaction
 | 
				
			||||||
 | 
					from django.utils import timezone
 | 
				
			||||||
 | 
					
 | 
				
			||||||
from .models import MatrixServiceProduct
 | 
					from .models import *
 | 
				
			||||||
from .serializers import MatrixServiceProductSerializer
 | 
					from .serializers import *
 | 
				
			||||||
 | 
					
 | 
				
			||||||
from uncloud_pay.helpers import ProductViewSet
 | 
					from uncloud_pay.helpers import ProductViewSet
 | 
				
			||||||
from uncloud_pay.models import Order
 | 
					from uncloud_pay.models import Order
 | 
				
			||||||
| 
						 | 
					@ -47,7 +48,10 @@ class MatrixServiceProductViewSet(ProductViewSet):
 | 
				
			||||||
        # Create base order.)
 | 
					        # Create base order.)
 | 
				
			||||||
        order = Order.objects.create(
 | 
					        order = Order.objects.create(
 | 
				
			||||||
                recurring_period=order_recurring_period,
 | 
					                recurring_period=order_recurring_period,
 | 
				
			||||||
                owner=request.user)
 | 
					                owner=request.user,
 | 
				
			||||||
 | 
					                starting_date=timezone.now()
 | 
				
			||||||
 | 
					                )
 | 
				
			||||||
 | 
					        order.save()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # Create unerderlying VM.
 | 
					        # Create unerderlying VM.
 | 
				
			||||||
        data = serializer.validated_data.pop('vm')
 | 
					        data = serializer.validated_data.pop('vm')
 | 
				
			||||||
| 
						 | 
					@ -65,3 +69,45 @@ class MatrixServiceProductViewSet(ProductViewSet):
 | 
				
			||||||
                vm=vm)
 | 
					                vm=vm)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return Response(serializer.data)
 | 
					        return Response(serializer.data)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class GenericServiceProductViewSet(ProductViewSet):
 | 
				
			||||||
 | 
					    permission_classes = [permissions.IsAuthenticated]
 | 
				
			||||||
 | 
					    serializer_class = GenericServiceProductSerializer
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def get_queryset(self):
 | 
				
			||||||
 | 
					        return GenericServiceProduct.objects.filter(owner=self.request.user)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @transaction.atomic
 | 
				
			||||||
 | 
					    def create(self, request):
 | 
				
			||||||
 | 
					        # Extract serializer data.
 | 
				
			||||||
 | 
					        serializer = self.get_serializer(data=request.data)
 | 
				
			||||||
 | 
					        serializer.is_valid(raise_exception=True)
 | 
				
			||||||
 | 
					        order_recurring_period = serializer.validated_data.pop("recurring_period")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        # Create base order.
 | 
				
			||||||
 | 
					        order = Order.objects.create(
 | 
				
			||||||
 | 
					                recurring_period=order_recurring_period,
 | 
				
			||||||
 | 
					                owner=request.user,
 | 
				
			||||||
 | 
					                starting_date=timezone.now()
 | 
				
			||||||
 | 
					                )
 | 
				
			||||||
 | 
					        order.save()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        # Create service.
 | 
				
			||||||
 | 
					        print(serializer.validated_data)
 | 
				
			||||||
 | 
					        service = serializer.save(order=order, owner=request.user)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        # XXX: Move this to some kind of on_create hook in parent
 | 
				
			||||||
 | 
					        # Product class?
 | 
				
			||||||
 | 
					        order.add_record(
 | 
				
			||||||
 | 
					                service.one_time_price,
 | 
				
			||||||
 | 
					                service.recurring_price,
 | 
				
			||||||
 | 
					                service.description)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        # XXX: Move this to some kind of on_create hook in parent
 | 
				
			||||||
 | 
					        # Product class?
 | 
				
			||||||
 | 
					        order.add_record(
 | 
				
			||||||
 | 
					                service.one_time_price,
 | 
				
			||||||
 | 
					                service.recurring_price,
 | 
				
			||||||
 | 
					                service.description)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return Response(serializer.data)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,18 @@
 | 
				
			||||||
 | 
					# Generated by Django 3.0.5 on 2020-04-17 05:51
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					from django.db import migrations, models
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class Migration(migrations.Migration):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    dependencies = [
 | 
				
			||||||
 | 
					        ('ungleich_service', '0004_auto_20200403_1727'),
 | 
				
			||||||
 | 
					    ]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    operations = [
 | 
				
			||||||
 | 
					        migrations.AlterField(
 | 
				
			||||||
 | 
					            model_name='matrixserviceproduct',
 | 
				
			||||||
 | 
					            name='status',
 | 
				
			||||||
 | 
					            field=models.CharField(choices=[('PENDING', 'Pending'), ('AWAITING_PAYMENT', 'Awaiting payment'), ('BEING_CREATED', 'Being created'), ('SCHEDULED', 'Scheduled'), ('ACTIVE', 'Active'), ('MODIFYING', 'Modifying'), ('DELETED', 'Deleted'), ('DISABLED', 'Disabled'), ('UNUSABLE', 'Unusable')], default='AWAITING_PAYMENT', max_length=32),
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					    ]
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,36 @@
 | 
				
			||||||
 | 
					# Generated by Django 3.0.5 on 2020-04-17 08:02
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					from django.conf import settings
 | 
				
			||||||
 | 
					import django.contrib.postgres.fields.jsonb
 | 
				
			||||||
 | 
					import django.core.validators
 | 
				
			||||||
 | 
					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', '0005_auto_20200417_0551'),
 | 
				
			||||||
 | 
					        ('ungleich_service', '0005_auto_20200417_0551'),
 | 
				
			||||||
 | 
					    ]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    operations = [
 | 
				
			||||||
 | 
					        migrations.CreateModel(
 | 
				
			||||||
 | 
					            name='GenericServiceProduct',
 | 
				
			||||||
 | 
					            fields=[
 | 
				
			||||||
 | 
					                ('extra_data', django.contrib.postgres.fields.jsonb.JSONField(blank=True, editable=False, null=True)),
 | 
				
			||||||
 | 
					                ('uuid', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)),
 | 
				
			||||||
 | 
					                ('status', models.CharField(choices=[('PENDING', 'Pending'), ('AWAITING_PAYMENT', 'Awaiting payment'), ('BEING_CREATED', 'Being created'), ('SCHEDULED', 'Scheduled'), ('ACTIVE', 'Active'), ('MODIFYING', 'Modifying'), ('DELETED', 'Deleted'), ('DISABLED', 'Disabled'), ('UNUSABLE', 'Unusable')], default='AWAITING_PAYMENT', max_length=32)),
 | 
				
			||||||
 | 
					                ('custom_description', models.TextField()),
 | 
				
			||||||
 | 
					                ('custom_recurring_price', models.DecimalField(decimal_places=2, default=0.0, max_digits=10, validators=[django.core.validators.MinValueValidator(0)])),
 | 
				
			||||||
 | 
					                ('custom_one_time_price', models.DecimalField(decimal_places=2, default=0.0, max_digits=10, validators=[django.core.validators.MinValueValidator(0)])),
 | 
				
			||||||
 | 
					                ('order', models.ForeignKey(editable=False, null=True, 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,
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					    ]
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue