Merge pull request #624 from pcoder/task/3934/move_hosting_order_out_of_celery_task
Task/3934/Create hostingorder outside celery task
This commit is contained in:
		
				commit
				
					
						1fa260aaf5
					
				
			
		
					 8 changed files with 241 additions and 100 deletions
				
			
		| 
						 | 
				
			
			@ -10,14 +10,13 @@ from django.utils import translation
 | 
			
		|||
from django.utils.translation import ugettext_lazy as _
 | 
			
		||||
 | 
			
		||||
from dynamicweb.celery import app
 | 
			
		||||
from hosting.models import HostingOrder, HostingBill
 | 
			
		||||
from membership.models import StripeCustomer, CustomUser
 | 
			
		||||
from hosting.models import HostingOrder
 | 
			
		||||
from membership.models import CustomUser
 | 
			
		||||
from opennebula_api.models import OpenNebulaManager
 | 
			
		||||
from opennebula_api.serializers import VirtualMachineSerializer
 | 
			
		||||
from utils.forms import UserBillingAddressForm
 | 
			
		||||
from utils.hosting_utils import get_all_public_keys, get_or_create_vm_detail
 | 
			
		||||
from utils.mailer import BaseEmail
 | 
			
		||||
from utils.models import BillingAddress
 | 
			
		||||
from utils.stripe_utils import StripeUtils
 | 
			
		||||
from .models import VMPricing
 | 
			
		||||
 | 
			
		||||
logger = get_task_logger(__name__)
 | 
			
		||||
| 
						 | 
				
			
			@ -50,24 +49,15 @@ def retry_task(task, exception=None):
 | 
			
		|||
 | 
			
		||||
 | 
			
		||||
@app.task(bind=True, max_retries=settings.CELERY_MAX_RETRIES)
 | 
			
		||||
def create_vm_task(self, vm_template_id, user, specs, template,
 | 
			
		||||
                   stripe_customer_id, billing_address_data,
 | 
			
		||||
                   stripe_subscription_id, cc_details):
 | 
			
		||||
