Merge pull request #543 from dod-ccpo/update-to-form-part-2

Update Task Order Form - Part 2
This commit is contained in:
leigh-mil 2019-01-17 10:53:43 -05:00 committed by GitHub
commit 9af74a8a53
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
17 changed files with 402 additions and 201 deletions

View File

@ -1,6 +1,6 @@
import re
import datetime
from atst.utils.localization import translate
from atst.utils.localization import translate, translate_duration
from flask import current_app as app, render_template
from jinja2 import contextfilter
from jinja2.exceptions import TemplateNotFound
@ -97,6 +97,19 @@ def renderAuditEvent(event):
return render_template("audit_log/events/default.html", event=event)
def removeHtml(text):
html_tags = re.compile("<.*?>")
return re.sub(html_tags, "", text)
def normalizeOrder(title):
# reorders titles from "Army, Department of the" to "Department of the Army"
text = title.split(", ")
reordered_text = text[0:-1]
reordered_text.insert(0, text[-1])
return " ".join(reordered_text)
def register_filters(app):
app.jinja_env.filters["iconSvg"] = iconSvg
app.jinja_env.filters["dollars"] = dollars
@ -110,6 +123,9 @@ def register_filters(app):
app.jinja_env.filters["dateFromString"] = dateFromString
app.jinja_env.filters["pageWindow"] = pageWindow
app.jinja_env.filters["renderAuditEvent"] = renderAuditEvent
app.jinja_env.filters["removeHtml"] = removeHtml
app.jinja_env.filters["normalizeOrder"] = normalizeOrder
app.jinja_env.filters["translateDuration"] = translate_duration
@contextfilter
def translateWithoutCache(context, *kwargs):

View File

