diff --git a/atst/domain/task_orders.py b/atst/domain/task_orders.py index a433965e..c5d45abd 100644 --- a/atst/domain/task_orders.py +++ b/atst/domain/task_orders.py @@ -1,3 +1,4 @@ +import datetime from flask import current_app as app from atst.database import db @@ -47,6 +48,16 @@ class TaskOrders(BaseDomainClass): return task_order + @classmethod + def sign(cls, task_order, signer_dod_id): + task_order.signer_dod_id = signer_dod_id + task_order.signed_at = datetime.datetime.now() + + db.session.add(task_order) + db.session.commit() + + return task_order + @classmethod def create_clins(cls, task_order_id, clin_list): for clin_data in clin_list: diff --git a/atst/models/task_order.py b/atst/models/task_order.py index 5088ce70..2ea5a614 100644 --- a/atst/models/task_order.py +++ b/atst/models/task_order.py @@ -1,3 +1,4 @@ +from datetime import timedelta from enum import Enum from sqlalchemy import Column, DateTime, ForeignKey, String @@ -100,7 +101,8 @@ class TaskOrder(Base, mixins.TimestampsMixin): @property def end_date(self): - return max((c.end_date for c in self.clins), default=None) + default_end_date = self.start_date + timedelta(days=1) + return max((c.end_date for c in self.clins), default=default_end_date) @property def days_to_expiration(self): diff --git a/atst/routes/task_orders/index.py b/atst/routes/task_orders/index.py index 5922aeb7..0746a606 100644 --- a/atst/routes/task_orders/index.py +++ b/atst/routes/task_orders/index.py @@ -1,5 +1,3 @@ -from datetime import date - from flask import g, render_template, url_for, redirect from . import task_orders_bp @@ -42,7 +40,10 @@ def review_task_order(task_order_id): @task_orders_bp.route("/task_orders//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( @@ -56,11 +57,11 @@ def portfolio_funding(portfolio_id): portfolio = Portfolios.get(g.current_user, portfolio_id) task_orders = TaskOrders.sort(portfolio.task_orders) label_colors = { - Status.DRAFT: "warning", - Status.ACTIVE: "success", - Status.UPCOMING: "info", - Status.EXPIRED: "error", - Status.UNSIGNED: "purple", + TaskOrderStatus.DRAFT: "warning", + TaskOrderStatus.ACTIVE: "success", + TaskOrderStatus.UPCOMING: "info", + TaskOrderStatus.EXPIRED: "error", + TaskOrderStatus.UNSIGNED: "purple", } return render_template( "portfolios/task_orders/index.html", diff --git a/tests/routes/task_orders/test_index.py b/tests/routes/task_orders/test_index.py index fbc830bb..d9494ad2 100644 --- a/tests/routes/task_orders/test_index.py +++ b/tests/routes/task_orders/test_index.py @@ -1,3 +1,4 @@ +from datetime import date from flask import url_for import pytest from datetime import timedelta, date @@ -6,16 +7,10 @@ from atst.domain.permission_sets import PermissionSets from atst.domain.task_orders import TaskOrders from atst.models import * from atst.models.portfolio_role import Status as PortfolioStatus +from atst.models.task_order import Status as TaskOrderStatus from atst.utils.localization import translate -from tests.factories import ( - PortfolioFactory, - PortfolioRoleFactory, - TaskOrderFactory, - UserFactory, - random_future_date, - random_past_date, -) +from tests.factories import * from tests.utils import captured_templates @@ -23,10 +18,12 @@ from tests.utils import captured_templates def portfolio(): return PortfolioFactory.create() + @pytest.fixture def user(): return UserFactory.create() + @pytest.fixture def task_order(): user = UserFactory.create() @@ -38,18 +35,37 @@ def task_order(): def test_review_task_order(client, user_session, task_order): user_session(task_order.portfolio.owner) - response = client.get(url_for("task_orders.review_task_order", task_order_id=task_order.id)) + response = client.get( + url_for("task_orders.review_task_order", task_order_id=task_order.id) + ) assert response.status_code == 200 + def test_submit_task_order(client, user_session, task_order): user_session(task_order.portfolio.owner) response = client.post( - url_for( - "task_orders.submit_task_order", task_order_id=task_order.id - ), + url_for("task_orders.submit_task_order", task_order_id=task_order.id) ) assert response.status_code == 302 + active_start_date = date.today() - timedelta(days=1) + active_task_order = TaskOrderFactory(portfolio=task_order.portfolio) + CLINFactory(task_order=active_task_order, start_date=active_start_date) + assert active_task_order.status == TaskOrderStatus.UNSIGNED + response = client.post( + url_for("task_orders.submit_task_order", task_order_id=active_task_order.id) + ) + assert active_task_order.status == TaskOrderStatus.ACTIVE + + upcoming_start_date = date.today() + timedelta(days=1) + upcoming_task_order = TaskOrderFactory(portfolio=task_order.portfolio) + CLINFactory(task_order=upcoming_task_order, start_date=upcoming_start_date) + assert upcoming_task_order.status == TaskOrderStatus.UNSIGNED + response = client.post( + url_for("task_orders.submit_task_order", task_order_id=upcoming_task_order.id) + ) + assert upcoming_task_order.status == TaskOrderStatus.UPCOMING + class TestPortfolioFunding: @pytest.mark.skip(reason="Update later when CLINs are implemented")