diff --git a/Changelog b/Changelog index fcf3c16c..95b7dab8 100644 --- a/Changelog +++ b/Changelog @@ -1,3 +1,11 @@ +1.0.18: 2017-07-02 + * [datacenterlight] Introduced the new flow. Landing page -> Payment -> Order confirmation -> Success + * [datacenterlight] Fixed issue showing local time to the user in order confirmation page, vm pages (like ssh keys) + * [hosting] Fixed responsive issue while user signup + * [hosting] Fixed 500 error when user requests for a vm whose id does not belong to him + * [datacenterlight] Refactored partially dcl text and dcl support email to be obtained from env parameters + * [datacenterlight] Updated DE translations + * [hosting] Updated email text for user activation 1.0.17: 2017-06-16 * [datacenterlight] Cleanup OrderView useless code * [datacenterlight] Replaced GiB to GB @@ -5,7 +13,7 @@ * [datacenterlight] Fixed translations * [datacenterlight] Added email confirmation feature * [datacenterlight] Changed logo on datacerlight dashboard - * [datacenterlight] Credit card input disappearance fix + * [datacenterlight] Credit card input disappearance fix 1.0.16: 2017-06-15 * [datacenterlight] .po file issue with multiple definition fixed * [datacenterlight] Navbar items in dcl user area rearranged diff --git a/datacenterlight/locale/de/LC_MESSAGES/django.po b/datacenterlight/locale/de/LC_MESSAGES/django.po index f6628b9f..6eeb605b 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-06-19 12:22+0530\n" +"POT-Creation-Date: 2017-07-01 02:15+0530\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -99,15 +99,18 @@ msgid "" "datacenterlight account.
\n" " %(base_url)s%(activation_link)s\n" " " -msgstr "\n" -" Klicke hier um deinen %(dcl_text)s zu aktivieren.

\n" -" Oder kopiere den folgenden Link in die Adressleiste deines Browsers und folge dann dem Link um deinen %(dcl_text)s Account zu aktivieren.
\n" +msgstr "" +"\n" +" Klicke hier " +"um deinen %(dcl_text)s zu aktivieren.

\n" +" Oder kopiere den folgenden Link in die Adressleiste deines " +"Browsers und folge dann dem Link um deinen %(dcl_text)s Account zu " +"aktivieren.
\n" " %(base_url)s%(activation_link)s\n" " " #: templates/datacenterlight/emails/user_activation.html:123 #: templates/datacenterlight/emails/user_activation.txt:11 -#| msgid "Your Name" msgid "Your" msgstr "Dein" @@ -128,8 +131,9 @@ msgstr "" "\n" "Hallo,\n" "\n" -"Du kannst deinen %(dcl_text)s Account aktivieren, indem du hier klickst %(base_url)s" -"%(activation_link)s\n" +"Du kannst deinen %(dcl_text)s Account aktivieren, indem du hier klickst " +"%(base_url)s%(activation_link)s\n" + #: templates/datacenterlight/includes/_footer.html:11 #: templates/datacenterlight/includes/_footer.html:31 #: templates/datacenterlight/includes/_navbar.html:27 @@ -298,6 +302,54 @@ msgstr "Fragen?" msgid "Contact us!" msgstr "Kontaktiere uns!" +#: templates/datacenterlight/order_detail.html:24 +msgid "Confirm Order" +msgstr "Bestellung Bestätigen" + +#: templates/datacenterlight/order_detail.html:30 +msgid "Billed To:" +msgstr "Rechnungsadresse" + +#: templates/datacenterlight/order_detail.html:39 +msgid "Date" +msgstr "Datum" + +#: templates/datacenterlight/order_detail.html:48 +msgid "Payment Method:" +msgstr "Bezahlmethode" + +#: templates/datacenterlight/order_detail.html:49 +msgid "ending" +msgstr "endend in" + +#: templates/datacenterlight/order_detail.html:59 +msgid "Order summary" +msgstr "Bestellungsübersicht" + +#: templates/datacenterlight/order_detail.html:63 +msgid "Cores" +msgstr "Prozessorkerne" + +#: templates/datacenterlight/order_detail.html:65 +msgid "Memory" +msgstr "Arbeitsspeicher" + +#: templates/datacenterlight/order_detail.html:67 +msgid "Disk space" +msgstr "Festplattenkapazität" + +#: templates/datacenterlight/order_detail.html:69 +msgid "Configuration" +msgstr "Konfiguration" + +#: templates/datacenterlight/order_detail.html:71 +msgid "Total" +msgstr "" + +#: templates/datacenterlight/order_detail.html:78 +msgid "Place order" +msgstr "Bestellen" + #: templates/datacenterlight/pricing.html:9 msgid "We are cutting down the costs significantly!" msgstr "Wir sorgen dafür, dass die Kosten für Dich signifikant abnehmen" diff --git a/datacenterlight/templates/datacenterlight/order_detail.html b/datacenterlight/templates/datacenterlight/order_detail.html index 24511463..273074cf 100644 --- a/datacenterlight/templates/datacenterlight/order_detail.html +++ b/datacenterlight/templates/datacenterlight/order_detail.html @@ -1,7 +1,9 @@ {% extends "hosting/base_short.html" %} {% load staticfiles bootstrap3 %} {% load i18n %} +{% load custom_tags %} {% block content %} +
{% if messages %}
@@ -18,37 +20,38 @@ {% if not error %}
-
-

