Skip to content

Commit

Permalink
Merge pull request #7 from gdsc-kaist/feature/transaction_pagination
Browse files Browse the repository at this point in the history
Enable pagination with sorting
  • Loading branch information
Byunk authored Nov 12, 2023
2 parents 008232f + e6c49ab commit d00e543
Show file tree
Hide file tree
Showing 3 changed files with 150 additions and 3 deletions.
52 changes: 49 additions & 3 deletions src/routes/transaction.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,59 @@

import express from 'express';
import { Transaction } from '../model';
import { sequelize } from '../db';
import { QueryTypes } from 'sequelize';

const router = express.Router();

router.get('/', async (req, res, next) => {
router.get('/:organization_id/:year/:half', async (req, res, next) => {
try {
const transactions = await Transaction.findAll();
res.json(transactions.map((transaction) => transaction.toJSON()));
const page = parseInt(req.query.page as string);
const limit = 20;
const startIndex = (page - 1) * limit;
const endIndex = page * limit;

const schema_name = process.env.NODE_ENV || 'development';
const transaction_table = schema_name + '."transactions"';
const income_table = schema_name + '."incomes"';
const expense_table = schema_name + '."expenses"';
const budget_table = schema_name + '."budgets"';
const transactions = await sequelize.query(
`SELECT *
FROM
(
SELECT T."id", T."projectAt", T."manager", T."content", T."type", T."amount", T."transactionAt", T."accountNumber", T."accountBank", T."accountOwner", T."hasBill", T."note", T."IncomeId", T."ExpenseId", I."code"
FROM ${income_table} AS I
INNER JOIN ${transaction_table} AS T
ON I.id = T."IncomeId"
WHERE I."BudgetId" IN (
SELECT id
FROM ${budget_table}
WHERE "OrganizationId" = ${req.params.organization_id}
AND "year" = '${req.params.year}' AND "half" = '${req.params.half}'
)
) as TIE
UNION ALL
(
SELECT T."id", T."projectAt", T."manager", T."content", T."type", T."amount", T."transactionAt", T."accountNumber", T."accountBank", T."accountOwner", T."hasBill", T."note", T."IncomeId", T."ExpenseId", E."code"
FROM ${expense_table} AS E
INNER JOIN ${transaction_table} AS T
ON E.id = T."ExpenseId"
WHERE "BudgetId" IN (
SELECT id
FROM ${budget_table}
WHERE "OrganizationId" = ${req.params.organization_id}
AND "year" = '${req.params.year}' AND "half" = '${req.params.half}'
)
)
ORDER BY "transactionAt" DESC`,
{
type: QueryTypes.SELECT,
},
);

const transaction1page = transactions.slice(startIndex, endIndex);
res.json(transaction1page);
} catch (error) {
next(error);
}
Expand Down
27 changes: 27 additions & 0 deletions swagger.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -877,6 +877,33 @@ paths:
get:
summary: 모든 통장거래내역 조회
tags: [통장거래내역]
parameters:
- name: organization_id
in: path
description: 피감기구 id
required: true
schema:
type: integer
format: int32
example: 1
- name: year
in: path
description: 연도
required: true
schema:
type: integer
format: int32
example: 2023
- name: half
in: path
description: 반기
required: true
schema:
type: string
enum:
- spring
- fall
example: spring
responses:
'200':
description: Successfully retrieved transactions
Expand Down
74 changes: 74 additions & 0 deletions test/routes/transaction.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
import chaiHttp from 'chai-http';
import app from '../../src/app';
import chai, { expect } from 'chai';
import { initDB } from '../../src/db/util';
import sinon from 'sinon';
import { Budget, Income, Organization, Transaction } from '../../src/model';

chai.use(chaiHttp);

describe('transaction router', () => {
before(async function () {
await initDB();
});

describe('GET /', () => {
it('should return all transactions', async () => {
const organization = await Organization.create({
name: '학부총학생회',
});

const budget = await Budget.create({
year: 2021,
half: 'spring',
manager: '김넙죽',
OrganizationId: organization.id,
});

const income = await Income.create({
code: '101',
source: '학생회비',
category: '중앙회계',
content: '예산',
amount: 10000,
BudgetId: budget.id,
});

const dates = [];
const t = new Date('2021-01-01:00:00:00');
for (var i = 0; i < 30; i++) {
t.setDate(t.getDate() + 1);
dates.push(new Date(t));
await Transaction.create({
projectAt: t,
manager: '김넙죽',
content: '테스트',
type: '공금카드',
amount: 10000,
transactionAt: t,
accountNumber: '1234567890',
accountBank: '우리은행',
accountOwner: '김넙죽',
hasBill: false,
IncomeId: income.id,
});
}

const expected_dates = dates
.sort((a, b) => b.getTime() - a.getTime())
.map((date) => date.toISOString())
.slice(20, 30);

const res = await chai
.request(app)
.get(`/transactions/${organization.id}/2021/spring?page=2`);
expect(res).to.have.status(200);
expect(res.body).to.be.an('array');

const actual_dates = res.body.map(
(transaction: any) => transaction.transactionAt,
);
expect(actual_dates).eql(expected_dates);
});
});
});

0 comments on commit d00e543

Please sign in to comment.