diff --git a/atst/handlers/request_financial_verification.py b/atst/handlers/request_financial_verification.py index 51445d66..a3bf8fc8 100644 --- a/atst/handlers/request_financial_verification.py +++ b/atst/handlers/request_financial_verification.py @@ -1,11 +1,6 @@ import tornado -from collections import defaultdict from atst.handler import BaseHandler -from atst.forms.request import RequestForm -from atst.forms.org import OrgForm -from atst.forms.poc import POCForm -from atst.forms.review import ReviewForm from atst.forms.financial import FinancialForm @@ -25,12 +20,54 @@ class RequestFinancialVerification(BaseHandler): @tornado.web.authenticated @tornado.gen.coroutine def get(self, request_id=None): - # self.check_xsrf_cookie() - # post_data = self.request.arguments - current_user = self.get_current_user() existing_request = yield self.get_existing_request(request_id) + form = FinancialForm(data=existing_request['body'].get('financial_verification')) self.render( "requests/financial_verification.html.to", page=self.page, + f=form, + request_id=request_id, ) + @tornado.gen.coroutine + def update_request(self, request_id, form_data): + request_data = { + "creator_id": self.current_user["id"], + "request": {"financial_verification": form_data}, + } + response = yield self.requests_client.patch( + "/requests/{}".format(request_id), json=request_data + ) + return response + + @tornado.web.authenticated + @tornado.gen.coroutine + def post(self, request_id=None): + self.check_xsrf_cookie() + post_data = self.request.arguments + existing_request = yield self.get_existing_request(request_id) + form = FinancialForm(post_data) + + rerender_args = dict(request_id=request_id, f=form) + + if form.validate(): + response = yield self.update_request(request_id, form.data) + if response.ok: + valid = yield form.perform_extra_validation( + existing_request.get('body', {}).get('financial_verification'), + self.fundz_client + ) + if valid: + self.redirect('/requests') + else: + self.render( + "requests/financial_verification.html.to", + **rerender_args + ) + else: + self.set_status(response.code) + else: + self.render( + "requests/financial_verification.html.to", + **rerender_args + ) diff --git a/atst/handlers/request_new.py b/atst/handlers/request_new.py index 096572d3..de3c2713 100644 --- a/atst/handlers/request_new.py +++ b/atst/handlers/request_new.py @@ -6,7 +6,6 @@ from atst.forms.request import RequestForm from atst.forms.org import OrgForm from atst.forms.poc import POCForm from atst.forms.review import ReviewForm -from atst.forms.financial import FinancialForm class RequestNew(BaseHandler): @@ -221,12 +220,6 @@ class JEDIRequestFlow(object): "form": ReviewForm, "show":True, }, - { - "title": "Financial Verification", - "section": "financial_verification", - "form": FinancialForm, - "show": self.request and self.request["status"] == "approved", - }, ] @tornado.gen.coroutine diff --git a/templates/requests/financial_verification.html.to b/templates/requests/financial_verification.html.to index 06abd2ea..dc1c4d71 100644 --- a/templates/requests/financial_verification.html.to +++ b/templates/requests/financial_verification.html.to @@ -9,13 +9,211 @@
-

Order #36552512

-

Financial Verification

+

Order #{{ request_id }}

+

Financial Verification

+ {% block form_action %} +
+ {% end %} + + {% module xsrf_form_html() %} + {% block form %} + {% autoescape None %} + {% if f.errors %} + There were some errors, see below. + {% end %} + +

In order to get you access to the JEDI Cloud, we will need you to enter the details below that will help us verify and account for your Task Order.

+ + {{ f.task_order_id.label }} + {{ f.task_order_id(placeholder="Example: 1234567899C0001") }} + {% for e in f.task_order_id.errors %} +
+ {{ e }} +
+ {% end %} + + {{ f.uii_ids.label }} + {{ f.uii_ids(placeholder="Example: \nDI 0CVA5786950 \nUN1945326361234786950") }} + {% for e in f.uii_ids.errors %} +
+ {{ e }} +
+ {% end %} + + {{ f.pe_id.label }} + {{ f.pe_id(placeholder="Example: 0203752A") }} + {% for e in f.pe_id.errors %} +
+ {{ e }} +
+ {% end %} + + {{ f.treasury_code.label }} + {{ f.treasury_code(placeholder="Example: 1200") }} + {% for e in f.treasury_code.errors %} +
+ {{ e }} +
+ {% end %} + + {{ f.ba_code.label }} + {{ f.ba_code(placeholder="Example: 02") }} + {% for e in f.ba_code.errors %} +
+ {{ e }} +
+ {% end %} + + + +

Contracting Officer (KO) Information

+ + {{ f.fname_co.label }} + {{ f.fname_co(placeholder="Contracting Officer first name") }} + {% for e in f.fname_co.errors %} +
+ {{ e }} +
+ {% end %} + + {{ f.lname_co.label }} + {{ f.lname_co(placeholder="Contracting Officer last name") }} + {% for e in f.lname_co.errors %} +
+ {{ e }} +
+ {% end %} + + {{ f.email_co.label }} + {{ f.email_co(placeholder="jane@mail.mil") }} + {% for e in f.email_co.errors %} +
+ {{ e }} +
+ {% end %} + + {{ f.office_co.label }} + {{ f.office_co(placeholder="Example: WHS") }} + {% for e in f.office_co.errors %} +
+ {{ e }} +
+ {% end %} + + + + +

Contracting Officer Representative (COR) Information

+ + {{ f.fname_cor.label }} + {{ f.fname_cor(placeholder="Contracting Officer Representative first name") }} + {% for e in f.fname_cor.errors %} +
+ {{ e }} +
+ {% end %} + + {{ f.lname_cor.label }} + {{ f.lname_cor(placeholder="Contracting Officer Representative last name") }} + {% for e in f.lname_cor.errors %} +
+ {{ e }} +
+ {% end %} + + {{ f.email_cor.label }} + {{ f.email_cor(placeholder="jane@mail.mil") }} + {% for e in f.email_cor.errors %} +
+ {{ e }} +
+ {% end %} + + {{ f.office_cor.label }} + {{ f.office_cor(placeholder="Example: WHS") }} + {% for e in f.office_cor.errors %} +
+ {{ e }} +
+ {% end %} + +

+ ↓ FIELDS NEEDED FOR MANUAL ENTRY OF TASK ORDER INFORMATION (only necessary if EDA info not available) + + + {{ f.funding_type.label }} + {{ f.funding_type }} + {% for e in f.funding_type.errors %} +
+ {{ e }} +
+ {% end %} + + {{ f.funding_type_other.label }} + {{ f.funding_type_other(placeholder="") }} + {% for e in f.funding_type_other.errors %} +
+ {{ e }} +
+ {% end %} + + {{ f.clin_0001.label }} + {{ f.clin_0001(placeholder="50,000") }} + {% for e in f.clin_0001.errors %} +
+ {{ e }} +
+ {% end %} + + {{ f.clin_0003.label }} + {{ f.clin_0003(placeholder="13,000") }} + {% for e in f.clin_0003.errors %} +
+ {{ e }} +
+ {% end %} + + {{ f.clin_1001.label }} + {{ f.clin_1001(placeholder="30,000") }} + {% for e in f.clin_1001.errors %} +
+ {{ e }} +
+ {% end %} + + {{ f.clin_1003.label }} + {{ f.clin_1003(placeholder="7,000") }} + {% for e in f.clin_1003.errors %} +
+ {{ e }} +
+ {% end %} + + {{ f.clin_2001.label }} + {{ f.clin_2001(placeholder="30,000") }} + {% for e in f.clin_2001.errors %} +
+ {{ e }} +
+ {% end %} + + {{ f.clin_2003.label }} + {{ f.clin_2003(placeholder="7,000") }} + {% for e in f.clin_2003.errors %} +
+ {{ e }} +
+ {% end %} + {% end %} + {% block next %} + + {% end %} +
+
{% end %} - diff --git a/tests/handlers/test_financial_verification.py b/tests/handlers/test_financial_verification.py new file mode 100644 index 00000000..4ca2ce2e --- /dev/null +++ b/tests/handlers/test_financial_verification.py @@ -0,0 +1,84 @@ +import re +import pytest +import tornado +import urllib +from tests.mocks import MOCK_REQUEST, MOCK_USER, MOCK_VALID_PE_ID + + +class TestPENumberInForm: + + required_data = { + "pe_id": "123", + "task_order_id": "1234567899C0001", + "fname_co": "Contracting", + "lname_co": "Officer", + "email_co": "jane@mail.mil", + "office_co": "WHS", + "fname_cor": "Officer", + "lname_cor": "Representative", + "email_cor": "jane@mail.mil", + "office_cor": "WHS", + "funding_type": "RDTE", + "funding_type_other": "other", + "clin_0001": "50,000", + "clin_0003": "13,000", + "clin_1001": "30,000", + "clin_1003": "7,000", + "clin_2001": "30,000", + "clin_2003": "7,000", + } + + def _set_monkeypatches(self, monkeypatch): + monkeypatch.setattr( + "atst.handlers.request_financial_verification.RequestFinancialVerification.get_current_user", lambda s: MOCK_USER + ) + monkeypatch.setattr( + "atst.handlers.request_financial_verification.RequestFinancialVerification.check_xsrf_cookie", lambda s: True + ) + monkeypatch.setattr("atst.forms.request.RequestForm.validate", lambda s: True) + + @tornado.gen.coroutine + def submit_data(self, http_client, base_url, data): + response = yield http_client.fetch( + base_url + "/requests/verify/{}".format(MOCK_REQUEST["id"]), + method="POST", + headers={"Content-Type": "application/x-www-form-urlencoded"}, + body=urllib.parse.urlencode(data), + follow_redirects=False, + raise_error=False, + ) + return response + + @pytest.mark.gen_test + def test_submit_request_form_with_invalid_pe_id(self, monkeypatch, http_client, base_url): + self._set_monkeypatches(monkeypatch) + + response = yield self.submit_data(http_client, base_url, self.required_data) + + assert "We couldn\'t find that PE number" in response.body.decode() + assert response.code == 200 + assert "/requests/verify" in response.effective_url + + @pytest.mark.gen_test + def test_submit_request_form_with_unchanged_pe_id(self, monkeypatch, http_client, base_url): + self._set_monkeypatches(monkeypatch) + + data = dict(self.required_data) + data['pe_id'] = MOCK_REQUEST['body']['financial_verification']['pe_id'] + + response = yield self.submit_data(http_client, base_url, data) + + assert response.code == 302 + assert response.headers.get("Location") == "/requests" + + @pytest.mark.gen_test + def test_submit_request_form_with_new_valid_pe_id(self, monkeypatch, http_client, base_url): + self._set_monkeypatches(monkeypatch) + + data = dict(self.required_data) + data['pe_id'] = MOCK_VALID_PE_ID + + response = yield self.submit_data(http_client, base_url, data) + + assert response.code == 302 + assert response.headers.get("Location") == "/requests" diff --git a/tests/handlers/test_request_new.py b/tests/handlers/test_request_new.py index 6a8a37f6..fc09cb3e 100644 --- a/tests/handlers/test_request_new.py +++ b/tests/handlers/test_request_new.py @@ -2,16 +2,9 @@ import re import pytest import tornado import urllib -from tests.mocks import MOCK_REQUEST, MOCK_VALID_PE_ID +from tests.mocks import MOCK_USER ERROR_CLASS = "usa-input-error-message" -MOCK_USER = { - "id": "9cb348f0-8102-4962-88c4-dac8180c904c", - "email": "fake.user@mail.com", - "first_name": "Fake", - "last_name": "User", -} - @pytest.mark.gen_test def test_submit_invalid_request_form(monkeypatch, http_client, base_url): @@ -50,82 +43,3 @@ def test_submit_valid_request_form(monkeypatch, http_client, base_url): body="meaning=42", ) assert "/requests/new/2" in response.effective_url - - -class TestPENumberInForm: - - required_data = { - "pe_id": "123", - "task_order_id": "1234567899C0001", - "fname_co": "Contracting", - "lname_co": "Officer", - "email_co": "jane@mail.mil", - "office_co": "WHS", - "fname_cor": "Officer", - "lname_cor": "Representative", - "email_cor": "jane@mail.mil", - "office_cor": "WHS", - "funding_type": "RDTE", - "funding_type_other": "other", - "clin_0001": "50,000", - "clin_0003": "13,000", - "clin_1001": "30,000", - "clin_1003": "7,000", - "clin_2001": "30,000", - "clin_2003": "7,000", - } - - def _set_monkeypatches(self, monkeypatch): - monkeypatch.setattr( - "atst.handlers.request_new.RequestNew.get_current_user", lambda s: MOCK_USER - ) - monkeypatch.setattr( - "atst.handlers.request_new.RequestNew.check_xsrf_cookie", lambda s: True - ) - monkeypatch.setattr("atst.forms.request.RequestForm.validate", lambda s: True) - - @tornado.gen.coroutine - def submit_data(self, http_client, base_url, data): - response = yield http_client.fetch( - base_url + "/requests/new/5/{}".format(MOCK_REQUEST["id"]), - method="POST", - headers={"Content-Type": "application/x-www-form-urlencoded"}, - body=urllib.parse.urlencode(data), - follow_redirects=False, - raise_error=False, - ) - return response - - @pytest.mark.gen_test - def test_submit_request_form_with_invalid_pe_id(self, monkeypatch, http_client, base_url): - self._set_monkeypatches(monkeypatch) - - response = yield self.submit_data(http_client, base_url, self.required_data) - - assert "We couldn\'t find that PE number" in response.body.decode() - assert response.code == 200 - assert "/requests/new/5" in response.effective_url - - @pytest.mark.gen_test - def test_submit_request_form_with_unchanged_pe_id(self, monkeypatch, http_client, base_url): - self._set_monkeypatches(monkeypatch) - - data = dict(self.required_data) - data['pe_id'] = MOCK_REQUEST['body']['financial_verification']['pe_id'] - - response = yield self.submit_data(http_client, base_url, data) - - assert response.code == 302 - assert response.headers.get("Location") == "/requests" - - @pytest.mark.gen_test - def test_submit_request_form_with_new_valid_pe_id(self, monkeypatch, http_client, base_url): - self._set_monkeypatches(monkeypatch) - - data = dict(self.required_data) - data['pe_id'] = MOCK_VALID_PE_ID - - response = yield self.submit_data(http_client, base_url, data) - - assert response.code == 302 - assert response.headers.get("Location") == "/requests" diff --git a/tests/mocks.py b/tests/mocks.py index 6cd3540c..a7290a03 100644 --- a/tests/mocks.py +++ b/tests/mocks.py @@ -4,6 +4,14 @@ from tornado.httpclient import HTTPRequest, HTTPResponse from atst.api_client import ApiClient +MOCK_USER = { + "id": "9cb348f0-8102-4962-88c4-dac8180c904c", + "email": "fake.user@mail.com", + "first_name": "Fake", + "last_name": "User", +} + + class MockApiClient(ApiClient): def __init__(self, service):