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().optional(), 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) .execute() }, }) done() } export default invoiceRoutes