From 4c3d70fd5539878e704996f61c253e883e615454 Mon Sep 17 00:00:00 2001 From: Pea Tyczynska Date: Tue, 23 Feb 2021 18:37:05 +0000 Subject: [PATCH] Update usage endpoint with billing details for orgs and services --- app/dao/fact_billing_dao.py | 17 +++++++ app/platform_stats/rest.py | 17 ++++++- tests/app/db.py | 64 +++++++++++++++++++++++---- tests/app/platform_stats/test_rest.py | 20 +++++++-- 4 files changed, 104 insertions(+), 14 deletions(-) diff --git a/app/dao/fact_billing_dao.py b/app/dao/fact_billing_dao.py index 152c7397d..d6fa52519 100644 --- a/app/dao/fact_billing_dao.py +++ b/app/dao/fact_billing_dao.py @@ -683,3 +683,20 @@ def fetch_usage_year_for_organisation(organisation_id, year): service_with_usage[str(email_usage.service_id)]['emails_sent'] = email_usage.emails_sent return service_with_usage + + +def fetch_billing_details_for_all_services(): + billing_details = db.session.query( + Service.id.label('service_id'), + func.coalesce(Service.purchase_order_number, Organisation.purchase_order_number).label('purchase_order_number'), + func.coalesce(Service.billing_contact_names, Organisation.billing_contact_names).label('billing_contact_names'), + func.coalesce( + Service.billing_contact_email_addresses, + Organisation.billing_contact_email_addresses + ).label('billing_contact_email_addresses'), + func.coalesce(Service.billing_reference, Organisation.billing_reference).label('billing_reference'), + ).outerjoin( + Service.organisation + ).all() + + return billing_details diff --git a/app/platform_stats/rest.py b/app/platform_stats/rest.py index 76132400a..2c0a804c9 100644 --- a/app/platform_stats/rest.py +++ b/app/platform_stats/rest.py @@ -4,6 +4,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_line_items_for_all_services, fetch_sms_billing_for_all_services, @@ -105,12 +106,24 @@ def get_usage_for_all_services(): for service_id, breakdown in lb_by_service: combined[service_id]['letter_breakdown'] += (breakdown + '\n') + billing_details = fetch_billing_details_for_all_services() + for service in billing_details: + if service.service_id in combined: + combined[service.service_id].update({ + 'purchase_order_number': service.purchase_order_number, + 'contact_names': service.billing_contact_names, + 'contact_email_addresses': service.billing_contact_email_addresses, + 'billing_reference': service.billing_reference + }) + # sorting first by name == '' means that blank orgs will be sorted last. - return jsonify(sorted(combined.values(), key=lambda x: ( + + result = sorted(combined.values(), key=lambda x: ( x['organisation_name'] == '', x['organisation_name'], x['service_name'] - ))) + )) + return jsonify(result) def postage_description(postage): diff --git a/tests/app/db.py b/tests/app/db.py index c1cddf53d..b059cb690 100644 --- a/tests/app/db.py +++ b/tests/app/db.py @@ -126,7 +126,11 @@ def create_service( go_live_user=None, go_live_at=None, crown=True, - organisation=None + organisation=None, + purchase_order_number=None, + billing_contact_names=None, + billing_contact_email_addresses=None, + billing_reference=None, ): if check_if_service_exists: service = Service.query.filter_by(name=service_name).first() @@ -142,7 +146,11 @@ def create_service( organisation=organisation, go_live_user=go_live_user, go_live_at=go_live_at, - crown=crown + crown=crown, + purchase_order_number=purchase_order_number, + billing_contact_names=billing_contact_names, + billing_contact_email_addresses=billing_contact_email_addresses, + billing_reference=billing_reference, ) dao_create_service( service, @@ -653,12 +661,26 @@ def create_domain(domain, organisation_id): return domain -def create_organisation(name='test_org_1', active=True, organisation_type=None, domains=None, organisation_id=None): +def create_organisation( + name='test_org_1', + active=True, + organisation_type=None, + domains=None, + organisation_id=None, + purchase_order_number=None, + billing_contact_names=None, + billing_contact_email_addresses=None, + billing_reference=None, +): data = { 'id': organisation_id, 'name': name, 'active': active, 'organisation_type': organisation_type, + 'purchase_order_number': purchase_order_number, + 'billing_contact_names': billing_contact_names, + 'billing_contact_email_addresses': billing_contact_email_addresses, + 'billing_reference': billing_reference, } organisation = Organisation(**data) dao_create_organisation(organisation) @@ -927,27 +949,53 @@ def set_up_usage_data(start_date): one_week_later = start_date + timedelta(days=7) one_month_later = start_date + timedelta(days=31) - service = create_service(service_name='a - with sms and letter') + service = create_service( + service_name='a - with sms and letter', + purchase_order_number="service purchase order number", + billing_contact_names="service billing contact names", + billing_contact_email_addresses="service@billing.contact email@addresses.gov.uk", + billing_reference="service billing reference" + ) letter_template_1 = create_template(service=service, template_type='letter') sms_template_1 = create_template(service=service, template_type='sms') create_annual_billing(service_id=service.id, free_sms_fragment_limit=10, financial_year_start=year) - org = create_organisation(name="Org for {}".format(service.name)) + org = create_organisation( + name="Org for {}".format(service.name), + purchase_order_number="org1 purchase order number", + billing_contact_names="org1 billing contact names", + billing_contact_email_addresses="org1@billing.contact email@addresses.gov.uk", + billing_reference="org1 billing reference" + ) dao_add_service_to_organisation(service=service, organisation_id=org.id) service_2 = create_service(service_name='b - emails') email_template = create_template(service=service_2, template_type='email') - org_2 = create_organisation(name='Org for {}'.format(service_2.name)) + org_2 = create_organisation( + name='Org for {}'.format(service_2.name), + ) dao_add_service_to_organisation(service=service_2, organisation_id=org_2.id) service_3 = create_service(service_name='c - letters only') letter_template_3 = create_template(service=service_3, template_type='letter') - org_3 = create_organisation(name="Org for {}".format(service_3.name)) + org_3 = create_organisation( + name="Org for {}".format(service_3.name), + purchase_order_number="org3 purchase order number", + billing_contact_names="org3 billing contact names", + billing_contact_email_addresses="org3@billing.contact email@addresses.gov.uk", + billing_reference="org3 billing reference" + ) dao_add_service_to_organisation(service=service_3, organisation_id=org_3.id) service_4 = create_service(service_name='d - service without org') letter_template_4 = create_template(service=service_4, template_type='letter') - service_sms_only = create_service(service_name='b - chargeable sms') + service_sms_only = create_service( + service_name='b - chargeable sms', + purchase_order_number="sms purchase order number", + billing_contact_names="sms billing contact names", + billing_contact_email_addresses="sms@billing.contact email@addresses.gov.uk", + billing_reference="sms billing reference" + ) sms_template = create_template(service=service_sms_only, template_type='sms') create_annual_billing(service_id=service_sms_only.id, free_sms_fragment_limit=10, financial_year_start=year) diff --git a/tests/app/platform_stats/test_rest.py b/tests/app/platform_stats/test_rest.py index 663beb62c..3986fa6ae 100644 --- a/tests/app/platform_stats/test_rest.py +++ b/tests/app/platform_stats/test_rest.py @@ -127,7 +127,7 @@ def test_validate_date_is_within_a_financial_year_when_input_is_not_a_date(start def test_get_usage_for_all_services(notify_db_session, admin_request): - org, org_2, service, service_2, service_3, service_sms_only, \ + org, org_3, service, service_3, service_without_org, service_sms_only, \ org_with_emails, service_with_emails = set_up_usage_data(datetime(2019, 5, 1)) response = admin_request.get("platform_stats.get_usage_for_all_services", start_date='2019-05-01', @@ -139,13 +139,21 @@ def test_get_usage_for_all_services(notify_db_session, admin_request): assert response[0]["sms_fragments"] == 0 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" + assert response[0]["contact_names"] == "service billing contact names" + assert response[0]["contact_email_addresses"] == "service@billing.contact email@addresses.gov.uk" + assert response[0]["billing_reference"] == "service billing reference" - assert response[1]["organisation_id"] == str(org_2.id) - assert response[1]["service_id"] == str(service_2.id) + assert response[1]["organisation_id"] == str(org_3.id) + assert response[1]["service_id"] == str(service_3.id) assert response[1]["sms_cost"] == 0 assert response[1]["sms_fragments"] == 0 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" + assert response[1]["contact_names"] == "org3 billing contact names" + assert response[1]["contact_email_addresses"] == "org3@billing.contact email@addresses.gov.uk" + assert response[1]["billing_reference"] == "org3 billing reference" assert response[2]["organisation_id"] == "" assert response[2]["service_id"] == str(service_sms_only.id) @@ -153,9 +161,13 @@ def test_get_usage_for_all_services(notify_db_session, admin_request): assert response[2]["sms_fragments"] == 3 assert response[2]["letter_cost"] == 0 assert response[2]["letter_breakdown"] == "" + assert response[2]["purchase_order_number"] == "sms purchase order number" + assert response[2]["contact_names"] == "sms billing contact names" + assert response[2]["contact_email_addresses"] == "sms@billing.contact email@addresses.gov.uk" + assert response[2]["billing_reference"] == "sms billing reference" assert response[3]["organisation_id"] == "" - assert response[3]["service_id"] == str(service_3.id) + assert response[3]["service_id"] == str(service_without_org.id) assert response[3]["sms_cost"] == 0 assert response[3]["sms_fragments"] == 0 assert response[3]["letter_cost"] == 24.45