diff --git a/atst/domain/requests.py b/atst/domain/requests.py index cc577d09..d44be200 100644 --- a/atst/domain/requests.py +++ b/atst/domain/requests.py @@ -87,6 +87,8 @@ class Requests(object): @classmethod def submit(cls, request): + request = Requests.set_status(request, RequestStatus.SUBMITTED) + new_status = None if Requests.should_auto_approve(request): new_status = RequestStatus.PENDING_FINANCIAL_VERIFICATION diff --git a/atst/models/request.py b/atst/models/request.py index e653edf8..466c6d91 100644 --- a/atst/models/request.py +++ b/atst/models/request.py @@ -2,9 +2,12 @@ from sqlalchemy import Column, func, ForeignKey from sqlalchemy.types import DateTime from sqlalchemy.dialects.postgresql import JSONB from sqlalchemy.orm import relationship +import pendulum from atst.models import Base from atst.models.types import Id +from atst.models.request_status_event import RequestStatus +from atst.utils import first_or_none class Request(Base): @@ -47,3 +50,13 @@ class Request(Base): if self.task_order: return self.task_order.verified return False + + @property + def last_submission_timestamp(self): + def _is_submission(status_event): + return status_event.new_status == RequestStatus.SUBMITTED + + last_submission = first_or_none(_is_submission, reversed(self.status_events)) + if last_submission: + return pendulum.instance(last_submission.time_created) + return None diff --git a/atst/models/request_status_event.py b/atst/models/request_status_event.py index 810a4427..bf95f5ce 100644 --- a/atst/models/request_status_event.py +++ b/atst/models/request_status_event.py @@ -10,6 +10,7 @@ from atst.models.types import Id class RequestStatus(Enum): STARTED = "Started" + SUBMITTED = "Submitted" PENDING_FINANCIAL_VERIFICATION = "Pending Financial Verification" PENDING_CCPO_APPROVAL = "Pending CCPO Approval" CHANGES_REQUESTED = "Changes Requested" diff --git a/atst/models/workspace.py b/atst/models/workspace.py index 8f6c58d9..aca024a4 100644 --- a/atst/models/workspace.py +++ b/atst/models/workspace.py @@ -4,6 +4,7 @@ from sqlalchemy.orm import relationship from atst.models import Base from atst.models.types import Id from atst.models.mixins import TimestampsMixin +from atst.utils import first_or_none MOCK_MEMBERS = [ @@ -48,14 +49,10 @@ class Workspace(Base, TimestampsMixin): @property def owner(self): - return next( - ( - workspace_role.user - for workspace_role in self.roles - if workspace_role.role.name == "owner" - ), - None, - ) + def _is_workspace_owner(workspace_role): + return workspace_role.role.name == "owner" + + return first_or_none(_is_workspace_owner, self.roles) @property def users(self): diff --git a/atst/routes/requests/index.py b/atst/routes/requests/index.py index e6606d91..6a5cc0f4 100644 --- a/atst/routes/requests/index.py +++ b/atst/routes/requests/index.py @@ -11,6 +11,11 @@ def map_request(request): is_new = time_created.add(days=1) > pendulum.now() app_count = request.body.get("details_of_use", {}).get("num_software_systems", 0) annual_usage = request.annual_spend + last_submission_timestamp = ( + request.last_submission_timestamp.format("M/DD/YYYY") + if request.last_submission_timestamp + else "-" + ) if Requests.is_pending_financial_verification(request): edit_link = url_for("requests.financial_verification", request_id=request.id) @@ -27,7 +32,7 @@ def map_request(request): "is_new": is_new, "status": request.status_displayname, "app_count": app_count, - "date": time_created.format("M/DD/YYYY"), + "last_submission_timestamp": last_submission_timestamp, "full_name": request.creator.full_name, "annual_usage": annual_usage, "edit_link": edit_link, diff --git a/atst/utils.py b/atst/utils.py new file mode 100644 index 00000000..db4933f4 --- /dev/null +++ b/atst/utils.py @@ -0,0 +1,2 @@ +def first_or_none(predicate, lst): + return next((x for x in lst if predicate(x)), None) diff --git a/templates/requests.html b/templates/requests.html index 05c1c673..ffa8a798 100644 --- a/templates/requests.html +++ b/templates/requests.html @@ -95,7 +95,7 @@ JEDI Cloud Request ID - Date Request Initiated / Created + Date Request Submitted {% if extended_view %} Requester Reason Flagged @@ -111,7 +111,7 @@ {{ r['order_id'] }} {% if r['is_new'] %}New{% endif %} - {{ r['date'] }} + {{ r.last_submission_timestamp }} {% if extended_view %} {{ r['full_name'] }} diff --git a/tests/domain/test_requests.py b/tests/domain/test_requests.py index 38a76e93..dfa6018a 100644 --- a/tests/domain/test_requests.py +++ b/tests/domain/test_requests.py @@ -70,6 +70,15 @@ def test_should_allow_submission(new_request): assert not Requests.should_allow_submission(new_request) +def test_request_knows_its_last_submission_timestamp(new_request): + submitted_request = Requests.submit(new_request) + assert submitted_request.last_submission_timestamp + + +def test_request_knows_if_it_has_no_last_submission_timestamp(new_request): + assert new_request.last_submission_timestamp is None + + def test_exists(session): user_allowed = UserFactory.create() user_denied = UserFactory.create()