From 484bd53bd26c87a1733216b7f875d45f34ba2b84 Mon Sep 17 00:00:00 2001 From: PCoder Date: Sat, 12 Jan 2019 11:02:33 +0100 Subject: [PATCH] Fix the way we calculate VAT and final VM price 1. Get the VM's pricing from its config and VMPricing 2. Compute and apply discount if any 3. Apply VAT on the discounted amount from 2 --- .../datacenterlight/order_detail.html | 24 +++++++------ datacenterlight/views.py | 8 ++--- hosting/templates/hosting/order_detail.html | 24 +++++++------ hosting/views.py | 30 ++++------------ utils/hosting_utils.py | 35 ++++++++++++------- 5 files changed, 60 insertions(+), 61 deletions(-) diff --git a/datacenterlight/templates/datacenterlight/order_detail.html b/datacenterlight/templates/datacenterlight/order_detail.html index 31933e12..9fd6c9d5 100644 --- a/datacenterlight/templates/datacenterlight/order_detail.html +++ b/datacenterlight/templates/datacenterlight/order_detail.html @@ -98,22 +98,26 @@ {% 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 %} +

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

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

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

+

+ {% trans "Subtotal after discount" %} + {{vm.total_after_discount|floatformat:2|intcomma}} CHF +

+ {% endif %} + {% if vm.vat > 0 %} +

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

