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 django.utils.translation import ugettext_lazy as _
 | 
				
			||||||
 | 
					
 | 
				
			||||||
from dynamicweb.celery import app
 | 
					from dynamicweb.celery import app
 | 
				
			||||||
from hosting.models import HostingOrder, HostingBill
 | 
					from hosting.models import HostingOrder
 | 
				
			||||||
from membership.models import StripeCustomer, CustomUser
 | 
					from membership.models import CustomUser
 | 
				
			||||||
from opennebula_api.models import OpenNebulaManager
 | 
					from opennebula_api.models import OpenNebulaManager
 | 
				
			||||||
from opennebula_api.serializers import VirtualMachineSerializer
 | 
					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.hosting_utils import get_all_public_keys, get_or_create_vm_detail
 | 
				
			||||||
from utils.mailer import BaseEmail
 | 
					from utils.mailer import BaseEmail
 | 
				
			||||||
from utils.models import BillingAddress
 | 
					from utils.stripe_utils import StripeUtils
 | 
				
			||||||
from .models import VMPricing
 | 
					from .models import VMPricing
 | 
				
			||||||
 | 
					
 | 
				
			||||||
logger = get_task_logger(__name__)
 | 
					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)
 | 
					@app.task(bind=True, max_retries=settings.CELERY_MAX_RETRIES)
 | 
				
			||||||
