Merge pull request #242 from dod-ccpo/requests-date-submitted

Show last submission date in requests index
This commit is contained in:
richard-dds 2018-09-04 14:01:21 -04:00 committed by GitHub
commit 762a44d9ab
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 40 additions and 11 deletions

View File

@ -87,6 +87,8 @@ class Requests(object):
@classmethod @classmethod
def submit(cls, request): def submit(cls, request):
request = Requests.set_status(request, RequestStatus.SUBMITTED)
new_status = None new_status = None
if Requests.should_auto_approve(request): if Requests.should_auto_approve(request):
new_status = RequestStatus.PENDING_FINANCIAL_VERIFICATION new_status = RequestStatus.PENDING_FINANCIAL_VERIFICATION

View File

@ -2,9 +2,12 @@ from sqlalchemy import Column, func, ForeignKey
from sqlalchemy.types import DateTime from sqlalchemy.types import DateTime
from sqlalchemy.dialects.postgresql import JSONB from sqlalchemy.dialects.postgresql import JSONB
from sqlalchemy.orm import relationship from sqlalchemy.orm import relationship
import pendulum
from atst.models import Base from atst.models import Base
from atst.models.types import Id from atst.models.types import Id
from atst.models.request_status_event import RequestStatus
from atst.utils import first_or_none
class Request(Base): class Request(Base):
@ -47,3 +50,13 @@ class Request(Base):
if self.task_order: if self.task_order:
return self.task_order.verified return self.task_order.verified
return False 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

View File

@ -10,6 +10,7 @@ from atst.models.types import Id
class RequestStatus(Enum): class RequestStatus(Enum):
STARTED = "Started" STARTED = "Started"
SUBMITTED = "Submitted"
PENDING_FINANCIAL_VERIFICATION = "Pending Financial Verification" PENDING_FINANCIAL_VERIFICATION = "Pending Financial Verification"
PENDING_CCPO_APPROVAL = "Pending CCPO Approval" PENDING_CCPO_APPROVAL = "Pending CCPO Approval"
CHANGES_REQUESTED = "Changes Requested" CHANGES_REQUESTED = "Changes Requested"

View File

@ -4,6 +4,7 @@ from sqlalchemy.orm import relationship
from atst.models import Base from atst.models import Base
from atst.models.types import Id from atst.models.types import Id
from atst.models.mixins import TimestampsMixin from atst.models.mixins import TimestampsMixin
from atst.utils import first_or_none
MOCK_MEMBERS = [ MOCK_MEMBERS = [
@ -48,14 +49,10 @@ class Workspace(Base, TimestampsMixin):
@property @property
def owner(self): def owner(self):
return next( def _is_workspace_owner(workspace_role):
( return workspace_role.role.name == "owner"
workspace_role.user
for workspace_role in self.roles return first_or_none(_is_workspace_owner, self.roles)
if workspace_role.role.name == "owner"
),
None,
)
@property @property
def users(self): def users(self):

View File

@ -11,6 +11,11 @@ def map_request(request):
is_new = time_created.add(days=1) > pendulum.now() is_new = time_created.add(days=1) > pendulum.now()
app_count = request.body.get("details_of_use", {}).get("num_software_systems", 0) app_count = request.body.get("details_of_use", {}).get("num_software_systems", 0)
annual_usage = request.annual_spend 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): if Requests.is_pending_financial_verification(request):
edit_link = url_for("requests.financial_verification", request_id=request.id) edit_link = url_for("requests.financial_verification", request_id=request.id)
@ -27,7 +32,7 @@ def map_request(request):
"is_new": is_new, "is_new": is_new,
"status": request.status_displayname, "status": request.status_displayname,
"app_count": app_count, "app_count": app_count,
"date": time_created.format("M/DD/YYYY"), "last_submission_timestamp": last_submission_timestamp,
"full_name": request.creator.full_name, "full_name": request.creator.full_name,
"annual_usage": annual_usage, "annual_usage": annual_usage,
"edit_link": edit_link, "edit_link": edit_link,

2
atst/utils.py Normal file
View File

@ -0,0 +1,2 @@
def first_or_none(predicate, lst):
return next((x for x in lst if predicate(x)), None)

View File

@ -95,7 +95,7 @@
<thead> <thead>
<tr> <tr>
<th scope="col">JEDI Cloud Request ID</th> <th scope="col">JEDI Cloud Request ID</th>
<th scope="col">Date Request Initiated / Created</th> <th scope="col">Date Request Submitted</th>
{% if extended_view %} {% if extended_view %}
<th scope="col">Requester</th> <th scope="col">Requester</th>
<th scope="col">Reason Flagged</th> <th scope="col">Reason Flagged</th>
@ -111,7 +111,7 @@
<a class='icon-link icon-link--large' href="{{ r['edit_link'] }}">{{ r['order_id'] }}</a> <a class='icon-link icon-link--large' href="{{ r['edit_link'] }}">{{ r['order_id'] }}</a>
{% if r['is_new'] %}<span class="usa-label">New</span>{% endif %} {% if r['is_new'] %}<span class="usa-label">New</span>{% endif %}
</th> </th>
<td>{{ r['date'] }}</td> <td>{{ r.last_submission_timestamp }}</td>
{% if extended_view %} {% if extended_view %}
<td>{{ r['full_name'] }}</td> <td>{{ r['full_name'] }}</td>
<td></td> <td></td>

View File

@ -70,6 +70,15 @@ def test_should_allow_submission(new_request):
assert not Requests.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): def test_exists(session):
user_allowed = UserFactory.create() user_allowed = UserFactory.create()
user_denied = UserFactory.create() user_denied = UserFactory.create()