mirror of
https://github.com/GSA/notifications-api.git
synced 2025-12-20 23:41:17 -05:00
New endpoint to return a summary of returned letters for the service.
This commit is contained in:
@@ -1,5 +1,6 @@
|
|||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
|
|
||||||
|
from sqlalchemy import func, desc
|
||||||
from sqlalchemy.dialects.postgresql import insert
|
from sqlalchemy.dialects.postgresql import insert
|
||||||
|
|
||||||
from app import db
|
from app import db
|
||||||
@@ -7,6 +8,19 @@ from app.dao.dao_utils import transactional
|
|||||||
from app.models import Notification, NotificationHistory, ReturnedLetter
|
from app.models import Notification, NotificationHistory, ReturnedLetter
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def _get_notification_ids_for_references(references):
|
||||||
|
notification_ids = db.session.query(Notification.id, Notification.service_id).filter(
|
||||||
|
Notification.reference.in_(references)
|
||||||
|
).all()
|
||||||
|
|
||||||
|
notification_history_ids = db.session.query(NotificationHistory.id, NotificationHistory.service_id).filter(
|
||||||
|
NotificationHistory.reference.in_(references)
|
||||||
|
).all()
|
||||||
|
|
||||||
|
return notification_ids + notification_history_ids
|
||||||
|
|
||||||
|
|
||||||
@transactional
|
@transactional
|
||||||
def insert_or_update_returned_letters(references):
|
def insert_or_update_returned_letters(references):
|
||||||
data = _get_notification_ids_for_references(references)
|
data = _get_notification_ids_for_references(references)
|
||||||
@@ -28,13 +42,14 @@ def insert_or_update_returned_letters(references):
|
|||||||
db.session.connection().execute(stmt)
|
db.session.connection().execute(stmt)
|
||||||
|
|
||||||
|
|
||||||
def _get_notification_ids_for_references(references):
|
def get_returned_letter_summary(service_id):
|
||||||
notification_ids = db.session.query(Notification.id, Notification.service_id).filter(
|
return db.session.query(
|
||||||
Notification.reference.in_(references)
|
func.count(ReturnedLetter.notification_id).label('returned_letter_count'),
|
||||||
|
ReturnedLetter.reported_at
|
||||||
|
).filter(
|
||||||
|
ReturnedLetter.service_id == service_id,
|
||||||
|
).group_by(
|
||||||
|
ReturnedLetter.reported_at
|
||||||
|
).order_by(
|
||||||
|
desc(ReturnedLetter.reported_at)
|
||||||
).all()
|
).all()
|
||||||
|
|
||||||
notification_history_ids = db.session.query(NotificationHistory.id, NotificationHistory.service_id).filter(
|
|
||||||
NotificationHistory.reference.in_(references)
|
|
||||||
).all()
|
|
||||||
|
|
||||||
return notification_ids + notification_history_ids
|
|
||||||
|
|||||||
@@ -29,6 +29,7 @@ from app.dao.fact_notification_status_dao import (
|
|||||||
)
|
)
|
||||||
from app.dao.inbound_numbers_dao import dao_allocate_number_for_service
|
from app.dao.inbound_numbers_dao import dao_allocate_number_for_service
|
||||||
from app.dao.organisation_dao import dao_get_organisation_by_service_id
|
from app.dao.organisation_dao import dao_get_organisation_by_service_id
|
||||||
|
from app.dao.returned_letters_dao import get_returned_letter_summary
|
||||||
from app.dao.service_data_retention_dao import (
|
from app.dao.service_data_retention_dao import (
|
||||||
fetch_service_data_retention,
|
fetch_service_data_retention,
|
||||||
fetch_service_data_retention_by_id,
|
fetch_service_data_retention_by_id,
|
||||||
@@ -939,3 +940,12 @@ def check_if_reply_to_address_already_in_use(service_id, email_address):
|
|||||||
raise InvalidRequest(
|
raise InvalidRequest(
|
||||||
"Your service already uses ‘{}’ as an email reply-to address.".format(email_address), status_code=400
|
"Your service already uses ‘{}’ as an email reply-to address.".format(email_address), status_code=400
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@service_blueprint.route('/returned-letter-summary')
|
||||||
|
def returned_letter_summary(service_id):
|
||||||
|
results = get_returned_letter_summary(service_id)
|
||||||
|
|
||||||
|
json_results = [{'returned_letter_count': x.returned_letter_count, 'reported_at': x.reported_at} for x in results]
|
||||||
|
|
||||||
|
return jsonify(json_results)
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
from datetime import datetime
|
from datetime import datetime, timedelta
|
||||||
|
|
||||||
from freezegun import freeze_time
|
from freezegun import freeze_time
|
||||||
|
|
||||||
from app.dao.returned_letters_dao import insert_or_update_returned_letters
|
from app.dao.returned_letters_dao import insert_or_update_returned_letters, get_returned_letter_summary
|
||||||
from app.models import ReturnedLetter
|
from app.models import ReturnedLetter
|
||||||
from tests.app.db import create_notification, create_notification_history
|
from tests.app.db import create_notification, create_notification_history, create_returned_letter
|
||||||
|
|
||||||
|
|
||||||
def test_insert_or_update_returned_letters_inserts(sample_letter_template):
|
def test_insert_or_update_returned_letters_inserts(sample_letter_template):
|
||||||
@@ -81,3 +81,34 @@ def test_insert_or_update_returned_letters_with_duplicates_in_reference_list(sam
|
|||||||
assert len(returned_letters) == 2
|
assert len(returned_letters) == 2
|
||||||
for x in returned_letters:
|
for x in returned_letters:
|
||||||
assert x.notification_id in [notification_1.id, notification_2.id]
|
assert x.notification_id in [notification_1.id, notification_2.id]
|
||||||
|
|
||||||
|
|
||||||
|
def test_get_returned_letter_summary(sample_service):
|
||||||
|
now = datetime.utcnow()
|
||||||
|
create_returned_letter(sample_service, reported_at=now)
|
||||||
|
create_returned_letter(sample_service, reported_at=now)
|
||||||
|
|
||||||
|
results = get_returned_letter_summary(sample_service.id)
|
||||||
|
|
||||||
|
assert len(results) == 1
|
||||||
|
|
||||||
|
assert results[0].returned_letter_count == 2
|
||||||
|
assert results[0].reported_at == now
|
||||||
|
|
||||||
|
|
||||||
|
def test_get_returned_letter_summary_orders_by_reported_at(sample_service):
|
||||||
|
now = datetime.utcnow()
|
||||||
|
last_month = datetime.utcnow() - timedelta(days=30)
|
||||||
|
create_returned_letter(sample_service, reported_at=now)
|
||||||
|
create_returned_letter(sample_service, reported_at=now)
|
||||||
|
create_returned_letter(sample_service, reported_at=now)
|
||||||
|
create_returned_letter(sample_service, reported_at=last_month)
|
||||||
|
create_returned_letter(sample_service, reported_at=last_month)
|
||||||
|
|
||||||
|
results = get_returned_letter_summary(sample_service.id)
|
||||||
|
|
||||||
|
assert len(results) == 2
|
||||||
|
assert results[0].reported_at == now
|
||||||
|
assert results[0].returned_letter_count == 3
|
||||||
|
assert results[1].reported_at == last_month
|
||||||
|
assert results[1].returned_letter_count == 2
|
||||||
|
|||||||
@@ -59,7 +59,9 @@ from app.models import (
|
|||||||
TemplateFolder,
|
TemplateFolder,
|
||||||
LetterBranding,
|
LetterBranding,
|
||||||
Domain,
|
Domain,
|
||||||
NotificationHistory
|
NotificationHistory,
|
||||||
|
NOTIFICATION_RETURNED_LETTER,
|
||||||
|
ReturnedLetter
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@@ -940,3 +942,19 @@ def set_up_usage_data(start_date):
|
|||||||
notifications_sent=15, billable_unit=4, rate=.55, postage='second')
|
notifications_sent=15, billable_unit=4, rate=.55, postage='second')
|
||||||
|
|
||||||
return org, org_3, service, service_3, service_4, service_sms_only
|
return org, org_3, service, service_3, service_4, service_sms_only
|
||||||
|
|
||||||
|
|
||||||
|
def create_returned_letter(service, reported_at=None):
|
||||||
|
if not service:
|
||||||
|
service = create_service(service_name='a - with sms and letter')
|
||||||
|
template = create_template(service=service, template_type=LETTER_TYPE)
|
||||||
|
notification = create_notification(template=template, status=NOTIFICATION_RETURNED_LETTER)
|
||||||
|
returned_letter = ReturnedLetter(
|
||||||
|
service_id= service.id,
|
||||||
|
reported_at= reported_at or datetime.utcnow(),
|
||||||
|
notification_id= notification.id
|
||||||
|
)
|
||||||
|
|
||||||
|
db.session.add(returned_letter)
|
||||||
|
db.session.commit()
|
||||||
|
return returned_letter
|
||||||
Reference in New Issue
Block a user