Update atst to atat
This commit is contained in:
4
atat/routes/task_orders/__init__.py
Normal file
4
atat/routes/task_orders/__init__.py
Normal file
@@ -0,0 +1,4 @@
|
||||
from . import index
|
||||
from . import new
|
||||
from . import downloads
|
||||
from .blueprint import task_orders_bp
|
5
atat/routes/task_orders/blueprint.py
Normal file
5
atat/routes/task_orders/blueprint.py
Normal file
@@ -0,0 +1,5 @@
|
||||
from flask import Blueprint
|
||||
from atat.utils.context_processors import portfolio as portfolio_context_processor
|
||||
|
||||
task_orders_bp = Blueprint("task_orders", __name__)
|
||||
task_orders_bp.context_processor(portfolio_context_processor)
|
27
atat/routes/task_orders/downloads.py
Normal file
27
atat/routes/task_orders/downloads.py
Normal file
@@ -0,0 +1,27 @@
|
||||
from flask import Response, current_app as app
|
||||
|
||||
from .blueprint import task_orders_bp
|
||||
from atat.domain.task_orders import TaskOrders
|
||||
from atat.domain.exceptions import NotFoundError
|
||||
from atat.domain.authz.decorator import user_can_access_decorator as user_can
|
||||
from atat.models.permissions import Permissions
|
||||
|
||||
|
||||
def send_file(attachment):
|
||||
generator = app.csp.files.download(attachment.object_name)
|
||||
return Response(
|
||||
generator,
|
||||
headers={
|
||||
"Content-Disposition": "attachment; filename={}".format(attachment.filename)
|
||||
},
|
||||
)
|
||||
|
||||
|
||||
@task_orders_bp.route("/task_orders/<task_order_id>/pdf")
|
||||
@user_can(Permissions.VIEW_TASK_ORDER_DETAILS, message="download task order PDF")
|
||||
def download_task_order_pdf(task_order_id):
|
||||
task_order = TaskOrders.get(task_order_id)
|
||||
if task_order.pdf:
|
||||
return send_file(task_order.pdf)
|
||||
else:
|
||||
raise NotFoundError("task_order pdf")
|
35
atat/routes/task_orders/index.py
Normal file
35
atat/routes/task_orders/index.py
Normal file
@@ -0,0 +1,35 @@
|
||||
from flask import g, render_template, url_for, redirect
|
||||
|
||||
from .blueprint import task_orders_bp
|
||||
from atat.domain.authz.decorator import user_can_access_decorator as user_can
|
||||
from atat.domain.portfolios import Portfolios
|
||||
from atat.domain.task_orders import TaskOrders
|
||||
from atat.forms.task_order import SignatureForm
|
||||
from atat.models import Permissions
|
||||
|
||||
|
||||
@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/view.html",
|
||||
task_order=task_order,
|
||||
signature_form=signature_form,
|
||||
)
|
||||
|
||||
|
||||
@task_orders_bp.route("/portfolios/<portfolio_id>/task_orders")
|
||||
@user_can(Permissions.VIEW_PORTFOLIO_FUNDING, message="view portfolio funding")
|
||||
def portfolio_funding(portfolio_id):
|
||||
portfolio = Portfolios.get(g.current_user, portfolio_id)
|
||||
task_orders = TaskOrders.sort_by_status(portfolio.task_orders)
|
||||
to_count = len(portfolio.task_orders)
|
||||
# TODO: Get expended amount from the CSP
|
||||
return render_template(
|
||||
"task_orders/index.html", task_orders=task_orders, to_count=to_count
|
||||
)
|
311
atat/routes/task_orders/new.py
Normal file
311
atat/routes/task_orders/new.py
Normal file
@@ -0,0 +1,311 @@
|
||||
from flask import (
|
||||
g,
|
||||
redirect,
|
||||
render_template,
|
||||
request as http_request,
|
||||
url_for,
|
||||
current_app as app,
|
||||
jsonify,
|
||||
)
|
||||
|
||||
from .blueprint import task_orders_bp
|
||||
from atat.domain.authz.decorator import user_can_access_decorator as user_can
|
||||
from atat.domain.exceptions import NoAccessError, AlreadyExistsError
|
||||
from atat.domain.task_orders import TaskOrders
|
||||
from atat.forms.task_order import TaskOrderForm, SignatureForm
|
||||
from atat.models.permissions import Permissions
|
||||
from atat.utils.flash import formatted_flash as flash
|
||||
|
||||
|
||||
def render_task_orders_edit(
|
||||
template, portfolio_id=None, task_order_id=None, form=None, extra_args=None
|
||||
):
|
||||
render_args = extra_args or {}
|
||||
|
||||
render_args["contract_start"] = app.config.get("CONTRACT_START_DATE")
|
||||
render_args["contract_end"] = app.config.get("CONTRACT_END_DATE")
|
||||
render_args["file_size_limit"] = int(app.config.get("FILE_SIZE_LIMIT"))
|
||||
|
||||
if task_order_id:
|
||||
task_order = TaskOrders.get(task_order_id)
|
||||
portfolio_id = task_order.portfolio_id
|
||||
render_args["form"] = form or TaskOrderForm(obj=task_order)
|
||||
render_args["task_order_id"] = task_order_id
|
||||
render_args["task_order"] = task_order
|
||||
else:
|
||||
render_args["form"] = form or TaskOrderForm()
|
||||
|
||||
render_args["cancel_save_url"] = url_for(
|
||||
"task_orders.cancel_edit",
|
||||
task_order_id=task_order_id,
|
||||
portfolio_id=portfolio_id,
|
||||
save=True,
|
||||
)
|
||||
render_args["cancel_discard_url"] = url_for(
|
||||
"task_orders.cancel_edit",
|
||||
task_order_id=task_order_id,
|
||||
portfolio_id=portfolio_id,
|
||||
save=False,
|
||||
)
|
||||
|
||||
return render_template(template, **render_args)
|
||||
|
||||
|
||||
def update_task_order(form, portfolio_id=None, task_order_id=None, flash_invalid=True):
|
||||
if form.validate(flash_invalid=flash_invalid):
|
||||
task_order = None
|
||||
try:
|
||||
if task_order_id:
|
||||
task_order = TaskOrders.update(task_order_id, **form.data)
|
||||
portfolio_id = task_order.portfolio_id
|
||||
else:
|
||||
task_order = TaskOrders.create(portfolio_id, **form.data)
|
||||
|
||||
return task_order
|
||||
|
||||
except AlreadyExistsError:
|
||||
flash("task_order_number_error", to_number=form.data["number"])
|
||||
return False
|
||||
else:
|
||||
return False
|
||||
|
||||
|
||||
def update_and_render_next(
|
||||
form_data,
|
||||
next_page,
|
||||
current_template,
|
||||
portfolio_id=None,
|
||||
task_order_id=None,
|
||||
previous=False,
|
||||
):
|
||||
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)
|
||||
|
||||
task_order = update_task_order(
|
||||
form, portfolio_id, task_order_id, flash_invalid=(not previous)
|
||||
)
|
||||
if task_order or previous:
|
||||
to_id = task_order.id if task_order else task_order_id
|
||||
return redirect(url_for(next_page, task_order_id=to_id))
|
||||
else:
|
||||
return (
|
||||
render_task_orders_edit(
|
||||
current_template, portfolio_id, task_order_id, form
|
||||
),
|
||||
400,
|
||||
)
|
||||
|
||||
|
||||
@task_orders_bp.route("/task_orders/<portfolio_id>/upload_token")
|
||||
@user_can(Permissions.CREATE_TASK_ORDER, message="edit task order form")
|
||||
def upload_token(portfolio_id):
|
||||
(token, object_name) = app.csp.files.get_token()
|
||||
render_args = {"token": token, "objectName": object_name}
|
||||
|
||||
return jsonify(render_args)
|
||||
|
||||
|
||||
@task_orders_bp.route("/task_orders/<portfolio_id>/download_link")
|
||||
@user_can(Permissions.VIEW_TASK_ORDER_DETAILS, message="view task order download link")
|
||||
def download_link(portfolio_id):
|
||||
filename = http_request.args.get("filename")
|
||||
object_name = http_request.args.get("objectName")
|
||||
render_args = {
|
||||
"downloadLink": app.csp.files.generate_download_link(object_name, filename)
|
||||
}
|
||||
|
||||
return jsonify(render_args)
|
||||
|
||||
|
||||
@task_orders_bp.route("/task_orders/<task_order_id>/edit")
|
||||
@user_can(Permissions.CREATE_TASK_ORDER, message="edit task order form")
|
||||
def edit(task_order_id):
|
||||
task_order = TaskOrders.get(task_order_id)
|
||||
|
||||
if not task_order.pdf:
|
||||
return redirect(
|
||||
url_for("task_orders.form_step_one_add_pdf", task_order_id=task_order_id)
|
||||
)
|
||||
elif not task_order.number:
|
||||
return redirect(
|
||||
url_for("task_orders.form_step_two_add_number", task_order_id=task_order_id)
|
||||
)
|
||||
elif not task_order.clins_are_completed:
|
||||
return redirect(
|
||||
url_for(
|
||||
"task_orders.form_step_three_add_clins", task_order_id=task_order_id
|
||||
)
|
||||
)
|
||||
elif task_order.is_completed:
|
||||
return redirect(
|
||||
url_for("task_orders.form_step_four_review", task_order_id=task_order_id)
|
||||
)
|
||||
else:
|
||||
return redirect(
|
||||
url_for("task_orders.form_step_one_add_pdf", task_order_id=task_order_id)
|
||||
)
|
||||
|
||||
|
||||
@task_orders_bp.route("/portfolios/<portfolio_id>/task_orders/form/step_1")
|
||||
@task_orders_bp.route("/task_orders/<task_order_id>/form/step_1")
|
||||
@user_can(Permissions.CREATE_TASK_ORDER, message="view task order form")
|
||||
def form_step_one_add_pdf(portfolio_id=None, task_order_id=None):
|
||||
return render_task_orders_edit(
|
||||
"task_orders/step_1.html",
|
||||
portfolio_id=portfolio_id,
|
||||
task_order_id=task_order_id,
|
||||
)
|
||||
|
||||
|
||||
@task_orders_bp.route(
|
||||
"/portfolios/<portfolio_id>/task_orders/form/step-1", methods=["POST"]
|
||||
)
|
||||
@task_orders_bp.route("/task_orders/<task_order_id>/form/step_1", methods=["POST"])
|
||||
@user_can(Permissions.CREATE_TASK_ORDER, message="update task order form")
|
||||
def submit_form_step_one_add_pdf(portfolio_id=None, task_order_id=None):
|
||||
form_data = {**http_request.form}
|
||||
next_page = "task_orders.form_step_two_add_number"
|
||||
current_template = "task_orders/step_1.html"
|
||||
|
||||
return update_and_render_next(
|
||||
form_data,
|
||||
next_page,
|
||||
current_template,
|
||||
portfolio_id=portfolio_id,
|
||||
task_order_id=task_order_id,
|
||||
)
|
||||
|
||||
|
||||
@task_orders_bp.route(
|
||||
"/portfolios/<portfolio_id>/task_orders/form/cancel", methods=["POST"]
|
||||
)
|
||||
@task_orders_bp.route("/task_orders/<task_order_id>/form/cancel", methods=["POST"])
|
||||
@user_can(Permissions.CREATE_TASK_ORDER, message="cancel task order form")
|
||||
def cancel_edit(task_order_id=None, portfolio_id=None):
|
||||
# Either save the currently entered data, or delete the TO
|
||||
save = http_request.args.get("save", "True").lower() == "true"
|
||||
|
||||
if save:
|
||||
form_data = {**http_request.form}
|
||||
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)
|
||||
|
||||
update_task_order(form, portfolio_id, task_order_id, flash_invalid=False)
|
||||
|
||||
elif not save and task_order_id:
|
||||
TaskOrders.delete(task_order_id)
|
||||
|
||||
return redirect(
|
||||
url_for("task_orders.portfolio_funding", portfolio_id=g.portfolio.id)
|
||||
)
|
||||
|
||||
|
||||
@task_orders_bp.route("/task_orders/<task_order_id>/form/step_2")
|
||||
@user_can(Permissions.CREATE_TASK_ORDER, message="view task order form")
|
||||
def form_step_two_add_number(task_order_id):
|
||||
return render_task_orders_edit(
|
||||
"task_orders/step_2.html", task_order_id=task_order_id
|
||||
)
|
||||
|
||||
|
||||
@task_orders_bp.route("/task_orders/<task_order_id>/form/step_2", methods=["POST"])
|
||||
@user_can(Permissions.CREATE_TASK_ORDER, message="update task order form")
|
||||
def submit_form_step_two_add_number(task_order_id):
|
||||
previous = http_request.args.get("previous", "False").lower() == "true"
|
||||
form_data = {**http_request.form}
|
||||
next_page = (
|
||||
"task_orders.form_step_three_add_clins"
|
||||
if not previous
|
||||
else "task_orders.form_step_one_add_pdf"
|
||||
)
|
||||
current_template = "task_orders/step_2.html"
|
||||
|
||||
return update_and_render_next(
|
||||
form_data,
|
||||
next_page,
|
||||
current_template,
|
||||
task_order_id=task_order_id,
|
||||
previous=previous,
|
||||
)
|
||||
|
||||
|
||||
@task_orders_bp.route("/task_orders/<task_order_id>/form/step_3")
|
||||
@user_can(Permissions.CREATE_TASK_ORDER, message="view task order form")
|
||||
def form_step_three_add_clins(task_order_id):
|
||||
return render_task_orders_edit(
|
||||
"task_orders/step_3.html", task_order_id=task_order_id
|
||||
)
|
||||
|
||||
|
||||
@task_orders_bp.route("/task_orders/<task_order_id>/form/step_3", methods=["POST"])
|
||||
@user_can(Permissions.CREATE_TASK_ORDER, message="update task order form")
|
||||
def submit_form_step_three_add_clins(task_order_id):
|
||||
previous = http_request.args.get("previous", "False").lower() == "true"
|
||||
form_data = {**http_request.form}
|
||||
next_page = (
|
||||
"task_orders.form_step_four_review"
|
||||
if not previous
|
||||
else "task_orders.form_step_two_add_number"
|
||||
)
|
||||
current_template = "task_orders/step_3.html"
|
||||
|
||||
return update_and_render_next(
|
||||
form_data,
|
||||
next_page,
|
||||
current_template,
|
||||
task_order_id=task_order_id,
|
||||
previous=previous,
|
||||
)
|
||||
|
||||
|
||||
@task_orders_bp.route("/task_orders/<task_order_id>/form/step_4")
|
||||
@user_can(Permissions.CREATE_TASK_ORDER, message="view task order form")
|
||||
def form_step_four_review(task_order_id):
|
||||
task_order = TaskOrders.get(task_order_id)
|
||||
|
||||
extra_args = {
|
||||
"pdf_download_url": app.csp.files.generate_download_link(
|
||||
task_order.pdf.object_name, task_order.pdf.filename
|
||||
)
|
||||
}
|
||||
|
||||
if task_order.is_completed == False:
|
||||
raise NoAccessError("task order form review")
|
||||
|
||||
return render_task_orders_edit(
|
||||
"task_orders/step_4.html", task_order_id=task_order_id, extra_args=extra_args
|
||||
)
|
||||
|
||||
|
||||
@task_orders_bp.route("/task_orders/<task_order_id>/form/step_5")
|
||||
@user_can(Permissions.CREATE_TASK_ORDER, message="view task order form")
|
||||
def form_step_five_confirm_signature(task_order_id):
|
||||
task_order = TaskOrders.get(task_order_id)
|
||||
|
||||
if task_order.is_completed == False:
|
||||
raise NoAccessError("task order form signature")
|
||||
|
||||
return render_task_orders_edit(
|
||||
"task_orders/step_5.html", task_order_id=task_order_id, form=SignatureForm()
|
||||
)
|
||||
|
||||
|
||||
@task_orders_bp.route("/task_orders/<task_order_id>/submit", methods=["POST"])
|
||||
@user_can(Permissions.CREATE_TASK_ORDER, "submit task order")
|
||||
def submit_task_order(task_order_id):
|
||||
task_order = TaskOrders.get(task_order_id)
|
||||
TaskOrders.sign(task_order=task_order, signer_dod_id=g.current_user.dod_id)
|
||||
|
||||
flash("task_order_submitted", task_order=task_order)
|
||||
|
||||
return redirect(
|
||||
url_for("task_orders.portfolio_funding", portfolio_id=task_order.portfolio_id)
|
||||
)
|
Reference in New Issue
Block a user