Added pagination to orders view, Created, Virtual machines booked page ,Changed logged user nabber , Added pagination to virtual machines view , Started Virtual machine detail page
This commit is contained in:
		
					parent
					
						
							
								c4bf4fc6ff
							
						
					
				
			
			
				commit
				
					
						7d697b3c3a
					
				
			
		
					 12 changed files with 289 additions and 116 deletions
				
			
		
							
								
								
									
										8
									
								
								hosting/managers.py
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								hosting/managers.py
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,8 @@ | ||||||
|  | from django.db import models | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | class VMPlansManager(models.Manager): | ||||||
|  | 
 | ||||||
|  |     def active(self, user, **kwargs): | ||||||
|  |         return self.select_related('hostingorder__customer__user').\ | ||||||
|  |             filter(hostingorder__customer__user=user, hostingorder__approved=True, **kwargs) | ||||||
							
								
								
									
										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, | ||||||
|  |         ), | ||||||
|  |     ] | ||||||
|  | @ -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,12 @@ 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() | ||||||
|  | 
 | ||||||
|     @classmethod |     @classmethod | ||||||
|     def create(cls, data, user): |     def create(cls, data, user): | ||||||
|         instance = cls.objects.create(**data) |         instance = cls.objects.create(**data) | ||||||
|  | @ -88,13 +97,23 @@ class VirtualMachinePlan(models.Model): | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| class HostingOrder(models.Model): | class HostingOrder(models.Model): | ||||||
|  | 
 | ||||||
|  |     ORDER_APPROVED_STATUS = 'Approved' | ||||||
|  |     ORDER_DECLINED_STATUS = 'Declined' | ||||||
|  | 
 | ||||||
