diff --git a/atst/routes/task_orders/new.py b/atst/routes/task_orders/new.py index 864e6010..428eddd5 100644 --- a/atst/routes/task_orders/new.py +++ b/atst/routes/task_orders/new.py @@ -1,4 +1,4 @@ -from flask import g, render_template, request as http_request +from flask import g, redirect, render_template, request as http_request, url_for from . import task_orders_bp from atst.domain.authz.decorator import user_can_access_decorator as user_can @@ -11,7 +11,14 @@ from atst.utils.flash import formatted_flash as flash @task_orders_bp.route("/portfolios//task_orders/new") @user_can(Permissions.CREATE_TASK_ORDER, message="view new task order form") def new(portfolio_id): - return render_template("task_orders/new.html", form=TaskOrderForm()) + cancel_url = ( + http_request.referrer + if http_request.referrer + else url_for("task_orders.portfolio_funding", portfolio_id=portfolio_id) + ) + return render_template( + "task_orders/new.html", form=TaskOrderForm(), cancel_url=cancel_url + ) @task_orders_bp.route("/portfolios//task_orders/new", methods=["POST"]) @@ -19,22 +26,32 @@ def new(portfolio_id): def create(portfolio_id): form_data = http_request.form form = TaskOrderForm(form_data) - + # todo: add in better error handling for dupe TO numbers if form.validate(): - TaskOrders.create(g.current_user, portfolio_id, **form.data) + task_order = TaskOrders.create(g.current_user, portfolio_id, **form.data) flash("task_order_draft") - return render_template("task_orders/new.html", form=form) + return redirect( + url_for( + "task_orders.edit", + portfolio_id=portfolio_id, + task_order_id=task_order.id, + ) + ) else: flash("form_errors") return render_template("task_orders/new.html", form=form) +# Combine with new route? @task_orders_bp.route("/portfolios//task_orders//edit") @user_can(Permissions.CREATE_TASK_ORDER, message="update task order") -def edit(portfolio_id, taks_order_id): - return render_template("task_orders/edit", form=TaskOrderForm()) +def edit(portfolio_id, task_order_id): + task_order = TaskOrders.get(task_order_id) + form = TaskOrderForm(number=task_order.number) + return render_template("task_orders/edit.html", form=form) +# Combine with create route? @task_orders_bp.route( "/portfolios//task_orders/", methods=["POST"] ) @@ -49,4 +66,4 @@ def update(portfolio_id, task_order_id=None): return render_template("task_orders/new.html", form=form) else: flash("form_errors") - return render_template("task_orders/new.html", form=form) + return render_template("task_orders/edit.html", form=form) diff --git a/js/lib/input_validations.js b/js/lib/input_validations.js index 3a2fcd18..377af19f 100644 --- a/js/lib/input_validations.js +++ b/js/lib/input_validations.js @@ -9,36 +9,6 @@ export default { unmask: [], validationError: 'Please enter a response', }, - requiredField: { - mask: false, - match: /.+/, - unmask: [], - validationError: 'This field is required', - }, - integer: { - mask: createNumberMask({ prefix: '', allowDecimal: false }), - match: /^[1-9]\d*$/, - unmask: [','], - validationError: 'Please enter a number', - }, - dollars: { - mask: createNumberMask({ prefix: '$', allowDecimal: true }), - match: /^-?\d+\.?\d*$/, - unmask: ['$', ','], - validationError: 'Please enter a dollar amount', - }, - gigabytes: { - mask: createNumberMask({ prefix: '', suffix: ' GB', allowDecimal: false }), - match: /^[1-9]\d*$/, - unmask: [',', ' GB'], - validationError: 'Please enter an amount of data in gigabytes', - }, - email: { - mask: emailMask, - match: /^.+@[^.].*\.[a-z]{2,10}$/, - unmask: [], - validationError: 'Please enter a valid e-mail address', - }, date: { mask: [/\d/, /\d/, '/', /\d/, /\d/, '/', /\d/, /\d/, /\d/, /\d/], match: /(0[1-9]|1[012])[- \/.](0[1-9]|[12][0-9]|3[01])[- \/.](19|20)\d\d/, @@ -47,6 +17,65 @@ export default { keepCharPositions: true, validationError: 'Please enter a valid date in the form MM/DD/YYYY', }, + dodId: { + mask: createNumberMask({ + prefix: '', + allowDecimal: false, + allowLeadingZeroes: true, + includeThousandsSeparator: false, + }), + match: /^\d{10}$/, + unmask: [], + validationError: 'Please enter a 10-digit DoD ID number', + }, + dollars: { + mask: createNumberMask({ prefix: '$', allowDecimal: true }), + match: /^-?\d+\.?\d*$/, + unmask: ['$', ','], + validationError: 'Please enter a dollar amount', + }, + email: { + mask: emailMask, + match: /^.+@[^.].*\.[a-z]{2,10}$/, + unmask: [], + validationError: 'Please enter a valid e-mail address', + }, + integer: { + mask: createNumberMask({ prefix: '', allowDecimal: false }), + match: /^[1-9]\d*$/, + unmask: [','], + validationError: 'Please enter a number', + }, + phoneExt: { + mask: createNumberMask({ + prefix: '', + allowDecimal: false, + integerLimit: 10, + allowLeadingZeroes: true, + includeThousandsSeparator: false, + }), + match: /^\d{0,10}$/, + unmask: [], + validationError: 'Optional: Please enter up to 10 digits', + }, + portfolioName: { + mask: false, + match: /^.{4,100}$/, + unmask: [], + validationError: 'Portfolio names can be between 4-100 characters', + }, + requiredField: { + mask: false, + match: /.+/, + unmask: [], + validationError: 'This field is required', + }, + taskOrderNumber: { + mask: false, + match: /^.{10}$/, + unmask: [], + validationError: 'TO number must be 10 digits', + }, usPhone: { mask: [ '(', @@ -68,59 +97,4 @@ export default { unmask: ['(', ')', '-', ' '], validationError: 'Please enter a 10-digit phone number', }, - phoneExt: { - mask: createNumberMask({ - prefix: '', - allowDecimal: false, - integerLimit: 10, - allowLeadingZeroes: true, - includeThousandsSeparator: false, - }), - match: /^\d{0,10}$/, - unmask: [], - validationError: 'Optional: Please enter up to 10 digits', - }, - dodId: { - mask: createNumberMask({ - prefix: '', - allowDecimal: false, - allowLeadingZeroes: true, - includeThousandsSeparator: false, - }), - match: /^\d{10}$/, - unmask: [], - validationError: 'Please enter a 10-digit DoD ID number', - }, - peNumber: { - mask: false, - match: /(0\d)(0\d)(\d{3})([a-z,A-Z]{1,3})/, - unmask: ['_'], - validationError: - 'Please enter a valid PE number. Note that it should be 7 digits followed by 1-3 letters, and should have a zero as the first and third digits.', - }, - treasuryCode: { - mask: createNumberMask({ - prefix: '', - allowDecimal: false, - allowLeadingZeroes: true, - includeThousandsSeparator: false, - }), - match: /^0*([1-9]{4}|[1-9]{6})$/, - unmask: [], - validationError: - 'Please enter a valid Program Treasury Code. Note that it should be a four digit or six digit number, optionally prefixed by one or more zeros.', - }, - baCode: { - mask: false, - match: /[0-9]{2}\w?$/, - unmask: [], - validationError: - 'Please enter a valid BA Code. Note that it should be two digits, followed by an optional letter.', - }, - portfolioName: { - mask: false, - match: /^.{4,100}$/, - unmask: [], - validationError: 'Portfolio names can be between 4-100 characters', - }, } diff --git a/templates/task_orders/edit.html b/templates/task_orders/edit.html index e69de29b..a856925b 100644 --- a/templates/task_orders/edit.html +++ b/templates/task_orders/edit.html @@ -0,0 +1,30 @@ +{% extends "base.html" %} + +{% from 'components/save_button.html' import SaveButton %} +{% from 'components/text_input.html' import TextInput %} + +{% block content %} +
+ {% include "fragments/flash.html" %} +
+ {% block portfolio_header %} + {% include "portfolios/header.html" %} + {% endblock %} + +
+ {{ form.csrf_token }} +
+ + Add Funding + {{ SaveButton(text=('common.save' | translate), element='input', form='new-task-order') }} +
+
+ {{ "task_orders.new.form_help_text" | translate }} +
+ {{ TextInput(form.number, validation='taskOrderNumber') }} +
+
+
+
+
+{% endblock %} diff --git a/templates/task_orders/new.html b/templates/task_orders/new.html index 41c6e5bc..43b96c23 100644 --- a/templates/task_orders/new.html +++ b/templates/task_orders/new.html @@ -16,12 +16,18 @@
Add Funding + + + {{ "common.cancel" | translate }} + {{ SaveButton(text=('common.save' | translate), element='input', form='new-task-order') }}
{{ "task_orders.new.form_help_text" | translate }}
- {{ TextInput(form.number) }} + {{ TextInput(form.number, validation='taskOrderNumber') }}
diff --git a/tests/routes/task_orders/test_new.py b/tests/routes/task_orders/test_new.py index 9760f26f..6ac1df4a 100644 --- a/tests/routes/task_orders/test_new.py +++ b/tests/routes/task_orders/test_new.py @@ -45,8 +45,18 @@ def test_task_orders_create(client, user_session, portfolio): url_for("task_orders.create", portfolio_id=portfolio.id), data={"number": "0123456789"}, ) + assert response.status_code == 302 + + +def test_task_orders_create_invalid_data(client, user_session, portfolio): + user_session(portfolio.owner) + num_task_orders = len(portfolio.task_orders) + response = client.post( + url_for("task_orders.create", portfolio_id=portfolio.id), data={"number": ""} + ) assert response.status_code == 200 - assert translate("task_orders.form.draft_alert_message") in response.data.decode() + assert num_task_orders == len(portfolio.task_orders) + assert "There were some errors" in response.data.decode() def test_task_orders_edit():