Skip to content

Commit

Permalink
Merge pull request #3393 from HHS/OPS-3348/add-agreement-attributes
Browse files Browse the repository at this point in the history
Ops 3348/add agreement attributes
  • Loading branch information
johndeange authored Feb 3, 2025
2 parents 5a82b89 + e281de2 commit b518976
Show file tree
Hide file tree
Showing 8 changed files with 150 additions and 14 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
"""add start/end date to agreement;add psc_contract_specialist and cotr_id to contract;fix direct_obligation
Revision ID: baeefc8305f1
Revises: 6e35b193a666
Create Date: 2025-01-30 20:12:00.747620+00:00
"""

from typing import Sequence, Union

import sqlalchemy as sa
from alembic import op
from alembic_postgresql_enum import TableReference

# revision identifiers, used by Alembic.
revision: str = "baeefc8305f1"
down_revision: Union[str, None] = "6e35b193a666"
branch_labels: Union[str, Sequence[str], None] = None
depends_on: Union[str, Sequence[str], None] = None


def upgrade() -> None:
# ### commands auto generated by Alembic - please adjust! ###
op.add_column("agreement", sa.Column("start_date", sa.Date(), nullable=True))
op.add_column("agreement", sa.Column("end_date", sa.Date(), nullable=True))
op.add_column(
"agreement_version",
sa.Column("start_date", sa.Date(), autoincrement=False, nullable=True),
)
op.add_column(
"agreement_version",
sa.Column("end_date", sa.Date(), autoincrement=False, nullable=True),
)
op.add_column(
"contract_agreement",
sa.Column("psc_contract_specialist", sa.String(), nullable=True),
)
op.add_column(
"contract_agreement", sa.Column("cotr_id", sa.Integer(), nullable=True)
)
op.create_foreign_key(None, "contract_agreement", "ops_user", ["cotr_id"], ["id"])
op.add_column(
"contract_agreement_version",
sa.Column(
"psc_contract_specialist", sa.String(), autoincrement=False, nullable=True
),
)
op.add_column(
"contract_agreement_version",
sa.Column("cotr_id", sa.Integer(), autoincrement=False, nullable=True),
)
op.add_column("agreement", sa.Column("maps_sys_id", sa.Integer(), nullable=True))
op.add_column(
"agreement_version",
sa.Column("maps_sys_id", sa.Integer(), autoincrement=False, nullable=True),
)
op.sync_enum_values(
"ops",
"agreementtype",
["CONTRACT", "GRANT", "DIRECT_OBLIGATION", "IAA", "IAA_AA", "MISCELLANEOUS"],
[
TableReference(
table_schema="ops", table_name="agreement", column_name="agreement_type"
),
TableReference(
table_schema="ops",
table_name="agreement_version",
column_name="agreement_type",
),
],
enum_values_to_rename=[],
)
# ### end Alembic commands ###


