diff --git a/backend/alembic/versions/2025_01_21_0619-6e35b193a666_updating_can_funding_source_enum.py b/backend/alembic/versions/2025_01_21_0619-6e35b193a666_updating_can_funding_source_enum.py new file mode 100644 index 0000000000..08068cc921 --- /dev/null +++ b/backend/alembic/versions/2025_01_21_0619-6e35b193a666_updating_can_funding_source_enum.py @@ -0,0 +1,42 @@ +"""updating CAN Funding Source enum + +Revision ID: 6e35b193a666 +Revises: 0536c9a5d32e +Create Date: 2025-01-21 06:19:03.550866+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 = '6e35b193a666' +down_revision: Union[str, None] = '0536c9a5d32e' +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.sync_enum_values( + enum_schema='ops', + enum_name='canfundingsource', + new_values=['OPRE', 'ACF', 'ACF_MOU', 'HHS', 'OTHER'], + affected_columns=[TableReference(table_schema='ops', table_name='can_funding_details', column_name='funding_source'), TableReference(table_schema='ops', table_name='can_funding_details_version', column_name='funding_source')], + enum_values_to_rename=[], + ) + # ### end Alembic commands ### + + +def downgrade() -> None: + # ### commands auto generated by Alembic - please adjust! ### + op.sync_enum_values( + enum_schema='ops', + enum_name='canfundingsource', + new_values=['OPRE', 'ACF', 'HHS'], + affected_columns=[TableReference(table_schema='ops', table_name='can_funding_details', column_name='funding_source'), TableReference(table_schema='ops', table_name='can_funding_details_version', column_name='funding_source')], + enum_values_to_rename=[], + ) + # ### end Alembic commands ### diff --git a/backend/models/cans.py b/backend/models/cans.py index 031e23c8d8..b9ddd33774 100644 --- a/backend/models/cans.py +++ b/backend/models/cans.py @@ -34,7 +34,9 @@ class CANFundingSource(Enum): OPRE = auto() ACF = auto() + ACF_MOU = auto() HHS = auto() + OTHER = auto() class CAN(BaseModel): diff --git a/backend/openapi.yml b/backend/openapi.yml index c1ceb68dcd..23d37d6a9a 100644 --- a/backend/openapi.yml +++ b/backend/openapi.yml @@ -2964,7 +2964,9 @@ components: enum: - OPRE - ACF + - ACF_MOU - HHS + - OTHER method_of_transfer: type: string enum: @@ -2998,7 +3000,9 @@ components: enum: - OPRE - ACF + - ACF_MOU - HHS + - OTHER id: type: integer method_of_transfer: diff --git a/backend/ops_api/ops/services/can_funding_summary.py b/backend/ops_api/ops/services/can_funding_summary.py index ed1ee8dda2..c753fe8c80 100644 --- a/backend/ops_api/ops/services/can_funding_summary.py +++ b/backend/ops_api/ops/services/can_funding_summary.py @@ -83,8 +83,6 @@ def get_can_funding_summary_request_data(request): @staticmethod def get_mapped_transfer_value(transfer: list[str]) -> tuple[bool, Optional[List[CANMethodOfTransfer]]]: - if "MOU" in transfer: - transfer[transfer.index("MOU")] = "COST_SHARE" try: transfer = [CANMethodOfTransfer[t] for t in transfer] except KeyError: diff --git a/backend/ops_api/tests/ops/funding_summary/test_can_funding_summary.py b/backend/ops_api/tests/ops/funding_summary/test_can_funding_summary.py index ded5d1e02b..7690d2d412 100644 --- a/backend/ops_api/tests/ops/funding_summary/test_can_funding_summary.py +++ b/backend/ops_api/tests/ops/funding_summary/test_can_funding_summary.py @@ -42,22 +42,22 @@ def test_can_get_can_funding_summary_fy_budget(auth_client: FlaskClient): def test_can_get_can_funding_summary_duplicate_transfer(auth_client: FlaskClient): - query_params = f"can_ids={0}&fiscal_year=2023&transfer=MOU&transfer=MOU" + query_params = f"can_ids={0}&fiscal_year=2023&transfer=COST_SHARE&transfer=COST_SHARE" response = auth_client.get(f"/api/v1/can-funding-summary?{query_params}") assert response.status_code == 200 assert len(response.json["cans"]) == 0 def test_can_get_can_funding_summary_cost_share_transfer(auth_client: FlaskClient): - query_params = f"can_ids={0}&fiscal_year=2023&transfer=COST_SHARE" + query_params = f"can_ids={0}&fiscal_year=2021&transfer=COST_SHARE" response = auth_client.get(f"/api/v1/can-funding-summary?{query_params}") assert response.status_code == 200 - assert len(response.json["cans"]) == 0 + assert len(response.json["cans"]) == 1 assert response.json["expected_funding"] == "0.0" - assert response.json["received_funding"] == "0.0" - assert response.json["total_funding"] == "0.0" + assert response.json["received_funding"] == "200000.0" + assert response.json["total_funding"] == "200000.0" def test_can_get_can_funding_summary_invalid_transfer(auth_client: FlaskClient): @@ -67,13 +67,6 @@ def test_can_get_can_funding_summary_invalid_transfer(auth_client: FlaskClient): assert response.json["Error"] == "Invalid 'transfer' value. Must be one of: DIRECT, COST_SHARE, IAA, IDDA, OTHER." -def test_can_get_can_funding_summary_mou_transfer(auth_client: FlaskClient): - query_params = f"can_ids={0}&fiscal_year=2023&transfer=MOU" - response = auth_client.get(f"/api/v1/can-funding-summary?{query_params}") - assert response.status_code == 200 - assert len(response.json["cans"]) == 0 - - def test_can_get_can_funding_summary_all_cans_fiscal_year_match(auth_client: FlaskClient) -> None: query_params = f"can_ids={0}&fiscal_year=2023" diff --git a/frontend/src/components/CANs/CAN.constants.js b/frontend/src/components/CANs/CAN.constants.js index fb1b9835ff..c51e44e62f 100644 --- a/frontend/src/components/CANs/CAN.constants.js +++ b/frontend/src/components/CANs/CAN.constants.js @@ -5,3 +5,11 @@ export const CAN_TRANSFER = { IAA: "IAA", OTHER: "OTHER" }; + +export const CAN_FUNDING_SOURCE = { + OPRE: "OPRE", + ACF: "ACF", + ACF_MOU: "ACF MOU", + HHS: "HHS", + OTHER: "Other" +}; diff --git a/frontend/src/components/CANs/CANTypes.d.ts b/frontend/src/components/CANs/CANTypes.d.ts index 9b0ebb9430..d1ab9d2f6a 100644 --- a/frontend/src/components/CANs/CANTypes.d.ts +++ b/frontend/src/components/CANs/CANTypes.d.ts @@ -75,7 +75,7 @@ export type FundingDetails = { fiscal_year: number; fund_code: string; funding_partner?: string; - funding_source?: "OPRE" | "ACF" | "HHS"; + funding_source?: keyof typeof CAN_FUNDING_SOURCE; funding_method?: "Direct" | "Reimbursable"; funding_received?: "Quarterly" | "FY Start"; funding_type?: "Discretionary" | "Mandatory";