def create_vm_task(self, vm_template_id, user, specs, template, order_id):
 | 
			
		||||
    logger.debug(
 | 
			
		||||
        "Running create_vm_task on {}".format(current_task.request.hostname))
 | 
			
		||||
    vm_id = None
 | 
			
		||||
    try:
 | 
			
		||||
        final_price = (specs.get('total_price') if 'total_price' in specs
 | 
			
		||||
                       else specs.get('price'))
 | 
			
		||||
        billing_address = BillingAddress(
 | 
			
		||||
            cardholder_name=billing_address_data['cardholder_name'],
 | 
			
		||||
            street_address=billing_address_data['street_address'],
 | 
			
		||||
            city=billing_address_data['city'],
 | 
			
		||||
            postal_code=billing_address_data['postal_code'],
 | 
			
		||||
            country=billing_address_data['country']
 | 
			
		||||
        final_price = (
 | 
			
		||||
            specs.get('total_price') if 'total_price' in specs
 | 
			
		||||
            else specs.get('price')
 | 
			
		||||
        )
 | 
			
		||||
        billing_address.save()
 | 
			
		||||
        customer = StripeCustomer.objects.filter(id=stripe_customer_id).first()
 | 
			
		||||
 | 
			
		||||
        if 'pass' in user:
 | 
			
		||||
            on_user = user.get('email')
 | 
			
		||||
| 
						 | 
				
			
			@ -96,38 +86,43 @@ def create_vm_task(self, vm_template_id, user, specs, template,
 | 
			
		|||
        if vm_id is None:
 | 
			
		||||
            raise Exception("Could not create VM")
 | 
			
		||||
 | 
			
		||||
        vm_pricing = VMPricing.get_vm_pricing_by_name(
 | 
			
		||||
            name=specs['pricing_name']
 | 
			
		||||
        ) if 'pricing_name' in specs else VMPricing.get_default_pricing()
 | 
			
		||||
        # Create a Hosting Order
 | 
			
		||||
        order = HostingOrder.create(
 | 
			
		||||
            price=final_price,
 | 
			
		||||
            vm_id=vm_id,
 | 
			
		||||
            customer=customer,
 | 
			
		||||
            billing_address=billing_address,
 | 
			
		||||
            vm_pricing=vm_pricing
 | 
			
		||||
        # Update HostingOrder with the created vm_id
 | 
			
		||||
        hosting_order = HostingOrder.objects.filter(id=order_id).first()
 | 
			
		||||
        error_msg = None
 | 
			
		||||
 | 
			
		||||
        try:
 | 
			
		||||
            hosting_order.vm_id = vm_id
 | 
			
		||||
            hosting_order.save()
 | 
			
		||||
            logger.debug(
 | 
			
		||||
                "Updated hosting_order {} with vm_id={}".format(
 | 
			
		||||
                    hosting_order.id, vm_id
 | 
			
		||||
                )
 | 
			
		||||
            )
 | 
			
		||||
        except Exception as ex:
 | 
			
		||||
            error_msg = (
 | 
			
		||||
                "HostingOrder with id {order_id} not found. This means that "
 | 
			
		||||
                "the hosting order was not created and/or it is/was not "
 | 
			
		||||
                "associated with VM with id {vm_id}. Details {details}".format(
 | 
			
		||||
                    order_id=order_id, vm_id=vm_id, details=str(ex)
 | 
			
		||||
                )
 | 
			
		||||
            )
 | 
			
		||||
            logger.error(error_msg)
 | 
			
		||||
 | 
			
		||||
        stripe_utils = StripeUtils()
 | 
			
		||||
        result = stripe_utils.set_subscription_metadata(
 | 
			
		||||
            subscription_id=hosting_order.subscription_id,
 | 
			
		||||
            metadata={"VM_ID": str(vm_id)}
 | 
			
		||||
        )
 | 
			
		||||
 | 
			
		||||
        # Create a Hosting Bill
 | 
			
		||||
        HostingBill.create(
 | 
			
		||||
            customer=customer, billing_address=billing_address
 | 
			
		||||
        if result.get('error') is not None:
 | 
			
		||||
            emsg = "Could not update subscription metadata for {sub}".format(
 | 
			
		||||
                sub=hosting_order.subscription_id
 | 
			
		||||
            )
 | 
			
		||||
 | 
			
		||||
        # Create Billing Address for User if he does not have one
 | 
			
		||||
        if not customer.user.billing_addresses.count():
 | 
			
		||||
            billing_address_data.update({
 | 
			
		||||
                'user': customer.user.id
 | 
			
		||||
            })
 | 
			
		||||
            billing_address_user_form = UserBillingAddressForm(
 | 
			
		||||
                billing_address_data)
 | 
			
		||||
            billing_address_user_form.is_valid()
 | 
			
		||||
            billing_address_user_form.save()
 | 
			
		||||
 | 
			
		||||
        # Associate an order with a stripe subscription
 | 
			
		||||
        order.set_subscription_id(stripe_subscription_id, cc_details)
 | 
			
		||||
 | 
			
		||||
        # If the Stripe payment succeeds, set order status approved
 | 
			
		||||
        order.set_approved()
 | 
			
		||||
            logger.error(emsg)
 | 
			
		||||
            if error_msg:
 | 
			
		||||
                error_msg += ". " + emsg
 | 
			
		||||
            else:
 | 
			
		||||
                error_msg = emsg
 | 
			
		||||
 | 
			
		||||
        vm = VirtualMachineSerializer(manager.get_vm(vm_id)).data
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -141,8 +136,11 @@ def create_vm_task(self, vm_template_id, user, specs, template,
 | 
			
		|||
            'template': template.get('name'),
 | 
			
		||||
            'vm_name': vm.get('name'),
 | 
			
		||||
            'vm_id': vm['vm_id'],
 | 
			
		||||
            'order_id': order.id
 | 
			
		||||
            'order_id': order_id
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if error_msg:
 | 
			
		||||
            context['errors'] = error_msg
 | 
			
		||||
        if 'pricing_name' in specs:
 | 
			
		||||
            context['pricing'] = str(VMPricing.get_vm_pricing_by_name(
 | 
			
		||||
                name=specs['pricing_name']
 | 
			
		||||
| 
						 | 
				
			
			@ -170,7 +168,7 @@ def create_vm_task(self, vm_template_id, user, specs, template,
 | 
			
		|||
                'base_url': "{0}://{1}".format(user.get('request_scheme'),
 | 
			
		||||
                                               user.get('request_host')),
 | 
			
		||||
                'order_url': reverse('hosting:orders',
 | 
			
		||||
                                     kwargs={'pk': order.id}),
 | 
			
		||||
                                     kwargs={'pk': order_id}),
 | 
			
		||||
                'page_header': _(
 | 
			
		||||
                    'Your New VM %(vm_name)s at Data Center Light') % {
 | 
			
		||||
                    'vm_name': vm.get('name')},
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -12,9 +12,11 @@ from unittest import skipIf
 | 
			
		|||
 | 
			
		||||
from datacenterlight.models import VMTemplate
 | 
			
		||||
from datacenterlight.tasks import create_vm_task
 | 
			
		||||
from hosting.models import HostingOrder
 | 
			
		||||
from membership.models import StripeCustomer
 | 
			
		||||
from opennebula_api.serializers import VMTemplateSerializer
 | 
			
		||||
from utils.hosting_utils import get_vm_price
 | 
			
		||||
from utils.models import BillingAddress
 | 
			
		||||
from utils.stripe_utils import StripeUtils
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -81,11 +83,14 @@ class CeleryTaskTestCase(TestCase):
 | 
			
		|||
 | 
			
		||||
        stripe_customer = StripeCustomer.get_or_create(
 | 
			
		||||
            email=self.customer_email,
 | 
			
		||||
            token=self.token)
 | 
			
		||||
            token=self.token
 | 
			
		||||
        )
 | 
			
		||||
        card_details = self.stripe_utils.get_card_details(
 | 
			
		||||
            stripe_customer.stripe_id,
 | 
			
		||||
            self.token)
 | 
			
		||||
        card_details_dict = card_details.get('response_object')
 | 
			
		||||
            self.token
 | 
			
		||||
        )
 | 
			
		||||
        card_details_dict = card_details.get('error')
 | 
			
		||||
        self.assertEquals(card_details_dict, None)
 | 
			
		||||
        billing_address_data = {'cardholder_name': self.customer_name,
 | 
			
		||||
                                'postal_code': '1231',
 | 
			
		||||
                                'country': 'CH',
 | 
			
		||||
| 
						 | 
				
			
			@ -122,10 +127,24 @@ class CeleryTaskTestCase(TestCase):
 | 
			
		|||
            msg = subscription_result.get('error')
 | 
			
		||||
            raise Exception("Creating subscription failed: {}".format(msg))
 | 
			
		||||
 | 
			
		||||
        billing_address = BillingAddress(
 | 
			
		||||
            cardholder_name=billing_address_data['cardholder_name'],
 | 
			
		||||
            street_address=billing_address_data['street_address'],
 | 
			
		||||
            city=billing_address_data['city'],
 | 
			
		||||
            postal_code=billing_address_data['postal_code'],
 | 
			
		||||
            country=billing_address_data['country']
 | 
			
		||||
        )
 | 
			
		||||
        billing_address.save()
 | 
			
		||||
 | 
			
		||||
        order = HostingOrder.create(
 | 
			
		||||
            price=specs['price'],
 | 
			
		||||
            vm_id=0,
 | 
			
		||||
            customer=stripe_customer,
 | 
			
		||||
            billing_address=billing_address
 | 
			
		||||
        )
 | 
			
		||||
 | 
			
		||||
        async_task = create_vm_task.delay(
 | 
			
		||||
            vm_template_id, self.user, specs, template_data,
 | 
			
		||||
            stripe_customer.id, billing_address_data,
 | 
			
		||||
            stripe_subscription_obj.id, card_details_dict
 | 
			
		||||
            vm_template_id, self.user, specs, template_data, order.id
 | 
			
		||||
        )
 | 
			
		||||
        new_vm_id = 0
 | 
			
		||||
        res = None
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,6 +1,12 @@
 | 
			
		|||
from django.contrib.sites.models import Site
 | 
			
		||||
 | 
			
		||||
from datacenterlight.tasks import create_vm_task
 | 
			
		||||
from hosting.models import HostingOrder, HostingBill, OrderDetail
 | 
			
		||||
from membership.models import StripeCustomer
 | 
			
		||||
from utils.forms import UserBillingAddressForm
 | 
			
		||||
from utils.models import BillingAddress
 | 
			
		||||
from .cms_models import CMSIntegration
 | 
			
		||||
from .models import VMPricing, VMTemplate
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def get_cms_integration(name):
 | 
			
		||||
| 
						 | 
				
			
			@ -12,3 +18,76 @@ def get_cms_integration(name):
 | 
			
		|||
    except CMSIntegration.DoesNotExist:
 | 
			
		||||
        cms_integration = CMSIntegration.objects.get(name=name, domain=None)
 | 
			
		||||
    return cms_integration
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def create_vm(billing_address_data, stripe_customer_id, specs,
 | 
			
		||||
              stripe_subscription_obj, card_details_dict, request,
 | 
			
		||||
              vm_template_id, template, user):
 | 
			
		||||
    billing_address = BillingAddress(
 | 
			
		||||
        cardholder_name=billing_address_data['cardholder_name'],
 | 
			
		||||
        street_address=billing_address_data['street_address'],
 | 
			
		||||
        city=billing_address_data['city'],
 | 
			
		||||
        postal_code=billing_address_data['postal_code'],
 | 
			
		||||
        country=billing_address_data['country']
 | 
			
		||||
    )
 | 
			
		||||
    billing_address.save()
 | 
			
		||||
    customer = StripeCustomer.objects.filter(id=stripe_customer_id).first()
 | 
			
		||||
    vm_pricing = (
 | 
			
		||||
        VMPricing.get_vm_pricing_by_name(name=specs['pricing_name'])
 | 
			
		||||
        if 'pricing_name' in specs else
 | 
			
		||||
        VMPricing.get_default_pricing()
 | 
			
		||||
    )
 | 
			
		||||
 | 
			
		||||
    final_price = (
 | 
			
		||||
        specs.get('total_price')
 | 
			
		||||
        if 'total_price' in specs
 | 
			
		||||
        else specs.get('price')
 | 
			
		||||
    )
 | 
			
		||||
 | 
			
		||||
    # Create a Hosting Order with vm_id = 0, we shall set it later in
 | 
			
		||||
    # celery task once the VM instance is up and running
 | 
			
		||||
    order = HostingOrder.create(
 | 
			
		||||
        price=final_price,
 | 
			
		||||
        customer=customer,
 | 
			
		||||
        billing_address=billing_address,
 | 
			
		||||
        vm_pricing=vm_pricing
 | 
			
		||||
    )
 | 
			
		||||
 | 
			
		||||
    order_detail_obj, obj_created = OrderDetail.objects.get_or_create(
 | 
			
		||||
        vm_template=VMTemplate.objects.get(
 | 
			
		||||
            opennebula_vm_template_id=vm_template_id
 | 
			
		||||
        ),
 | 
			
		||||
        cores=specs['cpu'], memory=specs['memory'], ssd_size=specs['disk_size']
 | 
			
		||||
    )
 | 
			
		||||
    order.order_detail = order_detail_obj
 | 
			
		||||
    order.save()
 | 
			
		||||
 | 
			
		||||
    # Create a Hosting Bill
 | 
			
		||||
    HostingBill.create(customer=customer, billing_address=billing_address)
 | 
			
		||||
 | 
			
		||||
    # Create Billing Address for User if he does not have one
 | 
			
		||||
    if not customer.user.billing_addresses.count():
 | 
			
		||||
        billing_address_data.update({
 | 
			
		||||
            'user': customer.user.id
 | 
			
		||||
        })
 | 
			
		||||
        billing_address_user_form = UserBillingAddressForm(
 | 
			
		||||
            billing_address_data
 | 
			
		||||
        )
 | 
			
		||||
        billing_address_user_form.is_valid()
 | 
			
		||||
        billing_address_user_form.save()
 | 
			
		||||
 | 
			
		||||
    # Associate the given stripe subscription with the order
 | 
			
		||||
    order.set_subscription_id(
 | 
			
		||||
        stripe_subscription_obj.id, card_details_dict
 | 
			
		||||
    )
 | 
			
		||||
 | 
			
		||||
    # Set order status approved
 | 
			
		||||
    order.set_approved()
 | 
			
		||||
 | 
			
		||||
    create_vm_task.delay(vm_template_id, user, specs, template, order.id)
 | 
			
		||||
 | 
			
		||||
    for session_var in ['specs', 'template', 'billing_address',
 | 
			
		||||
                        'billing_address_data',
 | 
			
		||||
                        'token', 'customer']:
 | 
			
		||||
        if session_var in request.session:
 | 
			
		||||
            del request.session[session_var]
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,4 +1,3 @@
 | 
			
		|||
import json
 | 
			
		||||
import logging
 | 
			
		||||
 | 
			
		||||
from django import forms
 | 
			
		||||
| 
						 | 
				
			
			@ -7,13 +6,12 @@ from django.contrib import messages
 | 
			
		|||
from django.contrib.auth import login, authenticate
 | 
			
		||||
from django.core.exceptions import ValidationError
 | 
			
		||||
from django.core.urlresolvers import reverse
 | 
			
		||||
from django.http import HttpResponseRedirect, HttpResponse
 | 
			
		||||
from django.http import HttpResponseRedirect, JsonResponse
 | 
			
		||||
from django.shortcuts import render
 | 
			
		||||
from django.utils.translation import get_language, ugettext_lazy as _
 | 
			
		||||
from django.views.decorators.cache import cache_control
 | 
			
		||||
from django.views.generic import FormView, CreateView, DetailView
 | 
			
		||||
 | 
			
		||||
from datacenterlight.tasks import create_vm_task
 | 
			
		||||
from hosting.forms import HostingUserLoginForm
 | 
			
		||||
from hosting.models import HostingOrder
 | 
			
		||||
from membership.models import CustomUser, StripeCustomer
 | 
			
		||||
| 
						 | 
				
			
			@ -24,7 +22,7 @@ from utils.stripe_utils import StripeUtils
 | 
			
		|||
from utils.tasks import send_plain_email_task
 | 
			
		||||
from .forms import ContactForm
 | 
			
		||||
from .models import VMTemplate, VMPricing
 | 
			
		||||
from .utils import get_cms_integration
 | 
			
		||||
from .utils import get_cms_integration, create_vm
 | 
			
		||||
 | 
			
		||||
logger = logging.getLogger(__name__)
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -417,8 +415,8 @@ class OrderConfirmationView(DetailView):
 | 
			
		|||
                      ' On close of this popup, you will be redirected back to'
 | 
			
		||||
                      ' the payment page.'))
 | 
			
		||||
            }
 | 
			
		||||
            return HttpResponse(json.dumps(response),
 | 
			
		||||
                                content_type="application/json")
 | 
			
		||||
            return JsonResponse(response)
 | 
			
		||||
 | 
			
		||||
        card_details_dict = card_details.get('response_object')
 | 
			
		||||
        cpu = specs.get('cpu')
 | 
			
		||||
        memory = specs.get('memory')
 | 
			
		||||
| 
						 | 
				
			
			@ -458,8 +456,7 @@ class OrderConfirmationView(DetailView):
 | 
			
		|||
                      ' On close of this popup, you will be redirected back to'
 | 
			
		||||
                      ' the payment page.'))
 | 
			
		||||
            }
 | 
			
		||||
            return HttpResponse(json.dumps(response),
 | 
			
		||||
                                content_type="application/json")
 | 
			
		||||
            return JsonResponse(response)
 | 
			
		||||
 | 
			
		||||
        # Create user if the user is not logged in and if he is not already
 | 
			
		||||
        # registered
 | 
			
		||||
