diff --git a/cloud/endagaweb/templates/dashboard/report/billing.html b/cloud/endagaweb/templates/dashboard/report/billing.html
new file mode 100644
index 00000000..56024ac8
--- /dev/null
+++ b/cloud/endagaweb/templates/dashboard/report/billing.html
@@ -0,0 +1,368 @@
+{% extends "dashboard/layout.html" %}
+{% comment %}
+Copyright (c) 2016-present, Facebook, Inc.
+All rights reserved.
+
+This source code is licensed under the BSD-style license found in the
+LICENSE file in the root directory of this source tree. An additional grant
+of patent rights can be found in the PATENTS file in the same directory.
+{% endcomment %}
+{% load apptags %}
+{% load humanize %}
+{% load crispy_forms_tags %}
+
+
+{% block title %}
+ {% tmpl_const "SITENAME" %} | Report
+ {% if report_summary %}
+ | "{{ report_summary }}"
+ {% endif %}
+{% endblock %}
+
+{% block pagestyle %}
+
+
+
+
+{% endblock %}
+
+{% block content %}
+ {% include "dashboard/report/header.html" with header='Billing' %}
+
+
+
+ {% include "dashboard/report/nav.html" with active_tab='billing_reports' %}
+
+ {% include "dashboard/report/filter.html" with action_url='/dashboard/reports/billing' %}
+ {% if network_has_activity %}
+
+
+
+
+
+ {% if 'Loader' in reports %}
+
+
+ {% include "dashboard/report/waterfall.html" with title="Waterfall - Loader" %}
+
+
+ {% endif %}
+ {% if 'Reload Rate' in reports %}
+
+
+
+ {% include "dashboard/report/waterfall.html" with title="Waterfall - Reload Rate" %}
+
+
+ {% endif %}
+ {% if 'Reload Amount' in reports %}
+
+
+
+ {% include "dashboard/report/waterfall.html" with title="Waterfall - Reload Amount" %}
+
+
+ {% endif %}
+ {% if 'Reload Transaction' in reports %}
+
+
+
+ {% include "dashboard/report/waterfall.html" with title="Waterfall - Reload Transaction" %}
+
+
+ {% endif %}
+ {% if 'Average Frequency' in reports %}
+
+
+
+ {% include "dashboard/report/waterfall.html" with title="Waterfall - Average Frequency" %}
+
+
+ {% endif %}
+
+
+
+
+
+
+
+
+ {% else %}
+
There is no network activity to display.
+ {% endif %}
+
+ {% include 'dashboard/timezone-notice.html' %}
+
+
+
+
+{% endblock %}
+
+{% block js %}
+{% if network_has_activity %}
+
+
+
+
+
+
+
+
+
+
+
+
+
+{% endif %}
+
+{% endblock %}
\ No newline at end of file
diff --git a/cloud/endagaweb/templates/dashboard/report/filter.html b/cloud/endagaweb/templates/dashboard/report/filter.html
new file mode 100644
index 00000000..de8bf18f
--- /dev/null
+++ b/cloud/endagaweb/templates/dashboard/report/filter.html
@@ -0,0 +1,75 @@
+
+
+
+
+
+
+
diff --git a/cloud/endagaweb/templates/dashboard/report/header.html b/cloud/endagaweb/templates/dashboard/report/header.html
new file mode 100644
index 00000000..c5281da6
--- /dev/null
+++ b/cloud/endagaweb/templates/dashboard/report/header.html
@@ -0,0 +1,19 @@
+{% comment %}
+Copyright (c) 2016-present, Facebook, Inc.
+All rights reserved.
+
+This source code is licensed under the BSD-style license found in the
+LICENSE file in the root directory of this source tree. An additional grant
+of patent rights can be found in the PATENTS file in the same directory.
+{% endcomment %}
+
+
\ No newline at end of file
diff --git a/cloud/endagaweb/templates/dashboard/report/nav.html b/cloud/endagaweb/templates/dashboard/report/nav.html
new file mode 100644
index 00000000..876bbcf0
--- /dev/null
+++ b/cloud/endagaweb/templates/dashboard/report/nav.html
@@ -0,0 +1,19 @@
+{% comment %}
+Copyright (c) 2016-present, Facebook, Inc.
+All rights reserved.
+
+This source code is licensed under the BSD-style license found in the
+LICENSE file in the root directory of this source tree. An additional grant
+of patent rights can be found in the PATENTS file in the same directory.
+{% endcomment %}
+
diff --git a/cloud/endagaweb/templates/dashboard/report/header.html b/cloud/endagaweb/templates/dashboard/report/header.html
deleted file mode 100644
index c5281da6..00000000
--- a/cloud/endagaweb/templates/dashboard/report/header.html
+++ /dev/null
@@ -1,19 +0,0 @@
-{% comment %}
-Copyright (c) 2016-present, Facebook, Inc.
-All rights reserved.
-
-This source code is licensed under the BSD-style license found in the
-LICENSE file in the root directory of this source tree. An additional grant
-of patent rights can be found in the PATENTS file in the same directory.
-{% endcomment %}
-
-
\ No newline at end of file
diff --git a/cloud/endagaweb/templates/dashboard/report/nav.html b/cloud/endagaweb/templates/dashboard/report/nav.html
deleted file mode 100644
index 876bbcf0..00000000
--- a/cloud/endagaweb/templates/dashboard/report/nav.html
+++ /dev/null
@@ -1,19 +0,0 @@
-{% comment %}
-Copyright (c) 2016-present, Facebook, Inc.
-All rights reserved.
-
-This source code is licensed under the BSD-style license found in the
-LICENSE file in the root directory of this source tree. An additional grant
-of patent rights can be found in the PATENTS file in the same directory.
-{% endcomment %}
-
diff --git a/cloud/endagaweb/urls.py b/cloud/endagaweb/urls.py
index 4b818068..d2b8d10c 100644
--- a/cloud/endagaweb/urls.py
+++ b/cloud/endagaweb/urls.py
@@ -87,7 +87,7 @@
# Dashboard.
url(r'^dashboard/card', endagaweb.views.dashboard.addcard),
url(r'^addmoney/', endagaweb.views.dashboard.addmoney),
- url(r'^dashboard/billing$', endagaweb.views.dashboard.billing_view),
+ url(r'^dashboard/billing', endagaweb.views.dashboard.billing_view),
url(r'^dashboard/profile', endagaweb.views.dashboard.profile_view),
# Tower views in the dashboard.
# /towers -- GET a list of towers or POST here to add one
@@ -157,9 +157,6 @@
url(r'^dashboard/activity',
endagaweb.views.dashboard.ActivityView.as_view(),
name='network-activity'),
- url(r'^dashboard/reports/billing',
- endagaweb.views.reports.BillingReportView.as_view(),
- name='billing-report'),
# Raise a server error on-demand to test the 500 template.
url(r'^insta-five-hundred$',
diff --git a/cloud/endagaweb/views/reports.py b/cloud/endagaweb/views/reports.py
index 08b15612..888d46f1 100644
--- a/cloud/endagaweb/views/reports.py
+++ b/cloud/endagaweb/views/reports.py
@@ -1,115 +1,3 @@
-"""Report views"""
-
-import datetime
-import time
-
-import pytz
-from django.core import urlresolvers
-from django.http import HttpResponse, HttpResponseBadRequest
-from django.shortcuts import redirect
-from django.template.loader import get_template
-from guardian.shortcuts import get_objects_for_user
-
-from ccm.common.currency import CURRENCIES
-from ccm.common.currency import humanize_credits
-from endagaweb import models
-from endagaweb.models import NetworkDenomination
-from endagaweb.models import (UserProfile, UsageEvent, Network)
-from endagaweb.views.dashboard import ProtectedView
-
-REPORTS_DICT = {
- 'Top Up': ['Amount Based', 'Count Based'],
- 'Call & SMS': ['SMS Billing', 'Call and SMS Billing', 'Call Billing'],
- 'Retailer': ['Retailer Recharge', 'Retailer Load Transfer'],
-}
-
-
-class BaseReport(ProtectedView):
- """The base Report class.
-
- Process request and response for report view pages.This class used for
- handling filter by network, tower and report list.
- """
-
- def __init__(self, reports, template, url_namespace='billing-report',
- **kwargs):
- super(BaseReport, self).__init__(**kwargs)
- self.reports = reports
- self.template = template
- self.url_namespace = url_namespace
-
- def handle_request(self, request):
- """Process request.
-
- We want filters to persist even when someone changes pages without
- re-submitting the form. Page changes will always come over a GET
- request, not a POST.
- - If it's a GET, we should try to pull settings from the session.
- - If it's a POST, we should replace whatever is in the session.
- - If it's a GET with no page, we should blank out the session.
- """
- user_profile = UserProfile.objects.get(user=request.user)
- network = user_profile.network
- report_list = list({x for v in self.reports.itervalues() for x in v})
- # Process parameters.
- # We want filters to persist even when someone changes pages without
- # re-submitting the form. Page changes will always come over a GET
- # request, not a POST.
- # - If it's a GET, we should try to pull settings from the session.
- # - If it's a POST, we should replace whatever is in the session.
- # - If it's a GET with no page variable, we should blank out the
- # session.
- if request.method == "POST":
- request.session['level_id'] = request.POST.get('level_id') or 0
- if request.session['level_id']:
- request.session['level'] = 'tower'
- else:
- request.session['level'] = "network"
- request.session['level_id'] = network.id
- request.session['reports'] = request.POST.getlist('reports', None)
- # We always just do a redirect to GET. We include page reference
- # to retain the search parameters in the session.
- return redirect(
- urlresolvers.reverse(self.url_namespace) + '?filter=1')
-
- elif request.method == "GET":
- if 'filter' not in request.GET:
- # Reset filtering params.
- request.session['level'] = 'network'
- if self.url_namespace == 'subscriber-report':
- request.session['level'] = 'network'
- request.session['level_id'] = network.id
- request.session['reports'] = report_list
- else:
- return HttpResponseBadRequest()
- timezone_offset = pytz.timezone(user_profile.timezone).utcoffset(
- datetime.datetime.now()).total_seconds()
- level = request.session['level']
- level_id = int(request.session['level_id'])
- reports = request.session['reports']
-
- towers = models.BTS.objects.filter(
- network=user_profile.network).values('nickname', 'uuid', 'id')
- network_has_activity = UsageEvent.objects.filter(
- network=network).exists()
-
- context = {
- 'networks': get_objects_for_user(request.user, 'view_network',
- klass=Network),
- 'towers': towers,
- 'level': level,
- 'level_id': level_id,
- 'reports': reports,
- 'report_list': self.reports,
- 'user_profile': user_profile,
- 'current_time_epoch': int(time.time()),
- 'timezone_offset': timezone_offset,
- 'network_has_activity': network_has_activity,
- 'value_type': ''
- }
- template = get_template(self.template)
- html = template.render(context, request)
- return HttpResponse(html)
class BillingReportView(ProtectedView):