Merge pull request #1275 from dod-ccpo/to-view-review-pages

To view review pages
This commit is contained in:
leigh-mil 2020-01-02 14:14:36 -05:00 committed by GitHub
commit b157daeff9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
24 changed files with 193 additions and 175 deletions

View File

@ -8,16 +8,16 @@ from atst.forms.task_order import SignatureForm
from atst.models import Permissions
@task_orders_bp.route("/task_orders/<task_order_id>/review")
@user_can(Permissions.VIEW_TASK_ORDER_DETAILS, message="review task order details")
def review_task_order(task_order_id):
@task_orders_bp.route("/task_orders/<task_order_id>")
@user_can(Permissions.VIEW_TASK_ORDER_DETAILS, message="view task order details")
def view_task_order(task_order_id):
task_order = TaskOrders.get(task_order_id)
if task_order.is_draft:
return redirect(url_for("task_orders.edit", task_order_id=task_order.id))
else:
signature_form = SignatureForm()
return render_template(
"task_orders/review.html",
"task_orders/view.html",
task_order=task_order,
signature_form=signature_form,
)

View File

@ -607,3 +607,28 @@
margin-right: $gap * 3;
}
}
.summary-item {
border-right: 1px solid $color-gray-light;
margin-right: $gap * 3;
padding-right: $gap * 3;
&:last-child {
border-right: none;
margin-right: 0;
padding-right: 0;
}
&__header {
margin: 0;
&-icon {
margin: 0;
padding: 0;
}
}
&__value {
font-size: $lead-font-size;
&--large {
font-size: 3.4rem;
font-weight: $font-bold;
}
}
}

View File

@ -63,4 +63,8 @@
font-size: $small-font-size;
font-weight: $font-bold;
}
&--link {
font-weight: $font-bold;
}
}

View File

@ -53,7 +53,6 @@ table.atat-table {
padding: $gap * 2;
border: 1px solid $color-gray-lighter;
display: table-cell;
white-space: nowrap;
vertical-align: top;
&:first-child {
@ -64,6 +63,12 @@ table.atat-table {
border-right: none;
}
}
&:last-child {
td {
border-bottom: none;
}
}
}
}

View File

@ -118,27 +118,6 @@
}
}
.reporting-summary-item {
border-right: 1px solid $color-gray-light;
margin-right: $gap * 3;
padding-right: $gap * 3;
&:last-child {
border-right: none;
margin-right: 0;
padding-right: 0;
}
&__header {
margin: 0;
&-icon {
margin: 0;
padding: 0;
}
}
&__value {
font-size: $lead-font-size;
}
}
.reporting-expended-funding {
&__header {
margin: 0;

View File

@ -36,22 +36,6 @@
margin-top: $gap * 2;
}
.task-order__review {
.h2 {
margin-bottom: $gap * 4;
}
.task-order__number {
text-align: right;
}
.totals-box {
flex-grow: unset;
display: table;
min-width: 350px;
}
}
.card {
padding: ($gap * 4) ($gap * 5) 0;

View File

@ -3,7 +3,7 @@
{% macro Tooltip(message,title='Help', classes="") %}
<button type="button" tabindex="0" class="icon-tooltip {{classes}}" v-tooltip.top="{content: '{{message}}', container: false}">
{{ Icon('help') }}<span>{{ title }}</span>
{{ Icon('question') }}<span>{{ title }}</span>
</button>
{%- endmacro %}

View File

@ -30,7 +30,7 @@
icon='funding',
text='navigation.portfolio_navigation.breadcrumbs.funding' | translate,
url=url_for("task_orders.portfolio_funding", portfolio_id=portfolio.id),
active=request.url_rule.endpoint in ["task_orders.portfolio_funding", "task_orders.review_task_order", "task_orders.form_step_one_add_pdf", "task_orders.submit_form_step_one_add_pdf", "task_orders.form_step_two_add_number", "task_orders.submit_form_step_two_add_number", "task_orders.form_step_three_add_clins", "task_orders.submit_form_step_three_add_clins", "task_orders.form_step_four_review", "task_orders.form_step_five_confirm_signature"],
active=request.url_rule.endpoint in ["task_orders.portfolio_funding", "task_orders.view_task_order", "task_orders.form_step_one_add_pdf", "task_orders.submit_form_step_one_add_pdf", "task_orders.form_step_two_add_number", "task_orders.submit_form_step_two_add_number", "task_orders.form_step_three_add_clins", "task_orders.submit_form_step_three_add_clins", "task_orders.form_step_four_review", "task_orders.form_step_five_confirm_signature"],
) }}
{% endif %}
{{ Link(

View File

@ -23,7 +23,7 @@
{% for task_order in expired_task_orders %}
<tr>
<td colspan="5">
<span class="h4 reporting-expended-funding__header">Task Order</span> <a href="{{ url_for("task_orders.review_task_order", task_order_id=task_order.id) }}">
<span class="h4 reporting-expended-funding__header">Task Order</span> <a href="{{ url_for("task_orders.view_task_order", task_order_id=task_order.id) }}">
{{ task_order.number }} {{ Icon("caret_right", classes="icon--tiny icon--blue" ) }}
</a>
</td>

View File

@ -67,7 +67,7 @@
Active Task Orders
</h3>
{% for task_order in portfolio.active_task_orders %}
<a href="{{ url_for("task_orders.review_task_order", task_order_id=task_order.id) }}">
<a href="{{ url_for("task_orders.view_task_order", task_order_id=task_order.id) }}">
{{ task_order.number }} {{ Icon("caret_right", classes="icon--tiny icon--blue" ) }}
</a>
{% endfor %}

View File

@ -3,34 +3,34 @@
<section class="row">
<div class='col col--grow reporting-summary-item'>
<h5 class="reporting-summary-item__header">
<span class="reporting-summary-item__header-text">Total Portfolio Value</span>
{{Tooltip(("common.lorem" | translate), title="", classes="reporting-summary-item__header-icon")}}
<div class='col col--grow summary-item'>
<h5 class="summary-item__header">
<span class="summary-item__header-text">Total Portfolio Value</span>
{{Tooltip(("common.lorem" | translate), title="", classes="summary-item__header-icon")}}
</h5>
<p class="reporting-summary-item__value">{{ total_portfolio_value | dollars }}</p>
<p class="summary-item__value">{{ total_portfolio_value | dollars }}</p>
</div>
<div class='col col--grow reporting-summary-item'>
<h5 class="reporting-summary-item__header">
<span class="reporting-summary-item__header-text">Funding Duration</span>
{{Tooltip(("common.lorem" | translate), title="", classes="reporting-summary-item__header-icon")}}
<div class='col col--grow summary-item'>
<h5 class="summary-item__header">
<span class="summary-item__header-text">Funding Duration</span>
{{Tooltip(("common.lorem" | translate), title="", classes="summary-item__header-icon")}}
</h5>
{% set earliest_pop_start_date, latest_pop_end_date = portfolio.funding_duration %}
{% if earliest_pop_start_date and latest_pop_end_date %}
<p class="reporting-summary-item__value" >
<p class="summary-item__value" >
{{ earliest_pop_start_date | formattedDate(formatter="%B %d, %Y") }}
-
{{ latest_pop_end_date | formattedDate(formatter="%B %d, %Y") }}
</p>
{% else %}
<p class="reporting-summary-item__value"> - </p>
<p class="summary-item__value"> - </p>
{% endif %}
</div>
<div class='col col--grow reporting-summary-item'>
<h5 class="reporting-summary-item__header">
<span class="reporting-summary-item__header-text">Days Remaining</span>
{{Tooltip(("common.lorem" | translate), title="", classes="reporting-summary-item__header-icon")}}
<div class='col col--grow summary-item'>
<h5 class="summary-item__header">
<span class="summary-item__header-text">Days Remaining</span>
{{Tooltip(("common.lorem" | translate), title="", classes="summary-item__header-icon")}}
</h5>
<p class="reporting-summary-item__value">{{ portfolio.days_to_funding_expiration }} days</p>
<p class="summary-item__value">{{ portfolio.days_to_funding_expiration }} days</p>
</div>
</section>

View File

@ -9,7 +9,7 @@
{{ form.csrf_token }}
{{ StickyCTA(
text='task_orders.form.sticky_header_text' | translate,
text=sticky_cta_text,
context=('task_orders.form.sticky_header_context' | translate({"step": step}) )) }}
{% call Modal(name='cancel', dismissable=True) %}

View File

@ -1,82 +0,0 @@
{% from "components/icon.html" import Icon %}
{% from "components/semi_collapsible_text.html" import SemiCollapsibleText %}
<div class="task-order__review">
<div class="form-row">
<div class="form-col">
<div class="h2">
{{ "task_orders.review.review_your_funding" | translate }}
</div>
<div>
<div class="totals-box">
{% if task_order %}
{% set obligated_funds = task_order.total_obligated_funds %}
{% set contract_amount = task_order.total_contract_amount %}
{% endif %}
<div class="h4">{{ 'components.totals_box.obligated_funds' | translate }}</div>
<div class="h3">{{ obligated_funds | dollars }}</div>
<p>{{ 'components.totals_box.obligated_text' | translate }}</p>
<div class="h4">{{ 'components.totals_box.total_amount' | translate }}</div>
<div class="h3">{{ contract_amount | dollars }}</div>
<p>{{ 'components.totals_box.total_text' | translate }}</p>
</div>
</div>
<div class="h3">
{{ 'task_orders.review.pdf_title' | translate }}
</div>
<a class="icon-link icon-link--download" href="{{ pdf_download_url }}">
{{ Icon('ok') }}
{{ task_order.pdf.filename }}
</a>
<hr>
<div class="col task-order__details">
<div class="h3">
{{ "task_orders.review.task_order_number" | translate }}
</div>
<div>{{task_order.number}}</div>
<hr>
<div class="h3">
{{ "task_orders.review.funding_summary" | translate }}
</div>
<table class="fixed-table-wrapper">
<thead>
<tr>
<th>{{ "task_orders.review.clins.number" | translate }}</th>
<th>{{ "task_orders.review.clins.type" | translate }}</th>
<th>{{ "task_orders.review.clins.idiq_clin_description" | translate }}</th>
<th>{{ "task_orders.review.clins.pop" | translate }}</th>
<th class="task-order__amount">{{ "task_orders.review.clins.total_amount" | translate }}</th>
<th class="task-order__amount">{{ "task_orders.review.clins.obligated" | translate }}</th>
</tr>
</thead>
<tbody>
{% for clin in task_order.sorted_clins %}
<tr>
<td>{{ clin.number }}</td>
<td>{{ clin.type }}</td>
<td>{{ "{}".format(clin.jedi_clin_type) | translate}}</td>
<td>
{{ clin.start_date | formattedDate }} - {{ clin.end_date | formattedDate }}
</td>
{# TODO: Swap in total CLIN amount #}
<td class="task-order__amount">{{ clin.total_amount | dollars }}</td>
<td class="task-order__amount">{{ clin.obligated_amount | dollars }}</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
</div>
</div>

View File

@ -0,0 +1,90 @@
{% from "components/icon.html" import Icon %}
{% from "components/semi_collapsible_text.html" import SemiCollapsibleText %}
{% from "components/tooltip.html" import Tooltip %}
{% macro TaskOrderView(task_order, portfolio, builder_mode=False) %}
{% set obligated_funds = task_order.total_obligated_funds %}
{% set contract_amount = task_order.total_contract_amount %}
{% set expended_funds = task_order.invoiced_funds %}
<div>
<section class="row">
<div class='col col--grow summary-item'>
<h4 class="summary-item__header">
<span class="summary-item__header-text">Total obligated funds</span>
{{ Tooltip(("task_orders.review.tooltip.obligated_funds" | translate), title="", classes="summary-item__header-icon") }}
</h4>
<p class="summary-item__value--large">
{{ obligated_funds | dollars }}
</p>
</div>
<div class='col col--grow summary-item'>
<h4 class="summary-item__header">
<span class="summary-item__header-text">Total Task Order value</span>
{{ Tooltip(("task_orders.review.tooltip.total_value" | translate), title="", classes="summary-item__header-icon") }}
</h4>
{% set earliest_pop_start_date, latest_pop_end_date = portfolio.funding_duration %}
{% if earliest_pop_start_date and latest_pop_end_date %}
<p class="summary-item__value--large">
{{ contract_amount | dollars }}
</p>
{% else %}
<p class="summary-item__value--large"> - </p>
{% endif %}
</div>
<div class='col col--grow summary-item'>
<h4 class="summary-item__header">
<span class="summary-item__header-text">Total expended funds</span>
{{ Tooltip(("task_orders.review.tooltip.expended_funds" | translate), title="", classes="summary-item__header-icon") }}
</h4>
<p class="summary-item__value--large">
{{ expended_funds | dollars }}
</p>
</div>
</section>
<hr>
<section>
<h4>Documents</h4>
<div class="panel panel__content">
{% if builder_mode %}
{{ Icon('ok', classes="icon--green icon--medium") }}
{% endif %}
<a href="{{ pdf_download_url }}">
{{ task_order.pdf.filename }}
{{ Icon('link', classes="icon--primary icon--medium") }}
</a>
</div>
</section>
<hr>
<section>
<h4>CLIN summary</h4>
<table class="fixed-table-wrapper atat-table">
<thead>
<tr>
<th>{{ "task_orders.review.clins.number" | translate }}</th>
<th>{{ "task_orders.review.clins.type" | translate }}</th>
<th>{{ "task_orders.review.clins.idiq_clin_description" | translate }}</th>
<th>{{ "task_orders.review.clins.pop" | translate }}</th>
<th class="task-order__amount">{{ "task_orders.review.clins.total_amount" | translate }}</th>
<th class="task-order__amount">{{ "task_orders.review.clins.obligated" | translate }}</th>
</tr>
</thead>
<tbody>
{% for clin in task_order.sorted_clins %}
<tr>
<td>{{ clin.number }}</td>
<td>{{ clin.type }}</td>
<td>{{ "{}".format(clin.jedi_clin_type) | translate}}</td>
<td>
{{ clin.start_date | formattedDate }} - {{ clin.end_date | formattedDate }}
</td>
<td class="task-order__amount">{{ clin.total_amount | dollars }}</td>
<td class="task-order__amount">{{ clin.obligated_amount | dollars }}</td>
</tr>
{% endfor %}
</tbody>
</table>
</section>
</div>
{% endmacro %}

View File

@ -26,7 +26,7 @@
{% endif %}
{% endset %}
<div class="accordion__content--list-item">
<h4><a href="{{ url_for('task_orders.review_task_order', task_order_id=task_order.id) }}">{{ to_number }} {{ Icon("caret_right", classes="icon--tiny icon--primary" ) }}</a></h4>
<h4><a href="{{ url_for('task_orders.view_task_order', task_order_id=task_order.id) }}">{{ to_number }} {{ Icon("caret_right", classes="icon--tiny icon--primary" ) }}</a></h4>
{% if status != 'Expired' -%}
<div class="row">
<div class="col col--grow">

View File

@ -1,16 +0,0 @@
{% from "components/sticky_cta.html" import StickyCTA %}
{% extends 'portfolios/base.html' %}
{% block portfolio_content %}
{% call StickyCTA(text="Task order details") %}
{% if user_can(permissions.EDIT_TASK_ORDER_DETAILS) and not task_order.is_expired %}
<a href="{{ url_for('task_orders.edit', task_order_id=task_order.id) }}" class="usa-button usa-button-secondary" type="submit">Edit</a>
{% endif %}
{% endcall %}
<div class="task-order">
{% include "task_orders/fragments/task_order_review.html" %}
</div>
{% endblock %}

View File

@ -12,6 +12,7 @@
{% set next_button_text = "Next: Add TO Number" %}
{% set step = "1" %}
{% set sticky_cta_text = 'task_orders.form.sticky_header_text' | translate %}
{% block to_builder_form_field %}
{{ TOFormStepHeader(

View File

@ -7,6 +7,7 @@
{% set next_button_text = "Next: Add Base CLIN" %}
{% set previous_button_link = url_for("task_orders.form_step_one_add_pdf", task_order_id=task_order_id) %}
{% set step = "2" %}
{% set sticky_cta_text = 'task_orders.form.sticky_header_text' | translate %}
{% block to_builder_form_field %}
{{ TOFormStepHeader(

View File

@ -8,6 +8,7 @@
{% set next_button_text = "task_orders.form.step_3.next_button" | translate %}
{% set previous_button_link = url_for("task_orders.form_step_two_add_number", task_order_id=task_order_id) %}
{% set step = "3" %}
{% set sticky_cta_text = 'task_orders.form.sticky_header_text' | translate %}
{% block to_builder_form_field %}

View File

@ -1,17 +1,20 @@
{% extends "task_orders/builder_base.html" %}
{% from "task_orders/fragments/task_order_view.html" import TaskOrderView %}
{% set action = url_for('task_orders.form_step_five_confirm_signature', task_order_id=task_order_id) %}
{% set previous_button_link = url_for("task_orders.form_step_three_add_clins", task_order_id=task_order_id) %}
{% set step = "4" %}
{% set sticky_cta_text = 'task_orders.form.sticky_header_review_text' | translate %}
{% block next_button %}
<a
href="{{ action }}"
class="usa-button usa-button-primary">
Next: Submit Task Order
Next: Confirm
</a>
{% endblock %}
{% block to_builder_form_field %}
{% include "task_orders/fragments/task_order_review.html" %}
{{ TaskOrderView(task_order, portfolio, builder_mode=True) }}
{% endblock %}

View File

@ -8,6 +8,7 @@
{% set next_button_text = 'task_orders.form.step_5.next_button' | translate %}
{% set previous_button_link = url_for("task_orders.form_step_four_review", task_order_id=task_order_id) %}
{% set step = "5" %}
{% set sticky_cta_text = 'task_orders.form.sticky_header_text' | translate %}
{% block to_builder_form_field %}
{{ TOFormStepHeader(

View File

@ -0,0 +1,17 @@
{% from "components/sticky_cta.html" import StickyCTA %}
{% from "task_orders/fragments/task_order_view.html" import TaskOrderView %}
{% extends 'portfolios/base.html' %}
{% block portfolio_content %}
{% call StickyCTA(text="Task Order #{}".format(task_order.number)) %}
{% if user_can(permissions.EDIT_TASK_ORDER_DETAILS) and not task_order.is_expired %}
<a class="sticky-cta--link" href="{{ url_for('task_orders.edit', task_order_id=task_order.id) }}">Correct an Error</a>
{% endif %}
{% endcall %}
<div class="task-order">
{{ TaskOrderView(task_order, portfolio) }}
</div>
{% endblock %}

View File

@ -35,22 +35,22 @@ def task_order():
return task_order
def test_review_task_order_not_draft(client, user_session, task_order):
def test_view_task_order_not_draft(client, user_session, task_order):
TaskOrders.sign(task_order=task_order, signer_dod_id=random_dod_id())
user_session(task_order.portfolio.owner)
response = client.get(
url_for("task_orders.review_task_order", task_order_id=task_order.id)
url_for("task_orders.view_task_order", task_order_id=task_order.id)
)
assert response.status_code == 200
def test_review_task_order_draft(client, user_session, task_order):
def test_view_task_order_draft(client, user_session, task_order):
TaskOrders.update(
task_order_id=task_order.id, number="1234567890", clins=[], pdf=None
)
user_session(task_order.portfolio.owner)
response = client.get(
url_for("task_orders.review_task_order", task_order_id=task_order.id)
url_for("task_orders.view_task_order", task_order_id=task_order.id)
)
assert response.status_code == 302
assert url_for("task_orders.edit", task_order_id=task_order.id) in response.location

View File

@ -491,6 +491,10 @@ task_orders:
pop: PoP
total_amount: CLIN Value
obligated: Amount Obligated
tooltip:
obligated_funds: Funds committed to fund your portfolio. This may represent 100% of your total Task Order value, or a portion of it.
total_value: All obligated and projected funds for the Task Orders Base and Option CLINs.
expended_funds: All funds spend from the Task Order so far.
form:
add_clin: Add another CLIN
add_to_header: Add your task order
@ -527,7 +531,8 @@ task_orders:
description: Prior to submitting the Task Order, you must acknowledge, by marking the appropriate box below, that the uploaded Task Order is signed by an appropriate, duly warranted Contracting Officer who has the authority to execute the uploaded Task Order on your Agencys behalf and has authorized you to upload the Task Order in accordance with Agency policy and procedures. You must further acknowledge, by marking the appropriate box below, that all information entered herein matches that of the submitted Task Order.
alert_message: All task orders require a Contracting Officer signature.
next_button: 'Confirm & Submit'
sticky_header_text: 'Add Task Order'
sticky_header_text: 'Add a Task Order'
sticky_header_review_text: Review Changes
sticky_header_context: 'Step {step} of 5'
empty_state:
header: Add approved task orders
@ -549,10 +554,10 @@ task_orders:
status_empty_state: 'This Portfolio has no {status} Task Orders.'
status_list_title: '{status} Task Orders'
JEDICLINType:
JEDI_CLIN_1: 'IDIQ CLIN 0001 Unclassified IaaS/PaaS'
JEDI_CLIN_2: 'IDIQ CLIN 0002 Classified IaaS/PaaS'
JEDI_CLIN_3: 'IDIQ CLIN 0003 Unclassified Cloud Support Package'
JEDI_CLIN_4: 'IDIQ CLIN 0004 Classified Cloud Support Package'
JEDI_CLIN_1: 'Unclassified IaaS and PaaS (IDIQ CLIN 0001)'
JEDI_CLIN_2: 'Classified IaaS and PaaS (IDIQ CLIN 0002)'
JEDI_CLIN_3: 'Unclassified Cloud Support Package (IDIQ CLIN 0003)'
JEDI_CLIN_4: 'Classified Cloud Support Package (IDIQ CLIN 0004)'
testing:
example_string: Hello World
example_with_variables: 'Hello, {name}!'