brf/server/routes/api/invoices.ts

128 lines
3.7 KiB
TypeScript

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