merged master
This commit is contained in:
		
				commit
				
					
						734a41a371
					
				
			
		
					 25 changed files with 330 additions and 370 deletions
				
			
		| 
						 | 
					@ -1,10 +1,15 @@
 | 
				
			||||||
Next:
 | 
					1.2.4: 2017-10-02
 | 
				
			||||||
 | 
					    * #3780: [hosting] Store VM details locally
 | 
				
			||||||
    * #3764: [hosting] Show cancelled VMs' invoices 
 | 
					    * #3764: [hosting] Show cancelled VMs' invoices 
 | 
				
			||||||
    * #3736: [dcl] Refactor the place where we compute the VM price
 | 
					    * #3736: [dcl] Refactor the place where we compute the VM price
 | 
				
			||||||
    * #3730: [dcl] Refactor price parameter passed in the DCL flow
 | 
					    * #3730: [dcl] Refactor price parameter passed in the DCL flow
 | 
				
			||||||
    * #3807: [dcl] Remove PricingView as it is no more used
 | 
					    * #3807: [dcl] Remove PricingView as it is no more used
 | 
				
			||||||
    * #3813: [hosting] JS error in create ssh key page
 | 
					    * #3813: [hosting] JS error in create ssh key page
 | 
				
			||||||
    * #3756: [dcl] Update landing calculator and billing info page
 | 
					    * #3756: [dcl] Update landing calculator and billing info page
 | 
				
			||||||
 | 
					    * Bugfix: Fix PR 493 bug that creates a new StripeCustomer for each buying of VM with the same email id
 | 
				
			||||||
 | 
					    * #3835: [all] Forbidden (403) CSRF verification failed issue.
 | 
				
			||||||
 | 
					    * Bugfix: [hosting] Dashboard strictly available after login
 | 
				
			||||||
 | 
					    * #3808: [dcl] Order confirmation page redesign
 | 
				
			||||||
1.2.3: 2017-09-25
 | 
					1.2.3: 2017-09-25
 | 
				
			||||||
    * #3484: [dcl, hosting] Refactored account activation, password reset, VM order and cancellation email
 | 
					    * #3484: [dcl, hosting] Refactored account activation, password reset, VM order and cancellation email
 | 
				
			||||||
    * #3731: [dcl, hosting] Added cdist ssh key handler 
 | 
					    * #3731: [dcl, hosting] Added cdist ssh key handler 
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -8,7 +8,7 @@ msgid ""
 | 
				
			||||||
msgstr ""
 | 
					msgstr ""
 | 
				
			||||||
"Project-Id-Version: PACKAGE VERSION\n"
 | 
					"Project-Id-Version: PACKAGE VERSION\n"
 | 
				
			||||||
"Report-Msgid-Bugs-To: \n"
 | 
					"Report-Msgid-Bugs-To: \n"
 | 
				
			||||||
"POT-Creation-Date: 2017-09-23 21:22+0000\n"
 | 
					"POT-Creation-Date: 2017-10-01 22:13+0000\n"
 | 
				
			||||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
 | 
					"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
 | 
				
			||||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
 | 
					"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
 | 
				
			||||||
"Language-Team: LANGUAGE <LL@li.org>\n"
 | 
					"Language-Team: LANGUAGE <LL@li.org>\n"
 | 
				
			||||||
| 
						 | 
					@ -388,24 +388,6 @@ msgstr "Weiter"
 | 
				
			||||||
msgid "Enter your credit card number"
 | 
					msgid "Enter your credit card number"
 | 
				
			||||||
msgstr "Deine Kreditkartennummer"
 | 
					msgstr "Deine Kreditkartennummer"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
msgid "Confirm Order"
 | 
					 | 
				
			||||||
msgstr "Bestellung Bestätigen"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
msgid "Date"
 | 
					 | 
				
			||||||
msgstr "Datum"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
msgid "Billed To:"
 | 
					 | 
				
			||||||
msgstr "Rechnungsadresse"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
msgid "Payment Method:"
 | 
					 | 
				
			||||||
msgstr "Bezahlmethode"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
msgid "ending in"
 | 
					 | 
				
			||||||
msgstr "endend in"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
msgid "Order summary"
 | 
					 | 
				
			||||||
msgstr "Bestellungsübersicht"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#, python-format
 | 
					#, python-format
 | 
				
			||||||
msgid ""
 | 
					msgid ""
 | 
				
			||||||
"By clicking \"Place order\" this plan will charge your credit card account "
 | 
					"By clicking \"Place order\" this plan will charge your credit card account "
 | 
				
			||||||
| 
						 | 
					@ -417,36 +399,6 @@ msgstr ""
 | 
				
			||||||
msgid "Place order"
 | 
					msgid "Place order"
 | 
				
			||||||
msgstr "Bestellen"
 | 
					msgstr "Bestellen"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
msgid "Processing..."
 | 
					 | 
				
			||||||
msgstr "Abarbeitung..."
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
msgid "Hold tight, we are processing your request"
 | 
					 | 
				
			||||||
msgstr "Bitte warten - wir verbeiten Deine Anfrage gerade"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
msgid "Some problem encountered. Please try again later."
 | 
					 | 
				
			||||||
msgstr "Ein Problem ist aufgetreten. Bitte versuche es später noch einmal."
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
msgid "We are cutting down the costs significantly!"
 | 
					 | 
				
			||||||
msgstr "Wir sorgen dafür, dass die Kosten für Dich signifikant abnehmen"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
msgid "Order Now!"
 | 
					 | 
				
			||||||
msgstr "Bestelle jetzt!"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
msgid ""
 | 
					 | 
				
			||||||
"Our VMs are hosted in Glarus, Switzerland, and our website is currently "
 | 
					 | 
				
			||||||
"running in BETA mode. If you want more information that you did not find on "
 | 
					 | 
				
			||||||
"our website, or if your order is more detailed, or if you encounter any "
 | 
					 | 
				
			||||||
"technical hiccups, please contact us at support@datacenterlight.ch, our team "
 | 
					 | 
				
			||||||
"will get in touch with you asap."
 | 
					 | 
				
			||||||
msgstr ""
 | 
					 | 
				
			||||||
"Unsere VMs werden in der Schweiz im Kanton Glarus gehostet und befinden sich "
 | 
					 | 
				
			||||||
"zur Zeit noch in der BETA-Phase. Möchtest du mehr über uns erfahren und hast "
 | 
					 | 
				
			||||||
"auf unserer Website nicht genügend Informationen gefunden? Möchtest eine "
 | 
					 | 
				
			||||||
"detailliertere Bestellung aufgeben? Bist du auf technische Probleme "
 | 
					 | 
				
			||||||
"gestossen, die du uns mitteilen möchtest? Dann zögere nicht und kontaktiere "
 | 
					 | 
				
			||||||
"uns unter support@datacenterlight.ch. Unser Team wird sich umgehend um dein "
 | 
					 | 
				
			||||||
"Anliegen kümmern!"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
msgid "Thank you for order! Our team will contact you via email"
 | 
					msgid "Thank you for order! Our team will contact you via email"
 | 
				
			||||||
msgstr ""
 | 
					msgstr ""
 | 
				
			||||||
"Vielen Dank für die Bestellung. Unser Team setzt sich sobald wie möglich mit "
 | 
					"Vielen Dank für die Bestellung. Unser Team setzt sich sobald wie möglich mit "
 | 
				
			||||||
| 
						 | 
					@ -540,6 +492,9 @@ msgstr "Ungültige RAM-Grösse"
 | 
				
			||||||
msgid "Invalid storage size"
 | 
					msgid "Invalid storage size"
 | 
				
			||||||
msgstr "Ungültige Speicher-Grösse"
 | 
					msgstr "Ungültige Speicher-Grösse"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					msgid "Confirm Order"
 | 
				
			||||||
 | 
					msgstr "Bestellung Bestätigen"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
msgid "Error."
 | 
					msgid "Error."
 | 
				
			||||||
msgstr ""
 | 
					msgstr ""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -547,6 +502,8 @@ msgid ""
 | 
				
			||||||
"There was a payment related error. On close of this popup, you will be "
 | 
					"There was a payment related error. On close of this popup, you will be "
 | 
				
			||||||
"redirected back to the payment page."
 | 
					"redirected back to the payment page."
 | 
				
			||||||
msgstr ""
 | 
					msgstr ""
 | 
				
			||||||
 | 
					"Es ist ein Fehler bei der Zahlung betreten. Du wirst nach dem Schliessen vom "
 | 
				
			||||||
 | 
					"Popup zur Bezahlseite weitergeleitet."
 | 
				
			||||||
 | 
					
 | 
				
			||||||
msgid "Thank you for the order."
 | 
					msgid "Thank you for the order."
 | 
				
			||||||
msgstr "Danke für Deine Bestellung."
 | 
					msgstr "Danke für Deine Bestellung."
 | 
				
			||||||
| 
						 | 
					@ -558,6 +515,51 @@ msgstr ""
 | 
				
			||||||
"Deine VM ist gleich bereit. Wir senden Dir eine Bestätigungsemail, sobald Du "
 | 
					"Deine VM ist gleich bereit. Wir senden Dir eine Bestätigungsemail, sobald Du "
 | 
				
			||||||
"auf sie zugreifen kannst."
 | 
					"auf sie zugreifen kannst."
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#~ msgid "Date"
 | 
				
			||||||
 | 
					#~ msgstr "Datum"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#~ msgid "Billed To:"
 | 
				
			||||||
 | 
					#~ msgstr "Rechnungsadresse"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#~ msgid "Payment Method:"
 | 
				
			||||||
 | 
					#~ msgstr "Bezahlmethode"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#~ msgid "ending in"
 | 
				
			||||||
 | 
					#~ msgstr "endend in"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#~ msgid "Order summary"
 | 
				
			||||||
 | 
					#~ msgstr "Bestellungsübersicht"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#~ msgid "Processing..."
 | 
				
			||||||
 | 
					#~ msgstr "Abarbeitung..."
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#~ msgid "Hold tight, we are processing your request"
 | 
				
			||||||
 | 
					#~ msgstr "Bitte warten - wir verbeiten Deine Anfrage gerade"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#~ msgid "Some problem encountered. Please try again later."
 | 
				
			||||||
 | 
					#~ msgstr "Ein Problem ist aufgetreten. Bitte versuche es später noch einmal."
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#~ msgid "We are cutting down the costs significantly!"
 | 
				
			||||||
 | 
					#~ msgstr "Wir sorgen dafür, dass die Kosten für Dich signifikant abnehmen"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#~ msgid "Order Now!"
 | 
				
			||||||
 | 
					#~ msgstr "Bestelle jetzt!"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#~ msgid ""
 | 
				
			||||||
 | 
					#~ "Our VMs are hosted in Glarus, Switzerland, and our website is currently "
 | 
				
			||||||
 | 
					#~ "running in BETA mode. If you want more information that you did not find "
 | 
				
			||||||
 | 
					#~ "on our website, or if your order is more detailed, or if you encounter "
 | 
				
			||||||
 | 
					#~ "any technical hiccups, please contact us at support@datacenterlight.ch, "
 | 
				
			||||||
 | 
					#~ "our team will get in touch with you asap."
 | 
				
			||||||
 | 
					#~ msgstr ""
 | 
				
			||||||
 | 
					#~ "Unsere VMs werden in der Schweiz im Kanton Glarus gehostet und befinden "
 | 
				
			||||||
 | 
					#~ "sich zur Zeit noch in der BETA-Phase. Möchtest du mehr über uns erfahren "
 | 
				
			||||||
 | 
					#~ "und hast auf unserer Website nicht genügend Informationen gefunden? "
 | 
				
			||||||
 | 
					#~ "Möchtest eine detailliertere Bestellung aufgeben? Bist du auf technische "
 | 
				
			||||||
 | 
					#~ "Probleme gestossen, die du uns mitteilen möchtest? Dann zögere nicht und "
 | 
				
			||||||
 | 
					#~ "kontaktiere uns unter support@datacenterlight.ch. Unser Team wird sich "
 | 
				
			||||||
 | 
					#~ "umgehend um dein Anliegen kümmern!"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#~ msgid "Email Address"
 | 
					#~ msgid "Email Address"
 | 
				
			||||||