@ -1,4 +1,6 @@
from atst.domain.roles import PORTFOLIO_ROLES as PORTFOLIO_ROLE_DEFINITIONS
from atst.utils.localization import translate, translate_duration
SERVICE_BRANCHES = [
("", "Select an option"),
@ -176,67 +178,41 @@ FUNDING_TYPES = [
TASK_ORDER_SOURCES = [("MANUAL", "Manual"), ("EDA", "EDA")]
APP_MIGRATION = [
("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"),
("on_premise", translate("forms.task_order.app_migration.on_premise")),
("cloud", translate("forms.task_order.app_migration.cloud")),
("both", translate("forms.task_order.app_migration.both")),
("none", translate("forms.task_order.app_migration.none")),
("not_sure", translate("forms.task_order.app_migration.not_sure")),
]
APPLICATION_COMPLEXITY = [
("storage", "Storage "),
("data_analytics", "Data Analytics "),
("conus", "CONUS Access "),
("oconus", "OCONUS Access "),
("tactical_edge", "Tactical Edge Access "),
("not_sure", "Not Sure "),
("other", "Other"),
("storage", translate("forms.task_order.complexity.storage")),
("data_analytics", translate("forms.task_order.complexity.data_analytics")),
("conus", translate("forms.task_order.complexity.conus")),
("oconus", translate("forms.task_order.complexity.oconus")),
("tactical_edge", translate("forms.task_order.complexity.tactical_edge")),
("not_sure", translate("forms.task_order.complexity.not_sure")),
("other", translate("forms.task_order.complexity.other")),
]
DEV_TEAM = [
("government_civilians", "Government Civilians"),
("military", "Military "),
("contractor", "Contractor "),
("other", "Other (E.g. University or other partner)"),
(
"government_civilians",
translate("forms.task_order.dev_team.government_civilians"),
),
("military", translate("forms.task_order.dev_team.military")),
("contractor", translate("forms.task_order.dev_team.contractor")),
("other", translate("forms.task_order.dev_team.other")),
]
TEAM_EXPERIENCE = [
("none", "No previous experience"),
("planned", "Researched or planned a cloud build or migration"),
("built_1", "Built or Migrated 1-2 applications"),
("built_3", "Built or Migrated 3-5 applications"),
(
"built_many",
"Built or migrated many applications, or consulted on several such applications",
),
("none", translate("forms.task_order.team_experience.none")),
("planned", translate("forms.task_order.team_experience.planned")),
("built_1", translate("forms.task_order.team_experience.built_1")),
("built_3", translate("forms.task_order.team_experience.built_3")),
("built_many", translate("forms.task_order.team_experience.built_many")),
]
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"),
(str(x + 1), translate_duration(x + 1)) for x in range(24)
]

View File

@ -39,8 +39,8 @@ class AppInfoForm(CacheableForm):
translate("forms.task_order.defense_component_label"), choices=SERVICE_BRANCHES
)
app_migration = RadioField(
translate("forms.task_order.app_migration_label"),
description=translate("forms.task_order.app_migration_description"),
translate("forms.task_order.app_migration.label"),
description=translate("forms.task_order.app_migration.description"),
choices=APP_MIGRATION,
default="",
)
@ -50,8 +50,8 @@ class AppInfoForm(CacheableForm):
choices=[("yes", "Yes"), ("no", "No"), ("not_sure", "Not Sure")],
)
complexity = SelectMultipleField(
translate("forms.task_order.complexity_label"),
description=translate("forms.task_order.complexity_description"),
translate("forms.task_order.complexity.label"),
description=translate("forms.task_order.complexity.description"),
choices=APPLICATION_COMPLEXITY,
default="",
widget=ListWidget(prefix_label=False),
@ -59,8 +59,8 @@ class AppInfoForm(CacheableForm):
)
complexity_other = StringField(translate("forms.task_order.complexity_other_label"))
dev_team = SelectMultipleField(
translate("forms.task_order.dev_team_label"),
description=translate("forms.task_order.dev_team_description"),
translate("forms.task_order.dev_team.label"),
description=translate("forms.task_order.dev_team.description"),
choices=DEV_TEAM,
default="",
widget=ListWidget(prefix_label=False),
@ -68,8 +68,8 @@ class AppInfoForm(CacheableForm):
)
dev_team_other = StringField(translate("forms.task_order.dev_team_other_label"))
team_experience = RadioField(
translate("forms.task_order.team_experience_label"),
description=translate("forms.task_order.team_experience_description"),
translate("forms.task_order.team_experience.label"),
description=translate("forms.task_order.team_experience.description"),
choices=TEAM_EXPERIENCE,
default="",
)
@ -77,7 +77,7 @@ class AppInfoForm(CacheableForm):
class FundingForm(CacheableForm):
performance_length = SelectField(
translate("forms.task_order.performance_length_label"),
translate("forms.task_order.performance_length.label"),
choices=PERIOD_OF_PERFORMANCE_LENGTH,
)
start_date = DateField(

View File

@ -1,6 +1,8 @@
import yaml
import os
from functools import lru_cache
import math
from gettext import ngettext
from flask import current_app as app
from atst.utils import getattr_path
@ -41,3 +43,14 @@ def translate(key, variables=None):
raise LocalizationInvalidKeyError(key, variables)
return value.format(**variables).replace("\n", "")
def translate_duration(duration_in_months):
duration = []
years = math.floor(duration_in_months / 12)
months = duration_in_months % 12
if years > 0:
duration.append("{} {}".format(years, ngettext("year", "years", years)))
if months > 0:
duration.append("{} {}".format(months, ngettext("month", "months", months)))
return (", ").join(duration)

View File

@ -38,6 +38,7 @@
@import 'components/budget_chart';
@import 'components/audit_log';
@import 'components/usa_banner';
@import 'components/checklist';
@import 'sections/login';
@import 'sections/home';

View File

@ -0,0 +1,9 @@
.checklist {
padding-left: 0;
list-style: none;
margin-top: 5px;
li {
margin-bottom: 0;
}
}

View File

@ -68,4 +68,8 @@
opacity: 0.3;
pointer-events: none;
}
&.icon-link--left {
padding-left: 0;
}
}

View File

@ -55,7 +55,19 @@
@include icon-size(24);
}
&.icon--remove {
&.icon--remove, &.icon--red {
@include icon-color($color-red);
}
&.icon--green {
@include icon-color($color-green);
}
&.icon--gray {
@include icon-color($color-gray);
}
&.icon--medium {
@include icon-size(12);
}
}

View File

