Refactor JEDI request form logic into new class

This commit is contained in:
richard-dds 2018-07-08 14:30:49 -04:00
parent d630e047a0
commit 7dadff7481
3 changed files with 164 additions and 91 deletions

View File

@ -1,43 +1,14 @@
import tornado import tornado
from atst.handler import BaseHandler from atst.handler import BaseHandler
from atst.forms.request import RequestForm from atst.forms.request import RequestForm
from atst.forms.org import OrgForm from atst.forms.org import OrgForm
from atst.forms.poc import POCForm from atst.forms.poc import POCForm
from atst.forms.review import ReviewForm from atst.forms.review import ReviewForm
from atst.forms.financial import FinancialForm from atst.forms.financial import FinancialForm
import tornado.httputil
class RequestNew(BaseHandler): 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): def initialize(self, page, requests_client):
self.page = page self.page = page
self.requests_client = requests_client self.requests_client = requests_client
@ -47,57 +18,60 @@ class RequestNew(BaseHandler):
def post(self, screen=1, request_id=None): def post(self, screen=1, request_id=None):
self.check_xsrf_cookie() self.check_xsrf_cookie()
screen = int(screen) screen = int(screen)
form_metadata = self.screens[screen - 1] post_data = self.request.arguments
form_section = form_metadata["section"] jedi_flow = JEDIRequestFlow(
form = form_metadata["form"](self.request.arguments) self.requests_client, screen, post_data=post_data, request_id=request_id
)
if form.validate(): if jedi_flow.validate():
response = yield self.create_or_update_request( response = yield jedi_flow.create_or_update_request(self.get_current_user())
form_section, form.data, request_id
)
if response.ok: if response.ok:
where = self.application.default_router.reverse_url( where = self.application.default_router.reverse_url(
"request_form_update", "request_form_update", str(screen + 1), jedi_flow.request_id
str(screen + 1),
request_id or response.json["id"],
) )
self.redirect(where) self.redirect(where)
else: else:
self.set_status(response.code) self.set_status(response.code)
else: 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.web.authenticated
@tornado.gen.coroutine @tornado.gen.coroutine
def get(self, screen=1, request_id=None): def get(self, screen=1, request_id=None):
form = None screen = int(screen)
form_data = None request = None
is_review_section = screen == 4
if request_id: if request_id:
request = yield self.get_request(request_id) response = yield self.requests_client.get(
if request.ok: "/users/{}/requests/{}".format(
if is_review_section: self.get_current_user()["id"], request_id
form_data = request.json["body"] ),
else: raise_error=False,
form_metadata = self.screens[int(screen) - 1] )
section = form_metadata["section"] if response.ok:
form_data = request.json["body"].get(section, request.json["body"]) request = response.json
form = form_metadata["form"](data=form_data)
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( self.render(
"requests/screen-%d.html.to" % int(screen), "requests/screen-%d.html.to" % int(screen),
f=form, f=jedi_flow.form(),
data=data, data=jedi_flow.current_step_data,
page=self.page, page=self.page,
screens=self.screens, screens=jedi_flow.screens,
current=int(screen), current=screen,
next_screen=int(screen) + 1, next_screen=screen + 1,
request_id=request_id, request_id=request_id,
) )
@ -109,16 +83,119 @@ class RequestNew(BaseHandler):
) )
return request 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
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):
if self.is_post:
return self.post_data
elif self.form_section == "review_submit":
return self.request["body"]
elif self.request:
return self.request["body"].get(self.form_section, {})
else:
return {}
@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": self.request and self.request["status"] == "pending_submission",
},
{
"title": "Financial Verification",
"section": "financial_verification",
"form": FinancialForm,
"show": self.request and self.request["status"] == "approved",
},
]
@tornado.gen.coroutine @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 = { request_data = {
"creator_id": self.get_current_user()["id"], "creator_id": user["id"],
"request": {form_section: form_data}, "request": {self.form_section: self.form().data},
} }
if request_id: if self.request_id:
response = yield self.requests_client.patch( response = yield self.requests_client.patch(
"/requests/{}".format(request_id), json=request_data "/requests/{}".format(self.request_id), json=request_data
) )
else: else:
response = yield self.requests_client.post("/requests", json=request_data) response = yield self.requests_client.post("/requests", json=request_data)
self.request = response.json
self.request_id = self.request["id"]
return response return response

View File

@ -29,12 +29,6 @@
<label>What organizations are supported by these applications?</label> <label>What organizations are supported by these applications?</label>
<b>{{ data.get('details_of_use', {}).get('supported_organizations') }}</b> <b>{{ data.get('details_of_use', {}).get('supported_organizations') }}</b>
<label>Please enter the Unique Item Identifier (UII)s related to your application(s) if you already have them.</label>
<b>{{ data.get('details_of_use', {}).get('uii_ids') }}</b>
<label>Please provide the Program Element (PE) Numbers related to your request</label>
<b>{{ data.get('details_of_use', {}).get('pe_id') }}</b>
<h4>Cloud Resources</h4> <h4>Cloud Resources</h4>
<label>Total Number of vCPU cores</label> <label>Total Number of vCPU cores</label>

View File

@ -7,25 +7,27 @@
<ul> <ul>
{% for i,s in enumerate(screens) %} {% for i,s in enumerate(screens) %}
<li> {% if s["show"] %}
{% if i+1==current %} <li>
<a class="sidenav__link sidenav__link--active" href="{{ reverse_url('request_form_update', i+1, request_id) if request_id else reverse_url('request_form_new',i+1) }}"> {% if i+1==current %}
{{ i+1 }}. {{ s['title'] }} <a class="sidenav__link sidenav__link--active" href="{{ reverse_url('request_form_update', i+1, request_id) if request_id else reverse_url('request_form_new',i+1) }}">
</a> {{ i+1 }}. {{ s['title'] }}
{% if s.get('subitems') %} </a>
<ul> {% if s.get('subitems') %}
{% for j,t in enumerate(s['subitems']) %} <ul>
<li><a class="sidenav__link" href="#{{ t['id'] }}">{{ t['title'] }}</a></li> {% for j,t in enumerate(s['subitems']) %}
{% end %} <li><a class="sidenav__link" href="#{{ t['id'] }}">{{ t['title'] }}</a></li>
</ul> {% end %}
{% end %} </ul>
{% end %}
{% else %} {% else %}
<a class="sidenav__link" href="{{ reverse_url('request_form_update', i+1, request_id) if request_id else reverse_url('request_form_new',i+1) }}"> <a class="sidenav__link" href="{{ reverse_url('request_form_update', i+1, request_id) if request_id else reverse_url('request_form_new',i+1) }}">
{{ i+1 }}. {{ s['title'] }} {{ i+1 }}. {{ s['title'] }}
</a> </a>
{% end %}
</li>
{% end %} {% end %}
</li>
{% end %} {% end %}
</ul> </ul>
</div> </div>