2020-03-10 10:33:30 +00:00
|
|
|
from datetime import datetime
|
2019-12-03 15:53:32 +00:00
|
|
|
from flask import current_app
|
2020-05-11 10:51:33 +01:00
|
|
|
from sqlalchemy import and_, desc, func, literal, text, String
|
2019-12-03 15:53:32 +00:00
|
|
|
|
|
|
|
|
from app import db
|
|
|
|
|
from app.models import (
|
|
|
|
|
Job, Notification, Template, LETTER_TYPE, JOB_STATUS_CANCELLED, JOB_STATUS_SCHEDULED,
|
2020-03-10 10:33:30 +00:00
|
|
|
NOTIFICATION_CANCELLED, ServiceDataRetention
|
2019-12-03 15:53:32 +00:00
|
|
|
)
|
|
|
|
|
from app.utils import midnight_n_days_ago
|
|
|
|
|
|
|
|
|
|
|
2020-05-11 10:51:33 +01:00
|
|
|
def _get_printing_day(created_at):
|
|
|
|
|
return func.date_trunc(
|
|
|
|
|
'day',
|
|
|
|
|
func.timezone('Europe/London', func.timezone('UTC', created_at)) + text(
|
|
|
|
|
"interval '6 hours 30 minutes'"
|
|
|
|
|
)
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def _get_printing_datetime(created_at):
|
|
|
|
|
return _get_printing_day(created_at) + text(
|
|
|
|
|
"interval '17 hours 30 minutes'"
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def _naive_gmt_to_utc(column):
|
|
|
|
|
return func.timezone('UTC', func.timezone('Europe/London', column))
|
|
|
|
|
|
|
|
|
|
|
2019-12-03 15:53:32 +00:00
|
|
|
def dao_get_uploads_by_service_id(service_id, limit_days=None, page=1, page_size=50):
|
2019-12-06 13:10:38 +00:00
|
|
|
# Hardcoded filter to exclude cancelled or scheduled jobs
|
|
|
|
|
# for the moment, but we may want to change this method take 'statuses' as a argument in the future
|
2020-03-10 10:33:30 +00:00
|
|
|
today = datetime.utcnow().date()
|
2019-12-03 15:53:32 +00:00
|
|
|
jobs_query_filter = [
|
|
|
|
|
Job.service_id == service_id,
|
|
|
|
|
Job.original_file_name != current_app.config['TEST_MESSAGE_FILENAME'],
|
|
|
|
|
Job.original_file_name != current_app.config['ONE_OFF_MESSAGE_FILENAME'],
|
2020-03-10 10:33:30 +00:00
|
|
|
Job.job_status.notin_([JOB_STATUS_CANCELLED, JOB_STATUS_SCHEDULED]),
|
|
|
|
|
func.coalesce(
|
|
|
|
|
Job.processing_started, Job.created_at
|
|
|
|
|
) >= today - func.coalesce(ServiceDataRetention.days_of_retention, 7)
|
2019-12-03 15:53:32 +00:00
|
|
|
]
|
|
|
|
|
if limit_days is not None:
|
|
|
|
|
jobs_query_filter.append(Job.created_at >= midnight_n_days_ago(limit_days))
|
|
|
|
|
|
|
|
|
|
jobs_query = db.session.query(
|
|
|
|
|
Job.id,
|
|
|
|
|
Job.original_file_name,
|
|
|
|
|
Job.notification_count,
|
2020-02-25 17:13:01 +00:00
|
|
|
Template.template_type,
|
2020-03-10 10:33:30 +00:00
|
|
|
func.coalesce(ServiceDataRetention.days_of_retention, 7).label('days_of_retention'),
|
2019-12-03 15:53:32 +00:00
|
|
|
Job.created_at.label("created_at"),
|
|
|
|
|
Job.scheduled_for.label("scheduled_for"),
|
|
|
|
|
Job.processing_started.label('processing_started'),
|
|
|
|
|
Job.job_status.label("status"),
|
2020-02-27 13:19:51 +00:00
|
|
|
literal('job').label('upload_type'),
|
|
|
|
|
literal(None).label('recipient'),
|
2020-02-25 17:13:01 +00:00
|
|
|
).join(
|
|
|
|
|
Template, Job.template_id == Template.id
|
2020-03-10 10:33:30 +00:00
|
|
|
).outerjoin(
|
|
|
|
|
ServiceDataRetention, and_(
|
|
|
|
|
Template.service_id == ServiceDataRetention.service_id,
|
|
|
|
|
func.cast(Template.template_type, String) == func.cast(ServiceDataRetention.notification_type, String)
|
|
|
|
|
)
|
2019-12-03 15:53:32 +00:00
|
|
|
).filter(
|
|
|
|
|
*jobs_query_filter
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
letters_query_filter = [
|
|
|
|
|
Notification.service_id == service_id,
|
|
|
|
|
Notification.notification_type == LETTER_TYPE,
|
|
|
|
|
Notification.api_key_id == None, # noqa
|
|
|
|
|
Notification.status != NOTIFICATION_CANCELLED,
|
|
|
|
|
Template.hidden == True,
|
2020-03-10 10:33:30 +00:00
|
|
|
Notification.created_at >= today - func.coalesce(ServiceDataRetention.days_of_retention, 7)
|
2019-12-03 15:53:32 +00:00
|
|
|
]
|
|
|
|
|
if limit_days is not None:
|
|
|
|
|
letters_query_filter.append(Notification.created_at >= midnight_n_days_ago(limit_days))
|
|
|
|
|
|
2020-05-11 10:51:33 +01:00
|
|
|
letters_subquery = db.session.query(
|
|
|
|
|
func.count().label('notification_count'),
|
|
|
|
|
_naive_gmt_to_utc(_get_printing_datetime(Notification.created_at)).label('printing_at'),
|
2019-12-03 15:53:32 +00:00
|
|
|
).join(
|
|
|
|
|
Template, Notification.template_id == Template.id
|
2020-03-10 10:33:30 +00:00
|
|
|
).outerjoin(
|
|
|
|
|
ServiceDataRetention, and_(
|
|
|
|
|
Template.service_id == ServiceDataRetention.service_id,
|
|
|
|
|
func.cast(Template.template_type, String) == func.cast(ServiceDataRetention.notification_type, String)
|
|
|
|
|
)
|
2019-12-03 15:53:32 +00:00
|
|
|
).filter(
|
|
|
|
|
*letters_query_filter
|
2020-05-11 10:51:33 +01:00
|
|
|
).group_by(
|
|
|
|
|
'printing_at'
|
|
|
|
|
).subquery()
|
|
|
|
|
|
|
|
|
|
letters_query = db.session.query(
|
|
|
|
|
literal(None).label('id'),
|
|
|
|
|
literal('Uploaded letters').label('original_file_name'),
|
|
|
|
|
letters_subquery.c.notification_count.label('notification_count'),
|
|
|
|
|
literal('letter').label('template_type'),
|
|
|
|
|
literal(None).label('days_of_retention'),
|
|
|
|
|
letters_subquery.c.printing_at.label('created_at'),
|
|
|
|
|
literal(None).label('scheduled_for'),
|
|
|
|
|
letters_subquery.c.printing_at.label('processing_started'),
|
|
|
|
|
literal(None).label('status'),
|
|
|
|
|
literal('letter_day').label('upload_type'),
|
|
|
|
|
literal(None).label('recipient'),
|
|
|
|
|
).group_by(
|
|
|
|
|
letters_subquery.c.notification_count,
|
|
|
|
|
letters_subquery.c.printing_at,
|
2019-12-03 15:53:32 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
|
|
return jobs_query.union_all(
|
|
|
|
|
letters_query
|
|
|
|
|
).order_by(
|
|
|
|
|
desc("processing_started"), desc("created_at")
|
|
|
|
|
).paginate(page=page, per_page=page_size)
|
2020-05-11 10:51:40 +01:00
|
|
|
|
|
|
|
|
|
|
|
|
|
def dao_get_uploaded_letters_by_print_date(service_id, letter_print_date, page=1, page_size=50):
|
|
|
|
|
return db.session.query(
|
|
|
|
|
Notification,
|
|
|
|
|
).join(
|
|
|
|
|
Template, Notification.template_id == Template.id
|
|
|
|
|
).filter(
|
|
|
|
|
Notification.service_id == service_id,
|
|
|
|
|
Notification.notification_type == LETTER_TYPE,
|
|
|
|
|
Notification.api_key_id.is_(None),
|
|
|
|
|
Notification.status != NOTIFICATION_CANCELLED,
|
|
|
|
|
Template.hidden.is_(True),
|
|
|
|
|
_get_printing_day(Notification.created_at) == letter_print_date.date(),
|
|
|
|
|
).order_by(
|
|
|
|
|
desc(Notification.created_at)
|
|
|
|
|
).paginate(
|
|
|
|
|
page=page,
|
|
|
|
|
per_page=page_size,
|
|
|
|
|
)
|