@ -179,3 +179,40 @@
}
}
}
.task-order-form {
.task-order-form__heading {
margin-bottom: 0;
&.inactive {
color: $color-gray-light;
}
&.subheading {
color: $color-gray;
}
}
.funding-summary__table {
tr td {
border-bottom: 0;
padding: 0.5rem 1.5rem;
.funding-summary__td {
margin-top: 0;
}
}
}
.task-order-invite-message {
&.not-sent {
color: $color-red;
font-weight: $font-bold;
}
&.sent {
color: $color-green;
font-weight: $font-bold;
}
}
}

View File

@ -33,10 +33,10 @@
<li>
{% if choice[0] != 'other' %}
<input type='checkbox' name='{{ field.name }}' id='{{ field.name }}-{{ loop.index0 }}' value='{{ choice[0] }}' v-model="selections"/>
<label for='{{ field.name }}-{{ loop.index0 }}'>{{ choice[1] }}</label>
<label for='{{ field.name }}-{{ loop.index0 }}'>{{ choice[1] | safe }}</label>
{% else %}
<input @click="otherToggle" type='checkbox' name='{{ field.name }}' id='{{ field.name }}-{{ loop.index0 }}' value='other' v-model="selections"/>
<label for='{{ field.name }}-{{ loop.index0 }}'>{{ choice[1] }}</label>
<label for='{{ field.name }}-{{ loop.index0 }}'>{{ choice[1] | safe }}</label>
<div v-show="otherChecked">
<input type='text' name='{{ other_input_field.name}}' id='{{ field.name }}-other' v-model:value="otherText" aria-expanded='false' />

View File

@ -2,7 +2,7 @@
{% block content %}
<div class="col">
<div class="col task-order-form">
{% include 'task_orders/new/menu.html' %}
@ -19,8 +19,10 @@
<div class="panel">
<div class="panel__heading">
<div class="subtitle h2">Task Order Builder</div>
<h1>{% block heading %}{% endblock %}</h1>
<h1 class="task-order-form__heading subheading">
<div class="h2">Task Order Builder</div>
{% block heading %}{% endblock %}
</h1>
</div>
<div class="panel__content">

View File

@ -12,7 +12,7 @@
{% block form %}
<!-- App Info Section -->
<h3>{{ "task_orders.new.app_info.basic_info_title"| translate }}</h3>
<h3 class="task-order-form__heading subheading">{{ "task_orders.new.app_info.basic_info_title"| translate }}</h3>
{{ TextInput(form.portfolio_name, placeholder="The name of your office or organization") }}
{{ TextInput(form.scope, paragraph=True) }}
<p><i>{{ "task_orders.new.app_info.sample_scope" | translate | safe }}</i></p>
@ -20,20 +20,20 @@
<hr>
<h3>{{ "task_orders.new.app_info.project_title" | translate }}</h3>
<h3 id="reporting" class="subheading">{{ "task_orders.new.app_info.project_title" | translate }}</h3>
{{ OptionsInput(form.app_migration) }}
{{ OptionsInput(form.native_apps) }}
{{ MultiCheckboxInput(form.complexity, form.complexity_other) }}
<hr>
<h3>{{ "task_orders.new.app_info.team_title" | translate }}</h3>
<h3 class="subheading">{{ "task_orders.new.app_info.team_title" | translate }}</h3>
{{ MultiCheckboxInput(form.dev_team, form.dev_team_other) }}
{{ OptionsInput(form.team_experience) }}
<hr>
<h3>{{ "task_orders.new.app_info.market_research_title" | translate }}</h3>
<h3 class="subheading">{{ "task_orders.new.app_info.market_research_title" | translate }}</h3>
<p>{{ "task_orders.new.app_info.market_research_paragraph" | translate | safe }}</p>
{% endblock %}

View File

