import _ from 'lodash' import { Type, type FastifyPluginCallbackTypebox } from '@fastify/type-provider-typebox' import knex from '../../lib/knex.ts' import StatusError from '../../lib/status_error.ts' const apiRoutes: FastifyPluginCallbackTypebox = (fastify, _, done) => { fastify.route({ url: '/', method: 'GET', schema: { querystring: Type.Object({ year: Type.Optional(Type.Number()), supplier: Type.Optional(Type.Number()), }), }, async handler(req) { let query: { financialYearId?: number; supplierId?: number } = {} if (req.query.year) { const year = await knex('financialYear').first('*').where('year', req.query.year) if (!year) throw new StatusError(404, `Year ${req.query.year} not found.`) query.financialYearId = year.id } if (req.query.supplier) { query.supplierId = req.query.supplier } return knex('invoice AS i') .select('i.*', 'fy.year', { files: knex .select(knex.raw('json_agg(files)')) .from( knex .select('id', 'filename') .from('file AS f') .innerJoin('filesToInvoice AS fi', 'f.id', 'fi.fileId') .where('fi.invoiceId', knex.ref('i.id')) .as('files'), ), transactions: knex .select(knex.raw('json_agg(transactions)')) .from(knex.select('*').from('transaction AS t').where('t.invoice_id', knex.ref('i.id')).as('transactions')), }) .leftOuterJoin('financialYear AS fy', 'i.financialYearId', 'fy.id') .where(query) }, }) fastify.route({ url: '/:id', method: 'GET', schema: { params: Type.Object({ id: Type.Number(), }), }, handler(req) { return knex('invoice AS i') .first('i.*', 'fy.year', { files: knex .select(knex.raw('json_agg(files)')) .from( knex .select('id', 'filename') .from('file AS f') .innerJoin('filesToInvoice AS fi', 'f.id', 'fi.fileId') .where('fi.invoiceId', knex.ref('i.id')) .as('files'), ), transactions: knex .select(knex.raw('json_agg(transactions)')) .from(knex.select('*').from('transaction AS t').where('t.invoice_id', knex.ref('i.id')).as('transactions')), }) .leftOuterJoin('financialYear AS fy', 'i.financialYearId', 'fy.id') .where('i.id', req.params.id) }, }) fastify.route({ url: '/by-supplier/:supplier', method: 'GET', schema: { params: Type.Object({ supplier: Type.Number(), }), }, handler(req) { return knex('invoice AS i') .select('*', { files: knex .select(knex.raw('json_agg(files)')) .from( knex .select('id', 'filename') .from('file AS f') .innerJoin('filesToInvoice AS fi', 'f.id', 'fi.fileId') .where('fi.invoiceId', knex.ref('i.id')) .as('files'), ), }) .where('supplierId', req.params.supplier) }, }) fastify.route({ url: '/by-year/:year', method: 'GET', schema: { params: Type.Object({ year: Type.Number(), }), }, async handler(req) { const year = await knex('financialYear').first('*').where('year', req.params.year) if (!year) throw new StatusError(404, `Year ${req.params.year} not found.`) return knex('invoice').select('*').where('financialYearId', year.id) }, }) done() } export default apiRoutes