Adding new method to cancel a letter job.

This commit is contained in:
Rebecca Law
2019-06-10 17:40:28 +01:00
committed by Pea Tyczynska
parent 5093b68f94
commit 6565c19a9b
3 changed files with 60 additions and 15 deletions

View File

@@ -2,14 +2,17 @@ import uuid
from datetime import datetime, timedelta from datetime import datetime, timedelta
from flask import current_app from flask import current_app
from notifications_utils.letter_timings import letter_can_be_cancelled
from notifications_utils.statsd_decorators import statsd from notifications_utils.statsd_decorators import statsd
from sqlalchemy import ( from sqlalchemy import (
asc, asc,
desc, desc,
func, func,
) )
from sqlalchemy.testing import not_in_
from app import db from app import db
from app.dao.dao_utils import transactional
from app.utils import midnight_n_days_ago from app.utils import midnight_n_days_ago
from app.models import ( from app.models import (
Job, Job,
@@ -18,7 +21,11 @@ from app.models import (
LETTER_TYPE, LETTER_TYPE,
Notification, Notification,
Template, Template,
ServiceDataRetention ServiceDataRetention,
NOTIFICATION_SENDING,
NOTIFICATION_CREATED,
NOTIFICATION_CANCELLED,
JOB_STATUS_CANCELLED
) )
from app.variables import LETTER_TEST_API_FILENAME from app.variables import LETTER_TEST_API_FILENAME
@@ -148,16 +155,37 @@ def dao_get_jobs_older_than_data_retention(notification_types):
return jobs return jobs
def dao_get_all_letter_jobs(): @transactional
return db.session.query( def dao_cancel_letter_job(service_id, job_id):
Job if can_cancel_letter_job(job_id, service_id):
).join( number_of_notifications_cancelled = Notification.query.filter(
Job.template Notification.job_id == job_id
).filter( ).update({'status': NOTIFICATION_CANCELLED,
Template.template_type == LETTER_TYPE, 'updated_at': datetime.utcnow(),
# test letter jobs (or from research mode services) are created with a different filename, 'billable_units': 0})
# exclude them so we don't see them on the send to CSV # calling this 2x - pass job into can_cancel_letter_job
Job.original_file_name != LETTER_TEST_API_FILENAME job = dao_get_job_by_service_id_and_job_id(service_id, job_id)
).order_by( job.job_status = JOB_STATUS_CANCELLED
desc(Job.created_at) dao_update_job(job)
).all() return number_of_notifications_cancelled
def can_cancel_letter_job(job_id, service_id):
job = dao_get_job_by_service_id_and_job_id(service_id, job_id)
# assert is a letter job
# assert job status == finished???
# Notifications are not in pending-virus-check
count_notifications_in_sending = Notification.query.filter(
Notification.job_id == job_id,
Notification.status.not_in_('created', 'pending-virus-check', 'cancelled')
).count()
if count_notifications_in_sending > 0:
return False
if not letter_can_be_cancelled(NOTIFICATION_CREATED, job.created_at):
return False
else:
return True

View File

@@ -5,6 +5,7 @@ from flask import (
request, request,
current_app current_app
) )
from notifications_utils.letter_timings import letter_can_be_cancelled
from app.aws.s3 import get_job_metadata_from_s3 from app.aws.s3 import get_job_metadata_from_s3
from app.dao.jobs_dao import ( from app.dao.jobs_dao import (
@@ -13,7 +14,8 @@ from app.dao.jobs_dao import (
dao_get_job_by_service_id_and_job_id, dao_get_job_by_service_id_and_job_id,
dao_get_jobs_by_service_id, dao_get_jobs_by_service_id,
dao_get_future_scheduled_job_by_id_and_service_id, dao_get_future_scheduled_job_by_id_and_service_id,
dao_get_notification_outcomes_for_job) dao_get_notification_outcomes_for_job, dao_cancel_letter_job
)
from app.dao.fact_notification_status_dao import fetch_notification_statuses_for_job from app.dao.fact_notification_status_dao import fetch_notification_statuses_for_job
from app.dao.services_dao import dao_fetch_service_by_id from app.dao.services_dao import dao_fetch_service_by_id
from app.dao.templates_dao import dao_get_template_by_id from app.dao.templates_dao import dao_get_template_by_id

View File

@@ -14,6 +14,7 @@ from app.dao.jobs_dao import (
dao_get_future_scheduled_job_by_id_and_service_id, dao_get_future_scheduled_job_by_id_and_service_id,
dao_get_notification_outcomes_for_job, dao_get_notification_outcomes_for_job,
dao_get_jobs_older_than_data_retention, dao_get_jobs_older_than_data_retention,
dao_cancel_letter_job
) )
from app.models import ( from app.models import (
Job, Job,
@@ -308,3 +309,17 @@ def assert_job_stat(job, result, sent, delivered, failed):
assert result.sent == sent assert result.sent == sent
assert result.delivered == delivered assert result.delivered == delivered
assert result.failed == failed assert result.failed == failed
def test_dao_cancel_letter_job_does_not_allow_cancel_if_notification_in_sending(sample_job):
create_notification(template=sample_job.template, job=sample_job, status='sending')
create_notification(template=sample_job.template, job=sample_job, status='created')
assert not dao_cancel_letter_job(service_id=sample_job.service_id, job_id=sample_job.id)
def test_dao_cancel_letter_job_updates_notifications_and_job_to_cancelled(sample_job):
notification = create_notification(template=sample_job.template, job=sample_job, status='created')
assert dao_cancel_letter_job(service_id=sample_job.service_id, job_id=sample_job.id) == 1
assert notification.status == 'cancelled'
assert sample_job.job_status == 'cancelled'