mirror of
https://github.com/GSA/notifications-api.git
synced 2026-05-27 17:38:17 -04:00
Only return the usage data for live services.
The list of trail mode services is only for platform admins, therefore the usage isn't needed for that page.
This commit is contained in:
@@ -12,7 +12,7 @@ from app.dao.date_util import (
|
||||
get_financial_year,
|
||||
get_financial_year_for_datetime
|
||||
)
|
||||
from app.dao.organisation_dao import dao_get_organisation_services
|
||||
from app.dao.organisation_dao import dao_get_organisation_live_services
|
||||
|
||||
from app.models import (
|
||||
FactBilling,
|
||||
@@ -187,7 +187,6 @@ def fetch_letter_line_items_for_all_services(start_date, end_date):
|
||||
|
||||
@statsd(namespace="dao")
|
||||
def fetch_billing_totals_for_year(service_id, year):
|
||||
print("fetch_billing_totals_for_year", year)
|
||||
year_start_date, year_end_date = get_financial_year(year)
|
||||
"""
|
||||
Billing for email: only record the total number of emails.
|
||||
@@ -541,3 +540,154 @@ def create_billing_record(data, rate, process_day):
|
||||
postage=data.postage,
|
||||
)
|
||||
return billing_record
|
||||
|
||||
|
||||
def fetch_letter_costs_for_organisation(organisation_id, start_date, end_date):
|
||||
query = db.session.query(
|
||||
Service.name.label("service_name"),
|
||||
Service.id.label("service_id"),
|
||||
func.sum(FactBilling.notifications_sent * FactBilling.rate).label("letter_cost")
|
||||
).select_from(
|
||||
Service
|
||||
).join(
|
||||
FactBilling, FactBilling.service_id == Service.id,
|
||||
).filter(
|
||||
FactBilling.service_id == Service.id,
|
||||
FactBilling.bst_date >= start_date,
|
||||
FactBilling.bst_date <= end_date,
|
||||
FactBilling.notification_type == LETTER_TYPE,
|
||||
Service.organisation_id == organisation_id
|
||||
).group_by(
|
||||
Service.id,
|
||||
Service.name,
|
||||
).order_by(
|
||||
Service.name
|
||||
)
|
||||
|
||||
return query.all()
|
||||
|
||||
|
||||
def fetch_email_usage_for_organisation(organisation_id, start_date, end_date):
|
||||
query = db.session.query(
|
||||
Service.name.label("service_name"),
|
||||
Service.id.label("service_id"),
|
||||
func.sum(FactBilling.notifications_sent).label("emails_sent")
|
||||
).select_from(
|
||||
Service
|
||||
).join(
|
||||
FactBilling, FactBilling.service_id == Service.id,
|
||||
).filter(
|
||||
FactBilling.service_id == Service.id,
|
||||
FactBilling.bst_date >= start_date,
|
||||
FactBilling.bst_date <= end_date,
|
||||
FactBilling.notification_type == EMAIL_TYPE,
|
||||
Service.organisation_id == organisation_id
|
||||
).group_by(
|
||||
Service.id,
|
||||
Service.name,
|
||||
).order_by(
|
||||
Service.name
|
||||
)
|
||||
|
||||
return query.all()
|
||||
|
||||
|
||||
@statsd(namespace="dao")
|
||||
def fetch_sms_billing_for_organisation(organisation_id, start_date, end_date):
|
||||
|
||||
# ASSUMPTION: AnnualBilling has been populated for year.
|
||||
free_allowance_remainder = fetch_sms_free_allowance_remainder(start_date).subquery()
|
||||
|
||||
sms_billable_units = func.sum(FactBilling.billable_units * FactBilling.rate_multiplier)
|
||||
sms_remainder = func.coalesce(
|
||||
free_allowance_remainder.c.sms_remainder,
|
||||
free_allowance_remainder.c.free_sms_fragment_limit
|
||||
)
|
||||
chargeable_sms = func.greatest(sms_billable_units - sms_remainder, 0)
|
||||
sms_cost = chargeable_sms * FactBilling.rate
|
||||
|
||||
query = db.session.query(
|
||||
Service.name.label("service_name"),
|
||||
Service.id.label("service_id"),
|
||||
free_allowance_remainder.c.free_sms_fragment_limit,
|
||||
FactBilling.rate.label('sms_rate'),
|
||||
sms_remainder.label("sms_remainder"),
|
||||
sms_billable_units.label('sms_billable_units'),
|
||||
chargeable_sms.label("chargeable_billable_sms"),
|
||||
sms_cost.label('sms_cost'),
|
||||
).select_from(
|
||||
Service
|
||||
).outerjoin(
|
||||
free_allowance_remainder, Service.id == free_allowance_remainder.c.service_id
|
||||
).join(
|
||||
FactBilling, FactBilling.service_id == Service.id,
|
||||
).filter(
|
||||
FactBilling.bst_date >= start_date,
|
||||
FactBilling.bst_date <= end_date,
|
||||
FactBilling.notification_type == SMS_TYPE,
|
||||
Service.organisation_id == organisation_id
|
||||
).group_by(
|
||||
Service.id,
|
||||
Service.name,
|
||||
free_allowance_remainder.c.free_sms_fragment_limit,
|
||||
free_allowance_remainder.c.sms_remainder,
|
||||
FactBilling.rate,
|
||||
).order_by(
|
||||
Service.name
|
||||
)
|
||||
|
||||
return query.all()
|
||||
|
||||
|
||||
def fetch_usage_year_for_organisation(organisation_id, year):
|
||||
year_start_datetime, year_end_datetime = get_financial_year(year)
|
||||
|
||||
year_start_date = convert_utc_to_bst(year_start_datetime).date()
|
||||
year_end_date = convert_utc_to_bst(year_end_datetime).date()
|
||||
|
||||
today = convert_utc_to_bst(datetime.utcnow()).date()
|
||||
services = dao_get_organisation_live_services(organisation_id)
|
||||
# if year end date is less than today, we are calculating for data in the past and have no need for deltas.
|
||||
if year_end_date >= today:
|
||||
yesterday = today - timedelta(days=1)
|
||||
for service in services:
|
||||
for day in [yesterday, today]:
|
||||
data = fetch_billing_data_for_day(process_day=day, service_id=service.id)
|
||||
for d in data:
|
||||
update_fact_billing(data=d, process_day=day)
|
||||
service_with_usage = {}
|
||||
# initialise results
|
||||
for service in services:
|
||||
service_with_usage[str(service.id)] = {
|
||||
'service_id': service.id,
|
||||
'service_name': service.name,
|
||||
'free_sms_limit': 0,
|
||||
'sms_remainder': 0,
|
||||
'sms_billable_units': 0,
|
||||
'chargeable_billable_sms': 0,
|
||||
'sms_cost': 0,
|
||||
'letter_cost': 0,
|
||||
'emails_sent': 0
|
||||
}
|
||||
sms_usages = fetch_sms_billing_for_organisation(organisation_id, year_start_date, year_end_date)
|
||||
letter_usages = fetch_letter_costs_for_organisation(organisation_id, year_start_date, year_end_date)
|
||||
email_usages = fetch_email_usage_for_organisation(organisation_id, year_start_date, year_end_date)
|
||||
|
||||
for usage in sms_usages:
|
||||
service_with_usage[str(usage.service_id)] = {
|
||||
'service_id': usage.service_id,
|
||||
'service_name': usage.service_name,
|
||||
'free_sms_limit': usage.free_sms_fragment_limit,
|
||||
'sms_remainder': usage.sms_remainder,
|
||||
'sms_billable_units': usage.sms_billable_units,
|
||||
'chargeable_billable_sms': usage.chargeable_billable_sms,
|
||||
'sms_cost': usage.sms_cost,
|
||||
'letter_cost': 0,
|
||||
'emails_sent': 0
|
||||
}
|
||||
for letter_usage in letter_usages:
|
||||
service_with_usage[str(letter_usage.service_id)]['letter_cost'] = letter_usage.letter_cost
|
||||
for email_usage in email_usages:
|
||||
service_with_usage[str(email_usage.service_id)]['emails_sent'] = email_usage.emails_sent
|
||||
|
||||
return service_with_usage
|
||||
|
||||
@@ -31,6 +31,13 @@ def dao_get_organisation_services(organisation_id):
|
||||
).one().services
|
||||
|
||||
|
||||
def dao_get_organisation_live_services(organisation_id):
|
||||
return Service.query.filter_by(
|
||||
organisation_id=organisation_id,
|
||||
restricted=False
|
||||
).all()
|
||||
|
||||
|
||||
def dao_get_organisation_by_id(organisation_id):
|
||||
return Organisation.query.filter_by(id=organisation_id).one()
|
||||
|
||||
|
||||
@@ -634,7 +634,62 @@ def test_fetch_letter_line_items_for_all_service(notify_db_session):
|
||||
def test_fetch_usage_year_for_organisation(notify_db_session):
|
||||
org, org_2, service, service_2, service_3, service_sms_only, \
|
||||
org_with_emails, service_with_emails = set_up_usage_data(datetime(2019, 5, 1))
|
||||
|
||||
service_with_emails_for_org = create_service(service_name='Service with emails for org')
|
||||
dao_add_service_to_organisation(service=service_with_emails_for_org, organisation_id=org.id)
|
||||
template = create_template(service=service_with_emails_for_org, template_type='email')
|
||||
create_ft_billing(bst_date=datetime(2019, 5, 1),
|
||||
template=template,
|
||||
notifications_sent=1100)
|
||||
results = fetch_usage_year_for_organisation(org.id, 2019)
|
||||
results = fetch_usage_year_for_organisation(org_2.id, 2019)
|
||||
results = fetch_usage_year_for_organisation(org_with_emails.id, 2019)
|
||||
|
||||
assert len(results) == 2
|
||||
first_row = results[str(service.id)]
|
||||
assert first_row['service_id'] == service.id
|
||||
assert first_row['service_name'] == service.name
|
||||
assert first_row['free_sms_limit'] == 10
|
||||
assert first_row['sms_remainder'] == 10
|
||||
assert first_row['chargeable_billable_sms'] == 0
|
||||
assert first_row['sms_cost'] == Decimal('0.0')
|
||||
assert first_row['letter_cost'] == Decimal('3.40')
|
||||
assert first_row['emails_sent'] == 0
|
||||
|
||||
second_row = results[str(service_with_emails_for_org.id)]
|
||||
assert second_row['service_id'] == service_with_emails_for_org.id
|
||||
assert second_row['service_name'] == service_with_emails_for_org.name
|
||||
assert second_row['free_sms_limit'] == 0
|
||||
assert second_row['sms_remainder'] == 0
|
||||
assert second_row['chargeable_billable_sms'] == 0
|
||||
assert second_row['sms_cost'] == 0
|
||||
assert second_row['letter_cost'] == 0
|
||||
assert second_row['emails_sent'] == 1100
|
||||
|
||||
|
||||
def test_fetch_usage_year_for_organisation_populates_ft_billing_for_today(notify_db_session):
|
||||
create_letter_rate(start_date=datetime.utcnow() - timedelta(days=1))
|
||||
create_rate(start_date=datetime.utcnow() - timedelta(days=1), value=0.65, notification_type='sms')
|
||||
new_org = create_organisation(name='New organisation')
|
||||
service = create_service()
|
||||
template = create_template(service=service)
|
||||
dao_add_service_to_organisation(service=service, organisation_id=new_org.id)
|
||||
current_year = datetime.utcnow().year
|
||||
create_annual_billing(service_id=service.id, free_sms_fragment_limit=10, financial_year_start=current_year)
|
||||
|
||||
assert FactBilling.query.count() == 0
|
||||
|
||||
create_notification(template=template, status='delivered')
|
||||
|
||||
results = fetch_usage_year_for_organisation(organisation_id=new_org.id, year=current_year)
|
||||
assert len(results) == 1
|
||||
assert FactBilling.query.count() == 1
|
||||
|
||||
|
||||
def test_fetch_usage_year_for_organisation_only_returns_data_for_live_services(notify_db_session):
|
||||
org = create_organisation(name='Organisation without live services')
|
||||
service = create_service(restricted=True)
|
||||
template = create_template(service=service)
|
||||
dao_add_service_to_organisation(service=service, organisation_id=org.id)
|
||||
create_ft_billing(bst_date=datetime.utcnow().date(), template=template, billable_unit=19, notifications_sent=19)
|
||||
|
||||
results = fetch_usage_year_for_organisation(organisation_id=org.id, year=datetime.utcnow().year)
|
||||
|
||||
assert len(results) == 0
|
||||
|
||||
Reference in New Issue
Block a user