mirror of
https://github.com/GSA/notifications-admin.git
synced 2026-09-10 10:03:21 -04:00
Merge pull request #2349 from alphagov/display-postage-on-usage-page
Display postage on usage page
This commit is contained in:
@@ -418,8 +418,8 @@ def get_months_for_year(start, end, year):
|
|||||||
|
|
||||||
def get_sum_billing_units(billing_units, month=None):
|
def get_sum_billing_units(billing_units, month=None):
|
||||||
if month:
|
if month:
|
||||||
return sum(b['billing_units'] * b.get('rate_multiplier', 1) for b in billing_units if b['month'] == month)
|
return sum(b['billing_units'] for b in billing_units if b['month'] == month)
|
||||||
return sum(b['billing_units'] * b.get('rate_multiplier', 1) for b in billing_units)
|
return sum(b['billing_units'] for b in billing_units)
|
||||||
|
|
||||||
|
|
||||||
def get_free_paid_breakdown_for_billable_units(year, free_sms_fragment_limit, billing_units):
|
def get_free_paid_breakdown_for_billable_units(year, free_sms_fragment_limit, billing_units):
|
||||||
@@ -435,8 +435,12 @@ def get_free_paid_breakdown_for_billable_units(year, free_sms_fragment_limit, bi
|
|||||||
free_sms_fragment_limit, cumulative, previous_cumulative,
|
free_sms_fragment_limit, cumulative, previous_cumulative,
|
||||||
[billing_month for billing_month in sms_units if billing_month['month'] == month]
|
[billing_month for billing_month in sms_units if billing_month['month'] == month]
|
||||||
)
|
)
|
||||||
letter_billing = [(x['billing_units'], x['rate'], (x['billing_units'] * x['rate']))
|
letter_billing = [(x['billing_units'], x['rate'], (x['billing_units'] * x['rate']), x['postage'])
|
||||||
for x in letter_units if x['month'] == month]
|
for x in letter_units if x['month'] == month]
|
||||||
|
|
||||||
|
if letter_billing:
|
||||||
|
letter_billing.sort(key=lambda x: (x[3], x[1]))
|
||||||
|
|
||||||
letter_total = 0
|
letter_total = 0
|
||||||
for x in letter_billing:
|
for x in letter_billing:
|
||||||
letter_total += x[2]
|
letter_total += x[2]
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
{% from "components/big-number.html" import big_number %}
|
{% from "components/big-number.html" import big_number %}
|
||||||
|
{% from "components/message-count-label.html" import message_count_label %}
|
||||||
{% from "components/table.html" import list_table, field, hidden_field_heading, row_heading, text_field %}
|
{% from "components/table.html" import list_table, field, hidden_field_heading, row_heading, text_field %}
|
||||||
{% from "components/pill.html" import pill %}
|
{% from "components/pill.html" import pill %}
|
||||||
|
|
||||||
@@ -100,10 +101,10 @@
|
|||||||
) }}
|
) }}
|
||||||
<ul>
|
<ul>
|
||||||
{% if month.free %}
|
{% if month.free %}
|
||||||
<li class="tabular-numbers">{{ "{:,}".format(month.free) }} free text messages</li>
|
<li class="tabular-numbers">{{ "{:,}".format(month.free) }} free {{ message_count_label(month.free, 'sms', '') }}</li>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% if month.paid %}
|
{% if month.paid %}
|
||||||
<li class="tabular-numbers">{{ "{:,}".format(month.paid) }} text messages at
|
<li class="tabular-numbers">{{ "{:,}".format(month.paid) }} {{ message_count_label(month.paid, 'sms', '') }}at
|
||||||
{{- ' {:.2f}p'.format(sms_rate * 100) }}</li>
|
{{- ' {:.2f}p'.format(sms_rate * 100) }}</li>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% if not (month.free or month.paid) %}
|
{% if not (month.free or month.paid) %}
|
||||||
@@ -113,8 +114,8 @@
|
|||||||
<ul>
|
<ul>
|
||||||
{% for letter in month.letters%}
|
{% for letter in month.letters%}
|
||||||
{% if letter[0] %}
|
{% if letter[0] %}
|
||||||
<li class="tabular-numbers">{{ "{:,}".format(letter[0])}} letters at {{ '{:.0f}p'.format(letter[1] * 100) }}
|
<li class="tabular-numbers">{{ "{:,} {}".format(letter[0], letter[3])}} class {{ message_count_label(letter[0], 'letter', '') }}at
|
||||||
</li>
|
{{ '{:.0f}p'.format(letter[1] * 100) }}</li>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</ul>
|
</ul>
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
{% from "components/big-number.html" import big_number %}
|
{% from "components/big-number.html" import big_number %}
|
||||||
|
{% from "components/message-count-label.html" import message_count_label %}
|
||||||
{% from "components/table.html" import list_table, field, hidden_field_heading, row_heading, text_field %}
|
{% from "components/table.html" import list_table, field, hidden_field_heading, row_heading, text_field %}
|
||||||
{% from "components/pill.html" import pill %}
|
{% from "components/pill.html" import pill %}
|
||||||
|
|
||||||
@@ -83,10 +84,10 @@
|
|||||||
) }}
|
) }}
|
||||||
<ul>
|
<ul>
|
||||||
{% if month.free %}
|
{% if month.free %}
|
||||||
<li class="tabular-numbers">{{ "{:,}".format(month.free) }} free text messages</li>
|
<li class="tabular-numbers">{{ "{:,}".format(month.free) }} free {{ message_count_label(month.free, 'sms', '') }}</li>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% if month.paid %}
|
{% if month.paid %}
|
||||||
<li class="tabular-numbers">{{ "{:,}".format(month.paid) }} text messages at
|
<li class="tabular-numbers">{{ "{:,}".format(month.paid) }} {{ message_count_label(month.free, 'sms', '') }}at
|
||||||
{{- ' {:.2f}p'.format(sms_rate * 100) }}</li>
|
{{- ' {:.2f}p'.format(sms_rate * 100) }}</li>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% if not (month.free or month.paid) %}
|
{% if not (month.free or month.paid) %}
|
||||||
|
|||||||
@@ -808,8 +808,35 @@ def test_usage_page_with_letters(
|
|||||||
assert '140 free text messages' in table
|
assert '140 free text messages' in table
|
||||||
assert '£20.30' in table
|
assert '£20.30' in table
|
||||||
assert '1,230 text messages at 1.65p' in table
|
assert '1,230 text messages at 1.65p' in table
|
||||||
assert '10 letters at 31p' in table
|
assert '10 second class letters at 31p' in normalize_spaces(table)
|
||||||
assert '5 letters at 33p' in table
|
assert '5 first class letters at 33p' in normalize_spaces(table)
|
||||||
|
|
||||||
|
|
||||||
|
@freeze_time("2012-04-30 12:12:12")
|
||||||
|
def test_usage_page_displays_letters_ordered_by_postage(
|
||||||
|
mocker,
|
||||||
|
logged_in_client,
|
||||||
|
service_one,
|
||||||
|
mock_get_usage,
|
||||||
|
mock_get_free_sms_fragment_limit
|
||||||
|
):
|
||||||
|
billable_units_resp = [
|
||||||
|
{'month': 'April', 'notification_type': 'letter', 'rate': 0.5, 'billing_units': 1, 'postage': 'second'},
|
||||||
|
{'month': 'April', 'notification_type': 'letter', 'rate': 0.3, 'billing_units': 3, 'postage': 'second'},
|
||||||
|
{'month': 'April', 'notification_type': 'letter', 'rate': 0.5, 'billing_units': 1, 'postage': 'first'},
|
||||||
|
]
|
||||||
|
mocker.patch('app.billing_api_client.get_billable_units_ft', return_value=billable_units_resp)
|
||||||
|
service_one['permissions'].append('letter')
|
||||||
|
response = logged_in_client.get(url_for('main.usage', service_id=SERVICE_ONE_ID))
|
||||||
|
|
||||||
|
page = BeautifulSoup(response.data.decode('utf-8'), 'html.parser')
|
||||||
|
row_for_april = page.find('table').find('tr', class_='table-row')
|
||||||
|
postage_details = row_for_april.find_all('li', class_='tabular-numbers')
|
||||||
|
|
||||||
|
assert len(postage_details) == 3
|
||||||
|
assert normalize_spaces(postage_details[0].text) == '1 first class letter at 50p'
|
||||||
|
assert normalize_spaces(postage_details[1].text) == '3 second class letters at 30p'
|
||||||
|
assert normalize_spaces(postage_details[2].text) == '1 second class letter at 50p'
|
||||||
|
|
||||||
|
|
||||||
def test_usage_page_with_year_argument(
|
def test_usage_page_with_year_argument(
|
||||||
|
|||||||
@@ -2278,16 +2278,11 @@ def mock_get_template_statistics_for_template(mocker, service_one):
|
|||||||
def mock_get_usage(mocker, service_one, fake_uuid):
|
def mock_get_usage(mocker, service_one, fake_uuid):
|
||||||
def _get_usage(service_id, year=None):
|
def _get_usage(service_id, year=None):
|
||||||
return [
|
return [
|
||||||
{"international": False, "rate": 0.00, "notification_type": "email",
|
{"notification_type": "email", "billing_units": 1000, "rate": 0.00, "letter_total": 0},
|
||||||
"rate_multiplier": None, "billing_units": 1000},
|
{"notification_type": "sms", "billing_units": 251500, "rate": 0.0165, "letter_total": 0},
|
||||||
{"international": False, "rate": 0.0165, "rate_multiplier": 1,
|
{"notification_type": "sms", "billing_units": 300, "rate": 0.0165, "letter_total": 0},
|
||||||
"notification_type": "sms", "billing_units": 251500},
|
{"notification_type": "sms", "billing_units": 300, "rate": 0.0165, "letter_total": 0},
|
||||||
{"international": True, "rate": 0.0165, "rate_multiplier": 1,
|
{"notification_type": "sms", "billing_units": 90, "rate": 0.0165, "letter_total": 0}
|
||||||
"notification_type": "sms", "billing_units": 300},
|
|
||||||
{"international": True, "rate": 0.0165, "rate_multiplier": 2,
|
|
||||||
"notification_type": "sms", "billing_units": 150},
|
|
||||||
{"international": True, "rate": 0.0165, "rate_multiplier": 3,
|
|
||||||
"notification_type": "sms", "billing_units": 30},
|
|
||||||
]
|
]
|
||||||
|
|
||||||
return mocker.patch(
|
return mocker.patch(
|
||||||
@@ -2300,99 +2295,87 @@ def mock_get_billable_units(mocker):
|
|||||||
return [
|
return [
|
||||||
{
|
{
|
||||||
'month': 'April',
|
'month': 'April',
|
||||||
'international': False,
|
|
||||||
'rate_multiplier': 1,
|
|
||||||
'notification_type': 'sms',
|
'notification_type': 'sms',
|
||||||
'rate': 0.0165,
|
'rate': 0.0165,
|
||||||
'billing_units': 249500
|
'billing_units': 249500,
|
||||||
|
'postage': 'none',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
'month': 'April',
|
'month': 'April',
|
||||||
'international': True,
|
|
||||||
'rate_multiplier': 1,
|
|
||||||
'notification_type': 'sms',
|
'notification_type': 'sms',
|
||||||
'rate': 0.0165,
|
'rate': 0.0165,
|
||||||
'billing_units': 100
|
'billing_units': 100,
|
||||||
|
'postage': 'none',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
'month': 'April',
|
'month': 'April',
|
||||||
'international': True,
|
|
||||||
'rate_multiplier': 2,
|
|
||||||
'notification_type': 'sms',
|
'notification_type': 'sms',
|
||||||
'rate': 0.0165,
|
'rate': 0.0165,
|
||||||
'billing_units': 100
|
'billing_units': 200,
|
||||||
|
'postage': 'none',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
'month': 'April',
|
'month': 'April',
|
||||||
'international': True,
|
|
||||||
'rate_multiplier': 3,
|
|
||||||
'notification_type': 'sms',
|
'notification_type': 'sms',
|
||||||
'rate': 0.0165,
|
'rate': 0.0165,
|
||||||
'billing_units': 20
|
'billing_units': 60,
|
||||||
|
'postage': 'none',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
'month': 'March',
|
'month': 'March',
|
||||||
'international': False,
|
|
||||||
'rate_multiplier': 1,
|
|
||||||
'notification_type': 'sms',
|
'notification_type': 'sms',
|
||||||
'rate': 0.0165,
|
'rate': 0.0165,
|
||||||
'billing_units': 1000
|
'billing_units': 1000,
|
||||||
|
'postage': 'none',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
'month': 'March',
|
'month': 'March',
|
||||||
'international': True,
|
|
||||||
'rate_multiplier': 1,
|
|
||||||
'notification_type': 'sms',
|
'notification_type': 'sms',
|
||||||
'rate': 0.0165,
|
'rate': 0.0165,
|
||||||
'billing_units': 100
|
'billing_units': 100,
|
||||||
|
'postage': 'none',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
'month': 'March',
|
'month': 'March',
|
||||||
'international': True,
|
|
||||||
'rate_multiplier': 2,
|
|
||||||
'notification_type': 'sms',
|
'notification_type': 'sms',
|
||||||
'rate': 0.0165,
|
'rate': 0.0165,
|
||||||
'billing_units': 50
|
'billing_units': 100,
|
||||||
|
'postage': 'none',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
'month': 'March',
|
'month': 'March',
|
||||||
'international': True,
|
|
||||||
'rate_multiplier': 3,
|
|
||||||
'notification_type': 'sms',
|
'notification_type': 'sms',
|
||||||
'rate': 0.0165,
|
'rate': 0.0165,
|
||||||
'billing_units': 10
|
'billing_units': 30,
|
||||||
|
'postage': 'none',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
'month': 'February',
|
'month': 'February',
|
||||||
'international': False,
|
|
||||||
'rate_multiplier': 1,
|
|
||||||
'notification_type': 'sms',
|
'notification_type': 'sms',
|
||||||
'rate': 0.0165,
|
'rate': 0.0165,
|
||||||
'billing_units': 1000
|
'billing_units': 1000,
|
||||||
|
'postage': 'none',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
'month': 'February',
|
'month': 'February',
|
||||||
'international': True,
|
|
||||||
'rate_multiplier': 1,
|
|
||||||
'notification_type': 'sms',
|
'notification_type': 'sms',
|
||||||
'rate': 0.0165,
|
'rate': 0.0165,
|
||||||
'billing_units': 100
|
'billing_units': 100,
|
||||||
|
'postage': 'none',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
'month': 'February',
|
'month': 'February',
|
||||||
'international': False,
|
|
||||||
'rate_multiplier': 1,
|
|
||||||
'notification_type': 'letter',
|
'notification_type': 'letter',
|
||||||
'rate': 0.31,
|
'rate': 0.31,
|
||||||
'billing_units': 10
|
'billing_units': 10,
|
||||||
|
'postage': 'second',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
'month': 'February',
|
'month': 'February',
|
||||||
'international': False,
|
|
||||||
'rate_multiplier': 1,
|
|
||||||
'notification_type': 'letter',
|
'notification_type': 'letter',
|
||||||
'rate': 0.33,
|
'rate': 0.33,
|
||||||
'billing_units': 5
|
'billing_units': 5,
|
||||||
|
'postage': 'first',
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
||||||
@@ -2405,12 +2388,12 @@ def mock_get_future_usage(mocker, service_one, fake_uuid):
|
|||||||
def _get_usage(service_id, year=None):
|
def _get_usage(service_id, year=None):
|
||||||
return [
|
return [
|
||||||
{
|
{
|
||||||
'notification_type': 'sms', 'international': False,
|
'notification_type': 'sms', 'billing_units': 0,
|
||||||
'credits': 0, 'rate_multiplier': 1, 'rate': 0.0158, 'billing_units': 0
|
'rate': 0.0158, 'letter_total': 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
'notification_type': 'email', 'international': False,
|
'notification_type': 'email', 'billing_units': 0,
|
||||||
'credits': 0, 'rate_multiplier': 1, 'rate': 0, 'billing_units': 0
|
'rate': 0.0, 'letter_total': 0
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user