{% endif %}
diff --git a/datacenterlight/views.py b/datacenterlight/views.py index 5dc3a3d3..d6441205 100644 --- a/datacenterlight/views.py +++ b/datacenterlight/views.py @@ -183,7 +183,7 @@ class IndexView(CreateView): ) return HttpResponseRedirect(referer_url + "#order_form") - price, vat, vat_percent, discount = get_vm_price_with_vat( + vm_price_dict = get_vm_price_with_vat( cpu=cores, memory=memory, ssd_size=storage, @@ -193,13 +193,9 @@ class IndexView(CreateView): 'cpu': cores, 'memory': memory, 'disk_size': storage, - 'price': price, - 'vat': vat, - 'vat_percent': vat_percent, - 'discount': discount, - 'total_price': round(price + vat - discount['amount'], 2), 'pricing_name': vm_pricing_name } + specs.update(vm_price_dict) request.session['specs'] = specs request.session['template'] = template_data return HttpResponseRedirect(reverse('datacenterlight:payment')) diff --git a/hosting/templates/hosting/order_detail.html b/hosting/templates/hosting/order_detail.html index 4a62e9fa..5ba8bc3b 100644 --- a/hosting/templates/hosting/order_detail.html +++ b/hosting/templates/hosting/order_detail.html @@ -135,22 +135,26 @@ {% 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 %} +

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

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

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

+

+ {% trans "Subtotal after discount" %} + {{vm.total_after_discount|floatformat:2|intcomma}} CHF +

+ {% endif %} + {% if vm.vat > 0 %} +

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

{% endif %}
diff --git a/hosting/views.py b/hosting/views.py index 32de4e54..eb6ec1a4 100644 --- a/hosting/views.py +++ b/hosting/views.py @@ -878,18 +878,14 @@ class OrdersHostingDetailView(LoginRequiredMixin, DetailView): context['vm'] = vm_detail.__dict__ context['vm']['name'] = '{}-{}'.format( context['vm']['configuration'], context['vm']['vm_id']) - price, vat, vat_percent, discount = get_vm_price_with_vat( + vm_price_dict = get_vm_price_with_vat( cpu=context['vm']['cores'], ssd_size=context['vm']['disk_size'], memory=context['vm']['memory'], pricing_name=(obj.vm_pricing.name if obj.vm_pricing else 'default') ) - context['vm']['vat'] = vat - context['vm']['price'] = price - context['vm']['discount'] = discount - context['vm']['vat_percent'] = vat_percent - context['vm']['total_price'] = price + vat - discount['amount'] + context['vm'] = vm_price_dict context['subscription_end_date'] = vm_detail.end_date() except VMDetail.DoesNotExist: try: @@ -898,20 +894,14 @@ class OrdersHostingDetailView(LoginRequiredMixin, DetailView): ) vm = manager.get_vm(obj.vm_id) context['vm'] = VirtualMachineSerializer(vm).data - price, vat, vat_percent, discount = get_vm_price_with_vat( + vm_price_dict = get_vm_price_with_vat( cpu=context['vm']['cores'], ssd_size=context['vm']['disk_size'], memory=context['vm']['memory'], pricing_name=(obj.vm_pricing.name if obj.vm_pricing else 'default') ) - context['vm']['vat'] = vat - context['vm']['price'] = price - context['vm']['discount'] = discount - context['vm']['vat_percent'] = vat_percent - context['vm']['total_price'] = ( - price + vat - discount['amount'] - ) + context['vm'] = vm_price_dict except WrongIdError: messages.error( self.request, @@ -1290,25 +1280,19 @@ class CreateVirtualMachinesView(LoginRequiredMixin, View): extra_tags='storage') return redirect(CreateVirtualMachinesView.as_view()) - price, vat, vat_percent, discount = get_vm_price_with_vat( + vm_price_dict = get_vm_price_with_vat( cpu=cores, memory=memory, ssd_size=storage, pricing_name=vm_pricing_name ) - specs = { 'cpu': cores, 'memory': memory, 'disk_size': storage, - 'discount': discount, - 'price': price, - 'vat': vat, - 'vat_percent': vat_percent, - 'total_price': round(price + vat - discount['amount'], 2), - 'pricing_name': vm_pricing_name + 'pricing_name': vm_pricing_name, } - + specs.update(vm_price_dict) request.session['specs'] = specs request.session['template'] = template_data return redirect(reverse('hosting:payment')) diff --git a/utils/hosting_utils.py b/utils/hosting_utils.py index ec97a320..b358ebdb 100644 --- a/utils/hosting_utils.py +++ b/utils/hosting_utils.py @@ -95,8 +95,14 @@ def get_vm_price_with_vat(cpu, memory, ssd_size, hdd_size=0, :param ssd_size: Disk space of the VM (SSD) :param hdd_size: The HDD size :param pricing_name: The pricing name to be used - :return: The a tuple containing the price of the VM, the VAT and the - VAT percentage + :return: A dict containing + 1. the price of the VM, + 2. the applied VAT amount + 3. the VAT percentage + 4. the discount (a dict containing the discount name and + the discount amount), + 5. the price after discount + 6. the final price """ try: pricing = VMPricing.objects.get(name=pricing_name) @@ -109,28 +115,33 @@ def get_vm_price_with_vat(cpu, memory, ssd_size, hdd_size=0, ) return None - price = ( + price = decimal.Decimal( (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) ) + discount = { + 'name': pricing.discount_name, + 'amount': round(pricing.discount_amount, 2) + } + price_after_discount = price - discount['amount'] + if pricing.vat_inclusive: vat = decimal.Decimal(0) vat_percent = decimal.Decimal(0) else: - vat = price * pricing.vat_percentage * decimal.Decimal(0.01) + vat = price_after_discount * pricing.vat_percentage * decimal.Decimal(0.01) vat_percent = pricing.vat_percentage - cents = decimal.Decimal('.01') - price = price.quantize(cents, decimal.ROUND_HALF_UP) - vat = vat.quantize(cents, decimal.ROUND_HALF_UP) - discount = { - 'name': pricing.discount_name, - 'amount': round(float(pricing.discount_amount), 2) + return { + 'price': round(price, 2), + 'vat': round(vat, 2), + 'vat_percent': round(vat_percent, 2), + 'discount': discount, + 'price_after_discount': round(price_after_discount, 2), + 'total_price': round(price_after_discount + vat, 2) } - return (round(float(price), 2), round(float(vat), 2), - round(float(vat_percent), 2), discount) def ping_ok(host_ipv6):