whisper-money/app/Services
Víctor Falcón ae2a8c0118
fix(open-banking): use net_amounts for Indexa Capital invested amount calculation (#156)
## Why

### Problem

The Indexa Capital dashboard shows +€11,339.01 profit for the Index
funds account, but our app shows +€9,680.43 — a €1,658.58 discrepancy.
The invested amount (and therefore the profit) is wrong.

### Root Cause

`calculateInvestedAmount()` used `instruments_cost + cash_amount` to
determine how much was invested. However, `instruments_cost` is the
**cost basis of currently held fund shares**, not the actual money
deposited. When Indexa rebalances portfolios, they sell shares
(realizing gains) and buy new ones at a higher cost basis. This inflates
`instruments_cost` over time without any new deposits, making the
"invested" figure too high and profit too low.

## What

### Changes

- Use `net_amounts` from the Indexa Capital API response instead of
`instruments_cost + cash_amount`
- `net_amounts` is an object keyed by date (`YYYYMMDD` format), where
each value is the cumulative net investment (inflows - outflows -
tax_outflows), matching Indexa Capital's own "investment" figure
- Keep `total_amount - return` as a fallback when `net_amounts` is
unavailable
- Return `null` when neither data source is available

### Concrete numbers (Index funds account, 2026-02-24)

| | Old (wrong) | New (correct) |
|---|---|---|
| Invested | €48,081.67 | €46,423.09 |
| Profit | €9,680.43 | €11,339.01 |

## Verification

### Tests

- Updated `stores invested_amount from net_amounts data` — verifies
invested_amount is sourced from `net_amounts`, not `instruments_cost +
cash_amount`
- Updated `stores null invested_amount when net_amounts is missing` —
verifies graceful null when API lacks `net_amounts`
- Updated `falls back to total_amount minus return when net_amounts is
missing` — verifies fallback path
- All 11 balance sync tests pass, all 23 SyncBankingConnectionJob tests
pass
2026-02-25 15:45:31 +01:00
..
Banking fix(open-banking): use net_amounts for Indexa Capital invested amount calculation (#156) 2026-02-25 15:45:31 +01:00
Demo Remove encryption from browser tests and demo user (#129) 2026-02-17 11:45:27 +01:00
AccountMetricsService.php refactor: extract AccountMetricsService to deduplicate balance computation logic (#147) 2026-02-24 09:07:42 +01:00
AutomationRuleService.php feat: Apply automation rules to bank-synced transactions (#112) 2026-02-12 14:20:55 +01:00
BalanceLookup.php perf(dashboard): optimize query performance and eliminate redundant requests (#146) 2026-02-24 08:43:48 +01:00
BudgetPeriodService.php fix(budgets): handle refunds correctly in budget spending calculations (#152) 2026-02-24 21:12:36 +01:00
BudgetTransactionService.php fix(budgets): handle refunds correctly in budget spending calculations (#152) 2026-02-24 21:12:36 +01:00
CurrencyConversionService.php feat: Add multi-currency conversion for net worth charts (#138) 2026-02-20 10:45:23 +01:00
ExchangeRateService.php feat: Add multi-currency conversion for net worth charts (#138) 2026-02-20 10:45:23 +01:00
PeriodComparator.php Refactor: Optimize category management in CreateDefaultCategories and ResetUserCategories 2025-12-01 15:37:53 +01:00
ResendService.php feat: Sync new users to Resend contacts (#85) 2026-01-28 21:25:58 +01:00