whisper-money/app/Services
Víctor Falcón 7e958284e3
fix(loans): project monthly balances from actual entries instead of original params (#259)
## Summary

- **Bug**: The `loans:generate-balances` command called
`getBalanceAtDate()` which always recalculated the remaining balance
from the **original loan parameters** (`original_amount`,
`annual_interest_rate`, `loan_term_months`, `start_date`), completely
ignoring existing actual balance entries. When the real balance was
lower than the theoretical amortization schedule (e.g. user made extra
payments), the auto-generated balance would **jump up** instead of
continuing to decrease.
- **Example**: Account `019d0b33-d3c5-7110-9033-51155ac93219` had a real
balance of ~4,489,670 (March 2026), but the command generated 5,700,356
(April 2026) — a jump **up** of ~1.2M cents instead of the expected ~16K
decrease.
- **Fix**: `getBalanceAtDate()` now checks for the latest
`AccountBalance` entry on or before the target date and projects forward
from it, falling back to the theoretical formula only when no entries
exist. This matches the method's own documented behavior and aligns with
how `generateProjection()` already works.

## Testing

Added 4 new tests:
- Projects from existing balance entries instead of original loan params
- Returns existing balance when target date is in the same month
- Generates correct monthly balance when existing entries differ from
theoretical
- All 44 existing loan tests continue to pass
2026-04-04 15:57:29 +01:00
..
Banking feat(settings): centralize currency options and split profile/account support (#256) 2026-04-02 19:23:10 +02:00
Demo Remove encryption from browser tests and demo user (#129) 2026-02-17 11:45:27 +01:00
AccountMetricsService.php feat(dashboard): merge real estate accounts with linked mortgages on dashboard 2026-03-26 21:04:13 +01:00
AutomationRuleService.php feat(rules): move automation rule evaluation to the backend (#168) 2026-03-01 10:37:12 +01:00
BalanceLookup.php fix(static-analysis): clear phpstan-baseline by fixing all suppressed errors (#183) 2026-03-02 12:22:30 +00:00
BudgetPeriodService.php fix(static-analysis): clear phpstan-baseline by fixing all suppressed errors (#183) 2026-03-02 12:22:30 +00: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
CurrencyOptions.php feat(settings): centralize currency options and split profile/account support (#256) 2026-04-02 19:23:10 +02:00
ExchangeRateService.php feat: Add multi-currency conversion for net worth charts (#138) 2026-02-20 10:45:23 +01:00
LoanAmortizationService.php fix(loans): project monthly balances from actual entries instead of original params (#259) 2026-04-04 15:57:29 +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