@ -15,14 +15,14 @@
<funding inline-template v-bind:initial-data='{{ form.data|tojson }}'>
<div>
<!-- Get Funding Section -->
<h3>{{ "task_orders.new.funding.performance_period_title" | translate }}</h3>
<h3 class="subheading">{{ "task_orders.new.funding.performance_period_title" | translate }}</h3>
<p>{{ "task_orders.new.funding.performance_period_description" | translate }}</p>
<p>{{ "task_orders.new.funding.performance_period_paragraph" | translate }}</p>
{{ OptionsInput(form.performance_length) }}
<hr>
<h3>{{ "task_orders.new.funding.estimate_usage_title" | translate }}</h3>
<h3 class="subheading">{{ "task_orders.new.funding.estimate_usage_title" | translate }}</h3>
<p>{{ "task_orders.new.funding.estimate_usage_description" | translate }}</p>
<p><a class="icon-link" href="{{ url_for('atst.jedi_csp_calculator') }}">
{{ Icon("link")}} Cloud Service Provider's estimate calculator
@ -36,15 +36,15 @@
<hr>
<h3>{{ "task_orders.new.funding.cloud_calculations_title" | translate }}</h3>
<h3 class="subheading">{{ "task_orders.new.funding.cloud_calculations_title" | translate }}</h3>
<p>{{ "task_orders.new.funding.cloud_calculations_paragraph" | translate }}</p>
<h4>{{ "task_orders.new.funding.cloud_offerings_title" | translate }}</h4>
<h4 class="task-order-form__heading">{{ "task_orders.new.funding.cloud_offerings_title" | translate }}</h4>
<p>{{ "task_orders.new.funding.cloud_offerings_paragraph" | translate }}</p>
{{ TextInput(form.clin_01, validation='dollars', placeholder="$0.00") }}
{{ TextInput(form.clin_02, validation='dollars', disabled=(not config.CLASSIFIED)) }}
<h4>{{ "task_orders.new.funding.support_assistance_title" | translate }}</h4>
<h4 class="task-order-form__heading">{{ "task_orders.new.funding.support_assistance_title" | translate }}</h4>
<p>{{ "task_orders.new.funding.support_assistance_paragraph" | translate }}</p>
{{ TextInput(form.clin_03, validation='dollars', tooltip='The cloud support and assistance packages cannot be used as a primary development resource.', placeholder="$0.00") }}
{{ TextInput(form.clin_04, validation='dollars', tooltip='The cloud support and assistance packages cannot be used as a primary development resource.', disabled=(not config.CLASSIFIED)) }}
@ -56,7 +56,7 @@
{% block next %}
<div class="row">
<div class="col col--grow">
<p>{{ "task_orders.new.funding.total" | translate }}<br><span id="to-target"></span></p>
<p><strong><span class="task-order-form__heading subheading">{{ "task_orders.new.funding.total" | translate }}</span><br><span id="to-target"></span></strong></p>
</div>
<div class="col col--grow">
{{ super() }}

View File

@ -11,7 +11,7 @@
{% block form %}
<!-- Oversight Section -->
<h3>{{ "task_orders.new.oversight.ko_info_title" | translate }}</h3>
<h3 class="subheading">{{ "task_orders.new.oversight.ko_info_title" | translate }}</h3>
<p>{{ "task_orders.new.oversight.ko_info_paragraph" | translate }}</p>
{{ UserInfo(form.ko_first_name, form.ko_last_name, form.ko_email, form.ko_phone_number) }}
{{ CheckboxInput(form.ko_invite) }}
@ -19,7 +19,7 @@
<hr />
<h3>{{ "task_orders.new.oversight.cor_info_title" | translate }}</h3>
<h3 class="subheading">{{ "task_orders.new.oversight.cor_info_title" | translate }}</h3>
<p>{{ "task_orders.new.oversight.cor_info_paragraph" | translate }}</p>
<div class='usa-input'>
<fieldset class="usa-input__choices">
@ -35,7 +35,7 @@
<hr />
<h3>{{ "task_orders.new.oversight.so_info_title" | translate }}</h3>
<h3 class="subheading">{{ "task_orders.new.oversight.so_info_title" | translate }}</h3>
<p>{{ "task_orders.new.oversight.so_info_paragraph" | translate }}</p>
{{ UserInfo(form.so_first_name, form.so_last_name, form.so_email, form.so_phone_number) }}
{{ CheckboxInput(form.so_invite) }}

View File