| 
						 | 
				
			
			@ -514,14 +511,11 @@ class OrderConfirmationView(DetailView):
 | 
			
		|||
            'language': get_language(),
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        create_vm_task.delay(vm_template_id, user, specs, template,
 | 
			
		||||
                             stripe_customer_id, billing_address_data,
 | 
			
		||||
                             stripe_subscription_obj.id, card_details_dict)
 | 
			
		||||
        for session_var in ['specs', 'template', 'billing_address',
 | 
			
		||||
                            'billing_address_data',
 | 
			
		||||
                            'token', 'customer', 'pricing_name']:
 | 
			
		||||
            if session_var in request.session:
 | 
			
		||||
                del request.session[session_var]
 | 
			
		||||
        create_vm(
 | 
			
		||||
            billing_address_data, stripe_customer_id, specs,
 | 
			
		||||
            stripe_subscription_obj, card_details_dict, request,
 | 
			
		||||
            vm_template_id, template, user
 | 
			
		||||
        )
 | 
			
		||||
 | 
			
		||||
        response = {
 | 
			
		||||
            'status': True,
 | 
			
		||||
| 
						 | 
				
			
			@ -537,5 +531,4 @@ class OrderConfirmationView(DetailView):
 | 
			
		|||
                  ' it is ready.'))
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return HttpResponse(json.dumps(response),
 | 
			
		||||
                            content_type="application/json")
 | 
			
		||||
        return JsonResponse(response)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										35
									
								
								hosting/migrations/0045_auto_20180701_2028.py
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										35
									
								
								hosting/migrations/0045_auto_20180701_2028.py
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,35 @@
 | 
			
		|||
