From 7a1acc32a9bc792422c4c5f225cac39731d9e35d Mon Sep 17 00:00:00 2001 From: siddharthd Date: Tue, 28 Jul 2026 11:39:11 +1000 Subject: [PATCH] feat(trips): say which direction a trip balance points MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit A participant who has overpaid a trip showed as "$-816.16" under a column headed "Outstanding on this trip". A negative outstanding reads as a bug rather than as "they are ahead", so the sign is now spelled out: magnitude plus one of all square / owes you / ahead — you owe them, coloured the same way Shared colours the same three states. Also corrects the footer, which had gone stale and was now simply false. It said settlement could not be computed per trip because payments carried no trip attribution. Migration 0022 added split_payments.trip_id and the figures above it have been net of trip-scoped payments since. What a reader needs to know is the opposite of what it said: household-tab payments are the ones NOT counted here. --- src/app/trips/[id]/page.tsx | 56 +++++++++++++++++++++++-------------- 1 file changed, 35 insertions(+), 21 deletions(-) diff --git a/src/app/trips/[id]/page.tsx b/src/app/trips/[id]/page.tsx index d00ff44..0af1671 100644 --- a/src/app/trips/[id]/page.tsx +++ b/src/app/trips/[id]/page.tsx @@ -291,32 +291,46 @@ export default function TripDetailPage({ params }: { params: Promise<{ id: strin - {participant_splits.map((p) => ( - - {p.name} - - - ${Number(p.owed).toFixed(2)} - - {p.unconverted_count > 0 && ( - - approx · {p.unconverted_count} unconverted + {/* A negative outstanding means they have paid more towards this + trip than their share of it — which reads as a typo unless the + sign is spelled out. Shown as a magnitude plus a word, the same + way Shared does it, so the two pages agree on what a direction + means. */} + {participant_splits.map((p) => { + const owed = Number(p.owed); + const square = Math.abs(owed) < 0.005; + const theyOweMe = owed > 0; + return ( + + {p.name} + + + ${Math.abs(owed).toFixed(2)} - )} - - - ))} + + {square ? "all square" : theyOweMe ? "owes you" : "ahead — you owe them"} + + {p.unconverted_count > 0 && ( + + approx · {p.unconverted_count} unconverted + + )} + + + ); + })} - {/* Settled/unsettled was reported from transaction_splits.settled, - which nothing sets — so every trip showed 100% unsettled forever, - including ones already paid in full. Settlement is tracked across - the whole relationship, not per trip: payments carry no trip - attribution, so a per-trip figure cannot be computed. */} + {/* This note used to say a per-trip figure could not be computed, + because payments carried no trip attribution. Migration 0022 added + split_payments.trip_id, so it can and now does — the figures above + are net of payments scoped to this trip. What the note has to say + instead is which payments are NOT in them. */}

- Settlement is tracked across all shared expenses, not per trip — + Net of payments recorded against this trip. Payments on the ongoing + household tab are not counted here — see Shared for - what is actually owed. + the overall balance.

)}