def create_vm_task(self, vm_template_id, user, specs, template,
 | 
					def create_vm_task(self, vm_template_id, user, specs, template, order_id):
 | 
				
			||||||
                   stripe_customer_id, billing_address_data,
 | 
					 | 
				
			||||||
                   stripe_subscription_id, cc_details):
 | 
					 | 
				
			||||||
    logger.debug(
 | 
					    logger.debug(
 | 
				
			||||||
        "Running create_vm_task on {}".format(current_task.request.hostname))
 | 
					        "Running create_vm_task on {}".format(current_task.request.hostname))
 | 
				
			||||||
    vm_id = None
 | 
					    vm_id = None
 | 
				
			||||||
    try:
 | 
					    try:
 | 
				
			||||||
        final_price = (specs.get('total_price') if 'total_price' in specs
 | 
					        final_price = (
 | 
				
			||||||
                       else specs.get('price'))
 | 
					            specs.get('total_price') if 'total_price' in specs
 | 
				
			||||||
        billing_address = BillingAddress(
 | 
					            else specs.get('price')
 | 
				
			||||||
            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()
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if 'pass' in user:
 | 
					        if 'pass' in user:
 | 
				
			||||||
            on_user = user.get('email')
 | 
					            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:
 | 
					        if vm_id is None:
 | 
				
			||||||
            raise Exception("Could not create VM")
 | 
					            raise Exception("Could not create VM")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        vm_pricing = VMPricing.get_vm_pricing_by_name(
 | 
					        # Update HostingOrder with the created vm_id
 | 
				
			||||||
            name=specs['pricing_name']
 | 
					        hosting_order = HostingOrder.objects.filter(id=order_id).first()
 | 
				
			||||||
        ) if 'pricing_name' in specs else VMPricing.get_default_pricing()
 | 
					        error_msg = None
 | 
				
			||||||
        # Create a Hosting Order
 | 
					
 | 
				
			||||||
        order = HostingOrder.create(
 | 
					        try:
 | 
				
			||||||
            price=final_price,
 | 
					            hosting_order.vm_id = vm_id
 | 
				
			||||||
            vm_id=vm_id,
 | 
					            hosting_order.save()
 | 
				
			||||||
            customer=customer,
 | 
					            logger.debug(
 | 
				
			||||||
            billing_address=billing_address,
 | 
					                "Updated hosting_order {} with vm_id={}".format(
 | 
				
			||||||
            vm_pricing=vm_pricing
 | 
					                    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
 | 
					        if result.get('error') is not None:
 | 
				
			||||||
        HostingBill.create(
 | 
					            emsg = "Could not update subscription metadata for {sub}".format(
 | 
				
			||||||
            customer=customer, billing_address=billing_address
 | 
					                sub=hosting_order.subscription_id
 | 
				
			||||||
        )
 | 
					            )
 | 
				
			||||||
 | 
					            logger.error(emsg)
 | 
				
			||||||
        # Create Billing Address for User if he does not have one
 | 
					            if error_msg:
 | 
				
			||||||
        if not customer.user.billing_addresses.count():
 | 
					                error_msg += ". " + emsg
 | 
				
			||||||
            billing_address_data.update({
 | 
					            else:
 | 
				
			||||||
                'user': customer.user.id
 | 
					                error_msg = emsg
 | 
				
			||||||
            })
 | 
					 | 
				
			||||||
            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()
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        vm = VirtualMachineSerializer(manager.get_vm(vm_id)).data
 | 
					        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'),
 | 
					            'template': template.get('name'),
 | 
				
			||||||
            'vm_name': vm.get('name'),
 | 
					            'vm_name': vm.get('name'),
 | 
				
			||||||
            'vm_id': vm['vm_id'],
 | 
					            '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:
 | 
					        if 'pricing_name' in specs:
 | 
				
			||||||
            context['pricing'] = str(VMPricing.get_vm_pricing_by_name(
 | 
					            context['pricing'] = str(VMPricing.get_vm_pricing_by_name(
 | 
				
			||||||
                name=specs['pricing_name']
 | 
					                name=specs['pricing_name']
 | 
				
			||||||
| 
						 | 
					@ -170,10 +168,10 @@ def create_vm_task(self, vm_template_id, user, specs, template,
 | 
				
			||||||
                'base_url': "{0}://{1}".format(user.get('request_scheme'),
 | 
					                'base_url': "{0}://{1}".format(user.get('request_scheme'),
 | 
				
			||||||
                                               user.get('request_host')),
 | 
					                                               user.get('request_host')),
 | 
				
			||||||
                'order_url': reverse('hosting:orders',
 | 
					                'order_url': reverse('hosting:orders',
 | 
				
			||||||
                                     kwargs={'pk': order.id}),
 | 
					                                     kwargs={'pk': order_id}),
 | 
				
			||||||
                'page_header': _(
 | 
					                'page_header': _(
 | 
				
			||||||
                    'Your New VM %(vm_name)s at Data Center Light') % {
 | 
					                    'Your New VM %(vm_name)s at Data Center Light') % {
 | 
				
			||||||
                                   'vm_name': vm.get('name')},
 | 
					                    'vm_name': vm.get('name')},
 | 
				
			||||||
                'vm_name': vm.get('name')
 | 
					                'vm_name': vm.get('name')
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            email_data = {
 | 
					            email_data = {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -12,9 +12,11 @@ from unittest import skipIf
 | 
				
			||||||
 | 
					
 | 
				
			||||||
from datacenterlight.models import VMTemplate
 | 
					from datacenterlight.models import VMTemplate
 | 
				
			||||||
from datacenterlight.tasks import create_vm_task
 | 
					from datacenterlight.tasks import create_vm_task
 | 
				
			||||||
 | 
					from hosting.models import HostingOrder
 | 
				
			||||||
from membership.models import StripeCustomer
 | 
					from membership.models import StripeCustomer
 | 
				
			||||||
from opennebula_api.serializers import VMTemplateSerializer
 | 
					from opennebula_api.serializers import VMTemplateSerializer
 | 
				
			||||||
from utils.hosting_utils import get_vm_price
 | 
					from utils.hosting_utils import get_vm_price
 | 
				
			||||||
 | 
					from utils.models import BillingAddress
 | 
				
			||||||
from utils.stripe_utils import StripeUtils
 | 
					from utils.stripe_utils import StripeUtils
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -81,11 +83,14 @@ class CeleryTaskTestCase(TestCase):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        stripe_customer = StripeCustomer.get_or_create(
 | 
					        stripe_customer = StripeCustomer.get_or_create(
 | 
				
			||||||
            email=self.customer_email,
 | 
					            email=self.customer_email,
 | 
				
			||||||
            token=self.token)
 | 
					            token=self.token
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
        card_details = self.stripe_utils.get_card_details(
 | 
					        card_details = self.stripe_utils.get_card_details(
 | 
				
			||||||
            stripe_customer.stripe_id,
 | 
					            stripe_customer.stripe_id,
 | 
				
			||||||
            self.token)
 | 
					            self.token
 | 
				
			||||||
        card_details_dict = card_details.get('response_object')
 | 
					        )
 | 
				
			||||||
 | 
					        card_details_dict = card_details.get('error')
 | 
				
			||||||
 | 
					        self.assertEquals(card_details_dict, None)
 | 
				
			||||||
        billing_address_data = {'cardholder_name': self.customer_name,
 | 
					        billing_address_data = {'cardholder_name': self.customer_name,
 | 
				
			||||||
                                'postal_code': '1231',
 | 
					                                'postal_code': '1231',
 | 
				
			||||||
                                'country': 'CH',
 | 
					                                'country': 'CH',
 | 
				
			||||||
| 
						 | 
					@ -122,10 +127,24 @@ class CeleryTaskTestCase(TestCase):
 | 
				
			||||||
            msg = subscription_result.get('error')
 | 
					            msg = subscription_result.get('error')
 | 
				
			||||||
            raise Exception("Creating subscription failed: {}".format(msg))
 | 
					            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(
 | 
					        async_task = create_vm_task.delay(
 | 
				
			||||||
            vm_template_id, self.user, specs, template_data,
 | 
					            vm_template_id, self.user, specs, template_data, order.id
 | 
				
			||||||
            stripe_customer.id, billing_address_data,
 | 
					 | 
				
			||||||
            stripe_subscription_obj.id, card_details_dict
 | 
					 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
        new_vm_id = 0
 | 
					        new_vm_id = 0
 | 
				
			||||||
        res = None
 | 
					        res = None
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,6 +1,12 @@
 | 
				
			||||||
from django.contrib.sites.models import Site
 | 
					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 .cms_models import CMSIntegration
 | 
				
			||||||
 | 
					from .models import VMPricing, VMTemplate
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def get_cms_integration(name):
 | 
					def get_cms_integration(name):
 | 
				
			||||||
| 
						 | 
					@ -12,3 +18,76 @@ def get_cms_integration(name):
 | 
				
			||||||
    except CMSIntegration.DoesNotExist:
 | 
					    except CMSIntegration.DoesNotExist:
 | 
				
			||||||
        cms_integration = CMSIntegration.objects.get(name=name, domain=None)
 | 
					        cms_integration = CMSIntegration.objects.get(name=name, domain=None)
 | 
				
			||||||
    return cms_integration
 | 
					    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
 | 
					import logging
 | 
				
			||||||
 | 
					
 | 
				
			||||||
from django import forms
 | 
					from django import forms
 | 
				
			||||||
| 
						 | 
					@ -7,13 +6,12 @@ from django.contrib import messages
 | 
				
			||||||
from django.contrib.auth import login, authenticate
 | 
					from django.contrib.auth import login, authenticate
 | 
				
			||||||
from django.core.exceptions import ValidationError
 | 
					from django.core.exceptions import ValidationError
 | 
				
			||||||
from django.core.urlresolvers import reverse
 | 
					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.shortcuts import render
 | 
				
			||||||
from django.utils.translation import get_language, ugettext_lazy as _
 | 
					from django.utils.translation import get_language, ugettext_lazy as _
 | 
				
			||||||
from django.views.decorators.cache import cache_control
 | 
					from django.views.decorators.cache import cache_control
 | 
				
			||||||
from django.views.generic import FormView, CreateView, DetailView
 | 
					from django.views.generic import FormView, CreateView, DetailView
 | 
				
			||||||
 | 
					
 | 
				
			||||||
from datacenterlight.tasks import create_vm_task
 | 
					 | 
				
			||||||
from hosting.forms import HostingUserLoginForm
 | 
					from hosting.forms import HostingUserLoginForm
 | 
				
			||||||
from hosting.models import HostingOrder
 | 
					from hosting.models import HostingOrder
 | 
				
			||||||
from membership.models import CustomUser, StripeCustomer
 | 
					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 utils.tasks import send_plain_email_task
 | 
				
			||||||
from .forms import ContactForm
 | 
					from .forms import ContactForm
 | 
				
			||||||
from .models import VMTemplate, VMPricing
 | 
					from .models import VMTemplate, VMPricing
 | 
				
			||||||
from .utils import get_cms_integration
 | 
					from .utils import get_cms_integration, create_vm
 | 
				
			||||||
 | 
					
 | 
				
			||||||
logger = logging.getLogger(__name__)
 | 
					logger = logging.getLogger(__name__)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -417,8 +415,8 @@ class OrderConfirmationView(DetailView):
 | 
				
			||||||
                      ' On close of this popup, you will be redirected back to'
 | 
					                      ' On close of this popup, you will be redirected back to'
 | 
				
			||||||
                      ' the payment page.'))
 | 
					                      ' the payment page.'))
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            return HttpResponse(json.dumps(response),
 | 
					            return JsonResponse(response)
 | 
				
			||||||
                                content_type="application/json")
 | 
					
 | 
				
			||||||
        card_details_dict = card_details.get('response_object')
 | 
					        card_details_dict = card_details.get('response_object')
 | 
				
			||||||
        cpu = specs.get('cpu')
 | 
					        cpu = specs.get('cpu')
 | 
				
			||||||
        memory = specs.get('memory')
 | 
					        memory = specs.get('memory')
 | 
				
			||||||
| 
						 | 
					@ -458,8 +456,7 @@ class OrderConfirmationView(DetailView):
 | 
				
			||||||
                      ' On close of this popup, you will be redirected back to'
 | 
					                      ' On close of this popup, you will be redirected back to'
 | 
				
			||||||
                      ' the payment page.'))
 | 
					                      ' the payment page.'))
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            return HttpResponse(json.dumps(response),
 | 
					            return JsonResponse(response)
 | 
				
			||||||
                                content_type="application/json")
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # Create user if the user is not logged in and if he is not already
 | 
					        # Create user if the user is not logged in and if he is not already
 | 
				
			||||||
        # registered
 | 
					        # registered
 | 
				
			||||||
| 
						 | 
					@ -514,14 +511,11 @@ class OrderConfirmationView(DetailView):
 | 
				
			||||||
            'language': get_language(),
 | 
					            'language': get_language(),
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        create_vm_task.delay(vm_template_id, user, specs, template,
 | 
					        create_vm(
 | 
				
			||||||
                             stripe_customer_id, billing_address_data,
 | 
					            billing_address_data, stripe_customer_id, specs,
 | 
				
			||||||
                             stripe_subscription_obj.id, card_details_dict)
 | 
					            stripe_subscription_obj, card_details_dict, request,
 | 
				
			||||||
        for session_var in ['specs', 'template', 'billing_address',
 | 
					            vm_template_id, template, user
 | 
				
			||||||
                            'billing_address_data',
 | 
					        )
 | 
				
			||||||
                            'token', 'customer', 'pricing_name']:
 | 
					 | 
				
			||||||
            if session_var in request.session:
 | 
					 | 
				
			||||||
                del request.session[session_var]
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        response = {
 | 
					        response = {
 | 
				
			||||||
            'status': True,
 | 
					            'status': True,
 | 
				
			||||||
| 
						 | 
					@ -537,5 +531,4 @@ class OrderConfirmationView(DetailView):
 | 
				
			||||||
                  ' it is ready.'))
 | 
					                  ' it is ready.'))
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return HttpResponse(json.dumps(response),
 | 
					        return JsonResponse(response)
 | 
				
			||||||
                            content_type="application/json")
 | 
					 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										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 django.utils.functional import cached_property
 | 
				
			||||||
from Crypto.PublicKey import RSA
 | 
					from Crypto.PublicKey import RSA
 | 
				
			||||||
 | 
					
 | 
				
			||||||
from datacenterlight.models import VMPricing
 | 
					from datacenterlight.models import VMPricing, VMTemplate
 | 
				
			||||||
from membership.models import StripeCustomer, CustomUser
 | 
					from membership.models import StripeCustomer, CustomUser
 | 
				
			||||||
from utils.models import BillingAddress
 | 
					from utils.models import BillingAddress
 | 
				
			||||||
from utils.mixins import AssignPermissionsMixin
 | 
					from utils.mixins import AssignPermissionsMixin
 | 
				
			||||||
| 
						 | 
					@ -41,6 +41,23 @@ class HostingPlan(models.Model):
 | 
				
			||||||
        return price
 | 
					        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):
 | 
					class HostingOrder(AssignPermissionsMixin, models.Model):
 | 
				
			||||||
    ORDER_APPROVED_STATUS = 'Approved'
 | 
					    ORDER_APPROVED_STATUS = 'Approved'
 | 
				
			||||||
    ORDER_DECLINED_STATUS = 'Declined'
 | 
					    ORDER_DECLINED_STATUS = 'Declined'
 | 
				
			||||||
| 
						 | 
					@ -56,6 +73,10 @@ class HostingOrder(AssignPermissionsMixin, models.Model):
 | 
				
			||||||
    price = models.FloatField()
 | 
					    price = models.FloatField()
 | 
				
			||||||
    subscription_id = models.CharField(max_length=100, null=True)
 | 
					    subscription_id = models.CharField(max_length=100, null=True)
 | 
				
			||||||
    vm_pricing = models.ForeignKey(VMPricing)
 | 
					    vm_pricing = models.ForeignKey(VMPricing)
 | 
				
			||||||
 | 
					    order_detail = models.ForeignKey(
 | 
				
			||||||
 | 
					        OrderDetail, null=True, blank=True, default=None,
 | 
				
			||||||
 | 
					        on_delete=models.SET_NULL
 | 
				
			||||||
 | 
					    )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    permissions = ('view_hostingorder',)
 | 
					    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
 | 
					        return self.ORDER_APPROVED_STATUS if self.approved else self.ORDER_DECLINED_STATUS
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @classmethod
 | 
					    @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):
 | 
					               billing_address=None, vm_pricing=None):
 | 
				
			||||||
        instance = cls.objects.create(
 | 
					        instance = cls.objects.create(
 | 
				
			||||||
            price=price,
 | 
					            price=price,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,4 +1,3 @@
 | 
				
			||||||
import json
 | 
					 | 
				
			||||||
import logging
 | 
					import logging
 | 
				
			||||||
import uuid
 | 
					import uuid
 | 
				
			||||||
from datetime import datetime
 | 
					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.exceptions import ValidationError
 | 
				
			||||||
from django.core.files.base import ContentFile
 | 
					from django.core.files.base import ContentFile
 | 
				
			||||||
from django.core.urlresolvers import reverse_lazy, reverse
 | 
					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.shortcuts import redirect, render
 | 
				
			||||||
from django.utils.http import urlsafe_base64_decode
 | 
					from django.utils.http import urlsafe_base64_decode
 | 
				
			||||||
from django.utils.safestring import mark_safe
 | 
					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 stored_messages.settings import stored_messages_settings
 | 
				
			||||||
 | 
					
 | 
				
			||||||
from datacenterlight.models import VMTemplate, VMPricing
 | 
					from datacenterlight.models import VMTemplate, VMPricing
 | 
				
			||||||
from datacenterlight.tasks import create_vm_task
 | 
					from datacenterlight.utils import create_vm, get_cms_integration
 | 
				
			||||||
from datacenterlight.utils import get_cms_integration
 | 
					 | 
				
			||||||
from membership.models import CustomUser, StripeCustomer
 | 
					from membership.models import CustomUser, StripeCustomer
 | 
				
			||||||
from opennebula_api.models import OpenNebulaManager
 | 
					from opennebula_api.models import OpenNebulaManager
 | 
				
			||||||
from opennebula_api.serializers import (
 | 
					from opennebula_api.serializers import (
 | 
				
			||||||
| 
						 | 
					@ -896,8 +896,8 @@ class OrdersHostingDetailView(LoginRequiredMixin, DetailView):
 | 
				
			||||||
                      ' On close of this popup, you will be redirected back to'
 | 
					                      ' On close of this popup, you will be redirected back to'
 | 
				
			||||||
                      ' the payment page.'))
 | 
					                      ' the payment page.'))
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            return HttpResponse(json.dumps(response),
 | 
					            return JsonResponse(response)
 | 
				
			||||||
                                content_type="application/json")
 | 
					
 | 
				
			||||||
        user = {
 | 
					        user = {
 | 
				
			||||||
            'name': self.request.user.name,
 | 
					            'name': self.request.user.name,
 | 
				
			||||||
            'email': self.request.user.email,
 | 
					            'email': self.request.user.email,
 | 
				
			||||||
| 
						 | 
					@ -906,15 +906,12 @@ class OrdersHostingDetailView(LoginRequiredMixin, DetailView):
 | 
				
			||||||
            'request_host': request.get_host(),
 | 
					            'request_host': request.get_host(),
 | 
				
			||||||
            'language': get_language(),
 | 
					            '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',
 | 
					        create_vm(
 | 
				
			||||||
                            'billing_address_data',
 | 
					            billing_address_data, stripe_customer_id, specs,
 | 
				
			||||||
                            'token', 'customer']:
 | 
					            stripe_subscription_obj, card_details_dict, request,
 | 
				
			||||||
            if session_var in request.session:
 | 
					            vm_template_id, template, user
 | 
				
			||||||
                del request.session[session_var]
 | 
					        )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        response = {
 | 
					        response = {
 | 
				
			||||||
            'status': True,
 | 
					            'status': True,
 | 
				
			||||||
| 
						 | 
					@ -926,8 +923,7 @@ class OrdersHostingDetailView(LoginRequiredMixin, DetailView):
 | 
				
			||||||
                  ' it is ready.'))
 | 
					                  ' it is ready.'))
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return HttpResponse(json.dumps(response),
 | 
					        return JsonResponse(response)
 | 
				
			||||||
                            content_type="application/json")
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class OrdersHostingListView(LoginRequiredMixin, ListView):
 | 
					class OrdersHostingListView(LoginRequiredMixin, ListView):
 | 
				
			||||||
| 
						 | 
					@ -1138,10 +1134,7 @@ class VirtualMachineView(LoginRequiredMixin, View):
 | 
				
			||||||
                for m in storage:
 | 
					                for m in storage:
 | 
				
			||||||
                    pass
 | 
					                    pass
 | 
				
			||||||
                storage.used = True
 | 
					                storage.used = True
 | 
				
			||||||
                return HttpResponse(
 | 
					                return JsonResponse({'text': ugettext('Terminated')})
 | 
				
			||||||
                    json.dumps({'text': ugettext('Terminated')}),
 | 
					 | 
				
			||||||
                    content_type="application/json"
 | 
					 | 
				
			||||||
                )
 | 
					 | 
				
			||||||
            else:
 | 
					            else:
 | 
				
			||||||
                return redirect(reverse('hosting:virtual_machines'))
 | 
					                return redirect(reverse('hosting:virtual_machines'))
 | 
				
			||||||
        elif self.request.is_ajax():
 | 
					        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()]),
 | 
					                ["%s=%s" % (k, v) for (k, v) in admin_email_body.items()]),
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        send_plain_email_task.delay(email_to_admin_data)
 | 
					        send_plain_email_task.delay(email_to_admin_data)
 | 
				
			||||||
        return HttpResponse(
 | 
					        return JsonResponse(response)
 | 
				
			||||||
            json.dumps(response),
 | 
					 | 
				
			||||||
            content_type="application/json"
 | 
					 | 
				
			||||||
        )
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class HostingBillListView(PermissionRequiredMixin, LoginRequiredMixin,
 | 
					class HostingBillListView(PermissionRequiredMixin, LoginRequiredMixin,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -233,6 +233,12 @@ class StripeUtils(object):
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
        return subscription_result
 | 
					        return subscription_result
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @handleStripeError
 | 
				
			||||||
 | 
					    def set_subscription_metadata(self, subscription_id, metadata):
 | 
				
			||||||
 | 
					        subscription = stripe.Subscription.retrieve(subscription_id)
 | 
				
			||||||
 | 
					        subscription.metadata = metadata
 | 
				
			||||||
 | 
					        subscription.save()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @handleStripeError
 | 
					    @handleStripeError
 | 
				
			||||||
    def unsubscribe_customer(self, subscription_id):
 | 
					    def unsubscribe_customer(self, subscription_id):
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue