diff --git a/datacenterlight/cms_models.py b/datacenterlight/cms_models.py index 7b0e81f4..2d1a98b5 100644 --- a/datacenterlight/cms_models.py +++ b/datacenterlight/cms_models.py @@ -361,3 +361,4 @@ class DCLCalculatorPluginModel(CMSPlugin): help_text="Write the name of the template that you need selected as" " default when the calculator loads" ) + enable_512mb_ram = models.BooleanField(default=False) diff --git a/datacenterlight/cms_plugins.py b/datacenterlight/cms_plugins.py index cac73e8a..c3ec974f 100644 --- a/datacenterlight/cms_plugins.py +++ b/datacenterlight/cms_plugins.py @@ -99,9 +99,8 @@ class DCLCalculatorPlugin(CMSPluginBase): context['templates'] = VMTemplate.objects.filter( vm_type=instance.vm_type ).order_by('name') - context['default_selected_template'] = ( - instance.default_selected_template - ) + context['instance'] = instance + context['min_ram'] = 0.5 if instance.enable_512mb_ram else 1 return context diff --git a/datacenterlight/migrations/0027_dclcalculatorpluginmodel_enable_512mb_ram.py b/datacenterlight/migrations/0027_dclcalculatorpluginmodel_enable_512mb_ram.py new file mode 100644 index 00000000..bd639c9d --- /dev/null +++ b/datacenterlight/migrations/0027_dclcalculatorpluginmodel_enable_512mb_ram.py @@ -0,0 +1,20 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.9.4 on 2018-09-29 05:36 +from __future__ import unicode_literals + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('datacenterlight', '0026_dclcalculatorpluginmodel_default_selected_template'), + ] + + operations = [ + migrations.AddField( + model_name='dclcalculatorpluginmodel', + name='enable_512mb_ram', + field=models.BooleanField(default=False), + ), + ] diff --git a/datacenterlight/static/datacenterlight/js/main.js b/datacenterlight/static/datacenterlight/js/main.js index 292e8c16..65db1d6b 100644 --- a/datacenterlight/static/datacenterlight/js/main.js +++ b/datacenterlight/static/datacenterlight/js/main.js @@ -5,6 +5,10 @@ /* --------------------------------------------- Scripts initialization --------------------------------------------- */ + var minRam = 1; + if(window.minRam){ + minRam = window.minRam; + } var cardPricing = { 'cpu': { 'id': 'coreValue', @@ -16,7 +20,7 @@ 'ram': { 'id': 'ramValue', 'value': 2, - 'min': 1, + 'min': minRam, 'max': 200, 'interval': 1 }, @@ -40,6 +44,7 @@ _initNavUrl(); _initPricing(); ajaxForms(); + $('#ramValue').data('old-value', $('#ramValue').val()); }); $(window).resize(function() { @@ -144,21 +149,54 @@ var data = $(this).data('minus'); if (cardPricing[data].value > cardPricing[data].min) { - cardPricing[data].value = Number(cardPricing[data].value) - cardPricing[data].interval; + if(data === 'ram' && String(cardPricing[data].value) === "1" && minRam === 0.5){ + cardPricing[data].value = 0.5; + $('#ramValue').val('0.5'); + $("#ramValue").attr('step', 0.5); + } else { + cardPricing[data].value = Number(cardPricing[data].value) - cardPricing[data].interval; + } } _fetchPricing(); + $('#ramValue').data('old-value', $('#ramValue').val()); }); $('.fa-plus-circle.right').click(function(event) { var data = $(this).data('plus'); if (cardPricing[data].value < cardPricing[data].max) { - cardPricing[data].value = Number(cardPricing[data].value) + cardPricing[data].interval; + if(data === 'ram' && String(cardPricing[data].value) === "0.5" && minRam === 0.5){ + cardPricing[data].value = 1; + $('#ramValue').val('1'); + $("#ramValue").attr('step', 1); + } else { + cardPricing[data].value = Number(cardPricing[data].value) + cardPricing[data].interval; + } } _fetchPricing(); + $('#ramValue').data('old-value', $('#ramValue').val()); }); $('.input-price').change(function() { var data = $(this).attr("name"); - cardPricing[data].value = $('input[name=' + data + ']').val(); + var input = $('input[name=' + data + ']'); + var inputValue = input.val(); + + if(data === 'ram') { + var ramInput = $('#ramValue'); + if ($('#ramValue').data('old-value') < $('#ramValue').val()) { + if($('#ramValue').val() === '1' && minRam === 0.5) { + $("#ramValue").attr('step', 1); + $('#ramValue').val('1'); + } + } else { + if($('#ramValue').val() === '0' && minRam === 0.5) { + $("#ramValue").attr('step', 0.5); + $('#ramValue').val('0.5'); + } + } + inputValue = $('#ramValue').val(); + $('#ramValue').data('old-value', $('#ramValue').val()); + } + cardPricing[data].value = inputValue; _fetchPricing(); }); } diff --git a/datacenterlight/templates/datacenterlight/includes/_calculator_form.html b/datacenterlight/templates/datacenterlight/includes/_calculator_form.html index 0a35e2ad..f9896f17 100644 --- a/datacenterlight/templates/datacenterlight/includes/_calculator_form.html +++ b/datacenterlight/templates/datacenterlight/includes/_calculator_form.html @@ -9,11 +9,14 @@ 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.minRam = {{min_ram}}; + window.minRamErr = '{% blocktrans with min_ram=min_ram %}Please enter a value in range {{min_ram}} - 200.{% endblocktrans %}'; {% endif %}
{% csrf_token %} +

{% trans "VM hosting" %}

@@ -54,8 +57,8 @@
- + GB RAM
@@ -92,11 +95,11 @@
-
\ No newline at end of file + diff --git a/datacenterlight/views.py b/datacenterlight/views.py index 19faa2d1..445ff7cf 100644 --- a/datacenterlight/views.py +++ b/datacenterlight/views.py @@ -27,6 +27,7 @@ from utils.forms import ( from utils.hosting_utils import get_vm_price_with_vat from utils.stripe_utils import StripeUtils from utils.tasks import send_plain_email_task +from .cms_models import DCLCalculatorPluginModel from .forms import ContactForm from .models import VMTemplate, VMPricing from .utils import get_cms_integration, create_vm, clear_all_session_vars @@ -89,7 +90,29 @@ class IndexView(CreateView): raise ValidationError(_('Invalid number of cores')) def validate_memory(self, value): - if (value > 200) or (value < 1): + if 'pid' in self.request.POST: + try: + plugin = DCLCalculatorPluginModel.objects.get( + id=self.request.POST['pid'] + ) + except DCLCalculatorPluginModel.DoesNotExist as dne: + logger.error( + str(dne) + " plugin_id: " + self.request.POST['pid'] + ) + raise ValidationError(_('Invalid calculator properties')) + if plugin.enable_512mb_ram: + if value % 1 == 0 or value == 0.5: + logger.debug( + "Given ram {value} is either 0.5 or a" + " whole number".format(value=value) + ) + if (value > 200) or (value < 0.5): + raise ValidationError(_('Invalid RAM size')) + else: + raise ValidationError(_('Invalid RAM size')) + elif (value > 200) or (value < 1) or (value % 1 != 0): + raise ValidationError(_('Invalid RAM size')) + else: raise ValidationError(_('Invalid RAM size')) def validate_storage(self, value): @@ -105,7 +128,7 @@ class IndexView(CreateView): cores = request.POST.get('cpu') cores_field = forms.IntegerField(validators=[self.validate_cores]) memory = request.POST.get('ram') - memory_field = forms.IntegerField(validators=[self.validate_memory]) + memory_field = forms.FloatField(validators=[self.validate_memory]) storage = request.POST.get('storage') storage_field = forms.IntegerField(validators=[self.validate_storage]) template_id = int(request.POST.get('config')) @@ -174,7 +197,7 @@ class IndexView(CreateView): 'vat': vat, 'vat_percent': vat_percent, 'discount': discount, - 'total_price': price + vat - discount['amount'], + 'total_price': round(price + vat - discount['amount'], 2), 'pricing_name': vm_pricing_name } request.session['specs'] = specs diff --git a/hosting/static/hosting/js/initial.js b/hosting/static/hosting/js/initial.js index 9c1c226e..6b6d744d 100644 --- a/hosting/static/hosting/js/initial.js +++ b/hosting/static/hosting/js/initial.js @@ -157,6 +157,10 @@ $( document ).ready(function() { /* --------------------------------------------- Scripts initialization --------------------------------------------- */ + var minRam = 1; + if(window.minRam){ + minRam = window.minRam; + } var cardPricing = { 'cpu': { 'id': 'coreValue', @@ -168,7 +172,7 @@ $( document ).ready(function() { 'ram': { 'id': 'ramValue', 'value': 2, - 'min': 1, + 'min': minRam, 'max': 200, 'interval': 1 }, @@ -188,21 +192,54 @@ $( document ).ready(function() { var data = $(this).data('minus'); if (cardPricing[data].value > cardPricing[data].min) { - cardPricing[data].value = Number(cardPricing[data].value) - cardPricing[data].interval; + if(data === 'ram' && String(cardPricing[data].value) === "1" && minRam === 0.5){ + cardPricing[data].value = 0.5; + $('#ramValue').val('0.5'); + $("#ramValue").attr('step', 0.5); + } else { + cardPricing[data].value = Number(cardPricing[data].value) - cardPricing[data].interval; + } } _fetchPricing(); + $('#ramValue').data('old-value', $('#ramValue').val()); }); $('.fa-plus-circle.right').click(function(event) { var data = $(this).data('plus'); if (cardPricing[data].value < cardPricing[data].max) { - cardPricing[data].value = Number(cardPricing[data].value) + cardPricing[data].interval; + if(data === 'ram' && String(cardPricing[data].value) === "0.5" && minRam === 0.5){ + cardPricing[data].value = 1; + $('#ramValue').val('1'); + $("#ramValue").attr('step', 1); + } else { + cardPricing[data].value = Number(cardPricing[data].value) + cardPricing[data].interval; + } } _fetchPricing(); + $('#ramValue').data('old-value', $('#ramValue').val()); }); $('.input-price').change(function() { var data = $(this).attr("name"); - cardPricing[data].value = $('input[name=' + data + ']').val(); + var input = $('input[name=' + data + ']'); + var inputValue = input.val(); + + if(data === 'ram') { + var ramInput = $('#ramValue'); + if ($('#ramValue').data('old-value') < $('#ramValue').val()) { + if($('#ramValue').val() === '1' && minRam === 0.5) { + $("#ramValue").attr('step', 1); + $('#ramValue').val('1'); + } + } else { + if($('#ramValue').val() === '0' && minRam === 0.5) { + $("#ramValue").attr('step', 0.5); + $('#ramValue').val('0.5'); + } + } + inputValue = $('#ramValue').val(); + $('#ramValue').data('old-value', $('#ramValue').val()); + } + cardPricing[data].value = inputValue; _fetchPricing(); }); } @@ -236,4 +273,5 @@ $( document ).ready(function() { } _initPricing(); -}); \ No newline at end of file + $('#ramValue').data('old-value', $('#ramValue').val()); +}); diff --git a/hosting/views.py b/hosting/views.py index c9b7ab08..32de4e54 100644 --- a/hosting/views.py +++ b/hosting/views.py @@ -32,6 +32,7 @@ from stored_messages.api import mark_read from stored_messages.models import Message from stored_messages.settings import stored_messages_settings +from datacenterlight.cms_models import DCLCalculatorPluginModel from datacenterlight.models import VMTemplate, VMPricing from datacenterlight.utils import create_vm, get_cms_integration from hosting.models import UserCardDetail @@ -1198,7 +1199,29 @@ class CreateVirtualMachinesView(LoginRequiredMixin, View): raise ValidationError(_('Invalid number of cores')) def validate_memory(self, value): - if (value > 200) or (value < 1): + if 'pid' in self.request.POST: + try: + plugin = DCLCalculatorPluginModel.objects.get( + id=self.request.POST['pid'] + ) + except DCLCalculatorPluginModel.DoesNotExist as dne: + logger.error( + str(dne) + " plugin_id: " + self.request.POST['pid'] + ) + raise ValidationError(_('Invalid calculator properties')) + if plugin.enable_512mb_ram: + if value % 1 == 0 or value == 0.5: + logger.debug( + "Given ram {value} is either 0.5 or a" + " whole number".format(value=value) + ) + if (value > 200) or (value < 0.5): + raise ValidationError(_('Invalid RAM size')) + else: + raise ValidationError(_('Invalid RAM size')) + elif (value > 200) or (value < 1) or (value % 1 != 0): + raise ValidationError(_('Invalid RAM size')) + else: raise ValidationError(_('Invalid RAM size')) def validate_storage(self, value): @@ -1218,7 +1241,7 @@ class CreateVirtualMachinesView(LoginRequiredMixin, View): cores = request.POST.get('cpu') cores_field = forms.IntegerField(validators=[self.validate_cores]) memory = request.POST.get('ram') - memory_field = forms.IntegerField(validators=[self.validate_memory]) + memory_field = forms.FloatField(validators=[self.validate_memory]) storage = request.POST.get('storage') storage_field = forms.IntegerField(validators=[self.validate_storage]) template_id = int(request.POST.get('config')) @@ -1282,7 +1305,7 @@ class CreateVirtualMachinesView(LoginRequiredMixin, View): 'price': price, 'vat': vat, 'vat_percent': vat_percent, - 'total_price': price + vat - discount['amount'], + 'total_price': round(price + vat - discount['amount'], 2), 'pricing_name': vm_pricing_name } diff --git a/opennebula_api/models.py b/opennebula_api/models.py index 0ce5e8a2..adc39bf0 100644 --- a/opennebula_api/models.py +++ b/opennebula_api/models.py @@ -249,8 +249,8 @@ class OpenNebulaManager(): vm_specs = vm_specs_formatter.format( vcpu=int(specs['cpu']), cpu=0.1 * int(specs['cpu']), - memory=1024 * int(specs['memory']), - + memory=(512 if specs['memory'] == 0.5 else + 1024 * int(specs['memory'])), ) vm_specs += """ fs @@ -269,8 +269,8 @@ class OpenNebulaManager(): vm_specs = vm_specs_formatter.format( vcpu=int(specs['cpu']), cpu=0.1 * int(specs['cpu']), - memory=1024 * int(specs['memory']), - + memory=(512 if specs['memory'] == 0.5 else + 1024 * int(specs['memory'])), ) vm_specs += """ fs