# -*- coding: utf-8 -*-
 | 
			
		||||
# Generated by Django 1.9.4 on 2018-07-01 20:28
 | 
			
		||||
from __future__ import unicode_literals
 | 
			
		||||
 | 
			
		||||
from django.db import migrations, models
 | 
			
		||||
import django.db.models.deletion
 | 
			
		||||
import utils.mixins
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class Migration(migrations.Migration):
 | 
			
		||||
 | 
			
		||||
    dependencies = [
 | 
			
		||||
        ('datacenterlight', '0024_dclcalculatorpluginmodel_vm_templates_to_show'),
 | 
			
		||||
        ('hosting', '0044_hostingorder_vm_pricing'),
 | 
			
		||||
    ]
 | 
			
		||||
 | 
			
		||||
    operations = [
 | 
			
		||||
        migrations.CreateModel(
 | 
			
		||||
            name='OrderDetail',
 | 
			
		||||
            fields=[
 | 
			
		||||
                ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
 | 
			
		||||
                ('cores', models.IntegerField(default=0)),
 | 
			
		||||
                ('memory', models.IntegerField(default=0)),
 | 
			
		||||
                ('hdd_size', models.IntegerField(default=0)),
 | 
			
		||||
                ('ssd_size', models.IntegerField(default=0)),
 | 
			
		||||
                ('vm_template', models.ForeignKey(blank=True, default=None, null=True, on_delete=django.db.models.deletion.SET_NULL, to='datacenterlight.VMTemplate')),
 | 
			
		||||
            ],
 | 
			
		||||
            bases=(utils.mixins.AssignPermissionsMixin, models.Model),
 | 
			
		||||
        ),
 | 
			
		||||
        migrations.AddField(
 | 
			
		||||
            model_name='hostingorder',
 | 
			
		||||
            name='order_detail',
 | 
			
		||||
            field=models.ForeignKey(blank=True, default=None, null=True, on_delete=django.db.models.deletion.SET_NULL, to='hosting.OrderDetail'),
 | 
			
		||||
        ),
 | 
			
		||||
    ]
 | 
			
		||||