@ -5,145 +5,219 @@
{% from "components/icon.html" import Icon %}
{% block heading %}
Review & Download
{{ "task_orders.new.review.section_title"| translate }}
{% endblock %}
{% block form %}
{% macro TOEditLink(screen=1) %}
{% macro TOEditLink(screen=1, anchor=None) %}
{% if task_order %}
{{ EditLink(url_for("task_orders.new", screen=screen, task_order_id=task_order.id)) }}
{{ EditLink(url_for("task_orders.new", screen=screen, task_order_id=task_order.id, _anchor=anchor)) }}
{% else %}
{{ EditLink(url_for("task_orders.new", screen=screen)) }}
{{ EditLink(url_for("task_orders.new", screen=screen, _anchor=anchor)) }}
{% endif %}
{% endmacro %}
<section>
<h3>Scope (Statement of Work) {{ TOEditLink() }}</h3>
<p>
{{ task_order.scope or RequiredLabel() }}
</p>
{% if task_order.defense_component %}
{% set defense_component_description = task_order.defense_component | normalizeOrder %}
{% endif %}
<div class="row">
<div class="col col--grow">
<h3>Period of Performance length {{ TOEditLink(screen=2) }}</h3>
{{ task_order.performance_length or RequiredLabel() }}
</div>
{% if task_order.app_migration %}
{% set app_migration_description = "forms.task_order.app_migration.{}".format(task_order.app_migration) | translate | removeHtml %}
{% endif %}
<div class="col col--grow">
<h3>Total funding requested {{ TOEditLink(screen=2) }}</h3>
{{ task_order.budget }}
</div>
{% if task_order.native_apps %}
{% set native_apps_description = "task_orders.new.review.{}_native".format(task_order.native_apps) | translate %}
{% endif %}
{% if task_order.team_experience %}
{% set team_experience_description = "forms.task_order.team_experience.{}".format(task_order.team_experience) | translate %}
{% endif %}
<h3 class="subheading">{{ "task_orders.new.review.app_info"| translate }} {{ TOEditLink(screen=1) }}</h3>
<div class="row">
<div class="col col--grow">
<h4 class='task-order-form__heading'>{{ "task_orders.new.review.portfolio"| translate }}</h4>
<p>{{ task_order.portfolio_name or RequiredLabel() }}</p>
</div>
</section>
<div class="col col--grow">
<h4 class='task-order-form__heading'>{{ "task_orders.new.review.dod"| translate }}</h4>
<p>{{ defense_component_description or RequiredLabel() }}</p>
</div>
</div>
<h4 class='task-order-form__heading'>{{ "task_orders.new.review.scope"| translate }}</h4>
<p>
{{ task_order.scope or RequiredLabel() }}
</p>
<hr>
<section>
<h2>Generated Documents</h2>
<h3 class="subheading">{{ "task_orders.new.review.reporting"| translate }} {{ TOEditLink(screen=1, anchor="reporting") }}</h3>
<ul class="usa-unstyled-list">
<div class="row">
<div class="col col--grow">
<h4 class='task-order-form__heading'>{{ "task_orders.new.review.migration"| translate }}</h4>
<p>{{ app_migration_description or RequiredLabel() }}</p>
</div>
<div class="col col--grow">
<h4 class='task-order-form__heading'>{{ "task_orders.new.review.native_apps"| translate }}</h4>
<p>{{ native_apps_description or RequiredLabel() }}</p>
</div>
</div>
<h4 class='task-order-form__heading'>{{ "task_orders.new.review.complexity"| translate }}</h4>
{% if task_order.complexity %}
<ul class="checklist">
{% for item in task_order.complexity %}
<li>
<a href="#" download>
{{ Icon('download') }}
Cover Sheet
</a>
</li>
<li>
<a href="#" download>
{{ Icon('download') }}
Market Research
</a>
</li
>
{% if task_order %}
<li>
<a href="{{ url_for('task_orders.download_summary', task_order_id=task_order.id) }}" download>
{{ Icon('download') }}
Task Order Draft
</a>
</li>
{% endif %}
<li>
<a href="#" download>
{{ Icon('download') }}
DD 254
</a>
{{ Icon('ok', classes='icon--gray icon--medium') }}{{ "forms.task_order.complexity.{}".format(item) | translate }}{% if item == 'other' %}: {{ task_order.complexity_other }}{% endif %}
</li>
{% endfor %}
</ul>
</section>
{% else %}
<p>{{ RequiredLabel() }}</p>
{% endif %}
<div class="row">
<div class="col col--grow">
<h4 class='task-order-form__heading'>{{ "task_orders.new.review.team"| translate }}</h4>
{% if task_order.dev_team %}
<ul class="checklist">
{% for item in task_order.dev_team %}
<li>
{% if item == 'other' %}
{{ Icon('ok', classes='icon--gray icon--medium') }}Other: {{ task_order.dev_team_other }}
{% else %}
{{ Icon('ok', classes='icon--gray icon--medium') }}{{ "forms.task_order.dev_team.{}".format(item) | translate }}
{% endif %}
</li>
{% endfor %}
</ul>
{% else %}
<p>{{ RequiredLabel() }}</p>
{% endif %}
</div>
<div class="col col--grow">
<h4 class='task-order-form__heading'>{{ "task_orders.new.review.experience"| translate }}</h4>
<p>{{ team_experience_description or RequiredLabel() }}</p>
</div>
</div>
<hr>
<section>
<h2>Invite Signatories/Collaborators</h2>
<h3 class="subheading">{{ "task_orders.new.review.funding"| translate }} {{ TOEditLink(screen=2) }}</h3>
<div class="form-row">
<div class="form-col">
<div class="usa-input">
<fieldset class="usa-input__choices">
<legend>Financial Oversight</legend>
<p>
{% if task_order.ko_first_name %}
{{ task_order.ko_first_name }}
{{ task_order.ko_last_name }}
{% else %}
{{ RequiredLabel() }}
{% endif %}
(Contracting Officer)
</p>
<p>
{% if task_order.ko_first_name %}
{{ task_order.cor_first_name }}
{{ task_order.cor_last_name }}
{% else %}
{{ RequiredLabel() }}
{% endif %}
(Contracting Officer Representative)
</p>
</fieldset>
</div>
</div>
<div class="form-col">
<div class="usa-input">
<fieldset class="usa-input__choices">
<legend>Invite?</legend>
</fieldset>
</div>
</div>
<div class="row">
<div class="col col--grow">
<h4 class='task-order-form__heading'>{{ "task_orders.new.review.performance_period"| translate }}</h4>
{{ task_order.performance_length | translateDuration or RequiredLabel() }}
<p><a href="#" class='icon-link icon-link--left' download>{{ Icon('download') }} {{ "task_orders.new.review.usage_est_link"| translate }}</a></p>
</div>
<div class="form-row">
<div class="form-col">
<div class="usa-input">
<fieldset class="usa-input__choices">
<legend>Security Officer</legend>
<p>
{% if task_order.so_first_name %}
{{ task_order.so_first_name }}
{{ task_order.so_last_name }}
{% else %}
{{ RequiredLabel() }}
{% endif %}
(Security Officer)
</p>
</fieldset>
</div>
</div>
<div class="form-col">
<div class="usa-input">
</div>
</div>
<div class="col col--grow">
<table class="funding-summary__table">
<tbody>
<tr>
<td><h4>{{ "task_orders.new.review.to_value"| translate }}</h4></td>
<td class="table-cell--align-right">{{ '${:,.2f}'.format(task_order.budget) }}</td>
</tr>
<tr>
<td><h4 class='task-order-form__heading funding-summary__td'>{{ "task_orders.new.review.clin_1"| translate }}</h4></td>
<td class="table-cell--align-right">{{ '${:,.2f}'.format(task_order.clin_01) }}</td>
</tr>
<tr>
<td><h4 class="task-order-form__heading funding-summary__td{% if not config.CLASSIFIED %} inactive{% endif %}">
{{ "task_orders.new.review.clin_2"| translate }}
{% if not config.CLASSIFIED %}
<div>{{ "task_orders.new.review.classified_inactive"| translate }}</div>
{% endif %}
</h4></td>
<td class="table-cell--align-right">
{% if config.CLASSIFIED %}
{{ '${:,.2f}'.format(task_order.clin_02) }}
{% endif %}
</td>
</tr>
<tr>
<td><h4 class='task-order-form__heading funding-summary__td'>{{ "task_orders.new.review.clin_3"| translate }}</h4></td>
<td class="table-cell--align-right">{{ '${:,.2f}'.format(task_order.clin_03) }}</td>
</tr>
<tr>
<td><h4 class="task-order-form__heading funding-summary__td{% if not config.CLASSIFIED %} inactive{% endif %}">
{{ "task_orders.new.review.clin_4"| translate }}
{% if not config.CLASSIFIED %}
<div>{{ "task_orders.new.review.classified_inactive"| translate }}</div>
{% endif %}
</h4></td>
<td class="table-cell--align-right">
{% if config.CLASSIFIED %}
{{ '${:,.2f}'.format(task_order.clin_04) }}
{% endif %}
</td>
<tr>
</tbody>
</table>
</div>
</section>
</div>
<hr>
<h3 class="subheading">{{ "task_orders.new.review.oversight"| translate }} {{ TOEditLink(screen=3) }}</h3>
<div class="row">
<div class="col col--grow">
<h4 class='task-order-form__heading'>{{ "task_orders.new.review.ko"| translate }}</h4>
{{ task_order.ko_first_name }} {{ task_order.ko_last_name }}<br>
{{ task_order.ko_email }}<br>
{{ task_order.ko_phone_number | usPhone }}<br>
{{ "task_orders.new.review.dod_id"| translate }} {{ task_order.ko_dod_id}}<br>
{% if task_order.ko_invite %}
{{ Icon('ok', classes='icon--green') }} <span class="task-order-invite-message sent">{{ "task_orders.new.review.invited"| translate }}</<span>
{% else %}
{{ Icon('alert', classes='icon--red') }} <span class="task-order-invite-message not-sent">{{ "task_orders.new.review.not_invited"| translate }}</span>
{% endif %}
</div>
<div class="col col--grow">
<h4 class='task-order-form__heading'>{{ "task_orders.new.review.cor"| translate }}</h4>
{{ task_order.cor_first_name }} {{ task_order.cor_last_name }}<br>
{{ task_order.cor_email }}<br>
{{ task_order.cor_phone_number | usPhone }}<br>
{{ "task_orders.new.review.dod_id"| translate }} {{ task_order.cor_dod_id}}<br>
{% if task_order.cor_invite %}
{{ Icon('ok', classes='icon--green') }} <span class="task-order-invite-message sent">{{ "task_orders.new.review.invited"| translate }}</<span>
{% else %}
{{ Icon('alert', classes='icon--red') }} <span class="task-order-invite-message not-sent">{{ "task_orders.new.review.not_invited"| translate }}</span>
{% endif %}
</div>
</div>
<div class="row">
<div class="col col--grow">
<h4 class='task-order-form__heading'>{{ "task_orders.new.review.so"| translate }}</h4>
{{ task_order.so_first_name }} {{ task_order.so_last_name }}<br>
{{ task_order.so_email }}<br>
{{ task_order.so_phone_number | usPhone }}<br>
{{ "task_orders.new.review.dod_id"| translate }} {{ task_order.so_dod_id}}<br>
{% if task_order.so_invite %}
{{ Icon('ok', classes='icon--green') }} <span class="task-order-invite-message sent">{{ "task_orders.new.review.invited"| translate }}</<span>
{% else %}
{{ Icon('alert', classes='icon--red') }} <span class="task-order-invite-message not-sent">{{ "task_orders.new.review.not_invited"| translate }}</span>
{% endif %}
</div>
</div>
{% endblock %}
{% block next %}
<div class='action-group'>
<input type='submit' class='usa-button usa-button-primary' value='Send Invitations' />
<input type='submit' class='usa-button usa-button-primary' value='Done' />
</div>
{% endblock %}

