From 0148b3dba64778a109a4bb875fee645c536e4c40 Mon Sep 17 00:00:00 2001 From: Katie Smith Date: Fri, 11 Jun 2021 11:11:47 +0100 Subject: [PATCH] Add new total_letters field to the billing report data This adds total_letters to the data that is returned by the `/platform-stats/data-for-billing-report` endpoint so that we can add total letters as a column in the CSV file that can be downloaded. --- app/dao/fact_billing_dao.py | 3 ++- app/platform_stats/rest.py | 27 ++++++++++++++++----------- tests/app/dao/test_ft_billing_dao.py | 12 ++++++------ tests/app/platform_stats/test_rest.py | 4 ++++ 4 files changed, 28 insertions(+), 18 deletions(-) diff --git a/app/dao/fact_billing_dao.py b/app/dao/fact_billing_dao.py index d88ef8b12..d580b2a39 100644 --- a/app/dao/fact_billing_dao.py +++ b/app/dao/fact_billing_dao.py @@ -114,12 +114,13 @@ def fetch_sms_billing_for_all_services(start_date, end_date): return query.all() -def fetch_letter_costs_for_all_services(start_date, end_date): +def fetch_letter_costs_and_totals_for_all_services(start_date, end_date): query = db.session.query( Organisation.name.label("organisation_name"), Organisation.id.label("organisation_id"), Service.name.label("service_name"), Service.id.label("service_id"), + func.sum(FactBilling.notifications_sent).label("total_letters"), func.sum(FactBilling.notifications_sent * FactBilling.rate).label("letter_cost") ).select_from( Service diff --git a/app/platform_stats/rest.py b/app/platform_stats/rest.py index 5ff451c94..2fdc03637 100644 --- a/app/platform_stats/rest.py +++ b/app/platform_stats/rest.py @@ -5,7 +5,7 @@ from flask import Blueprint, jsonify, request from app.dao.date_util import get_financial_year_for_datetime from app.dao.fact_billing_dao import ( fetch_billing_details_for_all_services, - fetch_letter_costs_for_all_services, + fetch_letter_costs_and_totals_for_all_services, fetch_letter_line_items_for_all_services, fetch_sms_billing_for_all_services, ) @@ -67,7 +67,7 @@ def get_data_for_billing_report(): start_date, end_date = validate_date_range_is_within_a_financial_year(start_date, end_date) sms_costs = fetch_sms_billing_for_all_services(start_date, end_date) - letter_costs = fetch_letter_costs_for_all_services(start_date, end_date) + letter_overview = fetch_letter_costs_and_totals_for_all_services(start_date, end_date) letter_breakdown = fetch_letter_line_items_for_all_services(start_date, end_date) lb_by_service = [ @@ -85,26 +85,31 @@ def get_data_for_billing_report(): "service_name": s.service_name, "sms_cost": float(s.sms_cost), "sms_fragments": s.chargeable_billable_sms, + "total_letters": 0, "letter_cost": 0, "letter_breakdown": "" } combined[s.service_id] = entry - for letter_cost in letter_costs: - if letter_cost.service_id in combined: - combined[letter_cost.service_id].update({'letter_cost': float(letter_cost.letter_cost)}) + for data in letter_overview: + if data.service_id in combined: + combined[data.service_id].update( + {'total_letters': data.total_letters, 'letter_cost': float(data.letter_cost)} + ) + else: letter_entry = { - "organisation_id": str(letter_cost.organisation_id) if letter_cost.organisation_id else "", - "organisation_name": letter_cost.organisation_name or "", - "service_id": str(letter_cost.service_id), - "service_name": letter_cost.service_name, + "organisation_id": str(data.organisation_id) if data.organisation_id else "", + "organisation_name": data.organisation_name or "", + "service_id": str(data.service_id), + "service_name": data.service_name, "sms_cost": 0, "sms_fragments": 0, - "letter_cost": float(letter_cost.letter_cost), + "total_letters": data.total_letters, + "letter_cost": float(data.letter_cost), "letter_breakdown": "" } - combined[letter_cost.service_id] = letter_entry + combined[data.service_id] = letter_entry for service_id, breakdown in lb_by_service: combined[service_id]['letter_breakdown'] += (breakdown + '\n') diff --git a/tests/app/dao/test_ft_billing_dao.py b/tests/app/dao/test_ft_billing_dao.py index 3ef4b3da5..24fbbc93c 100644 --- a/tests/app/dao/test_ft_billing_dao.py +++ b/tests/app/dao/test_ft_billing_dao.py @@ -10,7 +10,7 @@ from app.dao.fact_billing_dao import ( delete_billing_data_for_service_for_day, fetch_billing_data_for_day, fetch_billing_totals_for_year, - fetch_letter_costs_for_all_services, + fetch_letter_costs_and_totals_for_all_services, fetch_letter_line_items_for_all_services, fetch_monthly_billing_for_year, fetch_sms_billing_for_all_services, @@ -628,26 +628,26 @@ def test_fetch_sms_billing_for_all_services_without_an_organisation_appears(noti ) -def test_fetch_letter_costs_for_all_services(notify_db_session): +def test_fetch_letter_costs_and_totals_for_all_services(notify_db_session): fixtures = set_up_usage_data(datetime(2019, 6, 1)) - results = fetch_letter_costs_for_all_services(datetime(2019, 6, 1), datetime(2019, 9, 30)) + results = fetch_letter_costs_and_totals_for_all_services(datetime(2019, 6, 1), datetime(2019, 9, 30)) assert len(results) == 3 assert results[0] == ( fixtures["org_1"].name, fixtures["org_1"].id, fixtures["service_1_sms_and_letter"].name, fixtures["service_1_sms_and_letter"].id, - Decimal('3.40') + 8, Decimal('3.40') ) assert results[1] == ( fixtures["org_for_service_with_letters"].name, fixtures["org_for_service_with_letters"].id, fixtures["service_with_letters"].name, fixtures["service_with_letters"].id, - Decimal('14.00') + 22, Decimal('14.00') ) assert results[2] == ( None, None, fixtures["service_with_letters_without_org"].name, fixtures["service_with_letters_without_org"].id, - Decimal('24.45') + 18, Decimal('24.45') ) diff --git a/tests/app/platform_stats/test_rest.py b/tests/app/platform_stats/test_rest.py index afb62f01e..af78ca243 100644 --- a/tests/app/platform_stats/test_rest.py +++ b/tests/app/platform_stats/test_rest.py @@ -141,6 +141,7 @@ def test_get_data_for_billing_report(notify_db_session, admin_request): assert response[0]["service_id"] == str(fixtures["service_1_sms_and_letter"].id) assert response[0]["sms_cost"] == 0 assert response[0]["sms_fragments"] == 0 + assert response[0]["total_letters"] == 8 assert response[0]["letter_cost"] == 3.40 assert response[0]["letter_breakdown"] == "6 second class letters at 45p\n2 first class letters at 35p\n" assert response[0]["purchase_order_number"] == "service purchase order number" @@ -152,6 +153,7 @@ def test_get_data_for_billing_report(notify_db_session, admin_request): assert response[1]["service_id"] == str(fixtures["service_with_letters"].id) assert response[1]["sms_cost"] == 0 assert response[1]["sms_fragments"] == 0 + assert response[1]["total_letters"] == 22 assert response[1]["letter_cost"] == 14 assert response[1]["letter_breakdown"] == "20 second class letters at 65p\n2 first class letters at 50p\n" assert response[1]["purchase_order_number"] == "org3 purchase order number" @@ -163,6 +165,7 @@ def test_get_data_for_billing_report(notify_db_session, admin_request): assert response[2]["service_id"] == str(fixtures["service_with_sms_without_org"].id) assert response[2]["sms_cost"] == 0.33 assert response[2]["sms_fragments"] == 3 + assert response[2]["total_letters"] == 0 assert response[2]["letter_cost"] == 0 assert response[2]["letter_breakdown"] == "" assert response[2]["purchase_order_number"] == "sms purchase order number" @@ -174,6 +177,7 @@ def test_get_data_for_billing_report(notify_db_session, admin_request): assert response[3]["service_id"] == str(fixtures["service_with_letters_without_org"].id) assert response[3]["sms_cost"] == 0 assert response[3]["sms_fragments"] == 0 + assert response[3]["total_letters"] == 18 assert response[3]["letter_cost"] == 24.45 assert response[3]["letter_breakdown"] == ( "2 second class letters at 35p\n1 first class letters at 50p\n15 international letters at £1.55\n"