This commit is contained in:
@@ -71,6 +71,28 @@ Verified via Playwright: a linked card with zero transactions shows no
|
||||
on the viewed month); adding a real $25 charge makes it appear correctly
|
||||
with the real amount.
|
||||
|
||||
**Follow-up in the same session: Overview's "Credit card debt" didn't
|
||||
match the per-card "next bill" tiles right below it.** User asked why the
|
||||
top total showed $0 while a card's tile showed a real upcoming amount.
|
||||
Root cause: the two figures used genuinely different logic —
|
||||
`totalCardDebt` summed real debt *as of today* while excluding anything
|
||||
dated in the future or explicitly tagged outside the current calendar
|
||||
month (from the earlier "should consider only current month" fix), while
|
||||
the per-card tiles use `nextBillFor`, which shows whichever bill is
|
||||
chronologically next regardless of month or the transaction's date.
|
||||
Confirmed with the user (their call, given the tension with the earlier
|
||||
fix): the total should just be the sum of the tiles, always consistent by
|
||||
construction. `totalCardDebt` now sums `nextBillFor(...).amountOwed` per
|
||||
card directly — same function, same result as what's rendered below.
|
||||
This does mean a transaction explicitly deferred to a future bill counts
|
||||
toward the total again when it's that card's only/next open bill (no
|
||||
longer zeroed out for not being "this month's" bill) — that's the
|
||||
accepted tradeoff for the total always matching what's on screen.
|
||||
|
||||
Verified via Playwright: a card whose only transaction is a $80 charge
|
||||
explicitly tagged to next month's bill now shows "$80.00" in both the top
|
||||
total and its own tile (previously $0 vs $80 — the reported mismatch).
|
||||
|
||||
## Status as of end of session (2026-07-08)
|
||||
|
||||
**Done, not yet committed: Credit card overhaul** (requested 2026-07-08 via
|
||||
|
||||
@@ -126,26 +126,14 @@ export default function Overview() {
|
||||
const ccAccounts = accounts.filter((a) => a.kind === 'CREDIT_CARD');
|
||||
const totalBalance = liquidAccounts.reduce((sum, a) => sum + (accountBalances.get(a.id) ?? Number(a.balance)), 0);
|
||||
|
||||
// Real debt as of today, except a charge the user explicitly tagged (via
|
||||
// the Bill dropdown) to a bill outside the current month is excluded —
|
||||
// that's a deliberate "count this toward next month instead" choice, not
|
||||
// this month's debt. A charge with no such override still counts even if
|
||||
// its *natural* due-day rollover lands next month (e.g. the due day has
|
||||
// already passed this cycle) — it happened today/this month and is real,
|
||||
// current debt regardless of which statement it'll appear on.
|
||||
const monthStart = new Date(today.getFullYear(), today.getMonth(), 1);
|
||||
const monthEnd = new Date(today.getFullYear(), today.getMonth() + 1, 0);
|
||||
const totalCardDebt = ccAccounts.reduce((sum, a) => {
|
||||
const adjustedBalance = (txnsByAccountId.get(a.id) || []).reduce((bal, t) => {
|
||||
if (parseLocalDate(t.occurredOn) > today) return bal;
|
||||
if (t.billDueDate) {
|
||||
const due = parseLocalDate(t.billDueDate);
|
||||
if (due < monthStart || due > monthEnd) return bal;
|
||||
}
|
||||
return bal + Number(t.amount);
|
||||
}, Number(a.openingBalance ?? 0));
|
||||
return sum + Math.max(-adjustedBalance, 0);
|
||||
}, 0);
|
||||
// Sum of each card's next open bill (same nextBillFor call the "Credit
|
||||
// cards" tiles below use) — so the total always matches what's shown on
|
||||
// screen, regardless of which calendar month that next bill happens to
|
||||
// land in. A card with nothing owed yet contributes 0.
|
||||
const totalCardDebt = ccAccounts.reduce(
|
||||
(sum, a) => sum + Math.max(nextBillFor(a, txnsByAccountId.get(a.id) || [], today)?.amountOwed ?? 0, 0),
|
||||
0
|
||||
);
|
||||
const { start, end } = rangeBounds(range);
|
||||
const recent = txnQueries
|
||||
.flatMap((q) => q.data || [])
|
||||
|
||||
Reference in New Issue
Block a user