Merge branch 'master' into request_form_styles

This commit is contained in:
luisgov
2018-07-17 14:46:42 -04:00
committed by GitHub
37 changed files with 716 additions and 286 deletions

View File

@@ -4,12 +4,13 @@ import tornado.web
from tornado.web import url
from redis import StrictRedis
from atst.handlers.main import MainHandler
from atst.handlers.home import Home
from atst.handlers.login import Login
from atst.handlers.main import Main
from atst.handlers.root import Root
from atst.handlers.login_redirect import LoginRedirect
from atst.handlers.workspace import Workspace
from atst.handlers.request import Request
from atst.handlers.request_new import RequestNew
from atst.handlers.request_submit import RequestsSubmit
from atst.handlers.dev import Dev
from atst.home import home
from atst.api_client import ApiClient
@@ -21,23 +22,23 @@ ENV = os.getenv("TORNADO_ENV", "dev")
def make_app(config, deps, **kwargs):
routes = [
url(r"/", Home, {"page": "login"}, name="main"),
url(r"/", Root, {"page": "root"}, name="root"),
url(
r"/login",
Login,
r"/login-redirect",
LoginRedirect,
{"sessions": deps["sessions"], "authnid_client": deps["authnid_client"]},
name="login",
name="login_redirect",
),
url(r"/home", MainHandler, {"page": "home"}, name="home"),
url(r"/home", Main, {"page": "home"}, name="home"),
url(
r"/styleguide",
MainHandler,
Main,
{"page": "styleguide"},
name="styleguide",
),
url(
r"/workspaces/blank",
MainHandler,
Main,
{"page": "workspaces_blank"},
name="workspaces_blank",
),
@@ -71,9 +72,15 @@ def make_app(config, deps, **kwargs):
{"page": "requests_new", "requests_client": deps["requests_client"]},
name="request_form_update",
),
url(r"/users", MainHandler, {"page": "users"}, name="users"),
url(r"/reports", MainHandler, {"page": "reports"}, name="reports"),
url(r"/calculator", MainHandler, {"page": "calculator"}, name="calculator"),
url(
r"/requests/submit/(\S+)",
RequestsSubmit,
{"requests_client": deps["requests_client"]},
name="requests_submit",
),
url(r"/users", Main, {"page": "users"}, name="users"),
url(r"/reports", Main, {"page": "reports"}, name="reports"),
url(r"/calculator", Main, {"page": "calculator"}, name="calculator"),
]
if not ENV == "production":

View File

