diff --git a/app/dao/services_dao.py b/app/dao/services_dao.py index 71896a5df..8e982c9da 100644 --- a/app/dao/services_dao.py +++ b/app/dao/services_dao.py @@ -263,3 +263,31 @@ def dao_fetch_todays_stats_for_all_services(include_from_test_key=True): query = query.filter(Notification.key_type != KEY_TYPE_TEST) return query + + +@statsd(namespace='dao') +def fetch_stats_by_date_range_for_all_services(start_date, end_date, include_from_test_key=True): + query = db.session.query( + NotificationHistory.notification_type, + NotificationHistory.status, + NotificationHistory.service_id, + func.count(NotificationHistory.id).label('count') + ).select_from( + Service + ).join( + NotificationHistory + ).filter( + func.date(NotificationHistory.created_at) >= start_date, + func.date(NotificationHistory.created_at) <= end_date + ).group_by( + NotificationHistory.notification_type, + NotificationHistory.status, + NotificationHistory.service_id + ).order_by( + NotificationHistory.service_id + ) + + if not include_from_test_key: + query = query.filter(NotificationHistory.key_type != KEY_TYPE_TEST) + + return query diff --git a/app/service/rest.py b/app/service/rest.py index 1c1e9b77c..29738141f 100644 --- a/app/service/rest.py +++ b/app/service/rest.py @@ -26,7 +26,8 @@ from app.dao.services_dao import ( dao_fetch_todays_stats_for_service, dao_fetch_weekly_historical_stats_for_service, dao_fetch_todays_stats_for_all_services, - dao_deactive_service + dao_deactive_service, + fetch_stats_by_date_range_for_all_services ) from app.dao.service_whitelist_dao import ( dao_fetch_service_whitelist, @@ -63,11 +64,14 @@ def get_services(): detailed = request.args.get('detailed') == 'True' user_id = request.args.get('user_id', None) include_from_test_key = request.args.get('include_from_test_key', 'True') != 'False' + start_date = request.args.get('start_date', None) + end_date = request.args.get('end_date', None) if user_id: services = dao_fetch_all_services_by_user(user_id, only_active) elif detailed: - return jsonify(data=get_detailed_services(only_active, include_from_test_key=include_from_test_key)) + return jsonify(data=get_detailed_services(only_active, include_from_test_key=include_from_test_key, + start_date=start_date, end_date=end_date)) else: services = dao_fetch_all_services(only_active) data = service_schema.dump(services, many=True).data @@ -269,18 +273,22 @@ def get_detailed_service(service_id, today_only=False): return detailed_service_schema.dump(service).data -def get_detailed_services(only_active=False, include_from_test_key=True): +def get_detailed_services(only_active=False, include_from_test_key=True, start_date=None, end_date=None): services = {service.id: service for service in dao_fetch_all_services(only_active)} - stats = dao_fetch_todays_stats_for_all_services(include_from_test_key=include_from_test_key) + if start_date: + stats = fetch_stats_by_date_range_for_all_services(start_date=start_date, + end_date=end_date, + include_from_test_key=include_from_test_key) + else: + stats = dao_fetch_todays_stats_for_all_services(include_from_test_key=include_from_test_key) for service_id, rows in itertools.groupby(stats, lambda x: x.service_id): - services[service_id].statistics = statistics.format_statistics(rows) + services[service_id].statistics = statistics.format_statistics(rows) # if service has not sent anything, query will not have set statistics correctly for service in services.values(): if not hasattr(service, 'statistics'): service.statistics = statistics.create_zeroed_stats_dicts() - return detailed_service_schema.dump(services.values(), many=True).data diff --git a/tests/app/dao/test_services_dao.py b/tests/app/dao/test_services_dao.py index eacca3db3..896089a24 100644 --- a/tests/app/dao/test_services_dao.py +++ b/tests/app/dao/test_services_dao.py @@ -1,4 +1,4 @@ -from datetime import datetime +from datetime import datetime, timedelta import uuid import functools @@ -21,7 +21,8 @@ from app.dao.services_dao import ( dao_fetch_todays_stats_for_service, dao_fetch_weekly_historical_stats_for_service, fetch_todays_total_message_count, - dao_fetch_todays_stats_for_all_services + dao_fetch_todays_stats_for_all_services, + fetch_stats_by_date_range_for_all_services ) from app.dao.users_dao import save_model_user from app.models import ( @@ -639,3 +640,19 @@ def test_dao_fetch_todays_stats_for_all_services_can_exclude_from_test_key(notif assert len(stats) == 1 assert stats[0].count == 2 + + +def test_fetch_stats_by_date_range_for_all_services(notify_db, notify_db_session): + create_notification(notify_db, notify_db_session, created_at=datetime.now() - timedelta(days=4)) + create_notification(notify_db, notify_db_session, created_at=datetime.now() - timedelta(days=3)) + result_one = create_notification(notify_db, notify_db_session, created_at=datetime.now() - timedelta(days=2)) + create_notification(notify_db, notify_db_session, created_at=datetime.now() - timedelta(days=1)) + create_notification(notify_db, notify_db_session, created_at=datetime.now()) + + start_date = (datetime.utcnow() - timedelta(days=2)).date() + end_date = (datetime.utcnow() - timedelta(days=1)).date() + + results = fetch_stats_by_date_range_for_all_services(start_date, end_date).all() + + assert len(results) == 1 + assert results[0] == ('sms', 'created', result_one.service_id, 2) diff --git a/tests/app/service/test_rest.py b/tests/app/service/test_rest.py index 3641982d1..cf5f458ca 100644 --- a/tests/app/service/test_rest.py +++ b/tests/app/service/test_rest.py @@ -1,4 +1,4 @@ -from datetime import datetime +from datetime import datetime, timedelta import json import uuid @@ -1363,6 +1363,25 @@ def test_get_detailed_services_only_includes_todays_notifications(notify_db, not } +def test_get_detailed_services_for_date_range(notify_db, notify_db_session): + from app.service.rest import get_detailed_services + create_sample_notification(notify_db, notify_db_session, created_at=datetime.now() - timedelta(days=3)) + create_sample_notification(notify_db, notify_db_session, created_at=datetime.now() - timedelta(days=2)) + create_sample_notification(notify_db, notify_db_session, created_at=datetime.now() - timedelta(days=1)) + create_sample_notification(notify_db, notify_db_session, created_at=datetime.now()) + + start_date = (datetime.utcnow() - timedelta(days=2)).date() + end_date = (datetime.utcnow() - timedelta(days=1)).date() + + data = get_detailed_services(only_active=False, include_from_test_key=True, + start_date=start_date, end_date=end_date) + assert len(data) == 1 + assert data[0]['statistics'] == { + 'email': {'delivered': 0, 'failed': 0, 'requested': 0}, + 'sms': {'delivered': 0, 'failed': 0, 'requested': 2} + } + + @freeze_time('2012-12-12T12:00:01') def test_get_notification_billable_unit_count(client, notify_db, notify_db_session): notification = create_sample_notification(notify_db, notify_db_session)