diff --git a/datacenterlight/templates/datacenterlight/order_detail.html b/datacenterlight/templates/datacenterlight/order_detail.html index b7e28e62..5f61ccf3 100644 --- a/datacenterlight/templates/datacenterlight/order_detail.html +++ b/datacenterlight/templates/datacenterlight/order_detail.html @@ -33,7 +33,12 @@ {{billing_address.street_address}}, {{billing_address.postal_code}}
{{billing_address.city}}, {{billing_address.country}} {% if billing_address.vat_number %} -
{% trans "VAT Number" %} {{billing_address.vat_number}} +
{% trans "VAT Number" %} {{billing_address.vat_number}}  + {% if vm.vat_validation_status == "verified" %} + + {% else %} + + {% endif %} {% endif %} {% endwith %}

diff --git a/datacenterlight/utils.py b/datacenterlight/utils.py index 08dd73aa..13d8386c 100644 --- a/datacenterlight/utils.py +++ b/datacenterlight/utils.py @@ -1,7 +1,9 @@ +import datetime import logging import pyotp import requests +import stripe from django.conf import settings from django.contrib.sites.models import Site @@ -9,12 +11,13 @@ from datacenterlight.tasks import create_vm_task from hosting.models import HostingOrder, HostingBill, OrderDetail from membership.models import StripeCustomer from utils.forms import UserBillingAddressForm -from utils.models import BillingAddress +from utils.models import BillingAddress, UserBillingAddress from .cms_models import CMSIntegration from .models import VMPricing, VMTemplate logger = logging.getLogger(__name__) + def get_cms_integration(name): current_site = Site.objects.get_current() try: @@ -124,3 +127,67 @@ def check_otp(name, realm, token): data=data ) return response.status_code + + +def validate_vat_number(self, stripe_customer_id, vat_number): + try: + billing_address = BillingAddress.objects.get(vat_number=vat_number) + except BillingAddress.DoesNotExist as dne: + billing_address = None + logger.debug("BillingAddress does not exist for %s" % vat_number) + except BillingAddress.MultipleObjectsReturned as mor: + logger.debug("Multiple BillingAddress exist for %s" % vat_number) + billing_address = BillingAddress.objects.last(vat_number=vat_number) + if billing_address is not None: + if billing_address.vat_number_validated_on: + return { + "validated_on": billing_address.vat_number_validated_on, + "status": "verified" + } + else: + if billing_address.stripe_tax_id: + tax_id_obj = stripe.Customer.retrieve_tax_id( + stripe_customer_id, + billing_address.stripe_tax_id, + ) + if tax_id_obj.verification.status == "verified": + return { + "status": "verified", + "validated_on": billing_address.vat_number_validated_on + } + else: + return { + "status": tax_id_obj.verification.status, + "validated_on": "" + } + else: + tax_id_obj = create_tax_id(stripe_customer_id, vat_number) + else: + tax_id_obj = create_tax_id(stripe_customer_id, vat_number) + + return { + "status": tax_id_obj.verification.status, + "validated_on": datetime.datetime.now() if tax_id_obj.verification.status == "verified" else "" + } + + +def create_tax_id(stripe_customer_id, vat_number): + tax_id_obj = stripe.Customer.create_tax_id( + stripe_customer_id, + type="eu_vat", + value=vat_number, + ) + b_addresses = BillingAddress.objects.filter( + stripe_customer_id=stripe_customer_id, + vat_number=vat_number + ) + for b_address in b_addresses: + b_address.stripe_tax_id = tax_id_obj.id + + ub_addresses = UserBillingAddress.objects.filter( + stripe_customer_id=stripe_customer_id, + vat_number=vat_number + ) + for ub_address in ub_addresses: + ub_address.stripe_tax_id = tax_id_obj.id + return tax_id_obj diff --git a/datacenterlight/views.py b/datacenterlight/views.py index 0763e259..512989ac 100644 --- a/datacenterlight/views.py +++ b/datacenterlight/views.py @@ -35,7 +35,9 @@ 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 +from .utils import ( + get_cms_integration, create_vm, clear_all_session_vars, validate_vat_number +) logger = logging.getLogger(__name__) @@ -540,6 +542,14 @@ class PaymentOrderView(FormView): else: request.session['customer'] = customer + validate_result = validate_vat_number( + stripe_customer_id=request.session['customer'], + vat_number=address_form.cleaned_data.get('vat_number') + ) + + request.session["vat_validation_status"] = validate_result["status"] + request.session["vat_validated_on"] = validate_result["validated_on"] + # For generic payment we take the user directly to confirmation if ('generic_payment_type' in request.session and self.request.session['generic_payment_type'] == 'generic'): @@ -596,6 +606,10 @@ class OrderConfirmationView(DetailView, FormView): if ('generic_payment_type' in request.session and self.request.session['generic_payment_type'] == 'generic'): + if request.session["vat_validation_status"] == "verified": + request.session['generic_payment_details']['vat_rate'] = 0 + request.session['generic_payment_details']['vat_amount'] = 0 + request.session['generic_payment_details']['amount'] = request.session['generic_payment_details']['amount_before_vat'] context.update({ 'generic_payment_details': request.session['generic_payment_details'], @@ -614,11 +628,20 @@ class OrderConfirmationView(DetailView, FormView): vat_rate=user_country_vat_rate * 100 ) vm_specs["price"] = price - vm_specs["vat"] = vat - vm_specs["vat_percent"] = vat_percent + + if request.session["vat_validation_status"] == "verified": + vm_specs["vat_percent"] = 0 + vm_specs["vat"] = 0 + vm_specs["total_price"] = price + vm_specs["vat_validation_status"] = "verified" + else: + vm_specs["vat"] = vat + vm_specs["vat_percent"] = vat_percent + vm_specs["total_price"] = round(price + vat - discount['amount'], 2) + vm_specs["vat_validation_status"] = request.session["vat_validation_status"] + vm_specs["vat_country"] = user_vat_country vm_specs["discount"] = discount - vm_specs["total_price"] = round(price + vat - discount['amount'], 2) request.session['specs'] = vm_specs context.update({