diff --git a/.bruno/BRF/api-accounts.bru b/.bruno/BRF/api-accounts.bru index ae4a888..620c1dd 100644 --- a/.bruno/BRF/api-accounts.bru +++ b/.bruno/BRF/api-accounts.bru @@ -1,7 +1,7 @@ meta { name: /api/accounts type: http - seq: 9 + seq: 2 } get { @@ -12,4 +12,5 @@ get { settings { encodeUrl: true + timeout: 0 } diff --git a/.bruno/BRF/api-entries.bru b/.bruno/BRF/api-entries.bru new file mode 100644 index 0000000..fd198f2 --- /dev/null +++ b/.bruno/BRF/api-entries.bru @@ -0,0 +1,21 @@ +meta { + name: /api/entries + type: http + seq: 3 +} + +get { + url: {{base_url}}/api/entries?year=2015&journal=A + body: none + auth: inherit +} + +params:query { + year: 2015 + journal: A +} + +settings { + encodeUrl: true + timeout: 0 +} diff --git a/.bruno/BRF/Financial Years.bru b/.bruno/BRF/api-financial-years.bru similarity index 79% rename from .bruno/BRF/Financial Years.bru rename to .bruno/BRF/api-financial-years.bru index 78fd030..991dd5b 100644 --- a/.bruno/BRF/Financial Years.bru +++ b/.bruno/BRF/api-financial-years.bru @@ -1,7 +1,7 @@ meta { - name: Financial Years + name: /api/financial-years type: http - seq: 2 + seq: 4 } get { diff --git a/.bruno/BRF/api-invoice--id.bru b/.bruno/BRF/api-invoice--id.bru deleted file mode 100644 index fbe4975..0000000 --- a/.bruno/BRF/api-invoice--id.bru +++ /dev/null @@ -1,20 +0,0 @@ -meta { - name: /api/invoice/:id - type: http - seq: 7 -} - -get { - url: {{base_url}}/api/invoices/:id - body: none - auth: inherit -} - -params:path { - id: 234 -} - -settings { - encodeUrl: true - timeout: 0 -} diff --git a/.bruno/BRF/api-invoices--id.bru b/.bruno/BRF/api-invoices--id.bru new file mode 100644 index 0000000..4890c9c --- /dev/null +++ b/.bruno/BRF/api-invoices--id.bru @@ -0,0 +1,16 @@ +meta { + name: /api/invoices/:id + type: http + seq: 8 +} + +get { + url: {{base_url}}/api/invoices/2631 + body: none + auth: inherit +} + +settings { + encodeUrl: true + timeout: 0 +} diff --git a/.bruno/BRF/Invoices.bru b/.bruno/BRF/api-invoices.bru similarity index 73% rename from .bruno/BRF/Invoices.bru rename to .bruno/BRF/api-invoices.bru index 9b485d4..5d020b2 100644 --- a/.bruno/BRF/Invoices.bru +++ b/.bruno/BRF/api-invoices.bru @@ -1,7 +1,7 @@ meta { - name: Invoices + name: /api/invoices type: http - seq: 6 + seq: 7 } get { @@ -12,4 +12,5 @@ get { settings { encodeUrl: true + timeout: 0 } diff --git a/.bruno/BRF/Object.bru b/.bruno/BRF/api-objects--id.bru similarity index 80% rename from .bruno/BRF/Object.bru rename to .bruno/BRF/api-objects--id.bru index dbcfd84..8bbd0eb 100644 --- a/.bruno/BRF/Object.bru +++ b/.bruno/BRF/api-objects--id.bru @@ -1,7 +1,7 @@ meta { - name: Object + name: /api/objects/:id type: http - seq: 3 + seq: 5 } get { diff --git a/.bruno/BRF/Objects.bru b/.bruno/BRF/api-objects.bru similarity index 82% rename from .bruno/BRF/Objects.bru rename to .bruno/BRF/api-objects.bru index c7f9678..5e1900b 100644 --- a/.bruno/BRF/Objects.bru +++ b/.bruno/BRF/api-objects.bru @@ -1,7 +1,7 @@ meta { - name: Objects + name: /api/objects type: http - seq: 4 + seq: 6 } get { diff --git a/.bruno/BRF/Result.bru b/.bruno/BRF/api-results--year.bru similarity index 79% rename from .bruno/BRF/Result.bru rename to .bruno/BRF/api-results--year.bru index bf0cafa..5561b81 100644 --- a/.bruno/BRF/Result.bru +++ b/.bruno/BRF/api-results--year.bru @@ -1,7 +1,7 @@ meta { - name: Result + name: /api/results/:year type: http - seq: 5 + seq: 11 } get { diff --git a/.bruno/BRF/Results.bru b/.bruno/BRF/api-results.bru similarity index 81% rename from .bruno/BRF/Results.bru rename to .bruno/BRF/api-results.bru index c5c2f6a..652bc37 100644 --- a/.bruno/BRF/Results.bru +++ b/.bruno/BRF/api-results.bru @@ -1,7 +1,7 @@ meta { - name: Results + name: /api/results type: http - seq: 6 + seq: 10 } get { diff --git a/.bruno/BRF/api-suppliers.bru b/.bruno/BRF/api-suppliers.bru index 19ce449..222eb98 100644 --- a/.bruno/BRF/api-suppliers.bru +++ b/.bruno/BRF/api-suppliers.bru @@ -1,7 +1,7 @@ meta { name: /api/suppliers type: http - seq: 8 + seq: 9 } get { @@ -12,4 +12,5 @@ get { settings { encodeUrl: true + timeout: 0 } diff --git a/server/routes/api.ts b/server/routes/api.ts index 6762839..e904576 100644 --- a/server/routes/api.ts +++ b/server/routes/api.ts @@ -1,10 +1,14 @@ 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' import accounts from './api/accounts.ts' +import entries from './api/entries.ts' +import financialYears from './api/financial_years.ts' import invoices from './api/invoices.ts' +import journals from './api/journals.ts' +import objects from './api/objects.ts' +import results from './api/results.ts' export const FinancialYear = Type.Object({ year: Type.Number(), @@ -16,139 +20,12 @@ export type FinancialYearType = Static const apiRoutes: FastifyPluginCallbackTypebox = (fastify, _, done) => { fastify.register(accounts, { prefix: '/accounts' }) + fastify.register(entries, { prefix: '/entries' }) + fastify.register(financialYears, { prefix: '/financial-years' }) fastify.register(invoices, { prefix: '/invoices' }) - - fastify.route({ - url: '/financial-years', - method: 'GET', - handler() { - return knex('financialYear').select('*') - }, - }) - - 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) - }, - }) + fastify.register(journals, { prefix: '/journals' }) + fastify.register(objects, { prefix: '/objects' }) + fastify.register(results, { prefix: '/results' }) done() } diff --git a/server/routes/api/accounts.ts b/server/routes/api/accounts.ts index ca66b6a..584234a 100644 --- a/server/routes/api/accounts.ts +++ b/server/routes/api/accounts.ts @@ -2,7 +2,7 @@ import _ from 'lodash' import { Type, type Static, type FastifyPluginCallbackTypebox } from '@fastify/type-provider-typebox' import knex from '../../lib/knex.ts' -const apiRoutes: FastifyPluginCallbackTypebox = (fastify, _, done) => { +const accountRoutes: FastifyPluginCallbackTypebox = (fastify, _, done) => { fastify.route({ url: '/', method: 'GET', @@ -14,4 +14,4 @@ const apiRoutes: FastifyPluginCallbackTypebox = (fastify, _, done) => { done() } -export default apiRoutes +export default accountRoutes diff --git a/server/routes/api/entries.ts b/server/routes/api/entries.ts new file mode 100644 index 0000000..78f802a --- /dev/null +++ b/server/routes/api/entries.ts @@ -0,0 +1,30 @@ +import _ from 'lodash' +import { Type, type Static, type FastifyPluginCallbackTypebox } from '@fastify/type-provider-typebox' +import knex from '../../lib/knex.ts' + +const entryRoutes: FastifyPluginCallbackTypebox = (fastify, _, done) => { + fastify.route({ + url: '/', + method: 'GET', + schema: { + querystring: Type.Object({ + journal: Type.String(), + year: Type.Number(), + }), + }, + async handler(req) { + const financialYearId = (await knex('financialYear').first('id').where('year', req.query.year))?.id + const journalId = (await knex('journal').first('id').where('identifier', req.query.journal))?.id + + if (!financialYearId || !journalId) { + return null + } + + return knex('entry').select('*').orderBy('entryDate').where({ financialYearId, journalId }) + }, + }) + + done() +} + +export default entryRoutes diff --git a/server/routes/api/financial_years.ts b/server/routes/api/financial_years.ts new file mode 100644 index 0000000..ee30a0a --- /dev/null +++ b/server/routes/api/financial_years.ts @@ -0,0 +1,17 @@ +import _ from 'lodash' +import { Type, type Static, type FastifyPluginCallbackTypebox } from '@fastify/type-provider-typebox' +import knex from '../../lib/knex.ts' + +const financialYearRoutes: FastifyPluginCallbackTypebox = (fastify, _, done) => { + fastify.route({ + url: '/', + method: 'GET', + handler() { + return knex('financialYear').select('*') + }, + }) + + done() +} + +export default financialYearRoutes diff --git a/server/routes/api/invoices.ts b/server/routes/api/invoices.ts index 722d40b..95f7c8f 100644 --- a/server/routes/api/invoices.ts +++ b/server/routes/api/invoices.ts @@ -3,7 +3,7 @@ import { Type, type FastifyPluginCallbackTypebox } from '@fastify/type-provider- import knex from '../../lib/knex.ts' import StatusError from '../../lib/status_error.ts' -const apiRoutes: FastifyPluginCallbackTypebox = (fastify, _, done) => { +const invoiceRoutes: FastifyPluginCallbackTypebox = (fastify, _, done) => { fastify.route({ url: '/', method: 'GET', @@ -124,4 +124,4 @@ const apiRoutes: FastifyPluginCallbackTypebox = (fastify, _, done) => { done() } -export default apiRoutes +export default invoiceRoutes diff --git a/server/routes/api/journals.ts b/server/routes/api/journals.ts new file mode 100644 index 0000000..365e269 --- /dev/null +++ b/server/routes/api/journals.ts @@ -0,0 +1,17 @@ +import _ from 'lodash' +import { Type, type Static, type FastifyPluginCallbackTypebox } from '@fastify/type-provider-typebox' +import knex from '../../lib/knex.ts' + +const journalRoutes: FastifyPluginCallbackTypebox = (fastify, _, done) => { + fastify.route({ + url: '/', + method: 'GET', + handler() { + return knex('journal').select('*').orderBy('identifier') + }, + }) + + done() +} + +export default journalRoutes diff --git a/server/routes/api/objects.ts b/server/routes/api/objects.ts new file mode 100644 index 0000000..ba10bc8 --- /dev/null +++ b/server/routes/api/objects.ts @@ -0,0 +1,42 @@ +import _ from 'lodash' +import { Type, type Static, type FastifyPluginCallbackTypebox } from '@fastify/type-provider-typebox' +import knex from '../../lib/knex.ts' + +const objectRoutes: FastifyPluginCallbackTypebox = (fastify, _, done) => { + fastify.route({ + url: '/', + 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: '/:id', + method: 'GET', + schema: { + params: Type.Object({ + id: Type.Number(), + }), + }, + async handler(req) { + 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) + }, + }) + + done() +} + +export default objectRoutes diff --git a/server/routes/api/results.ts b/server/routes/api/results.ts new file mode 100644 index 0000000..cc26626 --- /dev/null +++ b/server/routes/api/results.ts @@ -0,0 +1,74 @@ +import _ from 'lodash' +import { Type, type Static, type FastifyPluginCallbackTypebox } from '@fastify/type-provider-typebox' +import knex from '../../lib/knex.ts' + +const resultRoutes: FastifyPluginCallbackTypebox = (fastify, _, done) => { + fastify.route({ + url: '/', + 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: '/: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') + }, + }) + + done() +} + +export default resultRoutes diff --git a/server/routes/api/suppliers.ts b/server/routes/api/suppliers.ts new file mode 100644 index 0000000..4ce45ba --- /dev/null +++ b/server/routes/api/suppliers.ts @@ -0,0 +1,30 @@ +import _ from 'lodash' +import { Type, type Static, type FastifyPluginCallbackTypebox } from '@fastify/type-provider-typebox' +import knex from '../../lib/knex.ts' + +const journalRoutes: FastifyPluginCallbackTypebox = (fastify, _, done) => { + fastify.route({ + url: '/', + method: 'GET', + async handler(req) { + return knex('supplier').select('*').orderBy('name') + }, + }) + + fastify.route({ + url: '/: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 journalRoutes