brf/server/routes/api/entries.ts
2025-12-18 10:20:02 +01:00

80 lines
2.2 KiB
TypeScript

import _ from 'lodash'
import * as z from 'zod'
import type { FastifyPluginCallbackZod } from 'fastify-type-provider-zod'
import { jsonArrayFrom } from 'kysely/helpers/postgres'
import { applyWhere } from '../../lib/kysely_helpers.ts'
const entryRoutes: FastifyPluginCallbackZod = (fastify, _, done) => {
const { db } = fastify
fastify.route({
url: '/',
method: 'GET',
schema: {
querystring: z.object({
journal: z.string().optional(),
year: z.coerce.number().optional(),
}),
},
async handler(request) {
return applyWhere(
db
.selectFrom('entry as e')
.innerJoin('transaction as t', 'e.id', 't.entryId')
.innerJoin('journal as j', 'j.id', 'e.journalId')
.innerJoin('financialYear as fy', 'fy.id', 'e.financialYearId')
.selectAll('e')
.select((eb) => eb.fn.sum('t.amount').as('amount'))
.orderBy('e.id')
.where('t.amount', '>', 0 as ANY)
.groupBy('e.id'),
{
year: request.query.year,
'j.identifier': request.query.journal,
},
).execute()
},
})
fastify.route({
url: '/:id',
method: 'GET',
schema: {
params: z.object({
id: z.coerce.number(),
}),
},
async handler(req) {
return db
.selectFrom('entry as e')
.innerJoin('journal as j', 'e.journalId', 'j.id')
.innerJoin('transaction as t', 'e.id', 't.entryId')
.select([
'e.id',
'j.identifier as journal',
'e.number',
'e.entryDate',
'e.transactionDate',
'e.description',
(eb) => eb.fn.sum('t.amount').as('amount'),
(eb) =>
jsonArrayFrom(
eb
.selectFrom('transaction as t')
.select(['id', 'accountNumber', 'amount', 'description'])
.selectAll()
.whereRef('t.entryId', '=', 'e.id'),
).as('transactions'),
])
.groupBy(['e.id', 'j.identifier'])
.where('e.id', '=', req.params.id)
.where('t.amount', '>', 0 as ANY)
.executeTakeFirst()
},
})
done()
}
export default entryRoutes