diff --git a/crates/fmp-py/python/fmp/_native/statements/balance/__init__.pyi b/crates/fmp-py/python/fmp/_native/statements/balance/__init__.pyi index 157dacfe..3dea836f 100644 --- a/crates/fmp-py/python/fmp/_native/statements/balance/__init__.pyi +++ b/crates/fmp-py/python/fmp/_native/statements/balance/__init__.pyi @@ -93,105 +93,111 @@ class BalanceSheetStatement: @property def fiscal_year(self) -> builtins.str: ... @property - def cash_and_cash_equivalents(self) -> builtins.float: ... + def cash_and_cash_equivalents(self) -> typing.Optional[builtins.float]: ... @property - def short_term_investments(self) -> builtins.float: ... + def short_term_investments(self) -> typing.Optional[builtins.float]: ... @property - def cash_and_short_term_investments(self) -> builtins.float: ... + def cash_and_short_term_investments(self) -> typing.Optional[builtins.float]: ... @property - def net_receivables(self) -> builtins.float: ... + def net_receivables(self) -> typing.Optional[builtins.float]: ... @property - def accounts_receivables(self) -> builtins.float: ... + def accounts_receivables(self) -> typing.Optional[builtins.float]: ... @property def other_receivables(self) -> builtins.float: ... @property - def inventory(self) -> builtins.float: ... + def inventory(self) -> typing.Optional[builtins.float]: ... @property - def prepaids(self) -> builtins.float: ... + def prepaids(self) -> typing.Optional[builtins.float]: ... @property def other_current_assets(self) -> builtins.float: ... @property - def total_current_assets(self) -> builtins.float: ... + def total_current_assets(self) -> typing.Optional[builtins.float]: ... @property - def property_plant_equipment_net(self) -> builtins.float: ... + def property_plant_equipment_net(self) -> typing.Optional[builtins.float]: ... @property - def goodwill(self) -> builtins.float: ... + def goodwill(self) -> typing.Optional[builtins.float]: ... @property - def intangible_assets(self) -> builtins.float: ... + def intangible_assets(self) -> typing.Optional[builtins.float]: ... @property - def goodwill_and_intangible_assets(self) -> builtins.float: ... + def goodwill_and_intangible_assets(self) -> typing.Optional[builtins.float]: ... @property - def long_term_investments(self) -> builtins.float: ... + def long_term_investments(self) -> typing.Optional[builtins.float]: ... @property - def tax_assets(self) -> builtins.float: ... + def tax_assets(self) -> typing.Optional[builtins.float]: ... @property def other_non_current_assets(self) -> builtins.float: ... @property - def total_non_current_assets(self) -> builtins.float: ... + def total_non_current_assets(self) -> typing.Optional[builtins.float]: ... @property def other_assets(self) -> builtins.float: ... @property - def total_assets(self) -> builtins.float: ... + def total_assets(self) -> typing.Optional[builtins.float]: ... @property def total_payables(self) -> builtins.float: ... @property - def account_payables(self) -> builtins.float: ... + def account_payables(self) -> typing.Optional[builtins.float]: ... @property - def other_payables(self) -> builtins.float: ... + def other_payables(self) -> typing.Optional[builtins.float]: ... @property - def accrued_expenses(self) -> builtins.float: ... + def accrued_expenses(self) -> typing.Optional[builtins.float]: ... @property - def short_term_debt(self) -> builtins.float: ... + def short_term_debt(self) -> typing.Optional[builtins.float]: ... @property - def capital_lease_obligations_current(self) -> builtins.float: ... + def capital_lease_obligations_current(self) -> typing.Optional[builtins.float]: ... @property - def tax_payables(self) -> builtins.float: ... + def tax_payables(self) -> typing.Optional[builtins.float]: ... @property - def deferred_revenue(self) -> builtins.float: ... + def deferred_revenue(self) -> typing.Optional[builtins.float]: ... @property def other_current_liabilities(self) -> builtins.float: ... @property - def total_current_liabilities(self) -> builtins.float: ... + def total_current_liabilities(self) -> typing.Optional[builtins.float]: ... @property - def long_term_debt(self) -> builtins.float: ... + def long_term_debt(self) -> typing.Optional[builtins.float]: ... @property - def capital_lease_obligations_non_current(self) -> builtins.float: ... + def capital_lease_obligations_non_current( + self, + ) -> typing.Optional[builtins.float]: ... @property - def deferred_revenue_non_current(self) -> builtins.float: ... + def deferred_revenue_non_current(self) -> typing.Optional[builtins.float]: ... @property - def deferred_tax_liabilities_non_current(self) -> builtins.float: ... + def deferred_tax_liabilities_non_current( + self, + ) -> typing.Optional[builtins.float]: ... @property def other_non_current_liabilities(self) -> builtins.float: ... @property - def total_non_current_liabilities(self) -> builtins.float: ... + def total_non_current_liabilities(self) -> typing.Optional[builtins.float]: ... @property def other_liabilities(self) -> builtins.float: ... @property def capital_lease_obligations(self) -> builtins.float: ... @property - def total_liabilities(self) -> builtins.float: ... + def total_liabilities(self) -> typing.Optional[builtins.float]: ... @property - def treasury_stock(self) -> builtins.float: ... + def treasury_stock(self) -> typing.Optional[builtins.float]: ... @property def preferred_stock(self) -> builtins.float: ... @property - def common_stock(self) -> builtins.float: ... + def common_stock(self) -> typing.Optional[builtins.float]: ... @property - def retained_earnings(self) -> builtins.float: ... + def retained_earnings(self) -> typing.Optional[builtins.float]: ... @property - def additional_paid_in_capital(self) -> builtins.float: ... + def additional_paid_in_capital(self) -> typing.Optional[builtins.float]: ... @property - def accumulated_other_comprehensive_income_loss(self) -> builtins.float: ... + def accumulated_other_comprehensive_income_loss( + self, + ) -> typing.Optional[builtins.float]: ... @property def other_total_stockholders_equity(self) -> builtins.float: ... @property - def total_stockholders_equity(self) -> builtins.float: ... + def total_stockholders_equity(self) -> typing.Optional[builtins.float]: ... @property - def total_equity(self) -> builtins.float: ... + def total_equity(self) -> typing.Optional[builtins.float]: ... @property def minority_interest(self) -> builtins.float: ... @property - def total_liabilities_and_total_equity(self) -> builtins.float: ... + def total_liabilities_and_total_equity(self) -> typing.Optional[builtins.float]: ... @property def total_investments(self) -> builtins.float: ... @property @@ -212,56 +218,56 @@ class BalanceSheetStatement: accepted_date: datetime.datetime, fiscal_year: builtins.str, period: typing.Literal["Q1", "Q2", "Q3", "Q4", "FY"], - cash_and_cash_equivalents: builtins.float, - short_term_investments: builtins.float, - cash_and_short_term_investments: builtins.float, - net_receivables: builtins.float, - accounts_receivables: builtins.float, + cash_and_cash_equivalents: typing.Optional[builtins.float], + short_term_investments: typing.Optional[builtins.float], + cash_and_short_term_investments: typing.Optional[builtins.float], + net_receivables: typing.Optional[builtins.float], + accounts_receivables: typing.Optional[builtins.float], other_receivables: builtins.float, - inventory: builtins.float, - prepaids: builtins.float, + inventory: typing.Optional[builtins.float], + prepaids: typing.Optional[builtins.float], other_current_assets: builtins.float, - total_current_assets: builtins.float, - property_plant_equipment_net: builtins.float, - goodwill: builtins.float, - intangible_assets: builtins.float, - goodwill_and_intangible_assets: builtins.float, - long_term_investments: builtins.float, - tax_assets: builtins.float, + total_current_assets: typing.Optional[builtins.float], + property_plant_equipment_net: typing.Optional[builtins.float], + goodwill: typing.Optional[builtins.float], + intangible_assets: typing.Optional[builtins.float], + goodwill_and_intangible_assets: typing.Optional[builtins.float], + long_term_investments: typing.Optional[builtins.float], + tax_assets: typing.Optional[builtins.float], other_non_current_assets: builtins.float, - total_non_current_assets: builtins.float, + total_non_current_assets: typing.Optional[builtins.float], other_assets: builtins.float, - total_assets: builtins.float, + total_assets: typing.Optional[builtins.float], total_payables: builtins.float, - account_payables: builtins.float, - other_payables: builtins.float, - accrued_expenses: builtins.float, - short_term_debt: builtins.float, - capital_lease_obligations_current: builtins.float, - tax_payables: builtins.float, - deferred_revenue: builtins.float, + account_payables: typing.Optional[builtins.float], + other_payables: typing.Optional[builtins.float], + accrued_expenses: typing.Optional[builtins.float], + short_term_debt: typing.Optional[builtins.float], + capital_lease_obligations_current: typing.Optional[builtins.float], + tax_payables: typing.Optional[builtins.float], + deferred_revenue: typing.Optional[builtins.float], other_current_liabilities: builtins.float, - total_current_liabilities: builtins.float, - long_term_debt: builtins.float, - capital_lease_obligations_non_current: builtins.float, - deferred_revenue_non_current: builtins.float, - deferred_tax_liabilities_non_current: builtins.float, + total_current_liabilities: typing.Optional[builtins.float], + long_term_debt: typing.Optional[builtins.float], + capital_lease_obligations_non_current: typing.Optional[builtins.float], + deferred_revenue_non_current: typing.Optional[builtins.float], + deferred_tax_liabilities_non_current: typing.Optional[builtins.float], other_non_current_liabilities: builtins.float, - total_non_current_liabilities: builtins.float, + total_non_current_liabilities: typing.Optional[builtins.float], other_liabilities: builtins.float, capital_lease_obligations: builtins.float, - total_liabilities: builtins.float, - treasury_stock: builtins.float, + total_liabilities: typing.Optional[builtins.float], + treasury_stock: typing.Optional[builtins.float], preferred_stock: builtins.float, - common_stock: builtins.float, - retained_earnings: builtins.float, - additional_paid_in_capital: builtins.float, - accumulated_other_comprehensive_income_loss: builtins.float, + common_stock: typing.Optional[builtins.float], + retained_earnings: typing.Optional[builtins.float], + additional_paid_in_capital: typing.Optional[builtins.float], + accumulated_other_comprehensive_income_loss: typing.Optional[builtins.float], other_total_stockholders_equity: builtins.float, - total_stockholders_equity: builtins.float, - total_equity: builtins.float, + total_stockholders_equity: typing.Optional[builtins.float], + total_equity: typing.Optional[builtins.float], minority_interest: builtins.float, - total_liabilities_and_total_equity: builtins.float, + total_liabilities_and_total_equity: typing.Optional[builtins.float], total_investments: builtins.float, total_debt: builtins.float, net_debt: builtins.float, diff --git a/crates/fmp-py/python/fmp/_native/statements/cash_flow/__init__.pyi b/crates/fmp-py/python/fmp/_native/statements/cash_flow/__init__.pyi index cebbfd10..e9680f33 100644 --- a/crates/fmp-py/python/fmp/_native/statements/cash_flow/__init__.pyi +++ b/crates/fmp-py/python/fmp/_native/statements/cash_flow/__init__.pyi @@ -82,17 +82,17 @@ class CashFlowStatement: @property def depreciation_and_amortization(self) -> builtins.float: ... @property - def deferred_income_tax(self) -> builtins.float: ... + def deferred_income_tax(self) -> typing.Optional[builtins.float]: ... @property - def stock_based_compensation(self) -> builtins.float: ... + def stock_based_compensation(self) -> typing.Optional[builtins.float]: ... @property def change_in_working_capital(self) -> builtins.float: ... @property - def accounts_receivables(self) -> builtins.float: ... + def accounts_receivables(self) -> typing.Optional[builtins.float]: ... @property - def inventory(self) -> builtins.float: ... + def inventory(self) -> typing.Optional[builtins.float]: ... @property - def accounts_payables(self) -> builtins.float: ... + def accounts_payables(self) -> typing.Optional[builtins.float]: ... @property def other_working_capital(self) -> builtins.float: ... @property @@ -104,9 +104,9 @@ class CashFlowStatement: @property def acquisitions_net(self) -> builtins.float: ... @property - def purchases_of_investments(self) -> builtins.float: ... + def purchases_of_investments(self) -> typing.Optional[builtins.float]: ... @property - def sales_maturities_of_investments(self) -> builtins.float: ... + def sales_maturities_of_investments(self) -> typing.Optional[builtins.float]: ... @property def other_investing_activities(self) -> builtins.float: ... @property @@ -114,29 +114,31 @@ class CashFlowStatement: @property def net_debt_issuance(self) -> builtins.float: ... @property - def long_term_net_debt_issuance(self) -> builtins.float: ... + def long_term_net_debt_issuance(self) -> typing.Optional[builtins.float]: ... @property def short_term_net_debt_issuance(self) -> builtins.float: ... @property - def net_stock_issuance(self) -> builtins.float: ... + def net_stock_issuance(self) -> typing.Optional[builtins.float]: ... @property - def net_common_stock_issuance(self) -> builtins.float: ... + def net_common_stock_issuance(self) -> typing.Optional[builtins.float]: ... @property def common_stock_issuance(self) -> builtins.float: ... @property - def common_stock_repurchased(self) -> builtins.float: ... + def common_stock_repurchased(self) -> typing.Optional[builtins.float]: ... @property - def net_preferred_stock_issuance(self) -> builtins.float: ... + def net_preferred_stock_issuance(self) -> typing.Optional[builtins.float]: ... @property - def net_dividends_paid(self) -> builtins.float: ... + def net_dividends_paid(self) -> typing.Optional[builtins.float]: ... @property - def common_dividends_paid(self) -> builtins.float: ... + def common_dividends_paid(self) -> typing.Optional[builtins.float]: ... @property - def preferred_dividends_paid(self) -> builtins.float: ... + def preferred_dividends_paid(self) -> typing.Optional[builtins.float]: ... @property def other_financing_activities(self) -> builtins.float: ... @property - def net_cash_provided_by_financing_activities(self) -> builtins.float: ... + def net_cash_provided_by_financing_activities( + self, + ) -> typing.Optional[builtins.float]: ... @property def effect_of_forex_changes_on_cash(self) -> builtins.float: ... @property @@ -144,7 +146,7 @@ class CashFlowStatement: @property def cash_at_end_of_period(self) -> builtins.float: ... @property - def cash_at_beginning_of_period(self) -> builtins.float: ... + def cash_at_beginning_of_period(self) -> typing.Optional[builtins.float]: ... @property def operating_cash_flow(self) -> builtins.float: ... @property @@ -152,9 +154,9 @@ class CashFlowStatement: @property def free_cash_flow(self) -> builtins.float: ... @property - def income_taxes_paid(self) -> builtins.float: ... + def income_taxes_paid(self) -> typing.Optional[builtins.float]: ... @property - def interest_paid(self) -> builtins.float: ... + def interest_paid(self) -> typing.Optional[builtins.float]: ... @property def period(self) -> typing.Literal["Q1", "Q2", "Q3", "Q4", "FY"]: ... def __eq__(self, other: builtins.object, /) -> builtins.bool: ... @@ -171,43 +173,43 @@ class CashFlowStatement: period: typing.Literal["Q1", "Q2", "Q3", "Q4", "FY"], net_income: builtins.float, depreciation_and_amortization: builtins.float, - deferred_income_tax: builtins.float, - stock_based_compensation: builtins.float, + deferred_income_tax: typing.Optional[builtins.float], + stock_based_compensation: typing.Optional[builtins.float], change_in_working_capital: builtins.float, - accounts_receivables: builtins.float, - inventory: builtins.float, - accounts_payables: builtins.float, + accounts_receivables: typing.Optional[builtins.float], + inventory: typing.Optional[builtins.float], + accounts_payables: typing.Optional[builtins.float], other_working_capital: builtins.float, other_non_cash_items: builtins.float, net_cash_provided_by_operating_activities: builtins.float, investments_in_property_plant_and_equipment: builtins.float, acquisitions_net: builtins.float, - purchases_of_investments: builtins.float, - sales_maturities_of_investments: builtins.float, + purchases_of_investments: typing.Optional[builtins.float], + sales_maturities_of_investments: typing.Optional[builtins.float], other_investing_activities: builtins.float, net_cash_provided_by_investing_activities: builtins.float, net_debt_issuance: builtins.float, - long_term_net_debt_issuance: builtins.float, + long_term_net_debt_issuance: typing.Optional[builtins.float], short_term_net_debt_issuance: builtins.float, - net_stock_issuance: builtins.float, - net_common_stock_issuance: builtins.float, + net_stock_issuance: typing.Optional[builtins.float], + net_common_stock_issuance: typing.Optional[builtins.float], common_stock_issuance: builtins.float, - common_stock_repurchased: builtins.float, - net_preferred_stock_issuance: builtins.float, - net_dividends_paid: builtins.float, - common_dividends_paid: builtins.float, - preferred_dividends_paid: builtins.float, + common_stock_repurchased: typing.Optional[builtins.float], + net_preferred_stock_issuance: typing.Optional[builtins.float], + net_dividends_paid: typing.Optional[builtins.float], + common_dividends_paid: typing.Optional[builtins.float], + preferred_dividends_paid: typing.Optional[builtins.float], other_financing_activities: builtins.float, - net_cash_provided_by_financing_activities: builtins.float, + net_cash_provided_by_financing_activities: typing.Optional[builtins.float], effect_of_forex_changes_on_cash: builtins.float, net_change_in_cash: builtins.float, cash_at_end_of_period: builtins.float, - cash_at_beginning_of_period: builtins.float, + cash_at_beginning_of_period: typing.Optional[builtins.float], operating_cash_flow: builtins.float, capital_expenditure: builtins.float, free_cash_flow: builtins.float, - income_taxes_paid: builtins.float, - interest_paid: builtins.float, + income_taxes_paid: typing.Optional[builtins.float], + interest_paid: typing.Optional[builtins.float], ) -> CashFlowStatement: ... def __getnewargs_ex__(self) -> tuple[tuple, dict]: ... def __repr__(self) -> builtins.str: ... diff --git a/crates/fmp-py/src/models/statements/balance.rs b/crates/fmp-py/src/models/statements/balance.rs index d8c3aa1d..235013b7 100644 --- a/crates/fmp-py/src/models/statements/balance.rs +++ b/crates/fmp-py/src/models/statements/balance.rs @@ -25,105 +25,105 @@ pub(crate) struct BalanceSheetStatement { pub fiscal_year: String, pub period: String, #[pyo3(get)] - pub cash_and_cash_equivalents: f64, + pub cash_and_cash_equivalents: Option, #[pyo3(get)] - pub short_term_investments: f64, + pub short_term_investments: Option, #[pyo3(get)] - pub cash_and_short_term_investments: f64, + pub cash_and_short_term_investments: Option, #[pyo3(get)] - pub net_receivables: f64, + pub net_receivables: Option, #[pyo3(get)] - pub accounts_receivables: f64, + pub accounts_receivables: Option, #[pyo3(get)] pub other_receivables: f64, #[pyo3(get)] - pub inventory: f64, + pub inventory: Option, #[pyo3(get)] - pub prepaids: f64, + pub prepaids: Option, #[pyo3(get)] pub other_current_assets: f64, #[pyo3(get)] - pub total_current_assets: f64, + pub total_current_assets: Option, #[pyo3(get)] - pub property_plant_equipment_net: f64, + pub property_plant_equipment_net: Option, #[pyo3(get)] - pub goodwill: f64, + pub goodwill: Option, #[pyo3(get)] - pub intangible_assets: f64, + pub intangible_assets: Option, #[pyo3(get)] - pub goodwill_and_intangible_assets: f64, + pub goodwill_and_intangible_assets: Option, #[pyo3(get)] - pub long_term_investments: f64, + pub long_term_investments: Option, #[pyo3(get)] - pub tax_assets: f64, + pub tax_assets: Option, #[pyo3(get)] pub other_non_current_assets: f64, #[pyo3(get)] - pub total_non_current_assets: f64, + pub total_non_current_assets: Option, #[pyo3(get)] pub other_assets: f64, #[pyo3(get)] - pub total_assets: f64, + pub total_assets: Option, #[pyo3(get)] pub total_payables: f64, #[pyo3(get)] - pub account_payables: f64, + pub account_payables: Option, #[pyo3(get)] - pub other_payables: f64, + pub other_payables: Option, #[pyo3(get)] - pub accrued_expenses: f64, + pub accrued_expenses: Option, #[pyo3(get)] - pub short_term_debt: f64, + pub short_term_debt: Option, #[pyo3(get)] - pub capital_lease_obligations_current: f64, + pub capital_lease_obligations_current: Option, #[pyo3(get)] - pub tax_payables: f64, + pub tax_payables: Option, #[pyo3(get)] - pub deferred_revenue: f64, + pub deferred_revenue: Option, #[pyo3(get)] pub other_current_liabilities: f64, #[pyo3(get)] - pub total_current_liabilities: f64, + pub total_current_liabilities: Option, #[pyo3(get)] - pub long_term_debt: f64, + pub long_term_debt: Option, #[pyo3(get)] - pub capital_lease_obligations_non_current: f64, + pub capital_lease_obligations_non_current: Option, #[pyo3(get)] - pub deferred_revenue_non_current: f64, + pub deferred_revenue_non_current: Option, #[pyo3(get)] - pub deferred_tax_liabilities_non_current: f64, + pub deferred_tax_liabilities_non_current: Option, #[pyo3(get)] pub other_non_current_liabilities: f64, #[pyo3(get)] - pub total_non_current_liabilities: f64, + pub total_non_current_liabilities: Option, #[pyo3(get)] pub other_liabilities: f64, #[pyo3(get)] pub capital_lease_obligations: f64, #[pyo3(get)] - pub total_liabilities: f64, + pub total_liabilities: Option, #[pyo3(get)] - pub treasury_stock: f64, + pub treasury_stock: Option, #[pyo3(get)] pub preferred_stock: f64, #[pyo3(get)] - pub common_stock: f64, + pub common_stock: Option, #[pyo3(get)] - pub retained_earnings: f64, + pub retained_earnings: Option, #[pyo3(get)] - pub additional_paid_in_capital: f64, + pub additional_paid_in_capital: Option, #[pyo3(get)] - pub accumulated_other_comprehensive_income_loss: f64, + pub accumulated_other_comprehensive_income_loss: Option, #[pyo3(get)] pub other_total_stockholders_equity: f64, #[pyo3(get)] - pub total_stockholders_equity: f64, + pub total_stockholders_equity: Option, #[pyo3(get)] - pub total_equity: f64, + pub total_equity: Option, #[pyo3(get)] pub minority_interest: f64, #[pyo3(get)] - pub total_liabilities_and_total_equity: f64, + pub total_liabilities_and_total_equity: Option, #[pyo3(get)] pub total_investments: f64, #[pyo3(get)] @@ -149,56 +149,56 @@ impl BalanceSheetStatement { fiscal_year: String, #[gen_stub(override_type(type_repr = "typing.Literal[\"Q1\", \"Q2\", \"Q3\", \"Q4\", \"FY\"]", imports = ("builtins", "typing")))] period: String, - cash_and_cash_equivalents: f64, - short_term_investments: f64, - cash_and_short_term_investments: f64, - net_receivables: f64, - accounts_receivables: f64, + cash_and_cash_equivalents: Option, + short_term_investments: Option, + cash_and_short_term_investments: Option, + net_receivables: Option, + accounts_receivables: Option, other_receivables: f64, - inventory: f64, - prepaids: f64, + inventory: Option, + prepaids: Option, other_current_assets: f64, - total_current_assets: f64, - property_plant_equipment_net: f64, - goodwill: f64, - intangible_assets: f64, - goodwill_and_intangible_assets: f64, - long_term_investments: f64, - tax_assets: f64, + total_current_assets: Option, + property_plant_equipment_net: Option, + goodwill: Option, + intangible_assets: Option, + goodwill_and_intangible_assets: Option, + long_term_investments: Option, + tax_assets: Option, other_non_current_assets: f64, - total_non_current_assets: f64, + total_non_current_assets: Option, other_assets: f64, - total_assets: f64, + total_assets: Option, total_payables: f64, - account_payables: f64, - other_payables: f64, - accrued_expenses: f64, - short_term_debt: f64, - capital_lease_obligations_current: f64, - tax_payables: f64, - deferred_revenue: f64, + account_payables: Option, + other_payables: Option, + accrued_expenses: Option, + short_term_debt: Option, + capital_lease_obligations_current: Option, + tax_payables: Option, + deferred_revenue: Option, other_current_liabilities: f64, - total_current_liabilities: f64, - long_term_debt: f64, - capital_lease_obligations_non_current: f64, - deferred_revenue_non_current: f64, - deferred_tax_liabilities_non_current: f64, + total_current_liabilities: Option, + long_term_debt: Option, + capital_lease_obligations_non_current: Option, + deferred_revenue_non_current: Option, + deferred_tax_liabilities_non_current: Option, other_non_current_liabilities: f64, - total_non_current_liabilities: f64, + total_non_current_liabilities: Option, other_liabilities: f64, capital_lease_obligations: f64, - total_liabilities: f64, - treasury_stock: f64, + total_liabilities: Option, + treasury_stock: Option, preferred_stock: f64, - common_stock: f64, - retained_earnings: f64, - additional_paid_in_capital: f64, - accumulated_other_comprehensive_income_loss: f64, + common_stock: Option, + retained_earnings: Option, + additional_paid_in_capital: Option, + accumulated_other_comprehensive_income_loss: Option, other_total_stockholders_equity: f64, - total_stockholders_equity: f64, - total_equity: f64, + total_stockholders_equity: Option, + total_equity: Option, minority_interest: f64, - total_liabilities_and_total_equity: f64, + total_liabilities_and_total_equity: Option, total_investments: f64, total_debt: f64, net_debt: f64, diff --git a/crates/fmp-py/src/models/statements/cash_flow.rs b/crates/fmp-py/src/models/statements/cash_flow.rs index c61c0ef3..7106b8c2 100644 --- a/crates/fmp-py/src/models/statements/cash_flow.rs +++ b/crates/fmp-py/src/models/statements/cash_flow.rs @@ -34,17 +34,17 @@ pub(crate) struct CashFlowStatement { #[pyo3(get)] pub depreciation_and_amortization: f64, #[pyo3(get)] - pub deferred_income_tax: f64, + pub deferred_income_tax: Option, #[pyo3(get)] - pub stock_based_compensation: f64, + pub stock_based_compensation: Option, #[pyo3(get)] pub change_in_working_capital: f64, #[pyo3(get)] - pub accounts_receivables: f64, + pub accounts_receivables: Option, #[pyo3(get)] - pub inventory: f64, + pub inventory: Option, #[pyo3(get)] - pub accounts_payables: f64, + pub accounts_payables: Option, #[pyo3(get)] pub other_working_capital: f64, #[pyo3(get)] @@ -56,9 +56,9 @@ pub(crate) struct CashFlowStatement { #[pyo3(get)] pub acquisitions_net: f64, #[pyo3(get)] - pub purchases_of_investments: f64, + pub purchases_of_investments: Option, #[pyo3(get)] - pub sales_maturities_of_investments: f64, + pub sales_maturities_of_investments: Option, #[pyo3(get)] pub other_investing_activities: f64, #[pyo3(get)] @@ -66,29 +66,29 @@ pub(crate) struct CashFlowStatement { #[pyo3(get)] pub net_debt_issuance: f64, #[pyo3(get)] - pub long_term_net_debt_issuance: f64, + pub long_term_net_debt_issuance: Option, #[pyo3(get)] pub short_term_net_debt_issuance: f64, #[pyo3(get)] - pub net_stock_issuance: f64, + pub net_stock_issuance: Option, #[pyo3(get)] - pub net_common_stock_issuance: f64, + pub net_common_stock_issuance: Option, #[pyo3(get)] pub common_stock_issuance: f64, #[pyo3(get)] - pub common_stock_repurchased: f64, + pub common_stock_repurchased: Option, #[pyo3(get)] - pub net_preferred_stock_issuance: f64, + pub net_preferred_stock_issuance: Option, #[pyo3(get)] - pub net_dividends_paid: f64, + pub net_dividends_paid: Option, #[pyo3(get)] - pub common_dividends_paid: f64, + pub common_dividends_paid: Option, #[pyo3(get)] - pub preferred_dividends_paid: f64, + pub preferred_dividends_paid: Option, #[pyo3(get)] pub other_financing_activities: f64, #[pyo3(get)] - pub net_cash_provided_by_financing_activities: f64, + pub net_cash_provided_by_financing_activities: Option, #[pyo3(get)] pub effect_of_forex_changes_on_cash: f64, #[pyo3(get)] @@ -96,7 +96,7 @@ pub(crate) struct CashFlowStatement { #[pyo3(get)] pub cash_at_end_of_period: f64, #[pyo3(get)] - pub cash_at_beginning_of_period: f64, + pub cash_at_beginning_of_period: Option, #[pyo3(get)] pub operating_cash_flow: f64, #[pyo3(get)] @@ -104,9 +104,9 @@ pub(crate) struct CashFlowStatement { #[pyo3(get)] pub free_cash_flow: f64, #[pyo3(get)] - pub income_taxes_paid: f64, + pub income_taxes_paid: Option, #[pyo3(get)] - pub interest_paid: f64, + pub interest_paid: Option, } #[gen_stub_pymethods] @@ -128,43 +128,43 @@ impl CashFlowStatement { period: String, net_income: f64, depreciation_and_amortization: f64, - deferred_income_tax: f64, - stock_based_compensation: f64, + deferred_income_tax: Option, + stock_based_compensation: Option, change_in_working_capital: f64, - accounts_receivables: f64, - inventory: f64, - accounts_payables: f64, + accounts_receivables: Option, + inventory: Option, + accounts_payables: Option, other_working_capital: f64, other_non_cash_items: f64, net_cash_provided_by_operating_activities: f64, investments_in_property_plant_and_equipment: f64, acquisitions_net: f64, - purchases_of_investments: f64, - sales_maturities_of_investments: f64, + purchases_of_investments: Option, + sales_maturities_of_investments: Option, other_investing_activities: f64, net_cash_provided_by_investing_activities: f64, net_debt_issuance: f64, - long_term_net_debt_issuance: f64, + long_term_net_debt_issuance: Option, short_term_net_debt_issuance: f64, - net_stock_issuance: f64, - net_common_stock_issuance: f64, + net_stock_issuance: Option, + net_common_stock_issuance: Option, common_stock_issuance: f64, - common_stock_repurchased: f64, - net_preferred_stock_issuance: f64, - net_dividends_paid: f64, - common_dividends_paid: f64, - preferred_dividends_paid: f64, + common_stock_repurchased: Option, + net_preferred_stock_issuance: Option, + net_dividends_paid: Option, + common_dividends_paid: Option, + preferred_dividends_paid: Option, other_financing_activities: f64, - net_cash_provided_by_financing_activities: f64, + net_cash_provided_by_financing_activities: Option, effect_of_forex_changes_on_cash: f64, net_change_in_cash: f64, cash_at_end_of_period: f64, - cash_at_beginning_of_period: f64, + cash_at_beginning_of_period: Option, operating_cash_flow: f64, capital_expenditure: f64, free_cash_flow: f64, - income_taxes_paid: f64, - interest_paid: f64, + income_taxes_paid: Option, + interest_paid: Option, ) -> Self { Self { date, diff --git a/crates/fmp-py/tests/test_statements_core.py b/crates/fmp-py/tests/test_statements_core.py index a1e1be19..bf1b739d 100644 --- a/crates/fmp-py/tests/test_statements_core.py +++ b/crates/fmp-py/tests/test_statements_core.py @@ -121,6 +121,28 @@ def test_cash_flow_statement_ttm_with_limit(client: Any, fixture_server: Fixture assert rows[0].net_income == 122_575_000_000 +def test_pre_ipo_stub_rows_decode_null_amounts_as_none(client: Any, fixture_server: FixtureServer) -> None: + """Issue #368: null stub-quarter amounts decode as ``None``; other amounts stay floats.""" + balance = load_fixture("balance_sheet_statement.json") + balance[0]["totalAssets"] = None + balance[0]["retainedEarnings"] = None + cash = load_fixture("cash_flow_statement.json") + cash[0]["stockBasedCompensation"] = None + cash[0]["interestPaid"] = None + fixture_server.route("/balance-sheet-statement", balance) + fixture_server.route("/cash-flow-statement", cash) + + balance_row = client.statements.balance.statement("AAPL")[0] + cash_row = client.statements.cash_flow.statement("AAPL")[0] + + assert balance_row.total_assets is None + assert balance_row.retained_earnings is None + assert isinstance(balance_row.other_receivables, float) + assert cash_row.stock_based_compensation is None + assert cash_row.interest_paid is None + assert cash_row.net_income == 112_010_000_000 + + def test_key_metrics_with_fiscal_quarter(client: Any, fixture_server: FixtureServer) -> None: """``metrics.key_metrics`` accepts a ``Q3`` fiscal quarter as the period.""" fixture_server.route("/key-metrics", load_fixture("key_metrics.json")) diff --git a/crates/libfmp/src/responses/statements/balance.rs b/crates/libfmp/src/responses/statements/balance.rs index 6fc4b295..89627df8 100644 --- a/crates/libfmp/src/responses/statements/balance.rs +++ b/crates/libfmp/src/responses/statements/balance.rs @@ -1,6 +1,6 @@ //! Balance-sheet response models. -use serde::{Deserialize, Serialize}; +use serde::{Deserialize, Deserializer, Serialize}; use crate::{ codecs::FiscalYearString, @@ -8,6 +8,14 @@ use crate::{ types::{ApiDateTime, Cik, CurrencyCode, Date, StatementAmount, Ticker}, }; +fn required_option<'de, D, T>(deserializer: D) -> Result, D::Error> +where + D: Deserializer<'de>, + T: Deserialize<'de>, +{ + Option::::deserialize(deserializer) +} + /// One historical worldwide balance-sheet statement. #[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] #[non_exhaustive] @@ -21,106 +29,144 @@ pub struct BalanceSheetStatement { pub accepted_date: ApiDateTime, pub fiscal_year: FiscalYearString, pub period: FiscalPeriod, - #[serde(serialize_with = "crate::codecs::integral_f64::serialize")] - pub cash_and_cash_equivalents: StatementAmount, - #[serde(serialize_with = "crate::codecs::integral_f64::serialize")] - pub short_term_investments: StatementAmount, - #[serde(serialize_with = "crate::codecs::integral_f64::serialize")] - pub cash_and_short_term_investments: StatementAmount, - #[serde(serialize_with = "crate::codecs::integral_f64::serialize")] - pub net_receivables: StatementAmount, - #[serde(serialize_with = "crate::codecs::integral_f64::serialize")] - pub accounts_receivables: StatementAmount, + #[serde(deserialize_with = "required_option")] + #[serde(serialize_with = "crate::codecs::integral_f64::serialize_option")] + pub cash_and_cash_equivalents: Option, + #[serde(deserialize_with = "required_option")] + #[serde(serialize_with = "crate::codecs::integral_f64::serialize_option")] + pub short_term_investments: Option, + #[serde(deserialize_with = "required_option")] + #[serde(serialize_with = "crate::codecs::integral_f64::serialize_option")] + pub cash_and_short_term_investments: Option, + #[serde(deserialize_with = "required_option")] + #[serde(serialize_with = "crate::codecs::integral_f64::serialize_option")] + pub net_receivables: Option, + #[serde(deserialize_with = "required_option")] + #[serde(serialize_with = "crate::codecs::integral_f64::serialize_option")] + pub accounts_receivables: Option, #[serde(serialize_with = "crate::codecs::integral_f64::serialize")] pub other_receivables: StatementAmount, - #[serde(serialize_with = "crate::codecs::integral_f64::serialize")] - pub inventory: StatementAmount, - #[serde(serialize_with = "crate::codecs::integral_f64::serialize")] - pub prepaids: StatementAmount, + #[serde(deserialize_with = "required_option")] + #[serde(serialize_with = "crate::codecs::integral_f64::serialize_option")] + pub inventory: Option, + #[serde(deserialize_with = "required_option")] + #[serde(serialize_with = "crate::codecs::integral_f64::serialize_option")] + pub prepaids: Option, #[serde(serialize_with = "crate::codecs::integral_f64::serialize")] pub other_current_assets: StatementAmount, - #[serde(serialize_with = "crate::codecs::integral_f64::serialize")] - pub total_current_assets: StatementAmount, - #[serde(serialize_with = "crate::codecs::integral_f64::serialize")] - pub property_plant_equipment_net: StatementAmount, - #[serde(serialize_with = "crate::codecs::integral_f64::serialize")] - pub goodwill: StatementAmount, - #[serde(serialize_with = "crate::codecs::integral_f64::serialize")] - pub intangible_assets: StatementAmount, - #[serde(serialize_with = "crate::codecs::integral_f64::serialize")] - pub goodwill_and_intangible_assets: StatementAmount, - #[serde(serialize_with = "crate::codecs::integral_f64::serialize")] - pub long_term_investments: StatementAmount, - #[serde(serialize_with = "crate::codecs::integral_f64::serialize")] - pub tax_assets: StatementAmount, + #[serde(deserialize_with = "required_option")] + #[serde(serialize_with = "crate::codecs::integral_f64::serialize_option")] + pub total_current_assets: Option, + #[serde(deserialize_with = "required_option")] + #[serde(serialize_with = "crate::codecs::integral_f64::serialize_option")] + pub property_plant_equipment_net: Option, + #[serde(deserialize_with = "required_option")] + #[serde(serialize_with = "crate::codecs::integral_f64::serialize_option")] + pub goodwill: Option, + #[serde(deserialize_with = "required_option")] + #[serde(serialize_with = "crate::codecs::integral_f64::serialize_option")] + pub intangible_assets: Option, + #[serde(deserialize_with = "required_option")] + #[serde(serialize_with = "crate::codecs::integral_f64::serialize_option")] + pub goodwill_and_intangible_assets: Option, + #[serde(deserialize_with = "required_option")] + #[serde(serialize_with = "crate::codecs::integral_f64::serialize_option")] + pub long_term_investments: Option, + #[serde(deserialize_with = "required_option")] + #[serde(serialize_with = "crate::codecs::integral_f64::serialize_option")] + pub tax_assets: Option, #[serde(serialize_with = "crate::codecs::integral_f64::serialize")] pub other_non_current_assets: StatementAmount, - #[serde(serialize_with = "crate::codecs::integral_f64::serialize")] - pub total_non_current_assets: StatementAmount, + #[serde(deserialize_with = "required_option")] + #[serde(serialize_with = "crate::codecs::integral_f64::serialize_option")] + pub total_non_current_assets: Option, #[serde(serialize_with = "crate::codecs::integral_f64::serialize")] pub other_assets: StatementAmount, - #[serde(serialize_with = "crate::codecs::integral_f64::serialize")] - pub total_assets: StatementAmount, + #[serde(deserialize_with = "required_option")] + #[serde(serialize_with = "crate::codecs::integral_f64::serialize_option")] + pub total_assets: Option, #[serde(serialize_with = "crate::codecs::integral_f64::serialize")] pub total_payables: StatementAmount, - #[serde(serialize_with = "crate::codecs::integral_f64::serialize")] - pub account_payables: StatementAmount, - #[serde(serialize_with = "crate::codecs::integral_f64::serialize")] - pub other_payables: StatementAmount, - #[serde(serialize_with = "crate::codecs::integral_f64::serialize")] - pub accrued_expenses: StatementAmount, - #[serde(serialize_with = "crate::codecs::integral_f64::serialize")] - pub short_term_debt: StatementAmount, - #[serde(serialize_with = "crate::codecs::integral_f64::serialize")] - pub capital_lease_obligations_current: StatementAmount, - #[serde(serialize_with = "crate::codecs::integral_f64::serialize")] - pub tax_payables: StatementAmount, - #[serde(serialize_with = "crate::codecs::integral_f64::serialize")] - pub deferred_revenue: StatementAmount, + #[serde(deserialize_with = "required_option")] + #[serde(serialize_with = "crate::codecs::integral_f64::serialize_option")] + pub account_payables: Option, + #[serde(deserialize_with = "required_option")] + #[serde(serialize_with = "crate::codecs::integral_f64::serialize_option")] + pub other_payables: Option, + #[serde(deserialize_with = "required_option")] + #[serde(serialize_with = "crate::codecs::integral_f64::serialize_option")] + pub accrued_expenses: Option, + #[serde(deserialize_with = "required_option")] + #[serde(serialize_with = "crate::codecs::integral_f64::serialize_option")] + pub short_term_debt: Option, + #[serde(deserialize_with = "required_option")] + #[serde(serialize_with = "crate::codecs::integral_f64::serialize_option")] + pub capital_lease_obligations_current: Option, + #[serde(deserialize_with = "required_option")] + #[serde(serialize_with = "crate::codecs::integral_f64::serialize_option")] + pub tax_payables: Option, + #[serde(deserialize_with = "required_option")] + #[serde(serialize_with = "crate::codecs::integral_f64::serialize_option")] + pub deferred_revenue: Option, #[serde(serialize_with = "crate::codecs::integral_f64::serialize")] pub other_current_liabilities: StatementAmount, - #[serde(serialize_with = "crate::codecs::integral_f64::serialize")] - pub total_current_liabilities: StatementAmount, - #[serde(serialize_with = "crate::codecs::integral_f64::serialize")] - pub long_term_debt: StatementAmount, - #[serde(serialize_with = "crate::codecs::integral_f64::serialize")] - pub capital_lease_obligations_non_current: StatementAmount, - #[serde(serialize_with = "crate::codecs::integral_f64::serialize")] - pub deferred_revenue_non_current: StatementAmount, - #[serde(serialize_with = "crate::codecs::integral_f64::serialize")] - pub deferred_tax_liabilities_non_current: StatementAmount, + #[serde(deserialize_with = "required_option")] + #[serde(serialize_with = "crate::codecs::integral_f64::serialize_option")] + pub total_current_liabilities: Option, + #[serde(deserialize_with = "required_option")] + #[serde(serialize_with = "crate::codecs::integral_f64::serialize_option")] + pub long_term_debt: Option, + #[serde(deserialize_with = "required_option")] + #[serde(serialize_with = "crate::codecs::integral_f64::serialize_option")] + pub capital_lease_obligations_non_current: Option, + #[serde(deserialize_with = "required_option")] + #[serde(serialize_with = "crate::codecs::integral_f64::serialize_option")] + pub deferred_revenue_non_current: Option, + #[serde(deserialize_with = "required_option")] + #[serde(serialize_with = "crate::codecs::integral_f64::serialize_option")] + pub deferred_tax_liabilities_non_current: Option, #[serde(serialize_with = "crate::codecs::integral_f64::serialize")] pub other_non_current_liabilities: StatementAmount, - #[serde(serialize_with = "crate::codecs::integral_f64::serialize")] - pub total_non_current_liabilities: StatementAmount, + #[serde(deserialize_with = "required_option")] + #[serde(serialize_with = "crate::codecs::integral_f64::serialize_option")] + pub total_non_current_liabilities: Option, #[serde(serialize_with = "crate::codecs::integral_f64::serialize")] pub other_liabilities: StatementAmount, #[serde(serialize_with = "crate::codecs::integral_f64::serialize")] pub capital_lease_obligations: StatementAmount, - #[serde(serialize_with = "crate::codecs::integral_f64::serialize")] - pub total_liabilities: StatementAmount, - #[serde(serialize_with = "crate::codecs::integral_f64::serialize")] - pub treasury_stock: StatementAmount, + #[serde(deserialize_with = "required_option")] + #[serde(serialize_with = "crate::codecs::integral_f64::serialize_option")] + pub total_liabilities: Option, + #[serde(deserialize_with = "required_option")] + #[serde(serialize_with = "crate::codecs::integral_f64::serialize_option")] + pub treasury_stock: Option, #[serde(serialize_with = "crate::codecs::integral_f64::serialize")] pub preferred_stock: StatementAmount, - #[serde(serialize_with = "crate::codecs::integral_f64::serialize")] - pub common_stock: StatementAmount, - #[serde(serialize_with = "crate::codecs::integral_f64::serialize")] - pub retained_earnings: StatementAmount, - #[serde(serialize_with = "crate::codecs::integral_f64::serialize")] - pub additional_paid_in_capital: StatementAmount, - #[serde(serialize_with = "crate::codecs::integral_f64::serialize")] - pub accumulated_other_comprehensive_income_loss: StatementAmount, + #[serde(deserialize_with = "required_option")] + #[serde(serialize_with = "crate::codecs::integral_f64::serialize_option")] + pub common_stock: Option, + #[serde(deserialize_with = "required_option")] + #[serde(serialize_with = "crate::codecs::integral_f64::serialize_option")] + pub retained_earnings: Option, + #[serde(deserialize_with = "required_option")] + #[serde(serialize_with = "crate::codecs::integral_f64::serialize_option")] + pub additional_paid_in_capital: Option, + #[serde(deserialize_with = "required_option")] + #[serde(serialize_with = "crate::codecs::integral_f64::serialize_option")] + pub accumulated_other_comprehensive_income_loss: Option, #[serde(serialize_with = "crate::codecs::integral_f64::serialize")] pub other_total_stockholders_equity: StatementAmount, - #[serde(serialize_with = "crate::codecs::integral_f64::serialize")] - pub total_stockholders_equity: StatementAmount, - #[serde(serialize_with = "crate::codecs::integral_f64::serialize")] - pub total_equity: StatementAmount, + #[serde(deserialize_with = "required_option")] + #[serde(serialize_with = "crate::codecs::integral_f64::serialize_option")] + pub total_stockholders_equity: Option, + #[serde(deserialize_with = "required_option")] + #[serde(serialize_with = "crate::codecs::integral_f64::serialize_option")] + pub total_equity: Option, #[serde(serialize_with = "crate::codecs::integral_f64::serialize")] pub minority_interest: StatementAmount, - #[serde(serialize_with = "crate::codecs::integral_f64::serialize")] - pub total_liabilities_and_total_equity: StatementAmount, + #[serde(deserialize_with = "required_option")] + #[serde(serialize_with = "crate::codecs::integral_f64::serialize_option")] + pub total_liabilities_and_total_equity: Option, #[serde(serialize_with = "crate::codecs::integral_f64::serialize")] pub total_investments: StatementAmount, #[serde(serialize_with = "crate::codecs::integral_f64::serialize")] diff --git a/crates/libfmp/src/responses/statements/cash_flow.rs b/crates/libfmp/src/responses/statements/cash_flow.rs index 90b088ae..d4f2211a 100644 --- a/crates/libfmp/src/responses/statements/cash_flow.rs +++ b/crates/libfmp/src/responses/statements/cash_flow.rs @@ -1,6 +1,6 @@ //! Cash-flow-statement response models. -use serde::{Deserialize, Serialize}; +use serde::{Deserialize, Deserializer, Serialize}; use crate::{ codecs::FiscalYearString, @@ -8,6 +8,14 @@ use crate::{ types::{ApiDateTime, Cik, CurrencyCode, Date, StatementAmount, Ticker}, }; +fn required_option<'de, D, T>(deserializer: D) -> Result, D::Error> +where + D: Deserializer<'de>, + T: Deserialize<'de>, +{ + Option::::deserialize(deserializer) +} + /// One historical or trailing-twelve-month worldwide cash-flow statement. #[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] #[non_exhaustive] @@ -25,18 +33,23 @@ pub struct CashFlowStatement { pub net_income: StatementAmount, #[serde(serialize_with = "crate::codecs::integral_f64::serialize")] pub depreciation_and_amortization: StatementAmount, - #[serde(serialize_with = "crate::codecs::integral_f64::serialize")] - pub deferred_income_tax: StatementAmount, - #[serde(serialize_with = "crate::codecs::integral_f64::serialize")] - pub stock_based_compensation: StatementAmount, + #[serde(deserialize_with = "required_option")] + #[serde(serialize_with = "crate::codecs::integral_f64::serialize_option")] + pub deferred_income_tax: Option, + #[serde(deserialize_with = "required_option")] + #[serde(serialize_with = "crate::codecs::integral_f64::serialize_option")] + pub stock_based_compensation: Option, #[serde(serialize_with = "crate::codecs::integral_f64::serialize")] pub change_in_working_capital: StatementAmount, - #[serde(serialize_with = "crate::codecs::integral_f64::serialize")] - pub accounts_receivables: StatementAmount, - #[serde(serialize_with = "crate::codecs::integral_f64::serialize")] - pub inventory: StatementAmount, - #[serde(serialize_with = "crate::codecs::integral_f64::serialize")] - pub accounts_payables: StatementAmount, + #[serde(deserialize_with = "required_option")] + #[serde(serialize_with = "crate::codecs::integral_f64::serialize_option")] + pub accounts_receivables: Option, + #[serde(deserialize_with = "required_option")] + #[serde(serialize_with = "crate::codecs::integral_f64::serialize_option")] + pub inventory: Option, + #[serde(deserialize_with = "required_option")] + #[serde(serialize_with = "crate::codecs::integral_f64::serialize_option")] + pub accounts_payables: Option, #[serde(serialize_with = "crate::codecs::integral_f64::serialize")] pub other_working_capital: StatementAmount, #[serde(serialize_with = "crate::codecs::integral_f64::serialize")] @@ -47,56 +60,70 @@ pub struct CashFlowStatement { pub investments_in_property_plant_and_equipment: StatementAmount, #[serde(serialize_with = "crate::codecs::integral_f64::serialize")] pub acquisitions_net: StatementAmount, - #[serde(serialize_with = "crate::codecs::integral_f64::serialize")] - pub purchases_of_investments: StatementAmount, - #[serde(serialize_with = "crate::codecs::integral_f64::serialize")] - pub sales_maturities_of_investments: StatementAmount, + #[serde(deserialize_with = "required_option")] + #[serde(serialize_with = "crate::codecs::integral_f64::serialize_option")] + pub purchases_of_investments: Option, + #[serde(deserialize_with = "required_option")] + #[serde(serialize_with = "crate::codecs::integral_f64::serialize_option")] + pub sales_maturities_of_investments: Option, #[serde(serialize_with = "crate::codecs::integral_f64::serialize")] pub other_investing_activities: StatementAmount, #[serde(serialize_with = "crate::codecs::integral_f64::serialize")] pub net_cash_provided_by_investing_activities: StatementAmount, #[serde(serialize_with = "crate::codecs::integral_f64::serialize")] pub net_debt_issuance: StatementAmount, - #[serde(serialize_with = "crate::codecs::integral_f64::serialize")] - pub long_term_net_debt_issuance: StatementAmount, + #[serde(deserialize_with = "required_option")] + #[serde(serialize_with = "crate::codecs::integral_f64::serialize_option")] + pub long_term_net_debt_issuance: Option, #[serde(serialize_with = "crate::codecs::integral_f64::serialize")] pub short_term_net_debt_issuance: StatementAmount, - #[serde(serialize_with = "crate::codecs::integral_f64::serialize")] - pub net_stock_issuance: StatementAmount, - #[serde(serialize_with = "crate::codecs::integral_f64::serialize")] - pub net_common_stock_issuance: StatementAmount, + #[serde(deserialize_with = "required_option")] + #[serde(serialize_with = "crate::codecs::integral_f64::serialize_option")] + pub net_stock_issuance: Option, + #[serde(deserialize_with = "required_option")] + #[serde(serialize_with = "crate::codecs::integral_f64::serialize_option")] + pub net_common_stock_issuance: Option, #[serde(serialize_with = "crate::codecs::integral_f64::serialize")] pub common_stock_issuance: StatementAmount, - #[serde(serialize_with = "crate::codecs::integral_f64::serialize")] - pub common_stock_repurchased: StatementAmount, - #[serde(serialize_with = "crate::codecs::integral_f64::serialize")] - pub net_preferred_stock_issuance: StatementAmount, - #[serde(serialize_with = "crate::codecs::integral_f64::serialize")] - pub net_dividends_paid: StatementAmount, - #[serde(serialize_with = "crate::codecs::integral_f64::serialize")] - pub common_dividends_paid: StatementAmount, - #[serde(serialize_with = "crate::codecs::integral_f64::serialize")] - pub preferred_dividends_paid: StatementAmount, + #[serde(deserialize_with = "required_option")] + #[serde(serialize_with = "crate::codecs::integral_f64::serialize_option")] + pub common_stock_repurchased: Option, + #[serde(deserialize_with = "required_option")] + #[serde(serialize_with = "crate::codecs::integral_f64::serialize_option")] + pub net_preferred_stock_issuance: Option, + #[serde(deserialize_with = "required_option")] + #[serde(serialize_with = "crate::codecs::integral_f64::serialize_option")] + pub net_dividends_paid: Option, + #[serde(deserialize_with = "required_option")] + #[serde(serialize_with = "crate::codecs::integral_f64::serialize_option")] + pub common_dividends_paid: Option, + #[serde(deserialize_with = "required_option")] + #[serde(serialize_with = "crate::codecs::integral_f64::serialize_option")] + pub preferred_dividends_paid: Option, #[serde(serialize_with = "crate::codecs::integral_f64::serialize")] pub other_financing_activities: StatementAmount, - #[serde(serialize_with = "crate::codecs::integral_f64::serialize")] - pub net_cash_provided_by_financing_activities: StatementAmount, + #[serde(deserialize_with = "required_option")] + #[serde(serialize_with = "crate::codecs::integral_f64::serialize_option")] + pub net_cash_provided_by_financing_activities: Option, #[serde(serialize_with = "crate::codecs::integral_f64::serialize")] pub effect_of_forex_changes_on_cash: StatementAmount, #[serde(serialize_with = "crate::codecs::integral_f64::serialize")] pub net_change_in_cash: StatementAmount, #[serde(serialize_with = "crate::codecs::integral_f64::serialize")] pub cash_at_end_of_period: StatementAmount, - #[serde(serialize_with = "crate::codecs::integral_f64::serialize")] - pub cash_at_beginning_of_period: StatementAmount, + #[serde(deserialize_with = "required_option")] + #[serde(serialize_with = "crate::codecs::integral_f64::serialize_option")] + pub cash_at_beginning_of_period: Option, #[serde(serialize_with = "crate::codecs::integral_f64::serialize")] pub operating_cash_flow: StatementAmount, #[serde(serialize_with = "crate::codecs::integral_f64::serialize")] pub capital_expenditure: StatementAmount, #[serde(serialize_with = "crate::codecs::integral_f64::serialize")] pub free_cash_flow: StatementAmount, - #[serde(serialize_with = "crate::codecs::integral_f64::serialize")] - pub income_taxes_paid: StatementAmount, - #[serde(serialize_with = "crate::codecs::integral_f64::serialize")] - pub interest_paid: StatementAmount, + #[serde(deserialize_with = "required_option")] + #[serde(serialize_with = "crate::codecs::integral_f64::serialize_option")] + pub income_taxes_paid: Option, + #[serde(deserialize_with = "required_option")] + #[serde(serialize_with = "crate::codecs::integral_f64::serialize_option")] + pub interest_paid: Option, } diff --git a/crates/libfmp/tests/statements_balance_endpoints.rs b/crates/libfmp/tests/statements_balance_endpoints.rs index bacb8976..39f171fb 100644 --- a/crates/libfmp/tests/statements_balance_endpoints.rs +++ b/crates/libfmp/tests/statements_balance_endpoints.rs @@ -102,8 +102,8 @@ async fn proxy_client_uses_exact_queries_custom_auth_and_decodes_both_bare_array .unwrap(); assert_eq!(historical.len(), 1); - assert_eq!(historical[0].total_assets, 359_241_000_000.0); - assert_eq!(historical[0].retained_earnings, -14_264_000_000.0); + assert_eq!(historical[0].total_assets, Some(359_241_000_000.0)); + assert_eq!(historical[0].retained_earnings, Some(-14_264_000_000.0)); assert_eq!(ttm.len(), 1); assert_eq!(ttm[0].total_assets, 371_082_000_000.0); diff --git a/crates/libfmp/tests/statements_balance_responses.rs b/crates/libfmp/tests/statements_balance_responses.rs index 812d7faf..5a2cf214 100644 --- a/crates/libfmp/tests/statements_balance_responses.rs +++ b/crates/libfmp/tests/statements_balance_responses.rs @@ -22,8 +22,8 @@ fn historical_fixture_decodes_all_61_documented_fields_exactly() { let rows: Vec = serde_json::from_value(value).unwrap(); assert_eq!(rows.len(), 1); assert_historical(&rows[0]); - assert_eq!(rows[0].total_assets, 359_241_000_000.0); - assert_eq!(rows[0].retained_earnings, -14_264_000_000.0); + assert_eq!(rows[0].total_assets, Some(359_241_000_000.0)); + assert_eq!(rows[0].retained_earnings, Some(-14_264_000_000.0)); assert_eq!(rows[0].cik.as_str(), "0000320193"); assert_eq!(rows[0].accepted_date.to_string(), "2025-10-31 06:01:26"); } @@ -132,6 +132,71 @@ fn statement_amounts_preserve_large_integral_values_in_both_contracts() { } } +const STUB_QUARTER_NULL_MEMBERS: [&str; 38] = [ + "accountPayables", + "accountsReceivables", + "accruedExpenses", + "accumulatedOtherComprehensiveIncomeLoss", + "additionalPaidInCapital", + "capitalLeaseObligationsCurrent", + "capitalLeaseObligationsNonCurrent", + "cashAndCashEquivalents", + "cashAndShortTermInvestments", + "commonStock", + "deferredRevenue", + "deferredRevenueNonCurrent", + "deferredTaxLiabilitiesNonCurrent", + "goodwill", + "goodwillAndIntangibleAssets", + "intangibleAssets", + "inventory", + "longTermDebt", + "longTermInvestments", + "netReceivables", + "otherPayables", + "prepaids", + "propertyPlantEquipmentNet", + "retainedEarnings", + "shortTermDebt", + "shortTermInvestments", + "taxAssets", + "taxPayables", + "totalAssets", + "totalCurrentAssets", + "totalCurrentLiabilities", + "totalEquity", + "totalLiabilities", + "totalLiabilitiesAndTotalEquity", + "totalNonCurrentAssets", + "totalNonCurrentLiabilities", + "totalStockholdersEquity", + "treasuryStock", +]; + +#[test] +fn pre_ipo_stub_row_decodes_its_null_amounts_as_none() { + let mut value: serde_json::Value = serde_json::from_slice(HISTORICAL).unwrap(); + for member in STUB_QUARTER_NULL_MEMBERS { + value[0][member] = serde_json::Value::Null; + } + + let rows: Vec = serde_json::from_value(value).unwrap(); + assert_eq!(rows[0].total_assets, None); + assert!(rows[0].other_receivables.is_finite()); + + let encoded = serde_json::to_value(&rows).unwrap(); + for member in STUB_QUARTER_NULL_MEMBERS { + assert!(encoded[0][member].is_null(), "{member}"); + } +} + +#[test] +fn null_on_an_amount_outside_the_stub_set_is_still_rejected() { + let mut value: serde_json::Value = serde_json::from_slice(HISTORICAL).unwrap(); + value[0]["otherReceivables"] = serde_json::Value::Null; + assert!(serde_json::from_value::>(value).is_err()); +} + fn assert_historical(row: &BalanceSheetStatement) { assert_row!( row, @@ -144,56 +209,56 @@ fn assert_historical(row: &BalanceSheetStatement) { accepted_date: ApiDateTime::from_str("2025-10-31 06:01:26").unwrap(), fiscal_year: FiscalYearString::new("2025").unwrap(), period: FiscalPeriod::FullYear, - cash_and_cash_equivalents: 35_934_000_000.0, - short_term_investments: 18_763_000_000.0, - cash_and_short_term_investments: 54_697_000_000.0, - net_receivables: 72_957_000_000.0, - accounts_receivables: 39_777_000_000.0, + cash_and_cash_equivalents: Some(35_934_000_000.0), + short_term_investments: Some(18_763_000_000.0), + cash_and_short_term_investments: Some(54_697_000_000.0), + net_receivables: Some(72_957_000_000.0), + accounts_receivables: Some(39_777_000_000.0), other_receivables: 33_180_000_000.0, - inventory: 5_718_000_000.0, - prepaids: 0.0, + inventory: Some(5_718_000_000.0), + prepaids: Some(0.0), other_current_assets: 14_585_000_000.0, - total_current_assets: 147_957_000_000.0, - property_plant_equipment_net: 49_834_000_000.0, - goodwill: 0.0, - intangible_assets: 0.0, - goodwill_and_intangible_assets: 0.0, - long_term_investments: 77_723_000_000.0, - tax_assets: 20_777_000_000.0, + total_current_assets: Some(147_957_000_000.0), + property_plant_equipment_net: Some(49_834_000_000.0), + goodwill: Some(0.0), + intangible_assets: Some(0.0), + goodwill_and_intangible_assets: Some(0.0), + long_term_investments: Some(77_723_000_000.0), + tax_assets: Some(20_777_000_000.0), other_non_current_assets: 62_950_000_000.0, - total_non_current_assets: 211_284_000_000.0, + total_non_current_assets: Some(211_284_000_000.0), other_assets: 0.0, - total_assets: 359_241_000_000.0, + total_assets: Some(359_241_000_000.0), total_payables: 82_876_000_000.0, - account_payables: 69_860_000_000.0, - other_payables: 13_016_000_000.0, - accrued_expenses: 8_919_000_000.0, - short_term_debt: 20_329_000_000.0, - capital_lease_obligations_current: 2_117_000_000.0, - tax_payables: 0.0, - deferred_revenue: 9_055_000_000.0, + account_payables: Some(69_860_000_000.0), + other_payables: Some(13_016_000_000.0), + accrued_expenses: Some(8_919_000_000.0), + short_term_debt: Some(20_329_000_000.0), + capital_lease_obligations_current: Some(2_117_000_000.0), + tax_payables: Some(0.0), + deferred_revenue: Some(9_055_000_000.0), other_current_liabilities: 42_335_000_000.0, - total_current_liabilities: 165_631_000_000.0, - long_term_debt: 78_328_000_000.0, - capital_lease_obligations_non_current: 11_603_000_000.0, - deferred_revenue_non_current: 0.0, - deferred_tax_liabilities_non_current: 0.0, + total_current_liabilities: Some(165_631_000_000.0), + long_term_debt: Some(78_328_000_000.0), + capital_lease_obligations_non_current: Some(11_603_000_000.0), + deferred_revenue_non_current: Some(0.0), + deferred_tax_liabilities_non_current: Some(0.0), other_non_current_liabilities: 29_946_000_000.0, - total_non_current_liabilities: 119_877_000_000.0, + total_non_current_liabilities: Some(119_877_000_000.0), other_liabilities: 0.0, capital_lease_obligations: 13_720_000_000.0, - total_liabilities: 285_508_000_000.0, - treasury_stock: 0.0, + total_liabilities: Some(285_508_000_000.0), + treasury_stock: Some(0.0), preferred_stock: 0.0, - common_stock: 93_568_000_000.0, - retained_earnings: -14_264_000_000.0, - additional_paid_in_capital: 0.0, - accumulated_other_comprehensive_income_loss: -5_571_000_000.0, + common_stock: Some(93_568_000_000.0), + retained_earnings: Some(-14_264_000_000.0), + additional_paid_in_capital: Some(0.0), + accumulated_other_comprehensive_income_loss: Some(-5_571_000_000.0), other_total_stockholders_equity: 0.0, - total_stockholders_equity: 73_733_000_000.0, - total_equity: 73_733_000_000.0, + total_stockholders_equity: Some(73_733_000_000.0), + total_equity: Some(73_733_000_000.0), minority_interest: 0.0, - total_liabilities_and_total_equity: 359_241_000_000.0, + total_liabilities_and_total_equity: Some(359_241_000_000.0), total_investments: 96_486_000_000.0, total_debt: 112_377_000_000.0, net_debt: 76_443_000_000.0, diff --git a/crates/libfmp/tests/statements_cash_flow_responses.rs b/crates/libfmp/tests/statements_cash_flow_responses.rs index 55007846..3eca9883 100644 --- a/crates/libfmp/tests/statements_cash_flow_responses.rs +++ b/crates/libfmp/tests/statements_cash_flow_responses.rs @@ -28,7 +28,7 @@ fn historical_fixture_decodes_all_47_documented_fields_exactly() { ); assert_eq!( rows[0].net_cash_provided_by_financing_activities, - -120_686_000_000.0 + Some(-120_686_000_000.0) ); assert_eq!(rows[0].cik.as_str(), "0000320193"); assert_eq!(rows[0].accepted_date.to_string(), "2025-10-31 06:01:26"); @@ -104,6 +104,63 @@ fn statement_amounts_preserve_large_integral_values_for_both_endpoints() { } } +const STUB_QUARTER_NULL_MEMBERS: [&str; 19] = [ + "accountsPayables", + "accountsReceivables", + "cashAtBeginningOfPeriod", + "commonDividendsPaid", + "commonStockRepurchased", + "deferredIncomeTax", + "incomeTaxesPaid", + "interestPaid", + "inventory", + "longTermNetDebtIssuance", + "netCashProvidedByFinancingActivities", + "netCommonStockIssuance", + "netDividendsPaid", + "netPreferredStockIssuance", + "netStockIssuance", + "preferredDividendsPaid", + "purchasesOfInvestments", + "salesMaturitiesOfInvestments", + "stockBasedCompensation", +]; + +#[test] +fn pre_ipo_stub_row_decodes_its_null_amounts_as_none() { + let mut value: serde_json::Value = serde_json::from_slice(HISTORICAL).unwrap(); + for member in STUB_QUARTER_NULL_MEMBERS { + value[0][member] = serde_json::Value::Null; + } + + let rows: Vec = serde_json::from_value(value).unwrap(); + assert_eq!(rows[0].stock_based_compensation, None); + assert!(rows[0].net_income.is_finite()); + + let encoded = serde_json::to_value(&rows).unwrap(); + for member in STUB_QUARTER_NULL_MEMBERS { + assert!(encoded[0][member].is_null(), "{member}"); + } +} + +#[test] +fn null_on_an_amount_outside_the_stub_set_is_still_rejected() { + let mut value: serde_json::Value = serde_json::from_slice(HISTORICAL).unwrap(); + value[0]["netIncome"] = serde_json::Value::Null; + assert!(serde_json::from_value::>(value).is_err()); +} + +#[test] +fn missing_stub_amount_key_is_still_rejected() { + let mut value: serde_json::Value = serde_json::from_slice(HISTORICAL).unwrap(); + value[0] + .as_object_mut() + .unwrap() + .remove("stockBasedCompensation"); + let error = serde_json::from_value::>(value).unwrap_err(); + assert!(error.to_string().contains("stockBasedCompensation")); +} + fn assert_historical(row: &CashFlowStatement) { assert_row!( row, @@ -118,43 +175,43 @@ fn assert_historical(row: &CashFlowStatement) { period: FiscalPeriod::FullYear, net_income: 112_010_000_000.0, depreciation_and_amortization: 11_698_000_000.0, - deferred_income_tax: 0.0, - stock_based_compensation: 12_863_000_000.0, + deferred_income_tax: Some(0.0), + stock_based_compensation: Some(12_863_000_000.0), change_in_working_capital: -25_000_000_000.0, - accounts_receivables: -7_029_000_000.0, - inventory: 1_400_000_000.0, - accounts_payables: 902_000_000.0, + accounts_receivables: Some(-7_029_000_000.0), + inventory: Some(1_400_000_000.0), + accounts_payables: Some(902_000_000.0), other_working_capital: -20_273_000_000.0, other_non_cash_items: -89_000_000.0, net_cash_provided_by_operating_activities: 111_482_000_000.0, investments_in_property_plant_and_equipment: -12_715_000_000.0, acquisitions_net: 0.0, - purchases_of_investments: -24_407_000_000.0, - sales_maturities_of_investments: 53_797_000_000.0, + purchases_of_investments: Some(-24_407_000_000.0), + sales_maturities_of_investments: Some(53_797_000_000.0), other_investing_activities: -1_480_000_000.0, net_cash_provided_by_investing_activities: 15_195_000_000.0, net_debt_issuance: -8_483_000_000.0, - long_term_net_debt_issuance: -6_451_000_000.0, + long_term_net_debt_issuance: Some(-6_451_000_000.0), short_term_net_debt_issuance: -2_032_000_000.0, - net_stock_issuance: -90_711_000_000.0, - net_common_stock_issuance: -90_711_000_000.0, + net_stock_issuance: Some(-90_711_000_000.0), + net_common_stock_issuance: Some(-90_711_000_000.0), common_stock_issuance: 0.0, - common_stock_repurchased: -90_711_000_000.0, - net_preferred_stock_issuance: 0.0, - net_dividends_paid: -15_421_000_000.0, - common_dividends_paid: -15_421_000_000.0, - preferred_dividends_paid: 0.0, + common_stock_repurchased: Some(-90_711_000_000.0), + net_preferred_stock_issuance: Some(0.0), + net_dividends_paid: Some(-15_421_000_000.0), + common_dividends_paid: Some(-15_421_000_000.0), + preferred_dividends_paid: Some(0.0), other_financing_activities: -6_071_000_000.0, - net_cash_provided_by_financing_activities: -120_686_000_000.0, + net_cash_provided_by_financing_activities: Some(-120_686_000_000.0), effect_of_forex_changes_on_cash: 0.0, net_change_in_cash: 5_991_000_000.0, cash_at_end_of_period: 35_934_000_000.0, - cash_at_beginning_of_period: 29_943_000_000.0, + cash_at_beginning_of_period: Some(29_943_000_000.0), operating_cash_flow: 111_482_000_000.0, capital_expenditure: -12_715_000_000.0, free_cash_flow: 98_767_000_000.0, - income_taxes_paid: 43_369_000_000.0, - interest_paid: 0.0, + income_taxes_paid: Some(43_369_000_000.0), + interest_paid: Some(0.0), } ); } @@ -173,43 +230,43 @@ fn assert_ttm(row: &CashFlowStatement) { period: FiscalPeriod::Q2, net_income: 122_575_000_000.0, depreciation_and_amortization: 12_610_000_000.0, - deferred_income_tax: 0.0, - stock_based_compensation: 13_473_000_000.0, + deferred_income_tax: Some(0.0), + stock_based_compensation: Some(13_473_000_000.0), change_in_working_capital: -8_847_000_000.0, - accounts_receivables: -4_163_000_000.0, - inventory: -542_000_000.0, - accounts_payables: 3_209_000_000.0, + accounts_receivables: Some(-4_163_000_000.0), + inventory: Some(-542_000_000.0), + accounts_payables: Some(3_209_000_000.0), other_working_capital: -7_351_000_000.0, other_non_cash_items: 411_000_000.0, net_cash_provided_by_operating_activities: 140_222_000_000.0, investments_in_property_plant_and_equipment: -11_048_000_000.0, acquisitions_net: 0.0, - purchases_of_investments: -44_397_000_000.0, - sales_maturities_of_investments: 49_306_000_000.0, + purchases_of_investments: Some(-44_397_000_000.0), + sales_maturities_of_investments: Some(49_306_000_000.0), other_investing_activities: -2_429_000_000.0, net_cash_provided_by_investing_activities: -8_568_000_000.0, net_debt_issuance: -14_331_000_000.0, - long_term_net_debt_issuance: -10_356_000_000.0, + long_term_net_debt_issuance: Some(-10_356_000_000.0), short_term_net_debt_issuance: -3_975_000_000.0, - net_stock_issuance: -78_196_000_000.0, - net_common_stock_issuance: -78_196_000_000.0, + net_stock_issuance: Some(-78_196_000_000.0), + net_common_stock_issuance: Some(-78_196_000_000.0), common_stock_issuance: 0.0, - common_stock_repurchased: -78_196_000_000.0, - net_preferred_stock_issuance: 0.0, - net_dividends_paid: -15_550_000_000.0, - common_dividends_paid: -15_550_000_000.0, - preferred_dividends_paid: 0.0, + common_stock_repurchased: Some(-78_196_000_000.0), + net_preferred_stock_issuance: Some(0.0), + net_dividends_paid: Some(-15_550_000_000.0), + common_dividends_paid: Some(-15_550_000_000.0), + preferred_dividends_paid: Some(0.0), other_financing_activities: -6_167_000_000.0, - net_cash_provided_by_financing_activities: -114_244_000_000.0, + net_cash_provided_by_financing_activities: Some(-114_244_000_000.0), effect_of_forex_changes_on_cash: 0.0, net_change_in_cash: 17_410_000_000.0, cash_at_end_of_period: 45_572_000_000.0, - cash_at_beginning_of_period: 28_162_000_000.0, + cash_at_beginning_of_period: Some(28_162_000_000.0), operating_cash_flow: 140_222_000_000.0, capital_expenditure: -11_048_000_000.0, free_cash_flow: 129_174_000_000.0, - income_taxes_paid: -11_286_000_000.0, - interest_paid: 0.0, + income_taxes_paid: Some(-11_286_000_000.0), + interest_paid: Some(0.0), } ); } diff --git a/sdk/go/statements_models.go b/sdk/go/statements_models.go index 8a73da3c..742e1433 100644 --- a/sdk/go/statements_models.go +++ b/sdk/go/statements_models.go @@ -79,56 +79,56 @@ type BalanceSheetStatement struct { AcceptedDate DateTime `json:"acceptedDate"` FiscalYear string `json:"fiscalYear"` Period string `json:"period"` - CashAndCashEquivalents float64 `json:"cashAndCashEquivalents"` - ShortTermInvestments float64 `json:"shortTermInvestments"` - CashAndShortTermInvestments float64 `json:"cashAndShortTermInvestments"` - NetReceivables float64 `json:"netReceivables"` - AccountsReceivables float64 `json:"accountsReceivables"` + CashAndCashEquivalents *float64 `json:"cashAndCashEquivalents"` + ShortTermInvestments *float64 `json:"shortTermInvestments"` + CashAndShortTermInvestments *float64 `json:"cashAndShortTermInvestments"` + NetReceivables *float64 `json:"netReceivables"` + AccountsReceivables *float64 `json:"accountsReceivables"` OtherReceivables float64 `json:"otherReceivables"` - Inventory float64 `json:"inventory"` - Prepaids float64 `json:"prepaids"` + Inventory *float64 `json:"inventory"` + Prepaids *float64 `json:"prepaids"` OtherCurrentAssets float64 `json:"otherCurrentAssets"` - TotalCurrentAssets float64 `json:"totalCurrentAssets"` - PropertyPlantEquipmentNet float64 `json:"propertyPlantEquipmentNet"` - Goodwill float64 `json:"goodwill"` - IntangibleAssets float64 `json:"intangibleAssets"` - GoodwillAndIntangibleAssets float64 `json:"goodwillAndIntangibleAssets"` - LongTermInvestments float64 `json:"longTermInvestments"` - TaxAssets float64 `json:"taxAssets"` + TotalCurrentAssets *float64 `json:"totalCurrentAssets"` + PropertyPlantEquipmentNet *float64 `json:"propertyPlantEquipmentNet"` + Goodwill *float64 `json:"goodwill"` + IntangibleAssets *float64 `json:"intangibleAssets"` + GoodwillAndIntangibleAssets *float64 `json:"goodwillAndIntangibleAssets"` + LongTermInvestments *float64 `json:"longTermInvestments"` + TaxAssets *float64 `json:"taxAssets"` OtherNonCurrentAssets float64 `json:"otherNonCurrentAssets"` - TotalNonCurrentAssets float64 `json:"totalNonCurrentAssets"` + TotalNonCurrentAssets *float64 `json:"totalNonCurrentAssets"` OtherAssets float64 `json:"otherAssets"` - TotalAssets float64 `json:"totalAssets"` + TotalAssets *float64 `json:"totalAssets"` TotalPayables float64 `json:"totalPayables"` - AccountPayables float64 `json:"accountPayables"` - OtherPayables float64 `json:"otherPayables"` - AccruedExpenses float64 `json:"accruedExpenses"` - ShortTermDebt float64 `json:"shortTermDebt"` - CapitalLeaseObligationsCurrent float64 `json:"capitalLeaseObligationsCurrent"` - TaxPayables float64 `json:"taxPayables"` - DeferredRevenue float64 `json:"deferredRevenue"` + AccountPayables *float64 `json:"accountPayables"` + OtherPayables *float64 `json:"otherPayables"` + AccruedExpenses *float64 `json:"accruedExpenses"` + ShortTermDebt *float64 `json:"shortTermDebt"` + CapitalLeaseObligationsCurrent *float64 `json:"capitalLeaseObligationsCurrent"` + TaxPayables *float64 `json:"taxPayables"` + DeferredRevenue *float64 `json:"deferredRevenue"` OtherCurrentLiabilities float64 `json:"otherCurrentLiabilities"` - TotalCurrentLiabilities float64 `json:"totalCurrentLiabilities"` - LongTermDebt float64 `json:"longTermDebt"` - CapitalLeaseObligationsNonCurrent float64 `json:"capitalLeaseObligationsNonCurrent"` - DeferredRevenueNonCurrent float64 `json:"deferredRevenueNonCurrent"` - DeferredTaxLiabilitiesNonCurrent float64 `json:"deferredTaxLiabilitiesNonCurrent"` + TotalCurrentLiabilities *float64 `json:"totalCurrentLiabilities"` + LongTermDebt *float64 `json:"longTermDebt"` + CapitalLeaseObligationsNonCurrent *float64 `json:"capitalLeaseObligationsNonCurrent"` + DeferredRevenueNonCurrent *float64 `json:"deferredRevenueNonCurrent"` + DeferredTaxLiabilitiesNonCurrent *float64 `json:"deferredTaxLiabilitiesNonCurrent"` OtherNonCurrentLiabilities float64 `json:"otherNonCurrentLiabilities"` - TotalNonCurrentLiabilities float64 `json:"totalNonCurrentLiabilities"` + TotalNonCurrentLiabilities *float64 `json:"totalNonCurrentLiabilities"` OtherLiabilities float64 `json:"otherLiabilities"` CapitalLeaseObligations float64 `json:"capitalLeaseObligations"` - TotalLiabilities float64 `json:"totalLiabilities"` - TreasuryStock float64 `json:"treasuryStock"` + TotalLiabilities *float64 `json:"totalLiabilities"` + TreasuryStock *float64 `json:"treasuryStock"` PreferredStock float64 `json:"preferredStock"` - CommonStock float64 `json:"commonStock"` - RetainedEarnings float64 `json:"retainedEarnings"` - AdditionalPaidInCapital float64 `json:"additionalPaidInCapital"` - AccumulatedOtherComprehensiveIncomeLoss float64 `json:"accumulatedOtherComprehensiveIncomeLoss"` + CommonStock *float64 `json:"commonStock"` + RetainedEarnings *float64 `json:"retainedEarnings"` + AdditionalPaidInCapital *float64 `json:"additionalPaidInCapital"` + AccumulatedOtherComprehensiveIncomeLoss *float64 `json:"accumulatedOtherComprehensiveIncomeLoss"` OtherTotalStockholdersEquity float64 `json:"otherTotalStockholdersEquity"` - TotalStockholdersEquity float64 `json:"totalStockholdersEquity"` - TotalEquity float64 `json:"totalEquity"` + TotalStockholdersEquity *float64 `json:"totalStockholdersEquity"` + TotalEquity *float64 `json:"totalEquity"` MinorityInterest float64 `json:"minorityInterest"` - TotalLiabilitiesAndTotalEquity float64 `json:"totalLiabilitiesAndTotalEquity"` + TotalLiabilitiesAndTotalEquity *float64 `json:"totalLiabilitiesAndTotalEquity"` TotalInvestments float64 `json:"totalInvestments"` TotalDebt float64 `json:"totalDebt"` NetDebt float64 `json:"netDebt"` @@ -138,67 +138,67 @@ type BalanceSheetStatement struct { // raw value for every required member so a missing or null member is // observable after decoding. type balanceSheetStatementShadow struct { - Date *Date `json:"date"` - Symbol *string `json:"symbol"` - ReportedCurrency *string `json:"reportedCurrency"` - CIK *string `json:"cik"` - FilingDate *Date `json:"filingDate"` - AcceptedDate *DateTime `json:"acceptedDate"` - FiscalYear *string `json:"fiscalYear"` - Period *string `json:"period"` - CashAndCashEquivalents *float64 `json:"cashAndCashEquivalents"` - ShortTermInvestments *float64 `json:"shortTermInvestments"` - CashAndShortTermInvestments *float64 `json:"cashAndShortTermInvestments"` - NetReceivables *float64 `json:"netReceivables"` - AccountsReceivables *float64 `json:"accountsReceivables"` - OtherReceivables *float64 `json:"otherReceivables"` - Inventory *float64 `json:"inventory"` - Prepaids *float64 `json:"prepaids"` - OtherCurrentAssets *float64 `json:"otherCurrentAssets"` - TotalCurrentAssets *float64 `json:"totalCurrentAssets"` - PropertyPlantEquipmentNet *float64 `json:"propertyPlantEquipmentNet"` - Goodwill *float64 `json:"goodwill"` - IntangibleAssets *float64 `json:"intangibleAssets"` - GoodwillAndIntangibleAssets *float64 `json:"goodwillAndIntangibleAssets"` - LongTermInvestments *float64 `json:"longTermInvestments"` - TaxAssets *float64 `json:"taxAssets"` - OtherNonCurrentAssets *float64 `json:"otherNonCurrentAssets"` - TotalNonCurrentAssets *float64 `json:"totalNonCurrentAssets"` - OtherAssets *float64 `json:"otherAssets"` - TotalAssets *float64 `json:"totalAssets"` - TotalPayables *float64 `json:"totalPayables"` - AccountPayables *float64 `json:"accountPayables"` - OtherPayables *float64 `json:"otherPayables"` - AccruedExpenses *float64 `json:"accruedExpenses"` - ShortTermDebt *float64 `json:"shortTermDebt"` - CapitalLeaseObligationsCurrent *float64 `json:"capitalLeaseObligationsCurrent"` - TaxPayables *float64 `json:"taxPayables"` - DeferredRevenue *float64 `json:"deferredRevenue"` - OtherCurrentLiabilities *float64 `json:"otherCurrentLiabilities"` - TotalCurrentLiabilities *float64 `json:"totalCurrentLiabilities"` - LongTermDebt *float64 `json:"longTermDebt"` - CapitalLeaseObligationsNonCurrent *float64 `json:"capitalLeaseObligationsNonCurrent"` - DeferredRevenueNonCurrent *float64 `json:"deferredRevenueNonCurrent"` - DeferredTaxLiabilitiesNonCurrent *float64 `json:"deferredTaxLiabilitiesNonCurrent"` - OtherNonCurrentLiabilities *float64 `json:"otherNonCurrentLiabilities"` - TotalNonCurrentLiabilities *float64 `json:"totalNonCurrentLiabilities"` - OtherLiabilities *float64 `json:"otherLiabilities"` - CapitalLeaseObligations *float64 `json:"capitalLeaseObligations"` - TotalLiabilities *float64 `json:"totalLiabilities"` - TreasuryStock *float64 `json:"treasuryStock"` - PreferredStock *float64 `json:"preferredStock"` - CommonStock *float64 `json:"commonStock"` - RetainedEarnings *float64 `json:"retainedEarnings"` - AdditionalPaidInCapital *float64 `json:"additionalPaidInCapital"` - AccumulatedOtherComprehensiveIncomeLoss *float64 `json:"accumulatedOtherComprehensiveIncomeLoss"` - OtherTotalStockholdersEquity *float64 `json:"otherTotalStockholdersEquity"` - TotalStockholdersEquity *float64 `json:"totalStockholdersEquity"` - TotalEquity *float64 `json:"totalEquity"` - MinorityInterest *float64 `json:"minorityInterest"` - TotalLiabilitiesAndTotalEquity *float64 `json:"totalLiabilitiesAndTotalEquity"` - TotalInvestments *float64 `json:"totalInvestments"` - TotalDebt *float64 `json:"totalDebt"` - NetDebt *float64 `json:"netDebt"` + Date *Date `json:"date"` + Symbol *string `json:"symbol"` + ReportedCurrency *string `json:"reportedCurrency"` + CIK *string `json:"cik"` + FilingDate *Date `json:"filingDate"` + AcceptedDate *DateTime `json:"acceptedDate"` + FiscalYear *string `json:"fiscalYear"` + Period *string `json:"period"` + CashAndCashEquivalents jsontext.Value `json:"cashAndCashEquivalents"` + ShortTermInvestments jsontext.Value `json:"shortTermInvestments"` + CashAndShortTermInvestments jsontext.Value `json:"cashAndShortTermInvestments"` + NetReceivables jsontext.Value `json:"netReceivables"` + AccountsReceivables jsontext.Value `json:"accountsReceivables"` + OtherReceivables *float64 `json:"otherReceivables"` + Inventory jsontext.Value `json:"inventory"` + Prepaids jsontext.Value `json:"prepaids"` + OtherCurrentAssets *float64 `json:"otherCurrentAssets"` + TotalCurrentAssets jsontext.Value `json:"totalCurrentAssets"` + PropertyPlantEquipmentNet jsontext.Value `json:"propertyPlantEquipmentNet"` + Goodwill jsontext.Value `json:"goodwill"` + IntangibleAssets jsontext.Value `json:"intangibleAssets"` + GoodwillAndIntangibleAssets jsontext.Value `json:"goodwillAndIntangibleAssets"` + LongTermInvestments jsontext.Value `json:"longTermInvestments"` + TaxAssets jsontext.Value `json:"taxAssets"` + OtherNonCurrentAssets *float64 `json:"otherNonCurrentAssets"` + TotalNonCurrentAssets jsontext.Value `json:"totalNonCurrentAssets"` + OtherAssets *float64 `json:"otherAssets"` + TotalAssets jsontext.Value `json:"totalAssets"` + TotalPayables *float64 `json:"totalPayables"` + AccountPayables jsontext.Value `json:"accountPayables"` + OtherPayables jsontext.Value `json:"otherPayables"` + AccruedExpenses jsontext.Value `json:"accruedExpenses"` + ShortTermDebt jsontext.Value `json:"shortTermDebt"` + CapitalLeaseObligationsCurrent jsontext.Value `json:"capitalLeaseObligationsCurrent"` + TaxPayables jsontext.Value `json:"taxPayables"` + DeferredRevenue jsontext.Value `json:"deferredRevenue"` + OtherCurrentLiabilities *float64 `json:"otherCurrentLiabilities"` + TotalCurrentLiabilities jsontext.Value `json:"totalCurrentLiabilities"` + LongTermDebt jsontext.Value `json:"longTermDebt"` + CapitalLeaseObligationsNonCurrent jsontext.Value `json:"capitalLeaseObligationsNonCurrent"` + DeferredRevenueNonCurrent jsontext.Value `json:"deferredRevenueNonCurrent"` + DeferredTaxLiabilitiesNonCurrent jsontext.Value `json:"deferredTaxLiabilitiesNonCurrent"` + OtherNonCurrentLiabilities *float64 `json:"otherNonCurrentLiabilities"` + TotalNonCurrentLiabilities jsontext.Value `json:"totalNonCurrentLiabilities"` + OtherLiabilities *float64 `json:"otherLiabilities"` + CapitalLeaseObligations *float64 `json:"capitalLeaseObligations"` + TotalLiabilities jsontext.Value `json:"totalLiabilities"` + TreasuryStock jsontext.Value `json:"treasuryStock"` + PreferredStock *float64 `json:"preferredStock"` + CommonStock jsontext.Value `json:"commonStock"` + RetainedEarnings jsontext.Value `json:"retainedEarnings"` + AdditionalPaidInCapital jsontext.Value `json:"additionalPaidInCapital"` + AccumulatedOtherComprehensiveIncomeLoss jsontext.Value `json:"accumulatedOtherComprehensiveIncomeLoss"` + OtherTotalStockholdersEquity *float64 `json:"otherTotalStockholdersEquity"` + TotalStockholdersEquity jsontext.Value `json:"totalStockholdersEquity"` + TotalEquity jsontext.Value `json:"totalEquity"` + MinorityInterest *float64 `json:"minorityInterest"` + TotalLiabilitiesAndTotalEquity jsontext.Value `json:"totalLiabilitiesAndTotalEquity"` + TotalInvestments *float64 `json:"totalInvestments"` + TotalDebt *float64 `json:"totalDebt"` + NetDebt *float64 `json:"netDebt"` } // UnmarshalJSONFrom decodes one JSON object and rejects it with a Decode @@ -226,105 +226,105 @@ func (m *BalanceSheetStatement) UnmarshalJSONFrom(dec *jsontext.Decoder) error { return missingMemberError("BalanceSheetStatement", "fiscalYear") case shadow.Period == nil: return missingMemberError("BalanceSheetStatement", "period") - case shadow.CashAndCashEquivalents == nil: + case len(shadow.CashAndCashEquivalents) == 0: return missingMemberError("BalanceSheetStatement", "cashAndCashEquivalents") - case shadow.ShortTermInvestments == nil: + case len(shadow.ShortTermInvestments) == 0: return missingMemberError("BalanceSheetStatement", "shortTermInvestments") - case shadow.CashAndShortTermInvestments == nil: + case len(shadow.CashAndShortTermInvestments) == 0: return missingMemberError("BalanceSheetStatement", "cashAndShortTermInvestments") - case shadow.NetReceivables == nil: + case len(shadow.NetReceivables) == 0: return missingMemberError("BalanceSheetStatement", "netReceivables") - case shadow.AccountsReceivables == nil: + case len(shadow.AccountsReceivables) == 0: return missingMemberError("BalanceSheetStatement", "accountsReceivables") case shadow.OtherReceivables == nil: return missingMemberError("BalanceSheetStatement", "otherReceivables") - case shadow.Inventory == nil: + case len(shadow.Inventory) == 0: return missingMemberError("BalanceSheetStatement", "inventory") - case shadow.Prepaids == nil: + case len(shadow.Prepaids) == 0: return missingMemberError("BalanceSheetStatement", "prepaids") case shadow.OtherCurrentAssets == nil: return missingMemberError("BalanceSheetStatement", "otherCurrentAssets") - case shadow.TotalCurrentAssets == nil: + case len(shadow.TotalCurrentAssets) == 0: return missingMemberError("BalanceSheetStatement", "totalCurrentAssets") - case shadow.PropertyPlantEquipmentNet == nil: + case len(shadow.PropertyPlantEquipmentNet) == 0: return missingMemberError("BalanceSheetStatement", "propertyPlantEquipmentNet") - case shadow.Goodwill == nil: + case len(shadow.Goodwill) == 0: return missingMemberError("BalanceSheetStatement", "goodwill") - case shadow.IntangibleAssets == nil: + case len(shadow.IntangibleAssets) == 0: return missingMemberError("BalanceSheetStatement", "intangibleAssets") - case shadow.GoodwillAndIntangibleAssets == nil: + case len(shadow.GoodwillAndIntangibleAssets) == 0: return missingMemberError("BalanceSheetStatement", "goodwillAndIntangibleAssets") - case shadow.LongTermInvestments == nil: + case len(shadow.LongTermInvestments) == 0: return missingMemberError("BalanceSheetStatement", "longTermInvestments") - case shadow.TaxAssets == nil: + case len(shadow.TaxAssets) == 0: return missingMemberError("BalanceSheetStatement", "taxAssets") case shadow.OtherNonCurrentAssets == nil: return missingMemberError("BalanceSheetStatement", "otherNonCurrentAssets") - case shadow.TotalNonCurrentAssets == nil: + case len(shadow.TotalNonCurrentAssets) == 0: return missingMemberError("BalanceSheetStatement", "totalNonCurrentAssets") case shadow.OtherAssets == nil: return missingMemberError("BalanceSheetStatement", "otherAssets") - case shadow.TotalAssets == nil: + case len(shadow.TotalAssets) == 0: return missingMemberError("BalanceSheetStatement", "totalAssets") case shadow.TotalPayables == nil: return missingMemberError("BalanceSheetStatement", "totalPayables") - case shadow.AccountPayables == nil: + case len(shadow.AccountPayables) == 0: return missingMemberError("BalanceSheetStatement", "accountPayables") - case shadow.OtherPayables == nil: + case len(shadow.OtherPayables) == 0: return missingMemberError("BalanceSheetStatement", "otherPayables") - case shadow.AccruedExpenses == nil: + case len(shadow.AccruedExpenses) == 0: return missingMemberError("BalanceSheetStatement", "accruedExpenses") - case shadow.ShortTermDebt == nil: + case len(shadow.ShortTermDebt) == 0: return missingMemberError("BalanceSheetStatement", "shortTermDebt") - case shadow.CapitalLeaseObligationsCurrent == nil: + case len(shadow.CapitalLeaseObligationsCurrent) == 0: return missingMemberError("BalanceSheetStatement", "capitalLeaseObligationsCurrent") - case shadow.TaxPayables == nil: + case len(shadow.TaxPayables) == 0: return missingMemberError("BalanceSheetStatement", "taxPayables") - case shadow.DeferredRevenue == nil: + case len(shadow.DeferredRevenue) == 0: return missingMemberError("BalanceSheetStatement", "deferredRevenue") case shadow.OtherCurrentLiabilities == nil: return missingMemberError("BalanceSheetStatement", "otherCurrentLiabilities") - case shadow.TotalCurrentLiabilities == nil: + case len(shadow.TotalCurrentLiabilities) == 0: return missingMemberError("BalanceSheetStatement", "totalCurrentLiabilities") - case shadow.LongTermDebt == nil: + case len(shadow.LongTermDebt) == 0: return missingMemberError("BalanceSheetStatement", "longTermDebt") - case shadow.CapitalLeaseObligationsNonCurrent == nil: + case len(shadow.CapitalLeaseObligationsNonCurrent) == 0: return missingMemberError("BalanceSheetStatement", "capitalLeaseObligationsNonCurrent") - case shadow.DeferredRevenueNonCurrent == nil: + case len(shadow.DeferredRevenueNonCurrent) == 0: return missingMemberError("BalanceSheetStatement", "deferredRevenueNonCurrent") - case shadow.DeferredTaxLiabilitiesNonCurrent == nil: + case len(shadow.DeferredTaxLiabilitiesNonCurrent) == 0: return missingMemberError("BalanceSheetStatement", "deferredTaxLiabilitiesNonCurrent") case shadow.OtherNonCurrentLiabilities == nil: return missingMemberError("BalanceSheetStatement", "otherNonCurrentLiabilities") - case shadow.TotalNonCurrentLiabilities == nil: + case len(shadow.TotalNonCurrentLiabilities) == 0: return missingMemberError("BalanceSheetStatement", "totalNonCurrentLiabilities") case shadow.OtherLiabilities == nil: return missingMemberError("BalanceSheetStatement", "otherLiabilities") case shadow.CapitalLeaseObligations == nil: return missingMemberError("BalanceSheetStatement", "capitalLeaseObligations") - case shadow.TotalLiabilities == nil: + case len(shadow.TotalLiabilities) == 0: return missingMemberError("BalanceSheetStatement", "totalLiabilities") - case shadow.TreasuryStock == nil: + case len(shadow.TreasuryStock) == 0: return missingMemberError("BalanceSheetStatement", "treasuryStock") case shadow.PreferredStock == nil: return missingMemberError("BalanceSheetStatement", "preferredStock") - case shadow.CommonStock == nil: + case len(shadow.CommonStock) == 0: return missingMemberError("BalanceSheetStatement", "commonStock") - case shadow.RetainedEarnings == nil: + case len(shadow.RetainedEarnings) == 0: return missingMemberError("BalanceSheetStatement", "retainedEarnings") - case shadow.AdditionalPaidInCapital == nil: + case len(shadow.AdditionalPaidInCapital) == 0: return missingMemberError("BalanceSheetStatement", "additionalPaidInCapital") - case shadow.AccumulatedOtherComprehensiveIncomeLoss == nil: + case len(shadow.AccumulatedOtherComprehensiveIncomeLoss) == 0: return missingMemberError("BalanceSheetStatement", "accumulatedOtherComprehensiveIncomeLoss") case shadow.OtherTotalStockholdersEquity == nil: return missingMemberError("BalanceSheetStatement", "otherTotalStockholdersEquity") - case shadow.TotalStockholdersEquity == nil: + case len(shadow.TotalStockholdersEquity) == 0: return missingMemberError("BalanceSheetStatement", "totalStockholdersEquity") - case shadow.TotalEquity == nil: + case len(shadow.TotalEquity) == 0: return missingMemberError("BalanceSheetStatement", "totalEquity") case shadow.MinorityInterest == nil: return missingMemberError("BalanceSheetStatement", "minorityInterest") - case shadow.TotalLiabilitiesAndTotalEquity == nil: + case len(shadow.TotalLiabilitiesAndTotalEquity) == 0: return missingMemberError("BalanceSheetStatement", "totalLiabilitiesAndTotalEquity") case shadow.TotalInvestments == nil: return missingMemberError("BalanceSheetStatement", "totalInvestments") @@ -333,6 +333,310 @@ func (m *BalanceSheetStatement) UnmarshalJSONFrom(dec *jsontext.Decoder) error { case shadow.NetDebt == nil: return missingMemberError("BalanceSheetStatement", "netDebt") } + var cashAndCashEquivalents *float64 + if shadow.CashAndCashEquivalents.Kind() != 'n' { + var value float64 + if err := json.Unmarshal(shadow.CashAndCashEquivalents, &value); err != nil { + return err + } + cashAndCashEquivalents = &value + } + var shortTermInvestments *float64 + if shadow.ShortTermInvestments.Kind() != 'n' { + var value float64 + if err := json.Unmarshal(shadow.ShortTermInvestments, &value); err != nil { + return err + } + shortTermInvestments = &value + } + var cashAndShortTermInvestments *float64 + if shadow.CashAndShortTermInvestments.Kind() != 'n' { + var value float64 + if err := json.Unmarshal(shadow.CashAndShortTermInvestments, &value); err != nil { + return err + } + cashAndShortTermInvestments = &value + } + var netReceivables *float64 + if shadow.NetReceivables.Kind() != 'n' { + var value float64 + if err := json.Unmarshal(shadow.NetReceivables, &value); err != nil { + return err + } + netReceivables = &value + } + var accountsReceivables *float64 + if shadow.AccountsReceivables.Kind() != 'n' { + var value float64 + if err := json.Unmarshal(shadow.AccountsReceivables, &value); err != nil { + return err + } + accountsReceivables = &value + } + var inventory *float64 + if shadow.Inventory.Kind() != 'n' { + var value float64 + if err := json.Unmarshal(shadow.Inventory, &value); err != nil { + return err + } + inventory = &value + } + var prepaids *float64 + if shadow.Prepaids.Kind() != 'n' { + var value float64 + if err := json.Unmarshal(shadow.Prepaids, &value); err != nil { + return err + } + prepaids = &value + } + var totalCurrentAssets *float64 + if shadow.TotalCurrentAssets.Kind() != 'n' { + var value float64 + if err := json.Unmarshal(shadow.TotalCurrentAssets, &value); err != nil { + return err + } + totalCurrentAssets = &value + } + var propertyPlantEquipmentNet *float64 + if shadow.PropertyPlantEquipmentNet.Kind() != 'n' { + var value float64 + if err := json.Unmarshal(shadow.PropertyPlantEquipmentNet, &value); err != nil { + return err + } + propertyPlantEquipmentNet = &value + } + var goodwill *float64 + if shadow.Goodwill.Kind() != 'n' { + var value float64 + if err := json.Unmarshal(shadow.Goodwill, &value); err != nil { + return err + } + goodwill = &value + } + var intangibleAssets *float64 + if shadow.IntangibleAssets.Kind() != 'n' { + var value float64 + if err := json.Unmarshal(shadow.IntangibleAssets, &value); err != nil { + return err + } + intangibleAssets = &value + } + var goodwillAndIntangibleAssets *float64 + if shadow.GoodwillAndIntangibleAssets.Kind() != 'n' { + var value float64 + if err := json.Unmarshal(shadow.GoodwillAndIntangibleAssets, &value); err != nil { + return err + } + goodwillAndIntangibleAssets = &value + } + var longTermInvestments *float64 + if shadow.LongTermInvestments.Kind() != 'n' { + var value float64 + if err := json.Unmarshal(shadow.LongTermInvestments, &value); err != nil { + return err + } + longTermInvestments = &value + } + var taxAssets *float64 + if shadow.TaxAssets.Kind() != 'n' { + var value float64 + if err := json.Unmarshal(shadow.TaxAssets, &value); err != nil { + return err + } + taxAssets = &value + } + var totalNonCurrentAssets *float64 + if shadow.TotalNonCurrentAssets.Kind() != 'n' { + var value float64 + if err := json.Unmarshal(shadow.TotalNonCurrentAssets, &value); err != nil { + return err + } + totalNonCurrentAssets = &value + } + var totalAssets *float64 + if shadow.TotalAssets.Kind() != 'n' { + var value float64 + if err := json.Unmarshal(shadow.TotalAssets, &value); err != nil { + return err + } + totalAssets = &value + } + var accountPayables *float64 + if shadow.AccountPayables.Kind() != 'n' { + var value float64 + if err := json.Unmarshal(shadow.AccountPayables, &value); err != nil { + return err + } + accountPayables = &value + } + var otherPayables *float64 + if shadow.OtherPayables.Kind() != 'n' { + var value float64 + if err := json.Unmarshal(shadow.OtherPayables, &value); err != nil { + return err + } + otherPayables = &value + } + var accruedExpenses *float64 + if shadow.AccruedExpenses.Kind() != 'n' { + var value float64 + if err := json.Unmarshal(shadow.AccruedExpenses, &value); err != nil { + return err + } + accruedExpenses = &value + } + var shortTermDebt *float64 + if shadow.ShortTermDebt.Kind() != 'n' { + var value float64 + if err := json.Unmarshal(shadow.ShortTermDebt, &value); err != nil { + return err + } + shortTermDebt = &value + } + var capitalLeaseObligationsCurrent *float64 + if shadow.CapitalLeaseObligationsCurrent.Kind() != 'n' { + var value float64 + if err := json.Unmarshal(shadow.CapitalLeaseObligationsCurrent, &value); err != nil { + return err + } + capitalLeaseObligationsCurrent = &value + } + var taxPayables *float64 + if shadow.TaxPayables.Kind() != 'n' { + var value float64 + if err := json.Unmarshal(shadow.TaxPayables, &value); err != nil { + return err + } + taxPayables = &value + } + var deferredRevenue *float64 + if shadow.DeferredRevenue.Kind() != 'n' { + var value float64 + if err := json.Unmarshal(shadow.DeferredRevenue, &value); err != nil { + return err + } + deferredRevenue = &value + } + var totalCurrentLiabilities *float64 + if shadow.TotalCurrentLiabilities.Kind() != 'n' { + var value float64 + if err := json.Unmarshal(shadow.TotalCurrentLiabilities, &value); err != nil { + return err + } + totalCurrentLiabilities = &value + } + var longTermDebt *float64 + if shadow.LongTermDebt.Kind() != 'n' { + var value float64 + if err := json.Unmarshal(shadow.LongTermDebt, &value); err != nil { + return err + } + longTermDebt = &value + } + var capitalLeaseObligationsNonCurrent *float64 + if shadow.CapitalLeaseObligationsNonCurrent.Kind() != 'n' { + var value float64 + if err := json.Unmarshal(shadow.CapitalLeaseObligationsNonCurrent, &value); err != nil { + return err + } + capitalLeaseObligationsNonCurrent = &value + } + var deferredRevenueNonCurrent *float64 + if shadow.DeferredRevenueNonCurrent.Kind() != 'n' { + var value float64 + if err := json.Unmarshal(shadow.DeferredRevenueNonCurrent, &value); err != nil { + return err + } + deferredRevenueNonCurrent = &value + } + var deferredTaxLiabilitiesNonCurrent *float64 + if shadow.DeferredTaxLiabilitiesNonCurrent.Kind() != 'n' { + var value float64 + if err := json.Unmarshal(shadow.DeferredTaxLiabilitiesNonCurrent, &value); err != nil { + return err + } + deferredTaxLiabilitiesNonCurrent = &value + } + var totalNonCurrentLiabilities *float64 + if shadow.TotalNonCurrentLiabilities.Kind() != 'n' { + var value float64 + if err := json.Unmarshal(shadow.TotalNonCurrentLiabilities, &value); err != nil { + return err + } + totalNonCurrentLiabilities = &value + } + var totalLiabilities *float64 + if shadow.TotalLiabilities.Kind() != 'n' { + var value float64 + if err := json.Unmarshal(shadow.TotalLiabilities, &value); err != nil { + return err + } + totalLiabilities = &value + } + var treasuryStock *float64 + if shadow.TreasuryStock.Kind() != 'n' { + var value float64 + if err := json.Unmarshal(shadow.TreasuryStock, &value); err != nil { + return err + } + treasuryStock = &value + } + var commonStock *float64 + if shadow.CommonStock.Kind() != 'n' { + var value float64 + if err := json.Unmarshal(shadow.CommonStock, &value); err != nil { + return err + } + commonStock = &value + } + var retainedEarnings *float64 + if shadow.RetainedEarnings.Kind() != 'n' { + var value float64 + if err := json.Unmarshal(shadow.RetainedEarnings, &value); err != nil { + return err + } + retainedEarnings = &value + } + var additionalPaidInCapital *float64 + if shadow.AdditionalPaidInCapital.Kind() != 'n' { + var value float64 + if err := json.Unmarshal(shadow.AdditionalPaidInCapital, &value); err != nil { + return err + } + additionalPaidInCapital = &value + } + var accumulatedOtherComprehensiveIncomeLoss *float64 + if shadow.AccumulatedOtherComprehensiveIncomeLoss.Kind() != 'n' { + var value float64 + if err := json.Unmarshal(shadow.AccumulatedOtherComprehensiveIncomeLoss, &value); err != nil { + return err + } + accumulatedOtherComprehensiveIncomeLoss = &value + } + var totalStockholdersEquity *float64 + if shadow.TotalStockholdersEquity.Kind() != 'n' { + var value float64 + if err := json.Unmarshal(shadow.TotalStockholdersEquity, &value); err != nil { + return err + } + totalStockholdersEquity = &value + } + var totalEquity *float64 + if shadow.TotalEquity.Kind() != 'n' { + var value float64 + if err := json.Unmarshal(shadow.TotalEquity, &value); err != nil { + return err + } + totalEquity = &value + } + var totalLiabilitiesAndTotalEquity *float64 + if shadow.TotalLiabilitiesAndTotalEquity.Kind() != 'n' { + var value float64 + if err := json.Unmarshal(shadow.TotalLiabilitiesAndTotalEquity, &value); err != nil { + return err + } + totalLiabilitiesAndTotalEquity = &value + } *m = BalanceSheetStatement{ Date: *shadow.Date, Symbol: *shadow.Symbol, @@ -342,56 +646,56 @@ func (m *BalanceSheetStatement) UnmarshalJSONFrom(dec *jsontext.Decoder) error { AcceptedDate: *shadow.AcceptedDate, FiscalYear: *shadow.FiscalYear, Period: *shadow.Period, - CashAndCashEquivalents: *shadow.CashAndCashEquivalents, - ShortTermInvestments: *shadow.ShortTermInvestments, - CashAndShortTermInvestments: *shadow.CashAndShortTermInvestments, - NetReceivables: *shadow.NetReceivables, - AccountsReceivables: *shadow.AccountsReceivables, + CashAndCashEquivalents: cashAndCashEquivalents, + ShortTermInvestments: shortTermInvestments, + CashAndShortTermInvestments: cashAndShortTermInvestments, + NetReceivables: netReceivables, + AccountsReceivables: accountsReceivables, OtherReceivables: *shadow.OtherReceivables, - Inventory: *shadow.Inventory, - Prepaids: *shadow.Prepaids, + Inventory: inventory, + Prepaids: prepaids, OtherCurrentAssets: *shadow.OtherCurrentAssets, - TotalCurrentAssets: *shadow.TotalCurrentAssets, - PropertyPlantEquipmentNet: *shadow.PropertyPlantEquipmentNet, - Goodwill: *shadow.Goodwill, - IntangibleAssets: *shadow.IntangibleAssets, - GoodwillAndIntangibleAssets: *shadow.GoodwillAndIntangibleAssets, - LongTermInvestments: *shadow.LongTermInvestments, - TaxAssets: *shadow.TaxAssets, + TotalCurrentAssets: totalCurrentAssets, + PropertyPlantEquipmentNet: propertyPlantEquipmentNet, + Goodwill: goodwill, + IntangibleAssets: intangibleAssets, + GoodwillAndIntangibleAssets: goodwillAndIntangibleAssets, + LongTermInvestments: longTermInvestments, + TaxAssets: taxAssets, OtherNonCurrentAssets: *shadow.OtherNonCurrentAssets, - TotalNonCurrentAssets: *shadow.TotalNonCurrentAssets, + TotalNonCurrentAssets: totalNonCurrentAssets, OtherAssets: *shadow.OtherAssets, - TotalAssets: *shadow.TotalAssets, + TotalAssets: totalAssets, TotalPayables: *shadow.TotalPayables, - AccountPayables: *shadow.AccountPayables, - OtherPayables: *shadow.OtherPayables, - AccruedExpenses: *shadow.AccruedExpenses, - ShortTermDebt: *shadow.ShortTermDebt, - CapitalLeaseObligationsCurrent: *shadow.CapitalLeaseObligationsCurrent, - TaxPayables: *shadow.TaxPayables, - DeferredRevenue: *shadow.DeferredRevenue, + AccountPayables: accountPayables, + OtherPayables: otherPayables, + AccruedExpenses: accruedExpenses, + ShortTermDebt: shortTermDebt, + CapitalLeaseObligationsCurrent: capitalLeaseObligationsCurrent, + TaxPayables: taxPayables, + DeferredRevenue: deferredRevenue, OtherCurrentLiabilities: *shadow.OtherCurrentLiabilities, - TotalCurrentLiabilities: *shadow.TotalCurrentLiabilities, - LongTermDebt: *shadow.LongTermDebt, - CapitalLeaseObligationsNonCurrent: *shadow.CapitalLeaseObligationsNonCurrent, - DeferredRevenueNonCurrent: *shadow.DeferredRevenueNonCurrent, - DeferredTaxLiabilitiesNonCurrent: *shadow.DeferredTaxLiabilitiesNonCurrent, + TotalCurrentLiabilities: totalCurrentLiabilities, + LongTermDebt: longTermDebt, + CapitalLeaseObligationsNonCurrent: capitalLeaseObligationsNonCurrent, + DeferredRevenueNonCurrent: deferredRevenueNonCurrent, + DeferredTaxLiabilitiesNonCurrent: deferredTaxLiabilitiesNonCurrent, OtherNonCurrentLiabilities: *shadow.OtherNonCurrentLiabilities, - TotalNonCurrentLiabilities: *shadow.TotalNonCurrentLiabilities, + TotalNonCurrentLiabilities: totalNonCurrentLiabilities, OtherLiabilities: *shadow.OtherLiabilities, CapitalLeaseObligations: *shadow.CapitalLeaseObligations, - TotalLiabilities: *shadow.TotalLiabilities, - TreasuryStock: *shadow.TreasuryStock, + TotalLiabilities: totalLiabilities, + TreasuryStock: treasuryStock, PreferredStock: *shadow.PreferredStock, - CommonStock: *shadow.CommonStock, - RetainedEarnings: *shadow.RetainedEarnings, - AdditionalPaidInCapital: *shadow.AdditionalPaidInCapital, - AccumulatedOtherComprehensiveIncomeLoss: *shadow.AccumulatedOtherComprehensiveIncomeLoss, + CommonStock: commonStock, + RetainedEarnings: retainedEarnings, + AdditionalPaidInCapital: additionalPaidInCapital, + AccumulatedOtherComprehensiveIncomeLoss: accumulatedOtherComprehensiveIncomeLoss, OtherTotalStockholdersEquity: *shadow.OtherTotalStockholdersEquity, - TotalStockholdersEquity: *shadow.TotalStockholdersEquity, - TotalEquity: *shadow.TotalEquity, + TotalStockholdersEquity: totalStockholdersEquity, + TotalEquity: totalEquity, MinorityInterest: *shadow.MinorityInterest, - TotalLiabilitiesAndTotalEquity: *shadow.TotalLiabilitiesAndTotalEquity, + TotalLiabilitiesAndTotalEquity: totalLiabilitiesAndTotalEquity, TotalInvestments: *shadow.TotalInvestments, TotalDebt: *shadow.TotalDebt, NetDebt: *shadow.NetDebt, @@ -738,96 +1042,96 @@ type CashFlowStatement struct { Period string `json:"period"` NetIncome float64 `json:"netIncome"` DepreciationAndAmortization float64 `json:"depreciationAndAmortization"` - DeferredIncomeTax float64 `json:"deferredIncomeTax"` - StockBasedCompensation float64 `json:"stockBasedCompensation"` + DeferredIncomeTax *float64 `json:"deferredIncomeTax"` + StockBasedCompensation *float64 `json:"stockBasedCompensation"` ChangeInWorkingCapital float64 `json:"changeInWorkingCapital"` - AccountsReceivables float64 `json:"accountsReceivables"` - Inventory float64 `json:"inventory"` - AccountsPayables float64 `json:"accountsPayables"` + AccountsReceivables *float64 `json:"accountsReceivables"` + Inventory *float64 `json:"inventory"` + AccountsPayables *float64 `json:"accountsPayables"` OtherWorkingCapital float64 `json:"otherWorkingCapital"` OtherNonCashItems float64 `json:"otherNonCashItems"` NetCashProvidedByOperatingActivities float64 `json:"netCashProvidedByOperatingActivities"` InvestmentsInPropertyPlantAndEquipment float64 `json:"investmentsInPropertyPlantAndEquipment"` AcquisitionsNet float64 `json:"acquisitionsNet"` - PurchasesOfInvestments float64 `json:"purchasesOfInvestments"` - SalesMaturitiesOfInvestments float64 `json:"salesMaturitiesOfInvestments"` + PurchasesOfInvestments *float64 `json:"purchasesOfInvestments"` + SalesMaturitiesOfInvestments *float64 `json:"salesMaturitiesOfInvestments"` OtherInvestingActivities float64 `json:"otherInvestingActivities"` NetCashProvidedByInvestingActivities float64 `json:"netCashProvidedByInvestingActivities"` NetDebtIssuance float64 `json:"netDebtIssuance"` - LongTermNetDebtIssuance float64 `json:"longTermNetDebtIssuance"` + LongTermNetDebtIssuance *float64 `json:"longTermNetDebtIssuance"` ShortTermNetDebtIssuance float64 `json:"shortTermNetDebtIssuance"` - NetStockIssuance float64 `json:"netStockIssuance"` - NetCommonStockIssuance float64 `json:"netCommonStockIssuance"` + NetStockIssuance *float64 `json:"netStockIssuance"` + NetCommonStockIssuance *float64 `json:"netCommonStockIssuance"` CommonStockIssuance float64 `json:"commonStockIssuance"` - CommonStockRepurchased float64 `json:"commonStockRepurchased"` - NetPreferredStockIssuance float64 `json:"netPreferredStockIssuance"` - NetDividendsPaid float64 `json:"netDividendsPaid"` - CommonDividendsPaid float64 `json:"commonDividendsPaid"` - PreferredDividendsPaid float64 `json:"preferredDividendsPaid"` + CommonStockRepurchased *float64 `json:"commonStockRepurchased"` + NetPreferredStockIssuance *float64 `json:"netPreferredStockIssuance"` + NetDividendsPaid *float64 `json:"netDividendsPaid"` + CommonDividendsPaid *float64 `json:"commonDividendsPaid"` + PreferredDividendsPaid *float64 `json:"preferredDividendsPaid"` OtherFinancingActivities float64 `json:"otherFinancingActivities"` - NetCashProvidedByFinancingActivities float64 `json:"netCashProvidedByFinancingActivities"` + NetCashProvidedByFinancingActivities *float64 `json:"netCashProvidedByFinancingActivities"` EffectOfForexChangesOnCash float64 `json:"effectOfForexChangesOnCash"` NetChangeInCash float64 `json:"netChangeInCash"` CashAtEndOfPeriod float64 `json:"cashAtEndOfPeriod"` - CashAtBeginningOfPeriod float64 `json:"cashAtBeginningOfPeriod"` + CashAtBeginningOfPeriod *float64 `json:"cashAtBeginningOfPeriod"` OperatingCashFlow float64 `json:"operatingCashFlow"` CapitalExpenditure float64 `json:"capitalExpenditure"` FreeCashFlow float64 `json:"freeCashFlow"` - IncomeTaxesPaid float64 `json:"incomeTaxesPaid"` - InterestPaid float64 `json:"interestPaid"` + IncomeTaxesPaid *float64 `json:"incomeTaxesPaid"` + InterestPaid *float64 `json:"interestPaid"` } // cashFlowStatementShadow mirrors CashFlowStatement with a pointer or raw // value for every required member so a missing or null member is observable // after decoding. type cashFlowStatementShadow struct { - Date *Date `json:"date"` - Symbol *string `json:"symbol"` - ReportedCurrency *string `json:"reportedCurrency"` - CIK *string `json:"cik"` - FilingDate *Date `json:"filingDate"` - AcceptedDate *DateTime `json:"acceptedDate"` - FiscalYear *string `json:"fiscalYear"` - Period *string `json:"period"` - NetIncome *float64 `json:"netIncome"` - DepreciationAndAmortization *float64 `json:"depreciationAndAmortization"` - DeferredIncomeTax *float64 `json:"deferredIncomeTax"` - StockBasedCompensation *float64 `json:"stockBasedCompensation"` - ChangeInWorkingCapital *float64 `json:"changeInWorkingCapital"` - AccountsReceivables *float64 `json:"accountsReceivables"` - Inventory *float64 `json:"inventory"` - AccountsPayables *float64 `json:"accountsPayables"` - OtherWorkingCapital *float64 `json:"otherWorkingCapital"` - OtherNonCashItems *float64 `json:"otherNonCashItems"` - NetCashProvidedByOperatingActivities *float64 `json:"netCashProvidedByOperatingActivities"` - InvestmentsInPropertyPlantAndEquipment *float64 `json:"investmentsInPropertyPlantAndEquipment"` - AcquisitionsNet *float64 `json:"acquisitionsNet"` - PurchasesOfInvestments *float64 `json:"purchasesOfInvestments"` - SalesMaturitiesOfInvestments *float64 `json:"salesMaturitiesOfInvestments"` - OtherInvestingActivities *float64 `json:"otherInvestingActivities"` - NetCashProvidedByInvestingActivities *float64 `json:"netCashProvidedByInvestingActivities"` - NetDebtIssuance *float64 `json:"netDebtIssuance"` - LongTermNetDebtIssuance *float64 `json:"longTermNetDebtIssuance"` - ShortTermNetDebtIssuance *float64 `json:"shortTermNetDebtIssuance"` - NetStockIssuance *float64 `json:"netStockIssuance"` - NetCommonStockIssuance *float64 `json:"netCommonStockIssuance"` - CommonStockIssuance *float64 `json:"commonStockIssuance"` - CommonStockRepurchased *float64 `json:"commonStockRepurchased"` - NetPreferredStockIssuance *float64 `json:"netPreferredStockIssuance"` - NetDividendsPaid *float64 `json:"netDividendsPaid"` - CommonDividendsPaid *float64 `json:"commonDividendsPaid"` - PreferredDividendsPaid *float64 `json:"preferredDividendsPaid"` - OtherFinancingActivities *float64 `json:"otherFinancingActivities"` - NetCashProvidedByFinancingActivities *float64 `json:"netCashProvidedByFinancingActivities"` - EffectOfForexChangesOnCash *float64 `json:"effectOfForexChangesOnCash"` - NetChangeInCash *float64 `json:"netChangeInCash"` - CashAtEndOfPeriod *float64 `json:"cashAtEndOfPeriod"` - CashAtBeginningOfPeriod *float64 `json:"cashAtBeginningOfPeriod"` - OperatingCashFlow *float64 `json:"operatingCashFlow"` - CapitalExpenditure *float64 `json:"capitalExpenditure"` - FreeCashFlow *float64 `json:"freeCashFlow"` - IncomeTaxesPaid *float64 `json:"incomeTaxesPaid"` - InterestPaid *float64 `json:"interestPaid"` + Date *Date `json:"date"` + Symbol *string `json:"symbol"` + ReportedCurrency *string `json:"reportedCurrency"` + CIK *string `json:"cik"` + FilingDate *Date `json:"filingDate"` + AcceptedDate *DateTime `json:"acceptedDate"` + FiscalYear *string `json:"fiscalYear"` + Period *string `json:"period"` + NetIncome *float64 `json:"netIncome"` + DepreciationAndAmortization *float64 `json:"depreciationAndAmortization"` + DeferredIncomeTax jsontext.Value `json:"deferredIncomeTax"` + StockBasedCompensation jsontext.Value `json:"stockBasedCompensation"` + ChangeInWorkingCapital *float64 `json:"changeInWorkingCapital"` + AccountsReceivables jsontext.Value `json:"accountsReceivables"` + Inventory jsontext.Value `json:"inventory"` + AccountsPayables jsontext.Value `json:"accountsPayables"` + OtherWorkingCapital *float64 `json:"otherWorkingCapital"` + OtherNonCashItems *float64 `json:"otherNonCashItems"` + NetCashProvidedByOperatingActivities *float64 `json:"netCashProvidedByOperatingActivities"` + InvestmentsInPropertyPlantAndEquipment *float64 `json:"investmentsInPropertyPlantAndEquipment"` + AcquisitionsNet *float64 `json:"acquisitionsNet"` + PurchasesOfInvestments jsontext.Value `json:"purchasesOfInvestments"` + SalesMaturitiesOfInvestments jsontext.Value `json:"salesMaturitiesOfInvestments"` + OtherInvestingActivities *float64 `json:"otherInvestingActivities"` + NetCashProvidedByInvestingActivities *float64 `json:"netCashProvidedByInvestingActivities"` + NetDebtIssuance *float64 `json:"netDebtIssuance"` + LongTermNetDebtIssuance jsontext.Value `json:"longTermNetDebtIssuance"` + ShortTermNetDebtIssuance *float64 `json:"shortTermNetDebtIssuance"` + NetStockIssuance jsontext.Value `json:"netStockIssuance"` + NetCommonStockIssuance jsontext.Value `json:"netCommonStockIssuance"` + CommonStockIssuance *float64 `json:"commonStockIssuance"` + CommonStockRepurchased jsontext.Value `json:"commonStockRepurchased"` + NetPreferredStockIssuance jsontext.Value `json:"netPreferredStockIssuance"` + NetDividendsPaid jsontext.Value `json:"netDividendsPaid"` + CommonDividendsPaid jsontext.Value `json:"commonDividendsPaid"` + PreferredDividendsPaid jsontext.Value `json:"preferredDividendsPaid"` + OtherFinancingActivities *float64 `json:"otherFinancingActivities"` + NetCashProvidedByFinancingActivities jsontext.Value `json:"netCashProvidedByFinancingActivities"` + EffectOfForexChangesOnCash *float64 `json:"effectOfForexChangesOnCash"` + NetChangeInCash *float64 `json:"netChangeInCash"` + CashAtEndOfPeriod *float64 `json:"cashAtEndOfPeriod"` + CashAtBeginningOfPeriod jsontext.Value `json:"cashAtBeginningOfPeriod"` + OperatingCashFlow *float64 `json:"operatingCashFlow"` + CapitalExpenditure *float64 `json:"capitalExpenditure"` + FreeCashFlow *float64 `json:"freeCashFlow"` + IncomeTaxesPaid jsontext.Value `json:"incomeTaxesPaid"` + InterestPaid jsontext.Value `json:"interestPaid"` } // UnmarshalJSONFrom decodes one JSON object and rejects it with a Decode @@ -859,17 +1163,17 @@ func (m *CashFlowStatement) UnmarshalJSONFrom(dec *jsontext.Decoder) error { return missingMemberError("CashFlowStatement", "netIncome") case shadow.DepreciationAndAmortization == nil: return missingMemberError("CashFlowStatement", "depreciationAndAmortization") - case shadow.DeferredIncomeTax == nil: + case len(shadow.DeferredIncomeTax) == 0: return missingMemberError("CashFlowStatement", "deferredIncomeTax") - case shadow.StockBasedCompensation == nil: + case len(shadow.StockBasedCompensation) == 0: return missingMemberError("CashFlowStatement", "stockBasedCompensation") case shadow.ChangeInWorkingCapital == nil: return missingMemberError("CashFlowStatement", "changeInWorkingCapital") - case shadow.AccountsReceivables == nil: + case len(shadow.AccountsReceivables) == 0: return missingMemberError("CashFlowStatement", "accountsReceivables") - case shadow.Inventory == nil: + case len(shadow.Inventory) == 0: return missingMemberError("CashFlowStatement", "inventory") - case shadow.AccountsPayables == nil: + case len(shadow.AccountsPayables) == 0: return missingMemberError("CashFlowStatement", "accountsPayables") case shadow.OtherWorkingCapital == nil: return missingMemberError("CashFlowStatement", "otherWorkingCapital") @@ -881,9 +1185,9 @@ func (m *CashFlowStatement) UnmarshalJSONFrom(dec *jsontext.Decoder) error { return missingMemberError("CashFlowStatement", "investmentsInPropertyPlantAndEquipment") case shadow.AcquisitionsNet == nil: return missingMemberError("CashFlowStatement", "acquisitionsNet") - case shadow.PurchasesOfInvestments == nil: + case len(shadow.PurchasesOfInvestments) == 0: return missingMemberError("CashFlowStatement", "purchasesOfInvestments") - case shadow.SalesMaturitiesOfInvestments == nil: + case len(shadow.SalesMaturitiesOfInvestments) == 0: return missingMemberError("CashFlowStatement", "salesMaturitiesOfInvestments") case shadow.OtherInvestingActivities == nil: return missingMemberError("CashFlowStatement", "otherInvestingActivities") @@ -891,29 +1195,29 @@ func (m *CashFlowStatement) UnmarshalJSONFrom(dec *jsontext.Decoder) error { return missingMemberError("CashFlowStatement", "netCashProvidedByInvestingActivities") case shadow.NetDebtIssuance == nil: return missingMemberError("CashFlowStatement", "netDebtIssuance") - case shadow.LongTermNetDebtIssuance == nil: + case len(shadow.LongTermNetDebtIssuance) == 0: return missingMemberError("CashFlowStatement", "longTermNetDebtIssuance") case shadow.ShortTermNetDebtIssuance == nil: return missingMemberError("CashFlowStatement", "shortTermNetDebtIssuance") - case shadow.NetStockIssuance == nil: + case len(shadow.NetStockIssuance) == 0: return missingMemberError("CashFlowStatement", "netStockIssuance") - case shadow.NetCommonStockIssuance == nil: + case len(shadow.NetCommonStockIssuance) == 0: return missingMemberError("CashFlowStatement", "netCommonStockIssuance") case shadow.CommonStockIssuance == nil: return missingMemberError("CashFlowStatement", "commonStockIssuance") - case shadow.CommonStockRepurchased == nil: + case len(shadow.CommonStockRepurchased) == 0: return missingMemberError("CashFlowStatement", "commonStockRepurchased") - case shadow.NetPreferredStockIssuance == nil: + case len(shadow.NetPreferredStockIssuance) == 0: return missingMemberError("CashFlowStatement", "netPreferredStockIssuance") - case shadow.NetDividendsPaid == nil: + case len(shadow.NetDividendsPaid) == 0: return missingMemberError("CashFlowStatement", "netDividendsPaid") - case shadow.CommonDividendsPaid == nil: + case len(shadow.CommonDividendsPaid) == 0: return missingMemberError("CashFlowStatement", "commonDividendsPaid") - case shadow.PreferredDividendsPaid == nil: + case len(shadow.PreferredDividendsPaid) == 0: return missingMemberError("CashFlowStatement", "preferredDividendsPaid") case shadow.OtherFinancingActivities == nil: return missingMemberError("CashFlowStatement", "otherFinancingActivities") - case shadow.NetCashProvidedByFinancingActivities == nil: + case len(shadow.NetCashProvidedByFinancingActivities) == 0: return missingMemberError("CashFlowStatement", "netCashProvidedByFinancingActivities") case shadow.EffectOfForexChangesOnCash == nil: return missingMemberError("CashFlowStatement", "effectOfForexChangesOnCash") @@ -921,7 +1225,7 @@ func (m *CashFlowStatement) UnmarshalJSONFrom(dec *jsontext.Decoder) error { return missingMemberError("CashFlowStatement", "netChangeInCash") case shadow.CashAtEndOfPeriod == nil: return missingMemberError("CashFlowStatement", "cashAtEndOfPeriod") - case shadow.CashAtBeginningOfPeriod == nil: + case len(shadow.CashAtBeginningOfPeriod) == 0: return missingMemberError("CashFlowStatement", "cashAtBeginningOfPeriod") case shadow.OperatingCashFlow == nil: return missingMemberError("CashFlowStatement", "operatingCashFlow") @@ -929,11 +1233,163 @@ func (m *CashFlowStatement) UnmarshalJSONFrom(dec *jsontext.Decoder) error { return missingMemberError("CashFlowStatement", "capitalExpenditure") case shadow.FreeCashFlow == nil: return missingMemberError("CashFlowStatement", "freeCashFlow") - case shadow.IncomeTaxesPaid == nil: + case len(shadow.IncomeTaxesPaid) == 0: return missingMemberError("CashFlowStatement", "incomeTaxesPaid") - case shadow.InterestPaid == nil: + case len(shadow.InterestPaid) == 0: return missingMemberError("CashFlowStatement", "interestPaid") } + var deferredIncomeTax *float64 + if shadow.DeferredIncomeTax.Kind() != 'n' { + var value float64 + if err := json.Unmarshal(shadow.DeferredIncomeTax, &value); err != nil { + return err + } + deferredIncomeTax = &value + } + var stockBasedCompensation *float64 + if shadow.StockBasedCompensation.Kind() != 'n' { + var value float64 + if err := json.Unmarshal(shadow.StockBasedCompensation, &value); err != nil { + return err + } + stockBasedCompensation = &value + } + var accountsReceivables *float64 + if shadow.AccountsReceivables.Kind() != 'n' { + var value float64 + if err := json.Unmarshal(shadow.AccountsReceivables, &value); err != nil { + return err + } + accountsReceivables = &value + } + var inventory *float64 + if shadow.Inventory.Kind() != 'n' { + var value float64 + if err := json.Unmarshal(shadow.Inventory, &value); err != nil { + return err + } + inventory = &value + } + var accountsPayables *float64 + if shadow.AccountsPayables.Kind() != 'n' { + var value float64 + if err := json.Unmarshal(shadow.AccountsPayables, &value); err != nil { + return err + } + accountsPayables = &value + } + var purchasesOfInvestments *float64 + if shadow.PurchasesOfInvestments.Kind() != 'n' { + var value float64 + if err := json.Unmarshal(shadow.PurchasesOfInvestments, &value); err != nil { + return err + } + purchasesOfInvestments = &value + } + var salesMaturitiesOfInvestments *float64 + if shadow.SalesMaturitiesOfInvestments.Kind() != 'n' { + var value float64 + if err := json.Unmarshal(shadow.SalesMaturitiesOfInvestments, &value); err != nil { + return err + } + salesMaturitiesOfInvestments = &value + } + var longTermNetDebtIssuance *float64 + if shadow.LongTermNetDebtIssuance.Kind() != 'n' { + var value float64 + if err := json.Unmarshal(shadow.LongTermNetDebtIssuance, &value); err != nil { + return err + } + longTermNetDebtIssuance = &value + } + var netStockIssuance *float64 + if shadow.NetStockIssuance.Kind() != 'n' { + var value float64 + if err := json.Unmarshal(shadow.NetStockIssuance, &value); err != nil { + return err + } + netStockIssuance = &value + } + var netCommonStockIssuance *float64 + if shadow.NetCommonStockIssuance.Kind() != 'n' { + var value float64 + if err := json.Unmarshal(shadow.NetCommonStockIssuance, &value); err != nil { + return err + } + netCommonStockIssuance = &value + } + var commonStockRepurchased *float64 + if shadow.CommonStockRepurchased.Kind() != 'n' { + var value float64 + if err := json.Unmarshal(shadow.CommonStockRepurchased, &value); err != nil { + return err + } + commonStockRepurchased = &value + } + var netPreferredStockIssuance *float64 + if shadow.NetPreferredStockIssuance.Kind() != 'n' { + var value float64 + if err := json.Unmarshal(shadow.NetPreferredStockIssuance, &value); err != nil { + return err + } + netPreferredStockIssuance = &value + } + var netDividendsPaid *float64 + if shadow.NetDividendsPaid.Kind() != 'n' { + var value float64 + if err := json.Unmarshal(shadow.NetDividendsPaid, &value); err != nil { + return err + } + netDividendsPaid = &value + } + var commonDividendsPaid *float64 + if shadow.CommonDividendsPaid.Kind() != 'n' { + var value float64 + if err := json.Unmarshal(shadow.CommonDividendsPaid, &value); err != nil { + return err + } + commonDividendsPaid = &value + } + var preferredDividendsPaid *float64 + if shadow.PreferredDividendsPaid.Kind() != 'n' { + var value float64 + if err := json.Unmarshal(shadow.PreferredDividendsPaid, &value); err != nil { + return err + } + preferredDividendsPaid = &value + } + var netCashProvidedByFinancingActivities *float64 + if shadow.NetCashProvidedByFinancingActivities.Kind() != 'n' { + var value float64 + if err := json.Unmarshal(shadow.NetCashProvidedByFinancingActivities, &value); err != nil { + return err + } + netCashProvidedByFinancingActivities = &value + } + var cashAtBeginningOfPeriod *float64 + if shadow.CashAtBeginningOfPeriod.Kind() != 'n' { + var value float64 + if err := json.Unmarshal(shadow.CashAtBeginningOfPeriod, &value); err != nil { + return err + } + cashAtBeginningOfPeriod = &value + } + var incomeTaxesPaid *float64 + if shadow.IncomeTaxesPaid.Kind() != 'n' { + var value float64 + if err := json.Unmarshal(shadow.IncomeTaxesPaid, &value); err != nil { + return err + } + incomeTaxesPaid = &value + } + var interestPaid *float64 + if shadow.InterestPaid.Kind() != 'n' { + var value float64 + if err := json.Unmarshal(shadow.InterestPaid, &value); err != nil { + return err + } + interestPaid = &value + } *m = CashFlowStatement{ Date: *shadow.Date, Symbol: *shadow.Symbol, @@ -945,43 +1401,43 @@ func (m *CashFlowStatement) UnmarshalJSONFrom(dec *jsontext.Decoder) error { Period: *shadow.Period, NetIncome: *shadow.NetIncome, DepreciationAndAmortization: *shadow.DepreciationAndAmortization, - DeferredIncomeTax: *shadow.DeferredIncomeTax, - StockBasedCompensation: *shadow.StockBasedCompensation, + DeferredIncomeTax: deferredIncomeTax, + StockBasedCompensation: stockBasedCompensation, ChangeInWorkingCapital: *shadow.ChangeInWorkingCapital, - AccountsReceivables: *shadow.AccountsReceivables, - Inventory: *shadow.Inventory, - AccountsPayables: *shadow.AccountsPayables, + AccountsReceivables: accountsReceivables, + Inventory: inventory, + AccountsPayables: accountsPayables, OtherWorkingCapital: *shadow.OtherWorkingCapital, OtherNonCashItems: *shadow.OtherNonCashItems, NetCashProvidedByOperatingActivities: *shadow.NetCashProvidedByOperatingActivities, InvestmentsInPropertyPlantAndEquipment: *shadow.InvestmentsInPropertyPlantAndEquipment, AcquisitionsNet: *shadow.AcquisitionsNet, - PurchasesOfInvestments: *shadow.PurchasesOfInvestments, - SalesMaturitiesOfInvestments: *shadow.SalesMaturitiesOfInvestments, + PurchasesOfInvestments: purchasesOfInvestments, + SalesMaturitiesOfInvestments: salesMaturitiesOfInvestments, OtherInvestingActivities: *shadow.OtherInvestingActivities, NetCashProvidedByInvestingActivities: *shadow.NetCashProvidedByInvestingActivities, NetDebtIssuance: *shadow.NetDebtIssuance, - LongTermNetDebtIssuance: *shadow.LongTermNetDebtIssuance, + LongTermNetDebtIssuance: longTermNetDebtIssuance, ShortTermNetDebtIssuance: *shadow.ShortTermNetDebtIssuance, - NetStockIssuance: *shadow.NetStockIssuance, - NetCommonStockIssuance: *shadow.NetCommonStockIssuance, + NetStockIssuance: netStockIssuance, + NetCommonStockIssuance: netCommonStockIssuance, CommonStockIssuance: *shadow.CommonStockIssuance, - CommonStockRepurchased: *shadow.CommonStockRepurchased, - NetPreferredStockIssuance: *shadow.NetPreferredStockIssuance, - NetDividendsPaid: *shadow.NetDividendsPaid, - CommonDividendsPaid: *shadow.CommonDividendsPaid, - PreferredDividendsPaid: *shadow.PreferredDividendsPaid, + CommonStockRepurchased: commonStockRepurchased, + NetPreferredStockIssuance: netPreferredStockIssuance, + NetDividendsPaid: netDividendsPaid, + CommonDividendsPaid: commonDividendsPaid, + PreferredDividendsPaid: preferredDividendsPaid, OtherFinancingActivities: *shadow.OtherFinancingActivities, - NetCashProvidedByFinancingActivities: *shadow.NetCashProvidedByFinancingActivities, + NetCashProvidedByFinancingActivities: netCashProvidedByFinancingActivities, EffectOfForexChangesOnCash: *shadow.EffectOfForexChangesOnCash, NetChangeInCash: *shadow.NetChangeInCash, CashAtEndOfPeriod: *shadow.CashAtEndOfPeriod, - CashAtBeginningOfPeriod: *shadow.CashAtBeginningOfPeriod, + CashAtBeginningOfPeriod: cashAtBeginningOfPeriod, OperatingCashFlow: *shadow.OperatingCashFlow, CapitalExpenditure: *shadow.CapitalExpenditure, FreeCashFlow: *shadow.FreeCashFlow, - IncomeTaxesPaid: *shadow.IncomeTaxesPaid, - InterestPaid: *shadow.InterestPaid, + IncomeTaxesPaid: incomeTaxesPaid, + InterestPaid: interestPaid, } return nil } diff --git a/sdk/go/statements_parity_test.go b/sdk/go/statements_parity_test.go index b03c8f5a..d1d958e6 100644 --- a/sdk/go/statements_parity_test.go +++ b/sdk/go/statements_parity_test.go @@ -80,8 +80,8 @@ func TestDocumentedBalanceSheetAndCashFlowFixturesDecodeExactAmounts(t *testing. t.Parallel() balance := assertFixtureParity[BalanceSheetStatement](t, "balance_sheet_statement.json") if len(balance) != 1 || balance[0].CIK != "0000320193" || balance[0].FiscalYear != "2025" || - balance[0].Period != "FY" || balance[0].TotalAssets != 359_241_000_000 || - balance[0].RetainedEarnings != -14_264_000_000 || len(memberSet(t, balance[0])) != 61 { + balance[0].Period != "FY" || !amountIs(balance[0].TotalAssets, 359_241_000_000) || + !amountIs(balance[0].RetainedEarnings, -14_264_000_000) || len(memberSet(t, balance[0])) != 61 { t.Fatalf("balance_sheet_statement = %+v", balance) } ttm := assertFixtureParity[BalanceSheetStatementTTM](t, "balance_sheet_statement_ttm.json") @@ -92,12 +92,12 @@ func TestDocumentedBalanceSheetAndCashFlowFixturesDecodeExactAmounts(t *testing. } cash := assertFixtureParity[CashFlowStatement](t, "cash_flow_statement.json") if len(cash) != 1 || cash[0].NetIncome != 112_010_000_000 || cash[0].FreeCashFlow != 98_767_000_000 || - cash[0].NetCashProvidedByFinancingActivities != -120_686_000_000 || len(memberSet(t, cash[0])) != 47 { + !amountIs(cash[0].NetCashProvidedByFinancingActivities, -120_686_000_000) || len(memberSet(t, cash[0])) != 47 { t.Fatalf("cash_flow_statement = %+v", cash) } cashTTM := assertFixtureParity[CashFlowStatement](t, "cash_flow_statement_ttm.json") if len(cashTTM) != 1 || cashTTM[0].Period != "Q2" || cashTTM[0].FreeCashFlow != 129_174_000_000 || - cashTTM[0].NetCashProvidedByFinancingActivities != -114_244_000_000 { + !amountIs(cashTTM[0].NetCashProvidedByFinancingActivities, -114_244_000_000) { t.Fatalf("cash_flow_statement_ttm = %+v", cashTTM) } } @@ -170,13 +170,13 @@ func TestStatementAmountsPreserveLargeIntegralValuesAndShareQuantitiesKeepFracti balance := statementsRoundTripExtreme[BalanceSheetStatement](t, "balance_sheet_statement.json", "totalAssets", large) balanceTTM := statementsRoundTripExtreme[BalanceSheetStatementTTM](t, "balance_sheet_statement_ttm.json", "retainedEarnings", negative) - if balance.TotalAssets != 9e18 || balanceTTM.RetainedEarnings != -9e18 { + if !amountIs(balance.TotalAssets, 9e18) || balanceTTM.RetainedEarnings != -9e18 { t.Fatalf("balance extremes = %v %v", balance.TotalAssets, balanceTTM.RetainedEarnings) } for _, fixture := range []string{"cash_flow_statement.json", "cash_flow_statement_ttm.json"} { cash := statementsRoundTripExtreme[CashFlowStatement](t, fixture, "freeCashFlow", large) financing := statementsRoundTripExtreme[CashFlowStatement](t, fixture, "netCashProvidedByFinancingActivities", negative) - if cash.FreeCashFlow != 9e18 || financing.NetCashProvidedByFinancingActivities != -9e18 { + if cash.FreeCashFlow != 9e18 || !amountIs(financing.NetCashProvidedByFinancingActivities, -9e18) { t.Fatalf("%s extremes = %v %v", fixture, cash.FreeCashFlow, financing.NetCashProvidedByFinancingActivities) } } @@ -200,3 +200,90 @@ func TestStatementAmountsPreserveLargeIntegralValuesAndShareQuantitiesKeepFracti t.Fatal("numeric fiscalYear decoded into a string on the TTM contract") } } + +// amountIs reports whether an optional statement amount is present and equal +// to want. +func amountIs(got *float64, want float64) bool { + return got != nil && *got == want +} + +// The pre-IPO stub-quarter members of statements_balance_responses.rs and +// statements_cash_flow_responses.rs: FMP sends null for them, which decodes to +// nil and re-encodes as null. +var ( + balanceStubQuarterNullMembers = []string{ + "accountPayables", "accountsReceivables", "accruedExpenses", "accumulatedOtherComprehensiveIncomeLoss", + "additionalPaidInCapital", "capitalLeaseObligationsCurrent", "capitalLeaseObligationsNonCurrent", + "cashAndCashEquivalents", "cashAndShortTermInvestments", "commonStock", "deferredRevenue", + "deferredRevenueNonCurrent", "deferredTaxLiabilitiesNonCurrent", "goodwill", "goodwillAndIntangibleAssets", + "intangibleAssets", "inventory", "longTermDebt", "longTermInvestments", "netReceivables", "otherPayables", + "prepaids", "propertyPlantEquipmentNet", "retainedEarnings", "shortTermDebt", "shortTermInvestments", + "taxAssets", "taxPayables", "totalAssets", "totalCurrentAssets", "totalCurrentLiabilities", "totalEquity", + "totalLiabilities", "totalLiabilitiesAndTotalEquity", "totalNonCurrentAssets", "totalNonCurrentLiabilities", + "totalStockholdersEquity", "treasuryStock", + } + cashFlowStubQuarterNullMembers = []string{ + "accountsPayables", "accountsReceivables", "cashAtBeginningOfPeriod", "commonDividendsPaid", + "commonStockRepurchased", "deferredIncomeTax", "incomeTaxesPaid", "interestPaid", "inventory", + "longTermNetDebtIssuance", "netCashProvidedByFinancingActivities", "netCommonStockIssuance", + "netDividendsPaid", "netPreferredStockIssuance", "netStockIssuance", "preferredDividendsPaid", + "purchasesOfInvestments", "salesMaturitiesOfInvestments", "stockBasedCompensation", + } +) + +func statementsWithNullMembers(t *testing.T, fixture string, members []string) []byte { + t.Helper() + var rows []map[string]jsontext.Value + if err := json.Unmarshal(readFixture(t, fixture), &rows); err != nil { + t.Fatalf("%s: %v", fixture, err) + } + for _, member := range members { + if _, ok := rows[0][member]; !ok { + t.Fatalf("%s: member %q is absent from the first row", fixture, member) + } + rows[0][member] = jsontext.Value("null") + } + encoded, err := json.Marshal(rows[:1]) + if err != nil { + t.Fatal(err) + } + return encoded +} + +func assertStubMembersReencodeNull(t *testing.T, row any, members []string) { + t.Helper() + encoded, err := json.Marshal(row) + if err != nil { + t.Fatal(err) + } + var got map[string]jsontext.Value + if err := json.Unmarshal(encoded, &got); err != nil { + t.Fatal(err) + } + for _, member := range members { + if string(got[member]) != "null" { + t.Fatalf("%s re-encoded as %s, want null", member, got[member]) + } + } +} + +func TestPreIPOStubRowsDecodeNullAmountsAsNil(t *testing.T) { + t.Parallel() + var balance []BalanceSheetStatement + if err := json.Unmarshal(statementsWithNullMembers(t, "balance_sheet_statement.json", balanceStubQuarterNullMembers), &balance); err != nil { + t.Fatalf("balance stub row: %v", err) + } + if balance[0].TotalAssets != nil || balance[0].OtherReceivables == 0 { + t.Fatalf("balance stub row = %+v", balance[0]) + } + assertStubMembersReencodeNull(t, balance[0], balanceStubQuarterNullMembers) + + var cash []CashFlowStatement + if err := json.Unmarshal(statementsWithNullMembers(t, "cash_flow_statement.json", cashFlowStubQuarterNullMembers), &cash); err != nil { + t.Fatalf("cash flow stub row: %v", err) + } + if cash[0].StockBasedCompensation != nil || cash[0].NetIncome == 0 { + t.Fatalf("cash flow stub row = %+v", cash[0]) + } + assertStubMembersReencodeNull(t, cash[0], cashFlowStubQuarterNullMembers) +} diff --git a/sdk/go/statements_test.go b/sdk/go/statements_test.go index 4a5121d8..09a3df06 100644 --- a/sdk/go/statements_test.go +++ b/sdk/go/statements_test.go @@ -94,7 +94,7 @@ func TestStatementsMethodsUseExactPathsAndWireOrder(t *testing.T) { incomeTTM, err := s.Income.StatementTTM(ctx, NewIncomeStatementTTMQuery(statementsTicker).WithLimit(7)) statementsCheck(t, "Income.StatementTTM", incomeTTM, err, func(r IncomeStatement) bool { return r.Period == "Q2" }) balance, err := s.Balance.Statement(ctx, NewBalanceSheetStatementQuery(statementsTicker).WithLimit(5).WithPeriod(StatementPeriodQ1)) - statementsCheck(t, "Balance.Statement", balance, err, func(r BalanceSheetStatement) bool { return r.TotalAssets == 359_241_000_000 }) + statementsCheck(t, "Balance.Statement", balance, err, func(r BalanceSheetStatement) bool { return amountIs(r.TotalAssets, 359_241_000_000) }) balanceTTM, err := s.Balance.StatementTTM(ctx, NewBalanceSheetStatementTTMQuery(statementsTicker).WithLimit(7)) statementsCheck(t, "Balance.StatementTTM", balanceTTM, err, func(r BalanceSheetStatementTTM) bool { return r.TotalAssets == 371_082_000_000 }) cash, err := s.CashFlow.Statement(ctx, NewCashFlowStatementQuery(statementsTicker).WithLimit(5).WithPeriod(StatementPeriodQ1))