Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[50기 홍영기 - ADD : 각 항목별 이달의 지출 조회 기능] #2

Open
wants to merge 13 commits into
base: main
Choose a base branch
from
30 changes: 30 additions & 0 deletions app.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
const http = require('http');
const express = require('express');
const cors = require('cors');
const dotenv = require('dotenv');
const routes = require('./src/routes');
const app = express()

dotenv.config()
app.use(cors())
app.use(express.json())
app.use(routes)

app.get('/ping',(req,res) => {
res.status(200).json({
message: 'pong'
})
})

const server = http.createServer(app)

const start = async () => {
try {
server.listen(process.env.TYPEORM_SERVER_PORT, () => console.log(
`Server is listening on ${process.env.TYPEORM_SERVER_PORT}`))
} catch (err) {
console.error(err)
}
}

start()
25 changes: 25 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
{
"name": "50-3rd-fin_pong-backend",
"version": "1.0.0",
"description": "",
"main": "app.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "",
"license": "ISC",
"dependencies": {
"bcrypt": "^5.1.1",
"cors": "^2.8.5",
"dotenv": "^16.3.1",
"express": "^4.18.2",
"http": "^0.0.1-security",
"jsonwebtoken": "^9.0.2",
"morgan": "^1.10.0",
"mysql2": "^3.6.3",
"nodemon": "^3.0.1",
"npm": "^10.2.3",
"typeorm": "^0.3.17"
}
}
60 changes: 60 additions & 0 deletions src/controllers/settingController.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
const settingServices = require('../services/settingService')

const viewMonthFamily = async(req, res) => {
try{
const year = new Date().getFullYear()
const familyId = 1
const result = await settingServices.viewMonthFamily( familyId, year )
res.status(200).json( result )
}catch(err){
console.log(err)
res.status(err.statusCode || 500).json({message : err.message})
}
}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
const viewMonthFamily = async(req, res) => {
try{
const year = new Date().getFullYear()
const familyId = 1
const result = await settingServices.viewMonthFamily( familyId, year )
res.status(200).json( result )
}catch(err){
console.log(err)
res.status(err.statusCode || 500).json({message : err.message})
}
}
const getMoneyFlowStatistics = async(req, res) => {
try {
const type = req.query.type
const period = req.query.period
const year = new Date().getFullYear()
const familyId = 1
const result = await settingServices.getMoneyFlowStatistics( type, period, userId, familyId)
res.status(200).json( result )
}catch(err){
console.log(err)
res.status(err.statusCode || 500).json({message : err.message})
}
}


const viewMonthPrivate = async(req, res) => {
try{
const year = new Date().getFullYear()
const userId = 1
const result = await settingServices.viewMonthPrivate( userId, year )
res.json(result)
}catch(err){
console.log(err)
res.status(err.statusCode || 500).json({message : err.message})
}
}

const viewCategoryFamily = async(req, res) => {
try{
const year = new Date().getFullYear()
const month = new Date().getMonth()+1
const date = year + '-' + month
const familyId = 1
const result = await settingServices.viewCategoryFamily( familyId, date )
res.json(result)
}catch(err){
console.log(err)
res.status(err.statusCode || 500).json({message : err.message})
}
}

const viewCategoryPrivate = async(req, res) => {
try{
const year = new Date().getFullYear()
const month = new Date().getMonth()+1
const date = year + '-' + month
const userId = 1
const result = await settingServices.viewCategoryPrivate( userId, date )
res.json(result)
}catch(err){
console.log(err)
res.status(err.statusCode || 500).json({message : err.message})
}
}

module.exports = {
viewMonthFamily,
viewMonthPrivate,
viewCategoryFamily,
viewCategoryPrivate,
}
18 changes: 18 additions & 0 deletions src/middlewares/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
const jwt = require('jsonwebtoken')
const dotenv = require('dotenv')
dotenv.config()

const makeToken = async( userId ) => {
return jwt.sign({id:userId},process.env.TYPEORM_SECRETKEY,{expiresIn:60*60})
}

