diff --git a/dynamicweb/settings/base.py b/dynamicweb/settings/base.py
index 69e708d2..9d64dc60 100644
--- a/dynamicweb/settings/base.py
+++ b/dynamicweb/settings/base.py
@@ -446,8 +446,8 @@ AUTH_USER_MODEL = 'membership.CustomUser'
# PAYMENT
-STRIPE_API_PUBLIC_KEY = 'pk_test_ZRg6P8g5ybiHE6l2RW5pSaYV' # used in frontend to call from user browser
-STRIPE_API_PRIVATE_KEY = 'sk_test_uIPMdgXoRGydrcD7fkwcn7dj' # used in backend payment
+STRIPE_API_PUBLIC_KEY = 'pk_test_QqBZ50Am8KOxaAlOxbcm9Psl' # used in frontend to call from user browser
+STRIPE_API_PRIVATE_KEY = 'sk_test_dqAmbKAij12QCGfkYZ3poGt2' # used in backend payment
STRIPE_DESCRIPTION_ON_PAYMENT = "Payment for ungleich GmbH services"
# EMAIL MESSAGES
diff --git a/hosting/managers.py b/hosting/managers.py
new file mode 100644
index 00000000..c474d61e
--- /dev/null
+++ b/hosting/managers.py
@@ -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()
diff --git a/hosting/migrations/0012_auto_20160501_1850.py b/hosting/migrations/0012_auto_20160501_1850.py
new file mode 100644
index 00000000..3ef15a46
--- /dev/null
+++ b/hosting/migrations/0012_auto_20160501_1850.py
@@ -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,
+ ),
+ ]
diff --git a/hosting/migrations/0013_auto_20160505_0302.py b/hosting/migrations/0013_auto_20160505_0302.py
new file mode 100644
index 00000000..ac4cd8e5
--- /dev/null
+++ b/hosting/migrations/0013_auto_20160505_0302.py
@@ -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'),
+ ),
+ ]
diff --git a/hosting/migrations/0014_auto_20160505_0541.py b/hosting/migrations/0014_auto_20160505_0541.py
new file mode 100644
index 00000000..532b25e8
--- /dev/null
+++ b/hosting/migrations/0014_auto_20160505_0541.py
@@ -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'),
+ ),
+ ]
diff --git a/hosting/models.py b/hosting/models.py
index f3e2a178..dd686312 100644
--- a/hosting/models.py
+++ b/hosting/models.py
@@ -2,10 +2,13 @@ import json
from django.db import models
from django.utils.translation import ugettext_lazy as _
+from django.utils.functional import cached_property
from django.core import serializers
from membership.models import StripeCustomer
from utils.models import BillingAddress
+from .managers import VMPlansManager
+
class RailsBetaUser(models.Model):
email = models.EmailField(unique=True)
@@ -81,6 +84,17 @@ class VirtualMachinePlan(models.Model):
vm_type = models.ForeignKey(VirtualMachineType)
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
def create(cls, data, user):
instance = cls.objects.create(**data)
@@ -88,13 +102,23 @@ class VirtualMachinePlan(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)
billing_address = models.ForeignKey(BillingAddress)
created_at = models.DateTimeField(auto_now_add=True)
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)
+ @cached_property
+ def status(self):
+ return self.ORDER_APPROVED_STATUS if self.approved else self.ORDER_DECLINED_STATUS
+
@classmethod
def create(cls, VMPlan=None, customer=None, billing_address=None):
instance = cls.objects.create(VMPlan=VMPlan, customer=customer,
@@ -107,6 +131,8 @@ class HostingOrder(models.Model):
def set_stripe_charge(self, stripe_charge):
self.stripe_charge_id = stripe_charge.id
+ self.last4 = stripe_charge.source.last4
+ self.cc_brand = stripe_charge.source.brand
self.save()
diff --git a/hosting/static/hosting/css/commons.css b/hosting/static/hosting/css/commons.css
new file mode 100644
index 00000000..f386cfd6
--- /dev/null
+++ b/hosting/static/hosting/css/commons.css
@@ -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;
+}
diff --git a/hosting/static/hosting/css/order.css b/hosting/static/hosting/css/order.css
new file mode 100644
index 00000000..8e0c5919
--- /dev/null
+++ b/hosting/static/hosting/css/order.css
@@ -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;
+}
diff --git a/hosting/static/hosting/css/orders.css b/hosting/static/hosting/css/orders.css
new file mode 100644
index 00000000..64e95328
--- /dev/null
+++ b/hosting/static/hosting/css/orders.css
@@ -0,0 +1,5 @@
+.orders-container {padding-top:5%; padding-bottom: 11%;}
+
+.orders-container .table > tbody > tr > td {
+ vertical-align: middle;
+}
\ No newline at end of file
diff --git a/hosting/static/hosting/css/virtual-machine.css b/hosting/static/hosting/css/virtual-machine.css
new file mode 100644
index 00000000..570d5118
--- /dev/null
+++ b/hosting/static/hosting/css/virtual-machine.css
@@ -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;
+}
\ No newline at end of file
diff --git a/hosting/templates/hosting/base_short.html b/hosting/templates/hosting/base_short.html
index fabfa030..339020de 100644
--- a/hosting/templates/hosting/base_short.html
+++ b/hosting/templates/hosting/base_short.html
@@ -18,6 +18,10 @@
+
+
+
+
@@ -49,30 +53,51 @@
-
+
diff --git a/hosting/templates/hosting/invoice.html b/hosting/templates/hosting/invoice.html
deleted file mode 100644
index 302028fe..00000000
--- a/hosting/templates/hosting/invoice.html
+++ /dev/null
@@ -1,79 +0,0 @@
-{% extends "hosting/base_short.html" %}
-{% load staticfiles bootstrap3 %}
-{% block content %}
-
-
-
-
-
-
-
-
Invoice
Order # {{order.id}}
-
-
-
-
-
- Billed To:
- John Smith
- 1234 Main
- Apt. 4B
- Springfield, ST 54321
-
-
-
-
- Order Date:
- {{order.created_at}}
-
-
-
-
-
-
- Payment Method:
- {{brand}} ending **** {{last4}}
- {{user.email}}
-
-
-
-
-
-
-
-
-
Order summary
-
-
-
Type {{request.session.vm_specs.hosting_company_name}}
-
-
Cores {{request.session.vm_specs.cores}}
-
-
Memory {{request.session.vm_specs.memory}} GiB
-
-
Disk space {{request.session.vm_specs.disk_size}} GiB
-
-
Total
{{request.session.vm_specs.final_price}} CHF
-
-
-
-
-{%endblock%}
diff --git a/hosting/templates/hosting/order_detail.html b/hosting/templates/hosting/order_detail.html
new file mode 100644
index 00000000..74b8d5bb
--- /dev/null
+++ b/hosting/templates/hosting/order_detail.html
@@ -0,0 +1,64 @@
+{% extends "hosting/base_short.html" %}
+{% load staticfiles bootstrap3 %}
+{% block content %}
+
+
+
+
+
+
Invoice
Order # {{object.id}}
+
+
+
+
+
+ Billed To:
+ {{user.name}}
+ {{object.billing_address.street_address}},{{order.billing_address.postal_code}}
+ {{object.billing_address.city}}, {{object.billing_address.country}}.
+
+
+
+
+ Order Date:
+ {{object.created_at}}
+ Status:
+ {{object.status}}
+
+
+
+
+
+
+
+
+ Payment Method:
+ {{object.cc_brand}} ending **** {{object.last4}}
+ {{user.email}}
+
+
+
+
+
+
+
+
+
Order summary
+
+
+
Type {{object.VMPlan.hosting_company_name}}
+
+
Cores {{object.VMPlan.cores}}
+
+
Memory {{object.VMPlan.memory}} GiB
+
+
Disk space {{object.VMPlan.disk_size}} GiB
+
+
Total
{{object.VMPlan.price}} CHF
+
+
+
+
+{%endblock%}
diff --git a/hosting/templates/hosting/orders.html b/hosting/templates/hosting/orders.html
index df5e6216..99c6464f 100644
--- a/hosting/templates/hosting/orders.html
+++ b/hosting/templates/hosting/orders.html
@@ -1,31 +1,59 @@
{% extends "hosting/base_short.html" %}
{% load staticfiles bootstrap3 %}
{% block content %}
+
-
+
-
- My orders.
+
+ My Orders
+
# |
Date |
Amount |
Status |
+ |
{% for order in orders %}
- {{order.id}} |
+ {{order.id}} |
{{order.created_at}} |
- {{order.VMPlan.price}} |
- {{order.approved}} |
-
+ {{order.VMPlan.price}} CHF |
+ {% if order.approved %}
+ Approved
+ {% else%}
+ Declined
+ {% endif%}
+ |
+
+
+ |
+
{% endfor %}
+
+ {% if is_paginated %}
+
+ {% endif %}
+
diff --git a/hosting/templates/hosting/virtual_machine_detail.html b/hosting/templates/hosting/virtual_machine_detail.html
new file mode 100644
index 00000000..e51e1d4e
--- /dev/null
+++ b/hosting/templates/hosting/virtual_machine_detail.html
@@ -0,0 +1,155 @@
+{% extends "hosting/base_short.html" %}
+{% load staticfiles bootstrap3 %}
+{% block content %}
+
+
+
+
+
+
{{virtual_machine.name}}
+
+
+
+
+
+
+
+
+
+
{{virtual_machine.hosting_company_name}}
+
+
+
+
+
+
+
+
+ Cores
+ {{virtual_machine.cores}}
+
+
+
+
+ Memory
+ {{virtual_machine.memory}} GiB
+
+
+
+
+ Disk
+ {{virtual_machine.disk_size}} GiB
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Orders
+
+
+
+ # |
+ Date |
+ Amount |
+ Status |
+ |
+
+
+
+ {% for order in virtual_machine.hosting_orders.all %}
+
+ {{order.id}} |
+ {{order.created_at}} |
+ {{order.VMPlan.price}} CHF |
+ {% if order.approved %}
+ Approved
+ {% else%}
+ Declined
+ {% endif%}
+ |
+
+
+ |
+
+ {% endfor %}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+{%endblock%}
+
+
+
+
+
+
+
+
+
diff --git a/hosting/templates/hosting/virtual_machines.html b/hosting/templates/hosting/virtual_machines.html
new file mode 100644
index 00000000..fa673c99
--- /dev/null
+++ b/hosting/templates/hosting/virtual_machines.html
@@ -0,0 +1,56 @@
+{% extends "hosting/base_short.html" %}
+{% load staticfiles bootstrap3 %}
+{% block content %}
+
+
+
+
+
+ Virtual Machines
+
+
+
+ ID |
+ Type |
+ Amount |
+ |
+
+
+
+ {% for vm in vms %}
+
+ {{vm.name}} |
+ {{vm.hosting_company_name}} |
+ {{vm.price}} CHF |
+
+
+ |
+
+ {% endfor %}
+
+
+
+ {% if is_paginated %}
+
+ {% endif %}
+
+
+
+
+
+
+
+
+{%endblock%}
\ No newline at end of file
diff --git a/hosting/test_views.py b/hosting/test_views.py
new file mode 100644
index 00000000..b2dfe9ae
--- /dev/null
+++ b/hosting/test_views.py
@@ -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(),
+ }
diff --git a/hosting/urls.py b/hosting/urls.py
index 3b40dff8..bb195b79 100644
--- a/hosting/urls.py
+++ b/hosting/urls.py
@@ -1,20 +1,24 @@
from django.conf.urls import url
from .views import DjangoHostingView, RailsHostingView, PaymentVMView, \
- NodeJSHostingView, LoginView, SignupView, IndexView, \
- InvoiceVMView, OrdersHostingView
+ NodeJSHostingView, LoginView, SignupView, IndexView, \
+ OrdersHostingListView, OrdersHostingDetailView, VirtualMachinesPlanListView,\
+ VirtualMachineDetailListView
urlpatterns = [
# url(r'pricing/?$', VMPricingView.as_view(), name='pricing'),
url(r'index/?$', IndexView.as_view(), name='index'),
url(r'django/?$', DjangoHostingView.as_view(), name='djangohosting'),
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'invoice/?$', InvoiceVMView.as_view(), name='invoice'),
- url(r'orders/?$', OrdersHostingView.as_view(), name='orders'),
- url(r'login/?$', LoginView.as_view(), name='login'),
+ url(r'orders/?$', OrdersHostingListView.as_view(), name='orders'),
+ url(r'orders/(?P\d+)/?$', OrdersHostingDetailView.as_view(), name='orders'),
+ url(r'my-virtual-machines/?$', VirtualMachinesPlanListView.as_view(), name='virtual_machines'),
+ url(r'my-virtual-machines/(?P\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'^logout/?$', 'django.contrib.auth.views.logout',
- {'next_page': '/ungleich_page'}, name='logout')
+ {'next_page': '/ungleich_page'}, name='logout')
]
diff --git a/hosting/views.py b/hosting/views.py
index 65bbbcf3..b0e76028 100644
--- a/hosting/views.py
+++ b/hosting/views.py
@@ -2,16 +2,12 @@
from django.shortcuts import get_object_or_404, render
from django.core.urlresolvers import reverse_lazy, reverse
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.shortcuts import redirect
+from django.views.generic import View, CreateView, FormView, ListView, DetailView
from django.http import HttpResponseRedirect
from django.contrib.auth import authenticate, login
from django.conf import settings
-from membership.forms import PaymentForm
from membership.models import CustomUser, StripeCustomer
from utils.stripe_utils import StripeUtils
from utils.forms import BillingAddressForm
@@ -21,7 +17,6 @@ from .forms import HostingUserSignupForm, HostingUserLoginForm
from .mixins import ProcessVMSelectionMixin
-
class DjangoHostingView(ProcessVMSelectionMixin, View):
template_name = "hosting/django.html"
@@ -106,7 +101,7 @@ class IndexView(View):
class LoginView(FormView):
template_name = 'hosting/login.html'
- success_url = reverse_lazy('hosting:login')
+ success_url = reverse_lazy('hosting:orders')
form_class = HostingUserLoginForm
moodel = CustomUser
@@ -217,60 +212,45 @@ class PaymentVMView(FormView):
'order': order.id,
'billing_address': billing_address.id
})
- return HttpResponseRedirect(reverse('hosting:invoice'))
+ return HttpResponseRedirect(reverse('hosting:orders', kwargs={'pk': order.id}))
else:
return self.form_invalid(form)
-class InvoiceVMView(LoginRequiredMixin, View):
- template_name = "hosting/invoice.html"
+class OrdersHostingDetailView(LoginRequiredMixin, DetailView):
+ template_name = "hosting/order_detail.html"
login_url = reverse_lazy('hosting:login')
-
- 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)
+ model = HostingOrder
-class OrdersHostingView(LoginRequiredMixin, View):
+class OrdersHostingListView(LoginRequiredMixin, ListView):
template_name = "hosting/orders.html"
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
- orders = HostingOrder.objects.filter(customer__user=user)
- context = {
- 'orders':orders
- }
-
- return context
-
- def get(self, request, *args, **kwargs):
-
- context = self.get_context_data()
-
- return render(request, self.template_name, context)
+ self.queryset = HostingOrder.objects.filter(customer__user=user)
+ return super(OrdersHostingListView, self).get_queryset()
+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"
diff --git a/membership/models.py b/membership/models.py
index a607906c..75962660 100644
--- a/membership/models.py
+++ b/membership/models.py
@@ -131,7 +131,7 @@ class StripeCustomer(models.Model):
Check if there is a registered stripe customer with that email
or create a new one
"""
-
+ stripe_customer = None
try:
stripe_utils = StripeUtils()
stripe_customer = cls.objects.get(user__email=email)
diff --git a/utils/stripe_utils.py b/utils/stripe_utils.py
index c0ea630b..ce14d417 100644
--- a/utils/stripe_utils.py
+++ b/utils/stripe_utils.py
@@ -52,8 +52,6 @@ def handleStripeError(f):
return handleProblems
-
-
class StripeUtils(object):
CURRENCY = 'chf'
INTERVAL = 'month'
@@ -71,7 +69,7 @@ class StripeUtils(object):
customer = stripe.Customer.retrieve(id)
except stripe.InvalidRequestError:
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()
return customer