fix(shared): exclude payments from balance when tag filter is active
This commit is contained in:
@@ -299,6 +299,9 @@ export default function SharedPage() {
|
|||||||
{addingParticipant && <AddParticipantForm onDone={() => setAddingParticipant(false)} />}
|
{addingParticipant && <AddParticipantForm onDone={() => setAddingParticipant(false)} />}
|
||||||
|
|
||||||
{/* Balance cards */}
|
{/* Balance cards */}
|
||||||
|
{realTagIds.length === 0 && tagIds.includes("untagged") ? null : realTagIds.length > 0 && (
|
||||||
|
<p className="text-xs text-zinc-500 mb-2">Showing split totals for selected tag — payments excluded (payments settle overall debt, not per-tag)</p>
|
||||||
|
)}
|
||||||
<div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-4">
|
<div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-4">
|
||||||
{balLoading ? (
|
{balLoading ? (
|
||||||
<p className="text-zinc-500 text-sm col-span-3">Loading balances...</p>
|
<p className="text-zinc-500 text-sm col-span-3">Loading balances...</p>
|
||||||
|
|||||||
+18
-12
@@ -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[]))`;
|
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>(`
|
return queryRaw<ParticipantBalance>(`
|
||||||
SELECT p.id, p.name,
|
SELECT p.id, p.name,
|
||||||
COALESCE(SUM(splits.signed_amount), 0)::numeric(12,2)
|
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
|
COALESCE(SUM(splits.split_count), 0)::int AS unsettled_count
|
||||||
FROM participants p
|
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
|
WHERE ts.participant_id = $1 AND COALESCE(t.owner_id, s.owner_id) != $1
|
||||||
${tagFilter}
|
${tagFilter}
|
||||||
) splits ON splits.pid = p.id
|
) splits ON splits.pid = p.id
|
||||||
|
${paymentsJoin}
|
||||||
-- 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
|
|
||||||
|
|
||||||
WHERE p.id != $1
|
WHERE p.id != $1
|
||||||
GROUP BY p.id, p.name, payments.net_paid
|
GROUP BY p.id, p.name ${paymentsGroup}
|
||||||
ORDER BY p.name
|
ORDER BY p.name
|
||||||
`, params);
|
`, params);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user