Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix funding response type on /can-funding-summary #3329

Merged
merged 15 commits into from
Jan 29, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 28 additions & 18 deletions backend/openapi.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand All @@ -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",
Expand All @@ -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:
Expand Down
20 changes: 10 additions & 10 deletions backend/ops_api/ops/schemas/can_funding_summary.py
Original file line number Diff line number Diff line change
Expand Up @@ -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)
30 changes: 15 additions & 15 deletions backend/ops_api/ops/utils/cans.py
Original file line number Diff line number Diff line change
Expand Up @@ -189,35 +189,35 @@ 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",
totals: CanFundingSummary = {
"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:
for key in totals:
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])

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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"]) == 1
assert response.json["expected_funding"] == "0.0"
assert response.json["received_funding"] == "200000.0"
assert response.json["total_funding"] == "200000.0"
assert response.json["expected_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):
Expand Down Expand Up @@ -85,16 +85,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")
Expand Down Expand Up @@ -292,7 +292,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]

Expand All @@ -308,9 +308,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 == "3340000.00"
assert response.json["new_funding"] == "1340000.0"
assert available_funding == 3340000.00
assert carry_forward_funding == 3340000.00
assert response.json["new_funding"] == 1340000.0


def test_can_get_can_funding_summary_filter(auth_client: FlaskClient, test_cans: list[Type[CAN]]) -> None:
Expand All @@ -330,9 +330,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:
Expand All @@ -351,7 +351,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():
Expand Down Expand Up @@ -488,7 +488,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,
Expand All @@ -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},
Expand All @@ -521,15 +521,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": 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"),
}


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1235,7 +1235,7 @@ const canData = [
];

const canFundingCardData = {
available_funding: "14300000.00",
available_funding: 14300000.0,
cans: [
{
can: {
Expand Down Expand Up @@ -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: {
Expand Down Expand Up @@ -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: {
Expand Down Expand Up @@ -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 = [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ const canData = {
};

const canFundingCardData = {
available_funding: "14300000.00",
available_funding: 14300000.0,
cans: [
{
can: {
Expand Down Expand Up @@ -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
};
Loading