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
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,57 +18,60 @@ 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)
if form.validate():
response = yield self.create_or_update_request(
form_section, form.data, request_id
post_data = self.request.arguments
jedi_flow = JEDIRequestFlow(
self.requests_client, screen, post_data=post_data, request_id=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,
)
@ -109,16 +83,119 @@ 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
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
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

@ -29,12 +29,6 @@
<label>What organizations are supported by these applications?</label>
<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>
<label>Total Number of vCPU cores</label>

View File

@ -7,6 +7,7 @@
<ul>
{% for i,s in enumerate(screens) %}
{% if s["show"] %}
<li>
{% if i+1==current %}
<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) }}">
@ -27,5 +28,6 @@
{% end %}
</li>
{% end %}
{% end %}
</ul>
</div>