Mortgages and personal loans use monthly compounding (rate/12), but
HELOCs and auto loans accrue interest daily (rate/365 * actual days).
Select the calculation method based on account type and update the
disclaimer to reflect which method is being used.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
formatDate was parsing UTC timestamps in local time, shifting dates
back a day in western timezones. Strip the time portion before parsing
so dates display correctly.
Revert interest calculation from daily accrual back to standard monthly
compounding (rate/12) with per-payment rounding. This matches how
mortgage servicers calculate interest and produces correct amortization
schedules.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The change tracker-based approaches (RemoveRange, Clear) both caused
DbUpdateConcurrencyException when deleting amortization entries.
Use ExecuteDeleteAsync to delete directly in the database, bypassing
the change tracker entirely.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replace the term months field with a maturity date picker - users know
when their loan ends, not the month count. Compute termMonths from the
two dates. Rename "Origination Date" to "First Payment Date" and adjust
the amortization schedule so payment #1 falls on the entered date.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
RemoveRange + collection replacement caused EF Core to attempt a
double-delete on amortization entries. Use Clear() on the tracked
collection instead, letting EF handle orphan deletion in a single pass.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The amortization schedule and payoff calculator were using rate/12 for
monthly interest, which assumes 30.42 days per period and overestimates
interest. Switch to daily accrual (rate/365 * actual days) to match how
lenders actually compute interest between payment dates.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The current account balance is not the origination balance, so defaulting
it into the Original Balance field is misleading. Leave it at 0 so users
enter the actual loan origination amount.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Fetch loan data (mortgage/student) from Plaid's Liabilities API during sync
and auto-create LoanDetail records. For accounts without liabilities data,
pre-populate the setup form with balance, interest rate, and smart term
defaults. Also fixes maturity date computation in the frontend form.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Npgsql requires DateTimeKind.Utc for timestamp with time zone
columns. This fixes errors in transaction create/edit, budgets,
reports, loans, scheduled transactions, and file imports.
Changes:
- TransactionService: SpecifyKind on request.Date for create,
update, and transfer
- BudgetService: UTC kind on all new DateTime(year, month, 1)
- ReportService: UTC kind on endOfMonth; rewrite spending-by-
category GroupBy to avoid untranslatable navigation properties
- LoanService: UTC kind on payoff scenario date construction
- ScheduledTransactionService: UTC kind on SemiMonthly date
- ImportService: SpecifyKind on parsed.Date when persisting
- OFX/CSV/QIF parsers: AssumeUniversal + AdjustToUniversal on
all date parsing
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>