Use Enum for request statuses

This commit is contained in:
richard-dds 2018-08-07 16:41:47 -04:00
parent 0c9005aaf6
commit 49b9fca793
5 changed files with 25 additions and 26 deletions

View File

@ -1,9 +1,9 @@
from enum import Enum
from sqlalchemy import exists, and_ from sqlalchemy import exists, and_
from sqlalchemy.orm.exc import NoResultFound from sqlalchemy.orm.exc import NoResultFound
from sqlalchemy.orm.attributes import flag_modified from sqlalchemy.orm.attributes import flag_modified
from atst.models import Request, RequestStatusEvent from atst.models.request import Request
from atst.models.request_status_event import RequestStatusEvent, RequestStatus
from atst.database import db from atst.database import db
from .exceptions import NotFoundError from .exceptions import NotFoundError
@ -27,13 +27,6 @@ def deep_merge(source, destination: dict):
return _deep_merge(source, dict(destination)) return _deep_merge(source, dict(destination))
class RequestStatus(Enum):
STARTED = "started"
PENDING_FINANCIAL_VERIFICATION = "pending_financial_verification"
PENDING_CCPO_APPROVAL = "pending_ccpo_approval"
APPROVED = "approved"
class Requests(object): class Requests(object):
AUTO_APPROVE_THRESHOLD = 1000000 AUTO_APPROVE_THRESHOLD = 1000000
@ -118,7 +111,7 @@ class Requests(object):
@classmethod @classmethod
def set_status(cls, request: Request, status: RequestStatus): def set_status(cls, request: Request, status: RequestStatus):
status_event = RequestStatusEvent(new_status=status.value) status_event = RequestStatusEvent(new_status=status)
request.status_events.append(status_event) request.status_events.append(status_event)
return request return request

View File

@ -24,3 +24,4 @@ class Request(Base):
def set_status(self, status): def set_status(self, status):
self.status_events.append(status) self.status_events.append(status)

View File