@@ -15,10 +15,14 @@ class FinancialForm(Form):
"Unique Item Identifier (UII)s related to your application(s) if you already have them."
)
pe_id = NewlineListField(
"Program Element (PE) Numbers related to your request"
pe_id = StringField(
"Program Element (PE) Number related to your request"
)
treasury_code = StringField("Please provide your Program Treasury Code")
ba_code = StringField("Please provide your Program BA Code")
fname_co = StringField("Contracting Officer First Name", validators=[Required()])
lname_co = StringField("Contracting Officer Last Name", validators=[Required()])

View File

@@ -2,7 +2,7 @@ from wtforms.fields.html5 import IntegerField
from wtforms.fields import RadioField, StringField, TextAreaField
from wtforms.validators import NumberRange, InputRequired
from wtforms_tornado import Form
from .fields import DateField, NewlineListField
from .fields import DateField
from .validators import DateRange
import pendulum

View File

@@ -23,6 +23,7 @@ class BaseHandler(tornado.web.RequestHandler):
try:
session = self.application.sessions.get_session(cookie)
except SessionNotFoundError:
self.clear_cookie("atat")
return None
else:
return None

View File

@@ -2,7 +2,7 @@ import tornado
from atst.handler import BaseHandler
class Login(BaseHandler):
class LoginRedirect(BaseHandler):
def initialize(self, authnid_client, sessions):
self.authnid_client = authnid_client
self.sessions = sessions

View File

@@ -2,7 +2,7 @@ import tornado
from atst.handler import BaseHandler
class MainHandler(BaseHandler):
class Main(BaseHandler):
def initialize(self, page):
self.page = page

View File

@@ -1,43 +1,15 @@
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
import tornado.httputil
class RequestNew(BaseHandler):
screens = [
{
"title": "Details of Use",
"section": "details_of_use",
"form": RequestForm,
"subitems": [
{"title": "Overall request details", "id": "overall-request-details"},
{"title": "Cloud Resources", "id": "cloud-resources"},
{"title": "Support Staff", "id": "support-staff"},
],
},
{
"title": "Information About You",
"section": "information_about_you",
"form": OrgForm,
},
{
"title": "Primary Point of Contact",
"section": "primary_poc",
"form": POCForm,
},
{"title": "Review & Submit", "section": "review_submit", "form": ReviewForm},
{
"title": "Financial Verification",
"section": "financial_verification",
"form": FinancialForm,
},
]
def initialize(self, page, requests_client):
self.page = page
self.requests_client = requests_client
@@ -47,58 +19,62 @@ class RequestNew(BaseHandler):
def post(self, screen=1, request_id=None):
self.check_xsrf_cookie()
screen = int(screen)
form_metadata = self.screens[screen - 1]
form_section = form_metadata["section"]
form = form_metadata["form"](self.request.arguments)
post_data = self.request.arguments
jedi_flow = JEDIRequestFlow(
self.requests_client, screen, post_data=post_data, request_id=request_id
)
if form.validate():
response = yield self.create_or_update_request(
form_section, form.data, request_id
)
if jedi_flow.validate():
response = yield jedi_flow.create_or_update_request(self.get_current_user())
if response.ok:
where = self.application.default_router.reverse_url(
"request_form_update",
str(screen + 1),
request_id or response.json["id"],
"request_form_update", str(screen + 1), jedi_flow.request_id
)
self.redirect(where)
else:
self.set_status(response.code)
else:
self.show_form(screen, form)
self.render(
"requests/screen-%d.html.to" % int(screen),
f=jedi_flow.form,
data=post_data,
page=self.page,
screens=jedi_flow.screens,
current=screen,
next_screen=jedi_flow.next_screen,
request_id=jedi_flow.request_id,
)
@tornado.web.authenticated
@tornado.gen.coroutine
def get(self, screen=1, request_id=None):
form = None
form_data = None
is_review_section = screen == 4
screen = int(screen)
request = None
if request_id:
request = yield self.get_request(request_id)
if request.ok:
if is_review_section:
form_data = request.json["body"]
else:
form_metadata = self.screens[int(screen) - 1]
section = form_metadata["section"]
form_data = request.json["body"].get(section, request.json["body"])
form = form_metadata["form"](data=form_data)
response = yield self.requests_client.get(
"/users/{}/requests/{}".format(
self.get_current_user()["id"], request_id
),
raise_error=False,
)
if response.ok:
request = response.json
self.show_form(screen=screen, form=form, request_id=request_id, data=form_data)
jedi_flow = JEDIRequestFlow(
self.requests_client, screen, request, request_id=request_id
)
def show_form(self, screen=1, form=None, request_id=None, data=None):
if not form:
form = self.screens[int(screen) - 1]["form"](self.request.arguments)
self.render(
"requests/screen-%d.html.to" % int(screen),
f=form,
data=data,
f=jedi_flow.form,
data=jedi_flow.current_step_data,
page=self.page,
screens=self.screens,
current=int(screen),
next_screen=int(screen) + 1,
screens=jedi_flow.screens,
current=screen,
next_screen=screen + 1,
request_id=request_id,
can_submit=jedi_flow.can_submit
)
@tornado.gen.coroutine
@@ -109,16 +85,128 @@ class RequestNew(BaseHandler):
)
return request
class JEDIRequestFlow(object):
def __init__(
self,
requests_client,
current_step,
request=None,
post_data=None,
request_id=None,
):
self.requests_client = requests_client
self.current_step = current_step
self.request = request
self.post_data = post_data
self.is_post = self.post_data is not None
self.request_id = request_id
self.form = self._form()
def _form(self):
if self.is_post:
return self.form_class()(self.post_data)
elif self.request:
return self.form_class()(data=self.current_step_data)
else:
return self.form_class()()
def validate(self):
return self.form.validate()
@property
def current_screen(self):
return self.screens[self.current_step - 1]
@property
def form_section(self):
return self.current_screen["section"]
def form_class(self):
return self.current_screen["form"]
@property
def current_step_data(self):
data = {}
if self.is_post:
data = self.post_data
if self.request:
if self.form_section == "review_submit":
data = self.request["body"]
else:
data = self.request["body"].get(self.form_section, {})
return defaultdict(lambda: defaultdict(lambda: 'Input required'), data)
@property
def can_submit(self):
return self.request and self.request["status"] != "incomplete"
@property
def next_screen(self):
return self.current_step + 1
@property
def screens(self):
return [
{
"title": "Details of Use",
"section": "details_of_use",
"form": RequestForm,
"subitems": [
{
"title": "Overall request details",
"id": "overall-request-details",
},
{"title": "Cloud Resources", "id": "cloud-resources"},
{"title": "Support Staff", "id": "support-staff"},
],
"show": True,
},
{
"title": "Information About You",
"section": "information_about_you",
"form": OrgForm,
"show": True,
},
{
"title": "Primary Point of Contact",
"section": "primary_poc",
"form": POCForm,
"show": True,
},
{
"title": "Review & Submit",
"section": "review_submit",
"form": ReviewForm,
"show":True,
},
{
"title": "Financial Verification",
"section": "financial_verification",
"form": FinancialForm,
"show": self.request and self.request["status"] == "approved",
},
]
@tornado.gen.coroutine
def create_or_update_request(self, form_section, form_data, request_id=None):
def create_or_update_request(self, user):
request_data = {
"creator_id": self.get_current_user()["id"],
"request": {form_section: form_data},
"creator_id": user["id"],
"request": {self.form_section: self.form.data},
}
if request_id:
if self.request_id:
response = yield self.requests_client.patch(
"/requests/{}".format(request_id), json=request_data
"/requests/{}".format(self.request_id), json=request_data
)
else:
response = yield self.requests_client.post("/requests", json=request_data)
self.request = response.json
self.request_id = self.request["id"]
return response

View File

@@ -0,0 +1,17 @@
import tornado
from atst.handler import BaseHandler
class RequestsSubmit(BaseHandler):
def initialize(self, requests_client):
self.requests_client = requests_client
@tornado.web.authenticated
@tornado.gen.coroutine
def post(self, request_id):
yield self.requests_client.post(
"/requests/{}/submit".format(request_id),
allow_nonstandard_methods=True
)
self.redirect("/requests")

View File

@@ -1,7 +1,7 @@
from atst.handler import BaseHandler
class Home(BaseHandler):
class Root(BaseHandler):
def initialize(self, page):
self.page = page