#~ msgstr "E-Mail-Adresse"
 | 
					#~ msgstr "E-Mail-Adresse"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1501,6 +1501,8 @@ tech-sub-sec h2 {
 | 
				
			||||||
    font-size: 14px;
 | 
					    font-size: 14px;
 | 
				
			||||||
    font-weight: 300;
 | 
					    font-weight: 300;
 | 
				
			||||||
    letter-spacing: 2px;
 | 
					    letter-spacing: 2px;
 | 
				
			||||||
 | 
					    line-height: 24px;
 | 
				
			||||||
 | 
					    display: block;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.content-section-a {
 | 
					.content-section-a {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -50,15 +50,20 @@ def retry_task(task, exception=None):
 | 
				
			||||||
@app.task(bind=True, max_retries=settings.CELERY_MAX_RETRIES)
 | 
					@app.task(bind=True, max_retries=settings.CELERY_MAX_RETRIES)
 | 
				
			||||||
def create_vm_task(self, vm_template_id, user, specs, template,
 | 
					def create_vm_task(self, vm_template_id, user, specs, template,
 | 
				
			||||||
                   stripe_customer_id, billing_address_data,
 | 
					                   stripe_customer_id, billing_address_data,
 | 
				
			||||||
                   billing_address_id,
 | 
					                   stripe_subscription_id, cc_details):
 | 
				
			||||||
                   charge, cc_details):
 | 
					 | 
				
			||||||
    logger.debug(
 | 
					    logger.debug(
 | 
				
			||||||
        "Running create_vm_task on {}".format(current_task.request.hostname))
 | 
					        "Running create_vm_task on {}".format(current_task.request.hostname))
 | 
				
			||||||
    vm_id = None
 | 
					    vm_id = None
 | 
				
			||||||
    try:
 | 
					    try:
 | 
				
			||||||
        final_price = specs.get('price')
 | 
					        final_price = specs.get('price')
 | 
				
			||||||
        billing_address = BillingAddress.objects.filter(
 | 
					        billing_address = BillingAddress(
 | 
				
			||||||
            id=billing_address_id).first()
 | 
					            cardholder_name=billing_address_data['cardholder_name'],
 | 
				
			||||||
 | 
					            street_address=billing_address_data['street_address'],
 | 
				
			||||||
 | 
					            city=billing_address_data['city'],
 | 
				
			||||||
 | 
					            postal_code=billing_address_data['postal_code'],
 | 
				
			||||||
 | 
					            country=billing_address_data['country']
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					        billing_address.save()
 | 
				
			||||||
        customer = StripeCustomer.objects.filter(id=stripe_customer_id).first()
 | 
					        customer = StripeCustomer.objects.filter(id=stripe_customer_id).first()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if 'pass' in user:
 | 
					        if 'pass' in user:
 | 
				
			||||||
| 
						 | 
					@ -111,8 +116,7 @@ def create_vm_task(self, vm_template_id, user, specs, template,
 | 
				
			||||||
            billing_address_user_form.save()
 | 
					            billing_address_user_form.save()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # Associate an order with a stripe subscription
 | 
					        # Associate an order with a stripe subscription
 | 
				
			||||||
        charge_object = DictDotLookup(charge)
 | 
					        order.set_subscription_id(stripe_subscription_id, cc_details)
 | 
				
			||||||
        order.set_subscription_id(charge_object, cc_details)
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # If the Stripe payment succeeds, set order status approved
 | 
					        # If the Stripe payment succeeds, set order status approved
 | 
				
			||||||
        order.set_approved()
 | 
					        order.set_approved()
 | 
				
			||||||
| 
						 | 
					@ -183,7 +187,8 @@ def create_vm_task(self, vm_template_id, user, specs, template,
 | 
				
			||||||
                            public_keys]
 | 
					                            public_keys]
 | 
				
			||||||
                    if len(keys) > 0:
 | 
					                    if len(keys) > 0:
 | 
				
			||||||
                        logger.debug(
 | 
					                        logger.debug(
 | 
				
			||||||
                            "Calling configure on {host} for {num_keys} keys".format(
 | 
					                            "Calling configure on {host} for "
 | 
				
			||||||
 | 
					                            "{num_keys} keys".format(
 | 
				
			||||||
                                host=new_host, num_keys=len(keys)))
 | 
					                                host=new_host, num_keys=len(keys)))
 | 
				
			||||||
                        # Let's delay the task by 75 seconds to be sure
 | 
					                        # Let's delay the task by 75 seconds to be sure
 | 
				
			||||||
                        # that we run the cdist configure after the host
 | 
					                        # that we run the cdist configure after the host
 | 
				
			||||||
| 
						 | 
					@ -212,32 +217,3 @@ def create_vm_task(self, vm_template_id, user, specs, template,
 | 
				
			||||||
            return
 | 
					            return
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return vm_id
 | 
					    return vm_id
 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
class DictDotLookup(object):
 | 
					 | 
				
			||||||
    """
 | 
					 | 
				
			||||||
    Creates objects that behave much like a dictionaries, but allow nested
 | 
					 | 
				
			||||||
    key access using object '.' (dot) lookups.
 | 
					 | 
				
			||||||
    """
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def __init__(self, d):
 | 
					 | 
				
			||||||
        for k in d:
 | 
					 | 
				
			||||||
            if isinstance(d[k], dict):
 | 
					 | 
				
			||||||
                self.__dict__[k] = DictDotLookup(d[k])
 | 
					 | 
				
			||||||
            elif isinstance(d[k], (list, tuple)):
 | 
					 | 
				
			||||||
                l = []
 | 
					 | 
				
			||||||
                for v in d[k]:
 | 
					 | 
				
			||||||
                    if isinstance(v, dict):
 | 
					 | 
				
			||||||
                        l.append(DictDotLookup(v))
 | 
					 | 
				
			||||||
                    else:
 | 
					 | 
				
			||||||
                        l.append(v)
 | 
					 | 
				
			||||||
                self.__dict__[k] = l
 | 
					 | 
				
			||||||
            else:
 | 
					 | 
				
			||||||
                self.__dict__[k] = d[k]
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def __getitem__(self, name):
 | 
					 | 
				
			||||||
        if name in self.__dict__:
 | 
					 | 
				
			||||||
            return self.__dict__[name]
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def __iter__(self):
 | 
					 | 
				
			||||||
        return iter(self.__dict__.keys())
 | 
					 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -16,7 +16,7 @@
 | 
				
			||||||
                        <hr class="intro-divider">
 | 
					                        <hr class="intro-divider">
 | 
				
			||||||
                        <ul class="list-inline intro-social-buttons">
 | 
					                        <ul class="list-inline intro-social-buttons">
 | 
				
			||||||
                            <li>
 | 
					                            <li>
 | 
				
			||||||
                                <a class="btn btn-default btn-lg btn-transparent url" href="#how"><i class="#Services"></i> <span class="network-name">{% trans "Highlights" %}</span></a>
 | 
					                                <a class="btn btn-default btn-lg btn-transparent url" href="#how"><span class="network-name">{% trans "Highlights" %}</span></a>
 | 
				
			||||||
                            </li>
 | 
					                            </li>
 | 
				
			||||||
                            <li>
 | 
					                            <li>
 | 
				
			||||||
                                <a class="btn btn-primary btn-lg page-scroll url" href="#price"><span class="network-name">{% trans "I want it!" %}</span></a>
 | 
					                                <a class="btn btn-primary btn-lg page-scroll url" href="#price"><span class="network-name">{% trans "I want it!" %}</span></a>
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,143 +1,24 @@
 | 
				
			||||||
{% extends "hosting/base_short.html" %}
 | 
					{% extends "hosting/order_detail.html" %}
 | 
				
			||||||
{% load staticfiles bootstrap3 %}
 | 
					 | 
				
			||||||
{% load i18n %}
 | 
					{% load i18n %}
 | 
				
			||||||
{% load custom_tags %}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
{% block navbar %}
 | 
					{% block navbar %}
 | 
				
			||||||
    {% include "datacenterlight/includes/_navbar.html" %}
 | 
					    {% include "datacenterlight/includes/_navbar.html" %}
 | 
				
			||||||
{% endblock navbar %}
 | 
					{% endblock navbar %}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
{% block content %}
 | 
					{% block submit_btn %}
 | 
				
			||||||
 | 
					  <form id="virtual_machine_create_form" action="" method="POST">
 | 
				
			||||||
<div class="order-detail-container">
 | 
					 | 
				
			||||||
   {% if messages %}
 | 
					 | 
				
			||||||
        <div class="row">
 | 
					 | 
				
			||||||
            <div class="col-xs-12 col-md-8 col-md-offset-2">
 | 
					 | 
				
			||||||
                <br/>
 | 
					 | 
				
			||||||
                <div class="alert alert-warning">
 | 
					 | 
				
			||||||
                    {% for message in messages %}
 | 
					 | 
				
			||||||
                    <span>{{ message }}</span>
 | 
					 | 
				
			||||||
                    {% endfor %}
 | 
					 | 
				
			||||||
                </div>
 | 
					 | 
				
			||||||
            </div>
 | 
					 | 
				
			||||||
        </div>
 | 
					 | 
				
			||||||
    {% endif %}
 | 
					 | 
				
			||||||
    {% if not error %}
 | 
					 | 
				
			||||||
        <div class="row">
 | 
					 | 
				
			||||||
            <div class="col-xs-12 col-md-8 col-md-offset-2">
 | 
					 | 
				
			||||||
                <div class="invoice-title">
 | 
					 | 
				
			||||||
                    <h2>{% trans "Confirm Order"%}</h2>
 | 
					 | 
				
			||||||
                </div>
 | 
					 | 
				
			||||||
                <hr>
 | 
					 | 
				
			||||||
                <div class="row">
 | 
					 | 
				
			||||||
                    <div class="col-xs-12 col-sm-6 pull-right order-confirm-date">
 | 
					 | 
				
			||||||
                        <address>
 | 
					 | 
				
			||||||
                            <strong>{% trans "Date"%}:</strong><br>
 | 
					 | 
				
			||||||
                            <span id="order-created_at">{% now "Y-m-d H:i" %}</span><br><br>
 | 
					 | 
				
			||||||
                        </address>
 | 
					 | 
				
			||||||
                    </div>
 | 
					 | 
				
			||||||
                    <div class="col-xs-12 col-sm-6">
 | 
					 | 
				
			||||||
                        <address>
 | 
					 | 
				
			||||||
                        <h3><b>{% trans "Billed To:"%}</b></h3>
 | 
					 | 
				
			||||||
                        {% with billing_address_data as billing_address %}
 | 
					 | 
				
			||||||
                            {{billing_address.cardholder_name}}<br> {{billing_address.street_address}}, {{billing_address.postal_code}}<br>
 | 
					 | 
				
			||||||
                            {{billing_address.city}}, {{billing_address.country}}.
 | 
					 | 
				
			||||||
                        {% endwith %}
 | 
					 | 
				
			||||||
                        </address>
 | 
					 | 
				
			||||||
                    </div>
 | 
					 | 
				
			||||||
                </div>
 | 
					 | 
				
			||||||
                <div class="row">
 | 
					 | 
				
			||||||
                    <div class="col-xs-6">
 | 
					 | 
				
			||||||
                        <address>
 | 
					 | 
				
			||||||
                            <strong>{% trans "Payment Method:"%}</strong><br>
 | 
					 | 
				
			||||||
                                {{cc_brand}} {% trans "ending in" %} **** {{cc_last4}}<br>
 | 
					 | 
				
			||||||
                                {{request.session.user.email}}
 | 
					 | 
				
			||||||
                        </address>
 | 
					 | 
				
			||||||
                    </div>
 | 
					 | 
				
			||||||
                </div>
 | 
					 | 
				
			||||||
            </div>
 | 
					 | 
				
			||||||
        </div>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        <div class="row">
 | 
					 | 
				
			||||||
            <div class="col-md-8 col-md-offset-2">
 | 
					 | 
				
			||||||
                <h3><b>{% trans "Order summary"%}</b></h3>
 | 
					 | 
				
			||||||
                <hr>
 | 
					 | 
				
			||||||
                <div class="content">
 | 
					 | 
				
			||||||
                    {% with request.session.specs as vm %}
 | 
					 | 
				
			||||||
                        <p><b>{% trans "Cores"%}</b> <span class="pull-right">{{vm.cpu}}</span></p>
 | 
					 | 
				
			||||||
                        <hr>
 | 
					 | 
				
			||||||
                        <p><b>{% trans "Memory"%}</b> <span class="pull-right">{{vm.memory}} GB</span></p>
 | 
					 | 
				
			||||||
                        <hr>
 | 
					 | 
				
			||||||
                        <p><b>{% trans "Disk space"%}</b> <span class="pull-right">{{vm.disk_size}} GB</span></p>
 | 
					 | 
				
			||||||
                        <hr>
 | 
					 | 
				
			||||||
                        <p><b>{% trans "Configuration"%}</b> <span class="pull-right">{{request.session.template.name}}</span></p>
 | 
					 | 
				
			||||||
                        <hr>
 | 
					 | 
				
			||||||
                        <h4>{% trans "Total"%}<p class="pull-right"><b>{{vm.price}} CHF</b><span class="dcl-price-month"> /{% trans "Month" %}</span></p></h4>
 | 
					 | 
				
			||||||
                    {% endwith %}
 | 
					 | 
				
			||||||
                </div>
 | 
					 | 
				
			||||||
                <br/>
 | 
					 | 
				
			||||||
                <form method="post" id="virtual_machine_create_form">
 | 
					 | 
				
			||||||
      {% csrf_token %}
 | 
					      {% csrf_token %}
 | 
				
			||||||
      <div class="row">
 | 
					      <div class="row">
 | 
				
			||||||
          <div class="col-sm-8">
 | 
					          <div class="col-sm-8">
 | 
				
			||||||
                            <p class="dcl-place-order-text">{% 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 %}.</p>
 | 
					              <div class="dcl-place-order-text">{% 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 %}.</div>
 | 
				
			||||||
          </div>
 | 
					          </div>
 | 
				
			||||||
                        <div class="col-sm-4 content">
 | 
					          <div class="col-sm-4 order-confirm-btn text-right">
 | 
				
			||||||
                            <button class="btn btn-info pull-right"
 | 
					              <button class="btn choice-btn" id="btn-create-vm"
 | 
				
			||||||
                                    id="btn-create-vm"
 | 
					                      data-toggle="modal" data-target="#createvm-modal">
 | 
				
			||||||
                                    data-href="{% url 'hosting:order-confirmation' %}"
 | 
					 | 
				
			||||||
                                    data-toggle="modal"
 | 
					 | 
				
			||||||
                                    data-target="#createvm-modal">
 | 
					 | 
				
			||||||
				{% trans "Place order" %}
 | 
									{% trans "Place order" %}
 | 
				
			||||||
              </button>
 | 
					              </button>
 | 
				
			||||||
          </div>
 | 
					          </div>
 | 
				
			||||||
      </div>
 | 
					      </div>
 | 
				
			||||||
  </form>
 | 
					  </form>
 | 
				
			||||||
            </div>
 | 
					{% endblock submit_btn %}
 | 
				
			||||||
        </div>
 | 
					 | 
				
			||||||
    {% endif %}
 | 
					 | 
				
			||||||
</div>
 | 
					 | 
				
			||||||
<!-- Create VM Modal -->
 | 
					 | 
				
			||||||
<div class="modal fade" id="createvm-modal" tabindex="-1" role="dialog"
 | 
					 | 
				
			||||||
     aria-hidden="true" data-backdrop="static" data-keyboard="false">
 | 
					 | 
				
			||||||
    <div class="modal-dialog">
 | 
					 | 
				
			||||||
        <div class="modal-content">
 | 
					 | 
				
			||||||
            <div class="modal-header">
 | 
					 | 
				
			||||||
                <button type="button" class="close hidden" data-dismiss="modal"
 | 
					 | 
				
			||||||
                        aria-label="create-vm-close">
 | 
					 | 
				
			||||||
                    <span aria-hidden="true">×</span>
 | 
					 | 
				
			||||||
                </button>
 | 
					 | 
				
			||||||
            </div>
 | 
					 | 
				
			||||||
            <div class="modal-body">
 | 
					 | 
				
			||||||
                <div class="modal-icon">
 | 
					 | 
				
			||||||
                    <i class="fa fa-cog fa-spin fa-3x fa-fw"></i>
 | 
					 | 
				
			||||||
                    <span class="sr-only">{% trans "Processing..." %}</span>
 | 
					 | 
				
			||||||
                </div>
 | 
					 | 
				
			||||||
                <h4 class="modal-title" id="createvm-modal-title">
 | 
					 | 
				
			||||||
                </h4>
 | 
					 | 
				
			||||||
                <div class="modal-text" id="createvm-modal-body">
 | 
					 | 
				
			||||||
                    {% trans "Hold tight, we are processing your request" %}
 | 
					 | 
				
			||||||
                </div>
 | 
					 | 
				
			||||||
                <div class="modal-footer">
 | 
					 | 
				
			||||||
                    <a id="createvm-modal-done-btn" class="btn btn-success btn-ok btn-wide hide" href="">{% trans "OK" %}</a>
 | 
					 | 
				
			||||||
                    <button id="createvm-modal-close-btn" type="button" class="btn btn-danger btn-ok btn-wide hide" data-dismiss="modal" aria-label="create-vm-close">{% trans "Close" %}</button>
 | 
					 | 
				
			||||||
                </div>
 | 
					 | 
				
			||||||
            </div>
 | 
					 | 
				
			||||||
        </div>
 | 
					 | 
				
			||||||
    </div>
 | 
					 | 
				
			||||||
</div>
 | 
					 | 
				
			||||||
<!-- / Create VM Modal -->
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
<script type="text/javascript">
 | 
					 | 
				
			||||||
    {% trans "Some problem encountered. Please try again later." as err_msg %}
 | 
					 | 
				
			||||||
    var create_vm_error_message = '{{err_msg|safe}}.';
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    window.onload = function () {
 | 
					 | 
				
			||||||
        var locale_date = moment.utc(document.getElementById("order-created_at").textContent,'YYYY-MM-DD HH:mm').toDate();
 | 
					 | 
				
			||||||
        locale_date =  moment(locale_date).format("YYYY-MM-DD h:mm:ss a");
 | 
					 | 
				
			||||||
        document.getElementById('order-created_at').innerHTML = locale_date;
 | 
					 | 
				
			||||||
    };
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
</script>
 | 
					 | 
				
			||||||
{%endblock%}
 | 
					 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -13,7 +13,6 @@ from datacenterlight.tasks import create_vm_task
 | 
				
			||||||
from membership.models import StripeCustomer
 | 
					from membership.models import StripeCustomer
 | 
				
			||||||
from opennebula_api.serializers import VMTemplateSerializer
 | 
					from opennebula_api.serializers import VMTemplateSerializer
 | 
				
			||||||
from utils.hosting_utils import get_vm_price
 | 
					from utils.hosting_utils import get_vm_price
 | 
				
			||||||
from utils.models import BillingAddress
 | 
					 | 
				
			||||||
from utils.stripe_utils import StripeUtils
 | 
					from utils.stripe_utils import StripeUtils
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -75,21 +74,12 @@ class CeleryTaskTestCase(TestCase):
 | 
				
			||||||
            stripe_customer.stripe_id,
 | 
					            stripe_customer.stripe_id,
 | 
				
			||||||
            self.token)
 | 
					            self.token)
 | 
				
			||||||
        card_details_dict = card_details.get('response_object')
 | 
					        card_details_dict = card_details.get('response_object')
 | 
				
			||||||
        billing_address = BillingAddress(
 | 
					 | 
				
			||||||
            cardholder_name=self.customer_name,
 | 
					 | 
				
			||||||
            postal_code='1232',
 | 
					 | 
				
			||||||
            country='CH',
 | 
					 | 
				
			||||||
            street_address='Monty\'s Street',
 | 
					 | 
				
			||||||
            city='Hollywood')
 | 
					 | 
				
			||||||
        billing_address.save()
 | 
					 | 
				
			||||||
        billing_address_data = {'cardholder_name': self.customer_name,
 | 
					        billing_address_data = {'cardholder_name': self.customer_name,
 | 
				
			||||||
                                'postal_code': '1231',
 | 
					                                'postal_code': '1231',
 | 
				
			||||||
                                'country': 'CH',
 | 
					                                'country': 'CH',
 | 
				
			||||||
                                'token': self.token,
 | 
					                                'token': self.token,
 | 
				
			||||||
                                'street_address': 'Monty\'s Street',
 | 
					                                'street_address': 'Monty\'s Street',
 | 
				
			||||||
                                'city': 'Hollywood'}
 | 
					                                'city': 'Hollywood'}
 | 
				
			||||||
 | 
					 | 
				
			||||||
        billing_address_id = billing_address.id
 | 
					 | 
				
			||||||
        vm_template_id = template_data.get('id', 1)
 | 
					        vm_template_id = template_data.get('id', 1)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        cpu = specs.get('cpu')
 | 
					        cpu = specs.get('cpu')
 | 
				
			||||||
| 
						 | 
					@ -125,8 +115,7 @@ class CeleryTaskTestCase(TestCase):
 | 
				
			||||||
                                          template_data,
 | 
					                                          template_data,
 | 
				
			||||||
                                          stripe_customer.id,
 | 
					                                          stripe_customer.id,
 | 
				
			||||||
                                          billing_address_data,
 | 
					                                          billing_address_data,
 | 
				
			||||||
                                          billing_address_id,
 | 
					                                          stripe_subscription_obj.id,
 | 
				
			||||||
                                          stripe_subscription_obj,
 | 
					 | 
				
			||||||
                                          card_details_dict)
 | 
					                                          card_details_dict)
 | 
				
			||||||
        new_vm_id = 0
 | 
					        new_vm_id = 0
 | 
				
			||||||
        res = None
 | 
					        res = None
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -19,7 +19,7 @@ from hosting.forms import HostingUserLoginForm
 | 
				
			||||||