const verifyToken = async( token ) => {
try{
return jwt.verify(token, process.env.TYPEORM_SECRETKEY)
}catch(err){
err.statusCode = 400
res.status(err.statusCode ).json({message : 'TOKEN_BROKEN'})
}
}

module.exports = { makeToken, verifyToken }
143 changes: 143 additions & 0 deletions src/models/settingDao.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
const { appDataSource } = require('../utils/dataSource')

const viewMonthFamily = async( familyId, year ) => {
const monthlyIncome = await appDataSource.query(`
SELECT family_id, month, budget AS income FROM budget
WHERE family_id = ? AND year = ?
ORDER BY month ASC;
`, [ familyId, year ])
const monthlySpending = await appDataSource.query(`
SELECT uf.family_id, month, sum(amount) AS spending FROM money_flows mf
JOIN users_families uf ON mf.user_id = uf.user_id
WHERE mf.flow_type_id = 2 AND uf.family_id = ? AND mf.year = ?
GROUP BY month
ORDER BY month ASC;
`, [ familyId, year ])
const monthIndex = [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
let incomeTable = {}
for (let i = 0; i < monthIndex.length; i++) {
incomeTable[monthIndex[i] + '월'] = 0
}
for(i=0;i<monthlyIncome.length;i++){
incomeTable[monthlyIncome[i].month + '월'] = Number( monthlyIncome[i].income )
}
let spendingTable = {}
for (let i = 0; i < monthIndex.length; i++) {
spendingTable[monthIndex[i] + '월'] = 0
}
for(i=0;i<monthlySpending.length;i++){
spendingTable[monthlySpending[i].month + '월'] = Number( monthlySpending[i].spending )
}
return { '수입' : incomeTable, '지출' : spendingTable }
}

const viewMonthPrivate = async( userId, year ) => {
const monthlyIncome = await appDataSource.query(`
SELECT user_id, month, amount AS income FROM allowances
WHERE user_id = ? AND year = ?
ORDER BY month ASC;
`, [ userId, year ])

const monthlySpending = await appDataSource.query(`
SELECT uf.user_id, month, sum(amount) AS spending FROM money_flows mf
JOIN users_families uf ON mf.user_id = uf.user_id
WHERE mf.flow_type_id = 2 AND uf.user_id = ? AND mf.year = ?
GROUP BY month
ORDER BY month ASC;
`, [ userId, year ])
const monthIndex = [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
let incomeTable = {}
for (let i = 0; i < monthIndex.length; i++) {
incomeTable[monthIndex[i] + '월'] = 0
}
for(i=0;i<monthlyIncome.length;i++){
incomeTable[monthlyIncome[i].month + '월'] = Number( monthlyIncome[i].income )
}
let spendingTable = {}
for (let i = 0; i < monthIndex.length; i++) {
spendingTable[monthIndex[i] + '월'] = 0
}
for(i=0;i<monthlySpending.length;i++){
spendingTable[monthlySpending[i].month + '월'] = Number( monthlySpending[i].spending )
}
return { '수입' : incomeTable, '지출' : spendingTable }
}

const viewCategoryFamily = async( familyId, date ) => {
const year = date.substr(0,4)
const month = date.substr(5)
const result = await appDataSource.query(`
SELECT uf.family_id, c.category, sum(amount) AS spending FROM money_flows mf
JOIN users_families uf ON uf.user_id = mf.user_id
JOIN categories c ON mf.category_id = c.id
WHERE uf.family_id = ? AND mf.year = ?
AND mf.month = ?
AND mf.flow_type_id = 2
GROUP BY c.category
ORDER BY mf.month ASC;
`, [ familyId, year, month ])
const category = await appDataSource.query(`
SELECT * FROM categories;
`)
for (j=0; j<result.length; j++){
for (i=0; i<category.length; i++){
if(category[i].category===result[j].category){
category[i].spending = Number(result[j].spending)
}
}
}
for (i=0; i<category.length; i++){
if(!category[i].spending){category[i].spending = 0}
}
let max = 0
for (i=0; i<category.length; i++){
max = max + Number(category[i].spending)}

for (i=0; i<category.length; i++){
category[i].spending = Math.round(category[i].spending*100 / max ) + '%'
}
return category

}

const viewCategoryPrivate = async( userId, date ) => {
const year = date.substr(0,4)
const month = date.substr(5)
const result = await appDataSource.query(`
SELECT mf.user_id, c.category, sum(amount) AS spending FROM money_flows mf
JOIN categories c on mf.category_id = c.id
WHERE user_id = ? AND mf.year = ?
AND mf.month = ?
AND mf.flow_type_id = 2
GROUP BY c.category
ORDER BY mf.month asc;
`, [ userId, year, month ])
const category = await appDataSource.query(`
SELECT * FROM categories;
`)
for (j=0; j<result.length; j++){
for (i=0; i<category.length; i++){
if(category[i].category===result[j].category){
category[i].spending = Number(result[j].spending)
}
}
}
for (i=0; i<category.length; i++){
if(!category[i].spending){category[i].spending = 0}
}
let max = 0
for (i=0; i<category.length; i++){
max = max + Number(category[i].spending)}

for (i=0; i<category.length; i++){
category[i].spending = Math.round(category[i].spending*100 / max ) + '%'
}
return category
}

module.exports = {
viewMonthFamily,
viewMonthPrivate,
viewCategoryFamily,
viewCategoryPrivate,
}
9 changes: 9 additions & 0 deletions src/routes/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
const express = require('express');
const router = express.Router();
// const middleware = require('../middlewares/index')

const settingRouter = require('./settingRouter')

router.use('/setting', settingRouter.router)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
router.use('/setting', settingRouter.router)
router.use('/flows', moneyFlowRouter.router)


module.exports = router;
13 changes: 13 additions & 0 deletions src/routes/settingRouter.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
const express = require('express');
const settingController = require('../controllers/settingController');

const router = express.Router();

router.get('/month/family/', settingController.viewMonthFamily );
router.get('/month/private/', settingController.viewMonthPrivate );

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
router.get('/month/family/', settingController.viewMonthFamily );
router.get('/month/private/', settingController.viewMonthPrivate );
router.get('/statistics', settingController.getMoneyFlowStatistics );

router.get('/category/family/', settingController.viewCategoryFamily );
router.get('/category/private/', settingController.viewCategoryPrivate );

module.exports = {
router,
};
24 changes: 24 additions & 0 deletions src/services/settingService.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
const settingDao = require('../models/settingDao')

const viewMonthFamily = async( familyId, year ) => {
return await settingDao.viewMonthFamily( familyId, year )
}

const viewMonthPrivate = async( userId, year ) => {
return await settingDao.viewMonthPrivate( userId, year )
}

const viewCategoryFamily = async( familyId, date ) => {
return await settingDao.viewCategoryFamily( familyId, date )
}

const viewCategoryPrivate = async( userId, date ) => {
return await settingDao.viewCategoryPrivate( userId, date )
}

module.exports = {
viewMonthFamily,
viewMonthPrivate,
viewCategoryFamily,
viewCategoryPrivate,
}
22 changes: 22 additions & 0 deletions src/utils/dataSource.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
const {DataSource} = require('typeorm');
const dotenv = require('dotenv')
dotenv.config()

const appDataSource = new DataSource({
type : process.env.TYPEORM_CONNECTION,
host: process.env.TYPEORM_HOST,
port: process.env.TYPEORM_PORT,
username: process.env.TYPEORM_USERNAME,
password: process.env.TYPEORM_PASSWORD,
database: process.env.TYPEORM_DATABASE
})

appDataSource.initialize()
.then(() => {
console.log('Data Source has been initialized!')
})
.catch((err) => {
console.error('Error occured during Data Source initialization', err)
})

module.exports = { appDataSource }