feat(transactions): add imported date column, split filter, and sortable columns
- Show created_at as "Imported" column in transactions and shared views - For reconciled transactions, show original CSV import date (not statement processing date) via LEFT JOIN on reconciled_with_id - Add has_split filter (all/split only/unsplit only) to transactions page - Transactions table: sortable by imported date; split filter dropdown - Shared table: client-side sort by date, imported, and amount
This commit is contained in:
@@ -26,6 +26,7 @@ interface TransactionFilters {
|
||||
offset?: number;
|
||||
amount_min?: number;
|
||||
amount_max?: number;
|
||||
has_split?: string;
|
||||
}
|
||||
|
||||
function buildParams(filters: TransactionFilters): string {
|
||||
|
||||
+12
-2
@@ -82,6 +82,7 @@ interface TransactionFilters {
|
||||
offset?: number;
|
||||
amount_min?: number;
|
||||
amount_max?: number;
|
||||
has_split?: string;
|
||||
}
|
||||
|
||||
export async function getTransactions(ownerId: number, filters: TransactionFilters) {
|
||||
@@ -148,10 +149,15 @@ export async function getTransactions(ownerId: number, filters: TransactionFilte
|
||||
conditions.push(`t.amount <= $${paramIdx++}`);
|
||||
params.push(filters.amount_max);
|
||||
}
|
||||
if (filters.has_split === "yes") {
|
||||
conditions.push(`EXISTS (SELECT 1 FROM transaction_splits ts_f WHERE ts_f.transaction_id = t.id)`);
|
||||
} else if (filters.has_split === "no") {
|
||||
conditions.push(`NOT EXISTS (SELECT 1 FROM transaction_splits ts_f WHERE ts_f.transaction_id = t.id)`);
|
||||
}
|
||||
|
||||
const where = `WHERE ${conditions.join(" AND ")}`;
|
||||
|
||||
const sortCol = filters.sort_by === "amount" ? "t.amount" : "t.transaction_date";
|
||||
const sortCol = filters.sort_by === "amount" ? "t.amount" : filters.sort_by === "created_at" ? "t.created_at" : "t.transaction_date";
|
||||
const sortDir = filters.sort_dir === "asc" ? "ASC" : "DESC";
|
||||
const limit = filters.limit || 50;
|
||||
const offset = filters.offset || 0;
|
||||
@@ -174,12 +180,14 @@ export async function getTransactions(ownerId: number, filters: TransactionFilte
|
||||
COALESCE(s.bank_name, 'Manual') as bank_name,
|
||||
COALESCE(t.owner_id, s.owner_id) as owner_id,
|
||||
p.name as owner_name,
|
||||
COALESCE(src.created_at, t.created_at) as created_at,
|
||||
txn_tags.tags,
|
||||
txn_splits.splits
|
||||
FROM transactions t
|
||||
LEFT JOIN transaction_overrides o ON o.transaction_id = t.id
|
||||
LEFT JOIN statements s ON s.id = t.statement_id
|
||||
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 LATERAL (
|
||||
SELECT COALESCE(json_agg(json_build_object('id', tg.id, 'name', tg.name, 'color', tg.color) ORDER BY tg.name), '[]'::json) as tags
|
||||
FROM transaction_tags tt
|
||||
@@ -552,6 +560,7 @@ export async function getSharedTransactions(ownerId: number, tagIds?: number[],
|
||||
COALESCE(s.bank_name, 'Manual') as bank_name,
|
||||
COALESCE(t.owner_id, s.owner_id) as owner_id,
|
||||
p_owner.name as owner_name,
|
||||
COALESCE(src.created_at, t.created_at) as created_at,
|
||||
json_agg(json_build_object(
|
||||
'split_id', ts.id,
|
||||
'participant_id', ts.participant_id,
|
||||
@@ -565,6 +574,7 @@ export async function getSharedTransactions(ownerId: number, tagIds?: number[],
|
||||
LEFT JOIN transaction_overrides o ON o.transaction_id = t.id
|
||||
LEFT JOIN statements s ON s.id = t.statement_id
|
||||
LEFT JOIN participants p_owner ON p_owner.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
|
||||
WHERE (
|
||||
(
|
||||
COALESCE(t.owner_id, s.owner_id) = $1
|
||||
@@ -575,7 +585,7 @@ export async function getSharedTransactions(ownerId: number, tagIds?: number[],
|
||||
)
|
||||
)
|
||||
${tagClause}
|
||||
GROUP BY t.id, o.category_override, o.merchant_normalized, o.notes, s.bank_name, s.owner_id, p_owner.name
|
||||
GROUP BY t.id, o.category_override, o.merchant_normalized, o.notes, s.bank_name, s.owner_id, p_owner.name, src.created_at
|
||||
ORDER BY t.transaction_date DESC
|
||||
`, params);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user