diff --git a/app/billing/rest.py b/app/billing/rest.py index cd7bc3864..82474014f 100644 --- a/app/billing/rest.py +++ b/app/billing/rest.py @@ -3,6 +3,7 @@ import json from flask import Blueprint, jsonify, request +from app.dao.fact_billing_dao import fetch_monthly_billing_for_year from app.dao.monthly_billing_dao import ( get_billing_data_for_financial_year, get_monthly_billing_by_notification_type @@ -30,6 +31,16 @@ billing_blueprint = Blueprint( register_errors(billing_blueprint) +@billing_blueprint.route('/ft-monthly-usage') +def get_yearly_usage_by_monthy_from_ft_billing(service_id): + try: + year = int(request.args.get('year')) + results = fetch_monthly_billing_for_year(service_id=service_id, year=year) + serialize_ft_billing(results) + except TypeError: + return jsonify(result='error', message='No valid year provided'), 400 + + @billing_blueprint.route('/monthly-usage') def get_yearly_usage_by_month(service_id): try: @@ -192,3 +203,21 @@ def update_free_sms_fragment_limit_data(service_id, free_sms_fragment_limit, fin free_sms_fragment_limit, financial_year_start ) + + +def serialize_ft_billing(data): + results = [] + + for d in data: + j = { + "Month": d.month, + "service_id": d.service_id, + "notifications_type": d.notification_type, + "notifications_sent": d.notifications_sent, + "billable_units": d.billable_units, + "rate": d.rate, + "rate_multiplier": d.rate_multiplier, + "international": d.international, + } + results.append(j) + return results diff --git a/app/dao/fact_billing_dao.py b/app/dao/fact_billing_dao.py index bc6f7d357..538d23ef2 100644 --- a/app/dao/fact_billing_dao.py +++ b/app/dao/fact_billing_dao.py @@ -20,7 +20,7 @@ from app.models import ( from app.utils import convert_utc_to_bst, convert_bst_to_utc -def fetch_montly_billing_for_year(service_id, year): +def fetch_monthly_billing_for_year(service_id, year): year_start_date, year_end_date = get_financial_year(year) utcnow = datetime.utcnow() today = convert_utc_to_bst(utcnow).date() @@ -39,7 +39,8 @@ def fetch_montly_billing_for_year(service_id, year): FactBilling.service_id, FactBilling.rate, FactBilling.rate_multiplier, - FactBilling.international + FactBilling.international, + FactBilling.notification_type ).filter( FactBilling.service_id == service_id, FactBilling.bst_date >= year_start_date, @@ -49,7 +50,12 @@ def fetch_montly_billing_for_year(service_id, year): FactBilling.service_id, FactBilling.rate, FactBilling.rate_multiplier, - FactBilling.international + FactBilling.international, + FactBilling.notification_type + ).order_by( + FactBilling.service_id, + 'Month', + FactBilling.notification_type ).all() return yearly_data diff --git a/tests/app/dao/test_ft_billing_dao.py b/tests/app/dao/test_ft_billing_dao.py index 4ed43ffc5..8c0d60f94 100644 --- a/tests/app/dao/test_ft_billing_dao.py +++ b/tests/app/dao/test_ft_billing_dao.py @@ -5,7 +5,7 @@ from freezegun import freeze_time from app import db from app.dao.fact_billing_dao import ( - fetch_montly_billing_for_year, fetch_billing_data_for_day, get_rates_for_billing, + fetch_monthly_billing_for_year, fetch_billing_data_for_day, get_rates_for_billing, get_rate ) from app.models import FactBilling @@ -132,6 +132,25 @@ def test_fetch_billing_data_for_day_is_grouped_by_international(notify_db_sessio assert results[1].notifications_sent == 1 +def test_fetch_billing_data_for_day_is_grouped_by_notification_type(notify_db_session): + service = create_service() + sms_template = create_template(service=service, template_type='sms') + email_template = create_template(service=service, template_type='email') + letter_template = create_template(service=service, template_type='letter') + create_notification(template=sms_template, status='delivered') + create_notification(template=sms_template, status='delivered') + create_notification(template=sms_template, status='delivered') + create_notification(template=email_template, status='delivered') + create_notification(template=email_template, status='delivered') + create_notification(template=letter_template, status='delivered') + + today = convert_utc_to_bst(datetime.utcnow()) + results = fetch_billing_data_for_day(today) + assert len(results) == 3 + notification_types = [x[2] for x in results if x[2] in ['email', 'sms', 'letter']] + assert len(notification_types) == 3 + + def test_fetch_billing_data_for_day_returns_empty_list(notify_db_session): today = convert_utc_to_bst(datetime.utcnow()) results = fetch_billing_data_for_day(today) @@ -181,7 +200,7 @@ def test_get_rate(notify_db_session): assert letter_rate == Decimal('4.4') -def test_fetch_annual_billing_for_year(notify_db_session): +def test_fetch_monthly_billing_for_year(notify_db_session): service = create_service() template = create_template(service=service, template_type="sms") for i in range(1, 31): @@ -197,28 +216,30 @@ def test_fetch_annual_billing_for_year(notify_db_session): notification_type='sms', rate=0.158) - results = fetch_montly_billing_for_year(service_id=service.id, year=2018) + results = fetch_monthly_billing_for_year(service_id=service.id, year=2018) assert len(results) == 2 - assert results[0][0] == 6.0 - assert results[0][1] == 30 - assert results[0][2] == Decimal('30') - assert results[0][3] == service.id - assert results[0][4] == Decimal('0.162') - assert results[0][5] == Decimal('1') - assert results[0][6] is False + assert results[0].Month == 6.0 + assert results[0].notifications_sent == 30 + assert results[0].billable_units == Decimal('30') + assert results[0].service_id == service.id + assert results[0].rate == Decimal('0.162') + assert results[0].rate_multiplier == Decimal('1') + assert results[0].international is False + assert results[0].notification_type == 'sms' - assert results[1][0] == 7.0 - assert results[1][1] == 31 - assert results[1][2] == Decimal('31') - assert results[1][3] == service.id - assert results[1][4] == Decimal('0.158') - assert results[1][5] == Decimal('1') - assert results[1][6] is False + assert results[1].Month == 7.0 + assert results[1].notifications_sent == 31 + assert results[1].billable_units == Decimal('31') + assert results[1].service_id == service.id + assert results[1].rate == Decimal('0.158') + assert results[1].rate_multiplier == Decimal('1') + assert results[1].international is False + assert results[1].notification_type == 'sms' @freeze_time('2018-08-01 13:30:00') -def test_fetch_annual_billing_for_year_adds_data_for_today(notify_db_session): +def test_fetch_monthly_billing_for_year_adds_data_for_today(notify_db_session): service = create_service() template = create_template(service=service, template_type="email") for i in range(1, 32): @@ -230,7 +251,47 @@ def test_fetch_annual_billing_for_year_adds_data_for_today(notify_db_session): create_notification(template=template, status='delivered') assert db.session.query(FactBilling.bst_date).count() == 31 - results = fetch_montly_billing_for_year(service_id=service.id, - year=2018) + results = fetch_monthly_billing_for_year(service_id=service.id, + year=2018) assert db.session.query(FactBilling.bst_date).count() == 32 assert len(results) == 2 + + +def test_fetch_monthly_billing_for_year(notify_db_session): + service = create_service() + sms_template = create_template(service=service, template_type="email") + email_template = create_template(service=service, template_type="email") + letter_template = create_template(service=service, template_type="email") + for month in range(1, 13): + mon = str(month).zfill(2) + days_in_month = {1: 32, 2: 30, 3: 32, 4: 31, 5: 32, 6: 31, 7: 32, 8: 32, 9: 31, 10: 32, 11: 31, 12: 32} + for day in range(1, days_in_month[month]): + d = str(day).zfill(2) + create_ft_billing(bst_date='2016-{}-{}'.format(mon, d), + service=service, + template=sms_template, + notification_type='sms', + rate=0.162) + create_ft_billing(bst_date='2016-{}-{}'.format(mon, d), + service=service, + template=email_template, + notification_type='email', + rate=0) + create_ft_billing(bst_date='2016-{}-{}'.format(mon, d), + service=service, + template=letter_template, + notification_type='letter', + rate=0.33) + + results = fetch_monthly_billing_for_year(service.id, 2016) + # returns 3 rows, per month, returns financial year april to december + # Orders by Month + assert len(results) == 27 + assert results[0][0] == 4 + assert results[1][0] == 4 + assert results[2][0] == 4 + assert results[3][0] == 5 + assert results[26][0] == 12 + + +