Five rows all reading "Order - Uber Trip" are indistinguishable — the list gives you a date and an amount and nothing to tell one ride from another (user, 2026-07-27). Where the trip went is exactly what separates them, and it was already stored on expense_metadata.route since this morning; nothing in the list read it. getTransactions now joins the receipt (both directions — transaction_id OR matched_transaction_id, since a card-settled order points at the statement line instead) and the description cell renders "Terminal 2, Melbourne Airport (MEL) → 19 Lady Penrhyn Dr" in the same italic sub-line notes use. Two deliberate limits: - **A note the user wrote always wins.** This only fills an empty sub-line; it never occupies the notes field, which is theirs. - **Deliveries are excluded.** Their merchant already identifies them, so the restaurant's street address would be clutter on every food order. Gated on platform = 'uber'. The summary keeps the first two comma-segments of each address — a truncation, not a guess about geography. Uber puts the venue or street first, which is the identifying part; the full stops with their times stay in the title attribute.
This commit is contained in:
+23
-1
@@ -1,5 +1,11 @@
|
||||
import { queryRaw } from "./db";
|
||||
|
||||
export interface RoutePointRow {
|
||||
label: string;
|
||||
time: string | null;
|
||||
address: string;
|
||||
}
|
||||
|
||||
export interface TagRow {
|
||||
id: number;
|
||||
name: string;
|
||||
@@ -28,6 +34,9 @@ export interface TransactionRow {
|
||||
// How it was paid (migration 0016). NULL = unknown, treated as reconcilable.
|
||||
// 'cash' and 'credits' are excluded from reconciliation — see needsCardMatch().
|
||||
payment_method: string | null;
|
||||
/** Uber pick-up/drop-off, when this row came from an order receipt. */
|
||||
order_route: RoutePointRow[] | null;
|
||||
order_platform: "doordash" | "ubereats" | "uber" | null;
|
||||
// override fields
|
||||
category_override: string | null;
|
||||
merchant_override: string | null;
|
||||
@@ -244,10 +253,23 @@ export async function getTransactions(ownerId: number, filters: TransactionFilte
|
||||
tr.name as trip_name,
|
||||
tr.color as trip_color,
|
||||
txn_tags.tags,
|
||||
txn_splits.splits
|
||||
txn_splits.splits,
|
||||
order_ctx.route as order_route,
|
||||
order_ctx.platform as order_platform
|
||||
FROM transactions t
|
||||
LEFT JOIN transaction_overrides o ON o.transaction_id = t.id
|
||||
LEFT JOIN statements s ON s.id = t.statement_id
|
||||
-- Order provenance, for the sub-line under the description. Five rows all
|
||||
-- reading "Order - Uber Trip" are indistinguishable; where they went is the
|
||||
-- only thing that tells them apart, and it was already stored.
|
||||
-- Both directions, because a card-settled order has no transaction of its
|
||||
-- own and points at the statement line instead (I5).
|
||||
LEFT JOIN LATERAL (
|
||||
SELECT em.route, em.platform
|
||||
FROM expense_metadata em
|
||||
WHERE em.transaction_id = t.id OR em.matched_transaction_id = t.id
|
||||
LIMIT 1
|
||||
) order_ctx ON true
|
||||
LEFT JOIN participants p ON p.id = COALESCE(t.owner_id, s.owner_id)
|
||||
LEFT JOIN transactions src ON src.reconciled_with_id = t.id AND src.statement_id IS NULL
|
||||
LEFT JOIN trips tr ON tr.id = o.trip_id
|
||||
|
||||
Reference in New Issue
Block a user