Merge pull request #361 from pcoder/new_flow_enhancement
New flow enhancement
This commit is contained in:
		
				commit
				
					
						0ad3e0d7c7
					
				
			
		
					 5 changed files with 203 additions and 151 deletions
				
			
		| 
						 | 
					@ -1,7 +1,8 @@
 | 
				
			||||||
{% extends "hosting/base_short.html" %}
 | 
					{% extends "hosting/base_short.html" %}
 | 
				
			||||||
{% load staticfiles bootstrap3 %}
 | 
					{% load staticfiles bootstrap3 %}
 | 
				
			||||||
{% load i18n %}
 | 
					{% load i18n %}
 | 
				
			||||||
{% block content %} 
 | 
					{% load custom_tags %}
 | 
				
			||||||
 | 
					{% block content %}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
<div class="order-detail-container">
 | 
					<div class="order-detail-container">
 | 
				
			||||||
   {% if messages %}
 | 
					   {% if messages %}
 | 
				
			||||||
| 
						 | 
					@ -19,37 +20,38 @@
 | 
				
			||||||
    {% if not error %}
 | 
					    {% if not error %}
 | 
				
			||||||
    <div class="row">  
 | 
					    <div class="row">  
 | 
				
			||||||
        <div class="col-xs-12 col-md-8 col-md-offset-2">
 | 
					        <div class="col-xs-12 col-md-8 col-md-offset-2">
 | 
				
			||||||
    		<div class="invoice-title">
 | 
					            <div class="invoice-title">
 | 
				
			||||||
    			<h2>{% trans "Confirm Order"%}</h2><h3 class="pull-right">{% trans "Order #"%} {{order.id}}</h3>
 | 
					                <h2>{% trans "Confirm Order"%}</h2>
 | 
				
			||||||
    		</div>
 | 
					            </div>
 | 
				
			||||||
    		<hr>
 | 
					            <hr>
 | 
				
			||||||
    		<div class="row">
 | 
					            <div class="row">
 | 
				
			||||||
    			<div class="col-xs-6">
 | 
					                <div class="col-xs-6">
 | 
				
			||||||
    				<address>
 | 
					                    <address>
 | 
				
			||||||
                    <h3><b>{% trans "Billed To:"%}</b></h3>
 | 
					                    <h3><b>{% trans "Billed To:"%}</b></h3>
 | 
				
			||||||
    					{{user.name}}<br>
 | 
					                    {% with request.session.billing_address_data as billing_address %}
 | 
				
			||||||
                        {{order.billing_address.street_address}},{{order.billing_address.postal_code}}<br>
 | 
					                        {{request.session.user.name}}<br> {{billing_address|get_value_from_dict:'street_address'}}, {{billing_address|get_value_from_dict:'postal_code'}}<br>
 | 
				
			||||||
                        {{order.billing_address.city}}, {{order.billing_address.country}}.
 | 
					                        {{billing_address|get_value_from_dict:'city'}}, {{billing_address|get_value_from_dict:'country'}}.
 | 
				
			||||||
    				</address>
 | 
					                    {% endwith %}
 | 
				
			||||||
    			</div>
 | 
					                    </address>
 | 
				
			||||||
 | 
					                </div>
 | 
				
			||||||
                <div class="col-xs-6 text-right">
 | 
					                <div class="col-xs-6 text-right">
 | 
				
			||||||
                    <address>
 | 
					                    <address>
 | 
				
			||||||
                        <strong>{% trans "Date"%}:</strong><br>
 | 
					                        <strong>{% trans "Date"%}:</strong><br>
 | 
				
			||||||
                        {{order.created_at}}<br><br>
 | 
					                        <span id="order-created_at">{% now "Y-m-d H:i" %}</span><br><br>
 | 
				
			||||||
                    </address>
 | 
					                    </address>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                </div>
 | 
					                </div>
 | 
				
			||||||
    		</div>
 | 
					            </div>
 | 
				
			||||||
    		<div class="row">
 | 
					            <div class="row">
 | 
				
			||||||
    			<div class="col-xs-6">
 | 
					                <div class="col-xs-6">
 | 
				
			||||||
    				<address>
 | 
					                    <address>
 | 
				
			||||||
    					<strong>{% trans "Payment Method:"%}</strong><br>
 | 
					                        <strong>{% trans "Payment Method:"%}</strong><br>
 | 
				
			||||||
    					{{order.cc_brand}} ending **** {{order.last4}}<br>
 | 
					                            {{cc_brand}} ending **** {{cc_last4}}<br>
 | 
				
			||||||
    					{{user.email}}
 | 
					                            {{request.session.user.email}}
 | 
				
			||||||
    				</address>
 | 
					                    </address>
 | 
				
			||||||
    			</div>
 | 
					                </div>
 | 
				
			||||||
    		</div>
 | 
					            </div>
 | 
				
			||||||
    	</div>
 | 
					        </div>
 | 
				
			||||||
    </div>
 | 
					    </div>
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    <div class="row">
 | 
					    <div class="row">
 | 
				
			||||||
| 
						 | 
					@ -57,23 +59,37 @@
 | 
				
			||||||
            <h3><b>{% trans "Order summary"%}</b></h3>
 | 
					            <h3><b>{% trans "Order summary"%}</b></h3>
 | 
				
			||||||
            <hr>
 | 
					            <hr>
 | 
				
			||||||
            <div class="content">
 | 
					            <div class="content">
 | 
				
			||||||
                <p><b>{% trans "Cores"%}</b> <span class="pull-right">{{vm.cores}}</span></p>
 | 
					                {% with request.session.specs as vm %}
 | 
				
			||||||
                <hr>
 | 
					                    <p><b>{% trans "Cores"%}</b> <span class="pull-right">{{vm.cpu}}</span></p>
 | 
				
			||||||
                <p><b>{% trans "Memory"%}</b> <span class="pull-right">{{vm.memory}} GB</span></p>
 | 
					                    <hr>
 | 
				
			||||||
                <hr>
 | 
					                    <p><b>{% trans "Memory"%}</b> <span class="pull-right">{{vm.memory}} GB</span></p>
 | 
				
			||||||
                <p><b>{% trans "Disk space"%}</b> <span class="pull-right">{{vm.disk_size}} GB</span></p>
 | 
					                    <hr>
 | 
				
			||||||
                <hr>
 | 
					                    <p><b>{% trans "Disk space"%}</b> <span class="pull-right">{{vm.disk_size}} GB</span></p>
 | 
				
			||||||
                <h4>{% trans "Total"%}<p class="pull-right"><b>{{vm.price}} CHF</b></p></h4>
 | 
					                    <hr>
 | 
				
			||||||
 | 
					                    <h4>{% trans "Total"%}<p class="pull-right"><b>{{vm.price}} CHF</b></p></h4>
 | 
				
			||||||
 | 
					                {% endwith %}
 | 
				
			||||||
            </div>
 | 
					            </div>
 | 
				
			||||||
            <br/>
 | 
					            <br/>
 | 
				
			||||||
            {% url 'datacenterlight:payment' as payment_url %}
 | 
					            <form method="post">
 | 
				
			||||||
            {% if payment_url in request.META.HTTP_REFERER  %}
 | 
					            {% csrf_token %}
 | 
				
			||||||
            <div class=" content pull-right">
 | 
					            <div class=" content pull-right">
 | 
				
			||||||
                <a href="{{next_url}}" ><button class="btn btn-info">{% trans "Finish Configuration"%}</button></a>
 | 
					                <a href="{{next_url}}" ><button class="btn btn-info">{% trans "Place order"%}</button></a>
 | 
				
			||||||
            </div>
 | 
					            </div>
 | 
				
			||||||
            {% endif %}
 | 
					            </form>
 | 
				
			||||||
        </div>
 | 
					        </div>
 | 
				
			||||||
    </div>
 | 
					    </div>
 | 
				
			||||||
    {% endif %}
 | 
					    {% endif %}
 | 
				
			||||||
</div>
 | 
					</div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
					<script type="text/javascript"> 
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    window.onload = function () {
 | 
				
			||||||
 | 
					            var locale_date = moment.utc(document.getElementById("order-created_at").textContent,'YYYY-MM-DD HH:mm').toDate();
 | 
				
			||||||
 | 
					            locale_date =  moment(locale_date).format("YYYY-MM-DD h:mm:ss a");
 | 
				
			||||||
 | 
					            document.getElementById('order-created_at').innerHTML = locale_date;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					</script>
 | 
				
			||||||
{%endblock%}
 | 
					{%endblock%}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -21,4 +21,14 @@ def change_lang(context, lang=None, *args, **kwargs):
 | 
				
			||||||
        activate(cur_language)
 | 
					        activate(cur_language)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return "%s" % url
 | 
					    return "%s" % url
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					@register.filter('get_value_from_dict')
 | 
				
			||||||
 | 
					def get_value_from_dict(dict_data, key):
 | 
				
			||||||
 | 
					    """
 | 
				
			||||||
 | 
					    usage example {{ your_dict|get_value_from_dict:your_key }}
 | 
				
			||||||
 | 
					    """
 | 
				
			||||||
 | 
					    if key:
 | 
				
			||||||
 | 
					        return dict_data.get(key)
 | 
				
			||||||
 | 
					    else :
 | 
				
			||||||
 | 
					        return ""
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -9,7 +9,7 @@ urlpatterns = [
 | 
				
			||||||
    url(r'^/landing/?$', LandingProgramView.as_view(), name='landing'),
 | 
					    url(r'^/landing/?$', LandingProgramView.as_view(), name='landing'),
 | 
				
			||||||
    url(r'^/pricing/?$', PricingView.as_view(), name='pricing'),
 | 
					    url(r'^/pricing/?$', PricingView.as_view(), name='pricing'),
 | 
				
			||||||
    url(r'^/payment/?$', PaymentOrderView.as_view(), name='payment'),
 | 
					    url(r'^/payment/?$', PaymentOrderView.as_view(), name='payment'),
 | 
				
			||||||
    url(r'^/order-confirmation/(?P<pk>\d+)/?$', OrderConfirmationView.as_view(), name='order_confirmation'),
 | 
					    url(r'^/order-confirmation/?$', OrderConfirmationView.as_view(), name='order_confirmation'),
 | 
				
			||||||
    url(r'^/order-success/?$', SuccessView.as_view(), name='order_success'),
 | 
					    url(r'^/order-success/?$', SuccessView.as_view(), name='order_success'),
 | 
				
			||||||
    url(r'^/beta_access?$', BetaAccessView.as_view(), name='beta_access'),
 | 
					    url(r'^/beta_access?$', BetaAccessView.as_view(), name='beta_access'),
 | 
				
			||||||
]
 | 
					]
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -13,6 +13,7 @@ from django.core.exceptions import ValidationError
 | 
				
			||||||
from django.views.decorators.cache import cache_control
 | 
					from django.views.decorators.cache import cache_control
 | 
				
			||||||
from django.conf import settings
 | 
					from django.conf import settings
 | 
				
			||||||
from utils.forms import BillingAddressForm, UserBillingAddressForm
 | 
					from utils.forms import BillingAddressForm, UserBillingAddressForm
 | 
				
			||||||
 | 
					from utils.models import BillingAddress
 | 
				
			||||||
from membership.models import StripeCustomer
 | 
					from membership.models import StripeCustomer
 | 
				
			||||||
from hosting.models import HostingOrder, HostingBill
 | 
					from hosting.models import HostingOrder, HostingBill
 | 
				
			||||||
from utils.stripe_utils import StripeUtils
 | 
					from utils.stripe_utils import StripeUtils
 | 
				
			||||||
| 
						 | 
					@ -31,9 +32,14 @@ class SuccessView(TemplateView):
 | 
				
			||||||
    def get(self, request, *args, **kwargs):
 | 
					    def get(self, request, *args, **kwargs):
 | 
				
			||||||
        if 'specs' not in request.session or 'user' not in request.session:
 | 
					        if 'specs' not in request.session or 'user' not in request.session:
 | 
				
			||||||
            return HttpResponseRedirect(reverse('datacenterlight:index'))
 | 
					            return HttpResponseRedirect(reverse('datacenterlight:index'))
 | 
				
			||||||
        else :
 | 
					        elif 'token' not in request.session:
 | 
				
			||||||
            del request.session['specs']
 | 
					            return HttpResponseRedirect(reverse('datacenterlight:payment'))            
 | 
				
			||||||
            del request.session['user']
 | 
					        elif 'order_confirmation' not in request.session:
 | 
				
			||||||
 | 
					            return HttpResponseRedirect(reverse('datacenterlight:order_confirmation'))            
 | 
				
			||||||
 | 
					        else:
 | 
				
			||||||
 | 
					            for session_var in ['specs', 'user', 'template', 'billing_address', 'billing_address_data', 'token', 'customer']:
 | 
				
			||||||
 | 
					                if session_var in request.session:
 | 
				
			||||||
 | 
					                    del request.session[session_var]
 | 
				
			||||||
        return render(request, self.template_name)
 | 
					        return render(request, self.template_name)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class PricingView(TemplateView):
 | 
					class PricingView(TemplateView):
 | 
				
			||||||
| 
						 | 
					@ -322,13 +328,9 @@ class PaymentOrderView(FormView):
 | 
				
			||||||
        if form.is_valid():
 | 
					        if form.is_valid():
 | 
				
			||||||
            # Get billing address data
 | 
					            # Get billing address data
 | 
				
			||||||
            billing_address_data = form.cleaned_data
 | 
					            billing_address_data = form.cleaned_data
 | 
				
			||||||
            context = self.get_context_data()
 | 
					 | 
				
			||||||
            template = request.session.get('template')
 | 
					 | 
				
			||||||
            specs = request.session.get('specs')
 | 
					 | 
				
			||||||
            user = request.session.get('user')
 | 
					 | 
				
			||||||
            vm_template_id = template.get('id', 1)
 | 
					 | 
				
			||||||
            final_price = specs.get('price')
 | 
					 | 
				
			||||||
            token = form.cleaned_data.get('token')
 | 
					            token = form.cleaned_data.get('token')
 | 
				
			||||||
 | 
					            user = request.session.get('user')
 | 
				
			||||||
 | 
					            
 | 
				
			||||||
            try:
 | 
					            try:
 | 
				
			||||||
                custom_user = CustomUser.objects.get(email=user.get('email'))
 | 
					                custom_user = CustomUser.objects.get(email=user.get('email'))
 | 
				
			||||||
            except CustomUser.DoesNotExist:
 | 
					            except CustomUser.DoesNotExist:
 | 
				
			||||||
| 
						 | 
					@ -340,7 +342,6 @@ class PaymentOrderView(FormView):
 | 
				
			||||||
                                    app='dcl', 
 | 
					                                    app='dcl', 
 | 
				
			||||||
                                    base_url=None, send_email=False)
 | 
					                                    base_url=None, send_email=False)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
            # Get or create stripe customer
 | 
					            # Get or create stripe customer
 | 
				
			||||||
            customer = StripeCustomer.get_or_create(email=user.get('email'),
 | 
					            customer = StripeCustomer.get_or_create(email=user.get('email'),
 | 
				
			||||||
                                                    token=token)
 | 
					                                                    token=token)
 | 
				
			||||||