| 
						 | 
				
			
			@ -7,7 +7,7 @@ from django.utils import timezone
 | 
			
		|||
from django.utils.functional import cached_property
 | 
			
		||||
from Crypto.PublicKey import RSA
 | 
			
		||||
 | 
			
		||||
from datacenterlight.models import VMPricing
 | 
			
		||||
from datacenterlight.models import VMPricing, VMTemplate
 | 
			
		||||
from membership.models import StripeCustomer, CustomUser
 | 
			
		||||
from utils.models import BillingAddress
 | 
			
		||||
from utils.mixins import AssignPermissionsMixin
 | 
			
		||||
| 
						 | 
				
			
			@ -41,6 +41,23 @@ class HostingPlan(models.Model):
 | 
			
		|||
        return price
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class OrderDetail(AssignPermissionsMixin, models.Model):
 | 
			
		||||
    vm_template = models.ForeignKey(
 | 
			
		||||
        VMTemplate, blank=True, null=True, default=None,
 | 
			
		||||
        on_delete=models.SET_NULL
 | 
			
		||||
    )
 | 
			
		||||
    cores = models.IntegerField(default=0)
 | 
			
		||||
    memory = models.IntegerField(default=0)
 | 
			
		||||
    hdd_size = models.IntegerField(default=0)
 | 
			
		||||
    ssd_size = models.IntegerField(default=0)
 | 
			
		||||
 | 
			
		||||
    def __str__(self):
 | 
			
		||||
        return "%s - %s, %s cores, %s GB RAM, %s GB SSD" % (
 | 
			
		||||
            self.vm_template.name, self.vm_template.vm_type, self.cores,
 | 
			
		||||
            self.memory, self.ssd_size
 | 
			
		||||
        )
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class HostingOrder(AssignPermissionsMixin, models.Model):
 | 
			
		||||
    ORDER_APPROVED_STATUS = 'Approved'
 | 
			
		||||
    ORDER_DECLINED_STATUS = 'Declined'
 | 
			
		||||
| 
						 | 
				
			
			@ -56,6 +73,10 @@ class HostingOrder(AssignPermissionsMixin, models.Model):
 | 
			
		|||
    price = models.FloatField()
 | 
			
		||||
    subscription_id = models.CharField(max_length=100, null=True)
 | 
			
		||||
    vm_pricing = models.ForeignKey(VMPricing)
 | 
			
		||||
    order_detail = models.ForeignKey(
 | 
			
		||||
        OrderDetail, null=True, blank=True, default=None,
 | 
			
		||||
        on_delete=models.SET_NULL
 | 
			
		||||
    )
 | 
			
		||||
 | 
			
		||||
    permissions = ('view_hostingorder',)
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -72,7 +93,7 @@ class HostingOrder(AssignPermissionsMixin, models.Model):
 | 
			
		|||
        return self.ORDER_APPROVED_STATUS if self.approved else self.ORDER_DECLINED_STATUS
 | 
			
		||||
 | 
			
		||||
    @classmethod
 | 
			
		||||
    def create(cls, price=None, vm_id=None, customer=None,
 | 
			
		||||
    def create(cls, price=None, vm_id=0, customer=None,
 | 
			
		||||
               billing_address=None, vm_pricing=None):
 | 
			
		||||
        instance = cls.objects.create(
 | 
			
		||||
            price=price,
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,4 +1,3 @@
 | 
			
		|||
import json
 | 
			
		||||
import logging
 | 
			
		||||
import uuid
 | 
			
		||||
from datetime import datetime
 | 
			
		||||
| 
						 | 
				
			
			@ -12,7 +11,9 @@ from django.contrib.auth.tokens import default_token_generator
 | 
			
		|||
from django.core.exceptions import ValidationError
 | 
			
		||||
from django.core.files.base import ContentFile
 | 
			
		||||
from django.core.urlresolvers import reverse_lazy, reverse
 | 
			
		||||
from django.http import Http404, HttpResponseRedirect, HttpResponse
 | 
			
		||||
from django.http import (
 | 
			
		||||
    Http404, HttpResponseRedirect, HttpResponse, JsonResponse
 | 
			
		||||
)
 | 
			
		||||
from django.shortcuts import redirect, render
 | 
			
		||||
from django.utils.http import urlsafe_base64_decode
 | 
			
		||||
from django.utils.safestring import mark_safe
 | 
			
		||||
| 
						 | 
				
			
			@ -31,8 +32,7 @@ from stored_messages.models import Message
 | 
			
		|||
from stored_messages.settings import stored_messages_settings
 | 
			
		||||
 | 
			
		||||
from datacenterlight.models import VMTemplate, VMPricing
 | 
			
		||||
from datacenterlight.tasks import create_vm_task
 | 
			
		||||
from datacenterlight.utils import get_cms_integration
 | 
			
		||||
from datacenterlight.utils import create_vm, get_cms_integration
 | 
			
		||||
from membership.models import CustomUser, StripeCustomer
 | 
			
		||||
from opennebula_api.models import OpenNebulaManager
 | 
			
		||||
from opennebula_api.serializers import (
 | 
			
		||||
| 
						 | 
				
			
			@ -896,8 +896,8 @@ class OrdersHostingDetailView(LoginRequiredMixin, DetailView):
 | 
			
		|||
                      ' On close of this popup, you will be redirected back to'
 | 
			
		||||
                      ' the payment page.'))
 | 
			
		||||
            }
 | 
			
		||||
            return HttpResponse(json.dumps(response),
 | 
			
		||||
                                content_type="application/json")
 | 
			
		||||
            return JsonResponse(response)
 | 
			
		||||
 | 
			
		||||
        user = {
 | 
			
		||||
            'name': self.request.user.name,
 | 
			
		||||
            'email': self.request.user.email,
 | 
			
		||||
| 
						 | 
				
			
			@ -906,15 +906,12 @@ class OrdersHostingDetailView(LoginRequiredMixin, DetailView):
 | 
			
		|||
            'request_host': request.get_host(),
 | 
			
		||||
            'language': get_language(),
 | 
			
		||||
        }
 | 
			
		||||
        create_vm_task.delay(vm_template_id, user, specs, template,
 | 
			
		||||
                             stripe_customer_id, billing_address_data,
 | 
			
		||||
                             stripe_subscription_obj.id, card_details_dict)
 | 
			
		||||
 | 
			
		||||
        for session_var in ['specs', 'template', 'billing_address',
 | 
			
		||||
                            'billing_address_data',
 | 
			
		||||
                            'token', 'customer']:
 | 
			
		||||
            if session_var in request.session:
 | 
			
		||||
                del request.session[session_var]
 | 
			
		||||
        create_vm(
 | 
			
		||||
            billing_address_data, stripe_customer_id, specs,
 | 
			
		||||
            stripe_subscription_obj, card_details_dict, request,
 | 
			
		||||
            vm_template_id, template, user
 | 
			
		||||
        )
 | 
			
		||||
 | 
			
		||||
        response = {
 | 
			
		||||
            'status': True,
 | 
			
		||||
| 
						 | 
				
			
			@ -926,8 +923,7 @@ class OrdersHostingDetailView(LoginRequiredMixin, DetailView):
 | 
			
		|||
                  ' it is ready.'))
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return HttpResponse(json.dumps(response),
 | 
			
		||||
                            content_type="application/json")
 | 
			
		||||
        return JsonResponse(response)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class OrdersHostingListView(LoginRequiredMixin, ListView):
 | 
			
		||||
