From f1cc6aa400d4963313edd3be87159a4890261ed0 Mon Sep 17 00:00:00 2001 From: Cliff Hill Date: Fri, 10 Jan 2025 13:47:43 -0500 Subject: [PATCH] estructuring how to get total_notifications. Signed-off-by: Cliff Hill --- app/dao/services_dao.py | 26 ++++++++++++++++++++++---- app/service/rest.py | 7 ++++--- app/service/statistics.py | 23 ++++++++++++++--------- 3 files changed, 40 insertions(+), 16 deletions(-) diff --git a/app/dao/services_dao.py b/app/dao/services_dao.py index 841434a62..c4eba56a0 100644 --- a/app/dao/services_dao.py +++ b/app/dao/services_dao.py @@ -457,7 +457,7 @@ def dao_fetch_stats_for_service_from_days(service_id, start_date, end_date): sub_stmt = ( select( - Job.id, + Job.id.label("job_id"), cast(Job.notification_count, Integer).label("notification_count"), # <-- i added cast here NotificationAllTimeView.notification_type, NotificationAllTimeView.status, @@ -481,6 +481,24 @@ def dao_fetch_stats_for_service_from_days(service_id, start_date, end_date): .subquery() ) + # Getting the total notifications through this query. + + total_stmt = ( + select( + sub_stmt.c.job_id, + sub_stmt.c.notification_count, + ) + .group_by( + sub_stmt.c.job_id, + sub_stmt.c.notification_count, + ) + ) + + total_notifications = sum( + count + for __, count in db.session.execute(total_stmt).all() + ) + stmt = ( select( cast(func.sum(sub_stmt.c.notification_count), Integer).label("total_notifications"), # <-- i added cast here @@ -495,7 +513,7 @@ def dao_fetch_stats_for_service_from_days(service_id, start_date, end_date): sub_stmt.c.day ) ) - return db.session.execute(stmt).all() + return total_notifications, db.session.execute(stmt).all() @@ -742,7 +760,7 @@ def fetch_notification_stats_for_service_by_month_by_user( return db.session.execute(stmt).all() -def get_specific_days_stats(data, start_date, days=None, end_date=None): +def get_specific_days_stats(data, start_date, days=None, end_date=None, total_notifications=None): if days is not None and end_date is not None: raise ValueError("Only set days OR set end_date, not both.") elif days is not None: @@ -758,7 +776,7 @@ def get_specific_days_stats(data, start_date, days=None, end_date=None): } stats = { - day.strftime("%Y-%m-%d"): statistics.format_statistics(rows) + day.strftime("%Y-%m-%d"): statistics.format_statistics(rows, total_notifications=total_notifications,) for day, rows in grouped_data.items() } diff --git a/app/service/rest.py b/app/service/rest.py index 7dd614058..3bc27ccb3 100644 --- a/app/service/rest.py +++ b/app/service/rest.py @@ -230,9 +230,9 @@ def get_service_statistics_for_specific_days(service_id, start, days=1): end_date = datetime.strptime(start, "%Y-%m-%d") start_date = end_date - timedelta(days=days - 1) - results = dao_fetch_stats_for_service_from_days(service_id, start_date, end_date) + total_notifications, results = dao_fetch_stats_for_service_from_days(service_id, start_date, end_date,) - stats = get_specific_days_stats(results, start_date, days=days) + stats = get_specific_days_stats(results, start_date, days=days, total_notifications=total_notifications,) return stats @@ -678,7 +678,8 @@ def get_single_month_notification_stats_for_service(service_id): month_year = datetime(year, month, 10, 00, 00, 00) start_date, end_date = get_month_start_and_end_date_in_utc(month_year) - results = dao_fetch_stats_for_service_from_days(service_id, start_date, end_date) + # First element is total notifications used elsewhere. + __, results = dao_fetch_stats_for_service_from_days(service_id, start_date, end_date) stats = get_specific_days_stats(results, start_date, end_date=end_date) return jsonify(stats) diff --git a/app/service/statistics.py b/app/service/statistics.py index d2e6f9976..4103daba8 100644 --- a/app/service/statistics.py +++ b/app/service/statistics.py @@ -5,7 +5,7 @@ from app.dao.date_util import get_months_for_financial_year from app.enums import KeyType, NotificationStatus, StatisticsType, TemplateType -def format_statistics(statistics): +def format_statistics(statistics, total_notifications=None): # statistics come in a named tuple with uniqueness from 'notification_type', 'status' - however missing # statuses/notification types won't be represented and the status types need to be simplified/summed up # so we can return emails/sms * created, sent, and failed @@ -14,7 +14,7 @@ def format_statistics(statistics): # any row could be null, if the service either has no notifications in the notifications table, # or no historical data in the ft_notification_status table. if row.notification_type: - _update_statuses_from_row(counts[row.notification_type], row) + _update_statuses_from_row(counts[row.notification_type], row, total_notifications=total_notifications,) return counts @@ -82,19 +82,22 @@ def create_zeroed_stats_dicts(): } -def _update_statuses_from_row(update_dict, row): +def _update_statuses_from_row(update_dict, row, total_notifications=None): # Initialize pending_count to total_notifications - pending_count = row.total_notifications + if total_notifications is not None: + pending_count = total_notifications # Update requested count if row.status != NotificationStatus.CANCELLED: update_dict[StatisticsType.REQUESTED] += row.count - pending_count -= row.count # Subtract from pending_count + if total_notifications is not None: + pending_count -= row.count # Subtract from pending_count # Update delivered count if row.status in (NotificationStatus.DELIVERED, NotificationStatus.SENT): update_dict[StatisticsType.DELIVERED] += row.count - pending_count -= row.count # Subtract from pending_count + if total_notifications is not None: + pending_count -= row.count # Subtract from pending_count # Update failure count if row.status in ( @@ -106,10 +109,12 @@ def _update_statuses_from_row(update_dict, row): NotificationStatus.VIRUS_SCAN_FAILED, ): update_dict[StatisticsType.FAILURE] += row.count - pending_count -= row.count # Subtract from pending_count + if total_notifications is not None: + pending_count -= row.count # Subtract from pending_count - # Update pending count directly - update_dict[StatisticsType.PENDING] = pending_count + if total_notifications is not None: + # Update pending count directly + update_dict[StatisticsType.PENDING] = pending_count def create_empty_monthly_notification_status_stats_dict(year): utc_month_starts = get_months_for_financial_year(year)