diff --git a/src/controllers/expense.controller.js b/src/controllers/expense.controller.js new file mode 100644 index 00000000..fce1ee20 --- /dev/null +++ b/src/controllers/expense.controller.js @@ -0,0 +1,113 @@ +'use strict'; + +const expenseService = require('../services/expense.service'); +const usersService = require('../services/user.service'); + +const getAll = async(req, res) => { + const { categories, userId, from, to } = req.query; + + const expenses = await expenseService.get({ + categories, + userId, + from, + to, + }); + + res.send(expenses); +}; + +const getOne = async(req, res) => { + const id = parseInt(req.params.id); + + if (isNaN(id)) { + res.sendStatus(400); + + return; + } + + const expense = await expenseService.getById(id); + + if (!expense) { + res.sendStatus(404); + + return; + } + + res.send(expense); +}; + +const create = async(req, res) => { + const { + userId, + spentAt, + title, + amount, + category, + note, + } = req.body; + + const user = await usersService.getById(userId); + + if (!user) { + res.sendStatus(400); + + return; + } + + if (!userId || !title || !spentAt || !amount) { + res.sendStatus(400); + + return; + } + + const expense = await expenseService.create({ + userId: user.id, + spentAt, + title, + amount, + category, + note, + }); + + res.statusCode = 201; + res.send(expense); +}; + +const update = async(req, res) => { + const { id } = req.params; + const body = req.body; + const expense = await expenseService.getById(+id); + + if (!expense) { + res.sendStatus(404); + + return; + } + + await expenseService.update(+id, body); + + res.send(await expenseService.getById(+id)); +}; + +const remove = async(req, res) => { + const { id } = req.params; + const expense = await expenseService.getById(+id); + + if (!expense) { + res.sendStatus(404); + + return; + } + + await expenseService.remove(expense.id); + + res.sendStatus(204); +}; + +module.exports = { + getAll, + getOne, + create, + update, + remove, +}; diff --git a/src/controllers/user.controller.js b/src/controllers/user.controller.js new file mode 100644 index 00000000..005cddbd --- /dev/null +++ b/src/controllers/user.controller.js @@ -0,0 +1,81 @@ +'use strict'; + +const usersService = require('../services/user.service'); + +const get = async(req, res) => { + res.send(await usersService.getAll()); +}; + +const getOne = async(req, res) => { + const id = parseInt(req.params.id); + const user = await usersService.getById(id); + + if (isNaN(id)) { + res.sendStatus(400); + + return; + } + + if (!user) { + res.sendStatus(404); + + return; + } + + res.send(user); +}; + +const create = async(req, res) => { + const { name } = req.body; + + if (!name || typeof name !== 'string') { + res.sendStatus(400); + + return; + } + + const user = await usersService.create(name); + + res.statusCode = 201; + res.send(user); +}; + +const update = async(req, res) => { + const { id } = req.params; + const { name } = req.body; + + const user = await usersService.getById(+id); + + if (!user) { + res.sendStatus(404); + + return; + } + + await usersService.update(+id, name); + + res.send(await usersService.getById(+id)); +}; + +const remove = async(req, res) => { + const { id } = req.params; + const user = await usersService.getById(+id); + + if (!user) { + res.sendStatus(404); + + return; + } + + await usersService.remove(user.id); + + res.sendStatus(204); +}; + +module.exports = { + get, + getOne, + create, + update, + remove, +}; diff --git a/src/createServer.js b/src/createServer.js index 1ea5542d..cf88ad5c 100644 --- a/src/createServer.js +++ b/src/createServer.js @@ -1,7 +1,16 @@ 'use strict'; +const express = require('express'); +const userRouter = require('./routes/user.route'); +const expenseRouter = require('./routes/expense.route'); + const createServer = () => { - // your code goes here + const app = express(); + + app.use('/users', userRouter); + app.use('/expenses', expenseRouter); + + return app; }; module.exports = { diff --git a/src/db.js b/src/db.js index 1ba3046c..d7738572 100644 --- a/src/db.js +++ b/src/db.js @@ -26,7 +26,7 @@ const sequelize = new Sequelize({ host: POSTGRES_HOST || 'localhost', dialect: 'postgres', port: POSTGRES_PORT || 5432, - password: POSTGRES_PASSWORD || '123', + password: POSTGRES_PASSWORD || '123456789', }); module.exports = { diff --git a/src/models/Expense.model.js b/src/models/Expense.model.js index 567e1c3e..c68e925c 100644 --- a/src/models/Expense.model.js +++ b/src/models/Expense.model.js @@ -1,9 +1,43 @@ 'use strict'; +const { DataTypes } = require('sequelize'); const { sequelize } = require('../db.js'); -const Expense = sequelize.define( - // your code goes here +const Expense = sequelize.define('Expense', { + id: { + type: DataTypes.INTEGER, + autoIncrement: true, + primaryKey: true, + }, + userId: { + type: DataTypes.INTEGER, + allowNull: false, + }, + spentAt: { + type: DataTypes.DATE, + allowNull: false, + }, + title: { + type: DataTypes.STRING, + allowNull: false, + }, + amount: { + type: DataTypes.INTEGER, + allowNull: false, + }, + category: { + type: DataTypes.STRING, + allowNull: true, + }, + note: { + type: DataTypes.STRING, + allowNull: true, + }, +}, { + tableName: 'expenses', + createdAt: false, + updatedAt: false, +} ); module.exports = { diff --git a/src/models/User.model.js b/src/models/User.model.js index 61861c9e..e3fe6d48 100644 --- a/src/models/User.model.js +++ b/src/models/User.model.js @@ -1,10 +1,23 @@ 'use strict'; +const { DataTypes } = require('sequelize'); const { sequelize } = require('../db.js'); -const User = sequelize.define( - // your code goes here -); +const User = sequelize.define('User', { + id: { + type: DataTypes.INTEGER, + autoIncrement: true, + primaryKey: true, + }, + name: { + type: DataTypes.STRING, + allowNull: false, + }, +}, { + tableName: 'users', + createdAt: false, + updatedAt: false, +}); module.exports = { User, diff --git a/src/routes/expense.route.js b/src/routes/expense.route.js new file mode 100644 index 00000000..0cc93293 --- /dev/null +++ b/src/routes/expense.route.js @@ -0,0 +1,18 @@ +'use strict'; + +const express = require('express'); +const expensesContoller = require('../controllers/expense.controller'); + +const router = express.Router(); + +router.get('/', expensesContoller.getAll); + +router.post('/', express.json(), expensesContoller.create); + +router.get('/:id', expensesContoller.getOne); + +router.delete('/:id', expensesContoller.remove); + +router.patch('/:id', express.json(), expensesContoller.update); + +module.exports = router; diff --git a/src/routes/user.route.js b/src/routes/user.route.js new file mode 100644 index 00000000..7e07b9a0 --- /dev/null +++ b/src/routes/user.route.js @@ -0,0 +1,18 @@ +'use strict'; + +const express = require('express'); +const usersContoller = require('../controllers/user.controller'); + +const router = express.Router(); + +router.get('/', usersContoller.get); + +router.post('/', express.json(), usersContoller.create); + +router.get('/:id', usersContoller.getOne); + +router.delete('/:id', usersContoller.remove); + +router.patch('/:id', express.json(), usersContoller.update); + +module.exports = router; diff --git a/src/services/expense.service.js b/src/services/expense.service.js new file mode 100644 index 00000000..0e0bcc58 --- /dev/null +++ b/src/services/expense.service.js @@ -0,0 +1,68 @@ +'use strict'; + +const { Op } = require('sequelize'); +const { Expense } = require('../models/Expense.model'); + +const get = async({ userId, categories, from, to }) => { + try { + const whereClause = {}; + + if (userId) { + whereClause.userId = userId; + } + + if (categories) { + whereClause.category = categories; + } + + if (from && to) { + whereClause.spentAt = { + [Op.between]: [new Date(from), new Date(to)], + }; + } + + const filteredExpenses = await Expense.findAll({ + where: whereClause, + }); + + return filteredExpenses; + } catch (error) { + throw error; + } +}; + +const getById = async(id) => { + const expense = await Expense.findByPk(id); + + return expense; +}; + +const create = async(fields) => { + const newExpense = await Expense.create({ ...fields }); + + return newExpense; +}; + +const update = async(id, fields) => { + await Expense.update({ ...fields }, { + where: { + id, + }, + }); +}; + +const remove = async(id) => { + await Expense.destroy({ + where: { + id, + }, + }); +}; + +module.exports = { + get, + getById, + create, + update, + remove, +}; diff --git a/src/services/user.service.js b/src/services/user.service.js new file mode 100644 index 00000000..7c0ea869 --- /dev/null +++ b/src/services/user.service.js @@ -0,0 +1,45 @@ +'use strict'; + +const { User } = require('../models/User.model'); + +const getAll = async() => { + const users = await User.findAll(); + + return users; +}; + +const getById = async(id) => { + const user = await User.findByPk(id); + + return user; +}; + +const create = async(name) => { + const newUser = await User.create({ name }); + + return newUser; +}; + +const update = async(id, name) => { + await User.update({ name }, { + where: { + id, + }, + }); +}; + +const remove = async(id) => { + await User.destroy({ + where: { + id, + }, + }); +}; + +module.exports = { + getAll, + getById, + create, + update, + remove, +};