-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #2624 from HHS/experiments/eliminate-old-workflows
Remove old workflows
- Loading branch information
Showing
33 changed files
with
1,578 additions
and
1,443 deletions.
There are no files selected for viewing
1,194 changes: 1,194 additions & 0 deletions
1,194
...nd/alembic/versions/2024_07_29_2149-fef3614083d9_remove_workflows_and_add_procurement_.py
Large diffs are not rendered by default.
Oops, something went wrong.
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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" | ||
) |
Oops, something went wrong.