Skip to content

Commit

Permalink
Merge pull request #2624 from HHS/experiments/eliminate-old-workflows
Browse files Browse the repository at this point in the history
Remove old workflows
  • Loading branch information
stevtek authored Jul 31, 2024
2 parents b0c867b + 6fc5b1b commit e0cb572
Show file tree
Hide file tree
Showing 33 changed files with 1,578 additions and 1,443 deletions.

Large diffs are not rendered by default.

112 changes: 0 additions & 112 deletions backend/data_tools/data/workflow_data.json5

This file was deleted.

3 changes: 0 additions & 3 deletions backend/data_tools/scripts/import_test_data.sh
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,4 @@ DATA=./data_tools/data/first_contract_data.json5 python ./data_tools/src/import_
echo "Loading 'agreements_and_blin_data.json5'..."
DATA=./data_tools/data/agreements_and_blin_data.json5 python ./data_tools/src/import_static_data/import_data.py

echo "Loading 'workflow_data.json5'..."
DATA=./data_tools/data/workflow_data.json5 python ./data_tools/src/import_static_data/import_data.py

echo "Data Loading Complete!"
2 changes: 1 addition & 1 deletion backend/models/__init__.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
from .auth import *
from .base import *
from .cans import *
from .change_requests import *
from .document import *
from .events import *
from .history import *
Expand All @@ -10,4 +11,3 @@
from .projects import *
from .users import *
from .vendors import *
from .workflows import *
44 changes: 17 additions & 27 deletions backend/models/cans.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,19 +27,10 @@
from typing_extensions import Any, override

from models.base import BaseModel
from models.change_requests import BudgetLineItemChangeRequest, ChangeRequestStatus
from models.portfolios import Portfolio
from models.procurement_tracker import ProcurementTracker
from models.users import User
from models.workflows import (
BudgetLineItemChangeRequest,
ChangeRequestStatus,
Package,
PackageSnapshot,
WorkflowAction,
WorkflowInstance,
WorkflowStepInstance,
WorkflowStepStatus,
WorkflowTriggerType,
)


class BudgetLineItemStatus(Enum):
Expand All @@ -48,16 +39,19 @@ class BudgetLineItemStatus(Enum):
IN_EXECUTION = auto()
OBLIGATED = auto()


class ModType(Enum):
ADMIN = auto()
AMOUNT_TBD = auto()
AS_IS = auto()
REPLACEMENT_AMOUNT_FINAL = auto()


class ContractCategory(Enum):
RESEARCH = auto()
SERVICE = auto()


class CANArrangementType(Enum):
OPRE_APPROPRIATION = auto()
COST_SHARE = auto()
Expand Down Expand Up @@ -238,20 +232,15 @@ def display_name(self):
}

@property
def procurement_tracker_workflow_id(self):
def procurement_tracker_id(self):
if object_session(self) is None:
return False
workflow_id = object_session(self).scalar(
select(WorkflowInstance.id).where(
and_(
WorkflowInstance.workflow_action
== WorkflowAction.PROCUREMENT_TRACKING,
WorkflowInstance.associated_type == WorkflowTriggerType.AGREEMENT,
WorkflowInstance.associated_id == self.id,
)
tracker_id = object_session(self).scalar(
select(ProcurementTracker.id).where(
ProcurementTracker.agreement_id == self.id
)
)
return workflow_id
return tracker_id


contract_support_contacts = Table(
Expand Down Expand Up @@ -319,7 +308,9 @@ class ContractAgreement(Agreement):
service_requirement_type: Mapped[Optional[ServiceRequirementType]] = mapped_column(
ENUM(ServiceRequirementType)
)
contract_category: Mapped[Optional[ContractCategory]] = mapped_column(ENUM(ContractCategory))
contract_category: Mapped[Optional[ContractCategory]] = mapped_column(
ENUM(ContractCategory)
)

__mapper_args__ = {
"polymorphic_identity": AgreementType.CONTRACT,
Expand Down Expand Up @@ -587,9 +578,7 @@ class BudgetLineItem(BaseModel):
clin: Mapped[Optional[CLIN]] = relationship(CLIN, backref="budget_line_items")

amount: Mapped[Optional[decimal]] = mapped_column(Numeric(12, 2))
mod_type: Mapped[Optional[ModType]] = mapped_column(
sa.Enum(ModType)
)
mod_type: Mapped[Optional[ModType]] = mapped_column(sa.Enum(ModType))

status: Mapped[Optional[BudgetLineItemStatus]] = mapped_column(
sa.Enum(BudgetLineItemStatus)
Expand All @@ -602,7 +591,9 @@ class BudgetLineItem(BaseModel):
requisition_number: Mapped[Optional[int]] = mapped_column(Integer)
requisition_date: Mapped[Optional[date]] = mapped_column(Date)

is_under_current_resolution: Mapped[Optional[bool]] = mapped_column(Boolean, default=False)
is_under_current_resolution: Mapped[Optional[bool]] = mapped_column(
Boolean, default=False
)

date_needed: Mapped[Optional[date]] = mapped_column(Date)

Expand Down Expand Up @@ -799,7 +790,6 @@ def appropriation_term(self):
return None
return self.expiration_date.year - self.appropriation_date.year


@BaseModel.display_name.getter
def display_name(self):
return self.number
Expand Down
139 changes: 139 additions & 0 deletions backend/models/change_requests.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
"""Workflow models."""

from enum import Enum, auto
from typing import Optional

import sqlalchemy as sa
from sqlalchemy import DateTime, ForeignKey, Integer, event
from sqlalchemy.dialects.postgresql import ENUM, JSONB
from sqlalchemy.ext.hybrid import hybrid_property
from sqlalchemy.orm import Mapped, mapped_column, relationship

from models import BaseModel

# ---=== CHANGE REQUESTS ===---


class ChangeRequestStatus(Enum):
IN_REVIEW = auto()
APPROVED = auto()
REJECTED = auto()


class ChangeRequestType(Enum):
CHANGE_REQUEST = auto()
AGREEMENT_CHANGE_REQUEST = auto()
BUDGET_LINE_ITEM_CHANGE_REQUEST = auto()


class ChangeRequest(BaseModel):
__tablename__ = "change_request"
id: Mapped[int] = mapped_column(Integer, primary_key=True)
change_request_type: Mapped[ChangeRequestType] = mapped_column(
ENUM(ChangeRequestType)
)

# agreement_type: Mapped[AgreementType] = mapped_column(ENUM(AgreementType))
status: Mapped[ChangeRequestStatus] = mapped_column(
ENUM(ChangeRequestStatus), nullable=False, default=ChangeRequestStatus.IN_REVIEW
)
requested_change_data: Mapped[JSONB] = mapped_column(JSONB)
requested_change_diff: Mapped[Optional[JSONB]] = mapped_column(JSONB)
requested_change_info: Mapped[Optional[JSONB]] = mapped_column(JSONB)
# BaseModel.created_by is the requestor, so there's no need for another column for that
requestor_notes: Mapped[Optional[str]] = mapped_column(sa.String)

managing_division_id: Mapped[Optional[int]] = mapped_column(
ForeignKey("division.id")
)
managing_division = relationship(
"Division",
passive_deletes=True,
)
reviewed_by_id: Mapped[Optional[int]] = mapped_column(ForeignKey("ops_user.id"))
reviewed_on: Mapped[Optional[DateTime]] = mapped_column(DateTime)
reviewer_notes: Mapped[Optional[str]] = mapped_column(sa.String)

__mapper_args__ = {
"polymorphic_on": "change_request_type",
"polymorphic_identity": ChangeRequestType.CHANGE_REQUEST,
}


class AgreementChangeRequest(ChangeRequest):
# if this isn't optional here, SQL will make the column non-nullable
agreement_id: Mapped[Optional[int]] = mapped_column(
ForeignKey("agreement.id", ondelete="CASCADE")
)
agreement = relationship(
"Agreement",
passive_deletes=True,
)

__mapper_args__ = {
"polymorphic_identity": ChangeRequestType.AGREEMENT_CHANGE_REQUEST,
}

budget_field_names = ["procurement_shop_id"]

@hybrid_property
def has_budget_change(self):
return any(key in self.requested_change_data for key in self.budget_field_names)

@has_budget_change.expression
def has_budget_change(cls):
return cls.requested_change_data.has_any(cls.budget_field_names)


class BudgetLineItemChangeRequest(AgreementChangeRequest):
budget_line_item_id: Mapped[Optional[int]] = mapped_column(
ForeignKey("budget_line_item.id", ondelete="CASCADE")
)
budget_line_item = relationship(
"BudgetLineItem",
passive_deletes=True,
)

__mapper_args__ = {
"polymorphic_identity": ChangeRequestType.BUDGET_LINE_ITEM_CHANGE_REQUEST,
}

budget_field_names = ["amount", "can_id", "date_needed"]

@hybrid_property
def has_budget_change(self):
return any(key in self.requested_change_data for key in self.budget_field_names)

@has_budget_change.expression
def has_budget_change(cls):
return cls.requested_change_data.has_any(cls.budget_field_names)

@hybrid_property
def has_status_change(self):
return "status" in self.requested_change_data

@has_status_change.expression
def has_status_change(cls):
return cls.requested_change_data.has_key("status")


# require agreement_id for Agreement changes.
# (It has to be Optional in the model to keep the column nullable for other types)
@event.listens_for(AgreementChangeRequest, "before_insert")
@event.listens_for(AgreementChangeRequest, "before_update")
@event.listens_for(BudgetLineItemChangeRequest, "before_insert")
@event.listens_for(BudgetLineItemChangeRequest, "before_update")
def check_agreement_id(mapper, connection, target):
if target.agreement_id is None:
raise ValueError("agreement_id is required for AgreementChangeRequest")


# require budget_line_item_id for BLI changes.
# (It has to be Optional in the model to keep the column nullable for other types)
@event.listens_for(BudgetLineItemChangeRequest, "before_insert")
@event.listens_for(BudgetLineItemChangeRequest, "before_update")
def check_budget_line_id(mapper, connection, target):
if target.budget_line_item_id is None:
raise ValueError(
"budget_line_item_id is required for BudgetLineItemChangeRequest"
)
Loading

0 comments on commit e0cb572

Please sign in to comment.