diff --git a/atst/routes/task_orders/new.py b/atst/routes/task_orders/new.py index de1d71a5..c6fd2d72 100644 --- a/atst/routes/task_orders/new.py +++ b/atst/routes/task_orders/new.py @@ -5,7 +5,6 @@ from atst.domain.authz.decorator import user_can_access_decorator as user_can from atst.domain.task_orders import TaskOrders from atst.forms.task_order import TaskOrderForm, SignatureForm from atst.models.permissions import Permissions -from atst.utils.flash import formatted_flash as flash def render_task_orders_edit(template, portfolio_id=None, task_order_id=None, form=None): @@ -137,60 +136,3 @@ def confirm_signature(task_order_id): return render_task_orders_edit( "task_orders/step_5.html", task_order_id=task_order_id, form=SignatureForm() ) - - -@task_orders_bp.route("/portfolios//task_orders/new") -@task_orders_bp.route("/task_orders//edit") -@user_can(Permissions.CREATE_TASK_ORDER, message="view new task order form") -def edit(portfolio_id=None, task_order_id=None): - return render_task_orders_edit(portfolio_id, task_order_id) - - -@task_orders_bp.route("/portfolios//task_orders/new", methods=["POST"]) -@task_orders_bp.route("/task_orders/", methods=["POST"]) -@user_can(Permissions.CREATE_TASK_ORDER, message="create new task order") -def update(portfolio_id=None, task_order_id=None): - # TODO: I think saving and incomplete TO and saving a finished one should - # be different routes. It would make the route functions more readable. - form_data = {**http_request.form, **http_request.files} - - form = None - if task_order_id: - task_order = TaskOrders.get(task_order_id) - form = TaskOrderForm(form_data, obj=task_order) - else: - form = TaskOrderForm(form_data) - - if form.validate(): - task_order = None - if task_order_id: - task_order = TaskOrders.update(task_order_id, **form.data) - portfolio_id = task_order.portfolio_id - else: - task_order = TaskOrders.create(g.current_user, portfolio_id, **form.data) - - # TO is finished and user can review and submit - if task_order.is_completed and http_request.args.get("review"): - return redirect( - url_for("task_orders.review_task_order", task_order_id=task_order.id) - ) - # User is trying to review and submit but the TO is not finished - elif http_request.args.get("review"): - return ( - render_task_orders_edit( - "task_orders/step_1.html", portfolio_id, task_order_id, form - ), - 400, - ) - # User is saving valid but incomplete TO state - else: - flash("task_order_draft") - return redirect(url_for("task_orders.edit", task_order_id=task_order.id)) - - else: - return ( - render_task_orders_edit( - "task_orders/step_1.html", portfolio_id, task_order_id, form - ), - 400, - ) diff --git a/templates/portfolios/header.html b/templates/portfolios/header.html index 36b1adca..46159a63 100644 --- a/templates/portfolios/header.html +++ b/templates/portfolios/header.html @@ -27,7 +27,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.edit", "task_orders.update"], + active=request.url_rule.endpoint in ["task_orders.portfolio_funding", "task_orders.review_task_order", "task_orders.add_pdf", "task_orders.upload_pdf", "task_orders.add_number", "task_orders.update_number", "task_orders.add_clins", "task_orders.update_clins", "task_orders.review", "task_orders.confirm_signature"], ) }} {{ Link( icon='applications', diff --git a/templates/portfolios/task_orders/index.html b/templates/portfolios/task_orders/index.html index 975b5286..ed8a776b 100644 --- a/templates/portfolios/task_orders/index.html +++ b/templates/portfolios/task_orders/index.html @@ -13,7 +13,7 @@ {% endmacro %} {% macro TaskOrderEditButton(task_order, text="Edit", secondary=False) %} - + {{ text }} {% endmacro %} @@ -111,7 +111,7 @@ {{ EmptyState( 'This portfolio doesn’t have any active or pending task orders.', action_label='Add a New Task Order', - action_href=url_for('task_orders.edit', portfolio_id=portfolio.id), + action_href=url_for('task_orders.add_pdf', portfolio_id=portfolio.id), icon='cloud', add_perms=user_can(permissions.CREATE_TASK_ORDER) ) }} diff --git a/templates/task_orders/edit.html b/templates/task_orders/edit.html deleted file mode 100644 index 4966993d..00000000 --- a/templates/task_orders/edit.html +++ /dev/null @@ -1,443 +0,0 @@ -{% extends "portfolios/base.html" %} - -{% from 'components/date_picker.html' import DatePicker %} -{% from 'components/icon.html' import Icon %} -{% from 'components/options_input.html' import OptionsInput %} -{% from 'components/save_button.html' import SaveButton %} -{% from "components/semi_collapsible_text.html" import SemiCollapsibleText %} -{% from "components/sticky_cta.html" import StickyCTA %} -{% from 'components/text_input.html' import TextInput %} -{% from "components/totals_box.html" import TotalsBox %} -{% from 'components/upload_input.html' import UploadInput %} - -{% macro LOAInput() %} -
- -
- - - - - - - -
-
-
- - - -{% endmacro %} - -{% macro CLINFields(fields, index) %} - {% if index != 0 %} -
- {% endif %} - - -
-
-
- {{ OptionsInput(fields.jedi_clin_type, watch=True) }} -
-
- {{ TextInput(fields.number, watch=True) }} -
-
- -
-
- -
- {{ 'task_orders.form.loa_label' | translate }} -
-
- {% for loa in fields.loas %} - {{ TextInput(loa, showLabel=False, watch=True) }} - {% endfor %} - - {{ LOAInput() }} -
-
- - {{ DatePicker(fields.start_date, watch=True, optional=False) }} - {{ DatePicker(fields.end_date, watch=True, optional=False) }} - {{ TextInput(fields.obligated_amount, validation='dollars', watch=True) }} -
-
-{% endmacro %} - -{% block portfolio_content %} - {% if task_order_id %} - {% set action = url_for("task_orders.update", task_order_id=task_order_id) %} - {% set review_action = url_for("task_orders.update", task_order_id=task_order_id, review=True) %} - {% else %} - {% set action = url_for("task_orders.update", portfolio_id=portfolio.id) %} - {% set review_action = url_for("task_orders.update", portfolio_id=portfolio.id, review=True) %} - {% endif %} -
- {{ form.csrf_token }} - - {% set obligated = task_order.total_obligated_funds if task_order else 0 %} - {% set total = task_order.total_contract_amount if task_order else 0 %} - - -
- {% call StickyCTA(text=('task_orders.form.sticky_header_text' | translate )) %} - - - - - {{ "common.cancel" | translate }} - - - {% endcall %} - -
-

- {{ "task_orders.new.form_help_text" | translate }} -

- -
- - {% include "fragments/flash.html" %} - -
-
-
{{ 'task_orders.form.add_to_header' | translate }}
- {{ TextInput(form.number, validation='taskOrderNumber', optional=False) }} - -
- -
{{ 'task_orders.form.cloud_funding_header' | translate }}
-
- {{ 'task_orders.form.cloud_funding_text' | translate }} -
- - {% for clin in form.clins %} - {{ CLINFields(clin, index=loop.index - 1) }} - {% endfor %} - -
-
- -
-
-
- -
-
- -
- {{ 'task_orders.form.clin_type_label' | translate }} -
-
- -
-
-
-
-
- -
- - - - - - - - - -
-
- -
-
- -
-
- -
- {{ 'task_orders.form.loa_label' | translate }} -
-
- {{ LOAInput() }} -
-
- - -
- -
- {{ 'task_orders.form.pop_start' | translate }} -
-
- -
- - -
- - -
- -
- - -
- -
- - - -
- -
- {{ Icon("ok", classes="icon--green") }} -
-
-
-
- - -
- -
- {{ 'task_orders.form.pop_end' | translate }} -
-
- -
- - -
- - -
- -
- - -
- -
- - - -
- -
- {{ Icon("ok", classes="icon--green") }} -
-
-
-
- - -
- - - - - - - - - -
-
-
-
-
- - - -
-
{{ 'task_orders.form.supporting_docs_header' | translate }}
-
- {{ 'task_orders.form.supporting_docs_text' | translate }} {{ Icon('question')}} -
- {{ UploadInput(form.pdf, watch=True) }} -
- - -
-
{{ 'components.totals_box.obligated_funds' | translate }}
-
-
{{ 'components.totals_box.obligated_text' | translate }}
- -
- -
{{ 'components.totals_box.total_amount' | translate }}
-
-
{{ 'components.totals_box.total_text' | translate }}
-
-
- -
- -
-
-
-
- -{% endblock %} diff --git a/tests/routes/task_orders/test_new.py b/tests/routes/task_orders/test_new.py index fdf9a987..1107c16c 100644 --- a/tests/routes/task_orders/test_new.py +++ b/tests/routes/task_orders/test_new.py @@ -115,29 +115,9 @@ def test_task_orders_confirm_signature(client, user_session, task_order): assert response.status_code == 200 -def test_task_orders_new_flow(): - pass - - -def test_task_orders_save_incomplete(client, user_session, portfolio): - user_session(portfolio.owner) - form_data = { - "number": "0123456789", - "clins-0-jedi_clin_type": "JEDI_CLIN_1", - "clins-0-clin_number": "12312", - } - response = client.post( - url_for("task_orders.update", portfolio_id=portfolio.id), data=form_data - ) - assert response.status_code == 302 - task_order = portfolio.task_orders[0] - expected_url = url_for( - "task_orders.edit", task_order_id=task_order.id, _external=True - ) - assert response.location == expected_url - - -def test_task_orders_add_pdf_existing_to(client, user_session, task_order): +def test_task_orders_form_step_one_add_pdf_existing_to( + client, user_session, task_order +): user_session(task_order.creator) response = client.get(url_for("task_orders.add_pdf", task_order_id=task_order.id)) assert response.status_code == 200 @@ -158,6 +138,17 @@ def test_task_orders_upload_pdf_existing_to( assert task_order.pdf.filename == pdf_upload2.filename +def test_task_orders_upload_pdf_delete_pdf(client, user_session, portfolio, pdf_upload): + user_session(portfolio.owner) + task_order = TaskOrderFactory.create(pdf=pdf_upload, portfolio=portfolio) + data = {"pdf": ""} + response = client.post( + url_for("task_orders.upload_pdf", task_order_id=task_order.id), data=data + ) + assert task_order.pdf is None + assert response.status_code == 302 + + def test_task_orders_update_number_existing_to(client, user_session, task_order): user_session(task_order.creator) form_data = {"number": "0000000000"} @@ -210,24 +201,6 @@ def test_task_orders_update_clins_existing_to(client, user_session, task_order): assert len(task_order.clins) == 1 -def test_task_orders_update_existing_to(client, user_session, task_order): - user_session(task_order.creator) - form_data = { - "number": "0123456789", - "clins-0-jedi_clin_type": "JEDI_CLIN_1", - "clins-0-number": "12312", - "clins-0-start_date": "01/01/2020", - "clins-0-end_date": "01/01/2021", - "clins-0-obligated_amount": "5000", - "clins-0-loas-0": "123123123123", - } - response = client.post( - url_for("task_orders.update", task_order_id=task_order.id), data=form_data - ) - assert response.status_code == 302 - assert task_order.number == "0123456789" - - @pytest.mark.skip(reason="Reevaluate how form handles invalid data") def test_task_orders_update_invalid_data(client, user_session, portfolio): user_session(portfolio.owner) @@ -240,41 +213,7 @@ def test_task_orders_update_invalid_data(client, user_session, portfolio): assert "There were some errors" in response.data.decode() -def test_task_orders_update(client, user_session, portfolio, pdf_upload): - user_session(portfolio.owner) - data = {"number": "0123456789", "pdf": pdf_upload} - task_order = TaskOrderFactory.create(number="0987654321", portfolio=portfolio) - response = client.post( - url_for("task_orders.update", task_order_id=task_order.id), data=data - ) - assert task_order.number == data["number"] - assert response.status_code == 302 - - -def test_task_orders_update_pdf( - client, user_session, portfolio, pdf_upload, pdf_upload2 -): - user_session(portfolio.owner) - task_order = TaskOrderFactory.create(pdf=pdf_upload, portfolio=portfolio) - data = {"number": "0123456789", "pdf": pdf_upload2} - response = client.post( - url_for("task_orders.update", task_order_id=task_order.id), data=data - ) - assert task_order.pdf.filename == pdf_upload2.filename - assert response.status_code == 302 - - -def test_task_orders_update_delete_pdf(client, user_session, portfolio, pdf_upload): - user_session(portfolio.owner) - task_order = TaskOrderFactory.create(pdf=pdf_upload, portfolio=portfolio) - data = {"number": "0123456789", "pdf": ""} - response = client.post( - url_for("task_orders.update", task_order_id=task_order.id), data=data - ) - assert task_order.pdf is None - assert response.status_code == 302 - - +@pytest.mark.skip(reason="Reevaluate if user can see review page w/ incomplete TO") def test_cannot_get_to_review_screen_with_incomplete_data( client, user_session, portfolio ): diff --git a/tests/test_access.py b/tests/test_access.py index c0e523d6..25dd7562 100644 --- a/tests/test_access.py +++ b/tests/test_access.py @@ -448,30 +448,67 @@ def test_task_orders_download_task_order_pdf_access(get_url_assert_status, monke get_url_assert_status(rando, url, 404) -# task_orders.update -def test_task_orders_update_access(post_url_assert_status): +# task_orders.add_pdf +# task_orders.add_number +# task_orders.add_clins +# task_orders.review +# task_orders.confirm_signature +def test_task_orders_new_get_routes(get_url_assert_status): + get_routes = [ + "task_orders.add_pdf", + "task_orders.add_number", + "task_orders.add_clins", + "task_orders.review", + "task_orders.confirm_signature", + ] + ccpo = user_with(PermissionSets.EDIT_PORTFOLIO_FUNDING) owner = user_with() rando = user_with() + portfolio = PortfolioFactory.create(owner=owner) - data = {"number": 1234567890} + task_order = TaskOrderFactory.create(portfolio=portfolio, creator=owner) - url = url_for("task_orders.update", portfolio_id=portfolio.id) - post_url_assert_status(owner, url, 302, data=data) - post_url_assert_status(ccpo, url, 302, data=data) - post_url_assert_status(rando, url, 404, data=data) + for route in get_routes: + url = url_for(route, task_order_id=task_order.id) - task_order = TaskOrderFactory.create(portfolio=portfolio) + get_url_assert_status(ccpo, url, 200) + get_url_assert_status(owner, url, 200) + get_url_assert_status(rando, url, 404) - url = url_for("task_orders.update", task_order_id=task_order.id) - post_url_assert_status(owner, url, 302, data=data) - post_url_assert_status(ccpo, url, 302, data=data) - post_url_assert_status(rando, url, 404, data=data) - url = url_for("task_orders.update", portfolio_id=portfolio.id) - post_url_assert_status(owner, url, 302, data=data) - post_url_assert_status(ccpo, url, 302, data=data) - post_url_assert_status(rando, url, 404, data=data) +# task_orders.upload_pdf +# task_orders.update_number +# task_orders.update_clins +def test_task_orders_new_post_routes(post_url_assert_status): + post_routes = [ + ("task_orders.upload_pdf", {"pdf": ""}), + ("task_orders.update_number", {"number": "1234567890"}), + ( + "task_orders.update_clins", + { + "clins-0-jedi_clin_type": "JEDI_CLIN_1", + "clins-0-clin_number": "12312", + "clins-0-start_date": "01/01/2020", + "clins-0-end_date": "01/01/2021", + "clins-0-obligated_amount": "5000", + "clins-0-loas-0": "123123123123", + }, + ), + ] + + ccpo = user_with(PermissionSets.EDIT_PORTFOLIO_FUNDING) + owner = user_with() + rando = user_with() + + portfolio = PortfolioFactory.create(owner=owner) + task_order = TaskOrderFactory.create(portfolio=portfolio, creator=owner) + + for route, data in post_routes: + url = url_for(route, task_order_id=task_order.id) + post_url_assert_status(owner, url, 302, data=data) + post_url_assert_status(ccpo, url, 302, data=data) + post_url_assert_status(rando, url, 404, data=data) def test_applications_application_team_access(get_url_assert_status):