def downgrade() -> None:
# ### commands auto generated by Alembic - please adjust! ###
op.sync_enum_values(
"ops",
"agreementtype",
["CONTRACT", "GRANT", "DIRECT_ALLOCATION", "IAA", "IAA_AA", "MISCELLANEOUS"],
[
TableReference(
table_schema="ops", table_name="agreement", column_name="agreement_type"
),
TableReference(
table_schema="ops",
table_name="agreement_version",
column_name="agreement_type",
),
],
enum_values_to_rename=[],
)
op.drop_column("contract_agreement_version", "cotr_id")
op.drop_column("contract_agreement_version", "psc_contract_specialist")
op.drop_constraint(None, "contract_agreement", type_="foreignkey")
op.drop_column("contract_agreement", "cotr_id")
op.drop_column("contract_agreement", "psc_contract_specialist")
op.drop_column("agreement_version", "end_date")
op.drop_column("agreement_version", "start_date")
op.drop_column("agreement", "end_date")
op.drop_column("agreement", "start_date")
op.drop_column("agreement_version", "maps_sys_id")
op.drop_column("agreement", "maps_sys_id")
# ### end Alembic commands ###
26 changes: 25 additions & 1 deletion backend/data_tools/data/agreements_and_blin_data.json5
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
product_service_code_id: 1,
agreement_reason: "NEW_REQ",
project_officer_id: 500,
agreement_type: "DIRECT_ALLOCATION",
agreement_type: "DIRECT_OBLIGATION",
project_id: 1000,
awarding_entity_id: 3,
created_by: 503,
Expand Down Expand Up @@ -86,6 +86,10 @@
contract_type: "FIRM_FIXED_PRICE",
contract_category: "RESEARCH",
support_contacts: [],
start_date: "2043-06-13T14:00:00",
end_date: "2044-06-13T14:00:00",
psc_contract_specialist: "PSC Contract Specialist",
cotr_id: 520,
},
{
name: "MIHOPE Check-In",
Expand All @@ -104,6 +108,10 @@
contract_category: "SERVICE",
support_contacts: [],
service_requirement_type: "SEVERABLE",
start_date: "2043-06-13T14:00:00",
end_date: "2044-06-13T14:00:00",
psc_contract_specialist: "PSC Contract Specialist",
cotr_id: 520
},
{
name: "MIHOPE Long-Term",
Expand All @@ -122,6 +130,10 @@
support_contacts: [],
contract_category: "SERVICE",
service_requirement_type: "NON_SEVERABLE",
start_date: "2043-06-13T14:00:00",
end_date: "2044-06-13T14:00:00",
psc_contract_specialist: "",
cotr_id: 520
},
{
name: "Interoperability Initiatives",
Expand Down Expand Up @@ -150,6 +162,10 @@
id: 520,
},
],
start_date: null,
end_date: null,
psc_contract_specialist: "",
cotr_id: null
},
{
name: "Contract Workflow Test",
Expand Down Expand Up @@ -186,6 +202,10 @@
id: 522,
},
],
start_date: null,
end_date: null,
psc_contract_specialist: "",
cotr_id: null
},
{
name: "Support Contract #1",
Expand Down Expand Up @@ -214,6 +234,10 @@
id: 520,
},
],
start_date: null,
end_date: null,
psc_contract_specialist: "",
cotr_id: null
},
],
clin: [
Expand Down
13 changes: 10 additions & 3 deletions backend/models/agreements.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
"""Agreement models."""

from datetime import date
from enum import Enum, auto
from typing import List, Optional

from sqlalchemy import Boolean, Column, ForeignKey, Integer, String, Table, Text, select
from sqlalchemy import Boolean, Column, Date, ForeignKey, Integer, String, Table, Text, select
from sqlalchemy.dialects.postgresql import ENUM
from sqlalchemy.orm import Mapped, mapped_column, object_session, relationship

Expand All @@ -25,7 +26,7 @@ class ContractCategory(Enum):
class AgreementType(Enum):
CONTRACT = auto()
GRANT = auto()
DIRECT_ALLOCATION = auto()
DIRECT_OBLIGATION = auto()
IAA = auto()
IAA_AA = auto()
MISCELLANEOUS = auto()
Expand Down Expand Up @@ -120,6 +121,10 @@ class Agreement(BaseModel):
procurement_shop = relationship("ProcurementShop", back_populates="agreements")
notes: Mapped[str] = mapped_column(Text, default="")

start_date: Mapped[Optional[date]] = mapped_column(Date)
end_date: Mapped[Optional[date]] = mapped_column(Date)
maps_sys_id: Mapped[Optional[int]] = mapped_column(Integer)

@BaseModel.display_name.getter
def display_name(self):
return self.name
Expand Down Expand Up @@ -205,6 +210,8 @@ class ContractAgreement(Agreement):
contract_category: Mapped[Optional[ContractCategory]] = mapped_column(
ENUM(ContractCategory)
)
psc_contract_specialist: Mapped[Optional[str]] = mapped_column(String)
cotr_id: Mapped[Optional[User]] = mapped_column(ForeignKey("ops_user.id"))

__mapper_args__ = {
"polymorphic_identity": AgreementType.CONTRACT,
Expand Down Expand Up @@ -264,7 +271,7 @@ class DirectAgreement(Agreement):
payee: Mapped[str] = mapped_column(String)

__mapper_args__ = {
"polymorphic_identity": AgreementType.DIRECT_ALLOCATION,
"polymorphic_identity": AgreementType.DIRECT_OBLIGATION,
}


Expand Down
10 changes: 5 additions & 5 deletions backend/ops_api/ops/resources/agreements_constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
AgreementType.CONTRACT: ContractAgreement,
AgreementType.GRANT: GrantAgreement,
AgreementType.IAA: IaaAgreement,
AgreementType.DIRECT_ALLOCATION: DirectAgreement,
AgreementType.DIRECT_OBLIGATION: DirectAgreement,
AgreementType.IAA_AA: IaaAaAgreement,
}

Expand All @@ -28,31 +28,31 @@
AgreementType.CONTRACT: ContractAgreementData,
AgreementType.GRANT: GrantAgreementData,
AgreementType.IAA: IaaAgreementData,
AgreementType.DIRECT_ALLOCATION: DirectAgreementData,
AgreementType.DIRECT_OBLIGATION: DirectAgreementData,
AgreementType.IAA_AA: IaaAaAgreementData,
}

AGREEMENT_TYPE_TO_RESPONSE_MAPPING = {
AgreementType.CONTRACT: ContractAgreementResponse,
AgreementType.GRANT: GrantAgreementResponse,
AgreementType.IAA: IaaAgreementResponse,
AgreementType.DIRECT_ALLOCATION: DirectAgreementResponse,
AgreementType.DIRECT_OBLIGATION: DirectAgreementResponse,
AgreementType.IAA_AA: IaaAaAgreementResponse,
}