@ -1,5 +1,6 @@
from sqlalchemy import Column, func, ForeignKey from enum import Enum, auto
from sqlalchemy.types import DateTime, String, BigInteger from sqlalchemy import Column, func, ForeignKey, Enum as SQLAEnum
from sqlalchemy.types import DateTime, BigInteger
from sqlalchemy.schema import Sequence from sqlalchemy.schema import Sequence
from sqlalchemy.dialects.postgresql import UUID from sqlalchemy.dialects.postgresql import UUID
@ -7,11 +8,18 @@ from atst.models import Base
from atst.models.types import Id from atst.models.types import Id
class RequestStatus(Enum):
STARTED = auto()
PENDING_FINANCIAL_VERIFICATION = auto()
PENDING_CCPO_APPROVAL = auto()
APPROVED = auto()
class RequestStatusEvent(Base): class RequestStatusEvent(Base):
__tablename__ = "request_status_events" __tablename__ = "request_status_events"
id = Id() id = Id()
new_status = Column(String()) new_status = Column(SQLAEnum(RequestStatus))
time_created = Column(DateTime(timezone=True), server_default=func.now()) time_created = Column(DateTime(timezone=True), server_default=func.now())
request_id = Column( request_id = Column(
UUID(as_uuid=True), ForeignKey("requests.id", ondelete="CASCADE") UUID(as_uuid=True), ForeignKey("requests.id", ondelete="CASCADE")

View File

@ -3,6 +3,7 @@ from uuid import uuid4
from atst.domain.exceptions import NotFoundError from atst.domain.exceptions import NotFoundError
from atst.domain.requests import Requests from atst.domain.requests import Requests
from atst.models.request_status_event import RequestStatus
from tests.factories import RequestFactory from tests.factories import RequestFactory
@ -25,25 +26,25 @@ def test_nonexistent_request_raises():
def test_new_request_has_started_status(): def test_new_request_has_started_status():
request = Requests.create(uuid4(), {}) request = Requests.create(uuid4(), {})
assert request.status == "started" assert request.status == RequestStatus.STARTED
def test_auto_approve_less_than_1m(new_request): def test_auto_approve_less_than_1m(new_request):
new_request.body = {"details_of_use": {"dollar_value": 999999}} new_request.body = {"details_of_use": {"dollar_value": 999999}}
request = Requests.submit(new_request) request = Requests.submit(new_request)
assert request.status == "pending_financial_verification" assert request.status == RequestStatus.PENDING_FINANCIAL_VERIFICATION
def test_dont_auto_approve_if_dollar_value_is_1m_or_above(new_request): def test_dont_auto_approve_if_dollar_value_is_1m_or_above(new_request):
new_request.body = {"details_of_use": {"dollar_value": 1000000}} new_request.body = {"details_of_use": {"dollar_value": 1000000}}
request = Requests.submit(new_request) request = Requests.submit(new_request)
assert request.status == "pending_ccpo_approval" assert request.status == RequestStatus.PENDING_CCPO_APPROVAL
def test_dont_auto_approve_if_no_dollar_value_specified(new_request): def test_dont_auto_approve_if_no_dollar_value_specified(new_request):
new_request.body = {"details_of_use": {}} new_request.body = {"details_of_use": {}}
request = Requests.submit(new_request) request = Requests.submit(new_request)
assert request.status == "pending_ccpo_approval" assert request.status == RequestStatus.PENDING_CCPO_APPROVAL

View File

@ -1,7 +1,8 @@
import factory import factory
from uuid import uuid4 from uuid import uuid4
from atst.models import Request, RequestStatusEvent from atst.models.request import Request
from atst.models.request_status_event import RequestStatusEvent, RequestStatus
from atst.models.pe_number import PENumber from atst.models.pe_number import PENumber
from atst.models.task_order import TaskOrder from atst.models.task_order import TaskOrder
from atst.models.user import User from atst.models.user import User
@ -9,34 +10,31 @@ from atst.models.role import Role
class RequestStatusFactory(factory.alchemy.SQLAlchemyModelFactory): class RequestStatusFactory(factory.alchemy.SQLAlchemyModelFactory):
class Meta: class Meta:
model = RequestStatusEvent model = RequestStatusEvent
class RequestFactory(factory.alchemy.SQLAlchemyModelFactory): class RequestFactory(factory.alchemy.SQLAlchemyModelFactory):
class Meta: class Meta:
model = Request model = Request
id = factory.Sequence(lambda x: uuid4()) id = factory.Sequence(lambda x: uuid4())
status_events = factory.RelatedFactory(RequestStatusFactory, "request", new_status="started") status_events = factory.RelatedFactory(
RequestStatusFactory, "request", new_status=RequestStatus.STARTED
)
class PENumberFactory(factory.alchemy.SQLAlchemyModelFactory): class PENumberFactory(factory.alchemy.SQLAlchemyModelFactory):
class Meta: class Meta:
model = PENumber model = PENumber
class TaskOrderFactory(factory.alchemy.SQLAlchemyModelFactory): class TaskOrderFactory(factory.alchemy.SQLAlchemyModelFactory):
class Meta: class Meta:
model = TaskOrder model = TaskOrder
class RoleFactory(factory.alchemy.SQLAlchemyModelFactory): class RoleFactory(factory.alchemy.SQLAlchemyModelFactory):
class Meta: class Meta:
model = Role model = Role
@ -44,7 +42,6 @@ class RoleFactory(factory.alchemy.SQLAlchemyModelFactory):
class UserFactory(factory.alchemy.SQLAlchemyModelFactory): class UserFactory(factory.alchemy.SQLAlchemyModelFactory):
class Meta: class Meta:
model = User model = User
@ -53,4 +50,3 @@ class UserFactory(factory.alchemy.SQLAlchemyModelFactory):
first_name = "Fake" first_name = "Fake"
last_name = "User" last_name = "User"
atat_role = factory.SubFactory(RoleFactory) atat_role = factory.SubFactory(RoleFactory)