From 00b434efb9a5f21e38501b58826624491e755b61 Mon Sep 17 00:00:00 2001 From: PCoder Date: Mon, 3 Feb 2020 11:37:30 +0530 Subject: [PATCH 1/9] Read VM_BASE_PRICE from env --- dynamicweb/settings/base.py | 1 + utils/hosting_utils.py | 5 ++++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/dynamicweb/settings/base.py b/dynamicweb/settings/base.py index c959c237..743d11c3 100644 --- a/dynamicweb/settings/base.py +++ b/dynamicweb/settings/base.py @@ -761,6 +761,7 @@ OTP_VERIFY_ENDPOINT = env('OTP_VERIFY_ENDPOINT') FIRST_VM_ID_AFTER_EU_VAT = int_env('FIRST_VM_ID_AFTER_EU_VAT') PRE_EU_VAT_RATE = float(env('PRE_EU_VAT_RATE')) +VM_BASE_PRICE = float(env('VM_BASE_PRICE')) if DEBUG: from .local import * # flake8: noqa diff --git a/utils/hosting_utils.py b/utils/hosting_utils.py index 7bff9a89..2c325364 100644 --- a/utils/hosting_utils.py +++ b/utils/hosting_utils.py @@ -3,6 +3,8 @@ import logging import math import subprocess +from django.conf import settings + from oca.pool import WrongIdError from datacenterlight.models import VMPricing @@ -154,7 +156,8 @@ def get_vm_price_with_vat(cpu, memory, ssd_size, hdd_size=0, (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) + (decimal.Decimal(hdd_size) * pricing.hdd_unit_price) + + decimal.Decimal(settings.VM_BASE_PRICE) ) if pricing.vat_inclusive: vat = decimal.Decimal(0) From e6de90e431a4486dd4c4006e46a80ba27902b2ad Mon Sep 17 00:00:00 2001 From: PCoder Date: Mon, 3 Feb 2020 12:07:50 +0530 Subject: [PATCH 2/9] Set vm base price in js also --- datacenterlight/cms_plugins.py | 2 ++ datacenterlight/static/datacenterlight/js/main.js | 4 ++-- datacenterlight/templates/datacenterlight/cms/calculator.html | 2 +- .../templates/datacenterlight/includes/_calculator_form.html | 1 + hosting/static/hosting/js/initial.js | 4 ++-- 5 files changed, 8 insertions(+), 5 deletions(-) diff --git a/datacenterlight/cms_plugins.py b/datacenterlight/cms_plugins.py index c3ec974f..52b4f19f 100644 --- a/datacenterlight/cms_plugins.py +++ b/datacenterlight/cms_plugins.py @@ -1,5 +1,6 @@ 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, @@ -100,6 +101,7 @@ 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/static/datacenterlight/js/main.js b/datacenterlight/static/datacenterlight/js/main.js index 8fea438a..c6869cda 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.discountAmount; + (cardPricing['storage'].value * window.ssdUnitPrice) + + window.vmBasePrice - window.discountAmount; total = parseFloat(total.toFixed(2)); $("#total").text(total); } diff --git a/datacenterlight/templates/datacenterlight/cms/calculator.html b/datacenterlight/templates/datacenterlight/cms/calculator.html index 7b123a72..20a6664a 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 %} + {% include "datacenterlight/includes/_calculator_form.html" with vm_pricing=instance.pricing vm_base_price=vm_base_price %}
\ No newline at end of file diff --git a/datacenterlight/templates/datacenterlight/includes/_calculator_form.html b/datacenterlight/templates/datacenterlight/includes/_calculator_form.html index f64a9500..2c2b51dd 100644 --- a/datacenterlight/templates/datacenterlight/includes/_calculator_form.html +++ b/datacenterlight/templates/datacenterlight/includes/_calculator_form.html @@ -9,6 +9,7 @@ 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/hosting/static/hosting/js/initial.js b/hosting/static/hosting/js/initial.js index 6b6d744d..36cf6d07 100644 --- a/hosting/static/hosting/js/initial.js +++ b/hosting/static/hosting/js/initial.js @@ -266,8 +266,8 @@ $( document ).ready(function() { } var total = (cardPricing['cpu'].value * window.coresUnitPrice) + (cardPricing['ram'].value * window.ramUnitPrice) + - (cardPricing['storage'].value * window.ssdUnitPrice) - - window.discountAmount; + (cardPricing['storage'].value * window.ssdUnitPrice) + + window.vmBasePrice - window.discountAmount; total = parseFloat(total.toFixed(2)); $("#total").text(total); } From c315030b06fde0d10e237d45f3f62fe7d785085c Mon Sep 17 00:00:00 2001 From: PCoder Date: Mon, 3 Feb 2020 12:29:14 +0530 Subject: [PATCH 3/9] Add vm base price to missing places --- utils/hosting_utils.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/utils/hosting_utils.py b/utils/hosting_utils.py index 2c325364..2ad3d335 100644 --- a/utils/hosting_utils.py +++ b/utils/hosting_utils.py @@ -81,7 +81,8 @@ def get_vm_price(cpu, memory, disk_size, hdd_size=0, pricing_name='default'): price = ((decimal.Decimal(cpu) * pricing.cores_unit_price) + (decimal.Decimal(memory) * pricing.ram_unit_price) + (decimal.Decimal(disk_size) * pricing.ssd_unit_price) + - (decimal.Decimal(hdd_size) * pricing.hdd_unit_price)) + (decimal.Decimal(hdd_size) * pricing.hdd_unit_price) + + decimal.Decimal(settings.VM_BASE_PRICE)) cents = decimal.Decimal('.01') price = price.quantize(cents, decimal.ROUND_HALF_UP) return round(float(price), 2) @@ -104,7 +105,8 @@ def get_vm_price_for_given_vat(cpu, memory, ssd_size, hdd_size=0, (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) + (decimal.Decimal(hdd_size) * pricing.hdd_unit_price) + + decimal.Decimal(settings.VM_BASE_PRICE) ) discount_name = pricing.discount_name From 3ca1a4521738708312910d3c7aadaf6add89c1fc Mon Sep 17 00:00:00 2001 From: PCoder Date: Tue, 4 Feb 2020 08:57:54 +0530 Subject: [PATCH 4/9] Add stripe_coupon_id to VMPricing --- .../0031_vmpricing_stripe_coupon_id.py | 20 +++++++++++++++++++ datacenterlight/models.py | 1 + 2 files changed, 21 insertions(+) create mode 100644 datacenterlight/migrations/0031_vmpricing_stripe_coupon_id.py diff --git a/datacenterlight/migrations/0031_vmpricing_stripe_coupon_id.py b/datacenterlight/migrations/0031_vmpricing_stripe_coupon_id.py new file mode 100644 index 00000000..d2e45871 --- /dev/null +++ b/datacenterlight/migrations/0031_vmpricing_stripe_coupon_id.py @@ -0,0 +1,20 @@ +# -*- 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 6410254b..64d785a2 100644 --- a/datacenterlight/models.py +++ b/datacenterlight/models.py @@ -54,6 +54,7 @@ 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([ From e322e58246dc9889e9146e51958b4c7cc46b2231 Mon Sep 17 00:00:00 2001 From: PCoder Date: Tue, 4 Feb 2020 09:06:10 +0530 Subject: [PATCH 5/9] Use appropriate stripe_coupon_id --- datacenterlight/views.py | 10 +++++----- hosting/views.py | 6 +++++- utils/hosting_utils.py | 6 ++++-- 3 files changed, 14 insertions(+), 8 deletions(-) diff --git a/datacenterlight/views.py b/datacenterlight/views.py index 185b3e29..3a720cdc 100644 --- a/datacenterlight/views.py +++ b/datacenterlight/views.py @@ -933,11 +933,11 @@ class OrderConfirmationView(DetailView, FormView): subscription_result = stripe_utils.subscribe_customer_to_plan( stripe_api_cus_id, [{"plan": stripe_plan.get('response_object').stripe_plan_id}], - coupon='ipv6-discount-8chf' if ( - 'name' in discount and - discount['name'] is not None and - 'ipv6' in discount['name'].lower() - ) else "", + coupon=(discount['stripe_coupon_id'] + if 'name' in discount and + 'ipv6' in discount['name'].lower() and + discount['stripe_coupon_id'] + else ""), tax_rates=[stripe_tax_rate.tax_rate_id] if stripe_tax_rate else [], ) stripe_subscription_obj = subscription_result.get('response_object') diff --git a/hosting/views.py b/hosting/views.py index 729d115b..17af51fd 100644 --- a/hosting/views.py +++ b/hosting/views.py @@ -1185,7 +1185,11 @@ class OrdersHostingDetailView(LoginRequiredMixin, DetailView, FormView): subscription_result = stripe_utils.subscribe_customer_to_plan( stripe_api_cus_id, [{"plan": stripe_plan.get('response_object').stripe_plan_id}], - coupon='ipv6-discount-8chf' if 'name' in discount and 'ipv6' in discount['name'].lower() else "", + coupon=(discount['stripe_coupon_id'] + if 'name' in discount and + 'ipv6' in discount['name'].lower() and + discount['stripe_coupon_id'] + else ""), tax_rates=[stripe_tax_rate.tax_rate_id] if stripe_tax_rate else [], ) stripe_subscription_obj = subscription_result.get('response_object') diff --git a/utils/hosting_utils.py b/utils/hosting_utils.py index 2ad3d335..aebbf717 100644 --- a/utils/hosting_utils.py +++ b/utils/hosting_utils.py @@ -122,7 +122,8 @@ def get_vm_price_for_given_vat(cpu, memory, ssd_size, hdd_size=0, discount = { 'name': discount_name, 'amount': discount_amount, - 'amount_with_vat': round(float(discount_amount_with_vat), 2) + 'amount_with_vat': round(float(discount_amount_with_vat), 2), + 'stripe_coupon_id': pricing.stripe_coupon_id } return (round(float(price), 2), round(float(vat), 2), round(float(vat_percent), 2), discount) @@ -173,7 +174,8 @@ def get_vm_price_with_vat(cpu, memory, ssd_size, hdd_size=0, vat = vat.quantize(cents, decimal.ROUND_HALF_UP) discount = { 'name': pricing.discount_name, - 'amount': round(float(pricing.discount_amount), 2) + 'amount': round(float(pricing.discount_amount), 2), + 'stripe_coupon_id': pricing.stripe_coupon_id } return (round(float(price), 2), round(float(vat), 2), round(float(vat_percent), 2), discount) From dd2eae68e6a1b989599beea3906d8dc489fdb1a6 Mon Sep 17 00:00:00 2001 From: PCoder Date: Tue, 4 Feb 2020 11:20:17 +0530 Subject: [PATCH 6/9] Use math round to round amount to 2 decimal places --- datacenterlight/views.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/datacenterlight/views.py b/datacenterlight/views.py index 3a720cdc..abd17964 100644 --- a/datacenterlight/views.py +++ b/datacenterlight/views.py @@ -678,9 +678,9 @@ class OrderConfirmationView(DetailView, FormView): vm_specs["vat_percent"] = vat_percent vm_specs["vat_validation_status"] = request.session["vat_validation_status"] if "vat_validation_status" in request.session else "" vm_specs["vat_country"] = user_vat_country - vm_specs["price_with_vat"] = round_up(price * (1 + vm_specs["vat_percent"] * 0.01), 2) - vm_specs["price_after_discount"] = round_up(price - discount['amount'], 2) - vm_specs["price_after_discount_with_vat"] = round_up((price - discount['amount']) * (1 + vm_specs["vat_percent"] * 0.01), 2) + vm_specs["price_with_vat"] = round(price * (1 + vm_specs["vat_percent"] * 0.01), 2) + vm_specs["price_after_discount"] = round(price - discount['amount'], 2) + vm_specs["price_after_discount_with_vat"] = round((price - discount['amount']) * (1 + vm_specs["vat_percent"] * 0.01), 2) discount["amount_with_vat"] = round(vm_specs["price_with_vat"] - vm_specs["price_after_discount_with_vat"], 2) vm_specs["total_price"] = vm_specs["price_after_discount_with_vat"] vm_specs["discount"] = discount From f45f8dd51f1349243178a21e65688f1241eda305 Mon Sep 17 00:00:00 2001 From: PCoder Date: Tue, 4 Feb 2020 11:27:59 +0530 Subject: [PATCH 7/9] Remove unused method round_up --- utils/hosting_utils.py | 5 ----- 1 file changed, 5 deletions(-) diff --git a/utils/hosting_utils.py b/utils/hosting_utils.py index aebbf717..b9e2eb8a 100644 --- a/utils/hosting_utils.py +++ b/utils/hosting_utils.py @@ -222,11 +222,6 @@ def get_ip_addresses(vm_id): return "--" -def round_up(n, decimals=0): - multiplier = 10 ** decimals - return math.ceil(n * multiplier) / multiplier - - class HostingUtils: @staticmethod def clear_items_from_list(from_list, items_list): From c05813804489cdb5bc73c96aa9564495990d4f2d Mon Sep 17 00:00:00 2001 From: PCoder Date: Tue, 4 Feb 2020 17:07:14 +0530 Subject: [PATCH 8/9] Update Changelog for 2.10.2 --- Changelog | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/Changelog b/Changelog index e636bc66..df611d74 100644 --- a/Changelog +++ b/Changelog @@ -1,4 +1,11 @@ -2.10.1: 2020-02-02: +2.10.2: 2020-02-04 + * 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.1: 2020-02-02 * Changes the pricing structure of generic products into the pre vat and with vat (like that for VM) * Shows product name (if exists) in the invoices list if it belongs to a generic product * Small bugfixes (right alignment of price in the invoice list, show prices with 2 decimal places etc) From 9d96ecefeadbfc6728383a08f50cbae30e07f0b3 Mon Sep 17 00:00:00 2001 From: PCoder Date: Wed, 18 Mar 2020 12:44:18 +0530 Subject: [PATCH 9/9] Remove unwanted import --- datacenterlight/views.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/datacenterlight/views.py b/datacenterlight/views.py index 2a55b96f..233edb20 100644 --- a/datacenterlight/views.py +++ b/datacenterlight/views.py @@ -29,7 +29,7 @@ from utils.forms import ( ) from utils.hosting_utils import ( get_vm_price_with_vat, get_all_public_keys, get_vat_rate_for_country, - get_vm_price_for_given_vat, round_up + get_vm_price_for_given_vat ) from utils.stripe_utils import StripeUtils from utils.tasks import send_plain_email_task