Money: move /projects/money-tracker to /trackers/money, rename to Money, 308 redirects from old paths (bank-callback query kept)
All checks were successful
Deploy production / deploy (push) Successful in 2m49s
All checks were successful
Deploy production / deploy (push) Successful in 2m49s
This commit is contained in:
114
src/routes/trackers/money/transactions/+page.server.ts
Normal file
114
src/routes/trackers/money/transactions/+page.server.ts
Normal file
@@ -0,0 +1,114 @@
|
||||
import { db } from '#lib/server/db/index.js';
|
||||
import { moneyAccounts, moneyTransactions } from '#lib/server/db/schema/index.js';
|
||||
import { requireAdmin } from '#lib/server/authorization.js';
|
||||
import { positiveId, validDate } from '#lib/server/money-tracker.js';
|
||||
import {
|
||||
and,
|
||||
asc,
|
||||
count,
|
||||
desc,
|
||||
eq,
|
||||
gt,
|
||||
gte,
|
||||
ilike,
|
||||
inArray,
|
||||
isNotNull,
|
||||
lt,
|
||||
lte,
|
||||
or,
|
||||
sql,
|
||||
sum,
|
||||
type SQL
|
||||
} from 'drizzle-orm';
|
||||
import { redirect } from '@sveltejs/kit';
|
||||
import type { PageServerLoad } from './$types';
|
||||
|
||||
const PAGE_SIZE = 50;
|
||||
const sources = ['manual', 'csv', 'enablebanking', 'linked'] as const;
|
||||
const sorts = ['newest', 'oldest', 'largest', 'smallest'] as const;
|
||||
|
||||
export const load: PageServerLoad = async (event) => {
|
||||
if (!event.locals.user)
|
||||
redirect(303, '/login?returnTo=' + encodeURIComponent(event.url.pathname + event.url.search));
|
||||
const user = requireAdmin(event);
|
||||
const params = event.url.searchParams;
|
||||
const q = (params.get('q') ?? '').trim().slice(0, 100);
|
||||
const accountIds = params
|
||||
.getAll('account')
|
||||
.map(positiveId)
|
||||
.filter((id): id is number => id !== null);
|
||||
const source = sources.find((item) => item === params.get('source')) ?? '';
|
||||
const type = params.get('type') === 'in' ? 'in' : params.get('type') === 'out' ? 'out' : '';
|
||||
const from = validDate(params.get('from')) ?? '';
|
||||
const to = validDate(params.get('to')) ?? '';
|
||||
const sort = sorts.find((item) => item === params.get('sort')) ?? 'newest';
|
||||
const requestedPage = positiveId(params.get('page')) ?? 1;
|
||||
|
||||
const t = moneyTransactions;
|
||||
const filters: (SQL | undefined)[] = [eq(t.userId, user.id)];
|
||||
if (q) {
|
||||
const pattern = '%' + q.replace(/[\\%_]/g, (c) => '\\' + c) + '%';
|
||||
filters.push(or(ilike(t.description, pattern), ilike(t.counterparty, pattern)));
|
||||
}
|
||||
if (accountIds.length) filters.push(inArray(t.accountId, accountIds));
|
||||
if (source === 'linked') filters.push(and(eq(t.source, 'manual'), isNotNull(t.externalId)));
|
||||
else if (source) filters.push(eq(t.source, source));
|
||||
if (type === 'in') filters.push(gt(t.amountCents, 0));
|
||||
if (type === 'out') filters.push(lt(t.amountCents, 0));
|
||||
if (from) filters.push(gte(t.date, from));
|
||||
if (to) filters.push(lte(t.date, to));
|
||||
const where = and(...filters);
|
||||
|
||||
const [accounts, [totals]] = await Promise.all([
|
||||
db
|
||||
.select({
|
||||
id: moneyAccounts.id,
|
||||
name: moneyAccounts.name,
|
||||
color: moneyAccounts.color,
|
||||
scope: moneyAccounts.scope
|
||||
})
|
||||
.from(moneyAccounts)
|
||||
.where(eq(moneyAccounts.userId, user.id))
|
||||
.orderBy(asc(moneyAccounts.name)),
|
||||
db
|
||||
.select({ count: count(), sum: sum(t.amountCents) })
|
||||
.from(t)
|
||||
.where(where)
|
||||
]);
|
||||
const pages = Math.max(1, Math.ceil(totals.count / PAGE_SIZE));
|
||||
const page = Math.min(requestedPage, pages);
|
||||
const order =
|
||||
sort === 'oldest'
|
||||
? [asc(t.date), asc(t.id)]
|
||||
: sort === 'largest'
|
||||
? [desc(t.amountCents), desc(t.date)]
|
||||
: sort === 'smallest'
|
||||
? [asc(t.amountCents), desc(t.date)]
|
||||
: [desc(t.date), desc(t.id)];
|
||||
const rows = await db
|
||||
.select({
|
||||
id: t.id,
|
||||
date: t.date,
|
||||
description: t.description,
|
||||
counterparty: t.counterparty,
|
||||
amountCents: t.amountCents,
|
||||
accountId: t.accountId,
|
||||
source: t.source,
|
||||
linked: sql<boolean>`${t.externalId} is not null`
|
||||
})
|
||||
.from(t)
|
||||
.where(where)
|
||||
.orderBy(...order)
|
||||
.limit(PAGE_SIZE)
|
||||
.offset((page - 1) * PAGE_SIZE);
|
||||
|
||||
return {
|
||||
accounts,
|
||||
rows,
|
||||
total: totals.count,
|
||||
sumCents: Number(totals.sum ?? 0),
|
||||
page,
|
||||
pages,
|
||||
filters: { q, accountIds, source, type, from, to, sort }
|
||||
};
|
||||
};
|
||||
Reference in New Issue
Block a user