Skip to content

Commit

Permalink
Merge pull request #1171 from GSA/main
Browse files Browse the repository at this point in the history
07/05/2024 Production Deploy
  • Loading branch information
ccostino authored Jul 5, 2024
2 parents d31d19d + c671189 commit 2090022
Show file tree
Hide file tree
Showing 25 changed files with 548 additions and 193 deletions.
27 changes: 27 additions & 0 deletions app/dao/date_util.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import calendar
from datetime import date, datetime, time, timedelta

from app.utils import utc_now
Expand Down Expand Up @@ -66,3 +67,29 @@ def get_calendar_year_for_datetime(start_date):
return year - 1
else:
return year


def get_number_of_days_for_month(year, month):
return calendar.monthrange(year, month)[1]


def generate_date_range(start_date, end_date=None, days=0):
if end_date:
current_date = start_date
while current_date <= end_date:
try:
yield current_date.date()
except ValueError:
pass
current_date += timedelta(days=1)
elif days > 0:
end_date = start_date + timedelta(days=days)
current_date = start_date
while current_date < end_date:
try:
yield current_date.date()
except ValueError:
pass
current_date += timedelta(days=1)
else:
return "An end_date or number of days must be specified"
22 changes: 11 additions & 11 deletions app/dao/fact_notification_status_dao.py
Original file line number Diff line number Diff line change
Expand Up @@ -84,21 +84,21 @@ def update_fact_notification_status(process_day, notification_type, service_id):
def fetch_notification_status_for_service_by_month(start_date, end_date, service_id):
return (
db.session.query(
func.date_trunc("month", FactNotificationStatus.local_date).label("month"),
FactNotificationStatus.notification_type,
FactNotificationStatus.notification_status,
func.sum(FactNotificationStatus.notification_count).label("count"),
func.date_trunc("month", NotificationAllTimeView.created_at).label("month"),
NotificationAllTimeView.notification_type,
NotificationAllTimeView.status.label("notification_status"),
func.count(NotificationAllTimeView.id).label("count"),
)
.filter(
FactNotificationStatus.service_id == service_id,
FactNotificationStatus.local_date >= start_date,
FactNotificationStatus.local_date < end_date,
FactNotificationStatus.key_type != KeyType.TEST,
NotificationAllTimeView.service_id == service_id,
NotificationAllTimeView.created_at >= start_date,
NotificationAllTimeView.created_at < end_date,
NotificationAllTimeView.key_type != KeyType.TEST,
)
.group_by(
func.date_trunc("month", FactNotificationStatus.local_date).label("month"),
FactNotificationStatus.notification_type,
FactNotificationStatus.notification_status,
func.date_trunc("month", NotificationAllTimeView.created_at).label("month"),
NotificationAllTimeView.notification_type,
NotificationAllTimeView.status,
)
.all()
)
Expand Down
108 changes: 107 additions & 1 deletion app/dao/services_dao.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

from app import db
from app.dao.dao_utils import VersionOptions, autocommit, version_class
from app.dao.date_util import get_current_calendar_year
from app.dao.date_util import generate_date_range, get_current_calendar_year
from app.dao.organization_dao import dao_get_organization_by_email_address
from app.dao.service_sms_sender_dao import insert_service_sms_sender
from app.dao.service_user_dao import dao_get_service_user
Expand All @@ -27,6 +27,7 @@
InvitedUser,
Job,
Notification,
NotificationAllTimeView,
NotificationHistory,
Organization,
Permission,
Expand All @@ -40,6 +41,7 @@
User,
VerifyCode,
)
from app.service import statistics
from app.utils import (
escape_special_characters,
get_archived_db_column_value,
Expand Down Expand Up @@ -426,6 +428,61 @@ def dao_fetch_todays_stats_for_service(service_id):
)


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))

return (
db.session.query(
NotificationAllTimeView.notification_type,
NotificationAllTimeView.status,
func.date_trunc("day", NotificationAllTimeView.created_at).label("day"),
func.count(NotificationAllTimeView.id).label("count"),
)
.filter(
NotificationAllTimeView.service_id == service_id,
NotificationAllTimeView.key_type != KeyType.TEST,
NotificationAllTimeView.created_at >= start_date,
NotificationAllTimeView.created_at < end_date,
)
.group_by(
NotificationAllTimeView.notification_type,
NotificationAllTimeView.status,
func.date_trunc("day", NotificationAllTimeView.created_at),
)
.all()
)


def dao_fetch_stats_for_service_from_days_for_user(
service_id, start_date, end_date, user_id
):
start_date = get_midnight_in_utc(start_date)
end_date = get_midnight_in_utc(end_date + timedelta(days=1))

return (
db.session.query(
NotificationAllTimeView.notification_type,
NotificationAllTimeView.status,
func.date_trunc("day", NotificationAllTimeView.created_at).label("day"),
func.count(NotificationAllTimeView.id).label("count"),
)
.filter(
NotificationAllTimeView.service_id == service_id,
NotificationAllTimeView.key_type != KeyType.TEST,
NotificationAllTimeView.created_at >= start_date,
NotificationAllTimeView.created_at < end_date,
NotificationAllTimeView.created_by_id == user_id,
)
.group_by(
NotificationAllTimeView.notification_type,
NotificationAllTimeView.status,
func.date_trunc("day", NotificationAllTimeView.created_at),
)
.all()
)


def dao_fetch_todays_stats_for_all_services(
include_from_test_key=True, only_active=True
):
Expand Down Expand Up @@ -607,3 +664,52 @@ def get_live_services_with_organization():
)

return query.all()


def fetch_notification_stats_for_service_by_month_by_user(
start_date, end_date, service_id, user_id
):
return (
db.session.query(
func.date_trunc("month", NotificationAllTimeView.created_at).label("month"),
NotificationAllTimeView.notification_type,
(NotificationAllTimeView.status).label("notification_status"),
func.count(NotificationAllTimeView.id).label("count"),
)
.filter(
NotificationAllTimeView.service_id == service_id,
NotificationAllTimeView.created_at >= start_date,
NotificationAllTimeView.created_at < end_date,
NotificationAllTimeView.key_type != KeyType.TEST,
NotificationAllTimeView.created_by_id == user_id,
)
.group_by(
func.date_trunc("month", NotificationAllTimeView.created_at).label("month"),
NotificationAllTimeView.notification_type,
NotificationAllTimeView.status,
)
.all()
)


def get_specific_days_stats(results, start_date, days=None, end_date=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:
gen_range = generate_date_range(start_date, days=days)
elif end_date is not None:
gen_range = generate_date_range(start_date, end_date)
else:
raise ValueError("Either days or end_date must be set.")

grouped_results = {date: [] for date in gen_range} | {
day.date(): [notification_type, status, day, count]
for notification_type, status, day, count in results
}

stats = {
day.strftime("%Y-%m-%d"): statistics.format_statistics(rows)
for day, rows in grouped_results.items()
}

return stats
14 changes: 13 additions & 1 deletion app/dao/users_dao.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

import sqlalchemy
from flask import current_app
from sqlalchemy import func
from sqlalchemy import func, text
from sqlalchemy.orm import joinedload

from app import db
Expand Down Expand Up @@ -244,3 +244,15 @@ def user_can_be_archived(user):
return False

return True


def dao_report_users():
sql = """
select users.name, users.email_address, users.mobile_number, services.name as service_name
from users
inner join user_to_service on users.id=user_to_service.user_id
inner join services on services.id=user_to_service.service_id
where services.name not like '_archived%'
order by services.name asc, users.name asc
"""
return db.session.execute(text(sql))
Loading

0 comments on commit 2090022

Please sign in to comment.