/// Model Portofolio: ringkasan posisi per saham dari Odoo saat.portofolio. class Portfolio { final int id; final String sahamTicker; final int sisaLembar; final double avgCost; final double hargaSekarang; final double nilaiSekarang; final double realizedPl; final double unrealizedPl; Portfolio({ required this.id, required this.sahamTicker, required this.sisaLembar, required this.avgCost, required this.hargaSekarang, required this.nilaiSekarang, required this.realizedPl, required this.unrealizedPl, }); factory Portfolio.fromOdoo(Map m) { // saham_id adalah tuple/list [id, ticker] dalam search_read String ticker = ''; final sahamId = m['saham_id']; if (sahamId is List && sahamId.isNotEmpty) { ticker = sahamId.length > 1 ? sahamId[1].toString() : '${sahamId[0]}'; } return Portfolio( id: (m['id'] as num).toInt(), sahamTicker: ticker, sisaLembar: (m['sisa_lembar'] as num?)?.toInt() ?? 0, avgCost: (m['avg_cost'] as num?)?.toDouble() ?? 0, hargaSekarang: (m['harga_sekarang'] as num?)?.toDouble() ?? 0, nilaiSekarang: (m['nilai_sekarang'] as num?)?.toDouble() ?? 0, realizedPl: (m['realized_pl'] as num?)?.toDouble() ?? 0, unrealizedPl: (m['unrealized_pl'] as num?)?.toDouble() ?? 0, ); } }