From 1d7daac260a9825689b67ecfefbaa481f3bf53ca Mon Sep 17 00:00:00 2001 From: Victor Shia Date: Wed, 25 Sep 2024 13:39:05 -0700 Subject: [PATCH] Serialize decimal with 2 decimal points (#441) * chore: Add CustomDecimal_13Digits * chore: Add CustomDecimal_12Digits * chore: 13 digits * chore: Add CustomDecimal_7Digits * chore: Add CustomDecimal_15Digits * chore: update import * chore: Add CustomDecimal_12Digits * chore: Add CustomDecimal_13Digits * chore: Add CustomDecimal_7Digits * chore: Update imports * chore: Update generate_treasury_report with str --------- Co-authored-by: Victor Shia <401047+vshia@users.noreply.github.com> --- .../src/functions/generate_treasury_report.py | 2 +- python/src/schemas/custom_types.py | 54 ++++++++++++ python/src/schemas/schema_V2024_04_01.py | 50 +++++------ python/src/schemas/schema_V2024_05_24.py | 84 +++++++------------ 4 files changed, 108 insertions(+), 82 deletions(-) create mode 100644 python/src/schemas/custom_types.py diff --git a/python/src/functions/generate_treasury_report.py b/python/src/functions/generate_treasury_report.py index b12f9d51..6b974205 100644 --- a/python/src/functions/generate_treasury_report.py +++ b/python/src/functions/generate_treasury_report.py @@ -447,7 +447,7 @@ def insert_project_row( if prop_meta[f"treasury_report_col_{project_use_code}"]: row_with_output_cols[ prop_meta[f"treasury_report_col_{project_use_code}"] - ] = row_dict[prop] if row_dict[prop] else "" + ] = str(row_dict[prop]) if row_dict[prop] else "" for col in row_with_output_cols.keys(): if sheet: diff --git a/python/src/schemas/custom_types.py b/python/src/schemas/custom_types.py new file mode 100644 index 00000000..7b80bb5c --- /dev/null +++ b/python/src/schemas/custom_types.py @@ -0,0 +1,54 @@ +from typing_extensions import Annotated +from pydantic import BaseModel, Field, PlainSerializer +from decimal import Decimal + + +CustomDecimal_16Digits = Annotated[ + Decimal, Field( + max_digits=16, + decimal_places=2 + ), PlainSerializer( + lambda x: f"{float(x):.2f}", + return_type=str, + ), +] + +CustomDecimal_15Digits = Annotated[ + Decimal, Field( + max_digits=15, + decimal_places=2 + ), PlainSerializer( + lambda x: f"{float(x):.2f}", + return_type=str, + ), +] + +CustomDecimal_13Digits = Annotated[ + Decimal, Field( + max_digits=13, + decimal_places=2 + ), PlainSerializer( + lambda x: f"{float(x):.2f}", + return_type=str, + ), +] + +CustomDecimal_12Digits = Annotated[ + Decimal, Field( + max_digits=12, + decimal_places=2 + ), PlainSerializer( + lambda x: f"{float(x):.2f}", + return_type=str, + ), +] + +CustomDecimal_7Digits = Annotated[ + Decimal, Field( + max_digits=7, + decimal_places=2 + ), PlainSerializer( + lambda x: f"{float(x):.2f}", + return_type=str, + ), +] diff --git a/python/src/schemas/schema_V2024_04_01.py b/python/src/schemas/schema_V2024_04_01.py index 6c6ce46c..44c585fa 100644 --- a/python/src/schemas/schema_V2024_04_01.py +++ b/python/src/schemas/schema_V2024_04_01.py @@ -7,7 +7,6 @@ ConfigDict, Field, ValidationInfo, - condecimal, conint, constr, field_serializer, @@ -15,6 +14,11 @@ ) from src.schemas.project_types import NAME_BY_PROJECT +from src.schemas.custom_types import ( + CustomDecimal_7Digits, + CustomDecimal_12Digits, + CustomDecimal_13Digits, +) class StateAbbreviation(str, Enum): @@ -137,14 +141,14 @@ class BaseProjectRow(BaseModel): serialization_alias="Capital Asset Owenership Type", json_schema_extra={"column": "F"}, ) - Total_CPF_Funding_for_Project__c: condecimal(max_digits=13, decimal_places=2) = ( + Total_CPF_Funding_for_Project__c: CustomDecimal_13Digits = ( Field( ..., serialization_alias="Total CPF Funding for Project", json_schema_extra={"column": "G"}, ) ) - Total_from_all_funding_sources__c: condecimal(max_digits=13, decimal_places=2) = ( + Total_from_all_funding_sources__c: CustomDecimal_13Digits = ( Field( ..., serialization_alias="Total From all Funding Sources", @@ -157,22 +161,22 @@ class BaseProjectRow(BaseModel): max_length=3000, json_schema_extra={"column": "I"}, ) - Current_Period_Obligation__c: condecimal(max_digits=12, decimal_places=2) = Field( + Current_Period_Obligation__c: CustomDecimal_12Digits = Field( ..., serialization_alias="Current Period Obligation", json_schema_extra={"column": "J"}, ) - Current_Period_Expenditure__c: condecimal(max_digits=12, decimal_places=2) = Field( + Current_Period_Expenditure__c: CustomDecimal_12Digits = Field( ..., serialization_alias="Current Period Expenditure", json_schema_extra={"column": "K"}, ) - Cumulative_Obligation__c: condecimal(max_digits=12, decimal_places=2) = Field( + Cumulative_Obligation__c: CustomDecimal_12Digits = Field( ..., serialization_alias="Cumulative Obligation", json_schema_extra={"column": "L"}, ) - Cumulative_Expenditure__c: condecimal(max_digits=12, decimal_places=2) = Field( + Cumulative_Expenditure__c: CustomDecimal_12Digits = Field( ..., serialization_alias="Cumulative Expenditure", json_schema_extra={"column": "M"}, @@ -240,9 +244,7 @@ class BaseProjectRow(BaseModel): max_length=50, json_schema_extra={"column": "Z"}, ) - Amount_of_Matching_Funds__c: Optional[ - condecimal(max_digits=12, decimal_places=2) - ] = Field( + Amount_of_Matching_Funds__c: Optional[CustomDecimal_12Digits] = Field( default=None, serialization_alias="Amount of Matching Funds", json_schema_extra={"column": "AA"}, @@ -623,16 +625,14 @@ class Project1BRow(BaseProjectRow, AddressFields): serialization_alias="Laptops (Actual)", json_schema_extra={"column": "CC"}, ) - Laptops_Expenditures_Planned__c: condecimal(max_digits=13, decimal_places=2) = ( + Laptops_Expenditures_Planned__c: CustomDecimal_13Digits = ( Field( ..., serialization_alias="Laptops Expenditure (Planned)", json_schema_extra={"column": "CD"}, ) ) - Laptops_Expenditures_Actual__c: Optional[ - condecimal(max_digits=13, decimal_places=2) - ] = Field( + Laptops_Expenditures_Actual__c: Optional[CustomDecimal_13Digits] = Field( default=None, serialization_alias="Laptops Expenditure (Actual)", json_schema_extra={"column": "CE"}, @@ -645,14 +645,12 @@ class Project1BRow(BaseProjectRow, AddressFields): serialization_alias="Tablets (Actual)", json_schema_extra={"column": "CG"}, ) - Tablet_Expenditures_Planned__c: condecimal(max_digits=13, decimal_places=2) = Field( + Tablet_Expenditures_Planned__c: CustomDecimal_13Digits = Field( ..., serialization_alias="Tablets Expenditure (Planned)", json_schema_extra={"column": "CH"}, ) - Tablets_Expenditures_Actual__c: Optional[ - condecimal(max_digits=13, decimal_places=2) - ] = Field( + Tablets_Expenditures_Actual__c: Optional[CustomDecimal_13Digits] = Field( default=None, serialization_alias="Tablets Expenditure (Actual)", json_schema_extra={"column": "CI"}, @@ -667,15 +665,13 @@ class Project1BRow(BaseProjectRow, AddressFields): serialization_alias="Desktop Computers (Actual)", json_schema_extra={"column": "CK"}, ) - Desktop_Computers_Expenditures_Planned__c: condecimal( - max_digits=13, decimal_places=2 - ) = Field( + Desktop_Computers_Expenditures_Planned__c: CustomDecimal_13Digits = Field( ..., serialization_alias="Desktop Computers Expenditure (Planned)", json_schema_extra={"column": "CL"}, ) Desktop_Computers_Expenditures_Actual__c: Optional[ - condecimal(max_digits=13, decimal_places=2) + CustomDecimal_13Digits ] = Field( default=None, serialization_alias="Desktop Computers Expenditure (Actual)", @@ -691,7 +687,7 @@ class Project1BRow(BaseProjectRow, AddressFields): serialization_alias="Public WiFi (Actual)", json_schema_extra={"column": "CO"}, ) - Public_WiFi_Expenditures_Planned__c: condecimal(max_digits=13, decimal_places=2) = ( + Public_WiFi_Expenditures_Planned__c: CustomDecimal_13Digits = ( Field( ..., serialization_alias="Public Wifi Expenditures (Planned)", @@ -699,7 +695,7 @@ class Project1BRow(BaseProjectRow, AddressFields): ) ) Public_WiFi_Expenditures_Actual__c: Optional[ - condecimal(max_digits=13, decimal_places=2) + CustomDecimal_13Digits ] = Field( default=None, serialization_alias="Public Wifi Expenditures (Actual)", @@ -715,14 +711,12 @@ class Project1BRow(BaseProjectRow, AddressFields): serialization_alias="Other Devices (Actual)", json_schema_extra={"column": "CS"}, ) - Other_Expenditures_Planned__c: condecimal(max_digits=7, decimal_places=2) = Field( + Other_Expenditures_Planned__c: CustomDecimal_7Digits = Field( ..., serialization_alias="Other Expenditures (Planned)", json_schema_extra={"column": "CT"}, ) - Other_Expenditures_Actual__c: Optional[ - condecimal(max_digits=7, decimal_places=2) - ] = Field( + Other_Expenditures_Actual__c: Optional[CustomDecimal_7Digits] = Field( default=None, serialization_alias="Other Expenditures (Actual)", json_schema_extra={"column": "CU"}, diff --git a/python/src/schemas/schema_V2024_05_24.py b/python/src/schemas/schema_V2024_05_24.py index 25d33fd7..18c6cea8 100644 --- a/python/src/schemas/schema_V2024_05_24.py +++ b/python/src/schemas/schema_V2024_05_24.py @@ -7,7 +7,6 @@ ConfigDict, Field, ValidationInfo, - condecimal, conint, constr, field_serializer, @@ -15,7 +14,12 @@ ) from src.schemas.project_types import NAME_BY_PROJECT - +from src.schemas.custom_types import ( + CustomDecimal_7Digits, + CustomDecimal_12Digits, + CustomDecimal_13Digits, + CustomDecimal_15Digits, +) class StateAbbreviation(str, Enum): AL = "AL" @@ -205,7 +209,7 @@ class BaseProjectRow(BaseModel): "treasury_report_col_1C": "G", }, ) - Total_CPF_Funding_for_Project__c: condecimal(max_digits=13, decimal_places=2) = ( + Total_CPF_Funding_for_Project__c: CustomDecimal_13Digits = ( Field( ..., serialization_alias="Total CPF Funding for Project", @@ -217,7 +221,7 @@ class BaseProjectRow(BaseModel): }, ) ) - Total_from_all_funding_sources__c: condecimal(max_digits=13, decimal_places=2) = ( + Total_from_all_funding_sources__c: CustomDecimal_13Digits = ( Field( ..., serialization_alias="Total From all Funding Sources", @@ -240,7 +244,7 @@ class BaseProjectRow(BaseModel): "treasury_report_col_1C": "J", }, ) - Current_Period_Obligation__c: condecimal(max_digits=12, decimal_places=2) = Field( + Current_Period_Obligation__c: CustomDecimal_12Digits = Field( ..., serialization_alias="Current Period Obligation", @@ -251,7 +255,7 @@ class BaseProjectRow(BaseModel): "treasury_report_col_1C": "K", }, ) - Current_Period_Expenditure__c: condecimal(max_digits=12, decimal_places=2) = Field( + Current_Period_Expenditure__c: CustomDecimal_12Digits = Field( ..., serialization_alias="Current Period Expenditure", json_schema_extra={ @@ -261,7 +265,7 @@ class BaseProjectRow(BaseModel): "treasury_report_col_1C": "L", }, ) - Cumulative_Obligation__c: condecimal(max_digits=12, decimal_places=2) = Field( + Cumulative_Obligation__c: CustomDecimal_12Digits = Field( ..., serialization_alias="Cumulative Obligation", json_schema_extra={ @@ -271,7 +275,7 @@ class BaseProjectRow(BaseModel): "treasury_report_col_1C": "M", }, ) - Cumulative_Expenditure__c: condecimal(max_digits=12, decimal_places=2) = Field( + Cumulative_Expenditure__c: CustomDecimal_12Digits = Field( ..., serialization_alias="Cumulative Expenditure", json_schema_extra={ @@ -415,9 +419,7 @@ class BaseProjectRow(BaseModel): "treasury_report_col_1C": "AG", }, ) - Amount_of_Matching_Funds__c: Optional[ - condecimal(max_digits=12, decimal_places=2) - ] = Field( + Amount_of_Matching_Funds__c: Optional[CustomDecimal_12Digits] = Field( default=None, serialization_alias="Amount of Matching Funds", json_schema_extra={ @@ -938,16 +940,14 @@ class Project1BRow(BaseProjectRow, AddressFields): serialization_alias="Laptops (Actual)", json_schema_extra={"column": "CE", "treasury_report_col_1B": "BK"}, ) - Laptops_Expenditures_Planned__c: condecimal(max_digits=13, decimal_places=2) = ( + Laptops_Expenditures_Planned__c: CustomDecimal_13Digits = ( Field( ..., serialization_alias="Laptops Expenditure (Planned)", json_schema_extra={"column": "CF", "treasury_report_col_1B": "BL"}, ) ) - Laptops_Expenditures_Actual__c: Optional[ - condecimal(max_digits=13, decimal_places=2) - ] = Field( + Laptops_Expenditures_Actual__c: Optional[CustomDecimal_13Digits] = Field( default=None, serialization_alias="Laptops Expenditure (Actual)", json_schema_extra={"column": "CG", "treasury_report_col_1B": "BM"}, @@ -962,14 +962,12 @@ class Project1BRow(BaseProjectRow, AddressFields): serialization_alias="Tablets (Actual)", json_schema_extra={"column": "CI", "treasury_report_col_1B": "BO"}, ) - Tablet_Expenditures_Planned__c: condecimal(max_digits=13, decimal_places=2) = Field( + Tablet_Expenditures_Planned__c: CustomDecimal_13Digits = Field( ..., serialization_alias="Tablets Expenditure (Planned)", json_schema_extra={"column": "CJ", "treasury_report_col_1B": "BP"}, ) - Tablets_Expenditures_Actual__c: Optional[ - condecimal(max_digits=13, decimal_places=2) - ] = Field( + Tablets_Expenditures_Actual__c: Optional[CustomDecimal_13Digits] = Field( default=None, serialization_alias="Tablets Expenditure (Actual)", json_schema_extra={"column": "CK", "treasury_report_col_1B": "BQ"}, @@ -984,15 +982,13 @@ class Project1BRow(BaseProjectRow, AddressFields): serialization_alias="Desktop Computers (Actual)", json_schema_extra={"column": "CM", "treasury_report_col_1B": "BS"}, ) - Desktop_Computers_Expenditures_Planned__c: condecimal( - max_digits=13, decimal_places=2 - ) = Field( + Desktop_Computers_Expenditures_Planned__c: CustomDecimal_13Digits = Field( ..., serialization_alias="Desktop Computers Expenditure (Planned)", json_schema_extra={"column": "CN", "treasury_report_col_1B": "BT"}, ) Desktop_Computers_Expenditures_Actual__c: Optional[ - condecimal(max_digits=13, decimal_places=2) + CustomDecimal_13Digits ] = Field( default=None, serialization_alias="Desktop Computers Expenditure (Actual)", @@ -1008,7 +1004,7 @@ class Project1BRow(BaseProjectRow, AddressFields): serialization_alias="Public WiFi (Actual)", json_schema_extra={"column": "CQ", "treasury_report_col_1B": "BW"}, ) - Public_WiFi_Expenditures_Planned__c: condecimal(max_digits=13, decimal_places=2) = ( + Public_WiFi_Expenditures_Planned__c: CustomDecimal_13Digits = ( Field( ..., serialization_alias="Public Wifi Expenditures (Planned)", @@ -1016,7 +1012,7 @@ class Project1BRow(BaseProjectRow, AddressFields): ) ) Public_WiFi_Expenditures_Actual__c: Optional[ - condecimal(max_digits=13, decimal_places=2) + CustomDecimal_13Digits ] = Field( default=None, serialization_alias="Public Wifi Expenditures (Actual)", @@ -1032,14 +1028,12 @@ class Project1BRow(BaseProjectRow, AddressFields): serialization_alias="Other Devices (Actual)", json_schema_extra={"column": "CU", "treasury_report_col_1B": "CA"}, ) - Other_Expenditures_Planned__c: condecimal(max_digits=7, decimal_places=2) = Field( + Other_Expenditures_Planned__c: CustomDecimal_7Digits = Field( ..., serialization_alias="Other Expenditures (Planned)", json_schema_extra={"column": "CV", "treasury_report_col_1B": "CB"}, ) - Other_Expenditures_Actual__c: Optional[ - condecimal(max_digits=7, decimal_places=2) - ] = Field( + Other_Expenditures_Actual__c: Optional[CustomDecimal_7Digits] = Field( default=None, serialization_alias="Other Expenditures (Actual)", json_schema_extra={"column": "CW", "treasury_report_col_1B": "CC"}, @@ -1079,30 +1073,22 @@ class Project1BRow(BaseProjectRow, AddressFields): json_schema_extra={"column": "DC", "treasury_report_col_1B": "CI"}, ) # Columns below exist on Project1CRow as well as Project1BRow, so they jump in column defs - Current_Program_Income_Earned__c: Optional[ - condecimal(max_digits=15, decimal_places=2) - ] = Field( + Current_Program_Income_Earned__c: Optional[CustomDecimal_15Digits] = Field( default=None, serialization_alias="Current Period Program Income Earned", json_schema_extra={"column": "DW", "treasury_report_col_1B": "O"}, ) - Current_Program_Income_Expended__c: Optional[ - condecimal(max_digits=15, decimal_places=2) - ] = Field( + Current_Program_Income_Expended__c: Optional[CustomDecimal_15Digits] = Field( default=None, serialization_alias="Current Period Program Income Expended", json_schema_extra={"column": "DX", "treasury_report_col_1B": "P"}, ) - Cumulative_Program_Income_Earned__c: Optional[ - condecimal(max_digits=15, decimal_places=2) - ] = Field( + Cumulative_Program_Income_Earned__c: Optional[CustomDecimal_15Digits] = Field( default=None, serialization_alias="Cumulative Program Income Earned", json_schema_extra={"column": "DY", "treasury_report_col_1B": "Q"}, ) - Cumulative_Program_Income_Expended__c: Optional[ - condecimal(max_digits=15, decimal_places=2) - ] = Field( + Cumulative_Program_Income_Expended__c: Optional[CustomDecimal_15Digits] = Field( default=None, serialization_alias="Cumulative Program Income Expended", json_schema_extra={"column": "DZ", "treasury_report_col_1B": "R"}, @@ -1236,30 +1222,22 @@ class Project1CRow(BaseProjectRow, AddressFields): json_schema_extra={"column": "DU", "treasury_report_col_1C": "CA"}, ) # Columns below exist on Project1BRow as well as Project1CRow - Current_Program_Income_Earned__c: Optional[ - condecimal(max_digits=15, decimal_places=2) - ] = Field( + Current_Program_Income_Earned__c: Optional[CustomDecimal_15Digits] = Field( default=None, serialization_alias="Current Period Program Income Earned", json_schema_extra={"column": "DW", "treasury_report_col_1C": "O"}, ) - Current_Program_Income_Expended__c: Optional[ - condecimal(max_digits=15, decimal_places=2) - ] = Field( + Current_Program_Income_Expended__c: Optional[CustomDecimal_15Digits] = Field( default=None, serialization_alias="Current Period Program Income Expended", json_schema_extra={"column": "DX", "treasury_report_col_1C": "P"}, ) - Cumulative_Program_Income_Earned__c: Optional[ - condecimal(max_digits=15, decimal_places=2) - ] = Field( + Cumulative_Program_Income_Earned__c: Optional[CustomDecimal_15Digits] = Field( default=None, serialization_alias="Cumulative Program Income Earned", json_schema_extra={"column": "DY", "treasury_report_col_1C": "Q"}, ) - Cumulative_Program_Income_Expended__c: Optional[ - condecimal(max_digits=15, decimal_places=2) - ] = Field( + Cumulative_Program_Income_Expended__c: Optional[CustomDecimal_15Digits] = Field( default=None, serialization_alias="Cumulative Program Income Expended", json_schema_extra={"column": "DZ", "treasury_report_col_1C": "R"},