Merge branch 'master' into template-query-to-not-limit-by-days

This commit is contained in:
Martyn Inglis
2017-06-16 14:06:56 +01:00
36 changed files with 1897 additions and 386 deletions

View File

@@ -47,3 +47,10 @@ def delete_inbound_sms_created_more_than_a_week_ago():
).delete(synchronize_session='fetch')
return deleted
def dao_get_inbound_sms_by_id(service_id, inbound_id):
return InboundSms.query.filter_by(
id=inbound_id,
service_id=service_id
).one()

View File

@@ -1,17 +1,15 @@
from datetime import datetime
from datetime import datetime, timedelta
from flask import current_app
from sqlalchemy import func, desc, asc, cast, Date as sql_date
from app import db
from app.dao import days_ago
from app.models import (Job,
Notification,
NotificationHistory,
Template,
JOB_STATUS_SCHEDULED,
JOB_STATUS_PENDING,
LETTER_TYPE, JobStatistics)
from app.models import (
Job, JobStatistics, Notification, NotificationHistory, Template,
JOB_STATUS_SCHEDULED, JOB_STATUS_PENDING,
LETTER_TYPE
)
from app.statsd_decorators import statsd
@@ -129,10 +127,14 @@ def dao_update_job_status(job_id, status):
db.session.commit()
def dao_get_jobs_older_than_limited_by(older_than=7, limit_days=2):
return Job.query.filter(
cast(Job.created_at, sql_date) < days_ago(older_than),
cast(Job.created_at, sql_date) >= days_ago(older_than + limit_days)
def dao_get_jobs_older_than_limited_by(job_types, older_than=7, limit_days=2):
end_date = datetime.utcnow() - timedelta(days=older_than)
start_date = end_date - timedelta(days=limit_days)
return Job.query.join(Template).filter(
Job.created_at < end_date,
Job.created_at >= start_date,
Template.template_type.in_(job_types)
).order_by(desc(Job.created_at)).all()
@@ -140,3 +142,56 @@ def dao_get_all_letter_jobs():
return db.session.query(Job).join(Job.template).filter(
Template.template_type == LETTER_TYPE
).order_by(desc(Job.created_at)).all()
@statsd(namespace="dao")
def dao_get_job_statistics_for_job(service_id, job_id):
query = Job.query.join(
JobStatistics, Job.id == JobStatistics.job_id
).filter(
Job.id == job_id,
Job.service_id == service_id
).add_columns(
JobStatistics.job_id,
Job.original_file_name,
Job.created_at,
Job.scheduled_for,
Job.template_id,
Job.template_version,
Job.job_status,
Job.service_id,
Job.notification_count,
JobStatistics.sent,
JobStatistics.delivered,
JobStatistics.failed
)
return query.one()
@statsd(namespace="dao")
def dao_get_job_stats_for_service(service_id, page=1, page_size=50, limit_days=None, statuses=None):
query = Job.query.join(
JobStatistics, Job.id == JobStatistics.job_id
).filter(
Job.service_id == service_id
).add_columns(
JobStatistics.job_id,
Job.original_file_name,
Job.created_at,
Job.scheduled_for,
Job.template_id,
Job.template_version,
Job.job_status,
Job.service_id,
Job.notification_count,
JobStatistics.sent,
JobStatistics.delivered,
JobStatistics.failed
)
if limit_days:
query = query.filter(Job.created_at >= days_ago(limit_days))
if statuses is not None and statuses != ['']:
query = query.filter(Job.job_status.in_(statuses))
query = query.order_by(Job.created_at.desc())
return query.paginate(page=page, per_page=page_size)

View File

@@ -1,5 +1,6 @@
from datetime import datetime, timedelta
from flask import current_app
from sqlalchemy import Float, Integer
from sqlalchemy import func, case, cast
from sqlalchemy import literal_column
@@ -11,7 +12,7 @@ from app.models import (NotificationHistory,
NOTIFICATION_STATUS_TYPES_BILLABLE,
KEY_TYPE_TEST,
SMS_TYPE,
EMAIL_TYPE)
EMAIL_TYPE, Service)
from app.statsd_decorators import statsd
from app.utils import get_london_month_from_utc_column
@@ -158,6 +159,8 @@ def rate_multiplier():
@statsd(namespace="dao")
def get_total_billable_units_for_sent_sms_notifications_in_date_range(start_date, end_date, service_id):
free_sms_limit = Service.free_sms_fragment_limit()
billable_units = 0
total_cost = 0.0
@@ -176,9 +179,15 @@ def get_total_billable_units_for_sent_sms_notifications_in_date_range(start_date
)
billable_units_by_rate_boundry = result.scalar()
if billable_units_by_rate_boundry:
billable_units += int(billable_units_by_rate_boundry)
total_cost += int(billable_units_by_rate_boundry) * rate_boundary['rate']
int_billable_units_by_rate_boundry = int(billable_units_by_rate_boundry)
if billable_units >= free_sms_limit:
total_cost += int_billable_units_by_rate_boundry * rate_boundary['rate']
elif billable_units + int_billable_units_by_rate_boundry > free_sms_limit:
remaining_free_allowance = abs(free_sms_limit - billable_units)
total_cost += ((int_billable_units_by_rate_boundry - remaining_free_allowance) * rate_boundary['rate'])
else:
total_cost += 0
billable_units += int_billable_units_by_rate_boundry
return billable_units, total_cost

View File

@@ -507,7 +507,7 @@ def dao_get_notifications_by_to_field(service_id, search_term, statuses=None):
if statuses:
filters.append(Notification.status.in_(statuses))
results = db.session.query(Notification).filter(*filters).all()
results = db.session.query(Notification).filter(*filters).order_by(desc(Notification.created_at)).all()
return results

View File

@@ -60,7 +60,10 @@ def timeout_job_counts(notifications_type, timeout_start):
).update({
sent: sent_count,
failed: failed_count,
delivered: delivered_count
delivered: delivered_count,
'sent': sent_count,
'delivered': delivered_count,
'failed': failed_count
}, synchronize_session=False)
return total_updated
@@ -87,11 +90,13 @@ def create_or_update_job_sending_statistics(notification):
@transactional
def __update_job_stats_sent_count(notification):
column = columns(notification.notification_type, 'sent')
new_column = 'sent'
return db.session.query(JobStatistics).filter_by(
job_id=notification.job_id,
).update({
column: column + 1
column: column + 1,
new_column: column + 1
})
@@ -102,7 +107,8 @@ def __insert_job_stats(notification):
emails_sent=1 if notification.notification_type == EMAIL_TYPE else 0,
sms_sent=1 if notification.notification_type == SMS_TYPE else 0,
letters_sent=1 if notification.notification_type == LETTER_TYPE else 0,
updated_at=datetime.utcnow()
updated_at=datetime.utcnow(),
sent=1
)
db.session.add(stats)
@@ -131,10 +137,12 @@ def columns(notification_type, status):
def update_job_stats_outcome_count(notification):
if notification.status in NOTIFICATION_STATUS_TYPES_FAILED:
column = columns(notification.notification_type, 'failed')
new_column = 'failed'
elif notification.status in [NOTIFICATION_DELIVERED,
NOTIFICATION_SENT] and notification.notification_type != LETTER_TYPE:
column = columns(notification.notification_type, 'delivered')
new_column = 'delivered'
else:
column = None
@@ -143,7 +151,8 @@ def update_job_stats_outcome_count(notification):
return db.session.query(JobStatistics).filter_by(
job_id=notification.job_id,
).update({
column: column + 1
column: column + 1,
new_column: column + 1
})
else:
return 0