View File

@ -388,7 +388,7 @@ class TaskOrderFactory(Base):
defense_component = factory.LazyFunction(random_service_branch)
app_migration = random_choice(data.APP_MIGRATION)
native_apps = random.choices(["yes", "no", "not_sure"])
native_apps = random.choice(["yes", "no", "not_sure"])
complexity = [random_choice(data.APPLICATION_COMPLEXITY)]
dev_team = [random_choice(data.DEV_TEAM)]
team_experience = random_choice(data.TEAM_EXPERIENCE)

View File

@ -169,19 +169,45 @@ forms:
scope_label: Cloud Project Scope
scope_description: Your team's plan for using the cloud, such as migrating an existing application or creating a prototype.
defense_component_label: Department of Defense Component
app_migration_label: App Migration
app_migration_description: Do you plan to migrate existing application(s) to the cloud?
app_migration:
label: App Migration
description: Do you plan to migrate existing application(s) to the cloud?
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"
native_apps_label: Native Apps
native_apps_description: Do you plan to develop application(s) natively in the cloud?
complexity_label: Project Complexity
complexity_description: Which of these describes how complex your team's use of the cloud will be? Select all that apply.
complexity:
label: Project Complexity
description: Which of these describes how complex your team's use of the cloud will be? Select all that apply.
storage: Storage
data_analytics: Data Analytics
conus: CONUS Acess
oconus: OCONUS Access
tactical_edge: Tactical Edge Access
not_sure: Not Sure
other: Other
complexity_other_label: Project Complexity Other
dev_team_label: Development Team
dev_team_description: Which people or teams will be completing the development work for your cloud applications? Select all that apply.
dev_team:
label: Development Team
description: Which people or teams will be completing the development work for your cloud applications? Select all that apply.
government_civilians: Government Civilians
military: Military
contractor: Contractor
other: "Other <em>(E.g. University or other partner)</em>"
dev_team_other_label: Development Team Other
team_experience_label: Team Experience
team_experience_description: How much experience does your team have with development in the cloud?
performance_length_label: Period of Performance length
team_experience:
label: Team Experience
description: How much experience does your team have with development in the cloud?
none: No previous experience
planned: Researched or planned a cloud build or migration
built_1: Built or Migrated 1-2 applications
built_3: Built or Migrated 3-5 applications
built_many: Built or migrated many applications, or consulted on several such projects
performance_length:
label: Period of Performance length
start_date_label: Start Date
end_date_label: End Date
pdf_label: Upload a copy of your CSP Cost Estimate Research
@ -375,11 +401,42 @@ task_orders:
ko_info_title: Contracting Officer (KO) Information
ko_info_paragraph: 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. You might want to work with your program Financial Manager to get your TO documents moving in the right dirction.
skip_ko_label: "Skip for now (We'll remind you to enter one later)"
cor_info_title: Contractive Officer Representative (COR) Information
cor_info_title: Contracting Officer Representative (COR) Information
cor_info_paragraph: Your COR may assist in submitting the Task Order documents within thier official system of record. They may also be invited to log in an manage the Task Order entry within the JEDI Cloud portal.
am_cor_label: I am the Contracting Officer Representative (COR) for this Task Order
so_info_title: Security Officer Information
so_info_paragraph: our Security Officer will need to answer some security configuration questions in order to generate a DD-254 document, then electronically sign.
so_info_paragraph: Your Security Officer will need to answer some security configuration questions in order to generate a DD-254 document, then electronically sign.
review:
section_title: Review Your Task Order Info
app_info: What are you building
portfolio: Portfolio
dod: DoD Component
scope: Scope (Statement of Work)
reporting: Reporting
migration: App Migration
native_apps: Native Apps
yes_native: Yes, planning to develop natively in the cloud
no_native: No, not planning to develop natively in the cloud
not_sure_native: Not sure, unsure if planning to develop natively in the cloud
complexity: Project Complexity
team: Development Team
experience: Team Experience
funding: Funding
performance_period: Period of Performance length
usage_est_link: View Usage Estimate
to_value: Task Order Value
clin_1: 'CLIN #1: Unclassified Cloud'
clin_2: 'CLIN #2: Classified Cloud'
clin_3: 'CLIN #3: Unclassified Cloud'
clin_4: 'CLIN $4: Classified Cloud'
classified_inactive: (Available Soon)
oversight: Oversight
ko: Contracting Officer (KO)
cor: Contracting Officer Representative (COR)
so: IA Security Officer
dod_id: 'DoD ID:'
invited: Invited
not_invited: Not Yet Invited
testing:
example_string: Hello World
example_with_variables: 'Hello, {name}!'