AGREEMENTS_REQUEST_SCHEMAS = {
AgreementType.CONTRACT: AGREEMENT_TYPE_TO_DATACLASS_MAPPING.get(AgreementType.CONTRACT)(),
AgreementType.GRANT: AGREEMENT_TYPE_TO_DATACLASS_MAPPING.get(AgreementType.GRANT)(),
AgreementType.IAA: AGREEMENT_TYPE_TO_DATACLASS_MAPPING.get(AgreementType.IAA)(),
AgreementType.DIRECT_ALLOCATION: AGREEMENT_TYPE_TO_DATACLASS_MAPPING.get(AgreementType.DIRECT_ALLOCATION)(),
AgreementType.DIRECT_OBLIGATION: AGREEMENT_TYPE_TO_DATACLASS_MAPPING.get(AgreementType.DIRECT_OBLIGATION)(),
AgreementType.IAA_AA: AGREEMENT_TYPE_TO_DATACLASS_MAPPING.get(AgreementType.IAA_AA)(),
}

AGREEMENT_RESPONSE_SCHEMAS = {
AgreementType.CONTRACT: AGREEMENT_TYPE_TO_RESPONSE_MAPPING.get(AgreementType.CONTRACT)(),
AgreementType.GRANT: AGREEMENT_TYPE_TO_RESPONSE_MAPPING.get(AgreementType.GRANT)(),
AgreementType.IAA: AGREEMENT_TYPE_TO_RESPONSE_MAPPING.get(AgreementType.IAA)(),
AgreementType.DIRECT_ALLOCATION: AGREEMENT_TYPE_TO_RESPONSE_MAPPING.get(AgreementType.DIRECT_ALLOCATION)(),
AgreementType.DIRECT_OBLIGATION: AGREEMENT_TYPE_TO_RESPONSE_MAPPING.get(AgreementType.DIRECT_OBLIGATION)(),
AgreementType.IAA_AA: AGREEMENT_TYPE_TO_RESPONSE_MAPPING.get(AgreementType.IAA_AA)(),
# IAA_AA as the Miscellaneous type type under its mapper args in cans.py so mapping misc to IAA_AA
AgreementType.MISCELLANEOUS: AGREEMENT_TYPE_TO_RESPONSE_MAPPING.get(AgreementType.IAA_AA)(),
Expand Down
2 changes: 1 addition & 1 deletion backend/ops_api/tests/ops/can/test_can.py
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ def test_can_get_all(auth_client, mocker, test_can):
mocker_get_can = mocker.patch("ops_api.ops.services.cans.CANService.get_list")
mocker_get_can.return_value = [test_can]
mock_simple_agreement = {
"agreement_type": "AgreementType.DIRECT_ALLOCATION",
"agreement_type": "AgreementType.DIRECT_OBLIGATION",
"name": "DIRECT ALLOCATION #2: African American Child and Family Research Center",
"awarding_entity_id": 3,
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,7 @@ def direct_agreement(loaded_db, test_project):
direct_agreement = DirectAgreement(
name="Feature Test Direct",
payee="Somebody who needs money",
agreement_type=AgreementType.DIRECT_ALLOCATION,
agreement_type=AgreementType.DIRECT_OBLIGATION,
project_id=test_project.id,
created_by=503,
)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
export const AGREEMENT_TYPES = {
CONTRACT: "CONTRACT",
GRANT: "GRANT",
DIRECT_ALLOCATION: "DIRECT_ALLOCATION",
DIRECT_OBLIGATION: "DIRECT_OBLIGATION",
IAA: "IAA",
IAA_AA: "IAA_AA",
MISCELLANEOUS: "MISCELLANEOUS"
Expand Down
4 changes: 2 additions & 2 deletions frontend/src/helpers/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ export const codesToDisplayText = {
agreementType: {
CONTRACT: "Contract",
GRANT: "Grant",
DIRECT_ALLOCATION: "Direct Allocation",
DIRECT_OBLIGATION: "Direct Obligation",
IAA: "IAA",
MISCELLANEOUS: "Misc"
},
Expand Down Expand Up @@ -197,7 +197,7 @@ export const codesToDisplayText = {
agreement: {
"AgreementType.CONTRACT": "Contract",
"AgreementType.GRANT": "Grant",
"AgreementType.DIRECT_ALLOCATION": "Direct Allocation",
"AgreementType.DIRECT_OBLIGATION": "Direct Obligation",
"AgreementType.IAA": "IAA",
"AgreementType.MISCELLANEOUS": "Misc"
}
Expand Down

0 comments on commit b518976

Please sign in to comment.