Merge pull request #535 from dod-ccpo/update-to-form-per-design-#163066434
Update to form per design - Part 1 of 2
This commit is contained in:
@@ -24,8 +24,8 @@ class TaskOrders(object):
|
||||
"team_experience",
|
||||
],
|
||||
"funding": [
|
||||
"start_date",
|
||||
"end_date",
|
||||
"performance_length",
|
||||
# "pdf",
|
||||
"clin_01",
|
||||
"clin_02",
|
||||
"clin_03",
|
||||
@@ -35,14 +35,17 @@ class TaskOrders(object):
|
||||
"ko_first_name",
|
||||
"ko_last_name",
|
||||
"ko_email",
|
||||
"ko_phone_number",
|
||||
"ko_dod_id",
|
||||
"cor_first_name",
|
||||
"cor_last_name",
|
||||
"cor_email",
|
||||
"cor_phone_number",
|
||||
"cor_dod_id",
|
||||
"so_first_name",
|
||||
"so_last_name",
|
||||
"so_email",
|
||||
"so_phone_number",
|
||||
"so_dod_id",
|
||||
],
|
||||
}
|
||||
|
@@ -176,16 +176,20 @@ FUNDING_TYPES = [
|
||||
TASK_ORDER_SOURCES = [("MANUAL", "Manual"), ("EDA", "EDA")]
|
||||
|
||||
APP_MIGRATION = [
|
||||
("on_premise", "Yes, migrating from an on-premise data center"),
|
||||
("cloud", "Yes, migrating from another cloud provider "),
|
||||
("none", "Not planning to migrate any applications "),
|
||||
("on_premise", "Yes, migrating from an <strong>on-premise data center</strong>"),
|
||||
("cloud", "Yes, migrating from <strong>another cloud provider</strong>"),
|
||||
(
|
||||
"both",
|
||||
"Yes, migrating from an <strong>on-premise data center</strong> and <strong>another cloud provider</strong>",
|
||||
),
|
||||
("none", "Not planning to migrate any applications"),
|
||||
("not_sure", "Not Sure"),
|
||||
]
|
||||
|
||||
PROJECT_COMPLEXITY = [
|
||||
("storage", "Storage "),
|
||||
("data_analytics", "Data Analytics "),
|
||||
("conus", "CONUS Only Access "),
|
||||
("conus", "CONUS Access "),
|
||||
("oconus", "OCONUS Access "),
|
||||
("tactical_edge", "Tactical Edge Access "),
|
||||
("not_sure", "Not Sure "),
|
||||
@@ -193,11 +197,10 @@ PROJECT_COMPLEXITY = [
|
||||
]
|
||||
|
||||
DEV_TEAM = [
|
||||
("government", "Government"),
|
||||
("civilians", "Civilians"),
|
||||
("government_civilians", "Government Civilians"),
|
||||
("military", "Military "),
|
||||
("contractor", "Contractor "),
|
||||
("other", "Other"),
|
||||
("other", "Other (E.g. University or other partner)"),
|
||||
]
|
||||
|
||||
TEAM_EXPERIENCE = [
|
||||
@@ -210,3 +213,30 @@ TEAM_EXPERIENCE = [
|
||||
"Built or migrated many applications, or consulted on several such projects",
|
||||
),
|
||||
]
|
||||
|
||||
PERIOD_OF_PERFORMANCE_LENGTH = [
|
||||
("1", "1 Month"),
|
||||
("2", "2 Months"),
|
||||
("3", "3 Months"),
|
||||
("4", "4 Months"),
|
||||
("5", "5 Months"),
|
||||
("6", "6 Months"),
|
||||
("7", "7 Months"),
|
||||
("8", "8 Months"),
|
||||
("9", "9 Months"),
|
||||
("10", "10 Months"),
|
||||
("11", "11 Months"),
|
||||
("12", "1 Year"),
|
||||
("13", "1 Year, 1 Month"),
|
||||
("14", "1 Year, 2 Months"),
|
||||
("15", "1 Year, 3 Months"),
|
||||
("16", "1 Year, 4 Months"),
|
||||
("17", "1 Year, 5 Months"),
|
||||
("18", "1 Year, 6 Months"),
|
||||
("19", "1 Year, 7 Months"),
|
||||
("20", "1 Year, 8 Months"),
|
||||
("21", "1 Year, 9 Months"),
|
||||
("22", "1 Year, 10 Months"),
|
||||
("23", "1 Year, 11 Months"),
|
||||
("24", "2 Years"),
|
||||
]
|
||||
|
@@ -6,12 +6,13 @@ from wtforms.fields import (
|
||||
SelectMultipleField,
|
||||
StringField,
|
||||
TextAreaField,
|
||||
FileField,
|
||||
)
|
||||
from wtforms.fields.html5 import DateField
|
||||
from wtforms.fields.html5 import DateField, TelField
|
||||
from wtforms.widgets import ListWidget, CheckboxInput
|
||||
from wtforms.validators import Required, Length
|
||||
|
||||
from atst.forms.validators import IsNumber
|
||||
from atst.forms.validators import IsNumber, PhoneNumber
|
||||
|
||||
from .forms import CacheableForm
|
||||
from .data import (
|
||||
@@ -20,70 +21,84 @@ from .data import (
|
||||
PROJECT_COMPLEXITY,
|
||||
DEV_TEAM,
|
||||
TEAM_EXPERIENCE,
|
||||
PERIOD_OF_PERFORMANCE_LENGTH,
|
||||
)
|
||||
from atst.utils.localization import translate
|
||||
|
||||
|
||||
class AppInfoForm(CacheableForm):
|
||||
portfolio_name = StringField(
|
||||
"Organization Portfolio Name",
|
||||
description="The name of your office or organization. You can add multiple applications to your portfolio. Your task orders are used to pay for these applications and their environments",
|
||||
translate("forms.task_order.portfolio_name_label"),
|
||||
description=translate("forms.task_order.portfolio_name_description"),
|
||||
)
|
||||
scope = TextAreaField(
|
||||
"Cloud Project Scope",
|
||||
description="Your team's plan for using the cloud, such as migrating an existing application or creating a prototype.",
|
||||
translate("forms.task_order.scope_label"),
|
||||
description=translate("forms.task_order.scope_description"),
|
||||
)
|
||||
defense_component = SelectField(
|
||||
"Department of Defense Component", choices=SERVICE_BRANCHES
|
||||
translate("forms.task_order.defense_component_label"), choices=SERVICE_BRANCHES
|
||||
)
|
||||
app_migration = RadioField(
|
||||
"App Migration",
|
||||
description="Do you plan to migrate existing application(s) to the cloud?",
|
||||
translate("forms.task_order.app_migration_label"),
|
||||
description=translate("forms.task_order.app_migration_description"),
|
||||
choices=APP_MIGRATION,
|
||||
default="",
|
||||
)
|
||||
native_apps = RadioField(
|
||||
"Native Apps",
|
||||
description="Do you plan to develop application(s) natively in the cloud? ",
|
||||
translate("forms.task_order.native_apps_label"),
|
||||
description=translate("forms.task_order.native_apps_description"),
|
||||
choices=[("yes", "Yes"), ("no", "No"), ("not_sure", "Not Sure")],
|
||||
)
|
||||
complexity = SelectMultipleField(
|
||||
"Project Complexity",
|
||||
description="Which of these describes how complex your team's use of the cloud will be? (Select all that apply.)",
|
||||
translate("forms.task_order.complexity_label"),
|
||||
description=translate("forms.task_order.complexity_description"),
|
||||
choices=PROJECT_COMPLEXITY,
|
||||
default="",
|
||||
widget=ListWidget(prefix_label=False),
|
||||
option_widget=CheckboxInput(),
|
||||
)
|
||||
complexity_other = StringField("Project Complexity Other")
|
||||
complexity_other = StringField(translate("forms.task_order.complexity_other_label"))
|
||||
dev_team = SelectMultipleField(
|
||||
"Development Team",
|
||||
description="Which people or teams will be completing the development work for your cloud applications?",
|
||||
translate("forms.task_order.dev_team_label"),
|
||||
description=translate("forms.task_order.dev_team_description"),
|
||||
choices=DEV_TEAM,
|
||||
default="",
|
||||
widget=ListWidget(prefix_label=False),
|
||||
option_widget=CheckboxInput(),
|
||||
)
|
||||
dev_team_other = StringField("Development Team Other")
|
||||
dev_team_other = StringField(translate("forms.task_order.dev_team_other_label"))
|
||||
team_experience = RadioField(
|
||||
"Team Experience",
|
||||
description="How much experience does your team have with development in the cloud?",
|
||||
translate("forms.task_order.team_experience_label"),
|
||||
description=translate("forms.task_order.team_experience_description"),
|
||||
choices=TEAM_EXPERIENCE,
|
||||
default="",
|
||||
)
|
||||
|
||||
|
||||
class FundingForm(CacheableForm):
|
||||
start_date = DateField("Start Date", format="%m/%d/%Y")
|
||||
end_date = DateField("End Date", format="%m/%d/%Y")
|
||||
clin_01 = IntegerField("CLIN 01 : Unclassified")
|
||||
clin_02 = IntegerField("CLIN 02: Classified")
|
||||
clin_03 = IntegerField("CLIN 03: Unclassified")
|
||||
clin_04 = IntegerField("CLIN 04: Classified")
|
||||
performance_length = SelectField(
|
||||
translate("forms.task_order.performance_length_label"),
|
||||
choices=PERIOD_OF_PERFORMANCE_LENGTH,
|
||||
)
|
||||
start_date = DateField(
|
||||
translate("forms.task_order.start_date_label"), format="%m/%d/%Y"
|
||||
)
|
||||
end_date = DateField(
|
||||
translate("forms.task_order.end_date_label"), format="%m/%d/%Y"
|
||||
)
|
||||
pdf = FileField(
|
||||
translate("forms.task_order.pdf_label"),
|
||||
description=translate("forms.task_order.pdf_description"),
|
||||
)
|
||||
clin_01 = IntegerField(translate("forms.task_order.clin_01_label"))
|
||||
clin_02 = IntegerField(translate("forms.task_order.clin_02_label"))
|
||||
clin_03 = IntegerField(translate("forms.task_order.clin_03_label"))
|
||||
clin_04 = IntegerField(translate("forms.task_order.clin_04_label"))
|
||||
|
||||
|
||||
class UnclassifiedFundingForm(FundingForm):
|
||||
clin_02 = IntegerField("CLIN 02: Classified (available soon)")
|
||||
clin_04 = IntegerField("CLIN 04: Classified (available soon)")
|
||||
clin_02 = IntegerField(translate("forms.task_order.unclassified_clin_02_label"))
|
||||
clin_04 = IntegerField(translate("forms.task_order.unclassified_clin_04_label"))
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
@@ -92,52 +107,56 @@ class UnclassifiedFundingForm(FundingForm):
|
||||
|
||||
|
||||
class OversightForm(CacheableForm):
|
||||
ko_first_name = StringField("First Name")
|
||||
ko_last_name = StringField("Last Name")
|
||||
ko_email = StringField("Email")
|
||||
ko_first_name = StringField(
|
||||
translate("forms.task_order.oversight_first_name_label")
|
||||
)
|
||||
ko_last_name = StringField(translate("forms.task_order.oversight_last_name_label"))
|
||||
ko_email = StringField(translate("forms.task_order.oversight_email_label"))
|
||||
ko_phone_number = TelField(
|
||||
translate("forms.task_order.oversight_phone_label"), validators=[PhoneNumber()]
|
||||
)
|
||||
ko_dod_id = StringField(
|
||||
"DOD ID", validators=[Required(), Length(min=10), IsNumber()]
|
||||
translate("forms.task_order.oversight_dod_id_label"),
|
||||
validators=[Required(), Length(min=10), IsNumber()],
|
||||
)
|
||||
|
||||
cor_first_name = StringField("First Name")
|
||||
cor_last_name = StringField("Last Name")
|
||||
cor_email = StringField("Email")
|
||||
cor_first_name = StringField(
|
||||
translate("forms.task_order.oversight_first_name_label")
|
||||
)
|
||||
cor_last_name = StringField(translate("forms.task_order.oversight_last_name_label"))
|
||||
cor_email = StringField(translate("forms.task_order.oversight_email_label"))
|
||||
cor_phone_number = TelField(
|
||||
translate("forms.task_order.oversight_phone_label"), validators=[PhoneNumber()]
|
||||
)
|
||||
cor_dod_id = StringField(
|
||||
"DOD ID", validators=[Required(), Length(min=10), IsNumber()]
|
||||
translate("forms.task_order.oversight_dod_id_label"),
|
||||
validators=[Required(), Length(min=10), IsNumber()],
|
||||
)
|
||||
|
||||
so_first_name = StringField("First Name")
|
||||
so_last_name = StringField("Last Name")
|
||||
so_email = StringField("Email")
|
||||
so_first_name = StringField(
|
||||
translate("forms.task_order.oversight_first_name_label")
|
||||
)
|
||||
so_last_name = StringField(translate("forms.task_order.oversight_last_name_label"))
|
||||
so_email = StringField(translate("forms.task_order.oversight_email_label"))
|
||||
so_phone_number = TelField(
|
||||
translate("forms.task_order.oversight_phone_label"), validators=[PhoneNumber()]
|
||||
)
|
||||
so_dod_id = StringField(
|
||||
"DOD ID", validators=[Required(), Length(min=10), IsNumber()]
|
||||
translate("forms.task_order.oversight_dod_id_label"),
|
||||
validators=[Required(), Length(min=10), IsNumber()],
|
||||
)
|
||||
|
||||
ko_invite = BooleanField(
|
||||
"Invite KO to Task Order Builder",
|
||||
description="""
|
||||
Your KO will need to approve funding for this Task Order by logging
|
||||
into the JEDI Cloud Portal, submitting the Task Order documents
|
||||
within their official system of record, and electronically signing.
|
||||
<i>You may choose to skip this for now and invite them later.</i>
|
||||
""",
|
||||
translate("forms.task_order.ko_invite_label"),
|
||||
description=translate("forms.task_order.skip_invite_description"),
|
||||
)
|
||||
cor_invite = BooleanField(
|
||||
"Invite COR to Task Order Builder",
|
||||
description="""
|
||||
Your COR may assist with submitting the Task Order documents within
|
||||
their official system of record. <i>You may choose to skip this for
|
||||
now and invite them later.</i>
|
||||
""",
|
||||
translate("forms.task_order.cor_invite_label"),
|
||||
description=translate("forms.task_order.skip_invite_description"),
|
||||
)
|
||||
so_invite = BooleanField(
|
||||
"Invite Security Officer to Task Order Builder",
|
||||
description="""
|
||||
Your Security Officer will need to answer some security
|
||||
configuration questions in order to generate a DD-254 document,
|
||||
then electronically sign. <i>You may choose to skip this for now
|
||||
and invite them later.</i>
|
||||
""",
|
||||
translate("forms.task_order.so_invite_label"),
|
||||
description=translate("forms.task_order.skip_invite_description"),
|
||||
)
|
||||
|
||||
|
||||
|
@@ -1,6 +1,14 @@
|
||||
from enum import Enum
|
||||
|
||||
from sqlalchemy import Column, Enum as SQLAEnum, Numeric, String, ForeignKey, Date
|
||||
from sqlalchemy import (
|
||||
Column,
|
||||
Enum as SQLAEnum,
|
||||
Numeric,
|
||||
String,
|
||||
ForeignKey,
|
||||
Date,
|
||||
Integer,
|
||||
)
|
||||
from sqlalchemy.types import ARRAY
|
||||
from sqlalchemy.orm import relationship
|
||||
|
||||
@@ -46,6 +54,9 @@ class TaskOrder(Base, mixins.TimestampsMixin):
|
||||
team_experience = Column(String) # Team Experience
|
||||
start_date = Column(Date) # Period of Performance
|
||||
end_date = Column(Date)
|
||||
performance_length = Column(Integer)
|
||||
attachment_id = Column(ForeignKey("attachments.id"))
|
||||
pdf = relationship("Attachment")
|
||||
clin_01 = Column(Numeric(scale=2))
|
||||
clin_02 = Column(Numeric(scale=2))
|
||||
clin_03 = Column(Numeric(scale=2))
|
||||
@@ -53,14 +64,17 @@ class TaskOrder(Base, mixins.TimestampsMixin):
|
||||
ko_first_name = Column(String) # First Name
|
||||
ko_last_name = Column(String) # Last Name
|
||||
ko_email = Column(String) # Email
|
||||
ko_phone_number = Column(String) # Phone Number
|
||||
ko_dod_id = Column(String) # DOD ID
|
||||
cor_first_name = Column(String) # First Name
|
||||
cor_last_name = Column(String) # Last Name
|
||||
cor_email = Column(String) # Email
|
||||
cor_phone_number = Column(String) # Phone Number
|
||||
cor_dod_id = Column(String) # DOD ID
|
||||
so_first_name = Column(String) # First Name
|
||||
so_last_name = Column(String) # Last Name
|
||||
so_email = Column(String) # Email
|
||||
so_phone_number = Column(String) # Phone Number
|
||||
so_dod_id = Column(String) # DOD ID
|
||||
number = Column(String, unique=True) # Task Order Number
|
||||
loa = Column(ARRAY(String)) # Line of Accounting (LOA)
|
||||
|
@@ -20,7 +20,7 @@ from atst.services.invitation import Invitation as InvitationService
|
||||
TASK_ORDER_SECTIONS = [
|
||||
{
|
||||
"section": "app_info",
|
||||
"title": "What You're Building",
|
||||
"title": "What You're Making",
|
||||
"template": "task_orders/new/app_info.html",
|
||||
"form": task_order_form.AppInfoForm,
|
||||
},
|
||||
@@ -166,7 +166,13 @@ class UpdateTaskOrderWorkflow(ShowTaskOrderWorkflow):
|
||||
prefix = officer_type["prefix"]
|
||||
officer_data = {
|
||||
field: getattr(self.task_order, prefix + "_" + field)
|
||||
for field in ["first_name", "last_name", "email", "dod_id"]
|
||||
for field in [
|
||||
"first_name",
|
||||
"last_name",
|
||||
"email",
|
||||
"phone_number",
|
||||
"dod_id",
|
||||
]
|
||||
}
|
||||
officer = TaskOrders.add_officer(
|
||||
self.user, self.task_order, officer_type["role"], officer_data
|
||||
|
Reference in New Issue
Block a user