diff --git a/app/assets/stylesheets/app.scss b/app/assets/stylesheets/app.scss index f28724c93..a6538fc3a 100644 --- a/app/assets/stylesheets/app.scss +++ b/app/assets/stylesheets/app.scss @@ -179,3 +179,16 @@ details summary { border: 0; margin-bottom: -$gutter + 2px; } + +.body-copy-table { + + table th, + table td { + font-size: 19px; + } + +} + +.tabular-numbers { + @include core-19($tabular-numbers: true); +} diff --git a/app/assets/stylesheets/components/table.scss b/app/assets/stylesheets/components/table.scss index a66baeff4..c748bdbcc 100644 --- a/app/assets/stylesheets/components/table.scss +++ b/app/assets/stylesheets/components/table.scss @@ -31,7 +31,7 @@ } .table-field-heading-first { - width: 52.5% + width: 52.5%; } .table-row { diff --git a/app/main/views/dashboard.py b/app/main/views/dashboard.py index b2787e8a4..def963624 100644 --- a/app/main/views/dashboard.py +++ b/app/main/views/dashboard.py @@ -8,7 +8,9 @@ from flask import ( url_for, session, jsonify, - current_app + current_app, + request, + abort ) from flask_login import login_required @@ -80,8 +82,16 @@ def template_history(service_id): @login_required @user_has_permissions('manage_settings', admin_override=True) def usage(service_id): + try: + year = int(request.args.get('year', 2016)) + except ValueError: + abort(404) return render_template( 'views/usage.html', + months=get_free_paid_breakdown_for_billable_units( + year, service_api_client.get_billable_units(service_id, year) + ), + year=year, **calculate_usage(service_api_client.get_service_usage(service_id)['data']) ) @@ -195,3 +205,58 @@ def format_weekly_stats_to_list(historical_stats): out.append(weekly_stats) return sorted(out, key=lambda x: x['week_start'], reverse=True) + + +def get_months_for_financial_year(year): + return [ + month.strftime('%B') + for month in ( + get_months_for_year(4, 13, year) + + get_months_for_year(1, 4, year + 1) + ) + if month < datetime.now() + ] + + +def get_months_for_year(start, end, year): + return [datetime(year, month, 1) for month in range(start, end)] + + +def get_free_paid_breakdown_for_billable_units(year, billable_units): + cumulative = 0 + for month in get_months_for_financial_year(year): + previous_cumulative = cumulative + monthly_usage = billable_units.get(month, 0) + cumulative += monthly_usage + breakdown = get_free_paid_breakdown_for_month( + cumulative, previous_cumulative, monthly_usage + ) + yield { + 'name': month, + 'paid': breakdown['paid'], + 'free': breakdown['free'] + } + + +def get_free_paid_breakdown_for_month( + cumulative, + previous_cumulative, + monthly_usage +): + allowance = 250000 + + if cumulative < allowance: + return { + 'paid': 0, + 'free': monthly_usage, + } + elif previous_cumulative < allowance: + return { + 'paid': monthly_usage - (allowance - previous_cumulative), + 'free': allowance - previous_cumulative + } + else: + return { + 'paid': monthly_usage, + 'free': 0 + } diff --git a/app/notify_client/service_api_client.py b/app/notify_client/service_api_client.py index ed14a803c..dfa64de51 100644 --- a/app/notify_client/service_api_client.py +++ b/app/notify_client/service_api_client.py @@ -211,6 +211,9 @@ class ServiceAPIClient(NotificationsAPIClient): def update_whitelist(self, service_id, data): return self.put(url='/service/{}/whitelist'.format(service_id), data=data) + def get_billable_units(self, service_id, year): + return self.get(url='/service/{}/billable-units?year={}'.format(service_id, year)) + class ServicesBrowsableItem(BrowsableItem): @property diff --git a/app/templates/views/usage.html b/app/templates/views/usage.html index 1f97fcd50..37794f1b4 100644 --- a/app/templates/views/usage.html +++ b/app/templates/views/usage.html @@ -1,4 +1,5 @@ {% from "components/big-number.html" import big_number %} +{% from "components/table.html" import list_table, field, hidden_field_heading, row_heading, text_field %} {% extends "withnav_template.html" %} @@ -13,7 +14,9 @@
+
What counts as 1 text message?
See pricing.