| 
						 | 
				
			
			@ -1138,10 +1134,7 @@ class VirtualMachineView(LoginRequiredMixin, View):
 | 
			
		|||
                for m in storage:
 | 
			
		||||
                    pass
 | 
			
		||||
                storage.used = True
 | 
			
		||||
                return HttpResponse(
 | 
			
		||||
                    json.dumps({'text': ugettext('Terminated')}),
 | 
			
		||||
                    content_type="application/json"
 | 
			
		||||
                )
 | 
			
		||||
                return JsonResponse({'text': ugettext('Terminated')})
 | 
			
		||||
            else:
 | 
			
		||||
                return redirect(reverse('hosting:virtual_machines'))
 | 
			
		||||
        elif self.request.is_ajax():
 | 
			
		||||
| 
						 | 
				
			
			@ -1273,10 +1266,7 @@ class VirtualMachineView(LoginRequiredMixin, View):
 | 
			
		|||
                ["%s=%s" % (k, v) for (k, v) in admin_email_body.items()]),
 | 
			
		||||
        }
 | 
			
		||||
        send_plain_email_task.delay(email_to_admin_data)
 | 
			
		||||
        return HttpResponse(
 | 
			
		||||
            json.dumps(response),
 | 
			
		||||
            content_type="application/json"
 | 
			
		||||
        )
 | 
			
		||||
        return JsonResponse(response)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class HostingBillListView(PermissionRequiredMixin, LoginRequiredMixin,
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -233,6 +233,12 @@ class StripeUtils(object):
 | 
			
		|||
        )
 | 
			
		||||
        return subscription_result
 | 
			
		||||
 | 
			
		||||
    @handleStripeError
 | 
			
		||||
    def set_subscription_metadata(self, subscription_id, metadata):
 | 
			
		||||
        subscription = stripe.Subscription.retrieve(subscription_id)
 | 
			
		||||
        subscription.metadata = metadata
 | 
			
		||||
        subscription.save()
 | 
			
		||||
 | 
			
		||||
    @handleStripeError
 | 
			
		||||
    def unsubscribe_customer(self, subscription_id):
 | 
			
		||||
        """
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue