Merge remote-tracking branch 'upstream/develop' into develop
This commit is contained in:
		
				commit
				
					
						5e51fa6dbf
					
				
			
		
					 21 changed files with 661 additions and 170 deletions
				
			
		| 
						 | 
					@ -446,8 +446,8 @@ AUTH_USER_MODEL = 'membership.CustomUser'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# PAYMENT
 | 
					# PAYMENT
 | 
				
			||||||
 | 
					
 | 
				
			||||||
STRIPE_API_PUBLIC_KEY = 'pk_test_ZRg6P8g5ybiHE6l2RW5pSaYV'  # used in frontend to call from user browser
 | 
					STRIPE_API_PUBLIC_KEY = 'pk_test_QqBZ50Am8KOxaAlOxbcm9Psl'  # used in frontend to call from user browser
 | 
				
			||||||
STRIPE_API_PRIVATE_KEY = 'sk_test_uIPMdgXoRGydrcD7fkwcn7dj'  # used in backend payment
 | 
					STRIPE_API_PRIVATE_KEY = 'sk_test_dqAmbKAij12QCGfkYZ3poGt2'  # used in backend payment
 | 
				
			||||||
STRIPE_DESCRIPTION_ON_PAYMENT = "Payment for ungleich GmbH services"
 | 
					STRIPE_DESCRIPTION_ON_PAYMENT = "Payment for ungleich GmbH services"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# EMAIL MESSAGES
 | 
					# EMAIL MESSAGES
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										9
									
								
								hosting/managers.py
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								hosting/managers.py
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,9 @@
 | 
				
			||||||
 | 
					from django.db import models
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class VMPlansManager(models.Manager):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def active(self, user, **kwargs):
 | 
				
			||||||
 | 
					        return self.prefetch_related('hosting_orders__customer__user').\
 | 
				
			||||||
 | 
					            filter(hosting_orders__customer__user=user, hosting_orders__approved=True, **kwargs)\
 | 
				
			||||||
 | 
					            .distinct()
 | 
				
			||||||
							
								
								
									
										27
									
								
								hosting/migrations/0012_auto_20160501_1850.py
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										27
									
								
								hosting/migrations/0012_auto_20160501_1850.py
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,27 @@
 | 
				
			||||||
 | 
					# -*- coding: utf-8 -*-
 | 
				
			||||||
 | 
					# Generated by Django 1.9.4 on 2016-05-01 18:50
 | 
				
			||||||
 | 
					from __future__ import unicode_literals
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					from django.db import migrations, models
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class Migration(migrations.Migration):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    dependencies = [
 | 
				
			||||||
 | 
					        ('hosting', '0011_auto_20160426_0555'),
 | 
				
			||||||
 | 
					    ]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    operations = [
 | 
				
			||||||
 | 
					        migrations.AddField(
 | 
				
			||||||
 | 
					            model_name='hostingorder',
 | 
				
			||||||
 | 
					            name='cc_brand',
 | 
				
			||||||
 | 
					            field=models.CharField(default='Visa', max_length=10),
 | 
				
			||||||
 | 
					            preserve_default=False,
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					        migrations.AddField(
 | 
				
			||||||
 | 
					            model_name='hostingorder',
 | 
				
			||||||
 | 
					            name='last4',
 | 
				
			||||||
 | 
					            field=models.CharField(default=1111, max_length=4),
 | 
				
			||||||
 | 
					            preserve_default=False,
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					    ]
 | 
				
			||||||
							
								
								
									
										21
									
								
								hosting/migrations/0013_auto_20160505_0302.py
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										21
									
								
								hosting/migrations/0013_auto_20160505_0302.py
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,21 @@
 | 
				
			||||||
 | 
					# -*- coding: utf-8 -*-
 | 
				
			||||||
 | 
					# Generated by Django 1.9.4 on 2016-05-05 03:02
 | 
				
			||||||
 | 
					from __future__ import unicode_literals
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					from django.db import migrations, models
 | 
				
			||||||
 | 
					import django.db.models.deletion
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class Migration(migrations.Migration):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    dependencies = [
 | 
				
			||||||
 | 
					        ('hosting', '0012_auto_20160501_1850'),
 | 
				
			||||||
 | 
					    ]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    operations = [
 | 
				
			||||||
 | 
					        migrations.AlterField(
 | 
				
			||||||
 | 
					            model_name='hostingorder',
 | 
				
			||||||
 | 
					            name='VMPlan',
 | 
				
			||||||
 | 
					            field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='hosting.VirtualMachinePlan'),
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					    ]
 | 
				
			||||||
							
								
								
									
										21
									
								
								hosting/migrations/0014_auto_20160505_0541.py
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										21
									
								
								hosting/migrations/0014_auto_20160505_0541.py
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,21 @@
 | 
				
			||||||
 | 
					# -*- coding: utf-8 -*-
 | 
				
			||||||
 | 
					# Generated by Django 1.9.4 on 2016-05-05 05:41
 | 
				
			||||||
 | 
					from __future__ import unicode_literals
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					from django.db import migrations, models
 | 
				
			||||||
 | 
					import django.db.models.deletion
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class Migration(migrations.Migration):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    dependencies = [
 | 
				
			||||||
 | 
					        ('hosting', '0013_auto_20160505_0302'),
 | 
				
			||||||
 | 
					    ]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    operations = [
 | 
				
			||||||
 | 
					        migrations.AlterField(
 | 
				
			||||||
 | 
					            model_name='hostingorder',
 | 
				
			||||||
 | 
					            name='VMPlan',
 | 
				
			||||||
 | 
					            field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='hosting_orders', to='hosting.VirtualMachinePlan'),
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					    ]
 | 
				
			||||||
| 
						 | 
					@ -2,10 +2,13 @@ import json
 | 
				
			||||||
 | 
					
 | 
				
			||||||
from django.db import models
 | 
					from django.db import models
 | 
				
			||||||
from django.utils.translation import ugettext_lazy as _
 | 
					from django.utils.translation import ugettext_lazy as _
 | 
				
			||||||
 | 
					from django.utils.functional import cached_property
 | 
				
			||||||
from django.core import serializers
 | 
					from django.core import serializers
 | 
				
			||||||
from membership.models import StripeCustomer
 | 
					from membership.models import StripeCustomer
 | 
				
			||||||
from utils.models import BillingAddress
 | 
					from utils.models import BillingAddress
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					from .managers import VMPlansManager
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class RailsBetaUser(models.Model):
 | 
					class RailsBetaUser(models.Model):
 | 
				
			||||||
    email = models.EmailField(unique=True)
 | 
					    email = models.EmailField(unique=True)
 | 
				
			||||||
| 
						 | 
					@ -81,6 +84,17 @@ class VirtualMachinePlan(models.Model):
 | 
				
			||||||
    vm_type = models.ForeignKey(VirtualMachineType)
 | 
					    vm_type = models.ForeignKey(VirtualMachineType)
 | 
				
			||||||
    price = models.FloatField()
 | 
					    price = models.FloatField()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    objects = VMPlansManager()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @cached_property
 | 
				
			||||||
 | 
					    def hosting_company_name(self):
 | 
				
			||||||
 | 
					        return self.vm_type.get_hosting_company_display()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @cached_property
 | 
				
			||||||
 | 
					    def name(self):
 | 
				
			||||||
 | 
					        name = 'vm-%s' % self.id
 | 
				
			||||||
 | 
					        return name
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @classmethod
 | 
					    @classmethod
 | 
				
			||||||
    def create(cls, data, user):
 | 
					    def create(cls, data, user):
 | 
				
			||||||
        instance = cls.objects.create(**data)
 | 
					        instance = cls.objects.create(**data)
 | 
				
			||||||
| 
						 | 
					@ -88,13 +102,23 @@ class VirtualMachinePlan(models.Model):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class HostingOrder(models.Model):
 | 
					class HostingOrder(models.Model):
 | 
				
			||||||
    VMPlan = models.OneToOneField(VirtualMachinePlan)
 | 
					
 | 
				
			||||||
 | 
					    ORDER_APPROVED_STATUS = 'Approved'
 | 
				
			||||||
 | 
					    ORDER_DECLINED_STATUS = 'Declined'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    VMPlan = models.ForeignKey(VirtualMachinePlan, related_name='hosting_orders')
 | 
				
			||||||
    customer = models.ForeignKey(StripeCustomer)
 | 
					    customer = models.ForeignKey(StripeCustomer)
 | 
				
			||||||
    billing_address = models.ForeignKey(BillingAddress)
 | 
					    billing_address = models.ForeignKey(BillingAddress)
 | 
				
			||||||
    created_at = models.DateTimeField(auto_now_add=True)
 | 
					    created_at = models.DateTimeField(auto_now_add=True)
 | 
				
			||||||
    approved = models.BooleanField(default=False)
 | 
					    approved = models.BooleanField(default=False)
 | 
				
			||||||
 | 
					    last4 = models.CharField(max_length=4)
 | 
				
			||||||
 | 
					    cc_brand = models.CharField(max_length=10)
 | 
				
			||||||
    stripe_charge_id = models.CharField(max_length=100, null=True)
 | 
					    stripe_charge_id = models.CharField(max_length=100, null=True)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @cached_property
 | 
				
			||||||
 | 
					    def status(self):
 | 
				
			||||||
 | 
					        return self.ORDER_APPROVED_STATUS if self.approved else self.ORDER_DECLINED_STATUS
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @classmethod
 | 
					    @classmethod
 | 
				
			||||||
    def create(cls, VMPlan=None, customer=None, billing_address=None):
 | 
					    def create(cls, VMPlan=None, customer=None, billing_address=None):
 | 
				
			||||||
        instance = cls.objects.create(VMPlan=VMPlan, customer=customer,
 | 
					        instance = cls.objects.create(VMPlan=VMPlan, customer=customer,
 | 
				
			||||||
| 
						 | 
					@ -107,6 +131,8 @@ class HostingOrder(models.Model):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def set_stripe_charge(self, stripe_charge):
 | 
					    def set_stripe_charge(self, stripe_charge):
 | 
				
			||||||
        self.stripe_charge_id = stripe_charge.id
 | 
					        self.stripe_charge_id = stripe_charge.id
 | 
				
			||||||
 | 
					        self.last4 = stripe_charge.source.last4
 | 
				
			||||||
 | 
					        self.cc_brand = stripe_charge.source.brand
 | 
				
			||||||
        self.save()
 | 
					        self.save()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										20
									
								
								hosting/static/hosting/css/commons.css
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								hosting/static/hosting/css/commons.css
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,20 @@
 | 
				
			||||||
 | 
					.dashboard-container {
 | 
				
			||||||
 | 
						padding-top:5%; padding-bottom: 11%;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.borderless td {
 | 
				
			||||||
 | 
					    border: none !important;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					.borderless thead {
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.borderless tbody:before {
 | 
				
			||||||
 | 
					    content: "-";
 | 
				
			||||||
 | 
					    display: block;
 | 
				
			||||||
 | 
					    color: transparent;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.inline-headers h3, .inline-headers h4 {
 | 
				
			||||||
 | 
					  display: inline-block;
 | 
				
			||||||
 | 
					  vertical-align: baseline;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										17
									
								
								hosting/static/hosting/css/order.css
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								hosting/static/hosting/css/order.css
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,17 @@
 | 
				
			||||||
 | 
					.order-detail-container {padding-top:5%; padding-bottom: 11%;}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.order-detail-container .invoice-title h2, .invoice-title h3 {
 | 
				
			||||||
 | 
					    display: inline-block;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.order-detail-container .table > tbody > tr > .no-line {
 | 
				
			||||||
 | 
					    border-top: none;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.order-detail-container .table > thead > tr > .no-line {
 | 
				
			||||||
 | 
					    border-bottom: none;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.order-detail-container .table > tbody > tr > .thick-line {
 | 
				
			||||||
 | 
					    border-top: 2px solid;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										5
									
								
								hosting/static/hosting/css/orders.css
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								hosting/static/hosting/css/orders.css
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,5 @@
 | 
				
			||||||
 | 
					.orders-container {padding-top:5%; padding-bottom: 11%;}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.orders-container .table > tbody > tr > td {
 | 
				
			||||||
 | 
					     vertical-align: middle;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										42
									
								
								hosting/static/hosting/css/virtual-machine.css
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										42
									
								
								hosting/static/hosting/css/virtual-machine.css
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,42 @@
 | 
				
			||||||
 | 
					.virtual-machine-container .tabs-left, .virtual-machine-container .tabs-right {
 | 
				
			||||||
 | 
					  border-bottom: none;
 | 
				
			||||||
 | 
					  padding-top: 2px;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					.virtual-machine-container .tabs-left {
 | 
				
			||||||
 | 
					  border-right: 1px solid #ddd;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					.virtual-machine-container .tabs-right {
 | 
				
			||||||
 | 
					  border-left: 1px solid #ddd;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					.virtual-machine-container .tabs-left>li, .virtual-machine-container .tabs-right>li {
 | 
				
			||||||
 | 
					  float: none;
 | 
				
			||||||
 | 
					  margin-bottom: 2px;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					.virtual-machine-container .tabs-left>li {
 | 
				
			||||||
 | 
					  margin-right: -1px;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					.virtual-machine-container .tabs-right>li {
 | 
				
			||||||
 | 
					  margin-left: -1px;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					.virtual-machine-container .tabs-left>li.active>a,
 | 
				
			||||||
 | 
					.virtual-machine-container .tabs-left>li.active>a:hover,
 | 
				
			||||||
 | 
					.virtual-machine-container .tabs-left>li.active>a:focus {
 | 
				
			||||||
 | 
					  border-bottom-color: #ddd;
 | 
				
			||||||
 | 
					  border-right-color: transparent;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.virtual-machine-container .tabs-right>li.active>a,
 | 
				
			||||||
 | 
					.virtual-machine-container .tabs-right>li.active>a:hover,
 | 
				
			||||||
 | 
					.virtual-machine-container .tabs-right>li.active>a:focus {
 | 
				
			||||||
 | 
					  border-bottom: 1px solid #ddd;
 | 
				
			||||||
 | 
					  border-left-color: transparent;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					.virtual-machine-container .tabs-left>li>a {
 | 
				
			||||||
 | 
					  border-radius: 4px 0 0 4px;
 | 
				
			||||||
 | 
					  margin-right: 0;
 | 
				
			||||||
 | 
					  display:block;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					.virtual-machine-container .tabs-right>li>a {
 | 
				
			||||||
 | 
					  border-radius: 0 4px 4px 0;
 | 
				
			||||||
 | 
					  margin-right: 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -18,6 +18,10 @@
 | 
				
			||||||
    <!-- Custom CSS -->
 | 
					    <!-- Custom CSS -->
 | 
				
			||||||
    <link href="{% static 'hosting/css/landing-page.css' %}" rel="stylesheet">
 | 
					    <link href="{% static 'hosting/css/landing-page.css' %}" rel="stylesheet">
 | 
				
			||||||
    <link href="{% static 'hosting/css/payment.css' %}" rel="stylesheet">
 | 
					    <link href="{% static 'hosting/css/payment.css' %}" rel="stylesheet">
 | 
				
			||||||
 | 
					    <link href="{% static 'hosting/css/order.css' %}" rel="stylesheet">
 | 
				
			||||||
 | 
					    <link href="{% static 'hosting/css/orders.css' %}" rel="stylesheet">
 | 
				
			||||||
 | 
					    <link href="{% static 'hosting/css/commons.css' %}" rel="stylesheet">
 | 
				
			||||||
 | 
					    <link href="{% static 'hosting/css/virtual-machine.css' %}" rel="stylesheet">
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    <!-- Custom Fonts -->
 | 
					    <!-- Custom Fonts -->
 | 
				
			||||||
    <link href='http://fonts.googleapis.com/css?family=Raleway' rel='stylesheet' type='text/css'>
 | 
					    <link href='http://fonts.googleapis.com/css?family=Raleway' rel='stylesheet' type='text/css'>
 | 
				
			||||||
| 
						 | 
					@ -49,30 +53,51 @@
 | 
				
			||||||
                    <span class="icon-bar"></span>
 | 
					                    <span class="icon-bar"></span>
 | 
				
			||||||
                    <span class="icon-bar"></span>
 | 
					                    <span class="icon-bar"></span>
 | 
				
			||||||
                </button>
 | 
					                </button>
 | 
				
			||||||
                <a class="navbar-brand topnav" href="#"><img src="img/logo_black.svg"></a>
 | 
					                <a class="navbar-brand topnav" href="#"><img src="{% static 'hosting/img/logo_black.svg' %}"></a>
 | 
				
			||||||
            </div>
 | 
					            </div>
 | 
				
			||||||
            <!-- Collect the nav links, forms, and other content for toggling -->
 | 
					            <!-- Collect the nav links, forms, and other content for toggling -->
 | 
				
			||||||
            <div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
 | 
					            <div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
 | 
				
			||||||
                <ul class="nav navbar-nav navbar-right">
 | 
					                <ul class="nav navbar-nav navbar-right">
 | 
				
			||||||
                    <li>
 | 
					
 | 
				
			||||||
                        <a href="{{ request.META.HTTP_REFERER }}#how">How it works</a>
 | 
					
 | 
				
			||||||
                    </li>
 | 
					 | 
				
			||||||
                    <li>
 | 
					 | 
				
			||||||
                        <a href="{{ request.META.HTTP_REFERER }}#your">Your infrastructure</a>
 | 
					 | 
				
			||||||
                    </li>
 | 
					 | 
				
			||||||
                   <li>
 | 
					 | 
				
			||||||
                        <a href="{{ request.META.HTTP_REFERER }}#our">Our inftrastructure</a>
 | 
					 | 
				
			||||||
                    </li>
 | 
					 | 
				
			||||||
                    <li>
 | 
					 | 
				
			||||||
                        <a href="{{ request.META.HTTP_REFERER }}#price">Pricing</a>
 | 
					 | 
				
			||||||
                    </li>
 | 
					 | 
				
			||||||
                    <li>
 | 
					 | 
				
			||||||
                        <a href="{{ request.META.HTTP_REFERER }}#contact">Contact</a>
 | 
					 | 
				
			||||||
                    </li>
 | 
					 | 
				
			||||||
                    {% if request.user.is_authenticated %}
 | 
					                    {% if request.user.is_authenticated %}
 | 
				
			||||||
                    <li>
 | 
					                        <li>
 | 
				
			||||||
                        <a href="{% url 'hosting:logout' %}"> Logout</a>
 | 
					                            <a href="{% url 'hosting:virtual_machines' %}">
 | 
				
			||||||
                    </li>
 | 
					                                <i class="fa fa-server" aria-hidden="true"></i> My Virtual Machines
 | 
				
			||||||
 | 
					                            </a>
 | 
				
			||||||
 | 
					                        </li>
 | 
				
			||||||
 | 
					                        <li>
 | 
				
			||||||
 | 
					                            <a href="{% url 'hosting:orders' %}">
 | 
				
			||||||
 | 
					                                <i class="fa fa-credit-card"></i> My Orders
 | 
				
			||||||
 | 
					                            </a>
 | 
				
			||||||
 | 
					                        </li>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                        <li class="dropdown">
 | 
				
			||||||
 | 
					                          <a class="dropdown-toggle" role="button" data-toggle="dropdown" href="#">
 | 
				
			||||||
 | 
					                            <i class="glyphicon glyphicon-user"></i> {{request.user.name}} <span class="caret"></span></a>
 | 
				
			||||||
 | 
					                          <ul id="g-account-menu" class="dropdown-menu" role="menu">
 | 
				
			||||||
 | 
					                            <li><a href="{% url 'hosting:logout' %}"><i class="glyphicon glyphicon-lock"></i> Logout</a></li>
 | 
				
			||||||
 | 
					                          </ul>
 | 
				
			||||||
 | 
					                        </li>
 | 
				
			||||||
 | 
					                    {% else %}
 | 
				
			||||||
 | 
					                        <li>
 | 
				
			||||||
 | 
					                            <a href="{{ request.META.HTTP_REFERER }}#how">How it works</a>
 | 
				
			||||||
 | 
					                        </li>
 | 
				
			||||||
 | 
					                        <li>
 | 
				
			||||||
 | 
					                            <a href="{{ request.META.HTTP_REFERER }}#your">Your infrastructure</a>
 | 
				
			||||||
 | 
					                        </li>
 | 
				
			||||||
 | 
					                       <li>
 | 
				
			||||||
 | 
					                            <a href="{{ request.META.HTTP_REFERER }}#our">Our inftrastructure</a>
 | 
				
			||||||
 | 
					                        </li>
 | 
				
			||||||
 | 
					                        <li>
 | 
				
			||||||
 | 
					                            <a href="{{ request.META.HTTP_REFERER }}#price">Pricing</a>
 | 
				
			||||||
 | 
					                        </li>
 | 
				
			||||||
 | 
					                        <li>
 | 
				
			||||||
 | 
					                            <a href="{{ request.META.HTTP_REFERER }}#contact">Contact</a>
 | 
				
			||||||
 | 
					                        </li>  
 | 
				
			||||||
 | 
					                        <li>
 | 
				
			||||||
 | 
					                            <a href="{% url 'hosting:login' %}?next={{request.current_path}}">Login</a>
 | 
				
			||||||
 | 
					                        </li>   
 | 
				
			||||||
                    {% endif %}
 | 
					                    {% endif %}
 | 
				
			||||||
                </ul>
 | 
					                </ul>
 | 
				
			||||||
            </div>
 | 
					            </div>
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,79 +0,0 @@
 | 
				
			||||||
{% extends "hosting/base_short.html" %}
 | 
					 | 
				
			||||||
{% load staticfiles bootstrap3 %}
 | 
					 | 
				
			||||||
{% block content %} 
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
<style type="text/css">
 | 
					 | 
				
			||||||
.invoice-title h2, .invoice-title h3 {
 | 
					 | 
				
			||||||
    display: inline-block;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
.table > tbody > tr > .no-line {
 | 
					 | 
				
			||||||
    border-top: none;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
.table > thead > tr > .no-line {
 | 
					 | 
				
			||||||
    border-bottom: none;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
.table > tbody > tr > .thick-line {
 | 
					 | 
				
			||||||
    border-top: 2px solid;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
</style>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
<div class="container  payment-container">
 | 
					 | 
				
			||||||
    <div class="row">
 | 
					 | 
				
			||||||
        <div class="col-xs-8 col-xs-offset-2">
 | 
					 | 
				
			||||||
    		<div class="invoice-title">
 | 
					 | 
				
			||||||
    			<h2>Invoice</h2><h3 class="pull-right">Order # {{order.id}}</h3>
 | 
					 | 
				
			||||||
    		</div>
 | 
					 | 
				
			||||||
    		<hr>
 | 
					 | 
				
			||||||
    		<div class="row">
 | 
					 | 
				
			||||||
    			<div class="col-xs-6">
 | 
					 | 
				
			||||||
    				<address>
 | 
					 | 
				
			||||||
                    <h3><b>Billed To:</b></h3>
 | 
					 | 
				
			||||||
    					John Smith<br>
 | 
					 | 
				
			||||||
    					1234 Main<br>
 | 
					 | 
				
			||||||
    					Apt. 4B<br>
 | 
					 | 
				
			||||||
    					Springfield, ST 54321
 | 
					 | 
				
			||||||
    				</address>
 | 
					 | 
				
			||||||
    			</div>
 | 
					 | 
				
			||||||
                <div class="col-xs-6 text-right">
 | 
					 | 
				
			||||||
                    <address>
 | 
					 | 
				
			||||||
                        <strong>Order Date:</strong><br>
 | 
					 | 
				
			||||||
                        {{order.created_at}}<br><br>
 | 
					 | 
				
			||||||
                    </address>
 | 
					 | 
				
			||||||
                </div>
 | 
					 | 
				
			||||||
    		</div>
 | 
					 | 
				
			||||||
    		<div class="row">
 | 
					 | 
				
			||||||
    			<div class="col-xs-6">
 | 
					 | 
				
			||||||
    				<address>
 | 
					 | 
				
			||||||
    					<strong>Payment Method:</strong><br>
 | 
					 | 
				
			||||||
    					{{brand}} ending **** {{last4}}<br>
 | 
					 | 
				
			||||||
    					{{user.email}}
 | 
					 | 
				
			||||||
    				</address>
 | 
					 | 
				
			||||||
    			</div>
 | 
					 | 
				
			||||||
    		</div>
 | 
					 | 
				
			||||||
    	</div>
 | 
					 | 
				
			||||||
    </div>
 | 
					 | 
				
			||||||
    
 | 
					 | 
				
			||||||
    <div class="row">
 | 
					 | 
				
			||||||
        <div class="col-md-8 col-md-offset-2">
 | 
					 | 
				
			||||||
            <h3><b>Order summary</b></h3>
 | 
					 | 
				
			||||||
            <hr>
 | 
					 | 
				
			||||||
            <div class="content">
 | 
					 | 
				
			||||||
                <p><b>Type</b> <span class="pull-right">{{request.session.vm_specs.hosting_company_name}}</span></p>
 | 
					 | 
				
			||||||
                <hr>
 | 
					 | 
				
			||||||
                <p><b>Cores</b> <span class="pull-right">{{request.session.vm_specs.cores}}</span></p>
 | 
					 | 
				
			||||||
                <hr>
 | 
					 | 
				
			||||||
                <p><b>Memory</b> <span class="pull-right">{{request.session.vm_specs.memory}} GiB</span></p>
 | 
					 | 
				
			||||||
                <hr>
 | 
					 | 
				
			||||||
                <p><b>Disk space</b> <span class="pull-right">{{request.session.vm_specs.disk_size}} GiB</span></p>
 | 
					 | 
				
			||||||
                <hr>
 | 
					 | 
				
			||||||
                <h4>Total<p class="pull-right"><b>{{request.session.vm_specs.final_price}} CHF</b></p></h4>
 | 
					 | 
				
			||||||
            </div>
 | 
					 | 
				
			||||||
        </div>
 | 
					 | 
				
			||||||
    </div>
 | 
					 | 
				
			||||||
</div>
 | 
					 | 
				
			||||||
{%endblock%}
 | 
					 | 
				
			||||||
							
								
								
									
										64
									
								
								hosting/templates/hosting/order_detail.html
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										64
									
								
								hosting/templates/hosting/order_detail.html
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,64 @@
 | 
				
			||||||
 | 
					{% extends "hosting/base_short.html" %}
 | 
				
			||||||
 | 
					{% load staticfiles bootstrap3 %}
 | 
				
			||||||
 | 
					{% block content %} 
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<div class="container  order-detail-container">
 | 
				
			||||||
 | 
					    <div class="row">
 | 
				
			||||||
 | 
					        <div class="col-xs-8 col-xs-offset-2">
 | 
				
			||||||
 | 
					    		<div class="invoice-title">
 | 
				
			||||||
 | 
					    			<h2>Invoice</h2><h3 class="pull-right">Order # {{object.id}}</h3>
 | 
				
			||||||
 | 
					    		</div>
 | 
				
			||||||
 | 
					    		<hr>
 | 
				
			||||||
 | 
					    		<div class="row">
 | 
				
			||||||
 | 
					    			<div class="col-xs-6">
 | 
				
			||||||
 | 
					    				<address>
 | 
				
			||||||
 | 
					                    <h3><b>Billed To:</b></h3>
 | 
				
			||||||
 | 
					    					{{user.name}}<br>
 | 
				
			||||||
 | 
					                        {{object.billing_address.street_address}},{{order.billing_address.postal_code}}<br>
 | 
				
			||||||
 | 
					                        {{object.billing_address.city}}, {{object.billing_address.country}}.
 | 
				
			||||||
 | 
					    				</address>
 | 
				
			||||||
 | 
					    			</div>
 | 
				
			||||||
 | 
					                <div class="col-xs-6 text-right">
 | 
				
			||||||
 | 
					                    <address>
 | 
				
			||||||
 | 
					                        <strong>Order Date:</strong><br>
 | 
				
			||||||
 | 
					                        {{object.created_at}}<br><br>
 | 
				
			||||||
 | 
					                        <strong>Status:</strong><br>
 | 
				
			||||||
 | 
					                        <strong class="{% if object.status == 'Approved' %}text-success
 | 
				
			||||||
 | 
					                                       {%else%} text-danger
 | 
				
			||||||
 | 
					                                       {% endif %}">{{object.status}}</strong>
 | 
				
			||||||
 | 
					                        <br><br>
 | 
				
			||||||
 | 
					                    </address>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                </div>
 | 
				
			||||||
 | 
					    		</div>
 | 
				
			||||||
 | 
					    		<div class="row">
 | 
				
			||||||
 | 
					    			<div class="col-xs-6">
 | 
				
			||||||
 | 
					    				<address>
 | 
				
			||||||
 | 
					    					<strong>Payment Method:</strong><br>
 | 
				
			||||||
 | 
					    					{{object.cc_brand}} ending **** {{object.last4}}<br>
 | 
				
			||||||
 | 
					    					{{user.email}}
 | 
				
			||||||
 | 
					    				</address>
 | 
				
			||||||
 | 
					    			</div>
 | 
				
			||||||
 | 
					    		</div>
 | 
				
			||||||
 | 
					    	</div>
 | 
				
			||||||
 | 
					    </div>
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    <div class="row">
 | 
				
			||||||
 | 
					        <div class="col-md-8 col-md-offset-2">
 | 
				
			||||||
 | 
					            <h3><b>Order summary</b></h3>
 | 
				
			||||||
 | 
					            <hr>
 | 
				
			||||||
 | 
					            <div class="content">
 | 
				
			||||||
 | 
					                <p><b>Type</b> <span class="pull-right">{{object.VMPlan.hosting_company_name}}</span></p>
 | 
				
			||||||
 | 
					                <hr>
 | 
				
			||||||
 | 
					                <p><b>Cores</b> <span class="pull-right">{{object.VMPlan.cores}}</span></p>
 | 
				
			||||||
 | 
					                <hr>
 | 
				
			||||||
 | 
					                <p><b>Memory</b> <span class="pull-right">{{object.VMPlan.memory}} GiB</span></p>
 | 
				
			||||||
 | 
					                <hr>
 | 
				
			||||||
 | 
					                <p><b>Disk space</b> <span class="pull-right">{{object.VMPlan.disk_size}} GiB</span></p>
 | 
				
			||||||
 | 
					                <hr>
 | 
				
			||||||
 | 
					                <h4>Total<p class="pull-right"><b>{{object.VMPlan.price}} CHF</b></p></h4>
 | 
				
			||||||
 | 
					            </div>
 | 
				
			||||||
 | 
					        </div>
 | 
				
			||||||
 | 
					    </div>
 | 
				
			||||||
 | 
					</div>
 | 
				
			||||||
 | 
					{%endblock%}
 | 
				
			||||||
| 
						 | 
					@ -1,31 +1,59 @@
 | 
				
			||||||
{% extends "hosting/base_short.html" %}
 | 
					{% extends "hosting/base_short.html" %}
 | 
				
			||||||
{% load staticfiles bootstrap3 %}
 | 
					{% load staticfiles bootstrap3 %}
 | 
				
			||||||
{% block content %} 
 | 
					{% block content %} 
 | 
				
			||||||
 | 
					
 | 
				
			||||||
<div>
 | 
					<div>
 | 
				
			||||||
	<div class="container payment-container">
 | 
						<div class="container orders-container">
 | 
				
			||||||
		<div class="row">
 | 
							<div class="row">
 | 
				
			||||||
			<div class="col-md-8 col-md-offset-2">
 | 
								<div class="col-md-8 col-md-offset-2">
 | 
				
			||||||
				<table class="table"> 
 | 
									<table class="table borderless table-hover"> 
 | 
				
			||||||
				<caption>My orders.</caption> 
 | 
									<h3><i class="fa fa-credit-card"></i> My Orders</h3> 
 | 
				
			||||||
 | 
									<br/>
 | 
				
			||||||
				<thead> 
 | 
									<thead> 
 | 
				
			||||||
				<tr> 
 | 
									<tr> 
 | 
				
			||||||
					<th>#</th>
 | 
										<th>#</th>
 | 
				
			||||||
					<th>Date</th>
 | 
										<th>Date</th>
 | 
				
			||||||
					<th>Amount</th>
 | 
										<th>Amount</th>
 | 
				
			||||||
					<th>Status</th>
 | 
										<th>Status</th>
 | 
				
			||||||
 | 
										<th></th>
 | 
				
			||||||
				</tr> 
 | 
									</tr> 
 | 
				
			||||||
				</thead> 
 | 
									</thead> 
 | 
				
			||||||
				<tbody> 
 | 
									<tbody> 
 | 
				
			||||||
					{% for order in orders %}
 | 
										{% for order in orders %}
 | 
				
			||||||
					<tr> 
 | 
										<tr> 
 | 
				
			||||||
						<th scope="row">{{order.id}}</th> 
 | 
											<td scope="row">{{order.id}}</td> 
 | 
				
			||||||
						<td>{{order.created_at}}</td> 
 | 
											<td>{{order.created_at}}</td> 
 | 
				
			||||||
						<td>{{order.VMPlan.price}}</td> 
 | 
											<td>{{order.VMPlan.price}} CHF</td> 
 | 
				
			||||||
						<td>{{order.approved}}</td> 
 | 
											<td>{% if order.approved %}
 | 
				
			||||||
					</tr> 
 | 
													<span class="text-success strong">Approved</span>
 | 
				
			||||||
 | 
												{% else%} 
 | 
				
			||||||
 | 
													<span class="text-danger strong">Declined</span>
 | 
				
			||||||
 | 
												{% endif%}
 | 
				
			||||||
 | 
											</td> 
 | 
				
			||||||
 | 
											<td>
 | 
				
			||||||
 | 
												<button type="button" class="btn btn-default"><a href="{% url 'hosting:orders' order.id %}">View Detail</a></button>
 | 
				
			||||||
 | 
											</td>
 | 
				
			||||||
 | 
										</tr>
 | 
				
			||||||
					{% endfor %}
 | 
										{% endfor %}
 | 
				
			||||||
				</tbody> 
 | 
									</tbody> 
 | 
				
			||||||
				</table>
 | 
									</table>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								    {% if is_paginated %}
 | 
				
			||||||
 | 
								        <div class="pagination">
 | 
				
			||||||
 | 
								            <span class="page-links">
 | 
				
			||||||
 | 
								                {% if page_obj.has_previous %}
 | 
				
			||||||
 | 
								                    <a href="{{request.path}}?page={{ page_obj.previous_page_number }}">previous</a>
 | 
				
			||||||
 | 
								                {% endif %}
 | 
				
			||||||
 | 
								                <span class="page-current">
 | 
				
			||||||
 | 
								                    Page {{ page_obj.number }} of {{ page_obj.paginator.num_pages }}.
 | 
				
			||||||
 | 
								                </span>
 | 
				
			||||||
 | 
								                {% if page_obj.has_next %}
 | 
				
			||||||
 | 
								                    <a href="{{request.path}}?page={{ page_obj.next_page_number }}">next</a>
 | 
				
			||||||
 | 
								                {% endif %}
 | 
				
			||||||
 | 
								            </span>
 | 
				
			||||||
 | 
								        </div>
 | 
				
			||||||
 | 
								    {% endif %}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			</div>
 | 
								</div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	    </div>
 | 
						    </div>
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										155
									
								
								hosting/templates/hosting/virtual_machine_detail.html
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										155
									
								
								hosting/templates/hosting/virtual_machine_detail.html
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,155 @@
 | 
				
			||||||
 | 
					{% extends "hosting/base_short.html" %}
 | 
				
			||||||
 | 
					{% load staticfiles bootstrap3 %}
 | 
				
			||||||
 | 
					{% block content %} 
 | 
				
			||||||
 | 
					<div>
 | 
				
			||||||
 | 
						<div class="container virtual-machine-container dashboard-container ">
 | 
				
			||||||
 | 
							<div class="row">
 | 
				
			||||||
 | 
								<div class="col-md-9 col-md-offset-2">
 | 
				
			||||||
 | 
									 <div  class="col-sm-12">
 | 
				
			||||||
 | 
									        <h3><i class="fa fa-cloud" aria-hidden="true"></i> {{virtual_machine.name}}</h3>
 | 
				
			||||||
 | 
									        <hr/>
 | 
				
			||||||
 | 
									        <div class="col-md-3"> <!-- required for floating -->
 | 
				
			||||||
 | 
									          <!-- Nav tabs -->
 | 
				
			||||||
 | 
									          <ul class="nav nav-tabs tabs-left sideways">
 | 
				
			||||||
 | 
									            <li class="active">
 | 
				
			||||||
 | 
									            	<a href="#settings-v" data-toggle="tab">
 | 
				
			||||||
 | 
									            		<i class="fa fa-cogs" aria-hidden="true"></i>
 | 
				
			||||||
 | 
									            		Settings
 | 
				
			||||||
 | 
									            	</a>
 | 
				
			||||||
 | 
									            </li>
 | 
				
			||||||
 | 
									            <li>
 | 
				
			||||||
 | 
									            	<a href="#billing-v" data-toggle="tab">
 | 
				
			||||||
 | 
									            		<i class="fa fa-money" aria-hidden="true"></i>
 | 
				
			||||||
 | 
									            		Billing
 | 
				
			||||||
 | 
									            	</a>
 | 
				
			||||||
 | 
									            </li>
 | 
				
			||||||
 | 
									            <li>
 | 
				
			||||||
 | 
									            	<a href="#orders-v" data-toggle="tab">
 | 
				
			||||||
 | 
									            		<i class="fa fa-credit-card"></i> 
 | 
				
			||||||
 | 
									            		Orders
 | 
				
			||||||
 | 
									            	</a>
 | 
				
			||||||
 | 
									            </li>
 | 
				
			||||||
 | 
									            <li>
 | 
				
			||||||
 | 
									            	<a href="#status-v" data-toggle="tab">
 | 
				
			||||||
 | 
									            		<i class="fa fa-signal" aria-hidden="true"></i> Status
 | 
				
			||||||
 | 
									            	</a>
 | 
				
			||||||
 | 
									            </li>
 | 
				
			||||||
 | 
									          </ul>
 | 
				
			||||||
 | 
									        </div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
									        <div class="col-md-9">
 | 
				
			||||||
 | 
									          <!-- Tab panes -->
 | 
				
			||||||
 | 
									          <div class="tab-content">
 | 
				
			||||||
 | 
									            <div class="tab-pane active" id="settings-v">
 | 
				
			||||||
 | 
									            	<div class="row">
 | 
				
			||||||
 | 
														<div class="col-md-12">
 | 
				
			||||||
 | 
														<h3>{{virtual_machine.hosting_company_name}}</h3>
 | 
				
			||||||
 | 
														<hr>
 | 
				
			||||||
 | 
														</div>
 | 
				
			||||||
 | 
									            	</div>
 | 
				
			||||||
 | 
													<div class="row">
 | 
				
			||||||
 | 
													  <div class="col-md-12">
 | 
				
			||||||
 | 
													    <div class="row">
 | 
				
			||||||
 | 
													      <div class="col-md-3">
 | 
				
			||||||
 | 
													        <div class="well text-center">
 | 
				
			||||||
 | 
													        	<i class="fa fa-cubes" aria-hidden="true"></i> Cores <br/>
 | 
				
			||||||
 | 
													        	<span class="label label-success">{{virtual_machine.cores}}</span>
 | 
				
			||||||
 | 
													        </div>
 | 
				
			||||||
 | 
													      </div>
 | 
				
			||||||
 | 
													      <div class="col-md-3">
 | 
				
			||||||
 | 
													        <div class="well text-center">
 | 
				
			||||||
 | 
													        	<i class="fa fa-tachometer" aria-hidden="true"></i> Memory <br/>
 | 
				
			||||||
 | 
													        	<span class="label label-success">{{virtual_machine.memory}} GiB</span>
 | 
				
			||||||
 | 
													        </div>
 | 
				
			||||||
 | 
													      </div>
 | 
				
			||||||
 | 
													      <div class="col-md-3">
 | 
				
			||||||
 | 
													        <div class="well text-center">
 | 
				
			||||||
 | 
													        	<i class="fa fa-hdd-o" aria-hidden="true"></i> Disk <br/>
 | 
				
			||||||
 | 
													        	<span class="label label-success">{{virtual_machine.disk_size}} GiB</span>
 | 
				
			||||||
 | 
													        </div>
 | 
				
			||||||
 | 
													      </div>
 | 
				
			||||||
 | 
													    </div><!--/row-->    
 | 
				
			||||||
 | 
													  </div><!--/col-12-->
 | 
				
			||||||
 | 
													</div><!--/row-->
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
									            </div>
 | 
				
			||||||
 | 
									            <div class="tab-pane" id="billing-v">
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
									            	<div class="row ">
 | 
				
			||||||
 | 
														<div class="col-md-12 inline-headers">
 | 
				
			||||||
 | 
															<h3>Current pricing</h3>
 | 
				
			||||||
 | 
															<span class="h3 pull-right"><strong>{{virtual_machine.price|floatformat}} CHF</strong>/mo</span> 
 | 
				
			||||||
 | 
															<hr>
 | 
				
			||||||
 | 
														</div>
 | 
				
			||||||
 | 
									            	</div>
 | 
				
			||||||
 | 
									            </div>
 | 
				
			||||||
 | 
									            <div class="tab-pane" id="orders-v">
 | 
				
			||||||
 | 
													<div class="row">
 | 
				
			||||||
 | 
													  <div class="col-md-12">
 | 
				
			||||||
 | 
														<table class="table borderless table-hover"> 
 | 
				
			||||||
 | 
															<h3>Orders</h3> 
 | 
				
			||||||
 | 
															<br/>
 | 
				
			||||||
 | 
															<thead> 
 | 
				
			||||||
 | 
															<tr> 
 | 
				
			||||||
 | 
																<th>#</th>
 | 
				
			||||||
 | 
																<th>Date</th>
 | 
				
			||||||
 | 
																<th>Amount</th>
 | 
				
			||||||
 | 
																<th>Status</th>
 | 
				
			||||||
 | 
																<th></th>
 | 
				
			||||||
 | 
															</tr> 
 | 
				
			||||||
 | 
															</thead> 
 | 
				
			||||||
 | 
															<tbody> 
 | 
				
			||||||
 | 
																{% for order in virtual_machine.hosting_orders.all %}
 | 
				
			||||||
 | 
																<tr> 
 | 
				
			||||||
 | 
																	<td scope="row">{{order.id}}</td> 
 | 
				
			||||||
 | 
																	<td>{{order.created_at}}</td> 
 | 
				
			||||||
 | 
																	<td>{{order.VMPlan.price}} CHF</td> 
 | 
				
			||||||
 | 
																	<td>{% if order.approved %}
 | 
				
			||||||
 | 
																			<span class="text-success strong">Approved</span>
 | 
				
			||||||
 | 
																		{% else%} 
 | 
				
			||||||
 | 
																			<span class="text-danger strong">Declined</span>
 | 
				
			||||||
 | 
																		{% endif%}
 | 
				
			||||||
 | 
																	</td> 
 | 
				
			||||||
 | 
																	<td>
 | 
				
			||||||
 | 
																		<button type="button" class="btn btn-default"><a href="{% url 'hosting:orders' order.id %}">View Detail</a></button>
 | 
				
			||||||
 | 
																	</td>
 | 
				
			||||||
 | 
																</tr>
 | 
				
			||||||
 | 
																{% endfor %}
 | 
				
			||||||
 | 
															</tbody> 
 | 
				
			||||||
 | 
														</table>
 | 
				
			||||||
 | 
													  </div><!--/col-12-->
 | 
				
			||||||
 | 
													</div><!--/row-->
 | 
				
			||||||
 | 
									            </div>
 | 
				
			||||||
 | 
									            <div class="tab-pane" id="status-v">
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
									            	<div class="row ">
 | 
				
			||||||
 | 
														<div class="col-md-12 inline-headers">
 | 
				
			||||||
 | 
															<h3>Current status</h3>
 | 
				
			||||||
 | 
															<span class="h3 pull-right label label-success"><strong>Online</strong></span> 
 | 
				
			||||||
 | 
															<hr>
 | 
				
			||||||
 | 
														</div>
 | 
				
			||||||
 | 
									            	</div>
 | 
				
			||||||
 | 
									            </div>
 | 
				
			||||||
 | 
									          </div>
 | 
				
			||||||
 | 
									        </div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
									        <div class="clearfix"></div>
 | 
				
			||||||
 | 
									</div>
 | 
				
			||||||
 | 
								</div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						    </div>
 | 
				
			||||||
 | 
						</div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					</div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					{%endblock%}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
							
								
								
									
										56
									
								
								hosting/templates/hosting/virtual_machines.html
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										56
									
								
								hosting/templates/hosting/virtual_machines.html
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,56 @@
 | 
				
			||||||
 | 
					{% extends "hosting/base_short.html" %}
 | 
				
			||||||
 | 
					{% load staticfiles bootstrap3 %}
 | 
				
			||||||
 | 
					{% block content %} 
 | 
				
			||||||
 | 
					<div>
 | 
				
			||||||
 | 
						<div class="container dashboard-container">
 | 
				
			||||||
 | 
							<div class="row">
 | 
				
			||||||
 | 
								<div class="col-md-8 col-md-offset-2">
 | 
				
			||||||
 | 
									<table class="table borderless table-hover"> 
 | 
				
			||||||
 | 
									<h3><i class="fa fa-server" aria-hidden="true"></i> Virtual Machines</h3> 
 | 
				
			||||||
 | 
									<br/>
 | 
				
			||||||
 | 
									<thead> 
 | 
				
			||||||
 | 
									<tr> 
 | 
				
			||||||
 | 
										<th>ID</th>
 | 
				
			||||||
 | 
										<th>Type</th>
 | 
				
			||||||
 | 
										<th>Amount</th>
 | 
				
			||||||
 | 
										<th></th>
 | 
				
			||||||
 | 
									</tr>
 | 
				
			||||||
 | 
									</thead>
 | 
				
			||||||
 | 
									<tbody> 
 | 
				
			||||||
 | 
										{% for vm in vms %}
 | 
				
			||||||
 | 
										<tr> 
 | 
				
			||||||
 | 
											<td scope="row">{{vm.name}}</td> 
 | 
				
			||||||
 | 
											<td>{{vm.hosting_company_name}}</td> 
 | 
				
			||||||
 | 
											<td>{{vm.price}} CHF</td> 
 | 
				
			||||||
 | 
											<td>
 | 
				
			||||||
 | 
												<button type="button" class="btn btn-default"><a href="{% url 'hosting:virtual_machines' vm.id %}">View Detail</a></button>
 | 
				
			||||||
 | 
											</td>
 | 
				
			||||||
 | 
										</tr>
 | 
				
			||||||
 | 
										{% endfor %}
 | 
				
			||||||
 | 
									</tbody> 
 | 
				
			||||||
 | 
									</table>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								    {% if is_paginated %}
 | 
				
			||||||
 | 
								        <div class="pagination">
 | 
				
			||||||
 | 
								            <span class="page-links">
 | 
				
			||||||
 | 
								                {% if page_obj.has_previous %}
 | 
				
			||||||
 | 
								                    <a href="{{request.path}}?page={{ page_obj.previous_page_number }}">previous</a>
 | 
				
			||||||
 | 
								                {% endif %}
 | 
				
			||||||
 | 
								                <span class="page-current">
 | 
				
			||||||
 | 
								                    Page {{ page_obj.number }} of {{ page_obj.paginator.num_pages }}.
 | 
				
			||||||
 | 
								                </span>
 | 
				
			||||||
 | 
								                {% if page_obj.has_next %}
 | 
				
			||||||
 | 
								                    <a href="{{request.path}}?page={{ page_obj.next_page_number }}">next</a>
 | 
				
			||||||
 | 
								                {% endif %}
 | 
				
			||||||
 | 
								            </span>
 | 
				
			||||||
 | 
								        </div>
 | 
				
			||||||
 | 
								    {% endif %}
 | 
				
			||||||
 | 
									
 | 
				
			||||||
 | 
								</div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						    </div>
 | 
				
			||||||
 | 
						</div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					</div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					{%endblock%}
 | 
				
			||||||
							
								
								
									
										72
									
								
								hosting/test_views.py
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										72
									
								
								hosting/test_views.py
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,72 @@
 | 
				
			||||||
 | 
					from django.test import TestCase
 | 
				
			||||||
 | 
					from django.core.urlresolvers import reverse
 | 
				
			||||||
 | 
					from django.core.urlresolvers import resolve
 | 
				
			||||||
 | 
					from .models import VirtualMachineType
 | 
				
			||||||
 | 
					from .views import DjangoHostingView, RailsHostingView, NodeJSHostingView
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class ProcessVMSelectionTestMixin(object):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def url_resolve_to_view_correctly(self):
 | 
				
			||||||
 | 
					        found = resolve(self.url)
 | 
				
			||||||
 | 
					        self.assertEqual(found.func.__name__, self.view.__name__)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_get(self):
 | 
				
			||||||
 | 
					        response = self.client.get(self.url)
 | 
				
			||||||
 | 
					        self.assertEqual(response.status_code, 200)
 | 
				
			||||||
 | 
					        self.assertEqual(self.view.get_context_data(), self.expected_context)
 | 
				
			||||||
 | 
					        self.assertEqual(response.context['hosting'], self.expected_context['hosting'])
 | 
				
			||||||
 | 
					        self.assertTemplateUsed(response, self.expected_template)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_anonymous_post(self):
 | 
				
			||||||
 | 
					        response = self.client.post(self.url)
 | 
				
			||||||
 | 
					        self.assertRedirects(response, expected_url=reverse('hosting:login'),
 | 
				
			||||||
 | 
					                             status_code=302, target_status_code=200)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class DjangoHostingViewTest(TestCase, ProcessVMSelectionTestMixin):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def setUp(self):
 | 
				
			||||||
 | 
					        self.url = reverse('django.hosting')
 | 
				
			||||||
 | 
					        self.view = DjangoHostingView()
 | 
				
			||||||
 | 
					        self.expected_template = 'hosting/django.html'
 | 
				
			||||||
 | 
					        self.expected_context = {
 | 
				
			||||||
 | 
					            'hosting': "django",
 | 
				
			||||||
 | 
					            'hosting_long': "Django",
 | 
				
			||||||
 | 
					            'domain': "django-hosting.ch",
 | 
				
			||||||
 | 
					            'google_analytics': "UA-62285904-6",
 | 
				
			||||||
 | 
					            'email': "info@django-hosting.ch",
 | 
				
			||||||
 | 
					            'vm_types': VirtualMachineType.get_serialized_vm_types(),
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class RailsHostingViewTest(TestCase, ProcessVMSelectionTestMixin):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def setUp(self):
 | 
				
			||||||
 | 
					        self.url = reverse('rails.hosting')
 | 
				
			||||||
 | 
					        self.view = RailsHostingView()
 | 
				
			||||||
 | 
					        self.expected_template = 'hosting/rails.html'
 | 
				
			||||||
 | 
					        self.expected_context = {
 | 
				
			||||||
 | 
					            'hosting': "rails",
 | 
				
			||||||
 | 
					            'hosting_long': "Ruby On Rails",
 | 
				
			||||||
 | 
					            'domain': "rails-hosting.ch",
 | 
				
			||||||
 | 
					            'google_analytics': "UA-62285904-5",
 | 
				
			||||||
 | 
					            'email': "info@rails-hosting.ch",
 | 
				
			||||||
 | 
					            'vm_types': VirtualMachineType.get_serialized_vm_types(),
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class NodeJSHostingViewTest(TestCase, ProcessVMSelectionTestMixin):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def setUp(self):
 | 
				
			||||||
 | 
					        self.url = reverse('node.hosting')
 | 
				
			||||||
 | 
					        self.view = NodeJSHostingView()
 | 
				
			||||||
 | 
					        self.expected_template = 'hosting/nodejs.html'
 | 
				
			||||||
 | 
					        self.expected_context = {
 | 
				
			||||||
 | 
					            'hosting': "nodejs",
 | 
				
			||||||
 | 
					            'hosting_long': "NodeJS",
 | 
				
			||||||
 | 
					            'domain': "node-hosting.ch",
 | 
				
			||||||
 | 
					            'google_analytics': "UA-62285904-7",
 | 
				
			||||||
 | 
					            'email': "info@node-hosting.ch",
 | 
				
			||||||
 | 
					            'vm_types': VirtualMachineType.get_serialized_vm_types(),
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
| 
						 | 
					@ -1,20 +1,24 @@
 | 
				
			||||||
from django.conf.urls import url
 | 
					from django.conf.urls import url
 | 
				
			||||||
 | 
					
 | 
				
			||||||
from .views import DjangoHostingView, RailsHostingView, PaymentVMView, \
 | 
					from .views import DjangoHostingView, RailsHostingView, PaymentVMView, \
 | 
				
			||||||
                    NodeJSHostingView, LoginView, SignupView, IndexView, \
 | 
					    NodeJSHostingView, LoginView, SignupView, IndexView, \
 | 
				
			||||||
                    InvoiceVMView, OrdersHostingView
 | 
					    OrdersHostingListView, OrdersHostingDetailView, VirtualMachinesPlanListView,\
 | 
				
			||||||
 | 
					    VirtualMachineDetailListView
 | 
				
			||||||
 | 
					
 | 
				
			||||||
urlpatterns = [
 | 
					urlpatterns = [
 | 
				
			||||||
    # url(r'pricing/?$', VMPricingView.as_view(), name='pricing'),
 | 
					    # url(r'pricing/?$', VMPricingView.as_view(), name='pricing'),
 | 
				
			||||||
    url(r'index/?$', IndexView.as_view(), name='index'),
 | 
					    url(r'index/?$', IndexView.as_view(), name='index'),
 | 
				
			||||||
    url(r'django/?$', DjangoHostingView.as_view(), name='djangohosting'),
 | 
					    url(r'django/?$', DjangoHostingView.as_view(), name='djangohosting'),
 | 
				
			||||||
    url(r'nodejs/?$', NodeJSHostingView.as_view(), name='nodejshosting'),
 | 
					    url(r'nodejs/?$', NodeJSHostingView.as_view(), name='nodejshosting'),
 | 
				
			||||||
    url(r'rails/?$', RailsHostingView.as_view(),   name='railshosting'),
 | 
					    url(r'rails/?$', RailsHostingView.as_view(), name='railshosting'),
 | 
				
			||||||
    url(r'payment/?$', PaymentVMView.as_view(), name='payment'),
 | 
					    url(r'payment/?$', PaymentVMView.as_view(), name='payment'),
 | 
				
			||||||
    url(r'invoice/?$', InvoiceVMView.as_view(), name='invoice'),
 | 
					    url(r'orders/?$', OrdersHostingListView.as_view(), name='orders'),
 | 
				
			||||||
    url(r'orders/?$', OrdersHostingView.as_view(), name='orders'),
 | 
					    url(r'orders/(?P<pk>\d+)/?$', OrdersHostingDetailView.as_view(), name='orders'),
 | 
				
			||||||
    url(r'login/?$', LoginView.as_view(),  name='login'),
 | 
					    url(r'my-virtual-machines/?$', VirtualMachinesPlanListView.as_view(), name='virtual_machines'),
 | 
				
			||||||
 | 
					    url(r'my-virtual-machines/(?P<pk>\d+)/?$', VirtualMachineDetailListView.as_view(),
 | 
				
			||||||
 | 
					        name='virtual_machines'),
 | 
				
			||||||
 | 
					    url(r'login/?$', LoginView.as_view(), name='login'),
 | 
				
			||||||
    url(r'signup/?$', SignupView.as_view(), name='signup'),
 | 
					    url(r'signup/?$', SignupView.as_view(), name='signup'),
 | 
				
			||||||
    url(r'^logout/?$', 'django.contrib.auth.views.logout',
 | 
					    url(r'^logout/?$', 'django.contrib.auth.views.logout',
 | 
				
			||||||
                          {'next_page': '/ungleich_page'}, name='logout')
 | 
					        {'next_page': '/ungleich_page'}, name='logout')
 | 
				
			||||||
]
 | 
					]
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -2,16 +2,12 @@
 | 
				
			||||||
from django.shortcuts import get_object_or_404, render
 | 
					from django.shortcuts import get_object_or_404, render
 | 
				
			||||||
from django.core.urlresolvers import reverse_lazy, reverse
 | 
					from django.core.urlresolvers import reverse_lazy, reverse
 | 
				
			||||||
from django.contrib.auth.mixins import LoginRequiredMixin
 | 
					from django.contrib.auth.mixins import LoginRequiredMixin
 | 
				
			||||||
from django.contrib.auth.decorators import login_required
 | 
					 | 
				
			||||||
from django.utils.decorators import method_decorator
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
from django.views.generic import View, CreateView, FormView
 | 
					from django.views.generic import View, CreateView, FormView, ListView, DetailView
 | 
				
			||||||
from django.shortcuts import redirect
 | 
					 | 
				
			||||||
from django.http import HttpResponseRedirect
 | 
					from django.http import HttpResponseRedirect
 | 
				
			||||||
from django.contrib.auth import authenticate, login
 | 
					from django.contrib.auth import authenticate, login
 | 
				
			||||||
from django.conf import settings
 | 
					from django.conf import settings
 | 
				
			||||||
 | 
					
 | 
				
			||||||
from membership.forms import PaymentForm
 | 
					 | 
				
			||||||
from membership.models import CustomUser, StripeCustomer
 | 
					from membership.models import CustomUser, StripeCustomer
 | 
				
			||||||
from utils.stripe_utils import StripeUtils
 | 
					from utils.stripe_utils import StripeUtils
 | 
				
			||||||
from utils.forms import BillingAddressForm
 | 
					from utils.forms import BillingAddressForm
 | 
				
			||||||
| 
						 | 
					@ -21,7 +17,6 @@ from .forms import HostingUserSignupForm, HostingUserLoginForm
 | 
				
			||||||
from .mixins import ProcessVMSelectionMixin
 | 
					from .mixins import ProcessVMSelectionMixin
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
class DjangoHostingView(ProcessVMSelectionMixin, View):
 | 
					class DjangoHostingView(ProcessVMSelectionMixin, View):
 | 
				
			||||||
    template_name = "hosting/django.html"
 | 
					    template_name = "hosting/django.html"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -106,7 +101,7 @@ class IndexView(View):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class LoginView(FormView):
 | 
					class LoginView(FormView):
 | 
				
			||||||
    template_name = 'hosting/login.html'
 | 
					    template_name = 'hosting/login.html'
 | 
				
			||||||
    success_url = reverse_lazy('hosting:login')
 | 
					    success_url = reverse_lazy('hosting:orders')
 | 
				
			||||||
    form_class = HostingUserLoginForm
 | 
					    form_class = HostingUserLoginForm
 | 
				
			||||||
    moodel = CustomUser
 | 
					    moodel = CustomUser
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -217,60 +212,45 @@ class PaymentVMView(FormView):
 | 
				
			||||||
                'order': order.id,
 | 
					                'order': order.id,
 | 
				
			||||||
                'billing_address': billing_address.id
 | 
					                'billing_address': billing_address.id
 | 
				
			||||||
            })
 | 
					            })
 | 
				
			||||||
            return HttpResponseRedirect(reverse('hosting:invoice'))
 | 
					            return HttpResponseRedirect(reverse('hosting:orders', kwargs={'pk': order.id}))
 | 
				
			||||||
        else:
 | 
					        else:
 | 
				
			||||||
            return self.form_invalid(form)
 | 
					            return self.form_invalid(form)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class InvoiceVMView(LoginRequiredMixin, View):
 | 
					class OrdersHostingDetailView(LoginRequiredMixin, DetailView):
 | 
				
			||||||
    template_name = "hosting/invoice.html"
 | 
					    template_name = "hosting/order_detail.html"
 | 
				
			||||||
    login_url = reverse_lazy('hosting:login')
 | 
					    login_url = reverse_lazy('hosting:login')
 | 
				
			||||||
 | 
					    model = HostingOrder
 | 
				
			||||||
    def get_context_data(self, **kwargs):
 | 
					 | 
				
			||||||
        charge = self.request.session.get('charge')
 | 
					 | 
				
			||||||
        order_id = self.request.session.get('order')
 | 
					 | 
				
			||||||
        billing_address_id = self.request.session.get('billing_address')
 | 
					 | 
				
			||||||
        last4 = charge.get('source').get('last4')
 | 
					 | 
				
			||||||
        brand = charge.get('source').get('brand')
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        order = get_object_or_404(HostingOrder, pk=order_id)
 | 
					 | 
				
			||||||
        billing_address = get_object_or_404(BillingAddress, pk=billing_address_id)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        if not charge:
 | 
					 | 
				
			||||||
            return
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        context = {
 | 
					 | 
				
			||||||
            'last4': last4,
 | 
					 | 
				
			||||||
            'brand': brand,
 | 
					 | 
				
			||||||
            'order': order,
 | 
					 | 
				
			||||||
            'billing_address': billing_address,
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        return context
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def get(self, request, *args, **kwargs):
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        context = self.get_context_data()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        return render(request, self.template_name, context)
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class OrdersHostingView(LoginRequiredMixin, View):
 | 
					class OrdersHostingListView(LoginRequiredMixin, ListView):
 | 
				
			||||||
    template_name = "hosting/orders.html"
 | 
					    template_name = "hosting/orders.html"
 | 
				
			||||||
    login_url = reverse_lazy('hosting:login')
 | 
					    login_url = reverse_lazy('hosting:login')
 | 
				
			||||||
 | 
					    context_object_name = "orders"
 | 
				
			||||||
 | 
					    model = HostingOrder
 | 
				
			||||||
 | 
					    paginate_by = 10
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def get_context_data(self, **kwargs):
 | 
					    def get_queryset(self):
 | 
				
			||||||
        user = self.request.user
 | 
					        user = self.request.user
 | 
				
			||||||
        orders = HostingOrder.objects.filter(customer__user=user)
 | 
					        self.queryset = HostingOrder.objects.filter(customer__user=user)
 | 
				
			||||||
        context = {
 | 
					        return super(OrdersHostingListView, self).get_queryset()
 | 
				
			||||||
            'orders':orders
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        return context
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def get(self, request, *args, **kwargs):
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        context = self.get_context_data()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        return render(request, self.template_name, context)
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class VirtualMachinesPlanListView(LoginRequiredMixin, ListView):
 | 
				
			||||||
 | 
					    template_name = "hosting/virtual_machines.html"
 | 
				
			||||||
 | 
					    login_url = reverse_lazy('hosting:login')
 | 
				
			||||||
 | 
					    context_object_name = "vms"
 | 
				
			||||||
 | 
					    model = VirtualMachinePlan
 | 
				
			||||||
 | 
					    paginate_by = 10
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def get_queryset(self):
 | 
				
			||||||
 | 
					        user = self.request.user
 | 
				
			||||||
 | 
					        self.queryset = VirtualMachinePlan.objects.active(user)
 | 
				
			||||||
 | 
					        return super(VirtualMachinesPlanListView, self).get_queryset()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class VirtualMachineDetailListView(LoginRequiredMixin, DetailView):
 | 
				
			||||||
 | 
					    template_name = "hosting/virtual_machine_detail.html"
 | 
				
			||||||
 | 
					    login_url = reverse_lazy('hosting:login')
 | 
				
			||||||
 | 
					    model = VirtualMachinePlan
 | 
				
			||||||
 | 
					    context_object_name = "virtual_machine"
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -131,7 +131,7 @@ class StripeCustomer(models.Model):
 | 
				
			||||||
            Check if there is a registered stripe customer with that email
 | 
					            Check if there is a registered stripe customer with that email
 | 
				
			||||||
            or create a new one
 | 
					            or create a new one
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
 | 
					        stripe_customer = None
 | 
				
			||||||
        try:
 | 
					        try:
 | 
				
			||||||
            stripe_utils = StripeUtils()
 | 
					            stripe_utils = StripeUtils()
 | 
				
			||||||
            stripe_customer = cls.objects.get(user__email=email)
 | 
					            stripe_customer = cls.objects.get(user__email=email)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -52,8 +52,6 @@ def handleStripeError(f):
 | 
				
			||||||
    return handleProblems
 | 
					    return handleProblems
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
class StripeUtils(object):
 | 
					class StripeUtils(object):
 | 
				
			||||||
    CURRENCY = 'chf'
 | 
					    CURRENCY = 'chf'
 | 
				
			||||||
    INTERVAL = 'month'
 | 
					    INTERVAL = 'month'
 | 
				
			||||||
| 
						 | 
					@ -71,7 +69,7 @@ class StripeUtils(object):
 | 
				
			||||||
                customer = stripe.Customer.retrieve(id)
 | 
					                customer = stripe.Customer.retrieve(id)
 | 
				
			||||||
            except stripe.InvalidRequestError:
 | 
					            except stripe.InvalidRequestError:
 | 
				
			||||||
                customer = self.create_customer(token, user.email)
 | 
					                customer = self.create_customer(token, user.email)
 | 
				
			||||||
                user.stripecustomer.stripe_id = customer.get('id')
 | 
					                user.stripecustomer.stripe_id = customer.get('response_object').get('id')
 | 
				
			||||||
                user.stripecustomer.save()
 | 
					                user.stripecustomer.save()
 | 
				
			||||||
        return customer
 | 
					        return customer
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue