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,7 +168,7 @@ 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')}, | ||||||
|  |  | ||||||
|  | @ -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