from membership.models import CustomUser, StripeCustomer
 | 
					from membership.models import CustomUser, StripeCustomer
 | 
				
			||||||
from opennebula_api.serializers import VMTemplateSerializer
 | 
					from opennebula_api.serializers import VMTemplateSerializer
 | 
				
			||||||
from utils.forms import (
 | 
					from utils.forms import (
 | 
				
			||||||
    BillingAddressForm, BillingAddressFormSignup, UserBillingAddressForm
 | 
					    BillingAddressForm, BillingAddressFormSignup
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
from utils.hosting_utils import get_vm_price
 | 
					from utils.hosting_utils import get_vm_price
 | 
				
			||||||
from utils.mailer import BaseEmail
 | 
					from utils.mailer import BaseEmail
 | 
				
			||||||
| 
						 | 
					@ -348,6 +348,11 @@ class PaymentOrderView(FormView):
 | 
				
			||||||
            form_kwargs.update({
 | 
					            form_kwargs.update({
 | 
				
			||||||
                'instance': self.request.user.billing_addresses.first()
 | 
					                'instance': self.request.user.billing_addresses.first()
 | 
				
			||||||
            })
 | 
					            })
 | 
				
			||||||
 | 
					        if 'billing_address_data' in self.request.session:
 | 
				
			||||||
 | 
					            billing_address_data = self.request.session['billing_address_data']
 | 
				
			||||||
 | 
					            form_kwargs.update({
 | 
				
			||||||
 | 
					                'initial': billing_address_data
 | 
				
			||||||
 | 
					            })
 | 
				
			||||||
        return form_kwargs
 | 
					        return form_kwargs
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def get_context_data(self, **kwargs):
 | 
					    def get_context_data(self, **kwargs):
 | 
				
			||||||
| 
						 | 
					@ -379,14 +384,40 @@ class PaymentOrderView(FormView):
 | 
				
			||||||
                    email=this_user.get('email'),
 | 
					                    email=this_user.get('email'),
 | 
				
			||||||
                    token=token)
 | 
					                    token=token)
 | 
				
			||||||
            else:
 | 
					            else:
 | 
				
			||||||
 | 
					                user_email = form.cleaned_data.get('email')
 | 
				
			||||||
 | 
					                user_name = form.cleaned_data.get('name')
 | 
				
			||||||
                this_user = {
 | 
					                this_user = {
 | 
				
			||||||
                    'email': form.cleaned_data.get('email'),
 | 
					                    'email': user_email,
 | 
				
			||||||
                    'name': form.cleaned_data.get('name')
 | 
					                    'name': user_name
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
 | 
					                try:
 | 
				
			||||||
 | 
					                    custom_user = CustomUser.objects.get(email=user_email)
 | 
				
			||||||
 | 
					                    customer = StripeCustomer.objects.filter(
 | 
				
			||||||
 | 
					                        user_id=custom_user.id).first()
 | 
				
			||||||
 | 
					                    if customer is None:
 | 
				
			||||||
 | 
					                        logger.debug(
 | 
				
			||||||
 | 
					                            ("User {email} is already registered with us."
 | 
				
			||||||
 | 
					                             "But, StripeCustomer does not exist for {email}."
 | 
				
			||||||
 | 
					                             "Hence, creating a new StripeCustomer.").format(
 | 
				
			||||||
 | 
					                                email=user_email
 | 
				
			||||||
 | 
					                            )
 | 
				
			||||||
 | 
					                        )
 | 
				
			||||||
                        customer = StripeCustomer.create_stripe_api_customer(
 | 
					                        customer = StripeCustomer.create_stripe_api_customer(
 | 
				
			||||||
                    email=this_user.get('email'),
 | 
					                            email=user_email,
 | 
				
			||||||
                            token=token,
 | 
					                            token=token,
 | 
				
			||||||
                    customer_name=form.cleaned_data.get('name'))
 | 
					                            customer_name=user_name)
 | 
				
			||||||
 | 
					                except CustomUser.DoesNotExist:
 | 
				
			||||||
 | 
					                    logger.debug(
 | 
				
			||||||
 | 
					                        ("StripeCustomer does not exist for {email}."
 | 
				
			||||||
 | 
					                         "Hence, creating a new StripeCustomer.").format(
 | 
				
			||||||
 | 
					                            email=user_email
 | 
				
			||||||
 | 
					                        )
 | 
				
			||||||
 | 
					                    )
 | 
				
			||||||
 | 
					                    customer = StripeCustomer.create_stripe_api_customer(
 | 
				
			||||||
 | 
					                        email=user_email,
 | 
				
			||||||
 | 
					                        token=token,
 | 
				
			||||||
 | 
					                        customer_name=user_name)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            request.session['billing_address_data'] = form.cleaned_data
 | 
					            request.session['billing_address_data'] = form.cleaned_data
 | 
				
			||||||
            request.session['user'] = this_user
 | 
					            request.session['user'] = this_user
 | 
				
			||||||
            # Get or create stripe customer
 | 
					            # Get or create stripe customer
 | 
				
			||||||
| 
						 | 
					@ -395,8 +426,10 @@ class PaymentOrderView(FormView):
 | 
				
			||||||
                return self.render_to_response(
 | 
					                return self.render_to_response(
 | 
				
			||||||
                    self.get_context_data(form=form))
 | 
					                    self.get_context_data(form=form))
 | 
				
			||||||
            request.session['token'] = token
 | 
					            request.session['token'] = token
 | 
				
			||||||
            request.session[
 | 
					            if type(customer) is StripeCustomer:
 | 
				
			||||||
                'customer'] = customer.id if request.user.is_authenticated() else customer
 | 
					                request.session['customer'] = customer.stripe_id
 | 
				
			||||||
 | 
					            else:
 | 
				
			||||||
 | 
					                request.session['customer'] = customer
 | 
				
			||||||
            return HttpResponseRedirect(
 | 
					            return HttpResponseRedirect(
 | 
				
			||||||
                reverse('datacenterlight:order_confirmation'))
 | 
					                reverse('datacenterlight:order_confirmation'))
 | 
				
			||||||
        else:
 | 
					        else:
 | 
				
			||||||
| 
						 | 
					@ -415,14 +448,7 @@ class OrderConfirmationView(DetailView):
 | 
				
			||||||
            return HttpResponseRedirect(reverse('datacenterlight:index'))
 | 
					            return HttpResponseRedirect(reverse('datacenterlight:index'))
 | 
				
			||||||
        if 'token' not in request.session:
 | 
					        if 'token' not in request.session:
 | 
				
			||||||
            return HttpResponseRedirect(reverse('datacenterlight:payment'))
 | 
					            return HttpResponseRedirect(reverse('datacenterlight:payment'))
 | 
				
			||||||
        stripe_customer_id = request.session.get('customer')
 | 
					        stripe_api_cus_id = request.session.get('customer')
 | 
				
			||||||
        if request.user.is_authenticated():
 | 
					 | 
				
			||||||
            customer = StripeCustomer.objects.filter(
 | 
					 | 
				
			||||||
                id=stripe_customer_id).first()
 | 
					 | 
				
			||||||
            stripe_api_cus_id = customer.stripe_id
 | 
					 | 
				
			||||||
        else:
 | 
					 | 
				
			||||||
            stripe_api_cus_id = stripe_customer_id
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        stripe_utils = StripeUtils()
 | 
					        stripe_utils = StripeUtils()
 | 
				
			||||||
        card_details = stripe_utils.get_card_details(stripe_api_cus_id,
 | 
					        card_details = stripe_utils.get_card_details(stripe_api_cus_id,
 | 
				
			||||||
                                                     request.session.get(
 | 
					                                                     request.session.get(
 | 
				
			||||||
| 
						 | 
					@ -437,6 +463,8 @@ class OrderConfirmationView(DetailView):
 | 
				
			||||||
            'site_url': reverse('datacenterlight:index'),
 | 
					            'site_url': reverse('datacenterlight:index'),
 | 
				
			||||||
            'cc_last4': card_details.get('response_object').get('last4'),
 | 
					            'cc_last4': card_details.get('response_object').get('last4'),
 | 
				
			||||||
            'cc_brand': card_details.get('response_object').get('brand'),
 | 
					            'cc_brand': card_details.get('response_object').get('brand'),
 | 
				
			||||||
 | 
					            'vm': request.session.get('specs'),
 | 
				
			||||||
 | 
					            'page_header_text': _('Confirm Order'),
 | 
				
			||||||
            'billing_address_data': request.session.get('billing_address_data')
 | 
					            'billing_address_data': request.session.get('billing_address_data')
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        return render(request, self.template_name, context)
 | 
					        return render(request, self.template_name, context)
 | 
				
			||||||
| 
						 | 
					@ -445,15 +473,8 @@ class OrderConfirmationView(DetailView):
 | 
				
			||||||
        template = request.session.get('template')
 | 
					        template = request.session.get('template')
 | 
				
			||||||
        specs = request.session.get('specs')
 | 
					        specs = request.session.get('specs')
 | 
				
			||||||
        user = request.session.get('user')
 | 
					        user = request.session.get('user')
 | 
				
			||||||
        stripe_customer_id = request.session.get('customer')
 | 
					        stripe_api_cus_id = request.session.get('customer')
 | 
				
			||||||
        if request.user.is_authenticated():
 | 
					 | 
				
			||||||
            customer = StripeCustomer.objects.filter(
 | 
					 | 
				
			||||||
                id=stripe_customer_id).first()
 | 
					 | 
				
			||||||
            stripe_api_cus_id = customer.stripe_id
 | 
					 | 
				
			||||||
        else:
 | 
					 | 
				
			||||||
            stripe_api_cus_id = stripe_customer_id
 | 
					 | 
				
			||||||
        vm_template_id = template.get('id', 1)
 | 
					        vm_template_id = template.get('id', 1)
 | 
				
			||||||
 | 
					 | 
				
			||||||
        stripe_utils = StripeUtils()
 | 
					        stripe_utils = StripeUtils()
 | 
				
			||||||
        card_details = stripe_utils.get_card_details(stripe_api_cus_id,
 | 
					        card_details = stripe_utils.get_card_details(stripe_api_cus_id,
 | 
				
			||||||
                                                     request.session.get(
 | 
					                                                     request.session.get(
 | 
				
			||||||
| 
						 | 
					@ -498,8 +519,8 @@ class OrderConfirmationView(DetailView):
 | 
				
			||||||
                'response_object').stripe_plan_id}])
 | 
					                'response_object').stripe_plan_id}])
 | 
				
			||||||
        stripe_subscription_obj = subscription_result.get('response_object')
 | 
					        stripe_subscription_obj = subscription_result.get('response_object')
 | 
				
			||||||
        # Check if the subscription was approved and is active
 | 
					        # Check if the subscription was approved and is active
 | 
				
			||||||
        if stripe_subscription_obj is None or \
 | 
					        if (stripe_subscription_obj is None
 | 
				
			||||||
                stripe_subscription_obj.status != 'active':
 | 
					                or stripe_subscription_obj.status != 'active'):
 | 
				
			||||||
            msg = subscription_result.get('error')
 | 
					            msg = subscription_result.get('error')
 | 
				
			||||||
            messages.add_message(self.request, messages.ERROR, msg,
 | 
					            messages.add_message(self.request, messages.ERROR, msg,
 | 
				
			||||||
                                 extra_tags='failed_payment')
 | 
					                                 extra_tags='failed_payment')
 | 
				
			||||||
| 
						 | 
					@ -546,10 +567,10 @@ class OrderConfirmationView(DetailView):
 | 
				
			||||||
                                        password=password)
 | 
					                                        password=password)
 | 
				
			||||||
                login(request, new_user)
 | 
					                login(request, new_user)
 | 
				
			||||||
        else:
 | 
					        else:
 | 
				
			||||||
            customer = StripeCustomer.objects.filter(
 | 
					            # We assume that if the user is here, his/her StripeCustomer
 | 
				
			||||||
                id=stripe_customer_id).first()
 | 
					            # object already exists
 | 
				
			||||||
            custom_user = customer.user
 | 
					            stripe_customer_id = request.user.stripecustomer.id
 | 
				
			||||||
            stripe_customer_id = customer.id
 | 
					            custom_user = request.user
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # Save billing address
 | 
					        # Save billing address
 | 
				
			||||||
        billing_address_data = request.session.get('billing_address_data')
 | 
					        billing_address_data = request.session.get('billing_address_data')
 | 
				
			||||||
