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
This commit is contained in:
parent
ef0e3b76fa
commit
484bd53bd2
5 changed files with 60 additions and 61 deletions
|
@ -98,22 +98,26 @@
|
|||
{% if vm.vat > 0 or vm.discount.amount > 0 %}
|
||||
<div class="col-sm-6">
|
||||
<div class="subtotal-price">
|
||||
{% if vm.vat > 0 %}
|
||||
<p>
|
||||
<strong class="text-lg">{% trans "Subtotal" %} </strong>
|
||||
<strong class="pull-right">{{vm.price|floatformat:2|intcomma}} CHF</strong>
|
||||
</p>
|
||||
<p>
|
||||
<small>{% trans "VAT" %} ({{ vm.vat_percent|floatformat:2|intcomma }}%) </small>
|
||||
<strong class="pull-right">{{vm.vat|floatformat:2|intcomma}} CHF</strong>
|
||||
</p>
|
||||
{% endif %}
|
||||
<p>
|
||||
<strong>{% trans "Subtotal" %} </strong>
|
||||
<strong class="pull-right">{{vm.price|floatformat:2|intcomma}} CHF</strong>
|
||||
</p>
|
||||
{% if vm.discount.amount > 0 %}
|
||||
<p class="text-primary">
|
||||
{%trans "Discount" as discount_name %}
|
||||
<strong>{{ vm.discount.name|default:discount_name }} </strong>
|
||||
<strong class="pull-right">- {{ vm.discount.amount }} CHF</strong>
|
||||
</p>
|
||||
<p>
|
||||
<small>{% trans "Subtotal after discount" %}</small>
|
||||
<strong class="pull-right">{{vm.total_after_discount|floatformat:2|intcomma}} CHF</strong>
|
||||
</p>
|
||||
{% endif %}
|
||||
{% if vm.vat > 0 %}
|
||||
<p>
|
||||
<small>{% trans "VAT" %} ({{ vm.vat_percent|floatformat:2|intcomma }}%) </small>
|
||||
<strong class="pull-right">{{vm.vat|floatformat:2|intcomma}} CHF</strong>
|
||||
</p>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -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'))
|
||||
|
|
|
@ -135,22 +135,26 @@
|
|||
{% if vm.vat > 0 or vm.discount.amount > 0 %}
|
||||
<div class="col-sm-6">
|
||||
<div class="subtotal-price">
|
||||
{% if vm.vat > 0 %}
|
||||
<p>
|
||||
<strong>{% trans "Subtotal" %} </strong>
|
||||
<strong class="pull-right">{{vm.price|floatformat:2|intcomma}} CHF</strong>
|
||||
</p>
|
||||
<p>
|
||||
<small>{% trans "VAT" %} ({{ vm.vat_percent|floatformat:2|intcomma }}%) </small>
|
||||
<strong class="pull-right">{{vm.vat|floatformat:2|intcomma}} CHF</strong>
|
||||
</p>
|
||||
{% endif %}
|
||||
<p>
|
||||
<strong>{% trans "Subtotal" %} </strong>
|
||||
<strong class="pull-right">{{vm.price|floatformat:2|intcomma}} CHF</strong>
|
||||
</p>
|
||||
{% if vm.discount.amount > 0 %}
|
||||
<p class="text-primary">
|
||||
{%trans "Discount" as discount_name %}
|
||||
<strong>{{ vm.discount.name|default:discount_name }} </strong>
|
||||
<strong class="pull-right">- {{ vm.discount.amount }} CHF</strong>
|
||||
</p>
|
||||
<p>
|
||||
<small>{% trans "Subtotal after discount" %}</small>
|
||||
<strong class="pull-right">{{vm.total_after_discount|floatformat:2|intcomma}} CHF</strong>
|
||||
</p>
|
||||
{% endif %}
|
||||
{% if vm.vat > 0 %}
|
||||
<p>
|
||||
<small>{% trans "VAT" %} ({{ vm.vat_percent|floatformat:2|intcomma }}%) </small>
|
||||
<strong class="pull-right">{{vm.vat|floatformat:2|intcomma}} CHF</strong>
|
||||
</p>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -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'))
|
||||
|
|
|
@ -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):
|
||||
|
|
Loading…
Reference in a new issue