fix(shared): exclude payments from balance when tag filter is active

This commit is contained in:
2026-04-13 05:41:00 +10:00
parent 1b561af9e9
commit 07b8c1ef16
2 changed files with 21 additions and 12 deletions
+18 -12
View File
@@ -287,10 +287,25 @@ export async function getParticipantBalances(ownerId: number, tagIds?: number[])
tagFilter = `AND EXISTS (SELECT 1 FROM transaction_tags tt WHERE tt.transaction_id = t.id AND tt.tag_id = ANY($2::int[]))`;
}
// Payments settle the total relationship between two people, not a specific tag.
// Only subtract payments when viewing the unfiltered total; with a tag filter
// active, show the raw split amount for that tag context only.
const paymentsJoin = tagIds?.length ? "" : `
LEFT JOIN (
SELECT
CASE WHEN sp.from_participant_id != $1 THEN sp.from_participant_id ELSE sp.to_participant_id END AS pid,
SUM(CASE WHEN sp.to_participant_id = $1 THEN sp.amount ELSE -sp.amount END) AS net_paid
FROM split_payments sp
WHERE sp.from_participant_id = $1 OR sp.to_participant_id = $1
GROUP BY pid
) payments ON payments.pid = p.id`;
const paymentsSelect = tagIds?.length ? "" : "- COALESCE(payments.net_paid, 0)::numeric(12,2)";
const paymentsGroup = tagIds?.length ? "" : ", payments.net_paid";
return queryRaw<ParticipantBalance>(`
SELECT p.id, p.name,
COALESCE(SUM(splits.signed_amount), 0)::numeric(12,2)
- COALESCE(payments.net_paid, 0)::numeric(12,2) AS total_owed,
${paymentsSelect} AS total_owed,
COALESCE(SUM(splits.split_count), 0)::int AS unsettled_count
FROM participants p
@@ -317,19 +332,10 @@ export async function getParticipantBalances(ownerId: number, tagIds?: number[])
WHERE ts.participant_id = $1 AND COALESCE(t.owner_id, s.owner_id) != $1
${tagFilter}
) splits ON splits.pid = p.id
-- Net payments always unfiltered (payments are against total debt, not per-tag)
LEFT JOIN (
SELECT
CASE WHEN sp.from_participant_id != $1 THEN sp.from_participant_id ELSE sp.to_participant_id END AS pid,
SUM(CASE WHEN sp.to_participant_id = $1 THEN sp.amount ELSE -sp.amount END) AS net_paid
FROM split_payments sp
WHERE sp.from_participant_id = $1 OR sp.to_participant_id = $1
GROUP BY pid
) payments ON payments.pid = p.id
${paymentsJoin}
WHERE p.id != $1
GROUP BY p.id, p.name, payments.net_paid
GROUP BY p.id, p.name ${paymentsGroup}
ORDER BY p.name
`, params);
}