diff --git a/atst/domain/requests/query.py b/atst/domain/requests/query.py index 10e6e434..d080f941 100644 --- a/atst/domain/requests/query.py +++ b/atst/domain/requests/query.py @@ -1,8 +1,10 @@ from sqlalchemy import exists, and_, exc, text +from sqlalchemy.orm.exc import NoResultFound from atst.database import db from atst.domain.common import Query from atst.models.request import Request +from atst.domain.exceptions import NotFoundError class RequestsQuery(Query): diff --git a/atst/routes/requests/financial_verification.py b/atst/routes/requests/financial_verification.py index 86b7f383..5b84392e 100644 --- a/atst/routes/requests/financial_verification.py +++ b/atst/routes/requests/financial_verification.py @@ -6,80 +6,129 @@ from atst.domain.requests import Requests from atst.forms.financial import FinancialForm, ExtendedFinancialForm -def task_order_data(task_order): - data = task_order.to_dictionary() - data["task_order_number"] = task_order.number - data["funding_type"] = task_order.funding_type.value - return data +class FinancialVerification: + def __init__(self, request, extended=False, post_data=None): + self.request = request + self._extended = extended + self._post_data = post_data + self._form = None + self.reset() + def reset(self): + self._updateable = False + self._valid = False + self.workspace = None + if self._form: + self._form.reset() -def is_extended(request): - return ( - http_request.args.get("extended") - or request.is_pending_financial_verification_changes - ) + @property + def is_extended(self): + return self._extended or self.is_pending_changes + @property + def is_pending_changes(self): + return self.request.is_pending_financial_verification_changes -def financial_form(request, data): - if is_extended(request): - return ExtendedFinancialForm(data=data) - else: - return FinancialForm(data=data) + @property + def _task_order_data(self): + if self.request.task_order: + task_order = self.request.task_order + data = task_order.to_dictionary() + data["task_order_number"] = task_order.number + data["funding_type"] = task_order.funding_type.value + return data + else: + return {} + + @property + def _form_data(self): + if self._post_data: + return self._post_data + else: + form_data = self.request.body.get("financial_verification", {}) + form_data.update(self._task_order_data) + + return form_data + + @property + def form(self): + if not self._form: + if self.is_extended: + self._form = ExtendedFinancialForm(data=self._form_data) + else: + self._form = FinancialForm(data=self._form_data) + + return self._form + + def validate(self): + if self.form.validate(): + self._updateable = True + self._valid = self.form.perform_extra_validation( + self.request.body.get("financial_verification") + ) + else: + self._updateable = False + self._valid = False + + return self._valid + + @property + def pending(self): + return self.request.is_pending_ccpo_approval + + def finalize(self): + if self._updateable: + self.request = Requests.update_financial_verification( + self.request.id, self.form.data + ) + + if self._valid: + self.request = Requests.submit_financial_verification(self.request) + + if self.request.is_financially_verified: + self.workspace = Requests.approve_and_create_workspace(self.request) @requests_bp.route("/requests/verify/", methods=["GET"]) -def financial_verification(request_id=None): +def financial_verification(request_id): request = Requests.get(g.current_user, request_id) - form_data = request.body.get("financial_verification") - if request.task_order: - form_data.update(task_order_data(request.task_order)) + finver = FinancialVerification(request, extended=http_request.args.get("extended")) - form = financial_form(request, form_data) return render_template( "requests/financial_verification.html", - f=form, - jedi_request=request, - review_comment=request.review_comment, - extended=is_extended(request), + f=finver.form, + jedi_request=finver.request, + review_comment=finver.request.review_comment, + extended=finver.is_extended, ) @requests_bp.route("/requests/verify/", methods=["POST"]) def update_financial_verification(request_id): - post_data = http_request.form - existing_request = Requests.get(g.current_user, request_id) - form = financial_form(existing_request, post_data) - rerender_args = dict( - jedi_request=existing_request, f=form, extended=is_extended(existing_request) + request = Requests.get(g.current_user, request_id) + finver = FinancialVerification( + request, extended=http_request.args.get("extended"), post_data=http_request.form ) - if form.validate(): - valid = form.perform_extra_validation( - existing_request.body.get("financial_verification") - ) - updated_request = Requests.update_financial_verification(request_id, form.data) - if valid: - submitted_request = Requests.submit_financial_verification(updated_request) - if submitted_request.is_financially_verified: - new_workspace = Requests.approve_and_create_workspace(submitted_request) - return redirect( - url_for( - "workspaces.new_project", - workspace_id=new_workspace.id, - newWorkspace=True, - ) - ) - else: - return redirect( - url_for("requests.requests_index", modal="pendingCCPOApproval") - ) + finver.validate() - else: - form.reset() - return render_template( - "requests/financial_verification.html", **rerender_args + finver.finalize() + + if finver.workspace: + return redirect( + url_for( + "workspaces.new_project", + workspace_id=finver.workspace.id, + newWorkspace=True, ) - + ) + elif finver.pending: + return redirect(url_for("requests.requests_index", modal="pendingCCPOApproval")) else: - form.reset() - return render_template("requests/financial_verification.html", **rerender_args) + finver.reset() + return render_template( + "requests/financial_verification.html", + jedi_request=finver.request, + f=finver.form, + extended=finver.is_extended, + ) diff --git a/tests/routes/test_financial_verification.py b/tests/routes/test_financial_verification.py index aaa9b54d..91630abe 100644 --- a/tests/routes/test_financial_verification.py +++ b/tests/routes/test_financial_verification.py @@ -4,6 +4,7 @@ from flask import url_for from atst.eda_client import MockEDAClient from atst.models.request_status_event import RequestStatus +from atst.routes.requests.financial_verification import FinancialVerification from tests.mocks import MOCK_REQUEST, MOCK_USER from tests.factories import ( @@ -172,3 +173,47 @@ def test_displays_ccpo_review_comment(user_session, client): response = client.get("/requests/verify/{}".format(request.id)) body = response.data.decode() assert review_comment in body + + +class TestFinancialVerification: + def _service_object(self, request=None, extended=False, post_data={}): + if not request: + self.request = RequestFactory.create() + else: + self.request = request + + return FinancialVerification( + self.request, extended=extended, post_data=post_data + ) + + def test_is_extended(self): + finver_one = self._service_object() + assert not finver_one.is_extended + finver_two = self._service_object( + request=RequestFactory.create_with_status( + RequestStatus.CHANGES_REQUESTED_TO_FINVER + ) + ) + assert finver_two.is_extended + finver_three = self._service_object(extended=True) + assert finver_three.is_extended + + def test_is_pending_changes(self): + finver_one = self._service_object() + assert not finver_one.is_pending_changes + finver_two = self._service_object( + request=RequestFactory.create_with_status( + RequestStatus.CHANGES_REQUESTED_TO_FINVER + ) + ) + assert finver_two.is_pending_changes + + def test_pending(self): + finver_one = self._service_object() + assert not finver_one.pending + finver_two = self._service_object( + request=RequestFactory.create_with_status( + RequestStatus.PENDING_CCPO_APPROVAL + ) + ) + assert finver_two.pending