From c2b5c620147231de927719384b92091a94fb31ab Mon Sep 17 00:00:00 2001 From: Arvind Tiwari Date: Fri, 15 Sep 2017 00:49:39 +0530 Subject: [PATCH 01/29] hosting calculator added --- .../static/hosting/css/price_calculator.css | 186 ++++++++++++++++++ hosting/templates/hosting/base_short.html | 4 +- .../templates/hosting/calculator_form.html | 123 ++++++++++++ .../hosting/create_virtual_machine.html | 87 +++----- 4 files changed, 334 insertions(+), 66 deletions(-) create mode 100644 hosting/static/hosting/css/price_calculator.css create mode 100644 hosting/templates/hosting/calculator_form.html diff --git a/hosting/static/hosting/css/price_calculator.css b/hosting/static/hosting/css/price_calculator.css new file mode 100644 index 00000000..bf99c66f --- /dev/null +++ b/hosting/static/hosting/css/price_calculator.css @@ -0,0 +1,186 @@ +/*Pricing page*/ + +.price-calc-section { + padding: 80px 40px !important; + background: -webkit-linear-gradient(top, #f0f4f7, #fff) no-repeat; + background: linear-gradient(to bottom, #f0f4f7, #fff) no-repeat; + display: flex; + /*font-family: 'Lato', sans-serif;*/ +/* font-weight: normal; */ +} + +.price-calc-section .text { + width: 50%; +} + +.price-calc-section .text .section-heading { + font-size: 48px; + line-height: 48px; + padding-bottom: 27px; + color: #3a3a3a; + letter-spacing: 1px; + position: relative; + text-align: right; +} + +.price-calc-section .text .description { + font-size: 20px; + text-align: right; +} + +.price-calc-section .text .section-heading::before { + content: ""; + position: absolute; + bottom: 0; + background: #29427A; + height: 7px; + width: 70px; + right: 0; +} + +.price-calc-section .card { + width: 50%; + margin: 0 auto; + background: #fff; + box-shadow: 0 10px 20px rgba(0, 0, 0, 0.19), 0 6px 6px rgba(0, 0, 0, 0.23); + padding-bottom: 40px; + border-radius: 7px; + text-align: center; + /* margin-right: auto; */ + max-width: 400px; + position: relative; +} + +.price-calc-section .landing { + width: 100% !important; +} + +.no-padding { + padding: 0 !important; +} + +.price-calc-section .card .img-beta { + position: absolute; + top: 5px; + width: 60px; + left: 3px; +} + +.price-calc-section .card .title { + padding: 15px 40px; +} + +.price-calc-section .card .title h3 { + /*font-family: 'Lato', sans-serif;*/ + font-weight: normal; +} + +.price-calc-section .card .price { + background: #5A74AF; + padding: 22px; + color: #fff; + font-size: 32px; +} + +.price-calc-section .card .price .price-text { + font-size: 14px; +} + +.price-calc-section .card .description { + padding: 12px; + position: relative; + display: flex; + justify-content: space-around !important; + align-items: center !important; +} + +.price-calc-section .card .description span { + font-size: 16px; + margin-left: 4px; + margin-left: 0px; + /* justify-self: start; */ + width: 30%; + text-align: left; +} + +.price-calc-section .card .description .select-number{ + font-size: 20px; + text-align: center; + width: 85px; +} + +.price-calc-section .card .description i { + color: #29427A; + cursor: pointer; + font-size: 24px; +} + +.price-calc-section .card .description .left { + margin-right: 7px; +} + +.price-calc-section .card .description .right { + margin-left: 7px; +} + +.price-calc-section .card .descriptions { + padding: 10px 30px; +} + +.price-calc-section .card .description p { + margin: 0; +} + +.price-calc-section .card .btn { + margin-top: 20px; + font-size: 20px; + width: 200px; + border: none; +} + +.price-calc-section .card .select-configuration select { + outline: none; + background: #fff; + border-color: #d0d0d0; + height: 40px; + width: 200px; + text-align: center; + font-size: 16px; + margin-left: 10px; +} + +.price-calc-section .card .check-ip { + font-size: 18px; +} + +.price-calc-section .card .justify-center { + justify-content: center !important; +} + +.price-calc-section .card .description.input label { + font-size: 15px; + font-weight: 700; + /*font-weight: 800;*/ + /*font-family: 'Lato';*/ + margin-bottom: 0; + width: 40px; +} + + +/*Changed class****.price-calc-section .card .description.input input*/ + +.price-calc-section .card .description input { + width: 200px; + font-size: 14px; + text-align: left; + padding: 5px 10px; + border-radius: 4px; + border: 1px solid #d0d0d0; + background: #fff; + margin-left: 10px; +} + +.price-calc-section .card .check-ip input[type=checkbox] { + font-size: 17px; + margin: 0 8px; +} \ No newline at end of file diff --git a/hosting/templates/hosting/base_short.html b/hosting/templates/hosting/base_short.html index 63a0681d..becb7873 100644 --- a/hosting/templates/hosting/base_short.html +++ b/hosting/templates/hosting/base_short.html @@ -25,6 +25,7 @@ + {% block css_extra %} {% endblock css_extra %} @@ -33,9 +34,6 @@ - - - diff --git a/hosting/templates/hosting/calculator_form.html b/hosting/templates/hosting/calculator_form.html new file mode 100644 index 00000000..cdba4809 --- /dev/null +++ b/hosting/templates/hosting/calculator_form.html @@ -0,0 +1,123 @@ +{% load staticfiles i18n%} +
+ {% csrf_token %} +
+

{% trans "VM hosting" %}

+
+
+ 15 + CHF/{% trans "month" %} +
+

{% trans "VAT included" %}

+
+
+
+
+

{% trans "Hosted in Switzerland" %}

+
+
+
+ + + Core + +
+
+ {% for message in messages %} + {% if 'cores' in message.tags %} +
  • + {{ message|safe }} +
+ {% endif %} + {% endfor %} +
+
+
+
+ + + GB RAM + +
+
+ {% for message in messages %} + {% if 'memory' in message.tags %} +
  • + {{ message|safe }} +
+ {% endif %} + {% endfor %} +
+
+
+
+ + + {% trans "GB Storage (SSD)" %} + +
+
+ {% for message in messages %} + {% if 'storage' in message.tags %} +
  • + {{ message|safe }} +
+ {% endif %} + {% endfor %} +
+
+
+ + +
+ + +
+
+ + +
+
+ {% for message in messages %} + {% if 'name' in message.tags %} +
    +
  • + {{ message|safe }} +
  • +
+ {% endif %} + {% endfor %} +
+
+
+
+ + +
+
+ {% for message in messages %} + {% if 'email' in message.tags %} +
    +
  • + {{ message|safe }} +
  • +
+ {% endif %} + {% endfor %} +
+
+
+ +
diff --git a/hosting/templates/hosting/create_virtual_machine.html b/hosting/templates/hosting/create_virtual_machine.html index f876ad76..5a5e789e 100644 --- a/hosting/templates/hosting/create_virtual_machine.html +++ b/hosting/templates/hosting/create_virtual_machine.html @@ -1,70 +1,31 @@ {% extends "hosting/base_short.html" %} {% load staticfiles bootstrap3 i18n %} -{% block content %} -
-
-
-
-
- {% if messages %} -
- {% for message in messages %} - {{ message }} - {% endfor %} -
- {% endif %} +{% block content %} +
+
+
+
+

{% trans "Create VM" %}

+ {% if messages %} +
+ {% for message in messages %} + {{ message }} + {% endfor %} +
+ {% endif %} +
+
+
+
+
+ +
+ {% include "hosting/calculator_form.html" %} +
- {% if not error %} -
-

{% trans "New Virtual Machine"%}

-
-
- -
- {% csrf_token %} - -
-

{% trans "Step 1. Select VM Template:" %}

-
-
- - -
-
-

{% trans "Step2. Select VM Configuration" %}

-
-
- - -
-
-
- {% trans "Price " %}0{% trans "CHF/Month" %} -
- -
-
- {% endif %} +
-
- -{%endblock%} +{%endblock%} \ No newline at end of file From 87327d028a1fac59192783082a9f181b5c2022ad Mon Sep 17 00:00:00 2001 From: Arvind Tiwari Date: Fri, 15 Sep 2017 20:03:52 +0530 Subject: [PATCH 02/29] hosting form view modified --- .../datacenterlight/calculator_form.html | 6 +- .../static/hosting/css/price_calculator.css | 99 +++++++++---- hosting/static/hosting/js/createvm.js | 137 +++++++++--------- hosting/static/hosting/js/createvm_old.js | 73 ++++++++++ hosting/templates/hosting/base_short.html | 6 +- .../templates/hosting/calculator_form.html | 86 ++++------- .../hosting/create_virtual_machine.html | 19 ++- hosting/views.py | 102 ++++++++----- 8 files changed, 324 insertions(+), 204 deletions(-) create mode 100644 hosting/static/hosting/js/createvm_old.js diff --git a/datacenterlight/templates/datacenterlight/calculator_form.html b/datacenterlight/templates/datacenterlight/calculator_form.html index cdba4809..b5bac1f9 100644 --- a/datacenterlight/templates/datacenterlight/calculator_form.html +++ b/datacenterlight/templates/datacenterlight/calculator_form.html @@ -26,9 +26,9 @@
{% for message in messages %} {% if 'cores' in message.tags %} -
  • - {{ message|safe }} -
+
    +
  • {{ message|safe }}
  • +
{% endif %} {% endfor %}
diff --git a/hosting/static/hosting/css/price_calculator.css b/hosting/static/hosting/css/price_calculator.css index bf99c66f..5aac2c97 100644 --- a/hosting/static/hosting/css/price_calculator.css +++ b/hosting/static/hosting/css/price_calculator.css @@ -1,12 +1,13 @@ -/*Pricing page*/ +/* Create VM calculator */ .price-calc-section { padding: 80px 40px !important; - background: -webkit-linear-gradient(top, #f0f4f7, #fff) no-repeat; - background: linear-gradient(to bottom, #f0f4f7, #fff) no-repeat; - display: flex; - /*font-family: 'Lato', sans-serif;*/ -/* font-weight: normal; */ +} + +@media (max-width: 768px) { + .price-calc-section { + margin-top: 40px; + } } .price-calc-section .text { @@ -42,12 +43,12 @@ width: 50%; margin: 0 auto; background: #fff; - box-shadow: 0 10px 20px rgba(0, 0, 0, 0.19), 0 6px 6px rgba(0, 0, 0, 0.23); - padding-bottom: 40px; - border-radius: 7px; + box-shadow: 1px 3px 6px 2px rgba(0, 0, 0, 0.2); + padding-bottom: 30px; + /* border-radius: 7px; */ text-align: center; /* margin-right: auto; */ - max-width: 400px; + max-width: 320px; position: relative; } @@ -87,7 +88,7 @@ } .price-calc-section .card .description { - padding: 12px; + padding: 7px 8px 2px; position: relative; display: flex; justify-content: space-around !important; @@ -95,24 +96,29 @@ } .price-calc-section .card .description span { - font-size: 16px; - margin-left: 4px; - margin-left: 0px; + font-size: 14px; + margin-left: 5px; + /* margin-left: 0px; */ /* justify-self: start; */ - width: 30%; + width: 29%; text-align: left; + line-height: 16px; + /* font-weight: normal; */ } .price-calc-section .card .description .select-number{ - font-size: 20px; + font-size: 16px; text-align: center; width: 85px; } .price-calc-section .card .description i { - color: #29427A; + color: #29427a; cursor: pointer; - font-size: 24px; + font-size: 20px; + border: 1px solid #eee; + padding: 5px 6px 3px; + border-radius: 5px; } .price-calc-section .card .description .left { @@ -124,7 +130,7 @@ } .price-calc-section .card .descriptions { - padding: 10px 30px; + padding: 10px; } .price-calc-section .card .description p { @@ -132,9 +138,9 @@ } .price-calc-section .card .btn { - margin-top: 20px; + margin-top: 15px; font-size: 20px; - width: 200px; + width: 150px; border: none; } @@ -142,11 +148,13 @@ outline: none; background: #fff; border-color: #d0d0d0; - height: 40px; - width: 200px; + height: 32px; + width: 150px; text-align: center; - font-size: 16px; + font-size: 14px; margin-left: 10px; + padding: 6px; + border-radius: 4px; } .price-calc-section .card .check-ip { @@ -173,7 +181,7 @@ width: 200px; font-size: 14px; text-align: left; - padding: 5px 10px; + padding: 4px 10px; border-radius: 4px; border: 1px solid #d0d0d0; background: #fff; @@ -183,4 +191,43 @@ .price-calc-section .card .check-ip input[type=checkbox] { font-size: 17px; margin: 0 8px; -} \ No newline at end of file +} + +.help-block.with-errors { + text-align: center; + margin: 0 0; + padding: 0 0 5px; +} +.help-block.with-errors ul { + margin-bottom: 0; +} + +.form-group { + margin: 0; + position: relative; +} + +.form-group:after { + content: ' '; + display: block; + position: absolute; + bottom: 0; + left: 18%; + z-index: 20; + height: 1px; + width: 65%; + background: rgba(128, 128, 128, 0.2); +} + +.btn-primary { + background: #29427A; + border-color: #29427A; + color: #fff; + width: auto; +} + +@media(min-width: 768px) { + .create-vm-container { + padding-top: 120px; + } +} diff --git a/hosting/static/hosting/js/createvm.js b/hosting/static/hosting/js/createvm.js index 53646b40..344aedfb 100644 --- a/hosting/static/hosting/js/createvm.js +++ b/hosting/static/hosting/js/createvm.js @@ -1,73 +1,76 @@ (function($){ "use strict"; // Start of use strict - - - $(window).load(function(){ - - - }); - - $(document).ready(function(){ - _initOs(); - - }); - - $(window).resize(function(){ - - - }); - - - function _initOs(){ - - - $('.os-circle').click(function(event){ - $('.os-circle').removeClass('active'); - $(this).addClass('active'); - - var idTemplate = $(this).data('id'); - $('input[name=vm_template_id]').val(idTemplate); - }); - $('.config-box').click(function(event){ - $('.config-box').removeClass('active'); - $(this).addClass('active'); - var idConfig = $(this).data('id'); - var price = $(this).data('price'); - $('input[name=configuration]').val(idConfig); - $('.container-button').fadeIn(); - $('#priceValue').text(price); - }); - - $('.owl-carousel').owlCarousel({ - items:4, - nav: true, - margin:30, - responsiveClass:true, - navText: ['', ''], - responsive:{ - 0:{ - items:1, - nav:true - }, - 600:{ - items:2, - nav:true - }, - 768:{ - items:3, - nav:true - }, - 990:{ - items:4, - nav:true - } + var cardPricing = { + 'cpu': { + 'id': 'coreValue', + 'value': 1, + 'min': 1, + 'max': 48, + 'interval': 1 + }, + 'ram': { + 'id': 'ramValue', + 'value': 2, + 'min': 2, + 'max': 200, + 'interval': 1 + }, + 'storage': { + 'id': 'storageValue', + 'value': 10, + 'min': 10, + 'max': 2000, + 'interval': 10 } - }); - } - - - -})(jQuery); + }; + + function _initPricing() { + _fetchPricing(); + + $('.fa-minus.left').click(function(event) { + var data = $(this).data('minus'); + + if (cardPricing[data].value > cardPricing[data].min) { + cardPricing[data].value = Number(cardPricing[data].value) - cardPricing[data].interval; + } + _fetchPricing(); + }); + $('.fa-plus.right').click(function(event) { + var data = $(this).data('plus'); + if (cardPricing[data].value < cardPricing[data].max) { + cardPricing[data].value = Number(cardPricing[data].value) + cardPricing[data].interval; + } + _fetchPricing(); + }); + + $('.input-price').change(function() { + var data = $(this).attr("name"); + cardPricing[data].value = $('input[name=' + data + ']').val(); + _fetchPricing(); + }); + } + + function _fetchPricing() { + Object.keys(cardPricing).map(function(element) { + //$('#'+cardPricing[element].id).val(cardPricing[element].value); + $('input[name=' + element + ']').val(cardPricing[element].value); + }); + _calcPricing(); + } + + function _calcPricing() { + var total = (cardPricing['cpu'].value * 5) + (2 * cardPricing['ram'].value) + (0.6 * cardPricing['storage'].value); + total = parseFloat(total.toFixed(2)); + + $("#total").text(total); + $('input[name=total]').val(total); + } + + $(document).ready(function() { + _initPricing(); + }); + +})(jQuery); diff --git a/hosting/static/hosting/js/createvm_old.js b/hosting/static/hosting/js/createvm_old.js new file mode 100644 index 00000000..53646b40 --- /dev/null +++ b/hosting/static/hosting/js/createvm_old.js @@ -0,0 +1,73 @@ +(function($){ + "use strict"; // Start of use strict + + + $(window).load(function(){ + + + }); + + $(document).ready(function(){ + _initOs(); + + }); + + $(window).resize(function(){ + + + }); + + + + function _initOs(){ + + + $('.os-circle').click(function(event){ + $('.os-circle').removeClass('active'); + $(this).addClass('active'); + + var idTemplate = $(this).data('id'); + $('input[name=vm_template_id]').val(idTemplate); + }); + $('.config-box').click(function(event){ + $('.config-box').removeClass('active'); + $(this).addClass('active'); + var idConfig = $(this).data('id'); + var price = $(this).data('price'); + $('input[name=configuration]').val(idConfig); + $('.container-button').fadeIn(); + $('#priceValue').text(price); + }); + + $('.owl-carousel').owlCarousel({ + items:4, + nav: true, + margin:30, + responsiveClass:true, + navText: ['', ''], + responsive:{ + 0:{ + items:1, + nav:true + }, + 600:{ + items:2, + nav:true + }, + 768:{ + items:3, + nav:true + }, + 990:{ + items:4, + nav:true + } + } + }); + } + + + +})(jQuery); + + diff --git a/hosting/templates/hosting/base_short.html b/hosting/templates/hosting/base_short.html index becb7873..382e763f 100644 --- a/hosting/templates/hosting/base_short.html +++ b/hosting/templates/hosting/base_short.html @@ -74,8 +74,8 @@ {% endif %} - - + + @@ -106,8 +106,6 @@ - - diff --git a/hosting/templates/hosting/calculator_form.html b/hosting/templates/hosting/calculator_form.html index cdba4809..5ba2a4c3 100644 --- a/hosting/templates/hosting/calculator_form.html +++ b/hosting/templates/hosting/calculator_form.html @@ -1,27 +1,20 @@ {% load staticfiles i18n%}
{% csrf_token %} -
-

{% trans "VM hosting" %}

-
15 - CHF/{% trans "month" %} + CHF/30 {% trans "days" %}

{% trans "VAT included" %}

-
-

{% trans "Hosted in Switzerland" %}

-
- - + + Core - +
{% for message in messages %} @@ -35,11 +28,11 @@
- + GB RAM - +
{% for message in messages %} @@ -53,11 +46,11 @@
- + {% trans "GB Storage (SSD)" %} - +
{% for message in messages %} @@ -69,55 +62,26 @@ {% endfor %}
-
- - + {% for template in templates %} + + {% endfor %} + +
+
+ {% for message in messages %} + {% if 'cores' in message.tags %} +
  • + {{ message|safe }} +
+ {% endif %} {% endfor %} - +
- -
-
- - -
-
- {% for message in messages %} - {% if 'name' in message.tags %} -
    -
  • - {{ message|safe }} -
  • -
- {% endif %} - {% endfor %} -
-
-
-
- - -
-
- {% for message in messages %} - {% if 'email' in message.tags %} -
    -
  • - {{ message|safe }} -
  • -
- {% endif %} - {% endfor %} -
-
diff --git a/hosting/templates/hosting/create_virtual_machine.html b/hosting/templates/hosting/create_virtual_machine.html index 5a5e789e..dff82199 100644 --- a/hosting/templates/hosting/create_virtual_machine.html +++ b/hosting/templates/hosting/create_virtual_machine.html @@ -2,24 +2,23 @@ {% load staticfiles bootstrap3 i18n %} {% block content %} -
+
-

{% trans "Create VM" %}

- {% if messages %} -
- {% for message in messages %} - {{ message }} - {% endfor %} -
- {% endif %} +

{% trans "Create VM" %}

+ {% if messages %} +
+ {% for message in messages %} + {{ message }} + {% endfor %} +
+ {% endif %}
-
{% include "hosting/calculator_form.html" %}
diff --git a/hosting/views.py b/hosting/views.py index f7d6e414..a61f4e41 100644 --- a/hosting/views.py +++ b/hosting/views.py @@ -1,9 +1,11 @@ import uuid +from django import forms from django.conf import settings from django.contrib import messages from django.contrib.auth.mixins import LoginRequiredMixin from django.contrib.auth.tokens import default_token_generator +from django.core.exceptions import ValidationError from django.core.files.base import ContentFile from django.core.urlresolvers import reverse_lazy, reverse from django.http import Http404 @@ -25,7 +27,7 @@ from stored_messages.settings import stored_messages_settings from membership.models import CustomUser, StripeCustomer from opennebula_api.models import OpenNebulaManager from opennebula_api.serializers import VirtualMachineSerializer, \ - VirtualMachineTemplateSerializer + VirtualMachineTemplateSerializer, VMTemplateSerializer from utils.forms import BillingAddressForm, PasswordResetRequestForm, \ UserBillingAddressForm from utils.mailer import BaseEmail @@ -36,6 +38,8 @@ from .forms import HostingUserSignupForm, HostingUserLoginForm, \ UserHostingKeyForm, generate_ssh_key_name from .mixins import ProcessVMSelectionMixin from .models import HostingOrder, HostingBill, HostingPlan, UserHostingKey +from datacenterlight.models import VMTemplate + CONNECTION_ERROR = "Your VMs cannot be displayed at the moment due to a backend \ connection error. please try again in a few minutes." @@ -711,7 +715,7 @@ class PaymentVMView(LoginRequiredMixin, FormView): request.get_host()), 'page_header': _( 'Your New VM %(vm_name)s at Data Center Light') % { - 'vm_name': vm.get('name')} + 'vm_name': vm.get('name')} } email_data = { 'subject': context.get('page_header'), @@ -827,48 +831,80 @@ class CreateVirtualMachinesView(LoginRequiredMixin, View): template_name = "hosting/create_virtual_machine.html" login_url = reverse_lazy('hosting:login') - def get(self, request, *args, **kwargs): + def validate_cores(self, value): + if (value > 48) or (value < 1): + raise ValidationError(_('Invalid number of cores')) + def validate_memory(self, value): + if (value > 200) or (value < 2): + raise ValidationError(_('Invalid RAM size')) + + def validate_storage(self, value): + if (value > 2000) or (value < 10): + raise ValidationError(_('Invalid storage size')) + + def get(self, request, *args, **kwargs): if not UserHostingKey.objects.filter(user=self.request.user).exists(): messages.success( request, _( - 'In order to create a VM, you need to create/upload your SSH KEY first.') + 'In order to create a VM, you need to' + 'create/upload your SSH KEY first.' + ) ) return HttpResponseRedirect(reverse('hosting:ssh_keys')) - - try: - manager = OpenNebulaManager() - templates = manager.get_templates() - configuration_options = HostingPlan.get_serialized_configs() - - context = { - 'templates': VirtualMachineTemplateSerializer(templates, - many=True).data, - 'configuration_options': configuration_options, - } - except: - messages.error( - request, - 'We could not load the VM templates due to a backend connection \ - error. Please try again in a few minutes' - ) - context = { - 'error': 'connection' - } - + context = {'templates': VMTemplate.objects.all()} return render(request, self.template_name, context) def post(self, request): - manager = OpenNebulaManager() - template_id = request.POST.get('vm_template_id') - template = manager.get_template(template_id) - configuration_id = int(request.POST.get('configuration')) - configuration = HostingPlan.objects.get(id=configuration_id) - request.session['template'] = VirtualMachineTemplateSerializer( - template).data + cores = request.POST.get('cpu') + cores_field = forms.IntegerField(validators=[self.validate_cores]) + memory = request.POST.get('ram') + memory_field = forms.IntegerField(validators=[self.validate_memory]) + storage = request.POST.get('storage') + storage_field = forms.IntegerField(validators=[self.validate_storage]) + price = request.POST.get('total') + template_id = int(request.POST.get('config')) + template = VMTemplate.objects.filter( + opennebula_vm_template_id=template_id).first() + template_data = VMTemplateSerializer(template).data - request.session['specs'] = configuration.serialize() + try: + cores = cores_field.clean(cores) + except ValidationError as err: + msg = '{} : {}.'.format(cores, str(err)) + messages.add_message(self.request, messages.ERROR, msg, + extra_tags='cores') + return HttpResponseRedirect( + reverse('datacenterlight:index') + "#order_form") + + try: + memory = memory_field.clean(memory) + except ValidationError as err: + msg = '{} : {}.'.format(memory, str(err)) + messages.add_message(self.request, messages.ERROR, msg, + extra_tags='memory') + return HttpResponseRedirect( + reverse('datacenterlight:index') + "#order_form") + + try: + storage = storage_field.clean(storage) + except ValidationError as err: + msg = '{} : {}.'.format(storage, str(err)) + messages.add_message(self.request, messages.ERROR, msg, + extra_tags='storage') + return HttpResponseRedirect( + reverse('datacenterlight:index') + "#order_form") + + specs = { + 'cpu': cores, + 'memory': memory, + 'disk_size': storage, + 'price': price + } + + request.session['specs'] = specs + request.session['template'] = template_data return redirect(reverse('hosting:payment')) From 556ed75262087ba55478bfcbbcdf91370db47222 Mon Sep 17 00:00:00 2001 From: Arvind Tiwari Date: Fri, 15 Sep 2017 20:14:32 +0530 Subject: [PATCH 03/29] translations --- .../locale/de/LC_MESSAGES/django.po | 11 ++- hosting/locale/de/LC_MESSAGES/django.po | 72 +++++++++++++------ .../static/hosting/css/price_calculator.css | 10 +-- hosting/views.py | 2 +- 4 files changed, 67 insertions(+), 28 deletions(-) diff --git a/datacenterlight/locale/de/LC_MESSAGES/django.po b/datacenterlight/locale/de/LC_MESSAGES/django.po index 6c9d36ae..4be77f10 100644 --- a/datacenterlight/locale/de/LC_MESSAGES/django.po +++ b/datacenterlight/locale/de/LC_MESSAGES/django.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2017-09-03 16:44+0000\n" +"POT-Creation-Date: 2017-09-15 20:11+0530\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -183,9 +183,18 @@ msgstr "Kontakt" msgid "All Rights Reserved" msgstr "Alle Rechte vorbehalten" +msgid "Toggle navigation" +msgstr "umschalten" + msgid "Why Data Center Light?" msgstr "Warum Data Center Light?" +msgid "Login" +msgstr "Anmelden" + +msgid "Dashboard" +msgstr "Mein Dashboard" + msgid "Finally, an affordable VM hosting in Switzerland!" msgstr "Endlich: bezahlbares VM Hosting in der Schweiz" diff --git a/hosting/locale/de/LC_MESSAGES/django.po b/hosting/locale/de/LC_MESSAGES/django.po index 780419b1..5a72c715 100644 --- a/hosting/locale/de/LC_MESSAGES/django.po +++ b/hosting/locale/de/LC_MESSAGES/django.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2017-09-09 06:04+0000\n" +"POT-Creation-Date: 2017-09-15 20:11+0530\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -100,6 +100,27 @@ msgstr "vorherige" msgid "next" msgstr "nächste" +msgid "days" +msgstr "tage" + +msgid "VAT included" +msgstr "MwSt. inklusive" + +msgid "Please enter a value in range 1 - 48." +msgstr "Bitte gib einen Wert von 1 bis 48 ein." + +msgid "Please enter a value in range 2 - 200." +msgstr "Bitte gib einen Wert von 2 bis 200 ein." + +msgid "Please enter a value in range 10 - 2000." +msgstr "Bitte gib einen Wert von 10 bis 200 ein." + +msgid "GB Storage (SSD)" +msgstr "GB Storage (SSD)" + +msgid "Continue" +msgstr "Weiter" + msgid "SSH Key" msgstr "SSH Key" @@ -139,30 +160,12 @@ msgstr "Hast Du bereits ein Benutzerkonto?" msgid "Login" msgstr "Anmelden" -msgid "New Virtual Machine" -msgstr "Neue virtuelle Maschine" - -msgid "Step 1. Select VM Template:" -msgstr "Wähle eine Vorlage" - -msgid "Step2. Select VM Configuration" -msgstr "Wähle eine Konfiguration" - -msgid "Price " -msgstr "Preis" - -msgid "CHF/Month" -msgstr "CHF/Monat" - -msgid "Start VM" -msgstr "VM jetzt starten" +msgid "Create VM" +msgstr "VM erstellen" msgid "My Dashboard" msgstr "Mein Dashboard" -msgid "Create VM" -msgstr "VM erstellen" - msgid "My VMs" msgstr "Meine VMs" @@ -619,6 +622,15 @@ msgid "In order to create a VM, you need to create/upload your SSH KEY first." msgstr "" "Um eine VM zu erstellen musst du zuerst einen SSH-Key erstellen / hochladen." +msgid "Invalid number of cores" +msgstr "Ungültige Anzahle CPU-Kerne" + +msgid "Invalid RAM size" +msgstr "Ungültige RAM-Grösse" + +msgid "Invalid storage size" +msgstr "Ungültige Speicher-Grösse" + msgid "" "We could not find the requested VM. Please " "contact Data Center Light Support." @@ -631,6 +643,24 @@ msgstr "VM Kündigung" msgid "VM %(VM_ID)s terminated successfully" msgstr "VM %(VM_ID)s erfolgreich beendet" +#~ msgid "New Virtual Machine" +#~ msgstr "Neue virtuelle Maschine" + +#~ msgid "Step 1. Select VM Template:" +#~ msgstr "Wähle eine Vorlage" + +#~ msgid "Step2. Select VM Configuration" +#~ msgstr "Wähle eine Konfiguration" + +#~ msgid "Price " +#~ msgstr "Preis" + +#~ msgid "CHF/Month" +#~ msgstr "CHF/Monat" + +#~ msgid "Start VM" +#~ msgstr "VM jetzt starten" + #~ msgid "My Virtual Machines" #~ msgstr "Meine virtuellen Maschinen" diff --git a/hosting/static/hosting/css/price_calculator.css b/hosting/static/hosting/css/price_calculator.css index 5aac2c97..43daa713 100644 --- a/hosting/static/hosting/css/price_calculator.css +++ b/hosting/static/hosting/css/price_calculator.css @@ -193,21 +193,21 @@ margin: 0 8px; } -.help-block.with-errors { +.price-calc-section .help-block.with-errors { text-align: center; margin: 0 0; padding: 0 0 5px; } -.help-block.with-errors ul { +.price-calc-section .help-block.with-errors ul { margin-bottom: 0; } -.form-group { +.price-calc-section .form-group { margin: 0; position: relative; } -.form-group:after { +.price-calc-section .form-group:after { content: ' '; display: block; position: absolute; @@ -219,7 +219,7 @@ background: rgba(128, 128, 128, 0.2); } -.btn-primary { +.price-calc-section .btn-primary { background: #29427A; border-color: #29427A; color: #fff; diff --git a/hosting/views.py b/hosting/views.py index a61f4e41..75162536 100644 --- a/hosting/views.py +++ b/hosting/views.py @@ -848,7 +848,7 @@ class CreateVirtualMachinesView(LoginRequiredMixin, View): messages.success( request, _( - 'In order to create a VM, you need to' + 'In order to create a VM, you need to ' 'create/upload your SSH KEY first.' ) ) From 2de0fc13b9c4506489a33cf75daa026eac4f4f1e Mon Sep 17 00:00:00 2001 From: Arvind Tiwari Date: Fri, 15 Sep 2017 20:17:54 +0530 Subject: [PATCH 04/29] translation fix --- datacenterlight/locale/de/LC_MESSAGES/django.po | 2 +- hosting/locale/de/LC_MESSAGES/django.po | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/datacenterlight/locale/de/LC_MESSAGES/django.po b/datacenterlight/locale/de/LC_MESSAGES/django.po index 4be77f10..fe120a25 100644 --- a/datacenterlight/locale/de/LC_MESSAGES/django.po +++ b/datacenterlight/locale/de/LC_MESSAGES/django.po @@ -193,7 +193,7 @@ msgid "Login" msgstr "Anmelden" msgid "Dashboard" -msgstr "Mein Dashboard" +msgstr "Dashboard" msgid "Finally, an affordable VM hosting in Switzerland!" msgstr "Endlich: bezahlbares VM Hosting in der Schweiz" diff --git a/hosting/locale/de/LC_MESSAGES/django.po b/hosting/locale/de/LC_MESSAGES/django.po index 5a72c715..0c031b6a 100644 --- a/hosting/locale/de/LC_MESSAGES/django.po +++ b/hosting/locale/de/LC_MESSAGES/django.po @@ -279,7 +279,7 @@ msgstr "" "%(base_url)s%(my_virtual_machines_url)s\n" msgid "Toggle navigation" -msgstr "Konfiguration" +msgstr "Umschalten" msgid "Dashboard" msgstr "Mein Dashboard" From 772469a23e4a6a5362ba5f2f20ef331c1900c0ea Mon Sep 17 00:00:00 2001 From: Arvind Tiwari Date: Mon, 18 Sep 2017 19:49:14 +0530 Subject: [PATCH 05/29] design modifications --- datacenterlight/locale/de/LC_MESSAGES/django.po | 2 +- hosting/locale/de/LC_MESSAGES/django.po | 12 ++++++------ hosting/static/hosting/css/price_calculator.css | 4 +++- hosting/templates/hosting/calculator_form.html | 2 +- .../templates/hosting/create_virtual_machine.html | 4 ++-- 5 files changed, 13 insertions(+), 11 deletions(-) diff --git a/datacenterlight/locale/de/LC_MESSAGES/django.po b/datacenterlight/locale/de/LC_MESSAGES/django.po index fe120a25..234f2a3b 100644 --- a/datacenterlight/locale/de/LC_MESSAGES/django.po +++ b/datacenterlight/locale/de/LC_MESSAGES/django.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2017-09-15 20:11+0530\n" +"POT-Creation-Date: 2017-09-17 01:31+0530\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" diff --git a/hosting/locale/de/LC_MESSAGES/django.po b/hosting/locale/de/LC_MESSAGES/django.po index 0c031b6a..c7a13e34 100644 --- a/hosting/locale/de/LC_MESSAGES/django.po +++ b/hosting/locale/de/LC_MESSAGES/django.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2017-09-15 20:11+0530\n" +"POT-Creation-Date: 2017-09-17 01:31+0530\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -100,8 +100,8 @@ msgstr "vorherige" msgid "next" msgstr "nächste" -msgid "days" -msgstr "tage" +msgid "Month" +msgstr "Monat" msgid "VAT included" msgstr "MwSt. inklusive" @@ -380,9 +380,6 @@ msgstr "Konfiguration" msgid "including VAT" msgstr "inkl. Mehrwertsteuer" -msgid "Month" -msgstr "Monat" - msgid "Billing Address" msgstr "Rechnungsadresse" @@ -643,6 +640,9 @@ msgstr "VM Kündigung" msgid "VM %(VM_ID)s terminated successfully" msgstr "VM %(VM_ID)s erfolgreich beendet" +#~ msgid "days" +#~ msgstr "tage" + #~ msgid "New Virtual Machine" #~ msgstr "Neue virtuelle Maschine" diff --git a/hosting/static/hosting/css/price_calculator.css b/hosting/static/hosting/css/price_calculator.css index 43daa713..e1ea2a5f 100644 --- a/hosting/static/hosting/css/price_calculator.css +++ b/hosting/static/hosting/css/price_calculator.css @@ -116,7 +116,7 @@ color: #29427a; cursor: pointer; font-size: 20px; - border: 1px solid #eee; + border: 1px solid #ccc; padding: 5px 6px 3px; border-radius: 5px; } @@ -229,5 +229,7 @@ @media(min-width: 768px) { .create-vm-container { padding-top: 120px; + max-width: 1120px; + /* width: 100%; */ } } diff --git a/hosting/templates/hosting/calculator_form.html b/hosting/templates/hosting/calculator_form.html index 5ba2a4c3..879f2054 100644 --- a/hosting/templates/hosting/calculator_form.html +++ b/hosting/templates/hosting/calculator_form.html @@ -3,7 +3,7 @@ {% csrf_token %}
15 - CHF/30 {% trans "days" %} + CHF/{% trans "Month" %}

{% trans "VAT included" %}

diff --git a/hosting/templates/hosting/create_virtual_machine.html b/hosting/templates/hosting/create_virtual_machine.html index dff82199..5f61eae8 100644 --- a/hosting/templates/hosting/create_virtual_machine.html +++ b/hosting/templates/hosting/create_virtual_machine.html @@ -4,7 +4,7 @@ {% block content %}
-
+

{% trans "Create VM" %}

{% if messages %} @@ -16,7 +16,7 @@ {% endif %}
-
+
From b276194f31cbacb41aaa6702181a9a617f98b98d Mon Sep 17 00:00:00 2001 From: Arvind Tiwari Date: Mon, 18 Sep 2017 20:18:02 +0530 Subject: [PATCH 06/29] width normalized --- hosting/static/hosting/css/price_calculator.css | 2 -- hosting/templates/hosting/create_virtual_machine.html | 2 +- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/hosting/static/hosting/css/price_calculator.css b/hosting/static/hosting/css/price_calculator.css index e1ea2a5f..310a9d05 100644 --- a/hosting/static/hosting/css/price_calculator.css +++ b/hosting/static/hosting/css/price_calculator.css @@ -229,7 +229,5 @@ @media(min-width: 768px) { .create-vm-container { padding-top: 120px; - max-width: 1120px; - /* width: 100%; */ } } diff --git a/hosting/templates/hosting/create_virtual_machine.html b/hosting/templates/hosting/create_virtual_machine.html index 5f61eae8..aff7862a 100644 --- a/hosting/templates/hosting/create_virtual_machine.html +++ b/hosting/templates/hosting/create_virtual_machine.html @@ -16,7 +16,7 @@ {% endif %}
-
+
From e893f1baf170fd12f8caec3349c93b4361123681 Mon Sep 17 00:00:00 2001 From: Arvind Tiwari Date: Tue, 19 Sep 2017 01:17:15 +0530 Subject: [PATCH 07/29] padding fix --- hosting/static/hosting/css/price_calculator.css | 8 ++++++-- hosting/templates/hosting/calculator_form.html | 2 +- hosting/templates/hosting/create_virtual_machine.html | 2 +- 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/hosting/static/hosting/css/price_calculator.css b/hosting/static/hosting/css/price_calculator.css index 310a9d05..24624f10 100644 --- a/hosting/static/hosting/css/price_calculator.css +++ b/hosting/static/hosting/css/price_calculator.css @@ -45,13 +45,17 @@ background: #fff; box-shadow: 1px 3px 6px 2px rgba(0, 0, 0, 0.2); padding-bottom: 30px; - /* border-radius: 7px; */ text-align: center; - /* margin-right: auto; */ max-width: 320px; position: relative; } +@media (min-width: 768px) { + .price-calc-section .card { + margin-left: 0; + } +} + .price-calc-section .landing { width: 100% !important; } diff --git a/hosting/templates/hosting/calculator_form.html b/hosting/templates/hosting/calculator_form.html index 879f2054..18bdd3cb 100644 --- a/hosting/templates/hosting/calculator_form.html +++ b/hosting/templates/hosting/calculator_form.html @@ -5,7 +5,7 @@ 15 CHF/{% trans "Month" %}
-

{% trans "VAT included" %}

+ {% trans "VAT included" %}
diff --git a/hosting/templates/hosting/create_virtual_machine.html b/hosting/templates/hosting/create_virtual_machine.html index aff7862a..4ba5274e 100644 --- a/hosting/templates/hosting/create_virtual_machine.html +++ b/hosting/templates/hosting/create_virtual_machine.html @@ -4,7 +4,7 @@ {% block content %}
-
+

{% trans "Create VM" %}

{% if messages %} From 98f094e5b850daa09b8575670eee6ce3cfd6812b Mon Sep 17 00:00:00 2001 From: Arvind Tiwari Date: Tue, 19 Sep 2017 15:03:06 +0530 Subject: [PATCH 08/29] initial changes --- hosting/static/hosting/css/order.css | 2 +- hosting/static/hosting/img/icon-pdf.svg | 18 ++ hosting/static/hosting/img/icon-print.svg | 17 ++ .../hosting/includes/_navbar_user.html | 6 +- hosting/templates/hosting/order_detail.html | 287 +++++++++--------- hosting/urls.py | 3 +- 6 files changed, 180 insertions(+), 153 deletions(-) create mode 100644 hosting/static/hosting/img/icon-pdf.svg create mode 100644 hosting/static/hosting/img/icon-print.svg diff --git a/hosting/static/hosting/css/order.css b/hosting/static/hosting/css/order.css index e8bc0328..f2f7993b 100644 --- a/hosting/static/hosting/css/order.css +++ b/hosting/static/hosting/css/order.css @@ -1,4 +1,4 @@ -.order-detail-container {padding-top: 70px; padding-bottom: 70px; margin-bottom: 70px;} +.order-detail-container {padding-top: 70px;padding-bottom: 70px;/* margin-bottom: 70px; */max-width: 720px;margin: 0 auto;} .order-detail-container .invoice-title h2, .invoice-title h3 { display: inline-block; diff --git a/hosting/static/hosting/img/icon-pdf.svg b/hosting/static/hosting/img/icon-pdf.svg new file mode 100644 index 00000000..20fc9c48 --- /dev/null +++ b/hosting/static/hosting/img/icon-pdf.svg @@ -0,0 +1,18 @@ + + + + icon-pdf + Created with Sketch. + + + + + + + + + + + + + \ No newline at end of file diff --git a/hosting/static/hosting/img/icon-print.svg b/hosting/static/hosting/img/icon-print.svg new file mode 100644 index 00000000..e440f326 --- /dev/null +++ b/hosting/static/hosting/img/icon-print.svg @@ -0,0 +1,17 @@ + + + + 54471 + Created with Sketch. + + + + + + + + + + + + \ No newline at end of file diff --git a/hosting/templates/hosting/includes/_navbar_user.html b/hosting/templates/hosting/includes/_navbar_user.html index d06477ca..126dd1e6 100644 --- a/hosting/templates/hosting/includes/_navbar_user.html +++ b/hosting/templates/hosting/includes/_navbar_user.html @@ -37,11 +37,7 @@
  • {% get_current_language as LANGUAGE_CODE %} - {% if LANGUAGE_CODE == 'en-us'%} -   Deutsch - {% else %} -   English - {% endif %} +
  • diff --git a/hosting/templates/hosting/order_detail.html b/hosting/templates/hosting/order_detail.html index 39c59808..f07aa998 100644 --- a/hosting/templates/hosting/order_detail.html +++ b/hosting/templates/hosting/order_detail.html @@ -7,168 +7,163 @@
    {% if messages %} -
    -
    -
    -
    - {% for message in messages %} - {{ message }} - {% endfor %} -
    +
    + {% for message in messages %} + {{ message }} + {% endfor %}
    -
    {% endif %} {% if not error %} -
    -
    -
    -

    {{page_header_text}}

    -

    - {% if order %} - {% trans "Order #"%} {{order.id}} - {% endif %} -

    -
    -
    -
    -
    -
    - {% trans "Date"%}:
    - - {% if order %} - {{order.created_at|date:'Y-m-d H:i'}} - {% else %} - {% now "Y-m-d H:i" %} - {% endif %} -

    +
    +
    +
    +

    {{page_header_text}}

    +

    {% if order %} - {% trans "Status:"%}
    - {% if order.status == 'Approved' %} - - {% trans "Approved" %} - - {% else %} - - {% trans "Declined" %} - + {% trans "Order #"%} {{order.id}} {% endif %} -

    - {% endif %} -

    + +
    +
    +
    +
    +
    + {% trans "Date"%}:
    + + {% if order %} + {{order.created_at|date:'Y-m-d H:i'}} + {% else %} + {% now "Y-m-d H:i" %} + {% endif %} +

    + {% if order %} + {% trans "Status:"%}
    + {% if order.status == 'Approved' %} + + {% trans "Approved" %} + + {% else %} + + {% trans "Declined" %} + + {% endif %} +

    + {% endif %} +
    + +
    +
    +
    +

    {% trans "Billed To:"%}

    + {% if order %} + {{user.name}}
    + {{order.billing_address.street_address}},{{order.billing_address.postal_code}}
    + {{order.billing_address.city}}, + {{order.billing_address.country}}. + {% else %} + {% with request.session.billing_address_data as billing_address %} + {{billing_address.cardholder_name}}
    + {{billing_address.street_address}}, + {{billing_address.postal_code}}
    + {{billing_address.city}}, + {{billing_address.country}}. + {% endwith %} + {% endif %} +
    +
    -
    -
    -

    {% trans "Billed To:"%}

    - {% if order %} - {{user.name}}
    - {{order.billing_address.street_address}},{{order.billing_address.postal_code}}
    - {{order.billing_address.city}}, - {{order.billing_address.country}}. - {% else %} - {% with request.session.billing_address_data as billing_address %} - {{billing_address|get_value_from_dict:'cardholder_name'}}
    - {{billing_address|get_value_from_dict:'street_address'}}, - {{billing_address|get_value_from_dict:'postal_code'}}
    - {{billing_address|get_value_from_dict:'city'}}, - {{billing_address|get_value_from_dict:'country'}}. - {% endwith %} - {% endif %} -
    -
    - -
    -
    -
    -
    - {% trans "Payment Method:"%}
    - {% if order %} - {{order.cc_brand}} {% trans "ending in" %} **** - {{order.last4}}
    - {{user.email}} - {% else %} - {{cc_brand}} {% trans "ending in" %} **** - {{cc_last4}}
    - {{request.session.user.email}} - {% endif %} -
    +
    +
    +
    + {% trans "Payment Method:"%}
    + {% if order %} + {{order.cc_brand}} {% trans "ending in" %} **** + {{order.last4}}
    + {{user.email}} + {% else %} + {{cc_brand}} {% trans "ending in" %} **** + {{cc_last4}}
    + {{request.session.user.email}} + {% endif %} +
    +
    -
    -
    -
    -

    {% trans "Order summary"%}

    -
    -
    - {% if request.session.specs %} - {% with request.session.specs as vm %} -

    {% trans "Cores"%} - {{vm.cpu}} -

    +
    +
    +

    {% trans "Order summary"%}


    -

    {% trans "Memory"%} - {{vm.memory}} GB -

    -
    -

    {% trans "Disk space"%} - {{vm.disk_size}} GB -

    -
    -

    {% trans "Configuration"%} - {{request.session.template.name}} -

    -
    -

    {% trans "Total"%} -

    - {{vm.price}} CHF - /{% trans "Month" %} - +

    + {% if request.session.specs %} + {% with request.session.specs as vm %} +

    {% trans "Cores"%} + {{vm.cpu}}

    -

    - {% endwith %} - {% else %} -

    {% trans "Cores"%} - {{vm.cores}} -

    -
    -

    {% trans "Memory"%} - {{vm.memory}} GB -

    -
    -

    {% trans "Disk space"%} - {{vm.disk_size}} GB -

    -
    -

    {% trans "Total"%}

    {{vm.price}} - CHF /{% trans "Month" %} -

    +
    +

    {% trans "Memory"%} + {{vm.memory}} GB +

    +
    +

    {% trans "Disk space"%} + {{vm.disk_size}} GB +

    +
    +

    {% trans "Configuration"%} + {{request.session.template.name}} +

    +
    +

    {% trans "Total"%} +

    + {{vm.price}} CHF + /{% trans "Month" %} + +

    +

    + {% endwith %} + {% else %} +

    {% trans "Cores"%} + {{vm.cores}} +

    +
    +

    {% trans "Memory"%} + {{vm.memory}} GB +

    +
    +

    {% trans "Disk space"%} + {{vm.disk_size}} GB +

    +
    +

    {% trans "Total"%}

    {{vm.price}} + CHF /{% trans "Month" %} +

    + {% endif %} +
    +
    + {% if not order %} +
    + {% csrf_token %} +
    +
    +

    {% blocktrans with vm_price=request.session.specs.price %}By clicking "Place order" this plan will charge your credit card account with the fee of {{ vm_price }}CHF/month{% endblocktrans %}.

    +
    +
    + +
    +
    +
    {% endif %}
    -
    - {% if not order %} -
    - {% csrf_token %} -
    -
    -

    {% blocktrans with vm_price=request.session.specs.price %}By clicking "Place order" this plan will charge your credit card account with the fee of {{ vm_price }}CHF/month{% endblocktrans %}.

    -
    -
    - -
    -
    -
    - {% endif %}
    -
    {% endif %}
    diff --git a/hosting/urls.py b/hosting/urls.py index 2868c717..bc14c3a6 100644 --- a/hosting/urls.py +++ b/hosting/urls.py @@ -9,9 +9,10 @@ from .views import ( HostingPricingView, CreateVirtualMachinesView, HostingBillListView, HostingBillDetailView, SSHKeyDeleteView, SSHKeyCreateView, SSHKeyListView, SSHKeyChoiceView, DashboardView, SettingsView) - +from django.views.generic import TemplateView urlpatterns = [ + url(r'test/?$', TemplateView.as_view(template_name='hosting/order_detail.html')), url(r'index/?$', IndexView.as_view(), name='index'), url(r'django/?$', DjangoHostingView.as_view(), name='djangohosting'), url(r'dashboard/?$', DashboardView.as_view(), name='dashboard'), From 37017dd31ad0adafda7a59106c3789f15c192ce3 Mon Sep 17 00:00:00 2001 From: Arvind Tiwari Date: Wed, 20 Sep 2017 23:06:51 +0530 Subject: [PATCH 09/29] minor mods --- hosting/static/hosting/css/order.css | 7 +- hosting/templates/hosting/order_detail.html | 290 ++++++++++---------- 2 files changed, 148 insertions(+), 149 deletions(-) diff --git a/hosting/static/hosting/css/order.css b/hosting/static/hosting/css/order.css index f2f7993b..bdd124c9 100644 --- a/hosting/static/hosting/css/order.css +++ b/hosting/static/hosting/css/order.css @@ -1,4 +1,9 @@ -.order-detail-container {padding-top: 70px;padding-bottom: 70px;/* margin-bottom: 70px; */max-width: 720px;margin: 0 auto;} +.order-detail-container { + max-width: 600px; + margin: 100px auto; + border: 1px solid #ccc; + padding: 30px; +} .order-detail-container .invoice-title h2, .invoice-title h3 { display: inline-block; diff --git a/hosting/templates/hosting/order_detail.html b/hosting/templates/hosting/order_detail.html index f07aa998..3d1ffd35 100644 --- a/hosting/templates/hosting/order_detail.html +++ b/hosting/templates/hosting/order_detail.html @@ -9,161 +9,155 @@ {% if messages %}
    {% for message in messages %} - {{ message }} + {{ message }} {% endfor %}
    {% endif %} {% if not error %} -
    -
    -
    -

    {{page_header_text}}

    -

    - {% if order %} - {% trans "Order #"%} {{order.id}} - {% endif %} -

    -
    -
    -
    -
    -
    - {% trans "Date"%}:
    - - {% if order %} - {{order.created_at|date:'Y-m-d H:i'}} - {% else %} - {% now "Y-m-d H:i" %} - {% endif %} -

    - {% if order %} - {% trans "Status:"%}
    - {% if order.status == 'Approved' %} - - {% trans "Approved" %} - - {% else %} - - {% trans "Declined" %} - - {% endif %} -

    - {% endif %} -
    - -
    -
    -
    -

    {% trans "Billed To:"%}

    - {% if order %} - {{user.name}}
    - {{order.billing_address.street_address}},{{order.billing_address.postal_code}}
    - {{order.billing_address.city}}, - {{order.billing_address.country}}. - {% else %} - {% with request.session.billing_address_data as billing_address %} - {{billing_address.cardholder_name}}
    - {{billing_address.street_address}}, - {{billing_address.postal_code}}
    - {{billing_address.city}}, - {{billing_address.country}}. - {% endwith %} - {% endif %} -
    -
    - -
    -
    -
    -
    - {% trans "Payment Method:"%}
    - {% if order %} - {{order.cc_brand}} {% trans "ending in" %} **** - {{order.last4}}
    - {{user.email}} - {% else %} - {{cc_brand}} {% trans "ending in" %} **** - {{cc_last4}}
    - {{request.session.user.email}} - {% endif %} -
    -
    -
    -
    -
    - -
    -
    -

    {% trans "Order summary"%}

    -
    -
    - {% if request.session.specs %} - {% with request.session.specs as vm %} -

    {% trans "Cores"%} - {{vm.cpu}} -

    -
    -

    {% trans "Memory"%} - {{vm.memory}} GB -

    -
    -

    {% trans "Disk space"%} - {{vm.disk_size}} GB -

    -
    -

    {% trans "Configuration"%} - {{request.session.template.name}} -

    -
    -

    {% trans "Total"%} -

    - {{vm.price}} CHF - /{% trans "Month" %} - -

    -

    - {% endwith %} - {% else %} -

    {% trans "Cores"%} - {{vm.cores}} -

    -
    -

    {% trans "Memory"%} - {{vm.memory}} GB -

    -
    -

    {% trans "Disk space"%} - {{vm.disk_size}} GB -

    -
    -

    {% trans "Total"%}

    {{vm.price}} - CHF /{% trans "Month" %} -

    - {% endif %} -
    -
    - {% if not order %} -
    - {% csrf_token %} -
    -
    -

    {% blocktrans with vm_price=request.session.specs.price %}By clicking "Place order" this plan will charge your credit card account with the fee of {{ vm_price }}CHF/month{% endblocktrans %}.

    -
    -
    - -
    -
    -
    +

    + {% blocktrans %}{{page_header_text|default:'Invoice'}}{% endblocktrans %} +

    +
    +

    + {% if order %} + {% trans "Order #"%} {{order.id}} {% endif %} +

    +
    +
    +
    +
    +
    + {% trans "Date"%}:
    + + {% if order %} + {{order.created_at|date:'Y-m-d H:i'}} + {% else %} + {% now "Y-m-d H:i" %} + {% endif %} +

    + {% if order %} + {% trans "Status:"%}
    + {% if order.status == 'Approved' %} + + {% trans "Approved" %} + + {% else %} + + {% trans "Declined" %} + + {% endif %} +

    + {% endif %} +
    + +
    +
    +
    +

    {% trans "Billed To:"%}

    + {% if order %} + {{user.name}}
    + {{order.billing_address.street_address}},{{order.billing_address.postal_code}}
    + {{order.billing_address.city}}, + {{order.billing_address.country}}. + {% else %} + {% with request.session.billing_address_data as billing_address %} + {{billing_address.cardholder_name}}
    + {{billing_address.street_address}}, + {{billing_address.postal_code}}
    + {{billing_address.city}}, + {{billing_address.country}}. + {% endwith %} + {% endif %} +
    +
    + +
    +
    +
    +
    + {% trans "Payment Method:"%}
    + {% if order %} + {{order.cc_brand}} {% trans "ending in" %} **** + {{order.last4}}
    + {{user.email}} + {% else %} + {{cc_brand}} {% trans "ending in" %} **** + {{cc_last4}}
    + {{request.session.user.email}} + {% endif %} +
    + +

    {% trans "Order summary"%}

    +
    +
    + {% if request.session.specs %} + {% with request.session.specs as vm %} +

    {% trans "Cores"%} + {{vm.cpu}} +

    +
    +

    {% trans "Memory"%} + {{vm.memory}} GB +

    +
    +

    {% trans "Disk space"%} + {{vm.disk_size}} GB +

    +
    +

    {% trans "Configuration"%} + {{request.session.template.name}} +

    +
    +

    {% trans "Total"%} +

    + {{vm.price}} CHF + /{% trans "Month" %} + +

    +

    + {% endwith %} + {% else %} +

    {% trans "Cores"%} + {{vm.cores}} +

    +
    +

    {% trans "Memory"%} + {{vm.memory}} GB +

    +
    +

    {% trans "Disk space"%} + {{vm.disk_size}} GB +

    +
    +

    {% trans "Total"%}

    {{vm.price}} + CHF /{% trans "Month" %} +

    + {% endif %} +
    +
    + {% if not order %} +
    + {% csrf_token %} +
    +
    +

    {% blocktrans with vm_price=request.session.specs.price %}By clicking "Place order" this plan will charge your credit card account with the fee of {{ vm_price }}CHF/month{% endblocktrans %}.

    +
    +
    + +
    +
    +
    + {% endif %} {% endif %}
    From ec354332f8b0159e62e6925a04e5d9bc700c66a8 Mon Sep 17 00:00:00 2001 From: Arvind Tiwari Date: Wed, 20 Sep 2017 23:28:36 +0530 Subject: [PATCH 10/29] translation fix --- hosting/locale/de/LC_MESSAGES/django.po | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hosting/locale/de/LC_MESSAGES/django.po b/hosting/locale/de/LC_MESSAGES/django.po index 006e8b20..b0cc0bf6 100644 --- a/hosting/locale/de/LC_MESSAGES/django.po +++ b/hosting/locale/de/LC_MESSAGES/django.po @@ -292,7 +292,7 @@ msgid "Toggle navigation" msgstr "Umschalten" msgid "Dashboard" -msgstr "Mein Dashboard" +msgstr "Dashboard" msgid "Logout" msgstr "Abmelden" From 98eb2f85d8913d36733467eedea0f1dce9ed50df Mon Sep 17 00:00:00 2001 From: Arvind Tiwari Date: Thu, 21 Sep 2017 01:19:38 +0530 Subject: [PATCH 11/29] printing pdf --- hosting/static/hosting/css/order.css | 16 + hosting/static/hosting/js/html2pdf.js | 387 ++++++++++++++++++++ hosting/templates/hosting/order_detail.html | 27 +- 3 files changed, 421 insertions(+), 9 deletions(-) create mode 100644 hosting/static/hosting/js/html2pdf.js diff --git a/hosting/static/hosting/css/order.css b/hosting/static/hosting/css/order.css index bdd124c9..3e916cdd 100644 --- a/hosting/static/hosting/css/order.css +++ b/hosting/static/hosting/css/order.css @@ -20,3 +20,19 @@ .order-detail-container .table > tbody > tr > .thick-line { border-top: 2px solid; } + +.order-detail-container .dashboard-title-thin { + margin-top: 0; +} + +.order-detail-container .dashboard-title-thin .un-icon { + margin-top: -6px; +} + +.order-detail-container .dashboard-title-thin .svg-img { + height: 20px; + margin-right: 5px; + margin-top: -2px; + width: 20px; + margin-top: -6px; +} \ No newline at end of file diff --git a/hosting/static/hosting/js/html2pdf.js b/hosting/static/hosting/js/html2pdf.js new file mode 100644 index 00000000..45ae5b0c --- /dev/null +++ b/hosting/static/hosting/js/html2pdf.js @@ -0,0 +1,387 @@ +/** + * @license + * + * MIT License + * + * Copyright (c) 2017 Erik Koopmans + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +/** + * Generate a PDF from an HTML element or string using html2canvas and jsPDF. + * + * @param {Element|string} source The source element or HTML string. + * @param {Object=} opt An object of optional settings: 'margin', 'filename', + * 'image' ('type' and 'quality'), and 'html2canvas' / 'jspdf', which are + * sent as settings to their corresponding functions. + */ +var html2pdf = (function(html2canvas, jsPDF) { + + /* ---------- MAIN FUNCTION ---------- */ + + var html2pdf = function(source, opt) { + // Handle input. + opt = objType(opt) === 'object' ? opt : {}; + var source = html2pdf.parseInput(source, opt); + + // Determine the PDF page size. + var pageSize = jsPDF.getPageSize(opt.jsPDF); + pageSize.inner = { + width: pageSize.width - opt.margin[1] - opt.margin[3], + height: pageSize.height - opt.margin[0] - opt.margin[2] + }; + pageSize.inner.ratio = pageSize.inner.height / pageSize.inner.width; + + // Copy the source element into a PDF-styled container div. + var container = html2pdf.makeContainer(source, pageSize); + var overlay = container.parentElement; + + // Get the locations of all hyperlinks. + if (opt.enableLinks) { + // Find all anchor tags and get the container's bounds for reference. + opt.links = []; + var links = container.querySelectorAll('a'); + var containerRect = unitConvert(container.getBoundingClientRect(), pageSize.k); + + // Treat each client rect as a separate link (for text-wrapping). + Array.prototype.forEach.call(links, function(link) { + var clientRects = link.getClientRects(); + for (var i=0; i