import 'package:equatable/equatable.dart'; class FundamentalDataModel extends Equatable { final String isin; final String primaryTicker; final String ticker; final String companyName; final String? exchange; final String? tradingCurrency; final String? businessSummary; final String? sector; final String? industry; final String? country; final int? employees; final double currentPrice; final double dayChangeAbsolute; final double dayChangePercent; final double fiftyTwoWeekHigh; final double fiftyTwoWeekLow; final double marketCapitalization; final double enterpriseValue; final double? peRatioTrailing; final double? peRatioForward; final double? pegRatio; final double? pbRatio; final double? psRatio; final double? evToEbitda; final double? evToRevenue; final double? grossMargin; final double? operatingMargin; final double? netProfitMargin; final double? returnOnEquity; final double? returnOnAssets; final double? returnOnInvestedCapital; final double? debtToEquity; final double? currentRatio; final double? quickRatio; final double? interestCoverage; final double? dividendYield; final double? payoutRatio; final String? exDividendDate; final String? nextEarningsDate; final double? percentHeldByInstitutions; final double? percentHeldByInsiders; final double? shortRatio; final double? shortPercentOfFloat; final String? consensusRating; final double? priceTargetLow; final double? priceTargetHigh; final double? priceTargetMedian; final double? priceTargetMean; final List executives; final List financialStatements; final List estimates; const FundamentalDataModel({ required this.isin, required this.primaryTicker, required this.ticker, required this.companyName, this.exchange, this.tradingCurrency, this.businessSummary, this.sector, this.industry, this.country, this.employees, required this.currentPrice, required this.dayChangeAbsolute, required this.dayChangePercent, required this.fiftyTwoWeekHigh, required this.fiftyTwoWeekLow, required this.marketCapitalization, required this.enterpriseValue, this.peRatioTrailing, this.peRatioForward, this.pegRatio, this.pbRatio, this.psRatio, this.evToEbitda, this.evToRevenue, this.grossMargin, this.operatingMargin, this.netProfitMargin, this.returnOnEquity, this.returnOnAssets, this.returnOnInvestedCapital, this.debtToEquity, this.currentRatio, this.quickRatio, this.interestCoverage, this.dividendYield, this.payoutRatio, this.exDividendDate, this.nextEarningsDate, this.percentHeldByInstitutions, this.percentHeldByInsiders, this.shortRatio, this.shortPercentOfFloat, this.consensusRating, this.priceTargetLow, this.priceTargetHigh, this.priceTargetMedian, this.priceTargetMean, required this.executives, required this.financialStatements, required this.estimates, }); factory FundamentalDataModel.fromJson(Map json) { double parseDouble(dynamic val) { if (val == null) return 0.0; if (val is num) return val.toDouble(); return double.tryParse(val.toString()) ?? 0.0; } double? parseNullableDouble(dynamic val) { if (val == null) return null; if (val is num) return val.toDouble(); return double.tryParse(val.toString()); } return FundamentalDataModel( isin: json['isin']?.toString() ?? '', primaryTicker: json['primaryTicker']?.toString() ?? '', ticker: json['ticker']?.toString() ?? '', companyName: json['companyName']?.toString() ?? '', exchange: json['exchange']?.toString(), tradingCurrency: json['tradingCurrency']?.toString(), businessSummary: json['businessSummary']?.toString(), sector: json['sector']?.toString(), industry: json['industry']?.toString(), country: json['country']?.toString(), employees: json['employees'] != null ? int.tryParse(json['employees'].toString()) : null, currentPrice: parseDouble(json['currentPrice']), dayChangeAbsolute: parseDouble(json['dayChangeAbsolute']), dayChangePercent: parseDouble(json['dayChangePercent']), fiftyTwoWeekHigh: parseDouble(json['fiftyTwoWeekHigh']), fiftyTwoWeekLow: parseDouble(json['fiftyTwoWeekLow']), marketCapitalization: parseDouble(json['marketCapitalization'] ?? json['marketCap']), enterpriseValue: parseDouble(json['enterpriseValue']), peRatioTrailing: parseNullableDouble(json['peRatioTrailing'] ?? json['peRatio']), peRatioForward: parseNullableDouble(json['peRatioForward']), pegRatio: parseNullableDouble(json['pegRatio']), pbRatio: parseNullableDouble(json['pbRatio']), psRatio: parseNullableDouble(json['psRatio']), evToEbitda: parseNullableDouble(json['evToEbitda']), evToRevenue: parseNullableDouble(json['evToRevenue']), grossMargin: parseNullableDouble(json['grossMargin']), operatingMargin: parseNullableDouble(json['operatingMargin']), netProfitMargin: parseNullableDouble(json['netProfitMargin']), returnOnEquity: parseNullableDouble(json['returnOnEquity']), returnOnAssets: parseNullableDouble(json['returnOnAssets']), returnOnInvestedCapital: parseNullableDouble(json['returnOnInvestedCapital']), debtToEquity: parseNullableDouble(json['debtToEquity']), currentRatio: parseNullableDouble(json['currentRatio']), quickRatio: parseNullableDouble(json['quickRatio']), interestCoverage: parseNullableDouble(json['interestCoverage']), dividendYield: parseNullableDouble(json['dividendYield']), payoutRatio: parseNullableDouble(json['payoutRatio']), exDividendDate: json['exDividendDate']?.toString(), nextEarningsDate: json['nextEarningsDate']?.toString(), percentHeldByInstitutions: parseNullableDouble(json['percentHeldByInstitutions']), percentHeldByInsiders: parseNullableDouble(json['percentHeldByInsiders']), shortRatio: parseNullableDouble(json['shortRatio']), shortPercentOfFloat: parseNullableDouble(json['shortPercentOfFloat']), consensusRating: json['consensusRating']?.toString(), priceTargetLow: parseNullableDouble(json['priceTargetLow']), priceTargetHigh: parseNullableDouble(json['priceTargetHigh']), priceTargetMedian: parseNullableDouble(json['priceTargetMedian']), priceTargetMean: parseNullableDouble(json['priceTargetMean']), executives: (json['executives'] as List?) ?.map((e) => CompanyExecutiveModel.fromJson(e)) .toList() ?? [], financialStatements: (json['financialStatements'] as List?) ?.map((e) => FinancialStatementModel.fromJson(e)) .toList() ?? [], estimates: (json['estimates'] as List?) ?.map((e) => ForwardEstimateModel.fromJson(e)) .toList() ?? [], ); } Map toJson() { return { 'isin': isin, 'primaryTicker': primaryTicker, 'ticker': ticker, 'companyName': companyName, 'exchange': exchange, 'tradingCurrency': tradingCurrency, 'businessSummary': businessSummary, 'sector': sector, 'industry': industry, 'country': country, 'employees': employees, 'currentPrice': currentPrice, 'dayChangeAbsolute': dayChangeAbsolute, 'dayChangePercent': dayChangePercent, 'fiftyTwoWeekHigh': fiftyTwoWeekHigh, 'fiftyTwoWeekLow': fiftyTwoWeekLow, 'marketCapitalization': marketCapitalization, 'enterpriseValue': enterpriseValue, 'peRatioTrailing': peRatioTrailing, 'peRatioForward': peRatioForward, 'pegRatio': pegRatio, 'pbRatio': pbRatio, 'psRatio': psRatio, 'evToEbitda': evToEbitda, 'evToRevenue': evToRevenue, 'grossMargin': grossMargin, 'operatingMargin': operatingMargin, 'netProfitMargin': netProfitMargin, 'returnOnEquity': returnOnEquity, 'returnOnAssets': returnOnAssets, 'returnOnInvestedCapital': returnOnInvestedCapital, 'debtToEquity': debtToEquity, 'currentRatio': currentRatio, 'quickRatio': quickRatio, 'dividendYield': dividendYield, 'payoutRatio': payoutRatio, 'exDividendDate': exDividendDate, 'nextEarningsDate': nextEarningsDate, 'percentHeldByInstitutions': percentHeldByInstitutions, 'percentHeldByInsiders': percentHeldByInsiders, 'shortRatio': shortRatio, 'shortPercentOfFloat': shortPercentOfFloat, 'consensusRating': consensusRating, 'priceTargetLow': priceTargetLow, 'priceTargetHigh': priceTargetHigh, 'priceTargetMedian': priceTargetMedian, 'priceTargetMean': priceTargetMean, 'executives': executives.map((e) => e.toJson()).toList(), 'financialStatements': financialStatements.map((e) => e.toJson()).toList(), 'estimates': estimates.map((e) => e.toJson()).toList(), }; } @override List get props => [ isin, primaryTicker, ticker, companyName, exchange, tradingCurrency, businessSummary, sector, industry, country, employees, currentPrice, dayChangeAbsolute, dayChangePercent, fiftyTwoWeekHigh, fiftyTwoWeekLow, marketCapitalization, enterpriseValue, peRatioTrailing, peRatioForward, pegRatio, pbRatio, psRatio, evToEbitda, evToRevenue, grossMargin, operatingMargin, netProfitMargin, returnOnEquity, returnOnAssets, returnOnInvestedCapital, debtToEquity, currentRatio, quickRatio, dividendYield, payoutRatio, exDividendDate, nextEarningsDate, percentHeldByInstitutions, percentHeldByInsiders, shortRatio, shortPercentOfFloat, consensusRating, priceTargetLow, priceTargetHigh, priceTargetMedian, priceTargetMean, executives, financialStatements, estimates, ]; } class CompanyExecutiveModel extends Equatable { final String name; final String title; final int? age; final double? compensation; const CompanyExecutiveModel({ required this.name, required this.title, this.age, this.compensation, }); factory CompanyExecutiveModel.fromJson(Map json) { return CompanyExecutiveModel( name: json['name']?.toString() ?? '', title: json['title']?.toString() ?? '', age: json['age'] != null ? int.tryParse(json['age'].toString()) : null, compensation: json['compensation'] != null ? double.tryParse(json['compensation'].toString()) : null, ); } Map toJson() { return { 'name': name, 'title': title, 'age': age, 'compensation': compensation, }; } @override List get props => [name, title, age, compensation]; } class FinancialStatementModel extends Equatable { final String periodType; final String endDate; // Income Statement final double? totalRevenue; final double? costOfRevenue; final double? grossProfit; final double? operatingExpenses; final double? operatingIncome; final double? ebitda; final double? netIncome; final double? epsBasic; final double? epsDiluted; // Balance Sheet final double? cashAndCashEquivalents; final double? accountsReceivable; final double? inventory; final double? totalCurrentAssets; final double? totalNonCurrentAssets; final double? currentLiabilities; final double? longTermDebt; final double? totalLiabilities; final double? totalStockholdersEquity; // Cash Flow final double? operatingCashFlow; final double? investingCashFlow; final double? capitalExpenditures; final double? financingCashFlow; final double? freeCashFlow; const FinancialStatementModel({ required this.periodType, required this.endDate, this.totalRevenue, this.costOfRevenue, this.grossProfit, this.operatingExpenses, this.operatingIncome, this.ebitda, this.netIncome, this.epsBasic, this.epsDiluted, this.cashAndCashEquivalents, this.accountsReceivable, this.inventory, this.totalCurrentAssets, this.totalNonCurrentAssets, this.currentLiabilities, this.longTermDebt, this.totalLiabilities, this.totalStockholdersEquity, this.operatingCashFlow, this.investingCashFlow, this.capitalExpenditures, this.financingCashFlow, this.freeCashFlow, }); factory FinancialStatementModel.fromJson(Map json) { double? parseD(dynamic val) { if (val == null) return null; if (val is num) return val.toDouble(); return double.tryParse(val.toString()); } return FinancialStatementModel( periodType: json['periodType']?.toString() ?? '', endDate: json['endDate']?.toString() ?? '', totalRevenue: parseD(json['totalRevenue']), costOfRevenue: parseD(json['costOfRevenue']), grossProfit: parseD(json['grossProfit']), operatingExpenses: parseD(json['operatingExpenses']), operatingIncome: parseD(json['operatingIncome']), ebitda: parseD(json['ebitda']), netIncome: parseD(json['netIncome']), epsBasic: parseD(json['epsBasic']), epsDiluted: parseD(json['epsDiluted']), cashAndCashEquivalents: parseD(json['cashAndCashEquivalents']), accountsReceivable: parseD(json['accountsReceivable']), inventory: parseD(json['inventory']), totalCurrentAssets: parseD(json['totalCurrentAssets']), totalNonCurrentAssets: parseD(json['totalNonCurrentAssets']), currentLiabilities: parseD(json['currentLiabilities']), longTermDebt: parseD(json['longTermDebt']), totalLiabilities: parseD(json['totalLiabilities']), totalStockholdersEquity: parseD(json['totalStockholdersEquity']), operatingCashFlow: parseD(json['operatingCashFlow']), investingCashFlow: parseD(json['investingCashFlow']), capitalExpenditures: parseD(json['capitalExpenditures']), financingCashFlow: parseD(json['financingCashFlow']), freeCashFlow: parseD(json['freeCashFlow']), ); } Map toJson() { return { 'periodType': periodType, 'endDate': endDate, 'totalRevenue': totalRevenue, 'costOfRevenue': costOfRevenue, 'grossProfit': grossProfit, 'operatingExpenses': operatingExpenses, 'operatingIncome': operatingIncome, 'ebitda': ebitda, 'netIncome': netIncome, 'epsBasic': epsBasic, 'epsDiluted': epsDiluted, 'cashAndCashEquivalents': cashAndCashEquivalents, 'accountsReceivable': accountsReceivable, 'inventory': inventory, 'totalCurrentAssets': totalCurrentAssets, 'totalNonCurrentAssets': totalNonCurrentAssets, 'currentLiabilities': currentLiabilities, 'longTermDebt': longTermDebt, 'totalLiabilities': totalLiabilities, 'totalStockholdersEquity': totalStockholdersEquity, 'operatingCashFlow': operatingCashFlow, 'investingCashFlow': investingCashFlow, 'capitalExpenditures': capitalExpenditures, 'financingCashFlow': financingCashFlow, 'freeCashFlow': freeCashFlow, }; } @override List get props => [ periodType, endDate, totalRevenue, costOfRevenue, grossProfit, operatingExpenses, operatingIncome, ebitda, netIncome, epsBasic, epsDiluted, cashAndCashEquivalents, accountsReceivable, inventory, totalCurrentAssets, totalNonCurrentAssets, currentLiabilities, longTermDebt, totalLiabilities, totalStockholdersEquity, operatingCashFlow, investingCashFlow, capitalExpenditures, financingCashFlow, freeCashFlow, ]; } class ForwardEstimateModel extends Equatable { final String period; final double? expectedRevenue; final double? expectedEps; final double? expectedGrowthRate; const ForwardEstimateModel({ required this.period, this.expectedRevenue, this.expectedEps, this.expectedGrowthRate, }); factory ForwardEstimateModel.fromJson(Map json) { return ForwardEstimateModel( period: json['period']?.toString() ?? '', expectedRevenue: json['expectedRevenue'] != null ? double.tryParse(json['expectedRevenue'].toString()) : null, expectedEps: json['expectedEps'] != null ? double.tryParse(json['expectedEps'].toString()) : null, expectedGrowthRate: json['expectedGrowthRate'] != null ? double.tryParse(json['expectedGrowthRate'].toString()) : null, ); } Map toJson() { return { 'period': period, 'expectedRevenue': expectedRevenue, 'expectedEps': expectedEps, 'expectedGrowthRate': expectedGrowthRate, }; } @override List get props => [period, expectedRevenue, expectedEps, expectedGrowthRate]; }