Merge branch 'master' into feature/6561/invoices-webhook
This commit is contained in:
commit
b9f9c7b00e
37 changed files with 855 additions and 104 deletions
|
|
@ -23,7 +23,6 @@
|
|||
|
||||
.hosting-dashboard .dashboard-container-head {
|
||||
color: #fff;
|
||||
margin-bottom: 60px;
|
||||
}
|
||||
|
||||
.hosting-dashboard-item {
|
||||
|
|
|
|||
|
|
@ -248,6 +248,9 @@
|
|||
.dashboard-title-thin {
|
||||
font-size: 22px;
|
||||
}
|
||||
.dashboard-greetings-thin {
|
||||
font-size: 16px;
|
||||
}
|
||||
}
|
||||
|
||||
.btn-vm-invoice {
|
||||
|
|
@ -315,6 +318,11 @@
|
|||
font-size: 32px;
|
||||
}
|
||||
|
||||
.dashboard-greetings-thin {
|
||||
font-weight: 300;
|
||||
font-size: 24px;
|
||||
}
|
||||
|
||||
.dashboard-title-thin .un-icon {
|
||||
height: 34px;
|
||||
margin-right: 5px;
|
||||
|
|
@ -411,6 +419,9 @@
|
|||
.dashboard-title-thin {
|
||||
font-size: 22px;
|
||||
}
|
||||
.dashboard-greetings-thin {
|
||||
font-size: 16px;
|
||||
}
|
||||
.dashboard-title-thin .un-icon {
|
||||
height: 22px;
|
||||
width: 22px;
|
||||
|
|
|
|||
|
|
@ -7,6 +7,9 @@
|
|||
<div class="dashboard-container-head">
|
||||
<h1 class="dashboard-title-thin">{% trans "My Dashboard" %}</h1>
|
||||
</div>
|
||||
<div style="color:#fff; font-size: 18px; font-weight:300; padding: 0 8px; margin-top: 30px; margin-bottom: 30px;">
|
||||
{% trans "Welcome" %} {{request.user.name}}
|
||||
</div>
|
||||
<div class="hosting-dashboard-content">
|
||||
<a href="{% url 'hosting:create_virtual_machine' %}" class="hosting-dashboard-item">
|
||||
<h2>{% trans "Create VM" %}</h2>
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@
|
|||
</li>
|
||||
<li class="dropdown highlights-dropdown">
|
||||
<a class="dropdown-toggle" role="button" data-toggle="dropdown" href="#">
|
||||
<i class="fa fa-fw fa-user"></i> {{request.user.name}} <span class="fa fa-fw fa-caret-down"></span>
|
||||
<i class="fa fa-fw fa-user"></i> {{request.user.username}} <span class="fa fa-fw fa-caret-down"></span>
|
||||
</a>
|
||||
<ul id="g-account-menu" class="dropdown-menu" role="menu">
|
||||
<li><a href="{% url 'hosting:logout' %}">{% trans "Logout"%}</a></li>
|
||||
|
|
|
|||
|
|
@ -147,8 +147,12 @@
|
|||
CHF</strong>
|
||||
</p>
|
||||
<p>
|
||||
<small>{% trans "VAT" %} ({{ vm.vat_percent|floatformat:2|intcomma }}%)
|
||||
{% if vm.after_eu_vat_intro %}
|
||||
<small>{% trans "VAT for" %} {{vm.vat_country}} ({{vm.vat_percent}}%) : </small>
|
||||
{% else %}
|
||||
<small>{% trans "VAT" %} ({{ vm.vat_percent|floatformat:2|intcomma }}%)
|
||||
</small>
|
||||
{% endif %}
|
||||
<strong class="pull-right">{{vm.vat|floatformat:2|intcomma}} CHF</strong>
|
||||
</p>
|
||||
{% endif %}
|
||||
|
|
|
|||
|
|
@ -142,7 +142,12 @@
|
|||
<strong class="pull-right">{{vm.price|floatformat:2|intcomma}} CHF</strong>
|
||||
</p>
|
||||
<p>
|
||||
<small>{% trans "VAT" %} ({{ vm.vat_percent|floatformat:2|intcomma }}%) </small>
|
||||
{% if vm.after_eu_vat_intro %}
|
||||
<small>{% trans "VAT for" %} {{vm.vat_country}} ({{vm.vat_percent}}%) : </small>
|
||||
{% else %}
|
||||
<small>{% trans "VAT" %} ({{ vm.vat_percent|floatformat:2|intcomma }}%)
|
||||
</small>
|
||||
{% endif %}
|
||||
<strong class="pull-right">{{vm.vat|floatformat:2|intcomma}} CHF</strong>
|
||||
</p>
|
||||
{% endif %}
|
||||
|
|
|
|||
|
|
@ -15,6 +15,10 @@
|
|||
<div class="settings-container">
|
||||
<div class="row">
|
||||
<div class="col-sm-5 col-md-6 billing dcl-billing">
|
||||
<h3><b>{%trans "My Username"%}</b></h3>
|
||||
<hr class="top-hr">
|
||||
<p>{{request.user.username}}</p>
|
||||
<br>
|
||||
<h3>{%trans "Billing Address" %}</h3>
|
||||
<hr>
|
||||
<form role="form" id="billing-form" method="post" action="" novalidate>
|
||||
|
|
|
|||
|
|
@ -45,8 +45,8 @@
|
|||
<h2 class="vm-detail-title">{% trans "Billing" %} <img src="{% static 'hosting/img/billing.svg' %}" class="un-icon"></h2>
|
||||
<div class="vm-vmid">
|
||||
<div class="vm-item-subtitle">{% trans "Current Pricing" %}</div>
|
||||
<div class="vm-item-lg">{{order.price|floatformat:2|intcomma}} CHF/{% trans "Month" %}</div>
|
||||
<a class="btn btn-vm-invoice" href="{% if has_invoices %}{% url 'hosting:invoices' %}{% else %}{% url 'hosting:orders' order.pk %}{% endif %}">{% trans "See Invoice" %}</a>
|
||||
<div class="vm-item-lg">{{order.price|floatformat:2|intcomma}} CHF/{% if order.generic_product %}{% trans order.generic_product.product_subscription_interval %}{% else %}{% trans "Month" %}{% endif %}</div>
|
||||
<a class="btn btn-vm-invoice" href="{% if has_invoices %}{% url 'hosting:invoices' %}{% else %}{% url 'hosting:orders' order.pk %}{% endif %}">{% trans "See Invoice" %}</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="vm-detail-item">
|
||||
|
|
|
|||
178
hosting/views.py
178
hosting/views.py
|
|
@ -50,10 +50,15 @@ from utils.forms import (
|
|||
ResendActivationEmailForm
|
||||
)
|
||||
from utils.hosting_utils import get_all_public_keys
|
||||
from utils.hosting_utils import get_vm_price_with_vat, HostingUtils
|
||||
from utils.hosting_utils import (
|
||||
get_vm_price_with_vat, get_vm_price_for_given_vat, HostingUtils,
|
||||
get_vat_rate_for_country
|
||||
)
|
||||
from utils.mailer import BaseEmail
|
||||
from utils.stripe_utils import StripeUtils
|
||||
from utils.tasks import send_plain_email_task
|
||||
from utils.ldap_manager import LdapManager
|
||||
|
||||
from utils.views import (
|
||||
PasswordResetViewMixin, PasswordResetConfirmViewMixin, LoginViewMixin,
|
||||
ResendActivationLinkViewMixin
|
||||
|
|
@ -391,21 +396,30 @@ class PasswordResetConfirmView(HostingContextMixin,
|
|||
if user is not None and default_token_generator.check_token(user,
|
||||
token):
|
||||
if form.is_valid():
|
||||
ldap_manager = LdapManager()
|
||||
new_password = form.cleaned_data['new_password2']
|
||||
user.set_password(new_password)
|
||||
user.save()
|
||||
messages.success(request, _('Password has been reset.'))
|
||||
|
||||
# Change opennebula password
|
||||
opennebula_client.change_user_password(user.password)
|
||||
# Make sure the user have an ldap account already
|
||||
user.create_ldap_account(new_password)
|
||||
|
||||
return self.form_valid(form)
|
||||
else:
|
||||
messages.error(
|
||||
request, _('Password reset has not been successful.'))
|
||||
form.add_error(None,
|
||||
_('Password reset has not been successful.'))
|
||||
return self.form_invalid(form)
|
||||
# We are changing password in ldap before changing in database because
|
||||
# ldap have more chances of failure than local database
|
||||
if ldap_manager.change_password(user.username, new_password):
|
||||
user.set_password(new_password)
|
||||
user.save()
|
||||
|
||||
messages.success(request, _('Password has been reset.'))
|
||||
|
||||
# Change opennebula password
|
||||
opennebula_client.change_user_password(user.password)
|
||||
|
||||
return self.form_valid(form)
|
||||
|
||||
messages.error(
|
||||
request, _('Password reset has not been successful.'))
|
||||
form.add_error(None,
|
||||
_('Password reset has not been successful.'))
|
||||
return self.form_invalid(form)
|
||||
|
||||
else:
|
||||
error_msg = _('The reset password link is no longer valid.')
|
||||
|
|
@ -845,18 +859,32 @@ class OrdersHostingDetailView(LoginRequiredMixin, DetailView, FormView):
|
|||
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(
|
||||
user_vat_country = obj.billing_address.country
|
||||
user_country_vat_rate = get_vat_rate_for_country(
|
||||
user_vat_country)
|
||||
price, vat, vat_percent, discount = get_vm_price_for_given_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')
|
||||
if obj.vm_pricing else 'default'),
|
||||
vat_rate= (
|
||||
user_country_vat_rate * 100
|
||||
if obj.vm_id >= settings.FIRST_VM_ID_AFTER_EU_VAT
|
||||
else settings.PRE_EU_VAT_RATE
|
||||
)
|
||||
)
|
||||
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']["after_eu_vat_intro"] = (
|
||||
True if obj.vm_id >= settings.FIRST_VM_ID_AFTER_EU_VAT
|
||||
else False
|
||||
)
|
||||
context['vm']["price"] = price
|
||||
context['vm']["vat"] = vat
|
||||
context['vm']["vat_percent"] = vat_percent
|
||||
context['vm']["vat_country"] = user_vat_country
|
||||
context['vm']["discount"] = discount
|
||||
context['vm']["total_price"] = round(
|
||||
price + vat - discount['amount'], 2)
|
||||
context['subscription_end_date'] = vm_detail.end_date()
|
||||
except VMDetail.DoesNotExist:
|
||||
try:
|
||||
|
|
@ -865,20 +893,32 @@ class OrdersHostingDetailView(LoginRequiredMixin, DetailView, FormView):
|
|||
)
|
||||
vm = manager.get_vm(obj.vm_id)
|
||||
context['vm'] = VirtualMachineSerializer(vm).data
|
||||
price, vat, vat_percent, discount = get_vm_price_with_vat(
|
||||
user_vat_country = obj.billing_address.country
|
||||
user_country_vat_rate = get_vat_rate_for_country(
|
||||
user_vat_country)
|
||||
price, vat, vat_percent, discount = get_vm_price_for_given_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')
|
||||
if obj.vm_pricing else 'default'),
|
||||
vat_rate=(
|
||||
user_country_vat_rate * 100
|
||||
if obj.vm_id >= settings.FIRST_VM_ID_AFTER_EU_VAT
|
||||
else settings.PRE_EU_VAT_RATE
|
||||
)
|
||||
)
|
||||
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']["after_eu_vat_intro"] = (
|
||||
True if obj.vm_id >= settings.FIRST_VM_ID_AFTER_EU_VAT
|
||||
else False
|
||||
)
|
||||
context['vm']["price"] = price
|
||||
context['vm']["vat"] = vat
|
||||
context['vm']["vat_percent"] = vat_percent
|
||||
context['vm']["vat_country"] = user_vat_country
|
||||
context['vm']["discount"] = discount
|
||||
context['vm']["total_price"] = round(
|
||||
price + vat - discount['amount'], 2)
|
||||
except WrongIdError:
|
||||
messages.error(
|
||||
self.request,
|
||||
|
|
@ -916,7 +956,27 @@ class OrdersHostingDetailView(LoginRequiredMixin, DetailView, FormView):
|
|||
context['cc_exp_year'] = card_detail.exp_year
|
||||
context['cc_exp_month'] = '{:02d}'.format(card_detail.exp_month)
|
||||
context['site_url'] = reverse('hosting:create_virtual_machine')
|
||||
context['vm'] = self.request.session.get('specs')
|
||||
vm_specs = self.request.session.get('specs')
|
||||
user_vat_country = (
|
||||
self.request.session.get('billing_address_data').get("country")
|
||||
)
|
||||
user_country_vat_rate = get_vat_rate_for_country(user_vat_country)
|
||||
price, vat, vat_percent, discount = get_vm_price_for_given_vat(
|
||||
cpu=vm_specs['cpu'],
|
||||
memory=vm_specs['memory'],
|
||||
ssd_size=vm_specs['disk_size'],
|
||||
pricing_name=vm_specs['pricing_name'],
|
||||
vat_rate=user_country_vat_rate * 100
|
||||
)
|
||||
vm_specs["price"] = price
|
||||
vm_specs["vat"] = vat
|
||||
vm_specs["vat_percent"] = vat_percent
|
||||
vm_specs["vat_country"] = user_vat_country
|
||||
vm_specs["discount"] = discount
|
||||
vm_specs["total_price"] = round(price + vat - discount['amount'],
|
||||
2)
|
||||
vm_specs["after_eu_vat_intro"] = True
|
||||
context['vm'] = vm_specs
|
||||
return context
|
||||
|
||||
@method_decorator(decorators)
|
||||
|
|
@ -1247,18 +1307,32 @@ class InvoiceDetailView(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(
|
||||
user_vat_country = obj.order.billing_address.country
|
||||
user_country_vat_rate = get_vat_rate_for_country(
|
||||
user_vat_country)
|
||||
price, vat, vat_percent, discount = get_vm_price_for_given_vat(
|
||||
cpu=context['vm']['cores'],
|
||||
ssd_size=context['vm']['disk_size'],
|
||||
memory=context['vm']['memory'],
|
||||
pricing_name=(obj.order.vm_pricing.name
|
||||
if obj.order.vm_pricing else 'default')
|
||||
if obj.order.vm_pricing else 'default'),
|
||||
vat_rate=(
|
||||
user_country_vat_rate * 100
|
||||
if obj.order.vm_id >= settings.FIRST_VM_ID_AFTER_EU_VAT
|
||||
else settings.PRE_EU_VAT_RATE
|
||||
)
|
||||
)
|
||||
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']["after_eu_vat_intro"] = (
|
||||
True if obj.order.vm_id >= settings.FIRST_VM_ID_AFTER_EU_VAT
|
||||
else False
|
||||
)
|
||||
context['vm']["price"] = price
|
||||
context['vm']["vat"] = vat
|
||||
context['vm']["vat_percent"] = vat_percent
|
||||
context['vm']["vat_country"] = user_vat_country
|
||||
context['vm']["discount"] = discount
|
||||
context['vm']["total_price"] = round(
|
||||
price + vat - discount['amount'], 2)
|
||||
except VMDetail.DoesNotExist:
|
||||
# fallback to get it from the infrastructure
|
||||
try:
|
||||
|
|
@ -1268,20 +1342,32 @@ class InvoiceDetailView(LoginRequiredMixin, DetailView):
|
|||
)
|
||||
vm = manager.get_vm(vm_id)
|
||||
context['vm'] = VirtualMachineSerializer(vm).data
|
||||
price, vat, vat_percent, discount = get_vm_price_with_vat(
|
||||
user_vat_country = obj.order.billing_address.country
|
||||
user_country_vat_rate = get_vat_rate_for_country(
|
||||
user_vat_country)
|
||||
price, vat, vat_percent, discount = get_vm_price_for_given_vat(
|
||||
cpu=context['vm']['cores'],
|
||||
ssd_size=context['vm']['disk_size'],
|
||||
memory=context['vm']['memory'],
|
||||
pricing_name=(obj.order.vm_pricing.name
|
||||
if obj.order.vm_pricing else 'default')
|
||||
if obj.order.vm_pricing else 'default'),
|
||||
vat_rate=(
|
||||
user_country_vat_rate * 100
|
||||
if obj.order.vm_id >= settings.FIRST_VM_ID_AFTER_EU_VAT
|
||||
else settings.PRE_EU_VAT_RATE
|
||||
)
|
||||
)
|
||||
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']["after_eu_vat_intro"] = (
|
||||
True if obj.order.vm_id >= settings.FIRST_VM_ID_AFTER_EU_VAT
|
||||
else False
|
||||
)
|
||||
context['vm']["price"] = price
|
||||
context['vm']["vat"] = vat
|
||||
context['vm']["vat_percent"] = vat_percent
|
||||
context['vm']["vat_country"] = user_vat_country
|
||||
context['vm']["discount"] = discount
|
||||
context['vm']["total_price"] = round(
|
||||
price + vat - discount['amount'], 2)
|
||||
except TypeError:
|
||||
logger.error("Type error. Probably we "
|
||||
"came from a generic product. "
|
||||
|
|
@ -1297,8 +1383,8 @@ class InvoiceDetailView(LoginRequiredMixin, DetailView):
|
|||
self.kwargs['error'] = 'WrongIdError'
|
||||
context['error'] = 'WrongIdError'
|
||||
return context
|
||||
else:
|
||||
logger.debug("No VM_ID. So, no details available.")
|
||||
else:
|
||||
logger.debug("No VM_ID. So, no details available.")
|
||||
|
||||
# add context params from monthly hosting bill
|
||||
context['period_start'] = obj.get_period_start()
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue