From d476124762569b3725ada1e5797ee17bfed3e0c9 Mon Sep 17 00:00:00 2001 From: Andrew Croce Date: Thu, 13 Sep 2018 12:44:21 -0400 Subject: [PATCH 01/37] Add label and description to internal notes field --- atst/forms/internal_comment.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/atst/forms/internal_comment.py b/atst/forms/internal_comment.py index a64833c8..71b88f7e 100644 --- a/atst/forms/internal_comment.py +++ b/atst/forms/internal_comment.py @@ -5,4 +5,8 @@ from .forms import ValidatedForm class InternalCommentForm(ValidatedForm): - text = TextAreaField(validators=[Optional()]) + text = TextAreaField( + "CCPO Internal Notes", + description="You may add additional comments and notes for internal CCPO reference and follow-up here.", + validators=[Optional()], + ) From 905226e98ad9060b38ec26efc630afbbe80b1e56 Mon Sep 17 00:00:00 2001 From: Andrew Croce Date: Thu, 13 Sep 2018 12:44:53 -0400 Subject: [PATCH 02/37] change label and description for review comments field --- atst/forms/ccpo_review.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/atst/forms/ccpo_review.py b/atst/forms/ccpo_review.py index 8b6ea64d..5d910fb6 100644 --- a/atst/forms/ccpo_review.py +++ b/atst/forms/ccpo_review.py @@ -7,7 +7,7 @@ from .validators import Alphabet, PhoneNumber class CCPOReviewForm(ValidatedForm): - comment = TextAreaField("Comments (optional)") + comment = TextAreaField("Instructions or comments", description='Provide instructions or notes for additional information that is necessary to approve the request here. The requestor may then re-submit the updated request or initiate contact outside of AT-AT if further discussion is required. This message will be shared with the person making the JEDI request..') fname_mao = StringField( "First Name (optional)", validators=[Optional(), Alphabet()] ) From 2a97ed5dc361396ca4fe9488f19df85eb3965b39 Mon Sep 17 00:00:00 2001 From: Andrew Croce Date: Thu, 13 Sep 2018 12:58:23 -0400 Subject: [PATCH 03/37] request approval screen --- atst/routes/requests/approval.py | 2 +- templates/requests/approval.html | 248 +++++++++++++++++-------------- 2 files changed, 138 insertions(+), 112 deletions(-) diff --git a/atst/routes/requests/approval.py b/atst/routes/requests/approval.py index 1843e127..7249f9a4 100644 --- a/atst/routes/requests/approval.py +++ b/atst/routes/requests/approval.py @@ -35,7 +35,7 @@ def render_approval(request, form=None): return render_template( "requests/approval.html", data=data, - status_events=reversed(request.status_events), + reviews=list(reversed(request.reviews)), request=request, current_status=request.status.value, pending_review=pending_review, diff --git a/templates/requests/approval.html b/templates/requests/approval.html index b9559712..a28a35c0 100644 --- a/templates/requests/approval.html +++ b/templates/requests/approval.html @@ -16,8 +16,9 @@ {% endif %}
-
-

Request #{{ request.id }}

+
+

Request #{{ request.id }} +

{{ current_status }}
@@ -32,153 +33,178 @@
{% if pending_review %} -
- {{ f.csrf_token }} -
-
-

Approval Notes

-
+
+ + {{ f.csrf_token }} -
+ +
+
+
+

Review this Request

-
+
+
+ + -

Instructions for the Requestor

+ + +
+
- Provide instructions or notes for additional information that is necessary to approve the request here. The requestor may then re-submit the updated request or initiate contact outside of AT-AT if further discussion is required. These notes will be visible to the person making the JEDI Cloud request. +
+

Message to Requestor (optional)

+
+ {{ TextInput( + f.comment, + label='Approval comments or notes', + description='Provide any comments or notes regarding the approval of this request. This message will be shared with the person making the JEDI request..', + paragraph=True, + noMaxWidth=True + ) }} +
- {{ TextInput(f.comment, paragraph=True, placeholder="Add notes or comments explaining what changes are being requested or why further discussion is needed about this request.") }} +
+ {{ TextInput( + f.comment, + label='Revision instructions or notes', + paragraph=True, + noMaxWidth=True + ) }} +
+
-
+
-
-
-

Authorizing Officials

-

This section is not visible to the person making the request. It is only viewable by CCPO staff.

-

Provide the name of the key officials for both parties that have authorized this request to move forward.

+

Authorizing Officials (optional)

+

Provide the name of the key officials for both parties that have authorized this request to move forward. This section is not visible to the person making the request. It is only viewable by CCPO staff.

+
+ +

Mission Authorizing Official

+ +
+
+ {{ TextInput(f.fname_mao, placeholder="First name of mission authorizing official") }} +
+ +
+ {{ TextInput(f.lname_mao, placeholder="Last name of mission authorizing official") }} +
+
+ +
+
+ {{ TextInput(f.email_mao, placeholder="name@mail.mil") }} +
+ +
+ {{ TextInput(f.phone_mao, placeholder="(123) 456-7890", validation='usPhone') }} +
+
+ +
+ +

CCPO Authorizing Official

+ +
+
+ {{ TextInput(f.fname_ccpo, placeholder="First name of CCPO authorizing official") }} +
+ +
+ {{ TextInput(f.lname_ccpo, placeholder="Last name of CCPO authorizing official") }} +
+
+
+
+
+ +
+ + + + {{ Icon('x') }} + Cancel +
-

Mission Authorizing Official

- - -
- -
- {{ TextInput(f.fname_mao, placeholder="First name of mission authorizing official") }} -
- -
- {{ TextInput(f.lname_mao, placeholder="Last name of mission authorizing official") }} -
- -
- -
- -
- {{ TextInput(f.email_mao, placeholder="name@mail.mil") }} -
- - -
- {{ TextInput(f.phone_mao, placeholder="(123) 456-7890", validation='usPhone') }} -
- -
- - -

CCPO Authorizing Official

- -
- -
- {{ TextInput(f.fname_ccpo, placeholder="First name of CCPO authorizing official") }} -
- -
- {{ TextInput(f.lname_ccpo, placeholder="Last name of CCPO authorizing official") }} -
- -
- - - -
- -
- - - - {{ Icon('x') }} - Cancel - -
- + + +
{% endif %} -
-

CCPO Internal Notes

-

You may add additional comments and notes for internal CCPO reference and follow-up here.

-
-
-
- {{ internal_comment_form.csrf_token }} - {{ TextInput(internal_comment_form.text, paragraph=True) }} - -
+ +
+
+
+
+ + {{ internal_comment_form.csrf_token }} + {{ TextInput(internal_comment_form.text, paragraph=True, noMaxWidth=True) }} + +
-
-
+ +
+ +
+
-
-
-

Approval Log

-
-
-
-
    +
    + {% if reviews %} +
    +
    +

    CCPO Activity Log

    +
    - {% for status_event in status_events %} - {% if status_event.review %} +
    +
      + {% for review in reviews %}
    1. -

      {{ status_event.log_name }} by {{ status_event.review.full_name_reviewer }}

      - {% if status_event.review.comment %} -

      {{ status_event.review.comment }}

      +

      {{ review.log_name }} by {{ review.full_name_reviewer }}

      + {% if review.comment %} +

      {{ review.comment }}

      {% endif %}
      - {% if status_event.review.lname_mao %} + {% if review.lname_mao %}

      Mission Owner approval on behalf of:

      - {{ status_event.review.full_name_mao }} - {{ status_event.review.email_mao }} - {{ status_event.review.phone_mao }} + {{ review.full_name_mao }} + {{ review.email_mao }} + {{ review.phone_mao }}
      {% endif %} - {% if status_event.review.lname_ccpo %} + {% if review.lname_ccpo %}

      CCPO approval on behalf of:

      - {{ status_event.review.full_name_ccpo }} + {{ review.full_name_ccpo }}
      {% endif %}
      - {% set timestamp=status_event.time_created | formattedDate("%Y-%m-%d %H:%M:%S %Z") %} + {% set timestamp=review.status.time_created | formattedDate("%Y-%m-%d %H:%M:%S %Z") %}
    2. - {% endif %} - {% endfor %} - -
    + {% endfor %} +
+
- + {% else %} + {{ Alert('CCPO Activity Log', + message='No CCPO approvals or request changes have been recorded yet.', + level='warning' + ) }} + {% endif %}
+ {% endblock %} From 4eaacce321db11f45318597225d306d0460fba36 Mon Sep 17 00:00:00 2001 From: Andrew Croce Date: Thu, 13 Sep 2018 12:58:41 -0400 Subject: [PATCH 04/37] add anchor to redirect --- atst/routes/requests/approval.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/atst/routes/requests/approval.py b/atst/routes/requests/approval.py index 7249f9a4..4d2fb87a 100644 --- a/atst/routes/requests/approval.py +++ b/atst/routes/requests/approval.py @@ -93,4 +93,4 @@ def create_internal_comment(request_id): request = Requests.get(g.current_user, request_id) Requests.update_internal_comments(g.current_user, request, form.data["text"]) - return redirect(url_for("requests.approval", request_id=request_id)) + return redirect(url_for("requests.approval", request_id=request_id, _anchor='ccpo-notes')) From 19e80cd18355adc0505e1db62556367d8357ddfc Mon Sep 17 00:00:00 2001 From: Andrew Croce Date: Thu, 13 Sep 2018 12:59:30 -0400 Subject: [PATCH 05/37] add noMaxWidth, label and description overrides to text input --- js/components/text_input.js | 3 ++- templates/components/text_input.html | 19 +++++++++++++++---- 2 files changed, 17 insertions(+), 5 deletions(-) diff --git a/js/components/text_input.js b/js/components/text_input.js index 8e4f8048..7d0bb78d 100644 --- a/js/components/text_input.js +++ b/js/components/text_input.js @@ -19,7 +19,8 @@ export default { default: () => '' }, initialErrors: Array, - paragraph: String + paragraph: String, + noMaxWidth: String }, data: function () { diff --git a/templates/components/text_input.html b/templates/components/text_input.html index ecd29f5c..f1cfb567 100644 --- a/templates/components/text_input.html +++ b/templates/components/text_input.html @@ -1,24 +1,35 @@ {% from "components/icon.html" import Icon %} {% from "components/tooltip.html" import Tooltip %} -{% macro TextInput(field, tooltip='', placeholder='', validation='anything', paragraph=False, initial_value='') -%} +{% macro TextInput( + field, + label=field.label | striptags, + description=field.description, + tooltip='', + placeholder='', + validation='anything', + paragraph=False, + initial_value='', + noMaxWidth=False) -%} +
+ v-bind:class="['usa-input usa-input--validation--' + validation, { 'usa-input--error': showError, 'usa-input--success': showValid, 'usa-input--validation--paragraph': paragraph, 'no-max-width': noMaxWidth }]">
{% set timestamp=review.status.time_created | formattedDate("%Y-%m-%d %H:%M:%S %Z") %} -
+
+ +
{% endfor %} From b7d2bf87ea09c3c1df43af71d6b794a0d5e11307 Mon Sep 17 00:00:00 2001 From: Andrew Croce Date: Thu, 13 Sep 2018 13:42:56 -0400 Subject: [PATCH 14/37] change submit button depending on whether approving or denying --- templates/requests/approval.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/templates/requests/approval.html b/templates/requests/approval.html index e0a11416..66762f35 100644 --- a/templates/requests/approval.html +++ b/templates/requests/approval.html @@ -122,8 +122,8 @@
- - + + {{ Icon('x') }} Cancel From 94670b5ecf5897595295903e719f59982ddeb700 Mon Sep 17 00:00:00 2001 From: Andrew Croce Date: Thu, 13 Sep 2018 13:48:26 -0400 Subject: [PATCH 15/37] Add missing email validation --- templates/requests/approval.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/templates/requests/approval.html b/templates/requests/approval.html index 66762f35..e39c1568 100644 --- a/templates/requests/approval.html +++ b/templates/requests/approval.html @@ -96,7 +96,7 @@
- {{ TextInput(f.email_mao, placeholder="name@mail.mil") }} + {{ TextInput(f.email_mao, placeholder="name@mail.mil", validation='email') }}
From 3e38b5ff1a812ee182458999e9af505e8db40e17 Mon Sep 17 00:00:00 2001 From: Andrew Croce Date: Thu, 13 Sep 2018 13:54:40 -0400 Subject: [PATCH 16/37] do that format thing --- atst/forms/ccpo_review.py | 5 ++++- atst/routes/requests/approval.py | 4 +++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/atst/forms/ccpo_review.py b/atst/forms/ccpo_review.py index 5d910fb6..2636d529 100644 --- a/atst/forms/ccpo_review.py +++ b/atst/forms/ccpo_review.py @@ -7,7 +7,10 @@ from .validators import Alphabet, PhoneNumber class CCPOReviewForm(ValidatedForm): - comment = TextAreaField("Instructions or comments", description='Provide instructions or notes for additional information that is necessary to approve the request here. The requestor may then re-submit the updated request or initiate contact outside of AT-AT if further discussion is required. This message will be shared with the person making the JEDI request..') + comment = TextAreaField( + "Instructions or comments", + description="Provide instructions or notes for additional information that is necessary to approve the request here. The requestor may then re-submit the updated request or initiate contact outside of AT-AT if further discussion is required. This message will be shared with the person making the JEDI request..", + ) fname_mao = StringField( "First Name (optional)", validators=[Optional(), Alphabet()] ) diff --git a/atst/routes/requests/approval.py b/atst/routes/requests/approval.py index 4d2fb87a..02bcfe75 100644 --- a/atst/routes/requests/approval.py +++ b/atst/routes/requests/approval.py @@ -93,4 +93,6 @@ def create_internal_comment(request_id): request = Requests.get(g.current_user, request_id) Requests.update_internal_comments(g.current_user, request, form.data["text"]) - return redirect(url_for("requests.approval", request_id=request_id, _anchor='ccpo-notes')) + return redirect( + url_for("requests.approval", request_id=request_id, _anchor="ccpo-notes") + ) From 738cbb1c654a5851da7effc981f5a7261178a61c Mon Sep 17 00:00:00 2001 From: dandds Date: Thu, 13 Sep 2018 14:15:25 -0400 Subject: [PATCH 17/37] render basic approval action for ccpo logs on request review screen --- atst/models/request_status_event.py | 2 ++ templates/requests/approval.html | 3 ++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/atst/models/request_status_event.py b/atst/models/request_status_event.py index 283633b1..4680d162 100644 --- a/atst/models/request_status_event.py +++ b/atst/models/request_status_event.py @@ -48,6 +48,8 @@ class RequestStatusEvent(Base): def log_name(self): if self.new_status == RequestStatus.CHANGES_REQUESTED: return "Denied" + if self.new_status == RequestStatus.CHANGES_REQUESTED_TO_FINVER: + return "Denied" elif self.new_status == RequestStatus.PENDING_FINANCIAL_VERIFICATION: return "Accepted" else: diff --git a/templates/requests/approval.html b/templates/requests/approval.html index e39c1568..1af2d43c 100644 --- a/templates/requests/approval.html +++ b/templates/requests/approval.html @@ -166,7 +166,8 @@
  • -

    {{ review.log_name }} by {{ review.full_name_reviewer }}

    + {{ review.log_name }} +

    {{ review.status.log_name }} by {{ review.full_name_reviewer }}

    {% if review.comment %}

    {{ review.comment }}

    {% endif %} From fbe701bba1580d249b576685fd175d3af48da1dd Mon Sep 17 00:00:00 2001 From: Andrew Croce Date: Thu, 13 Sep 2018 14:21:51 -0400 Subject: [PATCH 18/37] use radio for checking approval/denial --- atst/routes/requests/approval.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/atst/routes/requests/approval.py b/atst/routes/requests/approval.py index 02bcfe75..a0f0f5e8 100644 --- a/atst/routes/requests/approval.py +++ b/atst/routes/requests/approval.py @@ -58,7 +58,7 @@ def submit_approval(request_id): form = CCPOReviewForm(http_request.form) if form.validate(): - if http_request.form.get("approved"): + if http_request.form.get("review") == "approving": Requests.advance(g.current_user, request, form.data) else: Requests.request_changes(g.current_user, request, form.data) From b473a87eea15c0a5a4e5df8d9af49da17c89a058 Mon Sep 17 00:00:00 2001 From: Andrew Croce Date: Thu, 13 Sep 2018 14:23:33 -0400 Subject: [PATCH 19/37] update test --- tests/routes/test_request_approval.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/routes/test_request_approval.py b/tests/routes/test_request_approval.py index 1955a04f..205bb28e 100644 --- a/tests/routes/test_request_approval.py +++ b/tests/routes/test_request_approval.py @@ -87,7 +87,7 @@ def test_can_submit_request_approval(client, user_session): status=RequestStatus.PENDING_CCPO_ACCEPTANCE ) review_data = RequestReviewFactory.dictionary() - review_data["approved"] = True + review_data["review"] = "approving" response = client.post( url_for("requests.submit_approval", request_id=request.id), data=review_data ) @@ -102,7 +102,7 @@ def test_can_submit_request_denial(client, user_session): status=RequestStatus.PENDING_CCPO_ACCEPTANCE ) review_data = RequestReviewFactory.dictionary() - review_data["denied"] = True + review_data["review"] = "denying" response = client.post( url_for("requests.submit_approval", request_id=request.id), data=review_data ) From 5018ff39fe3f3f7e039d273f872c0330e70cb8fa Mon Sep 17 00:00:00 2001 From: Andrew Croce Date: Thu, 13 Sep 2018 14:46:44 -0400 Subject: [PATCH 20/37] no need for an alert when no history present --- styles/sections/_request_approval.scss | 2 +- templates/requests/approval.html | 93 +++++++++++++------------- 2 files changed, 47 insertions(+), 48 deletions(-) diff --git a/styles/sections/_request_approval.scss b/styles/sections/_request_approval.scss index 7011d745..f4b36140 100644 --- a/styles/sections/_request_approval.scss +++ b/styles/sections/_request_approval.scss @@ -49,7 +49,7 @@ border-top: 1px dashed $color-gray-light; &:first-child { - border-top-style: solid; + border-top: none; } @include media($medium-screen) { diff --git a/templates/requests/approval.html b/templates/requests/approval.html index 1af2d43c..d93a0f1d 100644 --- a/templates/requests/approval.html +++ b/templates/requests/approval.html @@ -154,58 +154,57 @@
    - {% if reviews %} -
    -
    -

    CCPO Activity Log

    -
    +
    +
    +

    CCPO Activity Log

    +
    -
    -
      - {% for review in reviews %} -
    1. -
      -
      - {{ review.log_name }} -

      {{ review.status.log_name }} by {{ review.full_name_reviewer }}

      - {% if review.comment %} -

      {{ review.comment }}

      +
      + {% if reviews %} +
        + {% for review in reviews %} +
      1. +
        +
        + {{ review.log_name }} +

        {{ review.status.log_name }} by {{ review.full_name_reviewer }}

        + {% if review.comment %} +

        {{ review.comment }}

        + {% endif %} + +
        + {% if review.lname_mao %} +
        +

        Mission Owner approval on behalf of:

        + {{ review.full_name_mao }} + {{ review.email_mao }} + {{ review.phone_mao }} +
        {% endif %} -
        - {% if review.lname_mao %} -
        -

        Mission Owner approval on behalf of:

        - {{ review.full_name_mao }} - {{ review.email_mao }} - {{ review.phone_mao }} -
        - {% endif %} - - {% if review.lname_ccpo %} -
        -

        CCPO approval on behalf of:

        - {{ review.full_name_ccpo }} -
        - {% endif %} -
        + {% if review.lname_ccpo %} +
        +

        CCPO approval on behalf of:

        + {{ review.full_name_ccpo }} +
        + {% endif %}
        - {% set timestamp=review.status.time_created | formattedDate("%Y-%m-%d %H:%M:%S %Z") %} -
        - -
        -
        -
      2. - {% endfor %} -
      -
      +
      + {% set timestamp=review.status.time_created | formattedDate("%Y-%m-%d %H:%M:%S %Z") %} +
      + +
      +
      +
    2. + {% endfor %} +
    + {% else %} +
    +

    No CCPO approvals or request changes have been recorded yet.

    +
    + {% endif %}
    - {% else %} - {{ Alert('CCPO Activity Log', - message='No CCPO approvals or request changes have been recorded yet.', - level='warning' - ) }} - {% endif %} +
    From 6cd627f820a6f1995b3d92495ea88e5c8da2517f Mon Sep 17 00:00:00 2001 From: richard-dds Date: Fri, 14 Sep 2018 10:43:42 -0400 Subject: [PATCH 21/37] Move "pending financial verification" alert --- atst/routes/requests/financial_verification.py | 2 +- templates/requests/financial_verification.html | 13 +++++++++---- templates/requests/index.html | 6 ------ 3 files changed, 10 insertions(+), 11 deletions(-) diff --git a/atst/routes/requests/financial_verification.py b/atst/routes/requests/financial_verification.py index 728f7f39..1aaf75e2 100644 --- a/atst/routes/requests/financial_verification.py +++ b/atst/routes/requests/financial_verification.py @@ -38,7 +38,7 @@ def financial_verification(request_id=None): return render_template( "requests/financial_verification.html", f=form, - request_id=request_id, + request=request, extended=is_extended(request), ) diff --git a/templates/requests/financial_verification.html b/templates/requests/financial_verification.html index f3950f00..2e03fa80 100644 --- a/templates/requests/financial_verification.html +++ b/templates/requests/financial_verification.html @@ -6,6 +6,11 @@ {% block content %} +{% if request.is_pending_financial_verification %} + {{ Alert('Pending Financial Verification', fragment="fragments/pending_financial_verification.html") }} +{% endif %} + + {% include 'requests/review_menu.html' %} @@ -19,7 +24,7 @@ {% endif %} {% if f.is_missing_task_order_number %} - {% set extended_url = url_for('requests.financial_verification', request_id=request_id, extended=True) %} + {% set extended_url = url_for('requests.financial_verification', request_id=request.id, extended=True) %} {{ Alert('Task Order not found in EDA', message="We could not find your Task Order in our system of record, EDA. Please confirm that you have entered it correctly.
    @@ -31,9 +36,9 @@ {% block form_action %} {% if extended %} -
    + {% else %} - + {% endif %} {% endblock %} @@ -52,7 +57,7 @@

    Financial Verification

    -

    Order #{{ request_id }}

    +

    Order #{{ request.id }}

    diff --git a/templates/requests/index.html b/templates/requests/index.html index dfee7184..2ef2fefa 100644 --- a/templates/requests/index.html +++ b/templates/requests/index.html @@ -45,12 +45,6 @@ {% else %} - {% if pending_financial_verification %} - - {{ Alert('Pending Financial Verification', fragment="fragments/pending_financial_verification.html") }} - - {% endif %} - {% if pending_ccpo_approval %} {{ Alert('Request submitted. Approval pending.', fragment="fragments/pending_ccpo_approval_alert.html") }} From 75344e2bf1f0410a3acdb7ee2ddba77ee24a5613 Mon Sep 17 00:00:00 2001 From: richard-dds Date: Fri, 14 Sep 2018 11:17:29 -0400 Subject: [PATCH 22/37] Move "Approval pending" alert --- atst/routes/requests/requests_form.py | 1 + templates/requests/details.html | 4 ++++ templates/requests/index.html | 4 ++-- 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/atst/routes/requests/requests_form.py b/atst/routes/requests/requests_form.py index 80f76931..2fb4891a 100644 --- a/atst/routes/requests/requests_form.py +++ b/atst/routes/requests/requests_form.py @@ -143,6 +143,7 @@ def view_request_details(request_id=None): request_id=request.id, status=request.status_displayname, pending_review=request.is_pending_ccpo_action, + pending_ccpo_acceptance=request.is_pending_ccpo_acceptance, financial_verification=request.is_pending_financial_verification or request.is_pending_financial_verification_changes, financial_review=financial_review, diff --git a/templates/requests/details.html b/templates/requests/details.html index 07bd49a7..095f5cc6 100644 --- a/templates/requests/details.html +++ b/templates/requests/details.html @@ -9,6 +9,10 @@ {% include 'requests/review_menu.html' %} {% endif %} + {% if pending_ccpo_acceptance %} + {{ Alert('Request submitted. Approval pending.', fragment="fragments/pending_ccpo_approval_alert.html") }} + {% endif %} + {% if pending_review %} {{ Alert('Your request is being reviewed', message="

    You cannot edit your submitted request while it is under review. Your request will be reviewed within 3 business days.

    ", diff --git a/templates/requests/index.html b/templates/requests/index.html index 2ef2fefa..06c56f00 100644 --- a/templates/requests/index.html +++ b/templates/requests/index.html @@ -45,9 +45,9 @@ {% else %} - {% if pending_ccpo_approval %} + {% if pending_financial_verification %} - {{ Alert('Request submitted. Approval pending.', fragment="fragments/pending_ccpo_approval_alert.html") }} + {{ Alert('Pending Financial Verification', fragment="fragments/pending_financial_verification.html") }} {% endif %} From 812da9fe5b2e29588cde20df28bb08256551b47d Mon Sep 17 00:00:00 2001 From: richard-dds Date: Fri, 14 Sep 2018 11:38:28 -0400 Subject: [PATCH 23/37] Remove financial verification alert from index --- templates/requests/index.html | 6 ------ 1 file changed, 6 deletions(-) diff --git a/templates/requests/index.html b/templates/requests/index.html index 06c56f00..9411776d 100644 --- a/templates/requests/index.html +++ b/templates/requests/index.html @@ -45,12 +45,6 @@ {% else %} - {% if pending_financial_verification %} - - {{ Alert('Pending Financial Verification', fragment="fragments/pending_financial_verification.html") }} - - {% endif %} - {% if extended_view %}
    From 7b2f897c9d0235fc33a77e1a2846ee6de3244a1e Mon Sep 17 00:00:00 2001 From: richard-dds Date: Fri, 14 Sep 2018 13:22:57 -0400 Subject: [PATCH 24/37] Fix extended FV form --- .../routes/requests/financial_verification.py | 2 +- .../requests/financial_verification.html | 20 +++++++++---------- 2 files changed, 10 insertions(+), 12 deletions(-) diff --git a/atst/routes/requests/financial_verification.py b/atst/routes/requests/financial_verification.py index 1aaf75e2..0be12e7b 100644 --- a/atst/routes/requests/financial_verification.py +++ b/atst/routes/requests/financial_verification.py @@ -49,7 +49,7 @@ def update_financial_verification(request_id): existing_request = Requests.get(g.current_user, request_id) form = financial_form(existing_request, post_data) rerender_args = dict( - request_id=request_id, f=form, extended=is_extended(existing_request) + request=existing_request, f=form, extended=is_extended(existing_request) ) if form.validate(): diff --git a/templates/requests/financial_verification.html b/templates/requests/financial_verification.html index 2e03fa80..06de0770 100644 --- a/templates/requests/financial_verification.html +++ b/templates/requests/financial_verification.html @@ -6,16 +6,17 @@ {% block content %} -{% if request.is_pending_financial_verification %} - {{ Alert('Pending Financial Verification', fragment="fragments/pending_financial_verification.html") }} -{% endif %} - {% include 'requests/review_menu.html' %}
    + {% if request.is_pending_financial_verification %} + {{ Alert('Pending Financial Verification', fragment="fragments/pending_financial_verification.html") }} + {% endif %} + + {% if extended %} {{ Alert('Task Order not found in EDA', message="Since the Task Order (TO) number was not found in our system of record, EDA, please populate the additional fields in the form below.", @@ -25,13 +26,10 @@ {% if f.is_missing_task_order_number %} {% set extended_url = url_for('requests.financial_verification', request_id=request.id, extended=True) %} - {{ Alert('Task Order not found in EDA', - message="We could not find your Task Order in our system of record, EDA. - Please confirm that you have entered it correctly.
    - Enter Task Order information manually - "|format(extended_url), - level='warning' - ) }} + {% call Alert('Task Order not found in EDA', level='warning') %} + We could not find your Task Order in our system of record, EDA. Please confirm that you have entered it correctly.
    +
    Enter Task Order information manually + {% endcall %} {% endif %} {% block form_action %} From 8355446965ee0449063aaea3201d565a7c676782 Mon Sep 17 00:00:00 2001 From: richard-dds Date: Fri, 14 Sep 2018 13:32:50 -0400 Subject: [PATCH 25/37] Move pending CCPO approval status to request --- atst/routes/requests/requests_form.py | 1 + ...roval_alert.html => pending_ccpo_acceptance_alert.html} | 0 templates/requests/details.html | 7 ++++++- 3 files changed, 7 insertions(+), 1 deletion(-) rename templates/fragments/{pending_ccpo_approval_alert.html => pending_ccpo_acceptance_alert.html} (100%) diff --git a/atst/routes/requests/requests_form.py b/atst/routes/requests/requests_form.py index 2fb4891a..221069c6 100644 --- a/atst/routes/requests/requests_form.py +++ b/atst/routes/requests/requests_form.py @@ -144,6 +144,7 @@ def view_request_details(request_id=None): status=request.status_displayname, pending_review=request.is_pending_ccpo_action, pending_ccpo_acceptance=request.is_pending_ccpo_acceptance, + pending_ccpo_approval=request.is_pending_ccpo_approval, financial_verification=request.is_pending_financial_verification or request.is_pending_financial_verification_changes, financial_review=financial_review, diff --git a/templates/fragments/pending_ccpo_approval_alert.html b/templates/fragments/pending_ccpo_acceptance_alert.html similarity index 100% rename from templates/fragments/pending_ccpo_approval_alert.html rename to templates/fragments/pending_ccpo_acceptance_alert.html diff --git a/templates/requests/details.html b/templates/requests/details.html index 095f5cc6..2b56398d 100644 --- a/templates/requests/details.html +++ b/templates/requests/details.html @@ -10,7 +10,12 @@ {% endif %} {% if pending_ccpo_acceptance %} - {{ Alert('Request submitted. Approval pending.', fragment="fragments/pending_ccpo_approval_alert.html") }} + {{ Alert('Request submitted. Approval pending.', fragment="fragments/pending_ccpo_acceptance_alert.html") }} + {% elif pending_ccpo_approval %} + {% call Alert('Pending CCPO Approval') %} +

    The CCPO will review and respond to your Financial Verification submission in 3 business days. You will be notified via email or phone.

    +

    Once the financial verification is approved you will be invited to create your JEDI Workspace and set-up your projects. Click here for more details.

    + {% endcall %} {% endif %} {% if pending_review %} From 1c19d44c9bc6dceeefd78bd9fb0a3e00247c038e Mon Sep 17 00:00:00 2001 From: richard-dds Date: Fri, 14 Sep 2018 13:48:29 -0400 Subject: [PATCH 26/37] Remove "pending review" alert --- atst/routes/requests/requests_form.py | 1 - templates/requests/details.html | 7 ------- 2 files changed, 8 deletions(-) diff --git a/atst/routes/requests/requests_form.py b/atst/routes/requests/requests_form.py index 221069c6..79a1535d 100644 --- a/atst/routes/requests/requests_form.py +++ b/atst/routes/requests/requests_form.py @@ -142,7 +142,6 @@ def view_request_details(request_id=None): data=data, request_id=request.id, status=request.status_displayname, - pending_review=request.is_pending_ccpo_action, pending_ccpo_acceptance=request.is_pending_ccpo_acceptance, pending_ccpo_approval=request.is_pending_ccpo_approval, financial_verification=request.is_pending_financial_verification diff --git a/templates/requests/details.html b/templates/requests/details.html index 2b56398d..3b18d8c9 100644 --- a/templates/requests/details.html +++ b/templates/requests/details.html @@ -18,13 +18,6 @@ {% endcall %} {% endif %} - {% if pending_review %} - {{ Alert('Your request is being reviewed', - message="

    You cannot edit your submitted request while it is under review. Your request will be reviewed within 3 business days.

    ", - level='warning' - ) }} - {% endif %} -

    Request Details


    From 35a1ed5045a7e9f1ae9a4a86c6c0ea104c1ee69a Mon Sep 17 00:00:00 2001 From: richard-dds Date: Fri, 14 Sep 2018 13:48:45 -0400 Subject: [PATCH 27/37] Swap position of FV menu and alert --- templates/requests/financial_verification.html | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/templates/requests/financial_verification.html b/templates/requests/financial_verification.html index 06de0770..1ef6b31f 100644 --- a/templates/requests/financial_verification.html +++ b/templates/requests/financial_verification.html @@ -6,17 +6,15 @@ {% block content %} +{% if request.is_pending_financial_verification %} + {{ Alert('Pending Financial Verification', fragment="fragments/pending_financial_verification.html") }} +{% endif %} {% include 'requests/review_menu.html' %}
    - {% if request.is_pending_financial_verification %} - {{ Alert('Pending Financial Verification', fragment="fragments/pending_financial_verification.html") }} - {% endif %} - - {% if extended %} {{ Alert('Task Order not found in EDA', message="Since the Task Order (TO) number was not found in our system of record, EDA, please populate the additional fields in the form below.", From 96186e2d99d48512a233730d0f84acd44b344863 Mon Sep 17 00:00:00 2001 From: richard-dds Date: Fri, 14 Sep 2018 14:03:48 -0400 Subject: [PATCH 28/37] Show FV alert on request review page --- atst/routes/requests/requests_form.py | 13 ++++++------- templates/requests/details.html | 17 +++++++++++------ templates/requests/review_menu.html | 4 ++-- 3 files changed, 19 insertions(+), 15 deletions(-) diff --git a/atst/routes/requests/requests_form.py b/atst/routes/requests/requests_form.py index 79a1535d..8e14b0e2 100644 --- a/atst/routes/requests/requests_form.py +++ b/atst/routes/requests/requests_form.py @@ -132,6 +132,10 @@ def view_request_details(request_id=None): or request.is_approved or request.is_pending_financial_verification_changes ) + requires_fv_action = ( + request.is_pending_financial_verification + or request.is_pending_financial_verification_changes + ) data = request.body if financial_review and request.task_order: @@ -140,11 +144,6 @@ def view_request_details(request_id=None): return render_template( "requests/details.html", data=data, - request_id=request.id, - status=request.status_displayname, - pending_ccpo_acceptance=request.is_pending_ccpo_acceptance, - pending_ccpo_approval=request.is_pending_ccpo_approval, - financial_verification=request.is_pending_financial_verification - or request.is_pending_financial_verification_changes, - financial_review=financial_review, + request=request, + requires_fv_action=requires_fv_action, ) diff --git a/templates/requests/details.html b/templates/requests/details.html index 3b18d8c9..89bdd105 100644 --- a/templates/requests/details.html +++ b/templates/requests/details.html @@ -5,23 +5,28 @@ {% block content %}
    - {% if financial_verification %} - {% include 'requests/review_menu.html' %} - {% endif %} + {% if request.is_pending_ccpo_acceptance %} - {% if pending_ccpo_acceptance %} {{ Alert('Request submitted. Approval pending.', fragment="fragments/pending_ccpo_acceptance_alert.html") }} - {% elif pending_ccpo_approval %} + + {% elif request.is_pending_ccpo_approval %} + {% call Alert('Pending CCPO Approval') %}

    The CCPO will review and respond to your Financial Verification submission in 3 business days. You will be notified via email or phone.

    Once the financial verification is approved you will be invited to create your JEDI Workspace and set-up your projects. Click here for more details.

    {% endcall %} + + {% elif requires_fv_action %} + + {{ Alert('Pending Financial Verification', fragment="fragments/pending_financial_verification.html") }} + {% include 'requests/review_menu.html' %} + {% endif %}

    Request Details


    -

    #{{ request_id }} {{ status }}

    +

    #{{ request.id }} {{ request.status_displayname }}

    diff --git a/templates/requests/review_menu.html b/templates/requests/review_menu.html index b8546233..f6f36aa0 100644 --- a/templates/requests/review_menu.html +++ b/templates/requests/review_menu.html @@ -1,5 +1,5 @@ -{% set pending_url=url_for('requests.view_request_details', request_id=request_id) %} -{% set financial_url=url_for('requests.financial_verification', request_id=request_id) %} +{% set pending_url=url_for('requests.view_request_details', request_id=request.id) %} +{% set financial_url=url_for('requests.financial_verification', request_id=request.id) %}
    • From 3b2251f8b2989185a8ac502dcc1cf83c0a46b5d4 Mon Sep 17 00:00:00 2001 From: dandds Date: Fri, 14 Sep 2018 13:14:10 -0400 Subject: [PATCH 29/37] display zeroes in the request review template --- templates/requests/_review.html | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/templates/requests/_review.html b/templates/requests/_review.html index d93a7ed2..a1c63b7e 100644 --- a/templates/requests/_review.html +++ b/templates/requests/_review.html @@ -6,8 +6,9 @@
      {{ title | safe }}
      - {% if data[section] and data[section][item_name] %} - {{ data[section][item_name] | findFilter(filter, filter_args) }} + {% set value = data.get(section, {}).get(item_name) %} + {% if value is not none %} + {{ value | findFilter(filter, filter_args) }} {% else %} {{ RequiredLabel() }} {% endif %} From e58013cd721303c8c4f2144a5d0f1c4be81b414c Mon Sep 17 00:00:00 2001 From: richard-dds Date: Mon, 17 Sep 2018 10:04:50 -0400 Subject: [PATCH 30/37] Remove internal notes form --- atst/routes/requests/approval.py | 16 ---------------- templates/requests/approval.html | 18 ------------------ 2 files changed, 34 deletions(-) diff --git a/atst/routes/requests/approval.py b/atst/routes/requests/approval.py index a0f0f5e8..28470b53 100644 --- a/atst/routes/requests/approval.py +++ b/atst/routes/requests/approval.py @@ -12,7 +12,6 @@ from . import requests_bp from atst.domain.requests import Requests from atst.domain.exceptions import NotFoundError from atst.forms.ccpo_review import CCPOReviewForm -from atst.forms.internal_comment import InternalCommentForm def map_ccpo_authorizing(user): @@ -26,8 +25,6 @@ def render_approval(request, form=None): if pending_final_approval and request.task_order: data["task_order"] = request.task_order.to_dictionary() - internal_comment_form = InternalCommentForm(text=request.internal_comments_text) - if not form: mo_data = map_ccpo_authorizing(g.current_user) form = CCPOReviewForm(data=mo_data) @@ -41,7 +38,6 @@ def render_approval(request, form=None): pending_review=pending_review, financial_review=pending_final_approval, f=form or CCPOReviewForm(), - internal_comment_form=internal_comment_form, ) @@ -84,15 +80,3 @@ def task_order_pdf_download(request_id): else: raise NotFoundError("task_order pdf") - - -@requests_bp.route("/requests/internal_comments/", methods=["POST"]) -def create_internal_comment(request_id): - form = InternalCommentForm(http_request.form) - if form.validate(): - request = Requests.get(g.current_user, request_id) - Requests.update_internal_comments(g.current_user, request, form.data["text"]) - - return redirect( - url_for("requests.approval", request_id=request_id, _anchor="ccpo-notes") - ) diff --git a/templates/requests/approval.html b/templates/requests/approval.html index d93a0f1d..5fff0b8a 100644 --- a/templates/requests/approval.html +++ b/templates/requests/approval.html @@ -135,24 +135,6 @@ {% endif %} - -
      - -
      -
      - - {{ internal_comment_form.csrf_token }} - {{ TextInput(internal_comment_form.text, paragraph=True, noMaxWidth=True) }} - -
      -
      - -
      - -
      - -
      -
      From 0d1494ea115d1a81a32605eeb37d82b8b122d640 Mon Sep 17 00:00:00 2001 From: dandds Date: Mon, 17 Sep 2018 10:18:14 -0400 Subject: [PATCH 31/37] create logout endpoint that clears user data from session --- atst/routes/__init__.py | 13 ++++++------- templates/navigation/topbar.html | 2 +- tests/test_auth.py | 31 ++++++++++++++++++++++++++++++- 3 files changed, 37 insertions(+), 9 deletions(-) diff --git a/atst/routes/__init__.py b/atst/routes/__init__.py index fb53802a..cee24c23 100644 --- a/atst/routes/__init__.py +++ b/atst/routes/__init__.py @@ -49,10 +49,9 @@ def login_redirect(): return redirect(url_for(".home")) -def _is_valid_certificate(request): - cert = request.environ.get("HTTP_X_SSL_CLIENT_CERT") - if cert: - result = app.crl_validator.validate(cert.encode()) - return result - else: - return False +@bp.route("/logout") +def logout(): + if session.get("user_id"): + del (session["user_id"]) + + return redirect(url_for(".home")) diff --git a/templates/navigation/topbar.html b/templates/navigation/topbar.html index 4db599f3..35b87473 100644 --- a/templates/navigation/topbar.html +++ b/templates/navigation/topbar.html @@ -17,7 +17,7 @@ {{ Icon('avatar', classes='topbar__link-icon') }} - + {{ Icon('logout', classes='topbar__link-icon') }}
      diff --git a/tests/test_auth.py b/tests/test_auth.py index 2bf24b69..fc551317 100644 --- a/tests/test_auth.py +++ b/tests/test_auth.py @@ -1,3 +1,5 @@ +from urllib.parse import urlparse + import pytest from flask import session, url_for from .mocks import DOD_SDN_INFO, DOD_SDN, FIXTURE_EMAIL_ADDRESS @@ -148,7 +150,6 @@ def test_creates_new_user_on_login(monkeypatch, client): def test_creates_new_user_without_email_on_login(monkeypatch, client): - monkeypatch.setattr("atst.routes._is_valid_certificate", lambda *args: True) cert_file = open("ssl/client-certs/atat.mil.crt").read() # ensure user does not exist @@ -168,3 +169,31 @@ def test_creates_new_user_without_email_on_login(monkeypatch, client): assert user.first_name == DOD_SDN_INFO["first_name"] assert user.last_name == DOD_SDN_INFO["last_name"] assert user.email == None + + +def test_logout(app, client, monkeypatch): + monkeypatch.setattr( + "atst.domain.authnid.AuthenticationContext.authenticate", lambda s: True + ) + monkeypatch.setattr( + "atst.domain.authnid.AuthenticationContext.get_user", + lambda s: UserFactory.create(), + ) + # create a real session + resp = client.get( + url_for("atst.login_redirect"), + environ_base={ + "HTTP_X_SSL_CLIENT_VERIFY": "SUCCESS", + "HTTP_X_SSL_CLIENT_S_DN": DOD_SDN, + "HTTP_X_SSL_CLIENT_CERT": "", + }, + ) + resp_success = client.get(url_for("requests.requests_index")) + # verify session is valid + assert resp_success.status_code == 200 + client.get(url_for("atst.logout")) + resp_failure = client.get(url_for("requests.requests_index")) + # verify that logging out has cleared the session + assert resp_failure.status_code == 302 + destination = urlparse(resp_failure.headers["Location"]).path + assert destination == url_for("atst.root") From 0e8d5f139016f536d17e5ad8fe1157f8a4a15ac1 Mon Sep 17 00:00:00 2001 From: dandds Date: Mon, 17 Sep 2018 10:27:49 -0400 Subject: [PATCH 32/37] some cleanup to auth tests --- tests/test_auth.py | 76 ++++++++++++---------------------------------- 1 file changed, 19 insertions(+), 57 deletions(-) diff --git a/tests/test_auth.py b/tests/test_auth.py index fc551317..c6af8448 100644 --- a/tests/test_auth.py +++ b/tests/test_auth.py @@ -16,6 +16,17 @@ def _fetch_user_info(c, t): return MOCK_USER +def _login(client, verify="SUCCESS", sdn=DOD_SDN, cert=""): + return client.get( + url_for("atst.login_redirect"), + environ_base={ + "HTTP_X_SSL_CLIENT_VERIFY": verify, + "HTTP_X_SSL_CLIENT_S_DN": sdn, + "HTTP_X_SSL_CLIENT_CERT": cert, + }, + ) + + def test_successful_login_redirect_non_ccpo(client, monkeypatch): monkeypatch.setattr( "atst.domain.authnid.AuthenticationContext.authenticate", lambda *args: True @@ -25,14 +36,7 @@ def test_successful_login_redirect_non_ccpo(client, monkeypatch): lambda *args: UserFactory.create(), ) - resp = client.get( - "/login-redirect", - environ_base={ - "HTTP_X_SSL_CLIENT_VERIFY": "SUCCESS", - "HTTP_X_SSL_CLIENT_S_DN": "", - "HTTP_X_SSL_CLIENT_CERT": "", - }, - ) + resp = _login(client) assert resp.status_code == 302 assert "home" in resp.headers["Location"] @@ -49,14 +53,7 @@ def test_successful_login_redirect_ccpo(client, monkeypatch): lambda *args: UserFactory.create(atat_role=role), ) - resp = client.get( - "/login-redirect", - environ_base={ - "HTTP_X_SSL_CLIENT_VERIFY": "SUCCESS", - "HTTP_X_SSL_CLIENT_S_DN": "", - "HTTP_X_SSL_CLIENT_CERT": "", - }, - ) + resp = _login(client) assert resp.status_code == 302 assert "home" in resp.headers["Location"] @@ -64,7 +61,7 @@ def test_successful_login_redirect_ccpo(client, monkeypatch): def test_unsuccessful_login_redirect(client, monkeypatch): - resp = client.get("/login-redirect") + resp = client.get(url_for("atst.login_redirect")) assert resp.status_code == 401 assert "user_id" not in session @@ -101,26 +98,12 @@ def test_crl_validation_on_login(client): bad_cert = open("ssl/client-certs/bad-atat.mil.crt").read() # bad cert is on the test CRL - resp = client.get( - "/login-redirect", - environ_base={ - "HTTP_X_SSL_CLIENT_VERIFY": "SUCCESS", - "HTTP_X_SSL_CLIENT_S_DN": DOD_SDN, - "HTTP_X_SSL_CLIENT_CERT": bad_cert, - }, - ) + resp = _login(client, cert=bad_cert) assert resp.status_code == 401 assert "user_id" not in session # good cert is not on the test CRL, passes - resp = client.get( - "/login-redirect", - environ_base={ - "HTTP_X_SSL_CLIENT_VERIFY": "SUCCESS", - "HTTP_X_SSL_CLIENT_S_DN": DOD_SDN, - "HTTP_X_SSL_CLIENT_CERT": good_cert, - }, - ) + resp = _login(client, cert=good_cert) assert session["user_id"] @@ -134,14 +117,7 @@ def test_creates_new_user_on_login(monkeypatch, client): with pytest.raises(NotFoundError): Users.get_by_dod_id(DOD_SDN_INFO["dod_id"]) - resp = client.get( - "/login-redirect", - environ_base={ - "HTTP_X_SSL_CLIENT_VERIFY": "SUCCESS", - "HTTP_X_SSL_CLIENT_S_DN": DOD_SDN, - "HTTP_X_SSL_CLIENT_CERT": cert_file, - }, - ) + resp = _login(client, cert=cert_file) user = Users.get_by_dod_id(DOD_SDN_INFO["dod_id"]) assert user.first_name == DOD_SDN_INFO["first_name"] @@ -156,14 +132,7 @@ def test_creates_new_user_without_email_on_login(monkeypatch, client): with pytest.raises(NotFoundError): Users.get_by_dod_id(DOD_SDN_INFO["dod_id"]) - resp = client.get( - "/login-redirect", - environ_base={ - "HTTP_X_SSL_CLIENT_VERIFY": "SUCCESS", - "HTTP_X_SSL_CLIENT_S_DN": DOD_SDN, - "HTTP_X_SSL_CLIENT_CERT": cert_file, - }, - ) + resp = _login(client, cert=cert_file) user = Users.get_by_dod_id(DOD_SDN_INFO["dod_id"]) assert user.first_name == DOD_SDN_INFO["first_name"] @@ -180,14 +149,7 @@ def test_logout(app, client, monkeypatch): lambda s: UserFactory.create(), ) # create a real session - resp = client.get( - url_for("atst.login_redirect"), - environ_base={ - "HTTP_X_SSL_CLIENT_VERIFY": "SUCCESS", - "HTTP_X_SSL_CLIENT_S_DN": DOD_SDN, - "HTTP_X_SSL_CLIENT_CERT": "", - }, - ) + resp = _login(client) resp_success = client.get(url_for("requests.requests_index")) # verify session is valid assert resp_success.status_code == 200 From a3e7310e07a3fdfdf72a2f4eee672ce1eea8c7b1 Mon Sep 17 00:00:00 2001 From: richard-dds Date: Mon, 17 Sep 2018 11:35:03 -0400 Subject: [PATCH 33/37] Move alerts below nav menu --- templates/requests/financial_verification.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/templates/requests/financial_verification.html b/templates/requests/financial_verification.html index 1ef6b31f..25a1c0b9 100644 --- a/templates/requests/financial_verification.html +++ b/templates/requests/financial_verification.html @@ -6,12 +6,12 @@ {% block content %} +{% include 'requests/review_menu.html' %} + {% if request.is_pending_financial_verification %} {{ Alert('Pending Financial Verification', fragment="fragments/pending_financial_verification.html") }} {% endif %} -{% include 'requests/review_menu.html' %} -
      From 73d385181348acb63c55c07910557f1edc993e8d Mon Sep 17 00:00:00 2001 From: dandds Date: Fri, 14 Sep 2018 10:40:59 -0400 Subject: [PATCH 34/37] request model knows its most recent review comment --- atst/models/request.py | 10 ++++++++++ tests/models/test_requests.py | 23 +++++++++++++++++++++++ 2 files changed, 33 insertions(+) diff --git a/atst/models/request.py b/atst/models/request.py index de374907..d7436355 100644 --- a/atst/models/request.py +++ b/atst/models/request.py @@ -194,3 +194,13 @@ class Request(Base): @property def is_approved(self): return self.status == RequestStatus.APPROVED + + @property + def review_comment(self): + if ( + self.status == RequestStatus.CHANGES_REQUESTED + or self.status == RequestStatus.CHANGES_REQUESTED_TO_FINVER + ): + review = self.latest_status.review + if review: + return review.comment diff --git a/tests/models/test_requests.py b/tests/models/test_requests.py index 7f5a3650..528d0b06 100644 --- a/tests/models/test_requests.py +++ b/tests/models/test_requests.py @@ -92,3 +92,26 @@ def test_reviews(): RequestStatusEventFactory.create(revision=request.latest_revision), ] assert len(request.reviews) == 2 + + +def test_review_comment(): + request = RequestFactory.create() + ccpo = UserFactory.from_atat_role("ccpo") + request.status_events = [ + RequestStatusEventFactory.create( + revision=request.latest_revision, + new_status=RequestStatus.CHANGES_REQUESTED, + review=RequestReviewFactory.create(reviewer=ccpo, comment="do better"), + ) + ] + assert request.review_comment == "do better" + + request.status_events = [ + RequestStatusEventFactory.create( + revision=request.latest_revision, + new_status=RequestStatus.APPROVED, + review=RequestReviewFactory.create(reviewer=ccpo, comment="much better"), + ) + ] + + assert not request.review_comment From 7f9c7dcaece45021dc2492f791dc5af827290dd7 Mon Sep 17 00:00:00 2001 From: dandds Date: Fri, 14 Sep 2018 11:03:53 -0400 Subject: [PATCH 35/37] display review comment for request that needs changes --- atst/routes/requests/requests_form.py | 1 + templates/requests/_new.html | 8 ++++++++ tests/routes/test_request_new.py | 27 ++++++++++++++++++++++++++- 3 files changed, 35 insertions(+), 1 deletion(-) diff --git a/atst/routes/requests/requests_form.py b/atst/routes/requests/requests_form.py index 8e14b0e2..b0252b86 100644 --- a/atst/routes/requests/requests_form.py +++ b/atst/routes/requests/requests_form.py @@ -62,6 +62,7 @@ def requests_form_update(screen=1, request_id=None): next_screen=screen + 1, request_id=request_id, jedi_request=jedi_flow.request, + review_comment=request.review_comment, can_submit=jedi_flow.can_submit, ) diff --git a/templates/requests/_new.html b/templates/requests/_new.html index da27e795..fcdf1c95 100644 --- a/templates/requests/_new.html +++ b/templates/requests/_new.html @@ -1,11 +1,19 @@ {% extends "base.html" %} +{% from "components/alert.html" import Alert %} + {% block content %}
      {% include 'requests/menu.html' %} + {% if review_comment %} + {{ Alert('Changes Requested', + message="

      CCPO has requested changes to your submission with the following notes:
      " + review_comment + "
      Please contact info@jedi.cloud or 123-123-4567 for further discussion.

      ", + level='warning') }} + {% endif %} + {% block form_action %} {% if request_id %}
      diff --git a/tests/routes/test_request_new.py b/tests/routes/test_request_new.py index b27f4758..9bc8a668 100644 --- a/tests/routes/test_request_new.py +++ b/tests/routes/test_request_new.py @@ -1,5 +1,12 @@ import re -from tests.factories import RequestFactory, UserFactory, RequestRevisionFactory +from tests.factories import ( + RequestFactory, + UserFactory, + RequestRevisionFactory, + RequestStatusEventFactory, + RequestReviewFactory, +) +from atst.models.request_status_event import RequestStatus from atst.domain.roles import Roles from atst.domain.requests import Requests from urllib.parse import urlencode @@ -213,3 +220,21 @@ def test_can_review_data(user_session, client): # assert a sampling of the request data is on the review page assert request.body["primary_poc"]["fname_poc"] in body assert request.body["information_about_you"]["email_request"] in body + + +def test_displays_ccpo_review_comment(user_session, client): + creator = UserFactory.create() + ccpo = UserFactory.from_atat_role("ccpo") + user_session(creator) + request = RequestFactory.create(creator=creator) + review_comment = "add all of the correct info, instead of the incorrect info" + request.status_events = [ + RequestStatusEventFactory.create( + revision=request.latest_revision, + new_status=RequestStatus.CHANGES_REQUESTED, + review=RequestReviewFactory.create(reviewer=ccpo, comment=review_comment), + ) + ] + response = client.get("/requests/new/1/{}".format(request.id)) + body = response.data.decode() + assert review_comment in body From 8359a2a079aabcf2619cacf83a441cfbbfda0201 Mon Sep 17 00:00:00 2001 From: dandds Date: Fri, 14 Sep 2018 11:33:02 -0400 Subject: [PATCH 36/37] display review comment for financial verification that needs changes --- .../routes/requests/financial_verification.py | 1 + templates/requests/_new.html | 6 +---- templates/requests/comment.html | 5 ++++ .../requests/financial_verification.html | 4 +++ tests/routes/test_financial_verification.py | 27 ++++++++++++++++++- 5 files changed, 37 insertions(+), 6 deletions(-) create mode 100644 templates/requests/comment.html diff --git a/atst/routes/requests/financial_verification.py b/atst/routes/requests/financial_verification.py index 0be12e7b..91baaa8c 100644 --- a/atst/routes/requests/financial_verification.py +++ b/atst/routes/requests/financial_verification.py @@ -39,6 +39,7 @@ def financial_verification(request_id=None): "requests/financial_verification.html", f=form, request=request, + review_comment=request.review_comment, extended=is_extended(request), ) diff --git a/templates/requests/_new.html b/templates/requests/_new.html index fcdf1c95..1da2f66f 100644 --- a/templates/requests/_new.html +++ b/templates/requests/_new.html @@ -1,7 +1,5 @@ {% extends "base.html" %} -{% from "components/alert.html" import Alert %} - {% block content %}
      @@ -9,9 +7,7 @@ {% include 'requests/menu.html' %} {% if review_comment %} - {{ Alert('Changes Requested', - message="

      CCPO has requested changes to your submission with the following notes:
      " + review_comment + "
      Please contact info@jedi.cloud or 123-123-4567 for further discussion.

      ", - level='warning') }} + {% include 'requests/comment.html' %} {% endif %} {% block form_action %} diff --git a/templates/requests/comment.html b/templates/requests/comment.html new file mode 100644 index 00000000..9d76e3dd --- /dev/null +++ b/templates/requests/comment.html @@ -0,0 +1,5 @@ +{% from "components/alert.html" import Alert %} + +{{ Alert('Changes Requested', + message="

      CCPO has requested changes to your submission with the following notes:
      " + review_comment + "
      Please contact info@jedi.cloud or 123-123-4567 for further discussion.

      ", + level='warning') }} diff --git a/templates/requests/financial_verification.html b/templates/requests/financial_verification.html index 25a1c0b9..4ae287af 100644 --- a/templates/requests/financial_verification.html +++ b/templates/requests/financial_verification.html @@ -12,6 +12,10 @@ {{ Alert('Pending Financial Verification', fragment="fragments/pending_financial_verification.html") }} {% endif %} +{% if review_comment %} + {% include 'requests/comment.html' %} +{% endif %} +
      diff --git a/tests/routes/test_financial_verification.py b/tests/routes/test_financial_verification.py index 71c38f00..1a2c4606 100644 --- a/tests/routes/test_financial_verification.py +++ b/tests/routes/test_financial_verification.py @@ -3,9 +3,16 @@ import pytest from flask import url_for from atst.eda_client import MockEDAClient +from atst.models.request_status_event import RequestStatus from tests.mocks import MOCK_REQUEST, MOCK_USER -from tests.factories import PENumberFactory, RequestFactory, UserFactory +from tests.factories import ( + PENumberFactory, + RequestFactory, + UserFactory, + RequestStatusEventFactory, + RequestReviewFactory, +) class TestPENumberInForm: @@ -148,3 +155,21 @@ class TestPENumberInForm: response = self.submit_data(client, user, data, extended=True) assert response.status_code == 200 + + +def test_displays_ccpo_review_comment(user_session, client): + creator = UserFactory.create() + ccpo = UserFactory.from_atat_role("ccpo") + user_session(creator) + request = RequestFactory.create(creator=creator) + review_comment = "add all of the correct info, instead of the incorrect info" + request.status_events = [ + RequestStatusEventFactory.create( + revision=request.latest_revision, + new_status=RequestStatus.CHANGES_REQUESTED_TO_FINVER, + review=RequestReviewFactory.create(reviewer=ccpo, comment=review_comment), + ) + ] + response = client.get("/requests/verify/{}".format(request.id)) + body = response.data.decode() + assert review_comment in body From 66ab56e518c9a75f16da5dc15a33de60b94ff70b Mon Sep 17 00:00:00 2001 From: dandds Date: Mon, 17 Sep 2018 09:15:58 -0400 Subject: [PATCH 37/37] use callable form of alert macro for request changes alert --- templates/requests/comment.html | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/templates/requests/comment.html b/templates/requests/comment.html index 9d76e3dd..2558ff90 100644 --- a/templates/requests/comment.html +++ b/templates/requests/comment.html @@ -1,5 +1,9 @@ {% from "components/alert.html" import Alert %} -{{ Alert('Changes Requested', - message="

      CCPO has requested changes to your submission with the following notes:
      " + review_comment + "
      Please contact info@jedi.cloud or 123-123-4567 for further discussion.

      ", - level='warning') }} +{% call Alert('Changes Requested', level='warning') %} +

      CCPO has requested changes to your submission with the following notes: +
      + {{ review_comment }} +
      + Please contact info@jedi.cloud or 123-123-4567 for further discussion.

      +{% endcall %}