|     VMPlan = models.OneToOneField(VirtualMachinePlan) |     VMPlan = models.OneToOneField(VirtualMachinePlan) | ||||||
|     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 +126,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() | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
							
								
								
									
										15
									
								
								hosting/static/hosting/css/commons.css
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								hosting/static/hosting/css/commons.css
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,15 @@ | ||||||
|  | .dashboard-container { | ||||||
|  | 	padding-top:5%; padding-bottom: 11%; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .borderless td { | ||||||
|  |     border: none !important; | ||||||
|  | } | ||||||
|  | .borderless thead { | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .borderless tbody:before { | ||||||
|  |     content: "-"; | ||||||
|  |     display: block; | ||||||
|  |     color: transparent; | ||||||
|  | } | ||||||
							
								
								
									
										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; | ||||||
|  | } | ||||||
|  | @ -18,6 +18,9 @@ | ||||||
|     <!-- 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/orders.css' %}" rel="stylesheet"> | ||||||
|  |     <link href="{% static 'hosting/css/orders.css' %}" rel="stylesheet"> | ||||||
|  |     <link href="{% static 'hosting/css/commons.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,11 +52,33 @@ | ||||||
|                     <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"> | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |                     {% if request.user.is_authenticated %} | ||||||
|  |                         <li> | ||||||
|  |                             <a href="{% url 'hosting:virtual_machines' %}"> | ||||||
|  |                                 <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> |                         <li> | ||||||
|                             <a href="{{ request.META.HTTP_REFERER }}#how">How it works</a> |                             <a href="{{ request.META.HTTP_REFERER }}#how">How it works</a> | ||||||
|                         </li> |                         </li> | ||||||
|  | @ -69,9 +94,8 @@ | ||||||
|                         <li> |                         <li> | ||||||
|                             <a href="{{ request.META.HTTP_REFERER }}#contact">Contact</a> |                             <a href="{{ request.META.HTTP_REFERER }}#contact">Contact</a> | ||||||
|                         </li>   |                         </li>   | ||||||
|                     {% if request.user.is_authenticated %} |  | ||||||
|                         <li> |                         <li> | ||||||
|                         <a href="{% url 'hosting:logout' %}"> Logout</a> |                             <a href="{% url 'hosting:login' %}?next={{request.current_path}}">Login</a> | ||||||
|                         </li>    |                         </li>    | ||||||
|                     {% endif %} |                     {% endif %} | ||||||
|                 </ul> |                 </ul> | ||||||
|  |  | ||||||
|  | @ -2,55 +2,37 @@ | ||||||
| {% load staticfiles bootstrap3 %} | {% load staticfiles bootstrap3 %} | ||||||
| {% block content %}  | {% block content %}  | ||||||
| 
 | 
 | ||||||
| <style type="text/css"> | <div class="container  order-detail-container"> | ||||||
| .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="row"> | ||||||
|         <div class="col-xs-8 col-xs-offset-2"> |         <div class="col-xs-8 col-xs-offset-2"> | ||||||
|     		<div class="invoice-title"> |     		<div class="invoice-title"> | ||||||
|     			<h2>Invoice</h2><h3 class="pull-right">Order # {{order.id}}</h3> |     			<h2>Invoice</h2><h3 class="pull-right">Order # {{object.id}}</h3> | ||||||
|     		</div> |     		</div> | ||||||
|     		<hr> |     		<hr> | ||||||
|     		<div class="row"> |     		<div class="row"> | ||||||
|     			<div class="col-xs-6"> |     			<div class="col-xs-6"> | ||||||
|     				<address> |     				<address> | ||||||
|                     <h3><b>Billed To:</b></h3> |                     <h3><b>Billed To:</b></h3> | ||||||
|     					John Smith<br> |     					{{user.name}}<br> | ||||||
|     					1234 Main<br> |                         {{object.billing_address.street_address}},{{order.billing_address.postal_code}}<br> | ||||||
|     					Apt. 4B<br> |                         {{object.billing_address.city}}, {{object.billing_address.country}}. | ||||||
|     					Springfield, ST 54321 |  | ||||||
|     				</address> |     				</address> | ||||||
|     			</div> |     			</div> | ||||||
|                 <div class="col-xs-6 text-right"> |                 <div class="col-xs-6 text-right"> | ||||||
|                     <address> |                     <address> | ||||||
|                         <strong>Order Date:</strong><br> |                         <strong>Order Date:</strong><br> | ||||||
|                         {{order.created_at}}<br><br> |                         {{object.created_at}}<br><br> | ||||||
|  |                         <strong>Status:</strong><br> | ||||||
|  |                         <strong class="text-danger">{{object.status}}</strong><br><br> | ||||||
|                     </address> |                     </address> | ||||||
|  | 
 | ||||||
|                 </div> |                 </div> | ||||||
|     		</div> |     		</div> | ||||||
|     		<div class="row"> |     		<div class="row"> | ||||||
|     			<div class="col-xs-6"> |     			<div class="col-xs-6"> | ||||||
|     				<address> |     				<address> | ||||||
|     					<strong>Payment Method:</strong><br> |     					<strong>Payment Method:</strong><br> | ||||||
|     					{{brand}} ending **** {{last4}}<br> |     					{{object.cc_brand}} ending **** {{object.last4}}<br> | ||||||
|     					{{user.email}} |     					{{user.email}} | ||||||
|     				</address> |     				</address> | ||||||
|     			</div> |     			</div> | ||||||
|  | @ -63,15 +45,15 @@ | ||||||
|             <h3><b>Order summary</b></h3> |             <h3><b>Order summary</b></h3> | ||||||
|             <hr> |             <hr> | ||||||
|             <div class="content"> |             <div class="content"> | ||||||
|                 <p><b>Type</b> <span class="pull-right">{{request.session.vm_specs.hosting_company_name}}</span></p> |                 <p><b>Type</b> <span class="pull-right">{{object.VMPlan.hosting_company_name}}</span></p> | ||||||
|                 <hr> |                 <hr> | ||||||
|                 <p><b>Cores</b> <span class="pull-right">{{request.session.vm_specs.cores}}</span></p> |                 <p><b>Cores</b> <span class="pull-right">{{object.VMPlan.cores}}</span></p> | ||||||
|                 <hr> |                 <hr> | ||||||
|                 <p><b>Memory</b> <span class="pull-right">{{request.session.vm_specs.memory}} GiB</span></p> |                 <p><b>Memory</b> <span class="pull-right">{{object.VMPlan.memory}} GiB</span></p> | ||||||
|                 <hr> |                 <hr> | ||||||
|                 <p><b>Disk space</b> <span class="pull-right">{{request.session.vm_specs.disk_size}} GiB</span></p> |                 <p><b>Disk space</b> <span class="pull-right">{{object.VMPlan.disk_size}} GiB</span></p> | ||||||
|                 <hr> |                 <hr> | ||||||
|                 <h4>Total<p class="pull-right"><b>{{request.session.vm_specs.final_price}} CHF</b></p></h4> |                 <h4>Total<p class="pull-right"><b>{{object.VMPlan.price}} CHF</b></p></h4> | ||||||
|             </div> |             </div> | ||||||
|         </div> |         </div> | ||||||
|     </div> |     </div> | ||||||
|  | @ -1,31 +1,75 @@ | ||||||
| {% extends "hosting/base_short.html" %} | {% extends "hosting/base_short.html" %} | ||||||
| {% load staticfiles bootstrap3 %} | {% load staticfiles bootstrap3 %} | ||||||
| {% block content %}  | {% block content %}  | ||||||
|  | 
 | ||||||
|  | <style type="text/css"> | ||||||
|  | 	 | ||||||
|  | .borderless td { | ||||||
|  |     border: none !important; | ||||||
|  | } | ||||||
|  | .borderless thead { | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .borderless tbody:before { | ||||||
|  |     content: "-"; | ||||||
|  |     display: block; | ||||||
|  |     color: transparent; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | </style> | ||||||
|  | 
 | ||||||
| <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 %} | ||||||
|  | 								<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> | 					</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> | ||||||
|  |  | ||||||
							
								
								
									
										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.id}}</td>  | ||||||
|  | 						<td>{{vm.hosting_company_name}}</td>  | ||||||
|  | 						<td>{{vm.price}} CHF</td>  | ||||||
|  | 						<td> | ||||||
|  | 							<button type="button" class="btn btn-default"><a href="">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%} | ||||||
|  | @ -2,7 +2,7 @@ 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 | ||||||
| 
 | 
 | ||||||
| urlpatterns = [ | urlpatterns = [ | ||||||
|     url(r'index/?$', IndexView.as_view(), name='index'), |     url(r'index/?$', IndexView.as_view(), name='index'), | ||||||
|  | @ -10,8 +10,9 @@ urlpatterns = [ | ||||||
|     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'my-virtual-machines/?$', VirtualMachinesPlanListView.as_view(), name='virtual_machines'), | ||||||
|     url(r'login/?$', LoginView.as_view(), name='login'), |     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', | ||||||
|  |  | ||||||
|  | @ -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" | ||||||
| 
 | 
 | ||||||
|  | @ -217,60 +212,38 @@ 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() | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue