diff --git a/app/billing/rest.py b/app/billing/rest.py index 82474014f..6034e1ad4 100644 --- a/app/billing/rest.py +++ b/app/billing/rest.py @@ -32,14 +32,16 @@ register_errors(billing_blueprint) @billing_blueprint.route('/ft-monthly-usage') -def get_yearly_usage_by_monthy_from_ft_billing(service_id): +def get_yearly_usage_by_monthly_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 + results = fetch_monthly_billing_for_year(service_id=service_id, year=year) + data = serialize_ft_billing(results) + return jsonify(monthly_usage=data) + @billing_blueprint.route('/monthly-usage') def get_yearly_usage_by_month(service_id): @@ -207,16 +209,15 @@ def update_free_sms_fragment_limit_data(service_id, free_sms_fragment_limit, fin def serialize_ft_billing(data): results = [] - for d in data: j = { - "Month": d.month, - "service_id": d.service_id, + "month": (datetime.strftime(d.month, "%B")), + "service_id": str(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, + "notifications_sent": int(d.notifications_sent), + "billable_units": int(d.billable_units), + "rate": float(d.rate), + "rate_multiplier": int(d.rate_multiplier), "international": d.international, } results.append(j) diff --git a/app/dao/fact_billing_dao.py b/app/dao/fact_billing_dao.py index 538d23ef2..7cc1919c0 100644 --- a/app/dao/fact_billing_dao.py +++ b/app/dao/fact_billing_dao.py @@ -1,7 +1,7 @@ from datetime import datetime, timedelta, time from flask import current_app -from sqlalchemy import func, case, desc, extract +from sqlalchemy import func, case, desc from app import db from app.dao.date_util import get_financial_year @@ -33,7 +33,7 @@ def fetch_monthly_billing_for_year(service_id, year): update_fact_billing(data=d, process_day=day) yearly_data = db.session.query( - extract('month', FactBilling.bst_date).label("Month"), + func.date_trunc('month', FactBilling.bst_date).label("month"), func.sum(FactBilling.notifications_sent).label("notifications_sent"), func.sum(FactBilling.billable_units).label("billable_units"), FactBilling.service_id, @@ -46,7 +46,7 @@ def fetch_monthly_billing_for_year(service_id, year): FactBilling.bst_date >= year_start_date, FactBilling.bst_date <= year_end_date ).group_by( - 'Month', + 'month', FactBilling.service_id, FactBilling.rate, FactBilling.rate_multiplier, @@ -54,7 +54,7 @@ def fetch_monthly_billing_for_year(service_id, year): FactBilling.notification_type ).order_by( FactBilling.service_id, - 'Month', + 'month', FactBilling.notification_type ).all() diff --git a/tests/app/billing/test_billing.py b/tests/app/billing/test_billing.py index 8250eaf40..c0cae0a1a 100644 --- a/tests/app/billing/test_billing.py +++ b/tests/app/billing/test_billing.py @@ -17,7 +17,9 @@ from tests.app.db import ( create_monthly_billing_entry, create_annual_billing, create_letter_rate, - create_template + create_template, + create_service, + create_ft_billing ) from app.billing.rest import update_free_sms_fragment_limit_data @@ -409,3 +411,45 @@ def test_update_free_sms_fragment_limit_data(client, sample_service): annual_billing = dao_get_free_sms_fragment_limit_for_year(sample_service.id, current_year) assert annual_billing.free_sms_fragment_limit == 9999 + + +def test_get_yearly_usage_by_monthly_from_ft_billing(client, 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") + 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) + + response = client.get('service/{}/billing/ft-monthly-usage?year=2016'.format(service.id), + headers=[('Content-Type', 'application/json'), create_authorization_header()]) + + json_resp = json.loads(response.get_data(as_text=True)) + + assert json_resp["monthly_usage"][0] == {"month": "April", + "service_id": str(service.id), + "notifications_type": 'email', + "notifications_sent": 30, + "billable_units": 30, + "rate": 0.0, + "rate_multiplier": 1, + "international": False, + } diff --git a/tests/app/dao/test_ft_billing_dao.py b/tests/app/dao/test_ft_billing_dao.py index 8c0d60f94..5230e72ec 100644 --- a/tests/app/dao/test_ft_billing_dao.py +++ b/tests/app/dao/test_ft_billing_dao.py @@ -219,7 +219,7 @@ def test_fetch_monthly_billing_for_year(notify_db_session): results = fetch_monthly_billing_for_year(service_id=service.id, year=2018) assert len(results) == 2 - assert results[0].Month == 6.0 + assert str(results[0].month) == "2018-06-01 00:00:00+01:00" assert results[0].notifications_sent == 30 assert results[0].billable_units == Decimal('30') assert results[0].service_id == service.id @@ -228,7 +228,7 @@ def test_fetch_monthly_billing_for_year(notify_db_session): assert results[0].international is False assert results[0].notification_type == 'sms' - assert results[1].Month == 7.0 + assert str(results[1].month) == "2018-07-01 00:00:00+01:00" assert results[1].notifications_sent == 31 assert results[1].billable_units == Decimal('31') assert results[1].service_id == service.id @@ -257,11 +257,11 @@ def test_fetch_monthly_billing_for_year_adds_data_for_today(notify_db_session): assert len(results) == 2 -def test_fetch_monthly_billing_for_year(notify_db_session): +def test_fetch_monthly_billing_for_year_return_financial_year(notify_db_session): service = create_service() - sms_template = create_template(service=service, template_type="email") + 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="email") + letter_template = create_template(service=service, template_type="letter") 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} @@ -286,12 +286,13 @@ def test_fetch_monthly_billing_for_year(notify_db_session): 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 - - - + assert str(results[0].month) == "2016-04-01 00:00:00+01:00" + assert results[0].notification_type == 'email' + assert str(results[1].month) == "2016-04-01 00:00:00+01:00" + assert results[1].notification_type == 'letter' + assert str(results[2].month) == "2016-04-01 00:00:00+01:00" + assert results[2].notification_type == 'sms' + assert str(results[3].month) == "2016-05-01 00:00:00+01:00" + assert str(results[26].month) == "2016-12-01 00:00:00+00:00"