Billing Setting for Notification and Company Info
This commit is contained in:
parent
a07a67419f
commit
1b22e7900c
22 changed files with 417 additions and 5 deletions
|
@ -18,6 +18,7 @@ ln -sf $root/yuyu/local/enabled/_6111_project_billing_panel_group.py $horizon_pa
|
|||
ln -sf $root/yuyu/local/enabled/_6112_project_billing_overview.py $horizon_path/openstack_dashboard/local/enabled/_6112_project_billing_overview.py
|
||||
ln -sf $root/yuyu/local/enabled/_6113_project_billing_usage_cost.py $horizon_path/openstack_dashboard/local/enabled/_6113_project_billing_usage_cost.py
|
||||
ln -sf $root/yuyu/local/enabled/_6114_project_billing_invoice.py $horizon_path/openstack_dashboard/local/enabled/_6114_project_billing_invoice.py
|
||||
ln -sf $root/yuyu/local/enabled/_6115_project_billing_setting.py $horizon_path/openstack_dashboard/local/enabled/_6115_project_billing_setting.py
|
||||
|
||||
echo "Symlink Creation Done"
|
||||
echo "Now you can configure and yuyu dashboard"
|
37
yuyu/admin/billing_setting/forms.py
Normal file
37
yuyu/admin/billing_setting/forms.py
Normal file
|
@ -0,0 +1,37 @@
|
|||
from django.utils.translation import ugettext_lazy as _
|
||||
|
||||
from horizon import forms, messages, exceptions
|
||||
from openstack_dashboard.dashboards.yuyu.cases.setting_use_case import SettingUseCase
|
||||
|
||||
|
||||
class SettingForm(forms.SelfHandlingForm):
|
||||
NAME = "Settings"
|
||||
USE_CASE = SettingUseCase()
|
||||
|
||||
company_name = forms.CharField(label=_("COMPANY NAME"),
|
||||
required=False)
|
||||
company_logo = forms.URLField(label=_("COMPANY LOGO URL"),
|
||||
required=False)
|
||||
company_address = forms.CharField(label=_("COMPANY ADDRESS"),
|
||||
required=False)
|
||||
email_admin = forms.EmailField(label=_("EMAIL ADMIN"),
|
||||
required=True)
|
||||
|
||||
invoice_tax = forms.IntegerField(label=_("INVOICE TAX (%)"),
|
||||
required=True)
|
||||
|
||||
def handle(self, request, data):
|
||||
try:
|
||||
result = ""
|
||||
for k, v in data.items():
|
||||
result = self.USE_CASE.set_setting(
|
||||
request=request,
|
||||
key=k,
|
||||
value=v
|
||||
)
|
||||
messages.success(request, _(f"Successfully update {self.NAME}"))
|
||||
|
||||
return result
|
||||
except Exception as e:
|
||||
exceptions.handle(request,
|
||||
_('Unable to update.'))
|
11
yuyu/admin/billing_setting/tables.py
Normal file
11
yuyu/admin/billing_setting/tables.py
Normal file
|
@ -0,0 +1,11 @@
|
|||
from openstack_dashboard.dashboards.yuyu.core.billing_setting.tables import BaseUpdateSettingAction, BaseSettingTable
|
||||
|
||||
|
||||
class UpdateSettingAction(BaseUpdateSettingAction):
|
||||
url = "horizon:admin:billing_setting:update_setting"
|
||||
|
||||
|
||||
class SettingTable(BaseSettingTable):
|
||||
class Meta(object):
|
||||
table_actions = (UpdateSettingAction,)
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
{% extends "horizon/common/_modal_form.html" %}
|
||||
{% load i18n %}
|
||||
|
||||
{% block modal-body-right %}
|
||||
<h3>{% trans "Description:" %}</h3>
|
||||
<p>{% trans 'Update a billing setting.' %}</p>
|
||||
{% endblock %}
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
{% extends 'base.html' %}
|
||||
{% load i18n %}
|
||||
|
||||
{% block title %}{% trans "Update Billing Setting" %}{% endblock %}
|
||||
|
||||
{% block main %}
|
||||
{% include "admin/billing_setting/_form_setting.html" %}
|
||||
{% endblock %}
|
|
@ -4,6 +4,14 @@
|
|||
|
||||
{% block main %}
|
||||
{% include "admin/price_configuration/missing_prices.html" %}
|
||||
{% include "admin/billing_setting/missing_billing_setting.html" %}
|
||||
|
||||
{# Form #}
|
||||
<div class="row">
|
||||
<div class="col-sm-12">
|
||||
{{ table.render }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-sm-12">
|
||||
|
@ -13,8 +21,7 @@
|
|||
{% else %}
|
||||
<h1>Billing Disabled</h1> <br/>
|
||||
<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 %} disabled {% endif %}">Enable</a>
|
||||
<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>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
|
|
@ -0,0 +1,38 @@
|
|||
{% if missing_setting.invoice_tax %}
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
<div class="alert alert-danger alert-dismissible" role="alert">
|
||||
<button type="button" class="close" data-dismiss="alert" aria-label="Close"><span aria-hidden="true">×</span></button>
|
||||
Tax not complete
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{% if missing_setting.email_notification %}
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
<div class="alert alert-danger alert-dismissible" role="alert">
|
||||
<button type="button" class="close" data-dismiss="alert" aria-label="Close"><span aria-hidden="true">×</span></button>
|
||||
Project Email Notification not complete
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
|
||||
{% if missing_setting.email_admin %}
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
<div class="alert alert-danger alert-dismissible" role="alert">
|
||||
<button type="button" class="close" data-dismiss="alert" aria-label="Close"><span aria-hidden="true">×</span></button>
|
||||
Email Admin not complete
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
@ -19,5 +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'^update_setting/$',
|
||||
views.UpdateSettingView.as_view(), name='update_setting'),
|
||||
]
|
||||
|
||||
|
|
|
@ -10,27 +10,70 @@
|
|||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
from django import shortcuts
|
||||
from django.urls import reverse_lazy
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
|
||||
from horizon import views, exceptions, messages
|
||||
from horizon import views, exceptions, messages, tables, forms
|
||||
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.utils.price_checker import has_missing_price
|
||||
from .forms import SettingForm
|
||||
from .tables import SettingTable
|
||||
|
||||
|
||||
class IndexView(views.APIView):
|
||||
class IndexView(tables.DataTableView):
|
||||
page_title = _("Setting")
|
||||
template_name = "admin/billing_setting/index.html"
|
||||
table_class = SettingTable
|
||||
|
||||
setting_uc = SettingUseCase()
|
||||
|
||||
def get_data(self):
|
||||
try:
|
||||
setting_uc = self.setting_uc.get_setting_admin(self.request)
|
||||
|
||||
except Exception:
|
||||
setting_uc = []
|
||||
exceptions.handle(self.request,
|
||||
_("Unable to retrieve data."))
|
||||
return setting_uc
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
context = super().get_context_data(**kwargs)
|
||||
|
||||
if hasattr(self, "table"):
|
||||
context[self.context_object_name] = self.table
|
||||
|
||||
context['setting'] = self.setting_uc.get_settings(self.request)
|
||||
context['missing_price'] = has_missing_price(self.request)
|
||||
context['missing_setting'] = self.setting_uc.has_missing_setting(self.request)
|
||||
return context
|
||||
|
||||
|
||||
class UpdateSettingView(forms.ModalFormView):
|
||||
form_class = SettingForm
|
||||
form_id = "setting_form_update"
|
||||
modal_id = "update_setting_modal"
|
||||
modal_header = _("Update Setting")
|
||||
page_title = _("Setting")
|
||||
submit_label = _("Update Setting")
|
||||
submit_url = reverse_lazy("horizon:admin:billing_setting:update_setting")
|
||||
success_url = reverse_lazy("horizon:admin:billing_setting:index")
|
||||
template_name = 'admin/billing_setting/form_setting.html'
|
||||
|
||||
setting_uc = SettingUseCase()
|
||||
|
||||
def get_initial(self):
|
||||
try:
|
||||
setting_uc = dict(self.setting_uc.get_setting_admin(self.request))
|
||||
except Exception:
|
||||
setting_uc = None
|
||||
exceptions.handle(self.request,
|
||||
_("Unable to retrieve setting."))
|
||||
|
||||
return setting_uc
|
||||
|
||||
|
||||
class EnableBillingView(views.APIView):
|
||||
invoice_uc = InvoiceUseCase()
|
||||
|
||||
|
|
|
@ -2,6 +2,15 @@ from openstack_dashboard.dashboards.yuyu.core import yuyu_client
|
|||
|
||||
|
||||
class ProjectOverviewUseCase:
|
||||
def get_tenant(self, request):
|
||||
response = yuyu_client.get(request, f"project_overview/{request.user.tenant_id}/get_tenant/")
|
||||
keys_to_include = ['email_notification', ]
|
||||
|
||||
return [x for x in response.json().items() if x[0] in keys_to_include]
|
||||
|
||||
def update_email(self, request, payload):
|
||||
return yuyu_client.post(request, f"project_overview/{request.user.tenant_id}/update_email/", payload).json()
|
||||
|
||||
def total_resource(self, request):
|
||||
response = yuyu_client.get(request, f"project_overview/total_resource/?tenant_id={request.user.tenant_id}")
|
||||
return response.json()
|
||||
|
|
|
@ -2,10 +2,32 @@ from openstack_dashboard.dashboards.yuyu.core import yuyu_client
|
|||
|
||||
|
||||
class SettingUseCase:
|
||||
|
||||
def get_settings(self, request):
|
||||
return yuyu_client.get(request, "settings/").json()
|
||||
response = yuyu_client.get(request, "settings/").json()
|
||||
return response
|
||||
|
||||
def set_setting(self, request, key, value):
|
||||
return yuyu_client.patch(request, f"settings/{key}/", {
|
||||
"value": value
|
||||
}).json()
|
||||
|
||||
def get_setting_admin(self, request):
|
||||
keys_to_exclude = ['billing_enabled',
|
||||
'email_notification']
|
||||
response = self.get_settings(request)
|
||||
|
||||
return [x for x in response.items() if x[0] not in keys_to_exclude]
|
||||
|
||||
def has_missing_setting(self, request):
|
||||
missing = [None, '']
|
||||
response = self.get_settings(request)
|
||||
context = {x[0]: True for x in response.items() if x[1] in missing}
|
||||
|
||||
if context:
|
||||
context['has_missing'] = True
|
||||
return context
|
||||
|
||||
context['has_missing'] = True
|
||||
|
||||
return context
|
||||
|
|
48
yuyu/core/billing_setting/tables.py
Normal file
48
yuyu/core/billing_setting/tables.py
Normal file
|
@ -0,0 +1,48 @@
|
|||
from django.urls import reverse
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
|
||||
from horizon import tables
|
||||
|
||||
|
||||
class SettingName:
|
||||
SETTING_NAMES = {
|
||||
"billing_enabled": _("Billing Enabled"),
|
||||
"invoice_tax": _("Invoice Tax"),
|
||||
"company_name": _("Company Name"),
|
||||
"company_logo": _("Company Logo"),
|
||||
"company_address": _("Company Address"),
|
||||
"email_admin": _("Email Admin"),
|
||||
"email_notification": _("Email Notification")
|
||||
}
|
||||
|
||||
def get_setting_name(self, setting):
|
||||
return self.SETTING_NAMES.get(setting[0], setting[0].replace("_", " ").title())
|
||||
|
||||
def get_setting_value(self, setting):
|
||||
return setting[1]
|
||||
|
||||
|
||||
class BaseUpdateSettingAction(tables.LinkAction):
|
||||
name = "update_setting"
|
||||
verbose_name = _("Update Setting")
|
||||
url = None
|
||||
classes = ("ajax-modal",)
|
||||
icon = "pencil"
|
||||
step = None
|
||||
|
||||
def get_link_url(self, datum=None):
|
||||
return reverse(self.url)
|
||||
|
||||
|
||||
class BaseSettingTable(tables.DataTable):
|
||||
setting_name = SettingName()
|
||||
name = tables.Column(setting_name.get_setting_name, verbose_name=_('Setting Name'))
|
||||
value = tables.Column(setting_name.get_setting_value, verbose_name=_('Value'))
|
||||
|
||||
def get_object_id(self, obj):
|
||||
return obj
|
||||
|
||||
class Meta(object):
|
||||
name = "settings"
|
||||
verbose_name = _("Settings")
|
||||
multi_select = False
|
10
yuyu/local/enabled/_6115_project_billing_setting.py
Normal file
10
yuyu/local/enabled/_6115_project_billing_setting.py
Normal file
|
@ -0,0 +1,10 @@
|
|||
# The slug of the panel to be added to HORIZON_CONFIG. Required.
|
||||
PANEL = 'billing_setting'
|
||||
# The slug of the dashboard the PANEL associated with. Required.
|
||||
PANEL_DASHBOARD = 'project'
|
||||
# The slug of the panel group the PANEL is associated with.
|
||||
PANEL_GROUP = 'billing'
|
||||
|
||||
# Python panel class of the PANEL to be added.
|
||||
ADD_PANEL = 'openstack_dashboard.dashboards.yuyu.project.billing_setting.panel.BillingSetting'
|
||||
# ADD_PANEL = 'openstack_dashboard.dashboards.yuyu.project.invoice.panel.Invoice'
|
0
yuyu/project/billing_setting/__init__.py
Normal file
0
yuyu/project/billing_setting/__init__.py
Normal file
26
yuyu/project/billing_setting/forms.py
Normal file
26
yuyu/project/billing_setting/forms.py
Normal file
|
@ -0,0 +1,26 @@
|
|||
from django.utils.translation import ugettext_lazy as _
|
||||
|
||||
from horizon import forms, messages, exceptions
|
||||
from openstack_dashboard.dashboards.yuyu.cases.project_overview_use_case import ProjectOverviewUseCase
|
||||
|
||||
|
||||
class SettingForm(forms.SelfHandlingForm):
|
||||
NAME = "Settings"
|
||||
USE_CASE = ProjectOverviewUseCase()
|
||||
|
||||
email_notification = forms.EmailField(label=_("EMAIL NOTIFICATION"),
|
||||
required=True)
|
||||
|
||||
def handle(self, request, data):
|
||||
try:
|
||||
print(data)
|
||||
result = self.USE_CASE.update_email(
|
||||
request=request,
|
||||
payload=data
|
||||
)
|
||||
messages.success(request, _(f"Successfully update {self.NAME}"))
|
||||
|
||||
return result
|
||||
except Exception as e:
|
||||
exceptions.handle(request,
|
||||
_('Unable to update.'))
|
20
yuyu/project/billing_setting/panel.py
Normal file
20
yuyu/project/billing_setting/panel.py
Normal file
|
@ -0,0 +1,20 @@
|
|||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
|
||||
import horizon
|
||||
|
||||
|
||||
class BillingSetting(horizon.Panel):
|
||||
name = _("Billing Setting")
|
||||
slug = "billing_setting"
|
10
yuyu/project/billing_setting/tables.py
Normal file
10
yuyu/project/billing_setting/tables.py
Normal file
|
@ -0,0 +1,10 @@
|
|||
from openstack_dashboard.dashboards.yuyu.core.billing_setting.tables import BaseSettingTable, BaseUpdateSettingAction
|
||||
|
||||
|
||||
class UpdateSettingAction(BaseUpdateSettingAction):
|
||||
url = "horizon:project:billing_setting:update_setting"
|
||||
|
||||
|
||||
class SettingTable(BaseSettingTable):
|
||||
class Meta(object):
|
||||
table_actions = (UpdateSettingAction,)
|
|
@ -0,0 +1,8 @@
|
|||
{% extends "horizon/common/_modal_form.html" %}
|
||||
{% load i18n %}
|
||||
|
||||
{% block modal-body-right %}
|
||||
<h3>{% trans "Description:" %}</h3>
|
||||
<p>{% trans 'Update a billing setting.' %}</p>
|
||||
{% endblock %}
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
{% extends 'base.html' %}
|
||||
{% load i18n %}
|
||||
|
||||
{% block title %}{% trans "Create/Update Volume Price" %}{% endblock %}
|
||||
|
||||
{% block main %}
|
||||
{% include "project/billing_setting/_form_setting.html" %}
|
||||
{% endblock %}
|
|
@ -0,0 +1,12 @@
|
|||
{% extends 'base.html' %}
|
||||
{% load i18n %}
|
||||
{% block title %}{% trans "Billing Setting" %}{% endblock %}
|
||||
|
||||
{% block main %}
|
||||
{# Form #}
|
||||
<div class="row">
|
||||
<div class="col-sm-12">
|
||||
{{ table.render }}
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
22
yuyu/project/billing_setting/urls.py
Normal file
22
yuyu/project/billing_setting/urls.py
Normal file
|
@ -0,0 +1,22 @@
|
|||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
from django.conf.urls import url
|
||||
|
||||
from . import views
|
||||
|
||||
urlpatterns = [
|
||||
url(r'^$', views.IndexView.as_view(), name='index'),
|
||||
url(r'^update_setting/$',
|
||||
views.UpdateSettingView.as_view(), name='update_setting'),
|
||||
]
|
||||
|
62
yuyu/project/billing_setting/views.py
Normal file
62
yuyu/project/billing_setting/views.py
Normal file
|
@ -0,0 +1,62 @@
|
|||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
from django import shortcuts
|
||||
from django.urls import reverse_lazy, reverse
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
|
||||
from horizon import views, exceptions, messages, tables, forms
|
||||
from openstack_dashboard.dashboards.yuyu.cases.setting_use_case import SettingUseCase
|
||||
from .forms import SettingForm
|
||||
from .tables import SettingTable
|
||||
from ...cases.project_overview_use_case import ProjectOverviewUseCase
|
||||
|
||||
|
||||
class IndexView(tables.DataTableView):
|
||||
page_title = _("Setting")
|
||||
template_name = "project/billing_setting/index.html"
|
||||
table_class = SettingTable
|
||||
|
||||
setting_uc = ProjectOverviewUseCase()
|
||||
|
||||
def get_data(self):
|
||||
try:
|
||||
setting_uc = self.setting_uc.get_tenant(self.request)
|
||||
|
||||
except Exception:
|
||||
setting_uc = []
|
||||
exceptions.handle(self.request,
|
||||
_("Unable to retrieve data."))
|
||||
return setting_uc
|
||||
|
||||
|
||||
class UpdateSettingView(forms.ModalFormView):
|
||||
form_class = SettingForm
|
||||
form_id = "setting_form_update"
|
||||
modal_id = "update_setting_modal"
|
||||
modal_header = _("Update Setting")
|
||||
page_title = _("Setting")
|
||||
submit_label = _("Update Setting")
|
||||
submit_url = reverse_lazy("horizon:project:billing_setting:update_setting")
|
||||
success_url = reverse_lazy("horizon:project:billing_setting:index")
|
||||
template_name = 'project/billing_setting/form_setting.html'
|
||||
|
||||
setting_uc = ProjectOverviewUseCase()
|
||||
|
||||
def get_initial(self):
|
||||
try:
|
||||
setting_uc = dict(self.setting_uc.get_tenant(self.request))
|
||||
except Exception:
|
||||
setting_uc = None
|
||||
exceptions.handle(self.request,
|
||||
_("Unable to retrieve setting."))
|
||||
|
||||
return setting_uc
|
Loading…
Add table
Reference in a new issue