From 8e000e3e77f03cdfa003753d78227cf1552e4ba0 Mon Sep 17 00:00:00 2001 From: dandds Date: Thu, 6 Sep 2018 15:43:14 -0400 Subject: [PATCH] add request review --- .../7bdb2055d7c7_add_request_review_table.py | 42 +++++++++++++++++++ atst/models/__init__.py | 1 + atst/models/request.py | 12 +++++- atst/models/request_review.py | 19 +++++++++ atst/models/request_status_event.py | 3 ++ tests/factories.py | 6 +++ tests/models/test_requests.py | 21 +++++++++- 7 files changed, 101 insertions(+), 3 deletions(-) create mode 100644 alembic/versions/7bdb2055d7c7_add_request_review_table.py create mode 100644 atst/models/request_review.py diff --git a/alembic/versions/7bdb2055d7c7_add_request_review_table.py b/alembic/versions/7bdb2055d7c7_add_request_review_table.py new file mode 100644 index 00000000..cdc979d0 --- /dev/null +++ b/alembic/versions/7bdb2055d7c7_add_request_review_table.py @@ -0,0 +1,42 @@ +"""add request review table + +Revision ID: 7bdb2055d7c7 +Revises: 06aa23166ca9 +Create Date: 2018-09-06 15:15:40.666840 + +""" +from alembic import op +import sqlalchemy as sa + + +# revision identifiers, used by Alembic. +revision = '7bdb2055d7c7' +down_revision = '06aa23166ca9' +branch_labels = None +depends_on = None + + +def upgrade(): + # ### commands auto generated by Alembic - please adjust! ### + op.create_table('request_reviews', + sa.Column('id', sa.Integer(), nullable=False), + sa.Column('comments', sa.String(), nullable=True), + sa.Column('fname_mao', sa.String(), nullable=True), + sa.Column('lname_mao', sa.String(), nullable=True), + sa.Column('email_mao', sa.String(), nullable=True), + sa.Column('phone_mao', sa.String(), nullable=True), + sa.Column('fname_ccpo', sa.String(), nullable=True), + sa.Column('lname_ccpo', sa.String(), nullable=True), + sa.PrimaryKeyConstraint('id') + ) + op.add_column('request_status_events', sa.Column('request_review_id', sa.Integer(), nullable=True)) + op.create_foreign_key(None, 'request_status_events', 'request_reviews', ['request_review_id'], ['id']) + # ### end Alembic commands ### + + +def downgrade(): + # ### commands auto generated by Alembic - please adjust! ### + op.drop_constraint(None, 'request_status_events', type_='foreignkey') + op.drop_column('request_status_events', 'request_review_id') + op.drop_table('request_reviews') + # ### end Alembic commands ### diff --git a/atst/models/__init__.py b/atst/models/__init__.py index 4bedebfe..245e3806 100644 --- a/atst/models/__init__.py +++ b/atst/models/__init__.py @@ -15,3 +15,4 @@ from .project import Project from .environment import Environment from .attachment import Attachment from .request_revision import RequestRevision +from .request_review import RequestReview diff --git a/atst/models/request.py b/atst/models/request.py index 4e155504..71609702 100644 --- a/atst/models/request.py +++ b/atst/models/request.py @@ -115,13 +115,17 @@ class Request(Base): return body + @property + def latest_status(self): + return self.status_events[-1] + @property def status(self): - return self.status_events[-1].new_status + return self.latest_status.new_status @property def status_displayname(self): - return self.status_events[-1].displayname + return self.latest_status.displayname @property def annual_spend(self): @@ -154,3 +158,7 @@ class Request(Base): RequestStatus.PENDING_FINANCIAL_VERIFICATION: "mission_owner", RequestStatus.PENDING_CCPO_APPROVAL: "ccpo", }.get(self.status) + + @property + def reviews(self): + return [status.review for status in self.status_events if status.review] diff --git a/atst/models/request_review.py b/atst/models/request_review.py new file mode 100644 index 00000000..3b4df410 --- /dev/null +++ b/atst/models/request_review.py @@ -0,0 +1,19 @@ +from sqlalchemy import Column, Integer, String +from sqlalchemy.orm import relationship + +from atst.models import Base + + +class RequestReview(Base): + __tablename__ = "request_reviews" + + id = Column(Integer, primary_key=True) + status = relationship("RequestStatusEvent", back_populates="review") + + comments = Column(String) + fname_mao = Column(String) + lname_mao = Column(String) + email_mao = Column(String) + phone_mao = Column(String) + fname_ccpo = Column(String) + lname_ccpo = Column(String) diff --git a/atst/models/request_status_event.py b/atst/models/request_status_event.py index ba13c242..11ae7dad 100644 --- a/atst/models/request_status_event.py +++ b/atst/models/request_status_event.py @@ -35,6 +35,9 @@ class RequestStatusEvent(Base): request_revision_id = Column(ForeignKey("request_revisions.id"), nullable=False) revision = relationship("RequestRevision") + request_review_id = Column(ForeignKey("request_reviews.id"), nullable=True) + review = relationship("RequestReview", back_populates="status") + @property def displayname(self): return self.new_status.value diff --git a/tests/factories.py b/tests/factories.py index b73ea74a..e2b659a7 100644 --- a/tests/factories.py +++ b/tests/factories.py @@ -7,6 +7,7 @@ import datetime from atst.forms.data import SERVICE_BRANCHES from atst.models.request import Request from atst.models.request_revision import RequestRevision +from atst.models.request_review import RequestReview from atst.models.request_status_event import RequestStatusEvent, RequestStatus from atst.models.pe_number import PENumber from atst.models.task_order import TaskOrder @@ -55,6 +56,11 @@ class RequestRevisionFactory(factory.alchemy.SQLAlchemyModelFactory): id = factory.Sequence(lambda x: uuid4()) +class RequestReviewFactory(factory.alchemy.SQLAlchemyModelFactory): + class Meta: + model = RequestReview + + class RequestFactory(factory.alchemy.SQLAlchemyModelFactory): class Meta: model = Request diff --git a/tests/models/test_requests.py b/tests/models/test_requests.py index cf17afa8..1b16d7db 100644 --- a/tests/models/test_requests.py +++ b/tests/models/test_requests.py @@ -1,4 +1,9 @@ -from tests.factories import RequestFactory, UserFactory +from tests.factories import ( + RequestFactory, + UserFactory, + RequestStatusEventFactory, + RequestReviewFactory, +) from atst.domain.requests import Requests, RequestStatus @@ -69,3 +74,17 @@ def test_annual_spend(): request = RequestFactory.create() monthly = request.body.get("details_of_use").get("estimated_monthly_spend") assert request.annual_spend == monthly * 12 + + +def test_reviews(): + request = RequestFactory.create() + request.status_events = [ + RequestStatusEventFactory.create( + revision=request.latest_revision, review=RequestReviewFactory.create() + ), + RequestStatusEventFactory.create( + revision=request.latest_revision, review=RequestReviewFactory.create() + ), + RequestStatusEventFactory.create(revision=request.latest_revision), + ] + assert len(request.reviews) == 2