From 5845ac3977d67b1fff30bc94cc1742d9422aab1f Mon Sep 17 00:00:00 2001 From: maiyerlee Date: Mon, 20 Jan 2025 21:36:39 -0600 Subject: [PATCH 1/9] fix: reformat CAN funding sum response type --- backend/openapi.yml | 46 +++++++++++++++++++++++++++------------------ 1 file changed, 28 insertions(+), 18 deletions(-) diff --git a/backend/openapi.yml b/backend/openapi.yml index c1ceb68dcd..c3c995fd19 100644 --- a/backend/openapi.yml +++ b/backend/openapi.yml @@ -1190,9 +1190,11 @@ paths: type: object properties: available_funding: - type: string + type: number + format: float carry_forward_funding: - type: string + type: number + format: float cans: type: array properties: @@ -1219,27 +1221,35 @@ paths: expiration_date: type: string expected_funding: - type: string + type: number + format: float in_draft_funding: - type: string + type: number + format: float in_execution_funding: - type: string + type: number + format: float new_funding: - type: string + type: number + format: float obligated_funding: - type: string + type: number + format: float planned_funding: - type: string + type: number + format: float received_funding: - type: string + type: number + format: float total_funding: - type: string + type: number + format: float examples: "0": value: | { - "available_funding": "8000000.00", - "carry_forward_funding": 0, + "available_funding": 8000000.00, + "carry_forward_funding": 8000000.00, "cans": [{ "can":{ "appropriation_date": "01/10/2022", @@ -1258,14 +1268,14 @@ paths: "carry_forward_label": "Carry-Forward", "expiration_date": "09/01/2023", }], - "expected_funding": "4000000.00", - "in_draft_funding": "500000.00", - "in_execution_funding": "2000000.00", - "new_funding": "2000000.00", + "expected_funding": 4000000.00, + "in_draft_funding": 500000.00, + "in_execution_funding": 2000000.00, + "new_funding": 2000000.00, "obligated_funding": 0, "planned_funding": 0, - "received_funding": "6000000.00", - "total_funding": "10000000.00" + "received_funding": 6000000.00, + "total_funding": 10000000.00 } /api/v1/users/: get: From 254fd0d629479deb0c5abc1cb9b38007eb863722 Mon Sep 17 00:00:00 2001 From: maiyerlee Date: Mon, 20 Jan 2025 22:23:53 -0600 Subject: [PATCH 2/9] feat: update CAN funding summary marshmallow schema --- .../ops/schemas/can_funding_summary.py | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/backend/ops_api/ops/schemas/can_funding_summary.py b/backend/ops_api/ops/schemas/can_funding_summary.py index 382994e3f3..fddbd262eb 100644 --- a/backend/ops_api/ops/schemas/can_funding_summary.py +++ b/backend/ops_api/ops/schemas/can_funding_summary.py @@ -18,14 +18,14 @@ class CANSFundingSourceSchema(Schema): class GetCANFundingSummaryResponseSchema(Schema): - available_funding = fields.String(allow_none=True) + available_funding = fields.Float(allow_none=True) cans = fields.List(fields.Nested(CANSFundingSourceSchema()), default=[]) - carry_forward_funding = fields.String(allow_none=True) - expected_funding = fields.String(allow_none=True) - in_draft_funding = fields.String(allow_none=True) - in_execution_funding = fields.String(allow_none=True) - new_funding = fields.String(allow_none=True) - obligated_funding = fields.String(allow_none=True) - planned_funding = fields.String(allow_none=True) - received_funding = fields.String(allow_none=True) - total_funding = fields.String(allow_none=True) + carry_forward_funding = fields.Float(allow_none=True) + expected_funding = fields.Float(allow_none=True) + in_draft_funding = fields.Float(allow_none=True) + in_execution_funding = fields.Float(allow_none=True) + new_funding = fields.Float(allow_none=True) + obligated_funding = fields.Float(allow_none=True) + planned_funding = fields.Float(allow_none=True) + received_funding = fields.Float(allow_none=True) + total_funding = fields.Float(allow_none=True) From 32c9d93553945219cf60f913bb95e32e29eb2489 Mon Sep 17 00:00:00 2001 From: maiyerlee Date: Mon, 20 Jan 2025 22:35:43 -0600 Subject: [PATCH 3/9] feat: update aggregate method return and fix unittests --- backend/ops_api/ops/utils/cans.py | 28 ++++---- .../test_can_funding_summary.py | 64 +++++++++---------- 2 files changed, 46 insertions(+), 46 deletions(-) diff --git a/backend/ops_api/ops/utils/cans.py b/backend/ops_api/ops/utils/cans.py index 02bbf6af01..fff9482d20 100644 --- a/backend/ops_api/ops/utils/cans.py +++ b/backend/ops_api/ops/utils/cans.py @@ -193,24 +193,24 @@ def get_filtered_cans(cans, fiscal_year=None, active_period=None, transfer=None, return cans -def aggregate_funding_summaries(funding_summaries: List[dict]) -> dict: +def aggregate_funding_summaries(funding_summaries: List[dict]) -> CanFundingSummary: """ Aggregates the funding summaries for multiple cans into a single total funding summary. :param funding_summaries: List of funding summaries to aggregate :return: A single total funding summary """ totals = { - "available_funding": "0.0", + "available_funding": 0.0, "cans": [], - "carry_forward_funding": "0.0", - "expected_funding": "0.0", - "in_draft_funding": "0.0", - "in_execution_funding": "0.0", - "new_funding": "0.0", - "obligated_funding": "0.0", - "planned_funding": "0.0", - "received_funding": "0.0", - "total_funding": "0.0", + "carry_forward_funding": 0.0, + "expected_funding": 0.0, + "in_draft_funding": 0.0, + "in_execution_funding": 0.0, + "new_funding": 0.0, + "obligated_funding": 0.0, + "planned_funding": 0.0, + "received_funding": 0.0, + "total_funding": 0.0, } for summary in funding_summaries: @@ -218,10 +218,10 @@ def aggregate_funding_summaries(funding_summaries: List[dict]) -> dict: if key != "cans": current_value = summary.get(key, None) if current_value is None: - current_value = "0.0" + current_value = 0.0 if isinstance(current_value, (int, float, Decimal)): - current_value = str(Decimal(current_value)) - totals[key] = str(Decimal(totals[key]) + Decimal(current_value)) + current_value = Decimal(current_value) + totals[key] = Decimal(totals[key]) + Decimal(current_value) totals["cans"].append(summary.get("cans", [])[0]) 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 a38012bc72..3d370feb35 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 @@ -55,9 +55,9 @@ def test_can_get_can_funding_summary_cost_share_transfer(auth_client: FlaskClien assert response.status_code == 200 assert len(response.json["cans"]) == 0 - assert response.json["expected_funding"] == "0.0" - assert response.json["received_funding"] == "0.0" - assert response.json["total_funding"] == "0.0" + assert response.json["expected_funding"] == 0.0 + assert response.json["received_funding"] == 0.0 + assert response.json["total_funding"] == 0.0 def test_can_get_can_funding_summary_invalid_transfer(auth_client: FlaskClient): @@ -92,16 +92,16 @@ def test_can_get_can_funding_summary_all_cans_no_fiscal_year_match( assert response.status_code == 200 assert len(response.json["cans"]) == 0 - assert response.json["available_funding"] == "0.0" - assert response.json["carry_forward_funding"] == "0.0" - assert response.json["expected_funding"] == "0.0" - assert response.json["in_draft_funding"] == "0.0" - assert response.json["in_execution_funding"] == "0.0" - assert response.json["new_funding"] == "0.0" - assert response.json["obligated_funding"] == "0.0" - assert response.json["planned_funding"] == "0.0" - assert response.json["received_funding"] == "0.0" - assert response.json["total_funding"] == "0.0" + assert response.json["available_funding"] == 0.0 + assert response.json["carry_forward_funding"] == 0.0 + assert response.json["expected_funding"] == 0.0 + assert response.json["in_draft_funding"] == 0.0 + assert response.json["in_execution_funding"] == 0.0 + assert response.json["new_funding"] == 0.0 + assert response.json["obligated_funding"] == 0.0 + assert response.json["planned_funding"] == 0.0 + assert response.json["received_funding"] == 0.0 + assert response.json["total_funding"] == 0.0 @pytest.mark.usefixtures("app_ctx") @@ -280,7 +280,7 @@ def test_get_can_funding_summary_with_fiscal_year(loaded_db, test_can) -> None: } ], "carry_forward_funding": 0, - "in_draft_funding": Decimal("0.0"), + "in_draft_funding": 0, "expected_funding": Decimal("260000.0"), "in_execution_funding": 0, "obligated_funding": 0, @@ -299,7 +299,7 @@ def test_can_get_can_funding_summary(auth_client: FlaskClient, test_can: CAN) -> assert response.status_code == 200 assert response.json["cans"][0]["can"]["id"] == test_can.id assert "new_funding" in response.json - assert isinstance(response.json["new_funding"], str) + assert isinstance(response.json["new_funding"], float) assert "expiration_date" in response.json["cans"][0] assert "carry_forward_label" in response.json["cans"][0] @@ -315,9 +315,9 @@ def test_cans_get_can_funding_summary(auth_client: FlaskClient, test_cans: list[ assert response.status_code == 200 assert len(response.json["cans"]) == 2 - assert available_funding == "3340000.00" - assert carry_forward_funding == "10000000.0" - assert response.json["new_funding"] == "1340000.0" + assert available_funding == 3340000.00 + assert carry_forward_funding == 10000000.0 + assert response.json["new_funding"] == 1340000.0 def test_can_get_can_funding_summary_filter(auth_client: FlaskClient, test_cans: list[Type[CAN]]) -> None: @@ -337,9 +337,9 @@ def test_can_get_can_funding_summary_transfer_filter(auth_client: FlaskClient) - assert response.status_code == 200 assert len(response.json["cans"]) == 6 - assert response.json["expected_funding"] == "4520000.0" - assert response.json["received_funding"] == "8760000.0" - assert response.json["total_funding"] == "13280000.0" + assert response.json["expected_funding"] == 4520000.0 + assert response.json["received_funding"] == 8760000.0 + assert response.json["total_funding"] == 13280000.0 def test_can_get_can_funding_summary_complete_filter(auth_client: FlaskClient, test_cans: list[Type[CAN]]) -> None: @@ -358,7 +358,7 @@ def test_can_get_can_funding_summary_complete_filter(auth_client: FlaskClient, t assert response.status_code == 200 assert len(response.json["cans"]) == 0 assert "new_funding" in response.json - assert response.json["obligated_funding"] == "0.0" + assert response.json["obligated_funding"] == 0.0 def test_get_nested_attribute_existing_attribute(): @@ -510,7 +510,7 @@ def test_aggregate_funding_summaries(): result = aggregate_funding_summaries(funding_sums) assert result == { - "available_funding": "250000.0", + "available_funding": 250000.0, "cans": [ { "can": {"amount": 50000, "description": "Grant for educational projects", "id": 1, "obligate_by": 2025}, @@ -528,15 +528,15 @@ def test_aggregate_funding_summaries(): "expiration_date": "10/01/2026", }, ], - "carry_forward_funding": "50000.0", - "expected_funding": "130000.0", - "in_draft_funding": "0.0", - "in_execution_funding": "130000.0", - "new_funding": "300000.0", - "obligated_funding": "80000.0", - "planned_funding": "280000.0", - "received_funding": "175000.0", - "total_funding": "305000.0", + "carry_forward_funding": 50000.0, + "expected_funding": 130000.0, + "in_draft_funding": 0.0, + "in_execution_funding": 130000.0, + "new_funding": 300000.0, + "obligated_funding": 80000.0, + "planned_funding": 280000.0, + "received_funding": 175000.0, + "total_funding": 305000.0, } From f63b7d4a50abab18f0681985a7121539d396f463 Mon Sep 17 00:00:00 2001 From: maiyerlee Date: Tue, 21 Jan 2025 09:13:52 -0600 Subject: [PATCH 4/9] fix: match funding total type --- backend/ops_api/ops/utils/cans.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/ops_api/ops/utils/cans.py b/backend/ops_api/ops/utils/cans.py index fff9482d20..0cbd38df04 100644 --- a/backend/ops_api/ops/utils/cans.py +++ b/backend/ops_api/ops/utils/cans.py @@ -199,7 +199,7 @@ def aggregate_funding_summaries(funding_summaries: List[dict]) -> CanFundingSumm :param funding_summaries: List of funding summaries to aggregate :return: A single total funding summary """ - totals = { + totals: CanFundingSummary = { "available_funding": 0.0, "cans": [], "carry_forward_funding": 0.0, From 5711cb9fa2bee83da0da57368ea7235830180e5a Mon Sep 17 00:00:00 2001 From: maiyerlee Date: Tue, 21 Jan 2025 14:43:42 -0600 Subject: [PATCH 5/9] test: fix funding summary unit tests --- .../ops/funding_summary/test_can_funding_summary.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) 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 378bae070b..11e0b2f08b 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 @@ -337,9 +337,9 @@ def test_can_get_can_funding_summary_transfer_filter(auth_client: FlaskClient) - assert response.status_code == 200 assert len(response.json["cans"]) == 6 - assert response.json["expected_funding"] == "4520000.0" - assert response.json["received_funding"] == "8760000.0" - assert response.json["total_funding"] == "13280000.0" + assert response.json["expected_funding"] == 4520000.0 + assert response.json["received_funding"] == 8760000.0 + assert response.json["total_funding"] == 13280000.0 def test_can_get_can_funding_summary_complete_filter(auth_client: FlaskClient, test_cans: list[Type[CAN]]) -> None: @@ -358,7 +358,7 @@ def test_can_get_can_funding_summary_complete_filter(auth_client: FlaskClient, t assert response.status_code == 200 assert len(response.json["cans"]) == 0 assert "new_funding" in response.json - assert response.json["obligated_funding"] == "0.0" + assert response.json["obligated_funding"] == 0.0 def test_get_nested_attribute_existing_attribute(): @@ -471,7 +471,7 @@ def test_aggregate_funding_summaries(): "expiration_date": "10/01/2025", } ], - "carry_forward_funding": 20000, + "carry_forward_funding": 100000, "received_funding": 75000, "expected_funding": 125000 - 75000, "in_draft_funding": 0, @@ -495,7 +495,7 @@ def test_aggregate_funding_summaries(): "expiration_date": "10/01/2026", } ], - "carry_forward_funding": 30000, + "carry_forward_funding": 150000, "received_funding": 100000, "expected_funding": 180000 - 100000, "in_draft_funding": 0, From c0108854180e806ac2c4e974dd0dee8872cd3819 Mon Sep 17 00:00:00 2001 From: maiyerlee Date: Tue, 21 Jan 2025 23:05:51 -0600 Subject: [PATCH 6/9] test: fix frontend test data --- .../AgreementCANReviewAccordion.test.jsx | 42 +++++++++---------- .../CANFundingCard/CanFundingCard.test.jsx | 14 +++---- 2 files changed, 28 insertions(+), 28 deletions(-) diff --git a/frontend/src/components/Agreements/AgreementCANReviewAccordion/AgreementCANReviewAccordion.test.jsx b/frontend/src/components/Agreements/AgreementCANReviewAccordion/AgreementCANReviewAccordion.test.jsx index 2c8f95887a..b1d2feb286 100644 --- a/frontend/src/components/Agreements/AgreementCANReviewAccordion/AgreementCANReviewAccordion.test.jsx +++ b/frontend/src/components/Agreements/AgreementCANReviewAccordion/AgreementCANReviewAccordion.test.jsx @@ -1235,7 +1235,7 @@ const canData = [ ]; const canFundingCardData = { - available_funding: "14300000.00", + available_funding: 14300000.0, cans: [ { can: { @@ -1273,19 +1273,19 @@ const canFundingCardData = { expiration_date: "09/01/2024" } ], - carry_forward_funding: "14300000.00", - expected_funding: "5000000.00", + carry_forward_funding: 14300000.0, + expected_funding: 5000000.0, in_draft_funding: 0, - in_execution_funding: "2000000.00", + in_execution_funding: 2000000.0, new_funding: 0, obligated_funding: 0, - planned_funding: "7700000.00", - received_funding: "19000000.00", - total_funding: "24000000.00" + planned_funding: 7700000.0, + received_funding: 19000000.0, + total_funding: 24000000.0 }; const canFundingCardData2 = { - available_funding: "1979500.00", + available_funding: 1979500.0, cans: [ { can: { @@ -1323,17 +1323,17 @@ const canFundingCardData2 = { expiration_date: "09/01/2023" } ], - carry_forward_funding: "1979500.00", - expected_funding: "520000.00", + carry_forward_funding: 1979500.0, + expected_funding: 520000.0, in_execution_funding: 0, - obligated_funding: "500.00", - planned_funding: "300000.00", - received_funding: "1760000.00", - total_funding: "2280000.00" + obligated_funding: 500.0, + planned_funding: 300000.0, + received_funding: 1760000.0, + total_funding: 2280000.0 }; const canFundingCard_G994426 = { - available_funding: "37000000.00", + available_funding: 37000000.0, cans: [ { can: { @@ -1371,13 +1371,13 @@ const canFundingCard_G994426 = { expiration_date: "09/01/2024" } ], - carry_forward_funding: "37000000.00", - expected_funding: "16000000.00", - in_execution_funding: "2000000.00", + carry_forward_funding: 37000000.0, + expected_funding: 16000000.0, + in_execution_funding: 2000000.0, obligated_funding: 0, - planned_funding: "1000000.00", - received_funding: "24000000.00", - total_funding: "40000000.00" + planned_funding: 1000000.0, + received_funding: 24000000.0, + total_funding: 40000000.0 }; const selectedBudgetLinesToAmount = [ diff --git a/frontend/src/components/CANs/CANFundingCard/CanFundingCard.test.jsx b/frontend/src/components/CANs/CANFundingCard/CanFundingCard.test.jsx index 9116b40909..9e56cf4819 100644 --- a/frontend/src/components/CANs/CANFundingCard/CanFundingCard.test.jsx +++ b/frontend/src/components/CANs/CANFundingCard/CanFundingCard.test.jsx @@ -53,7 +53,7 @@ const canData = { }; const canFundingCardData = { - available_funding: "14300000.00", + available_funding: 14300000.0, cans: [ { can: { @@ -91,13 +91,13 @@ const canFundingCardData = { expiration_date: "09/01/2024" } ], - carry_forward_funding: "14300000.00", - expected_funding: "5000000.00", + carry_forward_funding: 14300000.0, + expected_funding: 5000000.0, in_draft_funding: 0, - in_execution_funding: "2000000.00", + in_execution_funding: 2000000.0, new_funding: 0, obligated_funding: 0, - planned_funding: "7700000.00", - received_funding: "19000000.00", - total_funding: "24000000.00" + planned_funding: 7700000.0, + received_funding: 19000000.0, + total_funding: 24000000.0 }; From 92d894ace32d4c8b32c3fcdfc42a5ed1b3183383 Mon Sep 17 00:00:00 2001 From: maiyerlee Date: Mon, 27 Jan 2025 10:12:00 -0600 Subject: [PATCH 7/9] fix: update TS for funding summary --- frontend/src/components/CANs/CANTypes.d.ts | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/frontend/src/components/CANs/CANTypes.d.ts b/frontend/src/components/CANs/CANTypes.d.ts index d1ab9d2f6a..5f47679e07 100644 --- a/frontend/src/components/CANs/CANTypes.d.ts +++ b/frontend/src/components/CANs/CANTypes.d.ts @@ -109,17 +109,17 @@ export type FundingReceived = { }; export type FundingSummary = { - available_funding: string; + available_funding: number; cans: FundingSummaryCAN[]; - carry_forward_funding: string; - expected_funding: string; - in_draft_funding: string; - in_execution_funding: string; - new_funding: string; - obligated_funding: string; - planned_funding: string; - received_funding: string; - total_funding: string; + carry_forward_funding: number; + expected_funding: number; + in_draft_funding: number; + in_execution_funding: number; + new_funding: number; + obligated_funding: number; + planned_funding: number; + received_funding: number; + total_funding: number; }; export type FundingSummaryCAN = { From cc52c6a84b375ceca6c90b8d373c79f021e923e8 Mon Sep 17 00:00:00 2001 From: maiyerlee Date: Mon, 27 Jan 2025 10:36:37 -0600 Subject: [PATCH 8/9] test: fix BE unittest --- .../test_can_funding_summary.py | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) 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 4486c46144..32868179d3 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 @@ -503,7 +503,7 @@ def test_aggregate_funding_summaries(): result = aggregate_funding_summaries(funding_sums) assert result == { - "available_funding": 250000.0, + "available_funding": Decimal("250000"), "cans": [ { "can": {"amount": 50000, "description": "Grant for educational projects", "id": 1, "obligate_by": 2025}, @@ -521,15 +521,15 @@ def test_aggregate_funding_summaries(): "expiration_date": "10/01/2026", }, ], - "carry_forward_funding": 250000.0, - "expected_funding": 130000.0, - "in_draft_funding": 0.0, - "in_execution_funding": 130000.0, - "new_funding": 300000.0, - "obligated_funding": 80000.0, - "planned_funding": 280000.0, - "received_funding": 175000.0, - "total_funding": 305000.0, + "carry_forward_funding": Decimal("170000"), + "expected_funding": Decimal("130000"), + "in_draft_funding": Decimal("0"), + "in_execution_funding": Decimal("130000"), + "new_funding": Decimal("300000"), + "obligated_funding": Decimal("80000"), + "planned_funding": Decimal("280000"), + "received_funding": Decimal("175000"), + "total_funding": Decimal("305000"), } From cc882ab9611b84559a6c27161cc19ad22e3fc7ca Mon Sep 17 00:00:00 2001 From: maiyerlee Date: Wed, 29 Jan 2025 00:14:29 -0600 Subject: [PATCH 9/9] test: fix welcome modal popup in can details e2e test --- frontend/src/pages/cans/detail/Can.hooks.js | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/frontend/src/pages/cans/detail/Can.hooks.js b/frontend/src/pages/cans/detail/Can.hooks.js index d5983269e6..7eda10f0a7 100644 --- a/frontend/src/pages/cans/detail/Can.hooks.js +++ b/frontend/src/pages/cans/detail/Can.hooks.js @@ -93,7 +93,7 @@ export default function useCan() { ); const toggleEditMode = () => { - if (isFundingPage && CANFunding?.total_funding === "0") { + if (isFundingPage && CANFunding?.total_funding === 0) { setModalProps({ heading: `Welcome to FY ${fiscalYear}! The new fiscal year started on October 1, ${fiscalYear - 1} and it's time to add the FY budget for this CAN. Data from the previous fiscal year can no longer be edited, but can be viewed by changing the FY dropdown on the CAN details page.`, actionButtonText: "Edit CAN", @@ -135,12 +135,12 @@ export default function useCan() { teamLeaders: can?.portfolio?.team_leaders ?? [], portfolioName: can?.portfolio?.name, portfolioId: can?.portfolio_id ?? -1, - totalFunding: CANFunding?.total_funding ?? "0", - plannedFunding: CANFunding?.planned_funding ?? "0", - obligatedFunding: CANFunding?.obligated_funding ?? "0", - inExecutionFunding: CANFunding?.in_execution_funding ?? "0", - inDraftFunding: CANFunding?.in_draft_funding ?? "0", - receivedFunding: CANFunding?.received_funding ?? "0", + totalFunding: CANFunding?.total_funding ?? 0, + plannedFunding: CANFunding?.planned_funding ?? 0, + obligatedFunding: CANFunding?.obligated_funding ?? 0, + inExecutionFunding: CANFunding?.in_execution_funding ?? 0, + inDraftFunding: CANFunding?.in_draft_funding ?? 0, + receivedFunding: CANFunding?.received_funding ?? 0, carryForwardFunding: previousFYfundingSummary?.available_funding ?? 0, subTitle: can?.nick_name ?? "", projectTypesCount,