brf/server/routes/api/invoices.ts

109 lines
3.0 KiB
TypeScript

import _ from 'lodash'
import { jsonArrayFrom } from 'kysely/helpers/postgres'
import * as z from 'zod'
import type { FastifyPluginCallbackZod } from 'fastify-type-provider-zod'
import { applyWhere, paginate } from '../../lib/kysely_helpers.ts'
const invoiceRoutes: FastifyPluginCallbackZod = (fastify, _, done) => {
const { db } = fastify
fastify.route({
url: '/',
method: 'GET',
schema: {
querystring: z.object({
year: z.coerce.number().optional(),
supplierId: z.coerce.number().optional(),
limit: z.coerce.number().default(100),
offset: z.coerce.number().default(0),
sort: z.literal(['supplierId', 'i.id', 'invoiceDate', 'dueDate']).default('i.id'),
}),
},
async handler(request) {
const { offset, limit, sort, ...where } = request.query
const baseQuery = db.selectFrom('invoice as i').leftJoin('financialYear as fy', 'fy.id', 'i.financialYearId')
return paginate(
baseQuery
.selectAll('i')
.select(['fy.year'])
.select((eb) => [
jsonArrayFrom(
eb
.selectFrom('file as f')
.innerJoin('filesToInvoice as fi', 'f.id', 'fi.fileId')
.select(['id', 'filename'])
.whereRef('fi.invoiceId', '=', 'i.id'),
).as('files'),
jsonArrayFrom(eb.selectFrom('transaction as t').selectAll().whereRef('t.invoiceId', '=', 'i.id')).as(
'transactions',
),
]),
baseQuery,
{
where,
limit,
offset,
sort,
},
)
},
})
fastify.route({
url: '/total-amount',
method: 'GET',
schema: {
querystring: z.object({
supplierId: z.coerce.number().optional(),
}),
response: {
200: z.object({
totalAmount: z.coerce.number(),
}),
},
},
handler(request) {
return applyWhere(
db.selectFrom('invoice').select((eb) => eb.fn.sum('amount').as('totalAmount')),
request.query,
).executeTakeFirst()
},
})
fastify.route({
url: '/:id',
method: 'GET',
schema: {
params: z.object({
id: z.coerce.number(),
}),
},
handler(request) {
return db
.selectFrom('invoice as i')
.leftJoin('financialYear as fy', 'fy.id', 'i.financialYearId')
.selectAll('i')
.select(['fy.year'])
.select((eb) => [
jsonArrayFrom(
eb
.selectFrom('file as f')
.innerJoin('filesToInvoice as fi', 'f.id', 'fi.fileId')
.select(['id', 'filename'])
.whereRef('fi.invoiceId', '=', 'i.id'),
).as('files'),
jsonArrayFrom(eb.selectFrom('transaction as t').selectAll().whereRef('t.invoiceId', '=', 'i.id')).as(
'transactions',
),
])
.where('i.id', '=', request.params.id)
.executeTakeFirst()
},
})
done()
}
export default invoiceRoutes