Handle request status event transitions

This commit is contained in:
richard-dds 2018-10-29 14:57:25 -04:00
parent f3be2d76ea
commit 85034185bc
7 changed files with 99 additions and 12 deletions

View File

@ -6,9 +6,11 @@ from atst.models.request_status_event import RequestStatusEvent, RequestStatus
from atst.models.request_review import RequestReview
from atst.models.request_internal_comment import RequestInternalComment
from atst.utils import deep_merge
from atst.queue import queue
from .query import RequestsQuery
from .authorization import RequestsAuthorization
from .status_event_handler import RequestStatusEventHandler
def create_revision_from_request_body(body):
@ -95,11 +97,17 @@ class Requests(object):
@classmethod
def set_status(cls, request, status: RequestStatus):
old_status = request.status
status_event = RequestStatusEvent(
new_status=status, revision=request.latest_revision
)
request.status_events.append(status_event)
return RequestsQuery.add_and_commit(request)
updated_request = RequestsQuery.add_and_commit(request)
RequestStatusEventHandler(queue).handle_status_change(
updated_request, old_status, status
)
return updated_request
@classmethod
def should_auto_approve(cls, request):

View File

@ -0,0 +1,41 @@
from flask import render_template
from atst.models.request_status_event import RequestStatus
class RequestStatusEventHandler(object):
def __init__(self, queue):
self.queue = queue
def handle_status_change(self, request, old_status, new_status):
handler = self._get_handler(old_status, new_status)
if handler:
handler(request)
def _get_handler(self, old_status, new_status):
return {
(
RequestStatus.PENDING_CCPO_ACCEPTANCE,
RequestStatus.PENDING_FINANCIAL_VERIFICATION,
): self._send_email,
(
RequestStatus.PENDING_CCPO_ACCEPTANCE,
RequestStatus.CHANGES_REQUESTED,
): self._send_email,
(
RequestStatus.PENDING_CCPO_APPROVAL,
RequestStatus.CHANGES_REQUESTED_TO_FINVER,
): self._send_email,
(
RequestStatus.PENDING_CCPO_APPROVAL,
RequestStatus.APPROVED,
): self._send_email,
}.get((old_status, new_status))
def _send_email(self, request):
email_body = render_template(
"emails/request_status_change.txt", request=request
)
self.queue.send_mail(
[request.creator.email], "Your JEDI request status has changed", email_body
)

View File

@ -27,8 +27,8 @@ class ATSTQueue(RQ):
# pylint: disable=pointless-string-statement
"""Instance methods to queue up application-specific jobs."""
def send_mail(self, to, subject, body):
self._queue_job(ATSTQueue._send_mail, to, subject, body)
def send_mail(self, recipients, subject, body):
self._queue_job(ATSTQueue._send_mail, recipients, subject, body)
# pylint: disable=pointless-string-statement
"""Class methods to actually perform the work.
@ -38,8 +38,8 @@ class ATSTQueue(RQ):
"""
@classmethod
def _send_mail(self, to, subject, body):
app.mailer.send(to, subject, body)
def _send_mail(self, recipients, subject, body):
app.mailer.send(recipients, subject, body)
queue = ATSTQueue()

View File

@ -0,0 +1,5 @@
<h1>Your JEDI request status has changed</h1>
The status of your JEDI Cloud request - {{ request.name }} - was recently updated. Log in to see whether this change requires an action or response from you.
{{ url_for('requests.view_request_details', request_id=request.id, _external=True) }}

View File

@ -137,8 +137,7 @@ def extended_financial_verification_data(pdf_upload):
}
@pytest.fixture(scope="function")
@pytest.fixture(scope="function", autouse=True)
def queue():
_queue = atst_queue
yield _queue
_queue.get_queue().empty()
yield atst_queue
atst_queue.get_queue().empty()

View File

@ -6,13 +6,11 @@ from atst.domain.requests import Requests
from atst.domain.requests.authorization import RequestsAuthorization
from atst.models.request import Request
from atst.models.request_status_event import RequestStatus
from atst.models.task_order import Source as TaskOrderSource
from tests.factories import (
RequestFactory,
UserFactory,
RequestStatusEventFactory,
TaskOrderFactory,
RequestRevisionFactory,
RequestReviewFactory,
)
@ -222,3 +220,37 @@ def test_random_user_cannot_view_request():
request = RequestFactory.create()
assert not RequestsAuthorization(user, request).can_view
def test_pending_finver_triggers_notification(queue):
request = RequestFactory.create()
request = Requests.set_status(request, RequestStatus.PENDING_CCPO_ACCEPTANCE)
request = Requests.set_status(request, RequestStatus.PENDING_FINANCIAL_VERIFICATION)
assert len(queue.get_queue()) == 1
def test_changes_requested_triggers_notification(queue):
request = RequestFactory.create()
request = Requests.set_status(request, RequestStatus.PENDING_CCPO_ACCEPTANCE)
request = Requests.set_status(request, RequestStatus.CHANGES_REQUESTED)
assert len(queue.get_queue()) == 1
def test_changes_requested_to_finver_triggers_notification(queue):
request = RequestFactory.create()
request = Requests.set_status(request, RequestStatus.PENDING_CCPO_APPROVAL)
request = Requests.set_status(request, RequestStatus.CHANGES_REQUESTED_TO_FINVER)
assert len(queue.get_queue()) == 1
def test_approval_triggers_notification(queue):
request = RequestFactory.create()
request = Requests.set_status(request, RequestStatus.PENDING_CCPO_APPROVAL)
request = Requests.set_status(request, RequestStatus.APPROVED)
assert len(queue.get_queue()) == 1
def test_submitted_does_not_trigger_notification(queue):
request = RequestFactory.create()
request = Requests.set_status(request, RequestStatus.SUBMITTED)
assert len(queue.get_queue()) == 0

View File

@ -239,7 +239,9 @@ def test_displays_ccpo_review_comment(user_session, client):
request = RequestFactory.create(creator=creator)
request = Requests.set_status(request, RequestStatus.CHANGES_REQUESTED)
review_comment = "add all of the correct info, instead of the incorrect info"
RequestReviewFactory.create(reviewer=ccpo, comment=review_comment, status=request.status_events[-1])
RequestReviewFactory.create(
reviewer=ccpo, comment=review_comment, status=request.status_events[-1]
)
response = client.get("/requests/new/1/{}".format(request.id))
body = response.data.decode()
assert review_comment in body