diff --git a/app/dao/notifications_dao.py b/app/dao/notifications_dao.py index 518811a28..5560a55d1 100644 --- a/app/dao/notifications_dao.py +++ b/app/dao/notifications_dao.py @@ -27,6 +27,7 @@ from app.models import ( from app.dao.dao_utils import transactional from app.statsd_decorators import statsd +from app.utils import get_london_month_from_utc_column def dao_get_notification_statistics_for_service_and_day(service_id, day): @@ -225,16 +226,8 @@ def get_notifications_for_job(service_id, job_id, filter_dict=None, page=1, page def get_notification_billable_unit_count_per_month(service_id, year): start, end = get_financial_year(year) - """ - The query needs to sum the billable_units per month, but this needs to be the month in BST (British Standard Time). - The database stores all timestamps as UTC without the timezone. - - First set the timezone on created_at to UTC - - then convert the timezone to BST (or Europe/London) - - lastly truncate the datetime to month to group the sum of the billable_units - """ - month = func.date_trunc("month", - func.timezone("Europe/London", func.timezone("UTC", - NotificationHistory.created_at))) + month = get_london_month_from_utc_column(NotificationHistory.created_at) + notifications = db.session.query( month, func.sum(NotificationHistory.billable_units) diff --git a/app/dao/services_dao.py b/app/dao/services_dao.py index 50f582ad2..b9ad66ae9 100644 --- a/app/dao/services_dao.py +++ b/app/dao/services_dao.py @@ -30,6 +30,7 @@ from app.models import ( TEMPLATE_TYPES, ) from app.statsd_decorators import statsd +from app.utils import get_london_month_from_utc_column def dao_fetch_all_services(only_active=False): @@ -247,13 +248,7 @@ def dao_fetch_monthly_historical_stats_for_service(service_id, year): monday_of_notification_week = func.date_trunc('week', NotificationHistory.created_at).label('week_start') start, end = get_financial_year(year) - month = func.date_trunc( - "month", - func.timezone( - "Europe/London", - func.timezone("UTC", NotificationHistory.created_at) - ) - ) + month = get_london_month_from_utc_column(NotificationHistory.created_at) rows = db.session.query( NotificationHistory.notification_type, diff --git a/app/utils.py b/app/utils.py index e8430b937..522d008f5 100644 --- a/app/utils.py +++ b/app/utils.py @@ -2,6 +2,7 @@ from datetime import datetime, timedelta import pytz from flask import url_for +from sqlalchemy import func from notifications_utils.template import SMSMessageTemplate, PlainTextEmailTemplate @@ -46,3 +47,19 @@ def get_london_midnight_in_utc(date): def get_midnight_for_day_before(date): day_before = date - timedelta(1) return get_london_midnight_in_utc(day_before) + + +def get_london_month_from_utc_column(column): + """ + Where queries need to count notifications by month it needs to be + the month in BST (British Summer Time). + The database stores all timestamps as UTC without the timezone. + - First set the timezone on created_at to UTC + - then convert the timezone to BST (or Europe/London) + - lastly truncate the datetime to month with which we can group + queries + """ + return func.date_trunc( + "month", + func.timezone("Europe/London", func.timezone("UTC", column)) + )