diff --git a/Changelog b/Changelog
index 44c4dee4..5700852e 100644
--- a/Changelog
+++ b/Changelog
@@ -1,44 +1,3 @@
-3.2: 2021-02-07
- * 8816: Update order confirmation text to better prepared for payment dispute
- * supportticket#22990: Fix: can't add a deleted card
-3.1: 2021-01-11
- * 8781: Fix error is setting a default card (MR!746)
-3.0: 2021-01-07
- * 8393: Implement SCA for stripe payments (MR!745)
- * 8691: Implment check_vm_templates management command (MR!744)
-2.14: 2020-12-07
- * 8692: Create a script that fixes django db for the order after celery error (MR!743)
-2.13: 2020-12-02
- * 8654: Fix 500 error on invoices list for the user contact+devuanhosting.com@virus.media (MR!742)
- * 8593: Escape user's ssh key in xml-rpc call to create VM (MR!741)
-2.12.1: 2020-07-21
- * 8307: Introduce "Exclude vat calculations" for Generic Products (MR!740)
- * Change DE VAT rate to 16% from 19% (MR!739)
-2.12: 2020-06-23
- * 7894: Show one time payment invoices (MR!738)
-2.11: 2020-06-11
- * Bugfix: Correct the wrong constant name (caused payment to go thru and showing error and VMs not instantiated)
-2.10.8: 2020-06-10
- * #8102: Refactor MAX_TIME_TO_WAIT_FOR_VM_TERMINATE to increase time to poll whether VM has been terminated or not (MR!737)
-2.10.7: 2020-05-25
- * Bugfix: Handle VM templates deleted in OpenNebula but VM instances still existing (MR!736)
- Notes for deployment:
- When deploying define a UPDATED_TEMPLATES string represented dictionary value in .env
-```
- # Represents Template Ids that were
- # deleted and the new template Id to look for the template
- # definition
- UPDATED_TEMPLATES="{1: 100}"
-```
-2.10.6: 2020-03-25
- * Bugfix: Handle Nonetype for discount's name (MR!735)
-2.10.5: 2020-03-17
- * Introduce base price for VMs and let admins add stripe_coupon_id (MR!730)
- Notes for deployment:
- 1. Add env variable `VM_BASE_PRICE`
- 2. Migrate datacenterlight app. This introduces the stripe_coupon_code field in the VMPricing.
- 3. Create a coupon in stripe with the desired value and note down the stripe's coupon id
- 4. Update the discount amount and set the corresponding coupon id in the admin
2.10.3b: 2020-03-05
* #7773: Use username for communicating with opennebula all the time
2.10.2b: 2020-02-25
diff --git a/datacenterlight/cms_plugins.py b/datacenterlight/cms_plugins.py
index 52b4f19f..c3ec974f 100644
--- a/datacenterlight/cms_plugins.py
+++ b/datacenterlight/cms_plugins.py
@@ -1,6 +1,5 @@
from cms.plugin_base import CMSPluginBase
from cms.plugin_pool import plugin_pool
-from django.conf import settings
from .cms_models import (
DCLBannerItemPluginModel, DCLBannerListPluginModel, DCLContactPluginModel,
@@ -101,7 +100,6 @@ class DCLCalculatorPlugin(CMSPluginBase):
vm_type=instance.vm_type
).order_by('name')
context['instance'] = instance
- context['vm_base_price'] = settings.VM_BASE_PRICE
context['min_ram'] = 0.5 if instance.enable_512mb_ram else 1
return context
diff --git a/datacenterlight/locale/de/LC_MESSAGES/django.po b/datacenterlight/locale/de/LC_MESSAGES/django.po
index cd7fab99..1a1a2a26 100644
--- a/datacenterlight/locale/de/LC_MESSAGES/django.po
+++ b/datacenterlight/locale/de/LC_MESSAGES/django.po
@@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2021-02-07 11:10+0000\n"
+"POT-Creation-Date: 2020-02-01 09:42+0000\n"
"PO-Revision-Date: 2018-03-30 23:22+0000\n"
"Last-Translator: b'Anonymous User '\n"
"Language-Team: LANGUAGE \n"
@@ -144,8 +144,8 @@ msgid ""
"the heart of Switzerland."
msgstr "Bei uns findest Du die günstiges VMs aus der Schweiz."
-msgid "Try now, order a VM. VM price starts from only 11.5 CHF per month."
-msgstr "Unser Angebot beginnt bei 11.5 CHF pro Monat. Probier's jetzt aus!"
+msgid "Try now, order a VM. VM price starts from only 10.5 CHF per month."
+msgstr "Unser Angebot beginnt bei 10.5 CHF pro Monat. Probier's jetzt aus!"
msgid "ORDER VM"
msgstr "VM BESTELLEN"
@@ -415,9 +415,8 @@ msgstr "Deine MwSt-Nummer wurde überprüft"
msgid ""
"Your VAT number is under validation. VAT will be adjusted, once the "
"validation is complete."
-msgstr ""
-"Deine MwSt-Nummer wird derzeit validiert. Die MwSt. wird angepasst, sobald "
-"die Validierung abgeschlossen ist."
+msgstr "Deine MwSt-Nummer wird derzeit validiert. Die MwSt. wird angepasst, "
+"sobald die Validierung abgeschlossen ist."
msgid "Payment method"
msgstr "Bezahlmethode"
@@ -431,6 +430,18 @@ msgstr "Bestellungsübersicht"
msgid "Product"
msgstr "Produkt"
+msgid "Price"
+msgstr "Preise"
+
+msgid "VAT for"
+msgstr "MwSt für"
+
+msgid "Total Amount"
+msgstr "Gesamtsumme"
+
+msgid "Amount"
+msgstr "Betrag"
+
msgid "Description"
msgstr "Beschreibung"
@@ -443,51 +454,42 @@ msgstr "Preis ohne MwSt."
msgid "Pre VAT"
msgstr "Exkl. MwSt."
-msgid "VAT for"
-msgstr "MwSt für"
-
msgid "Your Price in Total"
msgstr "Dein Gesamtpreis"
-#, python-format
msgid ""
-" By clicking \"Place order\" you agree to our Terms of Service and "
-"this plan will charge your credit card account with %(total_price)s CHF/year"
+"By clicking \"Place order\" this plan will charge your credit card account "
+"with %(total_price)s CHF/year"
msgstr ""
-"Indem Du auf \"Bestellung aufgeben\" klickst, erklärst Du dich mit unseren Nutzungsbedingungen einverstanden und Dein Kreditkartenkonto wird mit %(total_price)s CHF/Jahr belastet."
+"Wenn Du \"bestellen\" auswählst, wird Deine Kreditkarte mit %(total_price)s "
+"CHF pro Jahr belastet"
#, python-format
msgid ""
-"\n"
-" By clicking \"Place order\" you agree to "
-"our Terms "
-"of Service and this plan will charge your credit card account with "
-"%(total_price)s CHF/month"
+"By clicking \"Place order\" this plan will charge your credit card account "
+"with %(total_price)s CHF/month"
msgstr ""
-"\n"
-"Indem Du auf \"Bestellung aufgeben\" klickst, erklärst Du dich mit unseren Nutzungsbedingungen einverstanden und Dein Kreditkartenkonto wird mit %(total_price)s CHF/Monat belastet."
+"Wenn Du \"bestellen\" auswählst, wird Deine Kreditkarte mit %(total_price)s "
+"CHF pro Monat belastet"
+
+#, fuzzy, python-format
+#| msgid ""
+#| "By clicking \"Place order\" this payment will charge your credit card "
+#| "account with a one time amount of %(total_price)s CHF"
+msgid ""
+"By clicking \"Place order\" this payment will charge your credit card "
+"account with a one time amount of %(total_price)s CHF"
+msgstr ""
+"Wenn Du \"bestellen\" auswählst, wird Deine Kreditkarte mit "
+"%(vm_total_price)s CHF pro Monat belastet"
#, python-format
msgid ""
-"By clicking \"Place order\" you agree to our Terms of Service and "
-"this plan will charge your credit card account with %(total_price)s CHF"
+"By clicking \"Place order\" this plan will charge your credit card account "
+"with %(vm_total_price)s CHF/month"
msgstr ""
-"Indem Du auf \"Bestellung aufgeben\" klickst, erklärst Du dich mit unseren Nutzungsbedingungen einverstanden und Dein Kreditkartenkonto wird mit %(total_price)s CHF belastet."
-
-#, python-format
-msgid ""
-"By clicking \"Place order\" you agree to our Terms of Service and "
-"this plan will charge your credit card account with %(vm_total_price)s CHF/"
-"month"
-msgstr ""
-"Indem Du auf \"Bestellung aufgeben\" klickst, erklärst Du dich mit unseren Nutzungsbedingungen einverstanden und Dein Kreditkartenkonto wird mit %(vm_total_price)s CHF/Monat belastet"
+"Wenn Du \"bestellen\" auswählst, wird Deine Kreditkarte mit "
+"%(vm_total_price)s CHF pro Monat belastet"
msgid "Place order"
msgstr "Bestellen"
@@ -606,22 +608,16 @@ msgid "Incorrect pricing name. Please contact support{support_email}"
msgstr ""
"Ungültige Preisbezeichnung. Bitte kontaktiere den Support{support_email}"
+#, python-brace-format
+msgid "{user} does not have permission to access the card"
+msgstr "{user} hat keine Erlaubnis auf diese Karte zuzugreifen"
+
+msgid "An error occurred. Details: {}"
+msgstr "Ein Fehler ist aufgetreten. Details: {}"
+
msgid "Confirm Order"
msgstr "Bestellung Bestätigen"
-#, fuzzy
-#| msgid "Thank you!"
-msgid "Thank you !"
-msgstr "Vielen Dank!"
-
-msgid "Your product will be provisioned as soon as we receive the payment."
-msgstr ""
-
-#, python-brace-format
-msgid "An error occurred while associating the card. Details: {details}"
-msgstr ""
-"Beim Verbinden der Karte ist ein Fehler aufgetreten. Details: {details}"
-
msgid "Error."
msgstr ""
@@ -632,21 +628,10 @@ 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."
-msgstr "Danke für Deine Bestellung."
-
-msgid ""
-"Your product will be provisioned as soon as we receive a payment "
-"confirmation from Stripe. We will send you a confirmation email. You can "
-"always contact us at support@datacenterlight.ch"
+#, python-brace-format
+msgid "An error occurred while associating the card. Details: {details}"
msgstr ""
-
-msgid ""
-"Your VM will be up and running in a few moments. We will send you a "
-"confirmation email as soon as it is ready."
-msgstr ""
-"Deine VM ist gleich bereit. Wir senden Dir eine Bestätigungsemail, sobald Du "
-"auf sie zugreifen kannst."
+"Beim Verbinden der Karte ist ein Fehler aufgetreten. Details: {details}"
msgid " This is a monthly recurring plan."
msgstr "Dies ist ein monatlich wiederkehrender Plan."
@@ -686,40 +671,15 @@ msgstr ""
"Du wirst bald eine Bestätigungs-E-Mail über die Zahlung erhalten. Du kannst "
"jederzeit unter info@ungleich.ch kontaktieren."
-#, python-format
-#~ msgid ""
-#~ "By clicking \"Place order\" this plan will charge your credit card "
-#~ "account with %(total_price)s CHF/month"
-#~ msgstr ""
-#~ "Wenn Du \"bestellen\" auswählst, wird Deine Kreditkarte mit "
-#~ "%(total_price)s CHF pro Monat belastet"
+msgid "Thank you for the order."
+msgstr "Danke für Deine Bestellung."
-#, fuzzy, python-format
-#~| msgid ""
-#~| "By clicking \"Place order\" this payment will charge your credit card "
-#~| "account with a one time amount of %(total_price)s CHF"
-#~ msgid ""
-#~ "By clicking \"Place order\" this payment will charge your credit card "
-#~ "account with a one time amount of %(total_price)s CHF"
-#~ msgstr ""
-#~ "Wenn Du \"bestellen\" auswählst, wird Deine Kreditkarte mit "
-#~ "%(vm_total_price)s CHF pro Monat belastet"
-
-#, python-brace-format
-#~ msgid "{user} does not have permission to access the card"
-#~ msgstr "{user} hat keine Erlaubnis auf diese Karte zuzugreifen"
-
-#~ msgid "An error occurred. Details: {}"
-#~ msgstr "Ein Fehler ist aufgetreten. Details: {}"
-
-#~ msgid "Price"
-#~ msgstr "Preise"
-
-#~ msgid "Total Amount"
-#~ msgstr "Gesamtsumme"
-
-#~ msgid "Amount"
-#~ msgstr "Betrag"
+msgid ""
+"Your VM will be up and running in a few moments. We will send you a "
+"confirmation email as soon as it is ready."
+msgstr ""
+"Deine VM ist gleich bereit. Wir senden Dir eine Bestätigungsemail, sobald Du "
+"auf sie zugreifen kannst."
#~ msgid "Subtotal"
#~ msgstr "Zwischensumme"
@@ -786,6 +746,9 @@ msgstr ""
#~ "Wir werden dann sobald als möglich Ihren Beta-Zugang erstellen und Sie "
#~ "daraufhin kontaktieren.Bis dahin bitten wir Sie um etwas Geduld."
+#~ msgid "Thank you!"
+#~ msgstr "Vielen Dank!"
+
#~ msgid "Thank you for order! Our team will contact you via email"
#~ msgstr ""
#~ "Vielen Dank für die Bestellung. Unser Team setzt sich sobald wie möglich "
diff --git a/datacenterlight/management/commands/check_vm_templates.py b/datacenterlight/management/commands/check_vm_templates.py
deleted file mode 100644
index db36fde8..00000000
--- a/datacenterlight/management/commands/check_vm_templates.py
+++ /dev/null
@@ -1,65 +0,0 @@
-from django.core.management.base import BaseCommand
-from opennebula_api.models import OpenNebulaManager
-from datacenterlight.models import VMTemplate
-from membership.models import CustomUser
-
-from django.conf import settings
-from time import sleep
-import datetime
-import json
-import logging
-import os
-
-logger = logging.getLogger(__name__)
-
-
-class Command(BaseCommand):
- help = '''Checks all VM templates to find if they can be instantiated'''
-
- def add_arguments(self, parser):
- parser.add_argument('user_email', type=str)
-
- def handle(self, *args, **options):
- result_dict = {}
- user_email = options['user_email'] if 'user_email' in options else ""
-
- if user_email:
- cu = CustomUser.objects.get(email=user_email)
- specs = {'cpu': 1, 'memory': 1, 'disk_size': 10}
- manager = OpenNebulaManager(email=user_email, password=cu.password)
- pub_keys = [settings.TEST_MANAGE_SSH_KEY_PUBKEY]
- PROJECT_PATH = os.path.abspath(os.path.dirname(__name__))
- if not os.path.exists("%s/outputs" % PROJECT_PATH):
- os.mkdir("%s/outputs" % PROJECT_PATH)
- for vm_template in VMTemplate.objects.all():
- vm_name = 'test-%s' % vm_template.name
- vm_id = manager.create_vm(
- template_id=vm_template.opennebula_vm_template_id,
- specs=specs,
- ssh_key='\n'.join(pub_keys),
- vm_name=vm_name
- )
- if vm_id and vm_id > 0:
- result_dict[vm_name] = "%s OK, created VM %s" % (
- '%s %s %s' % (vm_template.opennebula_vm_template_id,
- vm_template.name, vm_template.vm_type),
- vm_id
- )
- self.stdout.write(self.style.SUCCESS(result_dict[vm_name]))
- manager.delete_vm(vm_id)
- else:
- result_dict[vm_name] = '''Error creating VM %s, template_id
- %s %s''' % (vm_name,
- vm_template.opennebula_vm_template_id,
- vm_template.vm_type)
- self.stdout.write(self.style.ERROR(result_dict[vm_name]))
- sleep(1)
- date_str = datetime.datetime.strftime(
- datetime.datetime.now(), '%Y%m%d%H%M%S'
- )
- with open("%s/outputs/check_vm_templates_%s.txt" %
- (PROJECT_PATH, date_str),
- 'w',
- encoding='utf-8') as f:
- f.write(json.dumps(result_dict))
- self.stdout.write(self.style.SUCCESS("Done"))
diff --git a/datacenterlight/management/commands/fix_vm_after_celery_error.py b/datacenterlight/management/commands/fix_vm_after_celery_error.py
deleted file mode 100644
index 0cfdb423..00000000
--- a/datacenterlight/management/commands/fix_vm_after_celery_error.py
+++ /dev/null
@@ -1,76 +0,0 @@
-from django.core.management.base import BaseCommand
-from datacenterlight.tasks import handle_metadata_and_emails
-from opennebula_api.models import OpenNebulaManager
-from membership.models import CustomUser
-import logging
-import json
-
-logger = logging.getLogger(__name__)
-
-
-class Command(BaseCommand):
- help = '''Updates the DB after manual creation of VM'''
-
- def add_arguments(self, parser):
- parser.add_argument('vm_id', type=int)
- parser.add_argument('order_id', type=int)
- parser.add_argument('user', type=str)
- parser.add_argument('specs', type=str)
- parser.add_argument('template', type=str)
-
- def handle(self, *args, **options):
- vm_id = options['vm_id']
- order_id = options['order_id']
- user_str = options['user']
- specs_str = options['specs']
- template_str = options['template']
-
- json_acceptable_string = user_str.replace("'", "\"")
- user_dict = json.loads(json_acceptable_string)
-
- json_acceptable_string = specs_str.replace("'", "\"")
- specs = json.loads(json_acceptable_string)
-
- json_acceptable_string = template_str.replace("'", "\"")
- template = json.loads(json_acceptable_string)
- if vm_id <= 0:
- self.stdout.write(self.style.ERROR(
- 'vm_id can\'t be less than or 0. Given: %s' % vm_id))
- return
- if vm_id <= 0:
- self.stdout.write(self.style.ERROR(
- 'order_id can\'t be less than or 0. Given: %s' % vm_id))
- return
- if specs_str is None or specs_str == "":
- self.stdout.write(
- self.style.ERROR('specs can\'t be empty or None'))
- return
-
- user = {
- 'name': user_dict['name'],
- 'email': user_dict['email'],
- 'username': user_dict['username'],
- 'pass': user_dict['pass'],
- 'request_scheme': user_dict['request_scheme'],
- 'request_host': user_dict['request_host'],
- 'language': user_dict['language'],
- }
- cu = CustomUser.objects.get(username=user.get('username'))
- # Create OpenNebulaManager
- self.stdout.write(
- self.style.SUCCESS(
- 'Connecting using %s' % (cu.username)
- )
- )
- manager = OpenNebulaManager(email=cu.username, password=cu.password)
- handle_metadata_and_emails(order_id, vm_id, manager, user, specs,
- template)
- self.stdout.write(
- self.style.SUCCESS(
- 'Done handling metadata and emails for %s %s %s' % (
- order_id,
- vm_id,
- str(user)
- )
- )
- )
diff --git a/datacenterlight/migrations/0031_vmpricing_stripe_coupon_id.py b/datacenterlight/migrations/0031_vmpricing_stripe_coupon_id.py
deleted file mode 100644
index d2e45871..00000000
--- a/datacenterlight/migrations/0031_vmpricing_stripe_coupon_id.py
+++ /dev/null
@@ -1,20 +0,0 @@
-# -*- coding: utf-8 -*-
-# Generated by Django 1.9.4 on 2020-02-04 03:16
-from __future__ import unicode_literals
-
-from django.db import migrations, models
-
-
-class Migration(migrations.Migration):
-
- dependencies = [
- ('datacenterlight', '0030_dclnavbarpluginmodel_show_non_transparent_navbar_always'),
- ]
-
- operations = [
- migrations.AddField(
- model_name='vmpricing',
- name='stripe_coupon_id',
- field=models.CharField(blank=True, max_length=255, null=True),
- ),
- ]
diff --git a/datacenterlight/models.py b/datacenterlight/models.py
index 64d785a2..6410254b 100644
--- a/datacenterlight/models.py
+++ b/datacenterlight/models.py
@@ -54,7 +54,6 @@ class VMPricing(models.Model):
discount_amount = models.DecimalField(
max_digits=6, decimal_places=2, default=0
)
- stripe_coupon_id = models.CharField(max_length=255, null=True, blank=True)
def __str__(self):
display_str = self.name + ' => ' + ' - '.join([
diff --git a/datacenterlight/static/datacenterlight/js/main.js b/datacenterlight/static/datacenterlight/js/main.js
index c6869cda..8fea438a 100644
--- a/datacenterlight/static/datacenterlight/js/main.js
+++ b/datacenterlight/static/datacenterlight/js/main.js
@@ -225,8 +225,8 @@
}
var total = (cardPricing['cpu'].value * window.coresUnitPrice) +
(cardPricing['ram'].value * window.ramUnitPrice) +
- (cardPricing['storage'].value * window.ssdUnitPrice) +
- window.vmBasePrice - window.discountAmount;
+ (cardPricing['storage'].value * window.ssdUnitPrice) -
+ window.discountAmount;
total = parseFloat(total.toFixed(2));
$("#total").text(total);
}
diff --git a/datacenterlight/tasks.py b/datacenterlight/tasks.py
index 9c98b729..f080da90 100644
--- a/datacenterlight/tasks.py
+++ b/datacenterlight/tasks.py
@@ -56,6 +56,11 @@ def create_vm_task(self, vm_template_id, user, specs, template, order_id):
"Running create_vm_task on {}".format(current_task.request.hostname))
vm_id = None
try:
+ final_price = (
+ specs.get('total_price') if 'total_price' in specs
+ else specs.get('price')
+ )
+
if 'pass' in user:
on_user = user.get('username')
on_pass = user.get('pass')
@@ -87,8 +92,107 @@ def create_vm_task(self, vm_template_id, user, specs, template, order_id):
if vm_id is None:
raise Exception("Could not create VM")
- handle_metadata_and_emails(order_id, vm_id, manager, user, specs,
- template)
+ # Update HostingOrder with the created vm_id
+ hosting_order = HostingOrder.objects.filter(id=order_id).first()
+ error_msg = None
+
+ try:
+ hosting_order.vm_id = vm_id
+ hosting_order.save()
+ logger.debug(
+ "Updated hosting_order {} with vm_id={}".format(
+ hosting_order.id, vm_id
+ )
+ )
+ except Exception as ex:
+ error_msg = (
+ "HostingOrder with id {order_id} not found. This means that "
+ "the hosting order was not created and/or it is/was not "
+ "associated with VM with id {vm_id}. Details {details}".format(
+ order_id=order_id, vm_id=vm_id, details=str(ex)
+ )
+ )
+ logger.error(error_msg)
+
+ stripe_utils = StripeUtils()
+ result = stripe_utils.set_subscription_metadata(
+ subscription_id=hosting_order.subscription_id,
+ metadata={"VM_ID": str(vm_id)}
+ )
+
+ if result.get('error') is not None:
+ emsg = "Could not update subscription metadata for {sub}".format(
+ sub=hosting_order.subscription_id
+ )
+ logger.error(emsg)
+ if error_msg:
+ error_msg += ". " + emsg
+ else:
+ error_msg = emsg
+
+ vm = VirtualMachineSerializer(manager.get_vm(vm_id)).data
+
+ context = {
+ 'name': user.get('name'),
+ 'email': user.get('email'),
+ 'cores': specs.get('cpu'),
+ 'memory': specs.get('memory'),
+ 'storage': specs.get('disk_size'),
+ 'price': final_price,
+ 'template': template.get('name'),
+ 'vm_name': vm.get('name'),
+ 'vm_id': vm['vm_id'],
+ 'order_id': order_id
+ }
+
+ if error_msg:
+ context['errors'] = error_msg
+ if 'pricing_name' in specs:
+ context['pricing'] = str(VMPricing.get_vm_pricing_by_name(
+ name=specs['pricing_name']
+ ))
+ email_data = {
+ 'subject': settings.DCL_TEXT + " Order from %s" % context['email'],
+ 'from_email': settings.DCL_SUPPORT_FROM_ADDRESS,
+ 'to': ['info@ungleich.ch'],
+ 'body': "\n".join(
+ ["%s=%s" % (k, v) for (k, v) in context.items()]),
+ 'reply_to': [context['email']],
+ }
+ email = EmailMessage(**email_data)
+ email.send()
+
+ if 'pass' in user:
+ lang = 'en-us'
+ if user.get('language') is not None:
+ logger.debug(
+ "Language is set to {}".format(user.get('language')))
+ lang = user.get('language')
+ translation.activate(lang)
+ # Send notification to the user as soon as VM has been booked
+ context = {
+ 'base_url': "{0}://{1}".format(user.get('request_scheme'),
+ user.get('request_host')),
+ 'order_url': reverse('hosting:invoices'),
+ 'page_header': _(
+ 'Your New VM %(vm_name)s at Data Center Light') % {
+ 'vm_name': vm.get('name')},
+ 'vm_name': vm.get('name')
+ }
+ email_data = {
+ 'subject': context.get('page_header'),
+ 'to': user.get('email'),
+ 'context': context,
+ 'template_name': 'new_booked_vm',
+ 'template_path': 'hosting/emails/',
+ 'from_address': settings.DCL_SUPPORT_FROM_ADDRESS,
+ }
+ email = BaseEmail(**email_data)
+ email.send()
+
+ logger.debug("New VM ID is {vm_id}".format(vm_id=vm_id))
+ if vm_id > 0:
+ get_or_create_vm_detail(custom_user, manager, vm_id)
except Exception as e:
logger.error(str(e))
try:
@@ -110,127 +214,3 @@ def create_vm_task(self, vm_template_id, user, specs, template, order_id):
return
return vm_id
-
-
-def handle_metadata_and_emails(order_id, vm_id, manager, user, specs,
- template):
- """
- Handle's setting up of the metadata in Stripe and database and sending of
- emails to the user after VM creation
-
- :param order_id: the hosting order id
- :param vm_id: the id of the vm created
- :param manager: the OpenNebula Manager instance
- :param user: the user's dict passed to the celery task
- :param specs: the specification's dict passed to the celery task
- :param template: the template dict passed to the celery task
-
- :return:
- """
-
- custom_user = CustomUser.objects.get(email=user.get('email'))
- final_price = (
- specs.get('total_price') if 'total_price' in specs
- else specs.get('price')
- )
- # Update HostingOrder with the created vm_id
- hosting_order = HostingOrder.objects.filter(id=order_id).first()
- error_msg = None
-
- try:
- hosting_order.vm_id = vm_id
- hosting_order.save()
- logger.debug(
- "Updated hosting_order {} with vm_id={}".format(
- hosting_order.id, vm_id
- )
- )
- except Exception as ex:
- error_msg = (
- "HostingOrder with id {order_id} not found. This means that "
- "the hosting order was not created and/or it is/was not "
- "associated with VM with id {vm_id}. Details {details}".format(
- order_id=order_id, vm_id=vm_id, details=str(ex)
- )
- )
- logger.error(error_msg)
-
- stripe_utils = StripeUtils()
- result = stripe_utils.set_subscription_metadata(
- subscription_id=hosting_order.subscription_id,
- metadata={"VM_ID": str(vm_id)}
- )
-
- if result.get('error') is not None:
- emsg = "Could not update subscription metadata for {sub}".format(
- sub=hosting_order.subscription_id
- )
- logger.error(emsg)
- if error_msg:
- error_msg += ". " + emsg
- else:
- error_msg = emsg
-
- vm = VirtualMachineSerializer(manager.get_vm(vm_id)).data
-
- context = {
- 'name': user.get('name'),
- 'email': user.get('email'),
- 'cores': specs.get('cpu'),
- 'memory': specs.get('memory'),
- 'storage': specs.get('disk_size'),
- 'price': final_price,
- 'template': template.get('name'),
- 'vm_name': vm.get('name'),
- 'vm_id': vm['vm_id'],
- 'order_id': order_id
- }
-
- if error_msg:
- context['errors'] = error_msg
- if 'pricing_name' in specs:
- context['pricing'] = str(VMPricing.get_vm_pricing_by_name(
- name=specs['pricing_name']
- ))
- email_data = {
- 'subject': settings.DCL_TEXT + " Order from %s" % context['email'],
- 'from_email': settings.DCL_SUPPORT_FROM_ADDRESS,
- 'to': ['info@ungleich.ch'],
- 'body': "\n".join(
- ["%s=%s" % (k, v) for (k, v) in context.items()]),
- 'reply_to': [context['email']],
- }
- email = EmailMessage(**email_data)
- email.send()
-
- if 'pass' in user:
- lang = 'en-us'
- if user.get('language') is not None:
- logger.debug(
- "Language is set to {}".format(user.get('language')))
- lang = user.get('language')
- translation.activate(lang)
- # Send notification to the user as soon as VM has been booked
- context = {
- 'base_url': "{0}://{1}".format(user.get('request_scheme'),
- user.get('request_host')),
- 'order_url': reverse('hosting:invoices'),
- 'page_header': _(
- 'Your New VM %(vm_name)s at Data Center Light') % {
- 'vm_name': vm.get('name')},
- 'vm_name': vm.get('name')
- }
- email_data = {
- 'subject': context.get('page_header'),
- 'to': user.get('email'),
- 'context': context,
- 'template_name': 'new_booked_vm',
- 'template_path': 'hosting/emails/',
- 'from_address': settings.DCL_SUPPORT_FROM_ADDRESS,
- }
- email = BaseEmail(**email_data)
- email.send()
-
- logger.debug("New VM ID is {vm_id}".format(vm_id=vm_id))
- if vm_id > 0:
- get_or_create_vm_detail(custom_user, manager, vm_id)
\ No newline at end of file
diff --git a/datacenterlight/templates/datacenterlight/cms/calculator.html b/datacenterlight/templates/datacenterlight/cms/calculator.html
index 20a6664a..7b123a72 100644
--- a/datacenterlight/templates/datacenterlight/cms/calculator.html
+++ b/datacenterlight/templates/datacenterlight/cms/calculator.html
@@ -1,5 +1,5 @@
- {% include "datacenterlight/includes/_calculator_form.html" with vm_pricing=instance.pricing vm_base_price=vm_base_price %}
+ {% include "datacenterlight/includes/_calculator_form.html" with vm_pricing=instance.pricing %}
\ No newline at end of file
diff --git a/datacenterlight/templates/datacenterlight/emails/welcome_user.html b/datacenterlight/templates/datacenterlight/emails/welcome_user.html
index 2044b2ee..25185618 100644
--- a/datacenterlight/templates/datacenterlight/emails/welcome_user.html
+++ b/datacenterlight/templates/datacenterlight/emails/welcome_user.html
@@ -28,7 +28,7 @@
{% blocktrans %}Thanks for joining us! We provide the most affordable virtual machines from the heart of Switzerland.{% endblocktrans %}
- {% blocktrans %}Try now, order a VM. VM price starts from only 11.5 CHF per month.{% endblocktrans %}
+ {% blocktrans %}Try now, order a VM. VM price starts from only 10.5 CHF per month.{% endblocktrans %}
diff --git a/datacenterlight/templates/datacenterlight/emails/welcome_user.txt b/datacenterlight/templates/datacenterlight/emails/welcome_user.txt
index 06e8aa33..772e51a5 100644
--- a/datacenterlight/templates/datacenterlight/emails/welcome_user.txt
+++ b/datacenterlight/templates/datacenterlight/emails/welcome_user.txt
@@ -3,7 +3,7 @@
{% trans "Welcome to Data Center Light!" %}
{% blocktrans %}Thanks for joining us! We provide the most affordable virtual machines from the heart of Switzerland.{% endblocktrans %}
-{% blocktrans %}Try now, order a VM. VM price starts from only 11.5 CHF per month.{% endblocktrans %}
+{% blocktrans %}Try now, order a VM. VM price starts from only 10.5 CHF per month.{% endblocktrans %}
{{ base_url }}{% url 'hosting:create_virtual_machine' %}
diff --git a/datacenterlight/templates/datacenterlight/includes/_calculator_form.html b/datacenterlight/templates/datacenterlight/includes/_calculator_form.html
index 2c2b51dd..f64a9500 100644
--- a/datacenterlight/templates/datacenterlight/includes/_calculator_form.html
+++ b/datacenterlight/templates/datacenterlight/includes/_calculator_form.html
@@ -9,7 +9,6 @@
window.ssdUnitPrice = {{vm_pricing.ssd_unit_price|default:0}};
window.hddUnitPrice = {{vm_pricing.hdd_unit_price|default:0}};
window.discountAmount = {{vm_pricing.discount_amount|default:0}};
- window.vmBasePrice = {{vm_base_price|default:0}};
window.minRam = {{min_ram}};
window.minRamErr = '{% blocktrans with min_ram=min_ram %}Please enter a value in range {{min_ram}} - 200.{% endblocktrans %}';
diff --git a/datacenterlight/templates/datacenterlight/order_detail.html b/datacenterlight/templates/datacenterlight/order_detail.html
index 1f7a3cda..02bce0ed 100644
--- a/datacenterlight/templates/datacenterlight/order_detail.html
+++ b/datacenterlight/templates/datacenterlight/order_detail.html
@@ -2,14 +2,6 @@
{% load staticfiles bootstrap3 i18n custom_tags humanize %}
{% block content %}
-
{% if messages %}
@@ -111,61 +103,58 @@
{% endif %}
- {% if generic_payment_details.exclude_vat_calculations %}
- {% else %}
-
-
+
+
+
+
+
+ {% trans "Price Before VAT" %}
+ {{generic_payment_details.amount_before_vat|floatformat:2|intcomma}} CHF
+
+
+
+
+
+
+
+
+
+
+
+
{% trans "Pre VAT" %}
+
+
+
{% trans "VAT for" %} {{generic_payment_details.vat_country}} ({{generic_payment_details.vat_rate}}%)
+
-
-
- {% trans "Price Before VAT" %}
- {{generic_payment_details.amount_before_vat|floatformat:2|intcomma}} CHF
-
@@ -278,16 +267,15 @@
{% if generic_payment_details %}
{% if generic_payment_details.recurring %}
{% if generic_payment_details.recurring_interval == 'year' %}
-
{% blocktrans with total_price=generic_payment_details.amount|floatformat:2|intcomma %} By clicking "Place order" you agree to our Terms of Service and this plan will charge your credit card account with {{ total_price }} CHF/year{% endblocktrans %}.
+
{% blocktrans with total_price=generic_payment_details.amount|floatformat:2|intcomma %}By clicking "Place order" this plan will charge your credit card account with {{total_price}} CHF/year{% endblocktrans %}.
{% else %}
-
{% blocktrans with total_price=generic_payment_details.amount|floatformat:2|intcomma %}
- By clicking "Place order" you agree to our Terms of Service and this plan will charge your credit card account with {{ total_price }} CHF/month{% endblocktrans %}.
+
{% blocktrans with total_price=generic_payment_details.amount|floatformat:2|intcomma %}By clicking "Place order" this plan will charge your credit card account with {{total_price}} CHF/month{% endblocktrans %}.
{% endif %}
{% else %}
-
{% blocktrans with total_price=generic_payment_details.amount|floatformat:2|intcomma %}By clicking "Place order" you agree to our Terms of Service and this plan will charge your credit card account with {{ total_price }} CHF{% endblocktrans %}.
+
{% blocktrans with total_price=generic_payment_details.amount|floatformat:2|intcomma %}By clicking "Place order" this payment will charge your credit card account with a one time amount of {{total_price}} CHF{% endblocktrans %}.
{% endif %}
{% else %}
-
{% blocktrans with vm_total_price=vm.total_price|floatformat:2|intcomma %}By clicking "Place order" you agree to our Terms of Service and this plan will charge your credit card account with {{ vm_total_price }} CHF/month{% endblocktrans %}.
+
{% blocktrans with vm_total_price=vm.total_price|floatformat:2|intcomma %}By clicking "Place order" this plan will charge your credit card account with {{vm_total_price}} CHF/month{% endblocktrans %}.
{% endif %}
@@ -330,14 +318,5 @@
{%endblock%}
diff --git a/datacenterlight/templatetags/custom_tags.py b/datacenterlight/templatetags/custom_tags.py
index 120cabbf..0cb18e5b 100644
--- a/datacenterlight/templatetags/custom_tags.py
+++ b/datacenterlight/templatetags/custom_tags.py
@@ -6,7 +6,7 @@ from django.core.urlresolvers import resolve, reverse
from django.utils.safestring import mark_safe
from django.utils.translation import activate, get_language, ugettext_lazy as _
-from hosting.models import GenericProduct, HostingOrder
+from hosting.models import GenericProduct
from utils.hosting_utils import get_ip_addresses
logger = logging.getLogger(__name__)
@@ -63,41 +63,6 @@ def escaped_line_break(value):
return value.replace("\\n", "\n")
-@register.filter('get_line_item_from_hosting_order_charge')
-def get_line_item_from_hosting_order_charge(hosting_order_id):
- """
- Returns ready-to-use "html" line item to be shown for a charge in the
- invoice list page
-
- :param hosting_order_id: the HostingOrder id
- :return:
- """
- try:
- hosting_order = HostingOrder.objects.get(id = hosting_order_id)
- if hosting_order.stripe_charge_id:
- return mark_safe("""
-
{% blocktrans with vm_price=vm.total_price|floatformat:2|intcomma %}By clicking "Place order" you agree to our Terms of Service and this plan will charge your credit card account with {{ vm_price }} CHF/month.{% endblocktrans %}.
+
{% blocktrans with vm_price=vm.total_price|floatformat:2|intcomma %}By clicking "Place order" this plan will charge your credit card account with {{ vm_price }} CHF/month{% endblocktrans %}.