{% trans "Confirm Order"%}

{% trans "Order #"%} {{order.id}}

-
-
-
-
-
+
+

{% trans "Confirm Order"%}

+
+
+
+
+

{% trans "Billed To:"%}

- {{user.name}}
- {{order.billing_address.street_address}},{{order.billing_address.postal_code}}
- {{order.billing_address.city}}, {{order.billing_address.country}}. -
-
+ {% with request.session.billing_address_data as billing_address %} + {{request.session.user.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 %} +
+
{% trans "Date"%}:
- {{order.created_at}}

+ {% now "Y-m-d H:i" %}

-
-
-
-
- {% trans "Payment Method:"%}
- {{order.cc_brand}} ending **** {{order.last4}}
- {{user.email}} -
-
-
-
+
+
+
+
+ {% trans "Payment Method:"%}
+ {{cc_brand}} {% trans "ending" %} **** {{cc_last4}}
+ {{request.session.user.email}} +
+
+
+
@@ -56,23 +59,39 @@

{% trans "Order summary"%}


-

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

-
-

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

-
-

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

-
-

{% trans "Total"%}

{{vm.price}} CHF

+ {% 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

+ {% endwith %}

- {% url 'datacenterlight:payment' as payment_url %} - {% if payment_url in request.META.HTTP_REFERER %} +
+ {% csrf_token %} - {% endif %} +
{% endif %} + + + {%endblock%} diff --git a/datacenterlight/templatetags/custom_tags.py b/datacenterlight/templatetags/custom_tags.py index 915e68fe..ed59af9a 100644 --- a/datacenterlight/templatetags/custom_tags.py +++ b/datacenterlight/templatetags/custom_tags.py @@ -21,4 +21,14 @@ def change_lang(context, lang=None, *args, **kwargs): activate(cur_language) - return "%s" % url \ No newline at end of file + return "%s" % url + +@register.filter('get_value_from_dict') +def get_value_from_dict(dict_data, key): + """ + usage example {{ your_dict|get_value_from_dict:your_key }} + """ + if key: + return dict_data.get(key) + else : + return "" diff --git a/datacenterlight/urls.py b/datacenterlight/urls.py index 65401b13..ca844278 100644 --- a/datacenterlight/urls.py +++ b/datacenterlight/urls.py @@ -9,7 +9,7 @@ urlpatterns = [ url(r'^/landing/?$', LandingProgramView.as_view(), name='landing'), url(r'^/pricing/?$', PricingView.as_view(), name='pricing'), url(r'^/payment/?$', PaymentOrderView.as_view(), name='payment'), - url(r'^/order-confirmation/(?P\d+)/?$', OrderConfirmationView.as_view(), name='order_confirmation'), + url(r'^/order-confirmation/?$', OrderConfirmationView.as_view(), name='order_confirmation'), url(r'^/order-success/?$', SuccessView.as_view(), name='order_success'), url(r'^/beta_access?$', BetaAccessView.as_view(), name='beta_access'), ] diff --git a/datacenterlight/views.py b/datacenterlight/views.py index e4329b89..07709981 100644 --- a/datacenterlight/views.py +++ b/datacenterlight/views.py @@ -13,6 +13,7 @@ from django.core.exceptions import ValidationError from django.views.decorators.cache import cache_control from django.conf import settings from utils.forms import BillingAddressForm, UserBillingAddressForm +from utils.models import BillingAddress from membership.models import StripeCustomer from hosting.models import HostingOrder, HostingBill from utils.stripe_utils import StripeUtils @@ -31,9 +32,14 @@ class SuccessView(TemplateView): def get(self, request, *args, **kwargs): if 'specs' not in request.session or 'user' not in request.session: return HttpResponseRedirect(reverse('datacenterlight:index')) - else : - del request.session['specs'] - del request.session['user'] + elif 'token' not in request.session: + return HttpResponseRedirect(reverse('datacenterlight:payment')) + elif 'order_confirmation' not in request.session: + return HttpResponseRedirect(reverse('datacenterlight:order_confirmation')) + else: + for session_var in ['specs', 'user', 'template', 'billing_address', 'billing_address_data', 'token', 'customer']: + if session_var in request.session: + del request.session[session_var] return render(request, self.template_name) class PricingView(TemplateView): @@ -192,11 +198,13 @@ class IndexView(CreateView): del request.session['specs'] if 'user' in request.session : del request.session['user'] + if 'billing_address_data' in request.session : + del request.session['billing_address_data'] try: manager = OpenNebulaManager() templates = manager.get_templates() context = { - 'templates': VirtualMachineTemplateSerializer(templates, many=True).data, + 'templates': VirtualMachineTemplateSerializer(templates, many=True).data } except: messages.error( request, @@ -303,11 +311,27 @@ class IndexView(CreateView): class PaymentOrderView(FormView): template_name = 'hosting/payment.html' form_class = BillingAddressForm + + def get_form_kwargs(self): + form_kwargs = super(PaymentOrderView, self).get_form_kwargs() + billing_address_data = self.request.session.get('billing_address_data') + if billing_address_data: + form_kwargs.update({ + 'initial': { + 'street_address': billing_address_data['street_address'], + 'city': billing_address_data['city'], + 'postal_code': billing_address_data['postal_code'], + 'country': billing_address_data['country'], + } + }) + return form_kwargs + def get_context_data(self, **kwargs): context = super(PaymentOrderView, self).get_context_data(**kwargs) context.update({ - 'stripe_key': settings.STRIPE_API_PUBLIC_KEY + 'stripe_key': settings.STRIPE_API_PUBLIC_KEY, + 'site_url': reverse('datacenterlight:index') }) return context @@ -322,13 +346,9 @@ class PaymentOrderView(FormView): if form.is_valid(): # Get billing address data billing_address_data = form.cleaned_data - context = self.get_context_data() - template = request.session.get('template') - specs = request.session.get('specs') - user = request.session.get('user') - vm_template_id = template.get('id', 1) - final_price = specs.get('price') token = form.cleaned_data.get('token') + user = request.session.get('user') + try: custom_user = CustomUser.objects.get(email=user.get('email')) except CustomUser.DoesNotExist: @@ -340,7 +360,6 @@ class PaymentOrderView(FormView): app='dcl', base_url=None, send_email=False) - # Get or create stripe customer customer = StripeCustomer.get_or_create(email=user.get('email'), token=token) @@ -350,115 +369,131 @@ class PaymentOrderView(FormView): # Create Billing Address billing_address = form.save() - - # Make stripe charge to a customer - stripe_utils = StripeUtils() - charge_response = stripe_utils.make_charge(amount=final_price, - customer=customer.stripe_id) - charge = charge_response.get('response_object') - - # Check if the payment was approved - if not charge: - context.update({ - 'paymentError': charge_response.get('error'), - 'form': form - }) - return render(request, self.template_name, context) - - charge = charge_response.get('response_object') - - # Create OpenNebulaManager - manager = OpenNebulaManager(email=settings.OPENNEBULA_USERNAME, - password=settings.OPENNEBULA_PASSWORD) - - # Create a vm using logged user - vm_id = manager.create_vm( - template_id=vm_template_id, - specs=specs, - vm_name="{email}-{template_name}-{date}".format( - email=user.get('email'), - template_name=template.get('name'), - date=int(datetime.now().strftime("%s"))) - ) - - # Create a Hosting Order - order = HostingOrder.create( - price=final_price, - vm_id=vm_id, - customer=customer, - billing_address=billing_address - ) - - # Create a Hosting Bill - bill = HostingBill.create( - customer=customer, billing_address=billing_address) - - # Create Billing Address for User if he does not have one - if not customer.user.billing_addresses.count(): - billing_address_data.update({ - 'user': customer.user.id - }) - billing_address_user_form = UserBillingAddressForm( - billing_address_data) - billing_address_user_form.is_valid() - billing_address_user_form.save() - - # Associate an order with a stripe payment - order.set_stripe_charge(charge) - - # If the Stripe payment was successed, set order status approved - order.set_approved() - - vm = VirtualMachineSerializer(manager.get_vm(vm_id)).data - - context = { - 'name': user.get('name'), - 'email': user.get('email'), - 'cores': specs.get('cpu'), - 'memory': specs.get('memory'), - 'storage': specs.get('disk_size'), - 'price': specs.get('price'), - 'template': template.get('name'), - 'vm.name': vm['name'], - 'vm.id': vm['vm_id'], - 'order.id': order.id - } - email_data = { - 'subject': "Data Center Light Order from %s" % context['email'], - 'from_email': '(Data Center Light) Data Center Light Support ', - 'to': ['info@ungleich.ch'], - 'body': "\n".join(["%s=%s" % (k, v) for (k, v) in context.items()]), - 'reply_to': [context['email']], - } - email = EmailMessage(**email_data) - email.send() - return HttpResponseRedirect(reverse('datacenterlight:order_confirmation', kwargs={'pk': order.id})) + request.session['billing_address_data'] = billing_address_data + request.session['billing_address'] = billing_address.id + request.session['token'] = token + request.session['customer'] = customer.id + return HttpResponseRedirect(reverse('datacenterlight:order_confirmation')) else: return self.form_invalid(form) class OrderConfirmationView(DetailView): template_name = "datacenterlight/order_detail.html" + payment_template_name = 'hosting/payment.html' context_object_name = "order" model = HostingOrder - def get_context_data(self, **kwargs): - # Get context - context = super(DetailView, self).get_context_data(**kwargs) - obj = self.get_object() + + @cache_control(no_cache=True, must_revalidate=True, no_store=True) + def get(self, request, *args, **kwargs): + if 'specs' not in request.session or 'user' not in request.session: + return HttpResponseRedirect(reverse('datacenterlight:index')) + if 'token' not in request.session: + return HttpResponseRedirect(reverse('datacenterlight:payment')) + stripe_customer_id = request.session.get('customer') + customer = StripeCustomer.objects.filter(id=stripe_customer_id).first() + stripe_utils = StripeUtils() + card_details = stripe_utils.get_card_details(customer.stripe_id, request.session.get('token')) + context = { + 'site_url': reverse('datacenterlight:index'), + 'cc_last4' : card_details.get('response_object').get('last4'), + 'cc_brand' : card_details.get('response_object').get('brand') + } + return render(request, self.template_name, context) + + def post(self, request, *args, **kwargs): + template = request.session.get('template') + specs = request.session.get('specs') + user = request.session.get('user') + stripe_customer_id = request.session.get('customer') + customer = StripeCustomer.objects.filter(id=stripe_customer_id).first() + billing_address_data = request.session.get('billing_address_data') + billing_address_id = request.session.get('billing_address') + billing_address = BillingAddress.objects.filter(id=billing_address_id).first() + token = request.session.get('token') + vm_template_id = template.get('id', 1) + final_price = specs.get('price') + + # Make stripe charge to a customer + stripe_utils = StripeUtils() + charge_response = stripe_utils.make_charge(amount=final_price, + customer=customer.stripe_id) + charge = charge_response.get('response_object') + + # Check if the payment was approved + if not charge: + context.update({ + 'paymentError': charge_response.get('error') + # TODO add logic in payment form to autofill data + #'form': form + }) + return render(request, self.payment_template_name, context) + + charge = charge_response.get('response_object') + + # Create OpenNebulaManager manager = OpenNebulaManager(email=settings.OPENNEBULA_USERNAME, password=settings.OPENNEBULA_PASSWORD) - try: - vm = manager.get_vm(obj.vm_id) - context['vm'] = VirtualMachineSerializer(vm).data - context['next_url'] = reverse('datacenterlight:order_success') - except WrongIdError: - messages.error(self.request, - 'The VM you are looking for is unavailable at the moment. \ - Please contact Data Center Light support.' - ) - self.kwargs['error'] = 'WrongIdError' - context['error'] = 'WrongIdError' - except ConnectionRefusedError: - messages.error(self.request, - 'In order to create a VM, you need to create/upload your SSH KEY first.' - ) - return context + + # Create a vm using oneadmin, also specify the name + vm_id = manager.create_vm( + template_id=vm_template_id, + specs=specs, + vm_name="{email}-{template_name}-{date}".format( + email=user.get('email'), + template_name=template.get('name'), + date=int(datetime.now().strftime("%s"))) + ) + + # Create a Hosting Order + order = HostingOrder.create( + price=final_price, + vm_id=vm_id, + customer=customer, + billing_address=billing_address + ) + + # Create a Hosting Bill + bill = HostingBill.create( + customer=customer, billing_address=billing_address) + + # Create Billing Address for User if he does not have one + if not customer.user.billing_addresses.count(): + billing_address_data.update({ + 'user': customer.user.id + }) + billing_address_user_form = UserBillingAddressForm( + billing_address_data) + billing_address_user_form.is_valid() + billing_address_user_form.save() + + # Associate an order with a stripe payment + order.set_stripe_charge(charge) + + # If the Stripe payment was successed, set order status approved + order.set_approved() + + vm = VirtualMachineSerializer(manager.get_vm(vm_id)).data + + context = { + 'name': user.get('name'), + 'email': user.get('email'), + 'cores': specs.get('cpu'), + 'memory': specs.get('memory'), + 'storage': specs.get('disk_size'), + 'price': specs.get('price'), + 'template': template.get('name'), + 'vm.name': vm['name'], + 'vm.id': vm['vm_id'], + 'order.id': order.id + } + email_data = { + 'subject': settings.DCL_TEXT + " Order from %s" % context['email'], + 'from_email': settings.DCL_SUPPORT_FROM_ADDRESS, + 'to': ['info@ungleich.ch'], + 'body': "\n".join(["%s=%s" % (k, v) for (k, v) in context.items()]), + 'reply_to': [context['email']], + } + email = EmailMessage(**email_data) + email.send() + request.session['order_confirmation'] = True + return HttpResponseRedirect(reverse('datacenterlight:order_success')) diff --git a/hosting/locale/de/LC_MESSAGES/django.po b/hosting/locale/de/LC_MESSAGES/django.po index 674f3db4..b3cc6c0b 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-06-23 02:28+0530\n" +"POT-Creation-Date: 2017-07-01 02:09+0530\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -26,47 +26,47 @@ msgstr "Dein Account wurde noch nicht aktiviert." msgid "Paste here your public key" msgstr "Fügen Sie Ihren public key ein" -#: templates/hosting/base_short.html:67 +#: templates/hosting/base_short.html:68 msgid "My Virtual Machines" msgstr "Meine virtuellen Maschinen" -#: templates/hosting/base_short.html:72 templates/hosting/orders.html.py:12 +#: templates/hosting/base_short.html:73 templates/hosting/orders.html.py:12 msgid "My Orders" msgstr "Meine Bestellungen" -#: templates/hosting/base_short.html:81 +#: templates/hosting/base_short.html:82 msgid "Keys" msgstr "Schlüssel" -#: templates/hosting/base_short.html:86 +#: templates/hosting/base_short.html:87 msgid "Notifications " msgstr "Benachrichtigungen" -#: templates/hosting/base_short.html:89 +#: templates/hosting/base_short.html:90 msgid "Logout" msgstr "Abmelden" -#: templates/hosting/base_short.html:94 +#: templates/hosting/base_short.html:95 msgid "How it works" msgstr "So funktioniert es" -#: templates/hosting/base_short.html:97 +#: templates/hosting/base_short.html:98 msgid "Your infrastructure" msgstr "deine Infrastruktur" -#: templates/hosting/base_short.html:100 +#: templates/hosting/base_short.html:101 msgid "Our inftrastructure" msgstr "Unsere Infrastruktur" -#: templates/hosting/base_short.html:103 +#: templates/hosting/base_short.html:104 msgid "Pricing" msgstr "Preise" -#: templates/hosting/base_short.html:106 +#: templates/hosting/base_short.html:107 msgid "Contact" msgstr "Kontakt" -#: templates/hosting/base_short.html:109 +#: templates/hosting/base_short.html:110 #: templates/hosting/confirm_reset_password.html:38 #: templates/hosting/login.html:17 templates/hosting/login.html.py:26 #: templates/hosting/reset_password.html:32 templates/hosting/signup.html:30 @@ -347,11 +347,11 @@ msgstr "Bestellung stornieren" msgid "Do You want to delete your order?" msgstr "Willst du deine Bestellung löschen?" -#: templates/hosting/orders.html:63 templates/hosting/user_keys.html.py:62 +#: templates/hosting/orders.html:63 templates/hosting/user_keys.html.py:63 msgid "Close" msgstr "Schliessen" -#: templates/hosting/orders.html:65 templates/hosting/user_keys.html.py:64 +#: templates/hosting/orders.html:65 templates/hosting/user_keys.html.py:65 msgid "Delete" msgstr "Löschen" @@ -359,31 +359,36 @@ msgstr "Löschen" msgid "Billing Amount" msgstr "Rechnungsbetrag" -#: templates/hosting/payment.html:35 +#: templates/hosting/payment.html:26 +#: templates/hosting/virtual_machine_detail.html:98 +msgid "Configuration" +msgstr "Konfiguration" + +#: templates/hosting/payment.html:38 msgid "Billing Address" msgstr "Rechnungsadresse" -#: templates/hosting/payment.html:49 +#: templates/hosting/payment.html:52 msgid "Payment Details" msgstr "Rechnungsdetails" -#: templates/hosting/payment.html:62 +#: templates/hosting/payment.html:65 msgid "Submit Payment" msgstr "Betrag überweisen" -#: templates/hosting/payment.html:81 +#: templates/hosting/payment.html:84 msgid "CARD NUMBER" msgstr "Kreditkartennummer" -#: templates/hosting/payment.html:86 +#: templates/hosting/payment.html:89 msgid "Valid Card Number" msgstr "Gültige Kreditkartennummer" -#: templates/hosting/payment.html:95 +#: templates/hosting/payment.html:98 msgid "EXPIRATION DATE" msgstr "Ablaufdatum" -#: templates/hosting/payment.html:106 +#: templates/hosting/payment.html:109 msgid "CV CODE" msgstr "CV Code" @@ -425,13 +430,13 @@ msgstr "Schlüssel hinzufügen" msgid "Created at" msgstr "Erstellt am" -#: templates/hosting/user_keys.html:42 +#: templates/hosting/user_keys.html:43 #, fuzzy #| msgid "Delete" msgid "Delete Key" msgstr "Löschen" -#: templates/hosting/user_keys.html:55 +#: templates/hosting/user_keys.html:56 #, fuzzy #| msgid "Do You want do delete your order?" msgid "Do You want to delete this key?" @@ -453,10 +458,6 @@ msgstr "Ip nicht zugewiesen" msgid "Disk" msgstr "Festplatte" -#: templates/hosting/virtual_machine_detail.html:98 -msgid "Configuration" -msgstr "Konfiguration" - #: templates/hosting/virtual_machine_detail.html:108 msgid "Current pricing" msgstr "Aktueller Preis" diff --git a/hosting/templates/hosting/base_short.html b/hosting/templates/hosting/base_short.html index e1a6a027..c3b19c8c 100644 --- a/hosting/templates/hosting/base_short.html +++ b/hosting/templates/hosting/base_short.html @@ -57,7 +57,7 @@ - + {% if request.user.is_authenticated %} @@ -131,6 +131,8 @@ + {% else %} + {% include "datacenterlight/includes/_footer.html" %} {% endif %} diff --git a/hosting/templates/hosting/payment.html b/hosting/templates/hosting/payment.html index e41f57d7..a09061bb 100644 --- a/hosting/templates/hosting/payment.html +++ b/hosting/templates/hosting/payment.html @@ -22,6 +22,9 @@

{%trans "Disk space"%} {{request.session.specs.disk_size|floatformat}} GB

+
+

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


Total

{{request.session.specs.price }} CHF

diff --git a/utils/stripe_utils.py b/utils/stripe_utils.py index 29b45d8e..3b20b708 100644 --- a/utils/stripe_utils.py +++ b/utils/stripe_utils.py @@ -77,6 +77,16 @@ class StripeUtils(object): } return new_card_data + @handleStripeError + def get_card_details(self, customer_id, token): + customer = stripe.Customer.retrieve(customer_id) + credit_card_raw_data = customer.sources.data.pop() + card_details = { + 'last4': credit_card_raw_data.last4, + 'brand': credit_card_raw_data.brand + } + return card_details + def check_customer(self, id, user, token): customers = self.stripe.Customer.all() if not customers.get('data'):