Merge pull request #242 from dod-ccpo/requests-date-submitted
Show last submission date in requests index
This commit is contained in:
commit
762a44d9ab
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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"
|
||||||
|
@ -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):
|
||||||
|
@ -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
2
atst/utils.py
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
def first_or_none(predicate, lst):
|
||||||
|
return next((x for x in lst if predicate(x)), None)
|
@ -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>
|
||||||
|
@ -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()
|
||||||
|
Loading…
x
Reference in New Issue
Block a user