| 
						 | 
					@ -350,115 +351,130 @@ class PaymentOrderView(FormView):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            # Create Billing Address
 | 
					            # Create Billing Address
 | 
				
			||||||
            billing_address = form.save()
 | 
					            billing_address = form.save()
 | 
				
			||||||
 | 
					            request.session['billing_address_data'] = billing_address_data
 | 
				
			||||||
            # Make stripe charge to a customer
 | 
					            request.session['billing_address'] = billing_address.id
 | 
				
			||||||
            stripe_utils = StripeUtils()
 | 
					            request.session['token'] = token
 | 
				
			||||||
            charge_response = stripe_utils.make_charge(amount=final_price,
 | 
					            request.session['customer'] = customer.id
 | 
				
			||||||
                                                       customer=customer.stripe_id)
 | 
					            return HttpResponseRedirect(reverse('datacenterlight:order_confirmation'))
 | 
				
			||||||
            charge = charge_response.get('response_object')
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            # Check if the payment was approved
 | 
					 | 
				
			||||||
            if not charge:
 | 
					 | 
				
			||||||
                context.update({
 | 
					 | 
				
			||||||
                    'paymentError': charge_response.get('error'),
 | 
					 | 
				
			||||||
                    'form': form
 | 
					 | 
				
			||||||
                })
 | 
					 | 
				
			||||||
                return render(request, self.template_name, context)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            charge = charge_response.get('response_object')
 | 
					 | 
				
			||||||
        
 | 
					 | 
				
			||||||
            # Create OpenNebulaManager
 | 
					 | 
				
			||||||
            manager = OpenNebulaManager(email=settings.OPENNEBULA_USERNAME,
 | 
					 | 
				
			||||||
                                        password=settings.OPENNEBULA_PASSWORD)
 | 
					 | 
				
			||||||
            
 | 
					 | 
				
			||||||
            # Create a vm using logged user
 | 
					 | 
				
			||||||
            vm_id = manager.create_vm(
 | 
					 | 
				
			||||||
                template_id=vm_template_id,
 | 
					 | 
				
			||||||
                specs=specs,
 | 
					 | 
				
			||||||
                vm_name="{email}-{template_name}-{date}".format(
 | 
					 | 
				
			||||||
                       email=user.get('email'), 
 | 
					 | 
				
			||||||
                       template_name=template.get('name'),
 | 
					 | 
				
			||||||
                       date=int(datetime.now().strftime("%s")))
 | 
					 | 
				
			||||||
            )
 | 
					 | 
				
			||||||
            
 | 
					 | 
				
			||||||
            # Create a Hosting Order
 | 
					 | 
				
			||||||
            order = HostingOrder.create(
 | 
					 | 
				
			||||||
                price=final_price,
 | 
					 | 
				
			||||||
                vm_id=vm_id,
 | 
					 | 
				
			||||||
                customer=customer,
 | 
					 | 
				
			||||||
                billing_address=billing_address
 | 
					 | 
				
			||||||
            )
 | 
					 | 
				
			||||||
            
 | 
					 | 
				
			||||||
            # Create a Hosting Bill
 | 
					 | 
				
			||||||
            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 an order with a stripe payment
 | 
					 | 
				
			||||||
            order.set_stripe_charge(charge)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            # If the Stripe payment was successed, set order status approved
 | 
					 | 
				
			||||||
            order.set_approved()
 | 
					 | 
				
			||||||
            
 | 
					 | 
				
			||||||
            vm = VirtualMachineSerializer(manager.get_vm(vm_id)).data
 | 
					 | 
				
			||||||
            
 | 
					 | 
				
			||||||
            context = {
 | 
					 | 
				
			||||||
                'name': user.get('name'),
 | 
					 | 
				
			||||||
                'email': user.get('email'),
 | 
					 | 
				
			||||||
                'cores': specs.get('cpu'),
 | 
					 | 
				
			||||||
                'memory': specs.get('memory'),
 | 
					 | 
				
			||||||
                'storage': specs.get('disk_size'),
 | 
					 | 
				
			||||||
                'price': specs.get('price'),
 | 
					 | 
				
			||||||
                'template': template.get('name'),
 | 
					 | 
				
			||||||
                'vm.name': vm['name'],
 | 
					 | 
				
			||||||
                'vm.id': vm['vm_id'],
 | 
					 | 
				
			||||||
                'order.id': order.id
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            email_data = {
 | 
					 | 
				
			||||||
                'subject': "Data Center Light Order from %s" % context['email'],
 | 
					 | 
				
			||||||
                'from_email': '(Data Center Light) Data Center Light Support <support@datacenterlight.ch>',
 | 
					 | 
				
			||||||
                'to': ['info@ungleich.ch'],
 | 
					 | 
				
			||||||
                'body': "\n".join(["%s=%s" % (k, v) for (k, v) in context.items()]),
 | 
					 | 
				
			||||||
                'reply_to': [context['email']],
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            email = EmailMessage(**email_data)
 | 
					 | 
				
			||||||
            email.send()
 | 
					 | 
				
			||||||
            return HttpResponseRedirect(reverse('datacenterlight:order_confirmation', kwargs={'pk': order.id}))
 | 
					 | 
				
			||||||
        else:
 | 
					        else:
 | 
				
			||||||
            return self.form_invalid(form)
 | 
					            return self.form_invalid(form)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class OrderConfirmationView(DetailView):
 | 
					class OrderConfirmationView(DetailView):
 | 
				
			||||||
    template_name = "datacenterlight/order_detail.html"
 | 
					    template_name = "datacenterlight/order_detail.html"
 | 
				
			||||||
 | 
					    payment_template_name = 'hosting/payment.html'
 | 
				
			||||||
    context_object_name = "order"
 | 
					    context_object_name = "order"
 | 
				
			||||||
    model = HostingOrder
 | 
					    model = HostingOrder
 | 
				
			||||||
    def get_context_data(self, **kwargs):
 | 
					    
 | 
				
			||||||
        # Get context
 | 
					    @cache_control(no_cache=True, must_revalidate=True, no_store=True)
 | 
				
			||||||
        context = super(DetailView, self).get_context_data(**kwargs)
 | 
					    def get(self, request, *args, **kwargs):
 | 
				
			||||||
        obj = self.get_object()
 | 
					        if 'specs' not in request.session or 'user' not in request.session:
 | 
				
			||||||
 | 
					            return HttpResponseRedirect(reverse('datacenterlight:index'))
 | 
				
			||||||
 | 
					        if 'token' not in request.session:
 | 
				
			||||||
 | 
					            return HttpResponseRedirect(reverse('datacenterlight:payment'))
 | 
				
			||||||
 | 
					        stripe_customer_id = request.session.get('customer')
 | 
				
			||||||
 | 
					        customer = StripeCustomer.objects.filter(id=stripe_customer_id).first()
 | 
				
			||||||
 | 
					        stripe_utils = StripeUtils()
 | 
				
			||||||
 | 
					        card_details = stripe_utils.get_card_details(customer.stripe_id, request.session.get('token'))
 | 
				
			||||||
 | 
					        context = {
 | 
				
			||||||
 | 
					            'cc_last4' : card_details.get('response_object').get('last4'),
 | 
				
			||||||
 | 
					            'cc_brand' : card_details.get('response_object').get('brand')
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        return render(request, self.template_name, context)
 | 
				
			||||||
 | 
					   
 | 
				
			||||||
 | 
					    def post(self, request, *args, **kwargs):
 | 
				
			||||||
 | 
					        template = request.session.get('template')
 | 
				
			||||||
 | 
					        specs = request.session.get('specs')
 | 
				
			||||||
 | 
					        user = request.session.get('user')
 | 
				
			||||||
 | 
					        stripe_customer_id = request.session.get('customer')
 | 
				
			||||||
 | 
					        customer = StripeCustomer.objects.filter(id=stripe_customer_id).first()
 | 
				
			||||||
 | 
					        billing_address_data = request.session.get('billing_address_data')
 | 
				
			||||||
 | 
					        billing_address_id = request.session.get('billing_address')
 | 
				
			||||||
 | 
					        billing_address = BillingAddress.objects.filter(id=billing_address_id).first()
 | 
				
			||||||
 | 
					        token = request.session.get('token')
 | 
				
			||||||
 | 
					        vm_template_id = template.get('id', 1)
 | 
				
			||||||
 | 
					        final_price = specs.get('price')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        # Make stripe charge to a customer
 | 
				
			||||||
 | 
					        stripe_utils = StripeUtils()
 | 
				
			||||||
 | 
					        charge_response = stripe_utils.make_charge(amount=final_price,
 | 
				
			||||||
 | 
					                                                   customer=customer.stripe_id)
 | 
				
			||||||
 | 
					        charge = charge_response.get('response_object')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        # Check if the payment was approved
 | 
				
			||||||
 | 
					        if not charge:
 | 
				
			||||||
 | 
					            context.update({
 | 
				
			||||||
 | 
					                'paymentError': charge_response.get('error')
 | 
				
			||||||
 | 
					                # TODO add logic in payment form to autofill data 
 | 
				
			||||||
 | 
					                #'form': form
 | 
				
			||||||
 | 
					            })
 | 
				
			||||||
 | 
					            return render(request, self.payment_template_name, context)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        charge = charge_response.get('response_object')
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        # Create OpenNebulaManager
 | 
				
			||||||
        manager = OpenNebulaManager(email=settings.OPENNEBULA_USERNAME,
 | 
					        manager = OpenNebulaManager(email=settings.OPENNEBULA_USERNAME,
 | 
				
			||||||
                                    password=settings.OPENNEBULA_PASSWORD)
 | 
					                                    password=settings.OPENNEBULA_PASSWORD)
 | 
				
			||||||
        try:
 | 
					        
 | 
				
			||||||
            vm = manager.get_vm(obj.vm_id)
 | 
					        # Create a vm using oneadmin, also specify the name
 | 
				
			||||||
            context['vm'] = VirtualMachineSerializer(vm).data
 | 
					        vm_id = manager.create_vm(
 | 
				
			||||||
            context['next_url'] = reverse('datacenterlight:order_success')
 | 
					            template_id=vm_template_id,
 | 
				
			||||||
        except WrongIdError:
 | 
					            specs=specs,
 | 
				
			||||||
            messages.error(self.request,
 | 
					            vm_name="{email}-{template_name}-{date}".format(
 | 
				
			||||||
                           'The VM you are looking for is unavailable at the moment. \
 | 
					                   email=user.get('email'), 
 | 
				
			||||||
                            Please contact Data Center Light support.'
 | 
					                   template_name=template.get('name'),
 | 
				
			||||||
                           )
 | 
					                   date=int(datetime.now().strftime("%s")))
 | 
				
			||||||
            self.kwargs['error'] = 'WrongIdError'
 | 
					        )
 | 
				
			||||||
            context['error'] = 'WrongIdError'
 | 
					        
 | 
				
			||||||
        except ConnectionRefusedError:
 | 
					        # Create a Hosting Order
 | 
				
			||||||
            messages.error(self.request,
 | 
					        order = HostingOrder.create(
 | 
				
			||||||
                           'In order to create a VM, you need to create/upload your SSH KEY first.'
 | 
					            price=final_price,
 | 
				
			||||||
                           )
 | 
					            vm_id=vm_id,
 | 
				
			||||||
        return context
 | 
					            customer=customer,
 | 
				
			||||||
 | 
					            billing_address=billing_address
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        # Create a Hosting Bill
 | 
				
			||||||
 | 
					        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 an order with a stripe payment
 | 
				
			||||||
 | 
					        order.set_stripe_charge(charge)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        # If the Stripe payment was successed, set order status approved
 | 
				
			||||||
 | 
					        order.set_approved()
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        vm = VirtualMachineSerializer(manager.get_vm(vm_id)).data
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        context = {
 | 
				
			||||||
 | 
					            'name': user.get('name'),
 | 
				
			||||||
 | 
					            'email': user.get('email'),
 | 
				
			||||||
 | 
					            'cores': specs.get('cpu'),
 | 
				
			||||||
 | 
					            'memory': specs.get('memory'),
 | 
				
			||||||
 | 
					            'storage': specs.get('disk_size'),
 | 
				
			||||||
 | 
					            'price': specs.get('price'),
 | 
				
			||||||
 | 
					            'template': template.get('name'),
 | 
				
			||||||
 | 
					            'vm.name': vm['name'],
 | 
				
			||||||
 | 
					            'vm.id': vm['vm_id'],
 | 
				
			||||||
 | 
					            'order.id': order.id
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        email_data = {
 | 
				
			||||||
 | 
					            'subject': settings.DCL_TEXT + " Order from %s" % context['email'],
 | 
				
			||||||
 | 
					            'from_email': settings.DCL_SUPPORT_FROM_ADDRESS,
 | 
				
			||||||
 | 
					            'to': ['info@ungleich.ch'],
 | 
				
			||||||
 | 
					            'body': "\n".join(["%s=%s" % (k, v) for (k, v) in context.items()]),
 | 
				
			||||||
 | 
					            'reply_to': [context['email']],
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        email = EmailMessage(**email_data)
 | 
				
			||||||
 | 
					        email.send()
 | 
				
			||||||
 | 
					        request.session['order_confirmation'] = True
 | 
				
			||||||
 | 
					        return HttpResponseRedirect(reverse('datacenterlight:order_success'))
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -77,6 +77,16 @@ class StripeUtils(object):
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        return new_card_data
 | 
					        return new_card_data
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @handleStripeError
 | 
				
			||||||
 | 
					    def get_card_details(self, customer_id, token):
 | 
				
			||||||
 | 
					        customer = stripe.Customer.retrieve(customer_id)
 | 
				
			||||||
 | 
					        credit_card_raw_data = customer.sources.data.pop()
 | 
				
			||||||
 | 
					        card_details = {
 | 
				
			||||||
 | 
					            'last4': credit_card_raw_data.last4,
 | 
				
			||||||
 | 
					            'brand': credit_card_raw_data.brand
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        return card_details
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def check_customer(self, id, user, token):
 | 
					    def check_customer(self, id, user, token):
 | 
				
			||||||
        customers = self.stripe.Customer.all()
 | 
					        customers = self.stripe.Customer.all()
 | 
				
			||||||
        if not customers.get('data'):
 | 
					        if not customers.get('data'):
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue