Use new functions for monthly usage API

This starts work towards replacing the manual free allowance and
cost calculations currently done in Admin.
This commit is contained in:
Ben Thorner
2022-04-20 18:13:22 +01:00
parent 106da583ea
commit e276e8a15c
4 changed files with 51 additions and 45 deletions

View File

@@ -17,7 +17,9 @@ def serialize_ft_billing_remove_emails(rows):
{
"month": (datetime.strftime(row.month, "%B")),
"notification_type": row.notification_type,
# TEMPORARY: while we migrate to "chargeable_units" in the Admin app
"billing_units": row.billable_units,
"chargeable_units": row.chargeable_units,
"rate": float(row.rate),
"postage": row.postage,
}

View File

@@ -224,7 +224,7 @@ def fetch_billing_totals_for_year(service_id, year):
def fetch_monthly_billing_for_year(service_id, year):
year_start, year_end = get_financial_year_dates(year)
_, year_end = get_financial_year_dates(year)
today = convert_utc_to_bst(datetime.utcnow()).date()
# if year end date is less than today, we are calculating for data in the past and have no need for deltas.
@@ -233,57 +233,42 @@ def fetch_monthly_billing_for_year(service_id, year):
for d in data:
update_fact_billing(data=d, process_day=today)
email_and_letters = db.session.query(
func.date_trunc('month', FactBilling.bst_date).cast(Date).label("month"),
func.sum(FactBilling.notifications_sent).label("notifications_sent"),
func.sum(FactBilling.notifications_sent).label("billable_units"),
FactBilling.rate.label('rate'),
FactBilling.notification_type.label('notification_type'),
FactBilling.postage
).filter(
FactBilling.service_id == service_id,
FactBilling.bst_date >= year_start,
FactBilling.bst_date <= year_end,
FactBilling.notification_type.in_([EMAIL_TYPE, LETTER_TYPE])
).group_by(
'month',
FactBilling.rate,
FactBilling.notification_type,
FactBilling.postage
)
sms = db.session.query(
func.date_trunc('month', FactBilling.bst_date).cast(Date).label("month"),
func.sum(FactBilling.notifications_sent).label("notifications_sent"),
func.sum(FactBilling.billable_units * FactBilling.rate_multiplier).label("billable_units"),
FactBilling.rate,
FactBilling.notification_type,
FactBilling.postage
).filter(
FactBilling.service_id == service_id,
FactBilling.bst_date >= year_start,
FactBilling.bst_date <= year_end,
FactBilling.notification_type == SMS_TYPE
).group_by(
'month',
FactBilling.rate,
FactBilling.notification_type,
FactBilling.postage
)
yearly_data = email_and_letters.union_all(sms).order_by(
'month',
'notification_type',
'rate'
return db.session.query(
union(*[
db.session.query(
func.date_trunc('month', query.c.bst_date).cast(Date).label("month"),
func.sum(query.c.notifications_sent).label("notifications_sent"),
# TEMPORARY: while we switch to "chargeable units"
func.sum(query.c.chargeable_units).label("billable_units"),
func.sum(query.c.chargeable_units).label("chargeable_units"),
query.c.rate.label("rate"),
query.c.postage.label("postage"),
query.c.notification_type.label("notification_type"),
).group_by(
query.c.rate,
query.c.notification_type,
query.c.postage,
'month',
)
for query in [
query_service_sms_usage_for_year(service_id, year).subquery(),
query_service_email_usage_for_year(service_id, year).subquery(),
query_service_letter_usage_for_year(service_id, year).subquery(),
]
]).subquery()
).order_by(
"month",
"notification_type",
"rate",
).all()
return yearly_data
def query_service_email_usage_for_year(service_id, year):
year_start, year_end = get_financial_year_dates(year)
return db.session.query(
FactBilling.bst_date,
FactBilling.postage, # should always be "none"
FactBilling.notifications_sent,
FactBilling.notifications_sent.label("chargeable_units"),
FactBilling.rate,
@@ -301,6 +286,8 @@ def query_service_letter_usage_for_year(service_id, year):
year_start, year_end = get_financial_year_dates(year)
return db.session.query(
FactBilling.bst_date,
FactBilling.postage,
FactBilling.notifications_sent,
FactBilling.notifications_sent.label("chargeable_units"),
FactBilling.rate,
@@ -339,6 +326,8 @@ def query_service_sms_usage_for_year(service_id, year):
)
return db.session.query(
FactBilling.bst_date,
FactBilling.postage, # should always be "none"
FactBilling.notifications_sent,
chargeable_units.label("chargeable_units"),
FactBilling.rate,

View File

@@ -147,6 +147,8 @@ def set_up_monthly_data():
billable_unit=1,
rate=0.33,
postage='second')
create_annual_billing(service_id=service.id, free_sms_fragment_limit=4, financial_year_start=2016)
return service
@@ -170,12 +172,14 @@ def test_get_yearly_usage_by_monthly_from_ft_billing(admin_request, notify_db_se
assert letter_row["month"] == "April"
assert letter_row["notification_type"] == "letter"
assert letter_row["billing_units"] == 30
assert letter_row["chargeable_units"] == 30
assert letter_row["rate"] == 0.33
assert letter_row["postage"] == "second"
assert sms_row["month"] == "April"
assert sms_row["notification_type"] == "sms"
assert sms_row["billing_units"] == 30
assert sms_row["chargeable_units"] == 30
assert sms_row["rate"] == 0.162
assert sms_row["postage"] == "none"

View File

@@ -417,6 +417,7 @@ def test_get_rate_for_letters_when_page_count_is_zero(notify_db_session):
def test_fetch_monthly_billing_for_year(notify_db_session):
service = set_up_yearly_data()
create_annual_billing(service_id=service.id, free_sms_fragment_limit=10, financial_year_start=2016)
results = fetch_monthly_billing_for_year(service.id, 2016)
assert len(results) == 48
@@ -425,24 +426,28 @@ def test_fetch_monthly_billing_for_year(notify_db_session):
assert results[0].notification_type == 'email'
assert results[0].notifications_sent == 30
assert results[0].billable_units == 30
assert results[0].chargeable_units == 30
assert results[0].rate == Decimal('0')
assert str(results[1].month) == "2016-04-01"
assert results[1].notification_type == 'letter'
assert results[1].notifications_sent == 30
assert results[1].billable_units == 30
assert results[1].chargeable_units == 30
assert results[1].rate == Decimal('0.30')
assert str(results[1].month) == "2016-04-01"
assert results[2].notification_type == 'letter'
assert results[2].notifications_sent == 30
assert results[2].billable_units == 30
assert results[2].chargeable_units == 30
assert results[2].rate == Decimal('0.33')
assert str(results[3].month) == "2016-04-01"
assert results[3].notification_type == 'sms'
assert results[3].notifications_sent == 30
assert results[3].billable_units == 30
assert results[3].chargeable_units == 30
assert results[3].rate == Decimal('0.162')
assert str(results[4].month) == "2016-05-01"
@@ -451,6 +456,7 @@ def test_fetch_monthly_billing_for_year(notify_db_session):
def test_fetch_monthly_billing_for_year_variable_rates(notify_db_session):
service = set_up_yearly_data_variable_rates()
create_annual_billing(service_id=service.id, free_sms_fragment_limit=6, financial_year_start=2018)
results = fetch_monthly_billing_for_year(service.id, 2018)
# Test data is only for the month of May
@@ -460,24 +466,28 @@ def test_fetch_monthly_billing_for_year_variable_rates(notify_db_session):
assert results[0].notification_type == 'letter'
assert results[0].notifications_sent == 1
assert results[0].billable_units == 1
assert results[0].chargeable_units == 1
assert results[0].rate == Decimal('0.33')
assert str(results[1].month) == "2018-05-01"
assert results[1].notification_type == 'letter'
assert results[1].notifications_sent == 1
assert results[1].billable_units == 1
assert results[1].chargeable_units == 1
assert results[1].rate == Decimal('0.36')
assert str(results[2].month) == "2018-05-01"
assert results[2].notification_type == 'sms'
assert results[2].notifications_sent == 1
assert results[2].billable_units == 4
assert results[2].chargeable_units == 4
assert results[2].rate == Decimal('0.015')
assert str(results[3].month) == "2018-05-01"
assert results[3].notification_type == 'sms'
assert results[3].notifications_sent == 2
assert results[3].billable_units == 5
assert results[3].chargeable_units == 5
assert results[3].rate == Decimal('0.162')
@@ -487,6 +497,7 @@ def test_fetch_monthly_billing_for_year_adds_data_for_today(notify_db_session):
template = create_template(service=service, template_type="sms")
create_rate(start_date=datetime.utcnow() - timedelta(days=1), value=0.158, notification_type='sms')
create_annual_billing(service_id=service.id, free_sms_fragment_limit=1000, financial_year_start=2018)
for i in range(1, 32):
create_ft_billing(bst_date='2018-07-{}'.format(i), template=template)