pending count

This commit is contained in:
Beverly Nguyen
2025-01-10 18:18:20 -08:00
parent 3f8c49d829
commit 7ef808196e
4 changed files with 73 additions and 15 deletions

View File

@@ -455,14 +455,49 @@ def dao_fetch_stats_for_service_from_days(service_id, start_date, end_date):
start_date = get_midnight_in_utc(start_date)
end_date = get_midnight_in_utc(end_date + timedelta(days=1))
# Subquery for daily total notifications
total_substmt = (
select(
func.date_trunc("day", NotificationAllTimeView.created_at).label("day"),
cast(Job.notification_count, Integer).label("notification_count")
)
.join(
Job, NotificationAllTimeView.job_id == Job.id
)
.where(
NotificationAllTimeView.service_id == service_id,
NotificationAllTimeView.key_type != KeyType.TEST,
NotificationAllTimeView.created_at >= start_date,
NotificationAllTimeView.created_at < end_date,
)
.group_by(
Job.id,
Job.notification_count,
func.date_trunc("day", NotificationAllTimeView.created_at),
)
.subquery()
)
# Query for daily total notifications
total_stmt = select(
func.date_trunc("day", total_substmt.c.day).label("day"),
func.sum(total_substmt.c.notification_count).label("total_notifications"),
).group_by(
total_substmt.c.day
)
# Execute both queries
total_notifications = {
row.day: row.total_notifications for row in db.session.execute(total_stmt).all()
}
# Query for breakdown by notification type and status
stmt = (
select(
NotificationAllTimeView.notification_type,
NotificationAllTimeView.status,
func.date_trunc("day", NotificationAllTimeView.created_at).label("day"),
cast(func.count(NotificationAllTimeView.id), Integer).label(
"count"
), # <-- i added cast here
cast(func.count(NotificationAllTimeView.id), Integer).label("count"),
)
.where(
NotificationAllTimeView.service_id == service_id,
@@ -479,8 +514,9 @@ def dao_fetch_stats_for_service_from_days(service_id, start_date, end_date):
data = db.session.execute(stmt).all()
return data
print("Daily Total Notifications:", total_notifications)
return total_notifications, data
def dao_fetch_stats_for_service_from_days_for_user(
service_id, start_date, end_date, user_id
@@ -725,7 +761,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:
@@ -736,13 +772,19 @@ def get_specific_days_stats(data, start_date, days=None, end_date=None):
raise ValueError("Either days or end_date must be set.")
grouped_data = {date: [] for date in gen_range} | {
day: [row for row in data if row.day.date() == day]
for day in {item.day.date() for item in data}
day: [row for row in data if row.day == day]
for day in {item.day for item in data}
}
stats = {
day.strftime("%Y-%m-%d"): statistics.format_statistics(rows)
day.strftime("%Y-%m-%d"): statistics.format_statistics(
rows,
total_notifications=(
total_notifications.get(day, 0)
if total_notifications is not None
else None
),
)
for day, rows in grouped_data.items()
}
return stats

View File

@@ -212,3 +212,5 @@ class StatisticsType(StrEnum):
DELIVERED = "delivered"
FAILURE = "failure"
PENDING = "pending"
SENDING = "sending"
CREATED = "created"

View File

@@ -230,13 +230,18 @@ 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(
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

View File

@@ -7,10 +7,11 @@ from app.enums import (
NotificationStatus,
StatisticsType,
TemplateType,
NotificationType
)
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
@@ -24,8 +25,18 @@ def format_statistics(statistics):
row,
)
return counts
if NotificationType.SMS in counts and total_notifications is not None:
sms_dict = counts[NotificationType.SMS]
delivered_count = sms_dict[StatisticsType.DELIVERED]
failed_count = sms_dict[StatisticsType.FAILURE]
print('total_notifications',total_notifications)
pending_count = total_notifications - (delivered_count + failed_count)
pending_count = max(0, pending_count)
sms_dict[StatisticsType.PENDING] = pending_count
return counts
def format_admin_stats(statistics):
counts = create_stats_dict()
@@ -98,12 +109,10 @@ def _update_statuses_from_row(update_dict, row):
# Update requested count
if row.status != NotificationStatus.CANCELLED:
update_dict[StatisticsType.REQUESTED] += row.count
requested_count += row.count
# Update delivered count
if row.status in (NotificationStatus.DELIVERED, NotificationStatus.SENT):
update_dict[StatisticsType.DELIVERED] += row.count
delivered_count += row.count
# Update failure count
if row.status in (