| 
						 | 
					@ -557,12 +578,6 @@ class OrderConfirmationView(DetailView):
 | 
				
			||||||
        billing_address_data.update({
 | 
					        billing_address_data.update({
 | 
				
			||||||
            'user': custom_user.id
 | 
					            'user': custom_user.id
 | 
				
			||||||
        })
 | 
					        })
 | 
				
			||||||
        billing_address_user_form = UserBillingAddressForm(
 | 
					 | 
				
			||||||
            instance=custom_user.billing_addresses.first(),
 | 
					 | 
				
			||||||
            data=billing_address_data)
 | 
					 | 
				
			||||||
        billing_address = billing_address_user_form.save()
 | 
					 | 
				
			||||||
        billing_address_id = billing_address.id
 | 
					 | 
				
			||||||
        logger.debug("billing address id = {}".format(billing_address_id))
 | 
					 | 
				
			||||||
        user = {
 | 
					        user = {
 | 
				
			||||||
            'name': custom_user.name,
 | 
					            'name': custom_user.name,
 | 
				
			||||||
            'email': custom_user.email,
 | 
					            'email': custom_user.email,
 | 
				
			||||||
| 
						 | 
					@ -574,8 +589,7 @@ class OrderConfirmationView(DetailView):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        create_vm_task.delay(vm_template_id, user, specs, template,
 | 
					        create_vm_task.delay(vm_template_id, user, specs, template,
 | 
				
			||||||
                             stripe_customer_id, billing_address_data,
 | 
					                             stripe_customer_id, billing_address_data,
 | 
				
			||||||
                             billing_address_id,
 | 
					                             stripe_subscription_obj.id, card_details_dict)
 | 
				
			||||||
                             stripe_subscription_obj, card_details_dict)
 | 
					 | 
				
			||||||
        for session_var in ['specs', 'template', 'billing_address',
 | 
					        for session_var in ['specs', 'template', 'billing_address',
 | 
				
			||||||
                            'billing_address_data',
 | 
					                            'billing_address_data',
 | 
				
			||||||
                            'token', 'customer']:
 | 
					                            'token', 'customer']:
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -161,6 +161,8 @@ MIDDLEWARE_CLASSES = (
 | 
				
			||||||
    'cms.middleware.language.LanguageCookieMiddleware',
 | 
					    'cms.middleware.language.LanguageCookieMiddleware',
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					CSRF_FAILURE_VIEW = 'hosting.views.forbidden_view'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
ROOT_URLCONF = 'dynamicweb.urls'
 | 
					ROOT_URLCONF = 'dynamicweb.urls'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
TEMPLATES = [
 | 
					TEMPLATES = [
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -8,7 +8,7 @@ msgid ""
 | 
				
			||||||
msgstr ""
 | 
					msgstr ""
 | 
				
			||||||
"Project-Id-Version: PACKAGE VERSION\n"
 | 
					"Project-Id-Version: PACKAGE VERSION\n"
 | 
				
			||||||
"Report-Msgid-Bugs-To: \n"
 | 
					"Report-Msgid-Bugs-To: \n"
 | 
				
			||||||
"POT-Creation-Date: 2017-09-24 12:34+0000\n"
 | 
					"POT-Creation-Date: 2017-10-01 22:12+0000\n"
 | 
				
			||||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
 | 
					"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
 | 
				
			||||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
 | 
					"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
 | 
				
			||||||
"Language-Team: LANGUAGE <LL@li.org>\n"
 | 
					"Language-Team: LANGUAGE <LL@li.org>\n"
 | 
				
			||||||
| 
						 | 
					@ -331,12 +331,15 @@ msgstr "Alle Benachrichtigungen"
 | 
				
			||||||
msgid "%(page_header_text)s"
 | 
					msgid "%(page_header_text)s"
 | 
				
			||||||
msgstr ""
 | 
					msgstr ""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
msgid "Invoice Date"
 | 
					msgid "Date"
 | 
				
			||||||
msgstr "Rechnung Datum"
 | 
					msgstr "Datum"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
msgid "Status"
 | 
					msgid "Status"
 | 
				
			||||||
msgstr ""
 | 
					msgstr ""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					msgid "Terminated"
 | 
				
			||||||
 | 
					msgstr "Beendet"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
msgid "Approved"
 | 
					msgid "Approved"
 | 
				
			||||||
msgstr "Akzeptiert"
 | 
					msgstr "Akzeptiert"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -352,12 +355,18 @@ msgstr "Bezahlmethode"
 | 
				
			||||||
msgid "ending in"
 | 
					msgid "ending in"
 | 
				
			||||||
msgstr "endend in"
 | 
					msgstr "endend in"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					msgid "Credit Card"
 | 
				
			||||||
 | 
					msgstr "Kreditkarte"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
msgid "Order summary"
 | 
					msgid "Order summary"
 | 
				
			||||||
msgstr "Bestellungsübersicht"
 | 
					msgstr "Bestellungsübersicht"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
msgid "Product"
 | 
					msgid "Product"
 | 
				
			||||||
msgstr "Produkt"
 | 
					msgstr "Produkt"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					msgid "Period"
 | 
				
			||||||
 | 
					msgstr "Periode"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
msgid "Cores"
 | 
					msgid "Cores"
 | 
				
			||||||
msgstr "Prozessorkerne"
 | 
					msgstr "Prozessorkerne"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -390,15 +399,18 @@ msgstr "Abarbeitung..."
 | 
				
			||||||
msgid "Hold tight, we are processing your request"
 | 
					msgid "Hold tight, we are processing your request"
 | 
				
			||||||
msgstr "Bitte warten - wir bearbeiten Deine Anfrage gerade"
 | 
					msgstr "Bitte warten - wir bearbeiten Deine Anfrage gerade"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					msgid "OK"
 | 
				
			||||||
 | 
					msgstr ""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					msgid "Close"
 | 
				
			||||||
 | 
					msgstr "Schliessen"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
msgid "Some problem encountered. Please try again later."
 | 
					msgid "Some problem encountered. Please try again later."
 | 
				
			||||||
msgstr "Ein Problem ist aufgetreten. Bitte versuche es später noch einmal."
 | 
					msgstr "Ein Problem ist aufgetreten. Bitte versuche es später noch einmal."
 | 
				
			||||||
 | 
					
 | 
				
			||||||
msgid "Order Nr."
 | 
					msgid "Order Nr."
 | 
				
			||||||
msgstr "Bestellung Nr."
 | 
					msgstr "Bestellung Nr."
 | 
				
			||||||
 | 
					
 | 
				
			||||||
msgid "Date"
 | 
					 | 
				
			||||||
msgstr "Datum"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
msgid "Amount"
 | 
					msgid "Amount"
 | 
				
			||||||
msgstr "Betrag"
 | 
					msgstr "Betrag"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -423,9 +435,6 @@ msgstr "inkl. Mehrwertsteuer"
 | 
				
			||||||
msgid "Billing Address"
 | 
					msgid "Billing Address"
 | 
				
			||||||
msgstr "Rechnungsadresse"
 | 
					msgstr "Rechnungsadresse"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
msgid "Credit Card"
 | 
					 | 
				
			||||||
msgstr "Kreditkarte"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
msgid ""
 | 
					msgid ""
 | 
				
			||||||
"\n"
 | 
					"\n"
 | 
				
			||||||
"                                Please fill in your credit card information "
 | 
					"                                Please fill in your credit card information "
 | 
				
			||||||
| 
						 | 
					@ -599,16 +608,13 @@ msgstr "Deine Virtuelle Maschine beenden"
 | 
				
			||||||
msgid "Do you want to cancel your Virtual Machine"
 | 
					msgid "Do you want to cancel your Virtual Machine"
 | 
				
			||||||
msgstr "Bist Du sicher, dass Du Deine virtuelle Maschine beenden willst"
 | 
					msgstr "Bist Du sicher, dass Du Deine virtuelle Maschine beenden willst"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
msgid "OK"
 | 
					 | 
				
			||||||
msgstr ""
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#, python-format
 | 
					#, python-format
 | 
				
			||||||
msgid ""
 | 
					msgid ""
 | 
				
			||||||
"Your Virtual Machine <strong>%(machine_name)s</strong> is successfully "
 | 
					"Your Virtual Machine <strong>%(machine_name)s</strong> is successfully "
 | 
				
			||||||
"terminated!"
 | 
					"terminated!"
 | 
				
			||||||
msgstr ""
 | 
					msgstr ""
 | 
				
			||||||
"Deine Virtuelle Machine (VM) <strong>%(machine_name)s</strong> wurde erfolgreich "
 | 
					"Deine Virtuelle Machine (VM) <strong>%(machine_name)s</strong> wurde "
 | 
				
			||||||
"beendet!"
 | 
					"erfolgreich beendet!"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
msgid "Virtual Machines"
 | 
					msgid "Virtual Machines"
 | 
				
			||||||
msgstr "Virtuelle Maschinen"
 | 
					msgstr "Virtuelle Maschinen"
 | 
				
			||||||
| 
						 | 
					@ -616,6 +622,13 @@ msgstr "Virtuelle Maschinen"
 | 
				
			||||||
msgid "To create a new virtual machine, click \"Create VM\""
 | 
					msgid "To create a new virtual machine, click \"Create VM\""
 | 
				
			||||||
msgstr "Um eine neue VM zu erzeugen, klicke \"Neue VM erzeugen\""
 | 
					msgstr "Um eine neue VM zu erzeugen, klicke \"Neue VM erzeugen\""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#, python-format
 | 
				
			||||||
 | 
					msgid ""
 | 
				
			||||||
 | 
					"To access your VM, <a href=\"%(create_ssh_url)s\">add your SSH key here</a>"
 | 
				
			||||||
 | 
					msgstr ""
 | 
				
			||||||
 | 
					"Um auf Deine VM zuzugreifen, <a href=\"%(create_ssh_url)s\">füge Deinen SSH-"
 | 
				
			||||||
 | 
					"Key hinzu</a>"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
msgid "CREATE VM"
 | 
					msgid "CREATE VM"
 | 
				
			||||||
msgstr "NEUE VM"
 | 
					msgstr "NEUE VM"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -673,6 +686,16 @@ msgid "In order to create a VM, you need to create/upload your SSH KEY first."
 | 
				
			||||||
msgstr ""
 | 
					msgstr ""
 | 
				
			||||||
"Um eine VM zu erstellen musst du zuerst einen SSH-Key erstellen / hochladen."
 | 
					"Um eine VM zu erstellen musst du zuerst einen SSH-Key erstellen / hochladen."
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					msgid "Error."
 | 
				
			||||||
 | 
					msgstr "Fehler"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					msgid ""
 | 
				
			||||||
 | 
					"There was a payment related error. On close of this popup, you will be "
 | 
				
			||||||
 | 
					"redirected back to the payment page."
 | 
				
			||||||
 | 
					msgstr ""
 | 
				
			||||||
 | 
					"Es ist ein Fehler bei der Zahlung betreten. Du wirst nach dem Schliessen vom "
 | 
				
			||||||
 | 
					"Popup zur Bezahlseite weitergeleitet"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
msgid "Thank you for the order."
 | 
					msgid "Thank you for the order."
 | 
				
			||||||
msgstr "Danke für Deine Bestellung."
 | 
					msgstr "Danke für Deine Bestellung."
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -697,8 +720,11 @@ msgid ""
 | 
				
			||||||
"contact Data Center Light Support."
 | 
					"contact Data Center Light Support."
 | 
				
			||||||
msgstr "Kontaktiere den Data Center Light Support."
 | 
					msgstr "Kontaktiere den Data Center Light Support."
 | 
				
			||||||
 | 
					
 | 
				
			||||||
msgid "Terminated"
 | 
					msgid ""
 | 
				
			||||||
msgstr "Beendet"
 | 
					"We could not find the requested VM. Please contact Data Center Light Support."
 | 
				
			||||||
 | 
					msgstr ""
 | 
				
			||||||
 | 
					"Wir konnten die gesucht VM nicht finden. Kontaktiere den Data Center Light "
 | 
				
			||||||
 | 
					"Support."
 | 
				
			||||||
 | 
					
 | 
				
			||||||
msgid "Error terminating VM"
 | 
					msgid "Error terminating VM"
 | 
				
			||||||
msgstr "Fehler beenden VM"
 | 
					msgstr "Fehler beenden VM"
 | 
				
			||||||
| 
						 | 
					@ -706,8 +732,13 @@ msgstr "Fehler beenden VM"
 | 
				
			||||||
msgid "Virtual Machine Cancellation"
 | 
					msgid "Virtual Machine Cancellation"
 | 
				
			||||||
msgstr "VM Kündigung"
 | 
					msgstr "VM Kündigung"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#~ msgid "Close"
 | 
					msgid "There was an error processing your request. Please try again."
 | 
				
			||||||
#~ msgstr "Schliessen"
 | 
					msgstr ""
 | 
				
			||||||
 | 
					"Es gab einen Fehler bei der Bearbeitung Deine Anfrage. Bitte versuche es "
 | 
				
			||||||
 | 
					"noch einmal."
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#~ msgid "Invoice Date"
 | 
				
			||||||
 | 
					#~ msgstr "Rechnung Datum"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#~ msgid "VM %(VM_ID)s terminated successfully"
 | 
					#~ msgid "VM %(VM_ID)s terminated successfully"
 | 
				
			||||||
#~ msgstr "VM %(VM_ID)s erfolgreich beendet"
 | 
					#~ msgstr "VM %(VM_ID)s erfolgreich beendet"
 | 
				
			||||||
| 
						 | 
					@ -842,5 +873,5 @@ msgstr "VM Kündigung"
 | 
				
			||||||
#~ "Your SSH private key was already generated and downloaded, if you lost "
 | 
					#~ "Your SSH private key was already generated and downloaded, if you lost "
 | 
				
			||||||
#~ "it, contact us. "
 | 
					#~ "it, contact us. "
 | 
				
			||||||
#~ msgstr ""
 | 
					#~ msgstr ""
 | 
				
			||||||
#~ "Dein privater SSH Key wurde bereits generiert und heruntergeladen. "
 | 
					#~ "Dein privater SSH Key wurde bereits generiert und heruntergeladen. Falls "
 | 
				
			||||||
#~ "Falls Du ihn verloren hast, kontaktiere uns."
 | 
					#~ "Du ihn verloren hast, kontaktiere uns."
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -90,19 +90,19 @@ class HostingOrder(AssignPermissionsMixin, models.Model):
 | 
				
			||||||
        self.cc_brand = stripe_charge.source.brand
 | 
					        self.cc_brand = stripe_charge.source.brand
 | 
				
			||||||
        self.save()
 | 
					        self.save()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def set_subscription_id(self, subscription_object, cc_details):
 | 
					    def set_subscription_id(self, subscription_id, cc_details):
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
        When creating a Stripe subscription, we have subscription id.
 | 
					        When creating a Stripe subscription, we have subscription id.
 | 
				
			||||||
        We store this in the subscription_id field.
 | 
					        We store this in the subscription_id field.
 | 
				
			||||||
        This method sets the subscription id from subscription_object
 | 
					        This method sets the subscription id
 | 
				
			||||||
        and also the last4 and credit card brands used for this order.
 | 
					        and the last4 and credit card brands used for this order.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        :param subscription_object: Stripe's subscription object
 | 
					        :param subscription_id: Stripe's subscription id
 | 
				
			||||||
        :param cc_details: A dict containing card details
 | 
					        :param cc_details: A dict containing card details
 | 
				
			||||||
        {last4, brand}
 | 
					        {last4, brand}
 | 
				
			||||||
        :return:
 | 
					        :return:
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
        self.subscription_id = subscription_object.id
 | 
					        self.subscription_id = subscription_id
 | 
				
			||||||
        self.last4 = cc_details.get('last4')
 | 
					        self.last4 = cc_details.get('last4')
 | 
				
			||||||
        self.cc_brand = cc_details.get('brand')
 | 
					        self.cc_brand = cc_details.get('brand')
 | 
				
			||||||
        self.save()
 | 
					        self.save()
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -86,23 +86,31 @@ $(document).ready(function() {
 | 
				
			||||||
            url: create_vm_form.attr('action'),
 | 
					            url: create_vm_form.attr('action'),
 | 
				
			||||||
            type: 'POST',
 | 
					            type: 'POST',
 | 
				
			||||||
            data: create_vm_form.serialize(),
 | 
					            data: create_vm_form.serialize(),
 | 
				
			||||||
 | 
					            init: function(){
 | 
				
			||||||
 | 
					                ok_btn = $('#createvm-modal-done-btn');
 | 
				
			||||||
 | 
					                close_btn = $('#createvm-modal-close-btn');
 | 
				
			||||||
 | 
					                ok_btn.addClass('btn btn-success btn-ok btn-wide hide');
 | 
				
			||||||
 | 
					                close_btn.addClass('btn btn-danger btn-ok btn-wide hide');
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
            success: function (data) {
 | 
					            success: function (data) {
 | 
				
			||||||
                if (data.status === true) {
 | 
					 | 
				
			||||||
                fa_icon = $('.modal-icon > .fa');
 | 
					                fa_icon = $('.modal-icon > .fa');
 | 
				
			||||||
                    fa_icon.attr('class', 'checkmark');
 | 
					                modal_btn = $('#createvm-modal-done-btn');
 | 
				
			||||||
                    // $('.modal-header > .close').removeClass('hidden');
 | 
					 | 
				
			||||||
                $('#createvm-modal-title').text(data.msg_title);
 | 
					                $('#createvm-modal-title').text(data.msg_title);
 | 
				
			||||||
                    $('#createvm-modal-body').text(data.msg_body);
 | 
					                $('#createvm-modal-body').html(data.msg_body);
 | 
				
			||||||
                    $('#createvm-modal-done-btn')
 | 
					                modal_btn.attr('href', data.redirect)
 | 
				
			||||||
                        .attr('href', data.redirect)
 | 
					 | 
				
			||||||
                    .removeClass('hide');
 | 
					                    .removeClass('hide');
 | 
				
			||||||
 | 
					                if (data.status === true) {
 | 
				
			||||||
 | 
					                    fa_icon.attr('class', 'checkmark');
 | 
				
			||||||
 | 
					                } else {
 | 
				
			||||||
 | 
					                    fa_icon.attr('class', 'fa fa-close');
 | 
				
			||||||
 | 
					                    modal_btn.attr('class', '').addClass('btn btn-danger btn-ok btn-wide');
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
            },
 | 
					            },
 | 
				
			||||||
            error: function (xmlhttprequest, textstatus, message) {
 | 
					            error: function (xmlhttprequest, textstatus, message) {
 | 
				
			||||||
                    fa_icon = $('.modal-icon > .fa');
 | 
					                    fa_icon = $('.modal-icon > .fa');
 | 
				
			||||||
                    fa_icon.attr('class', 'fa fa-close');
 | 
					                    fa_icon.attr('class', 'fa fa-close');
 | 
				
			||||||
                    if (typeof(create_vm_error_message) !== 'undefined') {
 | 
					                    if (typeof(create_vm_error_message) !== 'undefined') {
 | 
				
			||||||
                        $('#createvm-modal-text').text(create_vm_error_message);
 | 
					                        $('#createvm-modal-body').text(create_vm_error_message);
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
                    $('#btn-create-vm').prop('disabled', false);
 | 
					                    $('#btn-create-vm').prop('disabled', false);
 | 
				
			||||||
                    $('#createvm-modal-close-btn').removeClass('hide');
 | 
					                    $('#createvm-modal-close-btn').removeClass('hide');
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										8
									
								
								hosting/templates/hosting/includes/_messages.html
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								hosting/templates/hosting/includes/_messages.html
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,8 @@
 | 
				
			||||||
 | 
					{% if messages %}
 | 
				
			||||||
 | 
					    <ul class="list-unstyled msg-list">
 | 
				
			||||||
 | 
					    {% for message in messages %}
 | 
				
			||||||
 | 
					        <div
 | 
				
			||||||
 | 
					                class="alert {% if message.tags and message.tags == 'error' %} alert-danger {% else %} alert-{{message.tags}} {% endif %}">{{ message|safe }}</div>
 | 
				
			||||||
 | 
					    {% endfor %}
 | 
				
			||||||
 | 
					    </ul>
 | 
				
			||||||
 | 
					{% endif %}
 | 
				
			||||||
| 
						 | 
					@ -16,13 +16,7 @@
 | 
				
			||||||
        <div class="auth-content">
 | 
					        <div class="auth-content">
 | 
				
			||||||
            <div class="intro-message auth-box">
 | 
					            <div class="intro-message auth-box">
 | 
				
			||||||
                <h2 class="section-heading">{% trans "Login"%}</h2>
 | 
					                <h2 class="section-heading">{% trans "Login"%}</h2>
 | 
				
			||||||
                {% if messages %}
 | 
					                {% include  'hosting/includes/_messages.html' %}
 | 
				
			||||||
                    <ul class="list-unstyled msg-list">
 | 
					 | 
				
			||||||
                    {% for message in messages %}
 | 
					 | 
				
			||||||
                        <li>{{ message }}</li>
 | 
					 | 
				
			||||||
                    {% endfor %}
 | 
					 | 
				
			||||||
                    </ul>
 | 
					 | 
				
			||||||
                {% endif %}
 | 
					 | 
				
			||||||
                <form action="{% url 'hosting:login' %}" method="post" class="form" novalidated>
 | 
					                <form action="{% url 'hosting:login' %}" method="post" class="form" novalidated>
 | 
				
			||||||
                    {% csrf_token %}
 | 
					                    {% csrf_token %}
 | 
				
			||||||
                    {% for field in form %}
 | 
					                    {% for field in form %}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -17,10 +17,12 @@
 | 
				
			||||||
            <h1 class="dashboard-title-thin">
 | 
					            <h1 class="dashboard-title-thin">
 | 
				
			||||||
                <img src="{% static 'hosting/img/billing.svg' %}" class="un-icon">{% blocktrans with page_header_text=page_header_text|default:"Invoice" %}{{page_header_text}}{% endblocktrans %}
 | 
					                <img src="{% static 'hosting/img/billing.svg' %}" class="un-icon">{% blocktrans with page_header_text=page_header_text|default:"Invoice" %}{{page_header_text}}{% endblocktrans %}
 | 
				
			||||||
            </h1>
 | 
					            </h1>
 | 
				
			||||||
 | 
					            {% if order %}
 | 
				
			||||||
                <div class="dashboard-container-options">
 | 
					                <div class="dashboard-container-options">
 | 
				
			||||||
                    <button type="button" class="btn-plain btn-pdf" data-target="#order-detail{{order.pk}}"><img src="{% static 'hosting/img/icon-pdf.svg' %}" class="svg-img"></button>
 | 
					                    <button type="button" class="btn-plain btn-pdf" data-target="#order-detail{{order.pk}}"><img src="{% static 'hosting/img/icon-pdf.svg' %}" class="svg-img"></button>
 | 
				
			||||||
                    <button type="button" class="btn-plain btn-print"><img src="{% static 'hosting/img/icon-print.svg' %}" class="svg-img"></button>
 | 
					                    <button type="button" class="btn-plain btn-print"><img src="{% static 'hosting/img/icon-print.svg' %}" class="svg-img"></button>
 | 
				
			||||||
                </div>
 | 
					                </div>
 | 
				
			||||||
 | 
					            {% endif %}
 | 
				
			||||||
        </div>
 | 
					        </div>
 | 
				
			||||||
        <div class="order-details">
 | 
					        <div class="order-details">
 | 
				
			||||||
            {% if order %}
 | 
					            {% if order %}
 | 
				
			||||||
| 
						 | 
					@ -29,7 +31,7 @@
 | 
				
			||||||
                </p>
 | 
					                </p>
 | 
				
			||||||
            {% endif %}
 | 
					            {% endif %}
 | 
				
			||||||
            <p>
 | 
					            <p>
 | 
				
			||||||
                <strong>{% trans "Invoice Date" %}:</strong>
 | 
					                <strong>{% trans "Date" %}:</strong>
 | 
				
			||||||
                <span id="order-created_at">
 | 
					                <span id="order-created_at">
 | 
				
			||||||
                    {% if order %}
 | 
					                    {% if order %}
 | 
				
			||||||
                        {{order.created_at|date:'Y-m-d H:i'}}
 | 
					                        {{order.created_at|date:'Y-m-d H:i'}}
 | 
				
			||||||
| 
						 | 
					@ -80,8 +82,7 @@
 | 
				
			||||||
                        {{order.last4}}<br>
 | 
					                        {{order.last4}}<br>
 | 
				
			||||||
                        {{user.email}}
 | 
					                        {{user.email}}
 | 
				
			||||||
                    {% else %}
 | 
					                    {% else %}
 | 
				
			||||||
                        {{cc_brand|default:'Card'}} {% trans "ending in" %} ****
 | 
					                        {{cc_brand|default:_('Credit Card')}} {% trans "ending in" %} ****{{cc_last4}}<br>
 | 
				
			||||||
                        {{cc_last4}}<br>
 | 
					 | 
				
			||||||
                        {% if request.user.is_authenticated %}
 | 
					                        {% if request.user.is_authenticated %}
 | 
				
			||||||
                            {{request.user.email}}
 | 
					                            {{request.user.email}}
 | 
				
			||||||
                        {% else %}
 | 
					                        {% else %}
 | 
				
			||||||
| 
						 | 
					@ -94,7 +95,12 @@
 | 
				
			||||||
            <div>
 | 
					            <div>
 | 
				
			||||||
                <h4>{% trans "Order summary" %}</h4>
 | 
					                <h4>{% trans "Order summary" %}</h4>
 | 
				
			||||||
                <p>
 | 
					                <p>
 | 
				
			||||||
                    <strong>{% trans "Product" %}:</strong> {{vm.name}}
 | 
					                    <strong>{% trans "Product" %}:</strong> 
 | 
				
			||||||
 | 
					                    {% if vm.name %}
 | 
				
			||||||
 | 
					                        {{ vm.name }}
 | 
				
			||||||
 | 
					                    {% else %}
 | 
				
			||||||
 | 
					                        {{ request.session.template.name }}
 | 
				
			||||||
 | 
					                    {% endif %}
 | 
				
			||||||
                </p>
 | 
					                </p>
 | 
				
			||||||
                <div class="row">
 | 
					                <div class="row">
 | 
				
			||||||
                    <div class="col-sm-6">
 | 
					                    <div class="col-sm-6">
 | 
				
			||||||
| 
						 | 
					@ -132,6 +138,7 @@
 | 
				
			||||||
            {% endif %}
 | 
					            {% endif %}
 | 
				
			||||||
        </div>
 | 
					        </div>
 | 
				
			||||||
        {% if not order %}
 | 
					        {% if not order %}
 | 
				
			||||||
 | 
					            {% block submit_btn %}
 | 
				
			||||||
                <form method="post" id="virtual_machine_create_form">
 | 
					                <form method="post" id="virtual_machine_create_form">
 | 
				
			||||||
                    {% csrf_token %}
 | 
					                    {% csrf_token %}
 | 
				
			||||||
                    <div class="row">
 | 
					                    <div class="row">
 | 
				
			||||||
| 
						 | 
					@ -145,6 +152,7 @@
 | 
				
			||||||
                        </div>
 | 
					                        </div>
 | 
				
			||||||
                    </div>
 | 
					                    </div>
 | 
				
			||||||
                </form>
 | 
					                </form>
 | 
				
			||||||
 | 
					            {% endblock submit_btn %}
 | 
				
			||||||
        {% endif %}
 | 
					        {% endif %}
 | 
				
			||||||
    {% endif %}
 | 
					    {% endif %}
 | 
				
			||||||
</div>
 | 
					</div>
 | 
				
			||||||
| 
						 | 
					@ -197,8 +205,10 @@
 | 
				
			||||||
{%endblock%}
 | 
					{%endblock%}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
{% block js_extra %}
 | 
					{% block js_extra %}
 | 
				
			||||||
 | 
					    {% if order %}
 | 
				
			||||||
        <script src="https://cdnjs.cloudflare.com/ajax/libs/jspdf/1.3.5/jspdf.min.js"></script>
 | 
					        <script src="https://cdnjs.cloudflare.com/ajax/libs/jspdf/1.3.5/jspdf.min.js"></script>
 | 
				
			||||||
        <script src="https://cdnjs.cloudflare.com/ajax/libs/html2canvas/0.4.1/html2canvas.min.js"></script>
 | 
					        <script src="https://cdnjs.cloudflare.com/ajax/libs/html2canvas/0.4.1/html2canvas.min.js"></script>
 | 
				
			||||||
        <script src="{% static 'hosting/js/html2pdf.js' %}"></script>
 | 
					        <script src="{% static 'hosting/js/html2pdf.js' %}"></script>
 | 
				
			||||||
        <script src="{% static 'hosting/js/order.js' %}"></script>
 | 
					        <script src="{% static 'hosting/js/order.js' %}"></script>
 | 
				
			||||||
 | 
					    {% endif %}
 | 
				
			||||||
{% endblock js_extra %}
 | 
					{% endblock js_extra %}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -17,6 +17,7 @@
 | 
				
			||||||
            <div class="auth-content">
 | 
					            <div class="auth-content">
 | 
				
			||||||
                <div class="intro-message auth-box sign-up">
 | 
					                <div class="intro-message auth-box sign-up">
 | 
				
			||||||
                    <h2  class="section-heading">{% trans "Resend activation link"%}</h2>
 | 
					                    <h2  class="section-heading">{% trans "Resend activation link"%}</h2>
 | 
				
			||||||
 | 
					                    {% include  'hosting/includes/_messages.html' %}
 | 
				
			||||||
                    <form action="{% url 'hosting:resend_activation_link' %}" method="post" class="form" novalidate>
 | 
					                    <form action="{% url 'hosting:resend_activation_link' %}" method="post" class="form" novalidate>
 | 
				
			||||||
                        {% csrf_token %}
 | 
					                        {% csrf_token %}
 | 
				
			||||||
                        {% for field in form %}
 | 
					                        {% for field in form %}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -17,6 +17,7 @@
 | 
				
			||||||
            <div class="auth-content">
 | 
					            <div class="auth-content">
 | 
				
			||||||
                <div class="intro-message auth-box sign-up">
 | 
					                <div class="intro-message auth-box sign-up">
 | 
				
			||||||
                    <h2  class="section-heading">{% trans "Reset your password"%}</h2>
 | 
					                    <h2  class="section-heading">{% trans "Reset your password"%}</h2>
 | 
				
			||||||
 | 
					                    {% include  'hosting/includes/_messages.html' %}
 | 
				
			||||||
                    <form action="{% url 'hosting:reset_password' %}" method="post" class="form" novalidate>
 | 
					                    <form action="{% url 'hosting:reset_password' %}" method="post" class="form" novalidate>
 | 
				
			||||||
                        {% csrf_token %}
 | 
					                        {% csrf_token %}
 | 
				
			||||||
                        {% for field in form %}
 | 
					                        {% for field in form %}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -15,6 +15,7 @@
 | 
				
			||||||
        <div class="auth-content">
 | 
					        <div class="auth-content">
 | 
				
			||||||
            <div class="intro-message auth-box sign-up">
 | 
					            <div class="intro-message auth-box sign-up">
 | 
				
			||||||
                <h2  class="section-heading">{% trans "Sign up"%}</h2>
 | 
					                <h2  class="section-heading">{% trans "Sign up"%}</h2>
 | 
				
			||||||
 | 
					                {% include  'hosting/includes/_messages.html' %}
 | 
				
			||||||
                <form action="{% url 'hosting:signup' %}" method="post" class="form" novalidate>
 | 
					                <form action="{% url 'hosting:signup' %}" method="post" class="form" novalidate>
 | 
				
			||||||
                    {% csrf_token %}
 | 
					                    {% csrf_token %}
 | 
				
			||||||
                    {% for field in form %}
 | 
					                    {% for field in form %}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -11,6 +11,7 @@
 | 
				
			||||||
    <div class="auth-center">
 | 
					    <div class="auth-center">
 | 
				
			||||||
            <div class="auth-title">
 | 
					            <div class="auth-title">
 | 
				
			||||||
                <h2>{% trans "Your VM hosted in Switzerland"%}</h2>
 | 
					                <h2>{% trans "Your VM hosted in Switzerland"%}</h2>
 | 
				
			||||||
 | 
					                {% include  'hosting/includes/_messages.html' %}
 | 
				
			||||||
            </div>
 | 
					            </div>
 | 
				
			||||||
            <div class="auth-content">
 | 
					            <div class="auth-content">
 | 
				
			||||||
                <div class="intro-message auth-box sign-up">
 | 
					                <div class="intro-message auth-box sign-up">
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -16,7 +16,7 @@
 | 
				
			||||||
                <p>{% trans 'To create a new virtual machine, click "Create VM"' %}
 | 
					                <p>{% trans 'To create a new virtual machine, click "Create VM"' %}
 | 
				
			||||||
                {% if show_create_ssh_key_msg %}
 | 
					                {% if show_create_ssh_key_msg %}
 | 
				
			||||||
                     {% url 'hosting:create_ssh_key' as create_ssh_url %}
 | 
					                     {% url 'hosting:create_ssh_key' as create_ssh_url %}
 | 
				
			||||||
                     <br/>{% blocktrans %}To access your VM, add your SSH key <a href="{{create_ssh_url}}">here</a>{% endblocktrans %}
 | 
					                     <br/>{% blocktrans %}To access your VM, <a href="{{create_ssh_url}}">add your SSH key here</a>{% endblocktrans %}
 | 
				
			||||||
                {% endif %}
 | 
					                {% endif %}
 | 
				
			||||||
                </p>
 | 
					                </p>
 | 
				
			||||||
                <div class="text-right">
 | 
					                <div class="text-right">
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -60,8 +60,9 @@ CONNECTION_ERROR = "Your VMs cannot be displayed at the moment due to a \
 | 
				
			||||||
                    minutes."
 | 
					                    minutes."
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class DashboardView(View):
 | 
					class DashboardView(LoginRequiredMixin, View):
 | 
				
			||||||
    template_name = "hosting/dashboard.html"
 | 
					    template_name = "hosting/dashboard.html"
 | 
				
			||||||
 | 
					    login_url = reverse_lazy('hosting:login')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def get_context_data(self, **kwargs):
 | 
					    def get_context_data(self, **kwargs):
 | 
				
			||||||
        context = {}
 | 
					        context = {}
 | 
				
			||||||
| 
						 | 
					@ -80,8 +81,6 @@ class DjangoHostingView(ProcessVMSelectionMixin, View):
 | 
				
			||||||
        templates = OpenNebulaManager().get_templates()
 | 
					        templates = OpenNebulaManager().get_templates()
 | 
				
			||||||
        data = VirtualMachineTemplateSerializer(templates, many=True).data
 | 
					        data = VirtualMachineTemplateSerializer(templates, many=True).data
 | 
				
			||||||
        configuration_options = HostingPlan.get_serialized_configs()
 | 
					        configuration_options = HostingPlan.get_serialized_configs()
 | 
				
			||||||
 | 
					 | 
				
			||||||
        # configuration_detail = dict(VirtualMachinePlan.VM_CONFIGURATION).get(HOSTING)
 | 
					 | 
				
			||||||
        context = {
 | 
					        context = {
 | 
				
			||||||
            'hosting': HOSTING,
 | 
					            'hosting': HOSTING,
 | 
				
			||||||
            'hosting_long': "Django",
 | 
					            'hosting_long': "Django",
 | 
				
			||||||
| 
						 | 
					@ -134,7 +133,6 @@ class NodeJSHostingView(ProcessVMSelectionMixin, View):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def get_context_data(self, **kwargs):
 | 
					    def get_context_data(self, **kwargs):
 | 
				
			||||||
        HOSTING = 'nodejs'
 | 
					        HOSTING = 'nodejs'
 | 
				
			||||||
        # configuration_detail = dict(VirtualMachinePlan.VM_CONFIGURATION).get(HOSTING)
 | 
					 | 
				
			||||||
        templates = OpenNebulaManager().get_templates()
 | 
					        templates = OpenNebulaManager().get_templates()
 | 
				
			||||||
        configuration_options = HostingPlan.get_serialized_configs()
 | 
					        configuration_options = HostingPlan.get_serialized_configs()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -249,7 +247,8 @@ class SignupValidateView(TemplateView):
 | 
				
			||||||
                 <br />{go_back} {hurl}.'.format(
 | 
					                 <br />{go_back} {hurl}.'.format(
 | 
				
			||||||
            signup_success_message=_(
 | 
					            signup_success_message=_(
 | 
				
			||||||
                'Thank you for signing up. We have sent an email to you. '
 | 
					                'Thank you for signing up. We have sent an email to you. '
 | 
				
			||||||
                'Please follow the instructions in it to activate your account. Once activated, you can login using'),
 | 
					                'Please follow the instructions in it to activate your '
 | 
				
			||||||
 | 
					                'account. Once activated, you can login using'),
 | 
				
			||||||
            go_back=_('Go back to'),
 | 
					            go_back=_('Go back to'),
 | 
				
			||||||
            lurl=login_url,
 | 
					            lurl=login_url,
 | 
				
			||||||
            hurl=home_url
 | 
					            hurl=home_url
 | 
				
			||||||
| 
						 | 
					@ -269,7 +268,8 @@ class SignupValidatedView(SignupValidateView):
 | 
				
			||||||
                    reverse('hosting:login') + '">' + str(_('login')) + '</a>'
 | 
					                    reverse('hosting:login') + '">' + str(_('login')) + '</a>'
 | 
				
			||||||
        section_title = _('Account activation')
 | 
					        section_title = _('Account activation')
 | 
				
			||||||
        if validated:
 | 
					        if validated:
 | 
				
			||||||
            message = '{account_activation_string} <br /> {login_string} {lurl}.'.format(
 | 
					            message = ('{account_activation_string} <br />'
 | 
				
			||||||
 | 
					                       ' {login_string} {lurl}.').format(
 | 
				
			||||||
                account_activation_string=_(
 | 
					                account_activation_string=_(
 | 
				
			||||||
                    "Your account has been activated."),
 | 
					                    "Your account has been activated."),
 | 
				
			||||||
                login_string=_("You can now"),
 | 
					                login_string=_("You can now"),
 | 
				
			||||||
| 
						 | 
					@ -636,10 +636,7 @@ class PaymentVMView(LoginRequiredMixin, FormView):
 | 
				
			||||||
                return HttpResponseRedirect(
 | 
					                return HttpResponseRedirect(
 | 
				
			||||||
                    reverse('hosting:payment') + '#payment_error')
 | 
					                    reverse('hosting:payment') + '#payment_error')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            # Create Billing Address
 | 
					 | 
				
			||||||
            billing_address = form.save()
 | 
					 | 
				
			||||||
            request.session['billing_address_data'] = billing_address_data
 | 
					            request.session['billing_address_data'] = billing_address_data
 | 
				
			||||||
            request.session['billing_address'] = billing_address.id
 | 
					 | 
				
			||||||
            request.session['token'] = token
 | 
					            request.session['token'] = token
 | 
				
			||||||
            request.session['customer'] = customer.id
 | 
					            request.session['customer'] = customer.id
 | 
				
			||||||
            return HttpResponseRedirect("{url}?{query_params}".format(
 | 
					            return HttpResponseRedirect("{url}?{query_params}".format(
 | 
				
			||||||
| 
						 | 
					@ -687,10 +684,12 @@ class OrdersHostingDetailView(LoginRequiredMixin,
 | 
				
			||||||
            try:
 | 
					            try:
 | 
				
			||||||
                vm_detail = VMDetail.objects.get(vm_id=obj.vm_id)
 | 
					                vm_detail = VMDetail.objects.get(vm_id=obj.vm_id)
 | 
				
			||||||
                context['vm'] = vm_detail.__dict__
 | 
					                context['vm'] = vm_detail.__dict__
 | 
				
			||||||
                context['vm']['name'] = (
 | 
					                context['vm']['name'] = '{}-{}'.format(
 | 
				
			||||||
                    '{}-{}'.format(
 | 
					                    context['vm']['configuration'], context['vm']['vm_id'])
 | 
				
			||||||
                        context['vm']['configuration'], context['vm']['vm_id']
 | 
					                context['vm']['price'] = get_vm_price(
 | 
				
			||||||
                    )
 | 
					                    cpu=context['vm']['cores'],
 | 
				
			||||||
 | 
					                    disk_size=context['vm']['disk_size'],
 | 
				
			||||||
 | 
					                    memory=context['vm']['memory']
 | 
				
			||||||
                )
 | 
					                )
 | 
				
			||||||
                context['subscription_end_date'] = vm_detail.end_date()
 | 
					                context['subscription_end_date'] = vm_detail.end_date()
 | 
				
			||||||
            except VMDetail.DoesNotExist:
 | 
					            except VMDetail.DoesNotExist:
 | 
				
			||||||
| 
						 | 
					@ -755,7 +754,6 @@ class OrdersHostingDetailView(LoginRequiredMixin,
 | 
				
			||||||
        stripe_customer_id = request.session.get('customer')
 | 
					        stripe_customer_id = request.session.get('customer')
 | 
				
			||||||
        customer = StripeCustomer.objects.filter(id=stripe_customer_id).first()
 | 
					        customer = StripeCustomer.objects.filter(id=stripe_customer_id).first()
 | 
				
			||||||
        billing_address_data = request.session.get('billing_address_data')
 | 
					        billing_address_data = request.session.get('billing_address_data')
 | 
				
			||||||
        billing_address_id = request.session.get('billing_address')
 | 
					 | 
				
			||||||
        vm_template_id = template.get('id', 1)
 | 
					        vm_template_id = template.get('id', 1)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # Make stripe charge to a customer
 | 
					        # Make stripe charge to a customer
 | 
				
			||||||
| 
						 | 
					@ -773,8 +771,7 @@ class OrdersHostingDetailView(LoginRequiredMixin,
 | 
				
			||||||
        cpu = specs.get('cpu')
 | 
					        cpu = specs.get('cpu')
 | 
				
			||||||
        memory = specs.get('memory')
 | 
					        memory = specs.get('memory')
 | 
				
			||||||
        disk_size = specs.get('disk_size')
 | 
					        disk_size = specs.get('disk_size')
 | 
				
			||||||
        amount_to_be_charged = get_vm_price(cpu=cpu, memory=memory,
 | 
					        amount_to_be_charged = specs.get('price')
 | 
				
			||||||
                                            disk_size=disk_size)
 | 
					 | 
				
			||||||
        plan_name = StripeUtils.get_stripe_plan_name(cpu=cpu,
 | 
					        plan_name = StripeUtils.get_stripe_plan_name(cpu=cpu,
 | 
				
			||||||
                                                     memory=memory,
 | 
					                                                     memory=memory,
 | 
				
			||||||
                                                     disk_size=disk_size)
 | 
					                                                     disk_size=disk_size)
 | 
				
			||||||
| 
						 | 
					@ -793,12 +790,24 @@ class OrdersHostingDetailView(LoginRequiredMixin,
 | 
				
			||||||
                'response_object').stripe_plan_id}])
 | 
					                'response_object').stripe_plan_id}])
 | 
				
			||||||
        stripe_subscription_obj = subscription_result.get('response_object')
 | 
					        stripe_subscription_obj = subscription_result.get('response_object')
 | 
				
			||||||
        # Check if the subscription was approved and is active
 | 
					        # Check if the subscription was approved and is active
 | 
				
			||||||
        if stripe_subscription_obj is None or stripe_subscription_obj.status != 'active':
 | 
					        if (stripe_subscription_obj is None or
 | 
				
			||||||
 | 
					                stripe_subscription_obj.status != 'active'):
 | 
				
			||||||
            msg = subscription_result.get('error')
 | 
					            msg = subscription_result.get('error')
 | 
				
			||||||
            messages.add_message(self.request, messages.ERROR, msg,
 | 
					            messages.add_message(self.request, messages.ERROR, msg,
 | 
				
			||||||
                                 extra_tags='failed_payment')
 | 
					                                 extra_tags='failed_payment')
 | 
				
			||||||
            return HttpResponseRedirect(
 | 
					            response = {
 | 
				
			||||||
                reverse('hosting:payment') + '#payment_error')
 | 
					                'status': False,
 | 
				
			||||||
 | 
					                'redirect': "{url}#{section}".format(
 | 
				
			||||||
 | 
					                    url=reverse('hosting:payment'),
 | 
				
			||||||
 | 
					                    section='payment_error'),
 | 
				
			||||||
 | 
					                'msg_title': str(_('Error.')),
 | 
				
			||||||
 | 
					                'msg_body': str(
 | 
				
			||||||
 | 
					                    _('There was a payment related error.'
 | 
				
			||||||
 | 
					                      ' On close of this popup, you will be redirected back to'
 | 
				
			||||||
 | 
					                      ' the payment page.'))
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            return HttpResponse(json.dumps(response),
 | 
				
			||||||
 | 
					                                content_type="application/json")
 | 
				
			||||||
        user = {
 | 
					        user = {
 | 
				
			||||||
            'name': self.request.user.name,
 | 
					            'name': self.request.user.name,
 | 
				
			||||||
            'email': self.request.user.email,
 | 
					            'email': self.request.user.email,
 | 
				
			||||||
| 
						 | 
					@ -809,8 +818,7 @@ class OrdersHostingDetailView(LoginRequiredMixin,
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        create_vm_task.delay(vm_template_id, user, specs, template,
 | 
					        create_vm_task.delay(vm_template_id, user, specs, template,
 | 
				
			||||||
                             stripe_customer_id, billing_address_data,
 | 
					                             stripe_customer_id, billing_address_data,
 | 
				
			||||||
                             billing_address_id,
 | 
					                             stripe_subscription_obj.id, card_details_dict)
 | 
				
			||||||
                             stripe_subscription_obj, card_details_dict)
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        for session_var in ['specs', 'template', 'billing_address',
 | 
					        for session_var in ['specs', 'template', 'billing_address',
 | 
				
			||||||
                            'billing_address_data',
 | 
					                            'billing_address_data',
 | 
				
			||||||
| 
						 | 
					@ -1013,6 +1021,7 @@ class VirtualMachineView(LoginRequiredMixin, View):
 | 
				
			||||||
                return redirect(reverse('hosting:virtual_machines'))
 | 
					                return redirect(reverse('hosting:virtual_machines'))
 | 
				
			||||||
        elif self.request.is_ajax():
 | 
					        elif self.request.is_ajax():
 | 
				
			||||||
            return HttpResponse()
 | 
					            return HttpResponse()
 | 
				
			||||||
 | 
					        context = None
 | 
				
			||||||
        try:
 | 
					        try:
 | 
				
			||||||
            serializer = VirtualMachineSerializer(vm)
 | 
					            serializer = VirtualMachineSerializer(vm)
 | 
				
			||||||
            context = {
 | 
					            context = {
 | 
				
			||||||
| 
						 | 
					@ -1022,7 +1031,11 @@ class VirtualMachineView(LoginRequiredMixin, View):
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        except Exception as ex:
 | 
					        except Exception as ex:
 | 
				
			||||||
            logger.debug("Exception generated {}".format(str(ex)))
 | 
					            logger.debug("Exception generated {}".format(str(ex)))
 | 
				
			||||||
            pass
 | 
					            messages.error(self.request,
 | 
				
			||||||
 | 
					                           _('We could not find the requested VM. Please '
 | 
				
			||||||
 | 
					                             'contact Data Center Light Support.')
 | 
				
			||||||
 | 
					                           )
 | 
				
			||||||
 | 
					            return redirect(reverse('hosting:virtual_machines'))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return render(request, self.template_name, context)
 | 
					        return render(request, self.template_name, context)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1130,3 +1143,15 @@ class HostingBillDetailView(PermissionRequiredMixin, LoginRequiredMixin,
 | 
				
			||||||
            bill.total_price += vm['price']
 | 
					            bill.total_price += vm['price']
 | 
				
			||||||
        context['vms'] = vms
 | 
					        context['vms'] = vms
 | 
				
			||||||
        return context
 | 
					        return context
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def forbidden_view(request, exception=None, reason=''):
 | 
				
			||||||
 | 
					    """
 | 
				
			||||||
 | 
					    Handle 403 error
 | 
				
			||||||
 | 
					    """
 | 
				
			||||||
 | 
					    logger.error(str(exception) if exception else None)
 | 
				
			||||||
 | 
					    logger.error('Reason = {reason}'.format(reason=reason))
 | 
				
			||||||
 | 
					    err_msg = _('There was an error processing your request. Please try '
 | 
				
			||||||
 | 
					                'again.')
 | 
				
			||||||
 | 
					    messages.add_message(request, messages.ERROR, err_msg)
 | 
				
			||||||
 | 
					    return HttpResponseRedirect(request.get_full_path())
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -8,7 +8,7 @@ msgid ""
 | 
				
			||||||
msgstr ""
 | 
					msgstr ""
 | 
				
			||||||
"Project-Id-Version: PACKAGE VERSION\n"
 | 
					"Project-Id-Version: PACKAGE VERSION\n"
 | 
				
			||||||
"Report-Msgid-Bugs-To: \n"
 | 
					"Report-Msgid-Bugs-To: \n"
 | 
				
			||||||
"POT-Creation-Date: 2017-09-25 20:11+0000\n"
 | 
					"POT-Creation-Date: 2017-09-29 20:33+0000\n"
 | 
				
			||||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
 | 
					"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
 | 
				
			||||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
 | 
					"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
 | 
				
			||||||
"Language-Team: LANGUAGE <LL@li.org>\n"
 | 
					"Language-Team: LANGUAGE <LL@li.org>\n"
 | 
				
			||||||
| 
						 | 
					@ -771,10 +771,13 @@ msgstr ""
 | 
				
			||||||
msgid "Country"
 | 
					msgid "Country"
 | 
				
			||||||
msgstr ""
 | 
					msgstr ""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
msgid "Street Building"
 | 
					msgid "Name"
 | 
				
			||||||
msgstr ""
 | 
					msgstr ""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
msgid "Name"
 | 
					msgid "Email Address"
 | 
				
			||||||
 | 
					msgstr ""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					msgid "Street Building"
 | 
				
			||||||
msgstr ""
 | 
					msgstr ""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
msgid "Email"
 | 
					msgid "Email"
 | 
				
			||||||
| 
						 | 
					@ -786,9 +789,9 @@ msgstr "Telefon"
 | 
				
			||||||
msgid "Message"
 | 
					msgid "Message"
 | 
				
			||||||
msgstr "Nachricht"
 | 
					msgstr "Nachricht"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
msgid "An email with the activation link has been sent to your email"
 | 
					msgid "An email with the activation link has been sent to you"
 | 
				
			||||||
msgstr ""
 | 
					msgstr ""
 | 
				
			||||||
"Der Link zum Zurücksetzen deines Passwortes wurde an deine E-Mail gesendet"
 | 
					"Es wurde eine E-Mail mit dem Aktivierungslink an Dich gesendet."
 | 
				
			||||||
 | 
					
 | 
				
			||||||
msgid "Account Activation"
 | 
					msgid "Account Activation"
 | 
				
			||||||
msgstr "Accountaktivierung"
 | 
					msgstr "Accountaktivierung"
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -28,28 +28,34 @@ def handleStripeError(f):
 | 
				
			||||||
            body = e.json_body
 | 
					            body = e.json_body
 | 
				
			||||||
            err = body['error']
 | 
					            err = body['error']
 | 
				
			||||||
            response.update({'error': err['message']})
 | 
					            response.update({'error': err['message']})
 | 
				
			||||||
 | 
					            logger.error(str(e))
 | 
				
			||||||
            return response
 | 
					            return response
 | 
				
			||||||
        except stripe.error.RateLimitError as e:
 | 
					        except stripe.error.RateLimitError as e:
 | 
				
			||||||
            response.update(
 | 
					            response.update(
 | 
				
			||||||
                {'error': "Too many requests made to the API too quickly"})
 | 
					                {'error': "Too many requests made to the API too quickly"})
 | 
				
			||||||
            return response
 | 
					            return response
 | 
				
			||||||
        except stripe.error.InvalidRequestError as e:
 | 
					        except stripe.error.InvalidRequestError as e:
 | 
				
			||||||
 | 
					            logger.error(str(e))
 | 
				
			||||||
            response.update({'error': "Invalid parameters"})
 | 
					            response.update({'error': "Invalid parameters"})
 | 
				
			||||||
            return response
 | 
					            return response
 | 
				
			||||||
        except stripe.error.AuthenticationError as e:
 | 
					        except stripe.error.AuthenticationError as e:
 | 
				
			||||||
            # Authentication with Stripe's API failed
 | 
					            # Authentication with Stripe's API failed
 | 
				
			||||||
            # (maybe you changed API keys recently)
 | 
					            # (maybe you changed API keys recently)
 | 
				
			||||||
 | 
					            logger.error(str(e))
 | 
				
			||||||
            response.update({'error': common_message})
 | 
					            response.update({'error': common_message})
 | 
				
			||||||
            return response
 | 
					            return response
 | 
				
			||||||
        except stripe.error.APIConnectionError as e:
 | 
					        except stripe.error.APIConnectionError as e:
 | 
				
			||||||
 | 
					            logger.error(str(e))
 | 
				
			||||||
            response.update({'error': common_message})
 | 
					            response.update({'error': common_message})
 | 
				
			||||||
            return response
 | 
					            return response
 | 
				
			||||||
        except stripe.error.StripeError as e:
 | 
					        except stripe.error.StripeError as e:
 | 
				
			||||||
            # maybe send email
 | 
					            # maybe send email
 | 
				
			||||||
 | 
					            logger.error(str(e))
 | 
				
			||||||
            response.update({'error': common_message})
 | 
					            response.update({'error': common_message})
 | 
				
			||||||
            return response
 | 
					            return response
 | 
				
			||||||
        except Exception as e:
 | 
					        except Exception as e:
 | 
				
			||||||
            # maybe send email
 | 
					            # maybe send email
 | 
				
			||||||
 | 
					            logger.error(str(e))
 | 
				
			||||||
            response.update({'error': common_message})
 | 
					            response.update({'error': common_message})
 | 
				
			||||||
            return response
 | 
					            return response
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -66,7 +66,7 @@ class LoginViewMixin(FormView):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class ResendActivationLinkViewMixin(FormView):
 | 
					class ResendActivationLinkViewMixin(FormView):
 | 
				
			||||||
    success_message = _(
 | 
					    success_message = _(
 | 
				
			||||||
        "An email with the activation link has been sent to your email")
 | 
					        "An email with the activation link has been sent to you")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def generate_email_context(self, user):
 | 
					    def generate_email_context(self, user):
 | 
				
			||||||
        context = {
 | 
					        context = {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue