247 lines
6.3 KiB
TypeScript
247 lines
6.3 KiB
TypeScript
import _ from 'lodash'
|
|
import { Type, type Static, type FastifyPluginCallbackTypebox } from '@fastify/type-provider-typebox'
|
|
import knex from '../lib/knex.ts'
|
|
import StatusError from '../lib/status_error.ts'
|
|
|
|
export const FinancialYear = Type.Object({
|
|
year: Type.Number(),
|
|
startDate: Type.String(),
|
|
endDate: Type.String(),
|
|
})
|
|
|
|
export type FinancialYearType = Static<typeof FinancialYear>
|
|
|
|
const apiRoutes: FastifyPluginCallbackTypebox = (fastify, _, done) => {
|
|
fastify.route({
|
|
url: '/financial-years',
|
|
method: 'GET',
|
|
handler() {
|
|
return knex('financialYear').select('*')
|
|
},
|
|
})
|
|
|
|
fastify.route({
|
|
url: '/invoices',
|
|
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('*', {
|
|
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(query)
|
|
},
|
|
})
|
|
|
|
fastify.route({
|
|
url: '/invoices/:id',
|
|
method: 'GET',
|
|
schema: {
|
|
params: Type.Object({
|
|
id: Type.Number(),
|
|
}),
|
|
},
|
|
handler(req) {
|
|
return knex('invoice').first('*').where('id', req.params.id)
|
|
},
|
|
})
|
|
|
|
fastify.route({
|
|
url: '/invoices/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: '/invoices/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)
|
|
},
|
|
})
|
|
|
|
fastify.route({
|
|
url: '/objects',
|
|
method: 'GET',
|
|
handler() {
|
|
return knex('object AS o')
|
|
.select('o.id', 'o.number', 'o.name', 'd.number AS dimensionNumber', 'd.name AS dimensionName')
|
|
.innerJoin('dimension AS d', function () {
|
|
this.on('o.dimensionId', '=', 'd.id')
|
|
})
|
|
},
|
|
})
|
|
|
|
fastify.route({
|
|
url: '/objects/:id',
|
|
method: 'GET',
|
|
schema: {
|
|
params: Type.Object({
|
|
id: Type.Number(),
|
|
}),
|
|
},
|
|
async handler(req) {
|
|
// const object = knex('object').first('*').where('id', req.params.id)
|
|
|
|
// if (!object) throw new StatusError(404)
|
|
console.log(req.params.id)
|
|
|
|
return knex('transaction AS t')
|
|
.select('e.transactionDate', 't.accountNumber', 't.amount')
|
|
.innerJoin('transactions_to_objects AS to', function () {
|
|
this.on('t.id', 'to.transactionId')
|
|
})
|
|
.innerJoin('entry AS e', function () {
|
|
this.on('e.id', '=', 't.entryId')
|
|
})
|
|
.where('to.objectId', req.params.id)
|
|
},
|
|
})
|
|
|
|
fastify.route({
|
|
url: '/results',
|
|
method: 'GET',
|
|
async handler() {
|
|
const years = await knex('financialYear').select('*')
|
|
|
|
const accounts = await knex('account').select('*')
|
|
|
|
return Promise.all(
|
|
years.map((year) =>
|
|
knex('account AS a')
|
|
.select('a.number', 'a.description')
|
|
.sum('t.amount as amount')
|
|
.innerJoin('transaction AS t', function () {
|
|
this.on('t.accountNumber', '=', 'a.number')
|
|
})
|
|
.innerJoin('entry AS e', function () {
|
|
this.on('t.entryId', '=', 'e.id')
|
|
})
|
|
.groupBy('a.number', 'a.description')
|
|
.where('a.number', '>=', 3000)
|
|
.where('e.financialYearId', year.id)
|
|
.orderBy('a.number')
|
|
.then((result) => ({
|
|
startDate: year.startDate,
|
|
endDate: year.endDate,
|
|
result,
|
|
})),
|
|
),
|
|
).then((years) => ({
|
|
accounts,
|
|
years,
|
|
}))
|
|
},
|
|
})
|
|
|
|
fastify.route({
|
|
url: '/results/: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) return null
|
|
|
|
return knex('transaction AS t')
|
|
.select('t.accountNumber', 'a.description')
|
|
.sum('t.amount as amount')
|
|
.innerJoin('account AS a', function () {
|
|
this.on('t.accountNumber', '=', 'a.number')
|
|
})
|
|
.innerJoin('entry AS e', function () {
|
|
this.on('t.entryId', '=', 'e.id')
|
|
})
|
|
.groupBy('t.accountNumber', 'a.description')
|
|
.where('t.accountNumber', '>=', 3000)
|
|
.where('e.financialYearId', year.id)
|
|
.orderBy('t.accountNumber')
|
|
},
|
|
})
|
|
|
|
fastify.route({
|
|
url: '/suppliers',
|
|
method: 'GET',
|
|
async handler(req) {
|
|
return knex('supplier').select('*').orderBy('name')
|
|
},
|
|
})
|
|
|
|
fastify.route({
|
|
url: '/suppliers/:id',
|
|
method: 'GET',
|
|
schema: {
|
|
params: Type.Object({
|
|
id: Type.Number(),
|
|
}),
|
|
},
|
|
async handler(req) {
|
|
return knex('supplier').first('*').where('id', req.params.id)
|
|
},
|
|
})
|
|
|
|
done()
|
|
}
|
|
|
|
export default apiRoutes
|