Compare commits
1 commit
Author | SHA1 | Date | |
---|---|---|---|
![]() |
6c2bec211f |
16 changed files with 317 additions and 96 deletions
|
@ -28,7 +28,8 @@
|
|||
<div class="panel-body">
|
||||
<p>Please make sure all price is already configured before enable billing</p>
|
||||
<a href="{% url 'horizon:admin:billing_setting:enable_billing' %}" class="btn btn-primary {% if missing_price.has_missing or missing_setting.has_missing %} disabled {% endif %}">Enable</a>
|
||||
<a href="{% url 'horizon:admin:billing_setting:reset_billing' %}" class="btn btn-danger">Reset Billing Data</a>
|
||||
<a href="{% url 'horizon:admin:billing_setting:reset_billing' %}" class="btn btn-danger">Reset All Billing Data</a>
|
||||
<a href="{% url 'horizon:admin:billing_setting:reset_transaction' %}" class="btn btn-danger">Reset Transaction Data</a>
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
|
|
@ -19,6 +19,7 @@ urlpatterns = [
|
|||
url(r'^enable_billing$', views.EnableBillingView.as_view(), name='enable_billing'),
|
||||
url(r'^disable_billing$', views.DisableBillingView.as_view(), name='disable_billing'),
|
||||
url(r'^reset_billing$', views.ResetBillingView.as_view(), name='reset_billing'),
|
||||
url(r'^reset_transaction$', views.ResetTransactionView.as_view(), name='reset_transaction'),
|
||||
url(r'^update_setting/$',
|
||||
views.UpdateSettingView.as_view(), name='update_setting'),
|
||||
]
|
||||
|
|
|
@ -111,3 +111,15 @@ class ResetBillingView(views.APIView):
|
|||
exceptions.handle(self.request,
|
||||
_("Unable to reset billing"))
|
||||
return shortcuts.redirect("horizon:admin:billing_setting:index")
|
||||
|
||||
class ResetTransactionView(views.APIView):
|
||||
invoice_uc = InvoiceUseCase()
|
||||
|
||||
def get(self, request, *args, **kwargs):
|
||||
try:
|
||||
self.invoice_uc.reset_transaction(request)
|
||||
messages.success(request, _("Data successfully Reset."))
|
||||
except Exception:
|
||||
exceptions.handle(self.request,
|
||||
_("Unable to reset transaction"))
|
||||
return shortcuts.redirect("horizon:admin:billing_setting:index")
|
|
@ -41,7 +41,7 @@ class IndexView(tables.DataTableView):
|
|||
if hasattr(self, "table"):
|
||||
context[self.context_object_name] = self.table
|
||||
|
||||
context['select_list'], _ = api.keystone.tenant_list(self.request, user=self.request.user.id)
|
||||
context['select_list'], _ = api.keystone.tenant_list(self.request)
|
||||
context['current_tenant_id'] = self.request.GET.get('tenant_id', None)
|
||||
|
||||
return context
|
||||
|
@ -67,6 +67,7 @@ class ReadAllView(views.APIView):
|
|||
try:
|
||||
notifications = self.notification_uc.get_list(self.request,
|
||||
filter_selection=self.kwargs['selection'])
|
||||
|
||||
for n in notifications:
|
||||
if not n["is_read"]:
|
||||
self.notification_uc.set_read(request, n['id'])
|
||||
|
|
|
@ -34,7 +34,7 @@ class IndexView(tables.DataTableView):
|
|||
def get_data(self):
|
||||
try:
|
||||
data = []
|
||||
project_list, has_more = api.keystone.tenant_list(self.request, user=self.request.user.id)
|
||||
project_list, has_more = api.keystone.tenant_list(self.request)
|
||||
for d in self.balance_uc.list(self.request):
|
||||
project = list(filter(lambda x: x.id == d['project']['tenant_id'], project_list))
|
||||
project_name = 'Unknown Project'
|
||||
|
|
|
@ -0,0 +1,139 @@
|
|||
<html>
|
||||
<head>
|
||||
<title>Invoice Download</title>
|
||||
{% include '_stylesheets.html' %}
|
||||
</head>
|
||||
<body>
|
||||
<style>
|
||||
.invoice {
|
||||
padding: 30px;
|
||||
}
|
||||
|
||||
.invoice h2 {
|
||||
margin-top: 0px;
|
||||
line-height: 0.8em;
|
||||
}
|
||||
|
||||
.invoice .small {
|
||||
font-weight: 300;
|
||||
}
|
||||
|
||||
.invoice hr {
|
||||
margin-top: 10px;
|
||||
border-color: #ddd;
|
||||
}
|
||||
|
||||
.invoice .table tr.line {
|
||||
border-bottom: 1px solid #ccc;
|
||||
}
|
||||
|
||||
.invoice .table td {
|
||||
border: none;
|
||||
}
|
||||
|
||||
.invoice .identity {
|
||||
margin-top: 10px;
|
||||
font-size: 1.1em;
|
||||
font-weight: 300;
|
||||
}
|
||||
|
||||
.invoice .identity strong {
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.grid {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
background: #fff;
|
||||
color: #666666;
|
||||
border-radius: 2px;
|
||||
margin-bottom: 25px;
|
||||
box-shadow: 0px 1px 4px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
</style>
|
||||
<div id="invoice">
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<!-- BEGIN INVOICE -->
|
||||
<div class="col-xs-12">
|
||||
<div class="grid invoice">
|
||||
<div class="grid-body">
|
||||
<div class="invoice-title">
|
||||
<div class="row">
|
||||
<div class="col-xs-12">{{ setting.company_logo }}</div>
|
||||
</div>
|
||||
<br />
|
||||
<div class="row">
|
||||
<div class="col-xs-12">
|
||||
<h2>
|
||||
invoice<br />
|
||||
<span class="small">order #{{ invoice.id }}</span>
|
||||
</h2>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<hr />
|
||||
<div class="row">
|
||||
<div class="col-xs-6">
|
||||
<address style="max-width: 30%;">
|
||||
{{ setting.company_name }} <br />
|
||||
{{ setting.company_address }}
|
||||
</address>
|
||||
</div>
|
||||
<div class="col-xs-6 text-right">
|
||||
<address>
|
||||
<strong>Invoice Month:</strong><br />
|
||||
{{ invoice.start_date|date:'M Y' }}
|
||||
<br />
|
||||
<br />
|
||||
<strong>Invoice State:</strong><br />
|
||||
{{ invoice.state_text }}
|
||||
<br />
|
||||
<br />
|
||||
<strong>Subtotal</strong><br />
|
||||
{{ invoice.subtotal_money }}
|
||||
<br />
|
||||
<br />
|
||||
{% if invoice.state != 1 %}
|
||||
<strong>Tax</strong><br />
|
||||
{{ invoice.tax_money }}
|
||||
<br />
|
||||
<br />
|
||||
<strong>Total</strong><br />
|
||||
{{ invoice.total_money }}
|
||||
<br />
|
||||
<br />
|
||||
{% endif %}
|
||||
</address>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
<h3>ORDER SUMMARY</h3>
|
||||
<br />
|
||||
<br />
|
||||
<div id="usage_cost">
|
||||
<div id="instance-cost">{{ instance_cost_table.render }}</div>
|
||||
|
||||
<div id="volume-cost">{{ volume_cost_table.render }}</div>
|
||||
<div id="floating-ip-cost">{{ floating_ip_cost_table.render }}</div>
|
||||
<div id="router-cost">{{ router_cost_table.render }}</div>
|
||||
<div id="snapshot-cost">{{ snapshot_cost_table.render }}</div>
|
||||
<div id="image-cost">{{ image_cost_table.render }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- END INVOICE -->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% include 'horizon/_scripts.html' %}
|
||||
<script type="text/javascript">
|
||||
window.print()
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
|
@ -14,7 +14,7 @@
|
|||
<div class="col-md-6">
|
||||
<span class="pull-right" data-html2canvas-ignore="true">
|
||||
{% include 'admin/projects_invoice/manage_invoice_modal.html' with invoice=invoice project_balance_amount=project_balance_amount %}
|
||||
<button onclick="javascript:downloadPdf();" class="btn btn-default">Download PDF</button>
|
||||
<a href="{% url "horizon:admin:projects_invoice:usage_cost_print" project_id invoice.id %}" target="_blank" class="btn btn-default">Download PDF</a>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -79,36 +79,3 @@
|
|||
{% endif %}
|
||||
{% endblock %}
|
||||
|
||||
{% block js %}
|
||||
{{ block.super }}
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/html2pdf.js/0.10.1/html2pdf.bundle.min.js"
|
||||
integrity="sha512-GsLlZN/3F2ErC5ifS5QtgpiJtWd43JWSuIgh7mbzZ8zBps+dvLusV+eNQATqgA/HdeKFVgA5v3S/cIrLF7QnIg=="
|
||||
crossorigin="anonymous" referrerpolicy="no-referrer"></script>
|
||||
|
||||
<script type="text/javascript">
|
||||
function downloadPdf() {
|
||||
let opt = {
|
||||
filename: 'usage_cost.pdf',
|
||||
margin: [16, 16],
|
||||
enableLinks: true,
|
||||
image: {type: 'jpeg', quality: 0.98},
|
||||
pagebreak: { mode: 'avoid-all', },
|
||||
jsPDF: {unit: 'mm', format: 'a4', orientation: 'portrait'},
|
||||
}
|
||||
|
||||
// clone element to modify
|
||||
const ucElement = document.getElementById('usage_cost');
|
||||
const ucElementClone = ucElement.cloneNode(true);
|
||||
|
||||
// modify element
|
||||
const navTabs = ucElementClone.querySelector('.nav-tabs');
|
||||
navTabs.style.display = 'none';
|
||||
const tabContent = ucElementClone.querySelectorAll('.tab-pane');
|
||||
tabContent.forEach(content => {
|
||||
content.classList.remove("tab-pane");
|
||||
});
|
||||
|
||||
html2pdf().set(opt).from(ucElementClone).save();
|
||||
}
|
||||
</script>
|
||||
{% endblock %}
|
||||
|
|
|
@ -7,17 +7,4 @@
|
|||
<br/>
|
||||
|
||||
{% include 'admin/projects_invoice/base_invoice.html' %}
|
||||
{% endblock %}
|
||||
{% block js %}
|
||||
{{ block.super }}
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/html2pdf.js/0.10.1/html2pdf.bundle.min.js"
|
||||
integrity="sha512-GsLlZN/3F2ErC5ifS5QtgpiJtWd43JWSuIgh7mbzZ8zBps+dvLusV+eNQATqgA/HdeKFVgA5v3S/cIrLF7QnIg=="
|
||||
crossorigin="anonymous" referrerpolicy="no-referrer"></script>
|
||||
|
||||
<script type="text/javascript">
|
||||
function downloadPdf() {
|
||||
window.print();
|
||||
}
|
||||
|
||||
</script>
|
||||
{% endblock %}
|
|
@ -19,6 +19,7 @@ urlpatterns = [
|
|||
url(r'^$', views.IndexView.as_view(), name='index'),
|
||||
url(r'^invoice/detail/(?P<project_id>[^/]+)/(?P<id>[^/]+)/$', views.InvoiceView.as_view(), name='invoice_detail'),
|
||||
url(r'^invoice/usage/(?P<project_id>[^/]+)/(?P<id>[^/]+)/$', views.UsageCostTabView.as_view(), name='usage_cost'),
|
||||
url(r'^invoice/usage/print/(?P<project_id>[^/]+)/(?P<id>[^/]+)/$', views.UsageCostView.as_view(), name='usage_cost_print'),
|
||||
url(r'^invoice/finish/(?P<id>[^/]+)/$', views.FinishInvoice.as_view(), name='finish_invoice'),
|
||||
url(r'^invoice/rollback_to_unpaid/(?P<id>[^/]+)/$', views.RollbackToUnpaidInvoice.as_view(),
|
||||
name='rollback_to_unpaid'),
|
||||
|
|
|
@ -46,7 +46,7 @@ class IndexView(tables.DataTableView):
|
|||
|
||||
def get_context_data(self, **kwargs):
|
||||
context = super().get_context_data(**kwargs)
|
||||
context['project_list'], _ = api.keystone.tenant_list(self.request, user=self.request.user.id)
|
||||
context['project_list'], _ = api.keystone.tenant_list(self.request)
|
||||
context['current_project_id'] = self.request.GET.get('project_id', self.request.user.project_id)
|
||||
context['current_project_name'] = self.request.GET.get('project_name', self.request.user.project_id)
|
||||
return context
|
||||
|
@ -129,6 +129,7 @@ class UsageCostTabView(tabs.TabbedTableView):
|
|||
context = super().get_context_data(**kwargs)
|
||||
balance = self.balance_uc.retrieve_by_project(self.request, self.kwargs['project_id'])
|
||||
context['invoice'] = self.request.invoice
|
||||
context['project_id'] = self.kwargs['project_id']
|
||||
context['project_balance_amount'] = Money(amount=balance['amount'],
|
||||
currency=balance['amount_currency']) if balance else 0
|
||||
return context
|
||||
|
@ -138,10 +139,12 @@ class UsageCostView(tables.MultiTableView):
|
|||
table_classes = (
|
||||
InstanceCostTable, VolumeCostTable, FloatingIpCostTable, RouterCostTable, SnapshotCostTable, ImageCostTable)
|
||||
page_title = _("Usage Cost")
|
||||
template_name = "admin/projects_invoice/cost_tables.html"
|
||||
template_name = "admin/projects_invoice/cost_download.html"
|
||||
|
||||
invoice_uc = InvoiceUseCase()
|
||||
balance_uc = BalanceUseCase()
|
||||
setting_uc = SettingUseCase()
|
||||
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
|
@ -154,6 +157,7 @@ class UsageCostView(tables.MultiTableView):
|
|||
def get_context_data(self, **kwargs):
|
||||
context = super().get_context_data(**kwargs)
|
||||
balance = self.balance_uc.retrieve_by_project(self.request, self.kwargs['project_id'])
|
||||
context['setting'] = self.setting_uc.get_settings(self.request)
|
||||
context['invoice'] = self.request.invoice
|
||||
context['project_balance_amount'] = Money(amount=balance['amount'],
|
||||
currency=balance['amount_currency']) if balance else 0
|
||||
|
|
|
@ -109,6 +109,9 @@ class InvoiceUseCase:
|
|||
|
||||
def reset_billing(self, request):
|
||||
yuyu_client.post(request, f"invoice/reset_billing/", {})
|
||||
|
||||
def reset_transaction(self, request):
|
||||
yuyu_client.post(request, f"invoice/reset_transaction_data/", {})
|
||||
|
||||
def finish_invoice(self, request, id, skip_balance):
|
||||
response = yuyu_client.get(request, f"invoice/{id}/finish/?skip_balance={skip_balance}")
|
||||
|
|
|
@ -3,7 +3,7 @@ from openstack_dashboard.dashboards.yuyu.core import yuyu_client
|
|||
|
||||
class NotificationCenterUseCase:
|
||||
def get_list(self, request, filter_selection=None):
|
||||
if filter_selection is None:
|
||||
if filter_selection is None or filter_selection == 'None':
|
||||
return yuyu_client.get(request, f"notification/").json()
|
||||
|
||||
return yuyu_client.get(request, f"notification/?tenant_id={filter_selection}").json()
|
||||
|
|
139
yuyu/project/usage_cost/templates/usage_cost/cost_download.html
Normal file
139
yuyu/project/usage_cost/templates/usage_cost/cost_download.html
Normal file
|
@ -0,0 +1,139 @@
|
|||
<html>
|
||||
<head>
|
||||
<title>Invoice Download</title>
|
||||
{% include '_stylesheets.html' %}
|
||||
</head>
|
||||
<body>
|
||||
<style>
|
||||
.invoice {
|
||||
padding: 30px;
|
||||
}
|
||||
|
||||
.invoice h2 {
|
||||
margin-top: 0px;
|
||||
line-height: 0.8em;
|
||||
}
|
||||
|
||||
.invoice .small {
|
||||
font-weight: 300;
|
||||
}
|
||||
|
||||
.invoice hr {
|
||||
margin-top: 10px;
|
||||
border-color: #ddd;
|
||||
}
|
||||
|
||||
.invoice .table tr.line {
|
||||
border-bottom: 1px solid #ccc;
|
||||
}
|
||||
|
||||
.invoice .table td {
|
||||
border: none;
|
||||
}
|
||||
|
||||
.invoice .identity {
|
||||
margin-top: 10px;
|
||||
font-size: 1.1em;
|
||||
font-weight: 300;
|
||||
}
|
||||
|
||||
.invoice .identity strong {
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.grid {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
background: #fff;
|
||||
color: #666666;
|
||||
border-radius: 2px;
|
||||
margin-bottom: 25px;
|
||||
box-shadow: 0px 1px 4px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
</style>
|
||||
<div id="invoice">
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<!-- BEGIN INVOICE -->
|
||||
<div class="col-xs-12">
|
||||
<div class="grid invoice">
|
||||
<div class="grid-body">
|
||||
<div class="invoice-title">
|
||||
<div class="row">
|
||||
<div class="col-xs-12">{{ setting.company_logo }}</div>
|
||||
</div>
|
||||
<br />
|
||||
<div class="row">
|
||||
<div class="col-xs-12">
|
||||
<h2>
|
||||
invoice<br />
|
||||
<span class="small">order #{{ invoice.id }}</span>
|
||||
</h2>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<hr />
|
||||
<div class="row">
|
||||
<div class="col-xs-6">
|
||||
<address style="max-width: 30%;">
|
||||
{{ setting.company_name }} <br />
|
||||
{{ setting.company_address }}
|
||||
</address>
|
||||
</div>
|
||||
<div class="col-xs-6 text-right">
|
||||
<address>
|
||||
<strong>Invoice Month:</strong><br />
|
||||
{{ invoice.start_date|date:'M Y' }}
|
||||
<br />
|
||||
<br />
|
||||
<strong>Invoice State:</strong><br />
|
||||
{{ invoice.state_text }}
|
||||
<br />
|
||||
<br />
|
||||
<strong>Subtotal</strong><br />
|
||||
{{ invoice.subtotal_money }}
|
||||
<br />
|
||||
<br />
|
||||
{% if invoice.state != 1 %}
|
||||
<strong>Tax</strong><br />
|
||||
{{ invoice.tax_money }}
|
||||
<br />
|
||||
<br />
|
||||
<strong>Total</strong><br />
|
||||
{{ invoice.total_money }}
|
||||
<br />
|
||||
<br />
|
||||
{% endif %}
|
||||
</address>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
<h3>ORDER SUMMARY</h3>
|
||||
<br />
|
||||
<br />
|
||||
<div id="usage_cost">
|
||||
<div id="instance-cost">{{ instance_cost_table.render }}</div>
|
||||
|
||||
<div id="volume-cost">{{ volume_cost_table.render }}</div>
|
||||
<div id="floating-ip-cost">{{ floating_ip_cost_table.render }}</div>
|
||||
<div id="router-cost">{{ router_cost_table.render }}</div>
|
||||
<div id="snapshot-cost">{{ snapshot_cost_table.render }}</div>
|
||||
<div id="image-cost">{{ image_cost_table.render }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- END INVOICE -->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% include 'horizon/_scripts.html' %}
|
||||
<script type="text/javascript">
|
||||
window.print()
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
|
@ -18,7 +18,7 @@
|
|||
</select>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<button onclick="javascript:downloadPdf();" class="btn btn-default pull-right" data-html2canvas-ignore="true">Download PDF</button>
|
||||
<a href="{% url "horizon:project:usage_cost:download" %}?invoice_id={{ invoice.id }}" target="_blank" class="btn btn-default pull-right">Download PDF</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
@ -81,42 +81,3 @@
|
|||
<h1>You don't have any usage yet</h1> <br/>
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
|
||||
{% block js %}
|
||||
{{ block.super }}
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/html2pdf.js/0.10.1/html2pdf.bundle.min.js"
|
||||
integrity="sha512-GsLlZN/3F2ErC5ifS5QtgpiJtWd43JWSuIgh7mbzZ8zBps+dvLusV+eNQATqgA/HdeKFVgA5v3S/cIrLF7QnIg=="
|
||||
crossorigin="anonymous" referrerpolicy="no-referrer"></script>
|
||||
|
||||
<script type="text/javascript">
|
||||
function onInvoiceChange(val) {
|
||||
var search = "?invoice_id=" + val;
|
||||
window.location.href = window.location.protocol + "//" + window.location.host + window.location.pathname + search;
|
||||
}
|
||||
|
||||
function downloadPdf() {
|
||||
let opt = {
|
||||
filename: 'usage_cost.pdf',
|
||||
margin: [16, 16],
|
||||
enableLinks: true,
|
||||
image: {type: 'jpeg', quality: 0.98},
|
||||
pagebreak: { mode: 'avoid-all', },
|
||||
jsPDF: {unit: 'mm', format: 'a4', orientation: 'portrait'},
|
||||
}
|
||||
|
||||
// clone element to modify
|
||||
const ucElement = document.getElementById('usage_cost');
|
||||
const ucElementClone = ucElement.cloneNode(true);
|
||||
|
||||
// modify element
|
||||
const navTabs = ucElementClone.querySelector('.nav-tabs');
|
||||
navTabs.style.display = 'none';
|
||||
const tabContent = ucElementClone.querySelectorAll('.tab-pane');
|
||||
tabContent.forEach(content => {
|
||||
content.classList.remove("tab-pane");
|
||||
});
|
||||
|
||||
html2pdf().set(opt).from(ucElementClone).save();
|
||||
}
|
||||
</script>
|
||||
{% endblock %}
|
||||
|
|
|
@ -17,4 +17,5 @@ from openstack_dashboard.dashboards.yuyu.project.usage_cost import views
|
|||
|
||||
urlpatterns = [
|
||||
url(r'^$', views.IndexViewTab.as_view(), name='index'),
|
||||
url(r'^download/$', views.DownloadView.as_view(), name='download'),
|
||||
]
|
||||
|
|
|
@ -17,6 +17,7 @@ from djmoney.money import Money
|
|||
from horizon import exceptions, tables, tabs
|
||||
from openstack_dashboard import api
|
||||
from openstack_dashboard.dashboards.yuyu.cases.invoice_use_case import InvoiceUseCase
|
||||
from openstack_dashboard.dashboards.yuyu.cases.setting_use_case import SettingUseCase
|
||||
from openstack_dashboard.dashboards.yuyu.core.usage_cost.tables import InstanceCostTable, VolumeCostTable, \
|
||||
FloatingIpCostTable, RouterCostTable, SnapshotCostTable, ImageCostTable
|
||||
from openstack_dashboard.dashboards.yuyu.core.usage_cost.tabs import UsageCostTabs
|
||||
|
@ -51,13 +52,14 @@ class IndexViewTab(tabs.TabbedTableView):
|
|||
return context
|
||||
|
||||
|
||||
class IndexView(tables.MultiTableView):
|
||||
class DownloadView(tables.MultiTableView):
|
||||
table_classes = (
|
||||
InstanceCostTable, VolumeCostTable, FloatingIpCostTable, RouterCostTable, SnapshotCostTable, ImageCostTable)
|
||||
page_title = _("Usage Cost")
|
||||
template_name = "project/usage_cost/cost_tables.html"
|
||||
template_name = "project/usage_cost/cost_download.html"
|
||||
|
||||
invoice_uc = InvoiceUseCase()
|
||||
setting_uc = SettingUseCase()
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
|
@ -71,12 +73,14 @@ class IndexView(tables.MultiTableView):
|
|||
invoice_id = request.invoice_list[0]['id']
|
||||
|
||||
request.invoice = self.invoice_uc.get_invoice(self.request, invoice_id) if request.has_invoice else {}
|
||||
return super(IndexView, self).get(request, *args, **kwargs)
|
||||
return super(DownloadView, self).get(request, *args, **kwargs)
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
context = super().get_context_data(**kwargs)
|
||||
context['invoice_list'] = self.request.invoice_list
|
||||
context['invoice'] = self.request.invoice
|
||||
context['setting'] = self.setting_uc.get_settings(self.request)
|
||||
|
||||
return context
|
||||
|
||||
def _get_flavor_name(self, flavor_id):
|
||||
|
|
Loading…
Add table
Reference in a new issue