diff --git a/datacenterlight/locale/de/LC_MESSAGES/django.po b/datacenterlight/locale/de/LC_MESSAGES/django.po index 50dbfbe8..a092641d 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: 2018-04-17 19:26+0000\n" +"POT-Creation-Date: 2018-05-12 03:46+0530\n" "PO-Revision-Date: 2018-03-30 23:22+0000\n" "Last-Translator: b'Anonymous User '\n" "Language-Team: LANGUAGE \n" @@ -19,6 +19,9 @@ msgstr "" "Plural-Forms: nplurals=2; plural=(n != 1);\n" "X-Translated-Using: django-rosetta 0.8.1\n" +msgid "CMS Favicon" +msgstr "" + #, python-format msgid "Your New VM %(vm_name)s at Data Center Light" msgstr "Deine neue VM %(vm_name)s bei Data Center Light" @@ -314,6 +317,12 @@ msgstr "exkl. Mehrwertsteuer" msgid "Month" msgstr "Monat" +msgid "Discount" +msgstr "Rabatt" + +msgid "Will be applied at checkout" +msgstr "wird an der Kasse angewendet" + msgid "Credit Card" msgstr "Kreditkarte" @@ -386,9 +395,10 @@ msgstr "Zwischensumme" msgid "VAT" msgstr "Mehrwertsteuer" +#, python-format msgid "" "By clicking \"Place order\" this plan will charge your credit card account " -"with the fee of %(vm_total_price)s CHF/month" +"with %(vm_total_price)s CHF/month" msgstr "" "Wenn Du \"bestellen\" auswählst, wird Deine Kreditkarte mit " "%(vm_total_price)s CHF pro Monat belastet" diff --git a/datacenterlight/migrations/0022_auto_20180506_1950.py b/datacenterlight/migrations/0022_auto_20180506_1950.py new file mode 100644 index 00000000..a5554a58 --- /dev/null +++ b/datacenterlight/migrations/0022_auto_20180506_1950.py @@ -0,0 +1,26 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.9.4 on 2018-05-07 02:19 +from __future__ import unicode_literals + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('datacenterlight', '0021_cmsintegration_calculator_placeholder'), + ] + + operations = [ + migrations.AddField( + model_name='vmpricing', + name='discount_amount', + field=models.DecimalField( + decimal_places=2, default=0, max_digits=6), + ), + migrations.AddField( + model_name='vmpricing', + name='discount_name', + field=models.CharField(blank=True, max_length=255, null=True), + ), + ] diff --git a/datacenterlight/models.py b/datacenterlight/models.py index eceb7617..ff7eeb8d 100644 --- a/datacenterlight/models.py +++ b/datacenterlight/models.py @@ -34,16 +34,29 @@ class VMPricing(models.Model): hdd_unit_price = models.DecimalField( max_digits=7, decimal_places=6, default=0 ) + discount_name = models.CharField(max_length=255, null=True, blank=True) + discount_amount = models.DecimalField( + max_digits=6, decimal_places=2, default=0 + ) def __str__(self): - return self.name + ' => ' + ' - '.join([ + display_str = self.name + ' => ' + ' - '.join([ '{}/Core'.format(self.cores_unit_price.normalize()), '{}/GB RAM'.format(self.ram_unit_price.normalize()), '{}/GB SSD'.format(self.ssd_unit_price.normalize()), '{}/GB HDD'.format(self.hdd_unit_price.normalize()), '{}% VAT'.format(self.vat_percentage.normalize()) - if not self.vat_inclusive else 'VAT-Incl', ] - ) + if not self.vat_inclusive else 'VAT-Incl', + ]) + if self.discount_amount: + display_str = ' - '.join([ + display_str, + '{} {}'.format( + self.discount_amount, + self.discount_name if self.discount_name else 'Discount' + ) + ]) + return display_str @classmethod def get_vm_pricing_by_name(cls, name): diff --git a/datacenterlight/static/datacenterlight/css/common.css b/datacenterlight/static/datacenterlight/css/common.css index 895256ef..b6eabd75 100644 --- a/datacenterlight/static/datacenterlight/css/common.css +++ b/datacenterlight/static/datacenterlight/css/common.css @@ -150,3 +150,12 @@ footer .dcl-link-separator::before { border-radius: 100%; background: #777; } + +.mb-0 { + margin-bottom: 0; +} + +.thin-hr { + margin-top: 10px; + margin-bottom: 10px; +} \ No newline at end of file diff --git a/datacenterlight/static/datacenterlight/css/hosting.css b/datacenterlight/static/datacenterlight/css/hosting.css index b4c5909c..0f16ab77 100644 --- a/datacenterlight/static/datacenterlight/css/hosting.css +++ b/datacenterlight/static/datacenterlight/css/hosting.css @@ -482,6 +482,7 @@ margin: 100px auto 40px; border: 1px solid #ccc; padding: 30px 30px 20px; + color: #595959; } .order-detail-container .dashboard-title-thin { @@ -503,10 +504,6 @@ margin-bottom: 15px; } -.order-detail-container .order-details strong { - color: #595959; -} - .order-detail-container h4 { font-size: 16px; font-weight: bold; @@ -515,13 +512,28 @@ .order-detail-container p { margin-bottom: 5px; - color: #595959; } .order-detail-container hr { margin: 15px 0; } +.order-detail-container .thin-hr { + margin: 10px 0; +} + +.order-detail-container .subtotal-price { + font-size: 16px; +} + +.order-detail-container .subtotal-price .text-primary { + font-size: 17px; +} + +.order-detail-container .total-price { + font-size: 18px; +} + @media (max-width: 767px) { .order-detail-container { padding: 15px; diff --git a/datacenterlight/static/datacenterlight/js/main.js b/datacenterlight/static/datacenterlight/js/main.js index f6ba036b..292e8c16 100644 --- a/datacenterlight/static/datacenterlight/js/main.js +++ b/datacenterlight/static/datacenterlight/js/main.js @@ -180,9 +180,13 @@ if(typeof window.ssdUnitPrice === 'undefined'){ window.ssdUnitPrice = 0.6; } + if(typeof window.discountAmount === 'undefined'){ + window.discountAmount = 0; + } var total = (cardPricing['cpu'].value * window.coresUnitPrice) + (cardPricing['ram'].value * window.ramUnitPrice) + - (cardPricing['storage'].value * window.ssdUnitPrice); + (cardPricing['storage'].value * window.ssdUnitPrice) - + window.discountAmount; total = parseFloat(total.toFixed(2)); $("#total").text(total); } diff --git a/datacenterlight/templates/datacenterlight/includes/_calculator_form.html b/datacenterlight/templates/datacenterlight/includes/_calculator_form.html index 8335c7ec..4b4aa04f 100644 --- a/datacenterlight/templates/datacenterlight/includes/_calculator_form.html +++ b/datacenterlight/templates/datacenterlight/includes/_calculator_form.html @@ -8,6 +8,7 @@ window.ramUnitPrice = {{vm_pricing.ram_unit_price|default:0}}; 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}}; {% endif %} @@ -19,11 +20,14 @@
CHF/{% trans "month" %} - {% if vm_pricing.vat_inclusive %}
-

{% trans "VAT included" %}

+

+ {% if vm_pricing.vat_inclusive %}{% trans "VAT included" %}
{% endif %} + {% if vm_pricing.discount_amount %} + You save {{ vm_pricing.discount_amount }} CHF + {% endif %} +

- {% endif %}
diff --git a/datacenterlight/templates/datacenterlight/landing_payment.html b/datacenterlight/templates/datacenterlight/landing_payment.html index b808e033..4d111fa1 100644 --- a/datacenterlight/templates/datacenterlight/landing_payment.html +++ b/datacenterlight/templates/datacenterlight/landing_payment.html @@ -78,7 +78,24 @@

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


-

{%trans "Total" %}  ({% if vm_pricing.vat_inclusive %}{%trans "including VAT" %}{% else %}{%trans "excluding VAT" %}{% endif %}) {{request.session.specs.price|intcomma}} CHF/{% trans "Month" %}

+

+ {%trans "Total" %}   + + ({% if vm_pricing.vat_inclusive %}{%trans "including VAT" %}{% else %}{%trans "excluding VAT" %}{% endif %}) + + {{request.session.specs.price|intcomma}} CHF/{% trans "Month" %} +

+
+ {% if vm_pricing.discount_amount %} +

+ {%trans "Discount" as discount_name %} + {{ vm_pricing.discount_name|default:discount_name }}   + - {{ vm_pricing.discount_amount }} CHF/{% trans "Month" %} +

+

+ ({% trans "Will be applied at checkout" %}) +

+ {% endif %}
diff --git a/datacenterlight/templates/datacenterlight/order_detail.html b/datacenterlight/templates/datacenterlight/order_detail.html index 95bfa3c6..8480e132 100644 --- a/datacenterlight/templates/datacenterlight/order_detail.html +++ b/datacenterlight/templates/datacenterlight/order_detail.html @@ -55,40 +55,53 @@

{% trans "Cores" %}: - {{vm.cpu|floatformat}} + {{vm.cpu|floatformat}}

{% trans "Memory" %}: - {{vm.memory|intcomma}} GB + {{vm.memory|intcomma}} GB

{% trans "Disk space" %}: - {{vm.disk_size|intcomma}} GB + {{vm.disk_size|intcomma}} GB

- {% if vm.vat > 0 %} -

- {% trans "Subtotal" %}: - {{vm.price|floatformat:2|intcomma}} CHF -

-

- {% trans "VAT" %} ({{ vm.vat_percent|floatformat:2|intcomma }}%): - {{vm.vat|floatformat:2|intcomma}} CHF -

+
+ {% if vm.vat > 0 or vm.discount.amount > 0 %} +
+ {% if vm.vat > 0 %} +

+ {% trans "Subtotal" %} + {{vm.price|floatformat:2|intcomma}} CHF +

+

+ {% trans "VAT" %} ({{ vm.vat_percent|floatformat:2|intcomma }}%) + {{vm.vat|floatformat:2|intcomma}} CHF +

+ {% endif %} + {% if vm.discount.amount > 0 %} +

+ {%trans "Discount" as discount_name %} + {{ vm.discount.name|default:discount_name }} + - {{ vm.discount.amount }} CHF +

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

- {% trans "Total" %} - {{vm.total_price|floatformat:2|intcomma}} CHF +

+ {% trans "Total" %} + {{vm.total_price|floatformat:2|intcomma}} CHF

-
+
{% csrf_token %}
-
{% blocktrans with vm_total_price=vm.total_price|floatformat:2|intcomma %}By clicking "Place order" this plan will charge your credit card account with the fee of {{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 %}.
-
+
{% if not order %} {% block submit_btn %} @@ -152,7 +165,7 @@ {% csrf_token %}
-
{% blocktrans with vm_price=request.session.specs.price %}By clicking "Place order" this plan will charge your credit card account with the fee of {{ vm_price|intcomma }}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 %}.
-
- {% else %} -
- -
-
-
- -
-
-
-
- -
-
-
- -
-
-
-
- - -
-
-
-
- {% if not messages and not form.non_field_errors %} -

- {% trans "You are not making any payment yet. After submitting your card information, you will be taken to the Confirm Order Page." %} + {% endif %} +

+ {% for message in messages %} + {% if 'failed_payment' or 'make_charge_error' in message.tags %} +
    +
  • +

    {{ message|safe }}

    +
  • +
+ {% endif %} + {% endfor %} + {% for error in form.non_field_errors %} +

+ {{ error|escape }}

- {% endif %} -
- {% for message in messages %} - {% if 'failed_payment' or 'make_charge_error' in message.tags %} -
    -
  • -

    {{ message|safe }}

    -
  • -
- {% endif %} - {% endfor %} - - {% for error in form.non_field_errors %} -

- {{ error|escape }} + {% endfor %} +

+
+ +
+ {% else %} + + +
+
+
+ +
+
+
+
+ +
+
+
+ +
+
+
+
+ + +
+
+
+
+ {% if not messages and not form.non_field_errors %} +

+ {% trans "You are not making any payment yet. After submitting your card information, you will be taken to the Confirm Order Page." %}

- {% endfor %} -
-
- -
-
+ {% endif %} +
+ {% for message in messages %} + {% if 'failed_payment' or 'make_charge_error' in message.tags %} +
    +
  • +

    {{ message|safe }}

    +
  • +
+ {% endif %} + {% endfor %} -
-

-
- - {% endif %} + {% for error in form.non_field_errors %} +

+ {{ error|escape }} +

+ {% endfor %} +
+
+ +
+ + +
+

+
+ + {% endif %} + diff --git a/hosting/views.py b/hosting/views.py index 495efd5c..8a4defda 100644 --- a/hosting/views.py +++ b/hosting/views.py @@ -652,7 +652,10 @@ class PaymentVMView(LoginRequiredMixin, FormView): }) context.update({ - 'stripe_key': settings.STRIPE_API_PUBLIC_KEY + 'stripe_key': settings.STRIPE_API_PUBLIC_KEY, + 'vm_pricing': VMPricing.get_vm_pricing_by_name( + self.request.session.get('specs', {}).get('pricing_name') + ), }) return context @@ -750,7 +753,7 @@ class OrdersHostingDetailView(LoginRequiredMixin, DetailView): context['vm'] = vm_detail.__dict__ context['vm']['name'] = '{}-{}'.format( context['vm']['configuration'], context['vm']['vm_id']) - price, vat, vat_percent = get_vm_price_with_vat( + price, vat, vat_percent, discount = get_vm_price_with_vat( cpu=context['vm']['cores'], ssd_size=context['vm']['disk_size'], memory=context['vm']['memory'], @@ -759,8 +762,9 @@ class OrdersHostingDetailView(LoginRequiredMixin, DetailView): ) context['vm']['vat'] = vat context['vm']['price'] = price + context['vm']['discount'] = discount context['vm']['vat_percent'] = vat_percent - context['vm']['total_price'] = price + vat + context['vm']['total_price'] = price + vat - discount['amount'] context['subscription_end_date'] = vm_detail.end_date() except VMDetail.DoesNotExist: try: @@ -769,7 +773,7 @@ class OrdersHostingDetailView(LoginRequiredMixin, DetailView): ) vm = manager.get_vm(obj.vm_id) context['vm'] = VirtualMachineSerializer(vm).data - price, vat, vat_percent = get_vm_price_with_vat( + price, vat, vat_percent, discount = get_vm_price_with_vat( cpu=context['vm']['cores'], ssd_size=context['vm']['disk_size'], memory=context['vm']['memory'], @@ -778,8 +782,10 @@ class OrdersHostingDetailView(LoginRequiredMixin, DetailView): ) context['vm']['vat'] = vat context['vm']['price'] = price + context['vm']['discount'] = discount context['vm']['vat_percent'] = vat_percent - context['vm']['total_price'] = price + vat + context['vm']['total_price'] = price + \ + vat - discount['amount'] except WrongIdError: messages.error( self.request, @@ -1004,7 +1010,6 @@ class CreateVirtualMachinesView(LoginRequiredMixin, View): @method_decorator(decorators) def get(self, request, *args, **kwargs): - print(get_cms_integration('default')) context = { 'templates': VMTemplate.objects.all(), 'cms_integration': get_cms_integration('default'), @@ -1065,7 +1070,7 @@ class CreateVirtualMachinesView(LoginRequiredMixin, View): extra_tags='storage') return redirect(CreateVirtualMachinesView.as_view()) - price, vat, vat_percent = get_vm_price_with_vat( + price, vat, vat_percent, discount = get_vm_price_with_vat( cpu=cores, memory=memory, ssd_size=storage, @@ -1076,10 +1081,11 @@ class CreateVirtualMachinesView(LoginRequiredMixin, View): 'cpu': cores, 'memory': memory, 'disk_size': storage, + 'discount': discount, 'price': price, 'vat': vat, 'vat_percent': vat_percent, - 'total_price': price + vat, + 'total_price': price + vat - discount['amount'], 'pricing_name': vm_pricing_name } diff --git a/utils/hosting_utils.py b/utils/hosting_utils.py index 04ed658a..36964867 100644 --- a/utils/hosting_utils.py +++ b/utils/hosting_utils.py @@ -107,10 +107,12 @@ def get_vm_price_with_vat(cpu, memory, ssd_size, hdd_size=0, ) return None - price = ((decimal.Decimal(cpu) * pricing.cores_unit_price) + - (decimal.Decimal(memory) * pricing.ram_unit_price) + - (decimal.Decimal(ssd_size) * pricing.ssd_unit_price) + - (decimal.Decimal(hdd_size) * pricing.hdd_unit_price)) + price = ( + (decimal.Decimal(cpu) * pricing.cores_unit_price) + + (decimal.Decimal(memory) * pricing.ram_unit_price) + + (decimal.Decimal(ssd_size) * pricing.ssd_unit_price) + + (decimal.Decimal(hdd_size) * pricing.hdd_unit_price) + ) if pricing.vat_inclusive: vat = decimal.Decimal(0) vat_percent = decimal.Decimal(0) @@ -121,4 +123,8 @@ def get_vm_price_with_vat(cpu, memory, ssd_size, hdd_size=0, cents = decimal.Decimal('.01') price = price.quantize(cents, decimal.ROUND_HALF_UP) vat = vat.quantize(cents, decimal.ROUND_HALF_UP) - return float(price), float(vat), float(vat_percent) + discount = { + 'name': pricing.discount_name, + 'amount': float(pricing.discount_amount), + } + return float(price), float(vat), float(vat_percent), discount