Add join to LetterRates for the billing query.

Fix the yearly totals to work for letters.
This commit is contained in:
Rebecca Law
2017-12-18 16:46:59 +00:00
parent ec28f48968
commit c4d869175a
3 changed files with 68 additions and 24 deletions

View File

@@ -7,7 +7,7 @@ from app.dao.monthly_billing_dao import (
get_billing_data_for_financial_year,
get_monthly_billing_by_notification_type
)
from app.dao.date_util import get_financial_year, get_months_for_financial_year
from app.dao.date_util import get_months_for_financial_year
from app.errors import register_errors
from app.models import SMS_TYPE, EMAIL_TYPE, LETTER_TYPE
from app.utils import convert_utc_to_bst
@@ -34,15 +34,14 @@ register_errors(billing_blueprint)
def get_yearly_usage_by_month(service_id):
try:
year = int(request.args.get('year'))
start_date, end_date = get_financial_year(year)
results = []
for month in get_months_for_financial_year(year):
billing_for_month = get_monthly_billing_by_notification_type(service_id, month, SMS_TYPE)
if billing_for_month:
results.append(_transform_billing_for_month(billing_for_month))
results.append(_transform_billing_for_month_sms(billing_for_month))
letter_billing_for_month = get_monthly_billing_by_notification_type(service_id, month, LETTER_TYPE)
if letter_billing_for_month:
results.append(_transform_billing_for_month(letter_billing_for_month))
results.extend(_transform_billing_for_month_letters(letter_billing_for_month))
return json.dumps(results)
except TypeError:
@@ -69,21 +68,29 @@ def get_yearly_billing_usage_summary(service_id):
def _get_total_billable_units_and_rate_for_notification_type(billing_data, noti_type):
total_sent = 0
rate = 0
letter_total = 0
for entry in billing_data:
for monthly_total in entry.monthly_totals:
if entry.notification_type == noti_type:
total_sent += monthly_total['billing_units'] \
if noti_type == EMAIL_TYPE else (monthly_total['billing_units'] * monthly_total['rate_multiplier'])
if entry.notification_type == EMAIL_TYPE:
total_sent += monthly_total['billing_units']
rate = monthly_total['rate']
elif entry.notification_type == SMS_TYPE:
total_sent += (monthly_total['billing_units'] * monthly_total['rate_multiplier'])
rate = monthly_total['rate']
elif entry.notification_type == LETTER_TYPE:
total_sent += monthly_total['billing_units']
letter_total += (monthly_total['billing_units'] * monthly_total['rate'])
return {
"notification_type": noti_type,
"billing_units": total_sent,
"rate": rate
"rate": rate,
"letter_total": letter_total
}
def _transform_billing_for_month(billing_for_month):
def _transform_billing_for_month_sms(billing_for_month):
month_name = datetime.strftime(convert_utc_to_bst(billing_for_month.start_date), "%B")
billing_units = rate = 0
@@ -99,6 +106,28 @@ def _transform_billing_for_month(billing_for_month):
}
def _transform_billing_for_month_letters(billing_for_month):
month_name = datetime.strftime(convert_utc_to_bst(billing_for_month.start_date), "%B")
x = list()
for total in billing_for_month.monthly_totals:
y = {
"month": month_name,
"billing_units": (total['billing_units'] * total['rate_multiplier']),
"notification_type": billing_for_month.notification_type,
"rate": total['rate']
}
x.append(y)
if len(billing_for_month.monthly_totals) == 0:
x.append({
"month": month_name,
"billing_units": 0,
"notification_type": billing_for_month.notification_type,
"rate": 0
})
return x
@billing_blueprint.route('/free-sms-fragment-limit', methods=["GET"])
def get_free_sms_fragment_limit(service_id):

View File

@@ -1,6 +1,6 @@
from datetime import datetime, timedelta
from sqlalchemy import Float, Integer
from sqlalchemy import Float, Integer, and_
from sqlalchemy import func, case, cast
from sqlalchemy import literal_column
@@ -156,12 +156,18 @@ def billing_letter_data_per_month_query(service_id, start_date, end_date):
NotificationHistory.international,
NotificationHistory.notification_type,
cast(LetterRate.rate, Float()).label('rate')
).join(
LetterRate,
and_(NotificationHistory.created_at >= LetterRate.start_date,
(LetterRate.end_date == None) | # noqa
(LetterRate.end_date > NotificationHistory.created_at))
).filter(
*billing_data_filter(LETTER_TYPE, start_date, end_date, service_id),
LetterRate.sheet_count == NotificationHistory.billable_units,
LetterRate.crown == crown,
NotificationHistory.created_at.between(LetterRate.start_date, end_date),
LetterRate.post_class == 'second'
LetterRate.post_class == 'second',
NotificationHistory.created_at < end_date,
).group_by(
NotificationHistory.notification_type,
month,

View File

@@ -3,7 +3,7 @@ import json
import pytest
from app.billing.rest import _transform_billing_for_month
from app.billing.rest import _transform_billing_for_month_sms
from app.dao.monthly_billing_dao import (
create_or_update_monthly_billing,
get_monthly_billing_by_notification_type,
@@ -16,6 +16,8 @@ from tests.app.db import (
create_rate,
create_monthly_billing_entry,
create_annual_billing,
create_letter_rate,
create_template
)
from app.billing.rest import update_free_sms_fragment_limit_data
@@ -29,8 +31,7 @@ IN_JUN_2016 = datetime(2016, 6, 3, 23, 00, 00)
def _assert_dict_equals(actual, expected_dict):
assert set(actual.keys()) == set(expected_dict.keys())
assert set(actual.values()) == set(expected_dict.values())
assert actual == expected_dict
def test_get_yearly_billing_summary_returns_correct_breakdown(client, sample_template):
@@ -43,6 +44,12 @@ def test_get_yearly_billing_summary_returns_correct_breakdown(client, sample_tem
template=sample_template, created_at=IN_JUN_2016,
billable_units=2, rate_multiplier=3, status='delivered'
)
create_letter_rate(crown=False, start_date=IN_MAY_2016, end_date=IN_JUN_2016)
create_letter_rate(crown=False, start_date=IN_JUN_2016, rate=0.41)
letter_template = create_template(service=sample_template.service, template_type=LETTER_TYPE)
create_notification(template=letter_template, created_at=IN_MAY_2016, status='delivered', billable_units=1)
create_notification(template=letter_template, created_at=IN_JUN_2016, status='delivered', billable_units=1)
create_or_update_monthly_billing(service_id=sample_template.service_id, billing_month=IN_MAY_2016)
create_or_update_monthly_billing(service_id=sample_template.service_id, billing_month=IN_JUN_2016)
@@ -59,18 +66,21 @@ def test_get_yearly_billing_summary_returns_correct_breakdown(client, sample_tem
_assert_dict_equals(resp_json[0], {
'notification_type': SMS_TYPE,
'billing_units': 8,
'rate': 0.12
'rate': 0.12,
'letter_total': 0
})
_assert_dict_equals(resp_json[1], {
'notification_type': EMAIL_TYPE,
'billing_units': 0,
'rate': 0
'rate': 0,
'letter_total': 0
})
_assert_dict_equals(resp_json[2], {
'notification_type': LETTER_TYPE,
'billing_units': 0,
'rate': 0
'billing_units': 2,
'rate': 0,
'letter_total': 0.72
})
@@ -130,7 +140,6 @@ def test_get_yearly_usage_by_month_returns_correctly(client, sample_template):
assert response.status_code == 200
resp_json = json.loads(response.get_data(as_text=True))
print(resp_json)
_assert_dict_equals(resp_json[0], {
'billing_units': 2,
'month': 'May',
@@ -167,7 +176,7 @@ def test_transform_billing_for_month_returns_empty_if_no_monthly_totals(sample_s
notification_type=SMS_TYPE
)
transformed_billing_data = _transform_billing_for_month(get_monthly_billing_by_notification_type(
transformed_billing_data = _transform_billing_for_month_sms(get_monthly_billing_by_notification_type(
sample_service.id, APR_2016_MONTH_START, SMS_TYPE
))
@@ -194,7 +203,7 @@ def test_transform_billing_for_month_formats_monthly_totals_correctly(sample_ser
notification_type=SMS_TYPE
)
transformed_billing_data = _transform_billing_for_month(get_monthly_billing_by_notification_type(
transformed_billing_data = _transform_billing_for_month_sms(get_monthly_billing_by_notification_type(
sample_service.id, APR_2016_MONTH_START, SMS_TYPE
))
@@ -229,7 +238,7 @@ def test_transform_billing_sums_billable_units(sample_service):
notification_type=SMS_TYPE
)
transformed_billing_data = _transform_billing_for_month(get_monthly_billing_by_notification_type(
transformed_billing_data = _transform_billing_for_month_sms(get_monthly_billing_by_notification_type(
sample_service.id, APR_2016_MONTH_START, SMS_TYPE
))
@@ -264,7 +273,7 @@ def test_transform_billing_calculates_with_different_rate_multipliers(sample_ser
notification_type=SMS_TYPE
)
transformed_billing_data = _transform_billing_for_month(get_monthly_billing_by_notification_type(
transformed_billing_data = _transform_billing_for_month_sms(get_monthly_billing_by_notification_type(
sample_service.id, APR_2016_MONTH_START, SMS_TYPE
))