From 2e4f0034a0d5ea1c548349bd50d6b44b92b240ac Mon Sep 17 00:00:00 2001 From: Leonardo Silveira Date: Sat, 8 Jun 2024 17:15:21 -0300 Subject: [PATCH] =?UTF-8?q?implementando=20a=20transfer=C3=AAncia=20-=20RE?= =?UTF-8?q?D-85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../app/controllers/movimentacao.mjs | 45 +++--- service-node-koa/app/main.mjs | 131 +++++++++--------- .../app/services/movimentacao.mjs | 6 +- .../src/pages/pagamento/pagamento-page.vue | 22 +-- .../pages/pagamento/transferencia-form.vue | 15 +- web-app-vue/src/services/api.js | 31 +++-- web-app-vue/src/stores/movimentacaoStore.js | 10 +- 7 files changed, 143 insertions(+), 117 deletions(-) diff --git a/service-node-koa/app/controllers/movimentacao.mjs b/service-node-koa/app/controllers/movimentacao.mjs index 9adf954..e0cc4e2 100644 --- a/service-node-koa/app/controllers/movimentacao.mjs +++ b/service-node-koa/app/controllers/movimentacao.mjs @@ -1,51 +1,51 @@ import { - downloadMovimentacoes, + downloadMovimentacoes, findConta, findMovimentacao, insertMovimentacao, listMovimentacaoByConta, listMovimentacaoByUsuario, - removeMovimentacao, + removeMovimentacao, transferencia, updateMovimentacao, uploadMovimentacoes } from '../services/index.mjs' export const listMovimentacaoRequest = async ctx => { - const {usuario_id} = ctx.request.params + const { usuario_id } = ctx.request.params // TODO validar - const params = {...ctx.request.query, usuario_id} + const params = { ...ctx.request.query, usuario_id } if (ctx.request.query.conta_id) ctx.body = await listMovimentacaoByConta(params) else ctx.body = await listMovimentacaoByUsuario(params) } export const findMovimentacaoRequest = async ctx => { - const {/*usuario_id, conta_id,*/ id} = ctx.request.params + const {/*usuario_id, conta_id,*/ id } = ctx.request.params ctx.body = await findMovimentacao(id) } export const insertMovimentacaoRequest = async ctx => { - const {conta_id} = ctx.request.params + const { conta_id } = ctx.request.params const novaMovimentacao = ctx.request.body novaMovimentacao.conta_id = conta_id ctx.body = await insertMovimentacao(novaMovimentacao) } export const updateMovimentacaoRequest = async ctx => { - const {conta_id, id} = ctx.request.params + const { conta_id, id } = ctx.request.params const movimentacao = ctx.request.body movimentacao.alteracao = new Date() movimentacao.conta_id = conta_id movimentacao.id = id - ctx.body = await updateMovimentacao({id, movimentacao}) + ctx.body = await updateMovimentacao({ id, movimentacao }) } export const removeMovimentacaoRequest = async ctx => { - const {id} = ctx.request.params + const { id } = ctx.request.params ctx.body = await removeMovimentacao(id) } export const uploadMovimentacoesRequest = async ctx => { - const {usuario_id: id} = ctx.request.params - const {file} = ctx.request.body + const { usuario_id: id } = ctx.request.params + const { file } = ctx.request.body ctx.logger.info(`prepare to import data for user #${id}`) if (!file) throw new Error('csv file not found') const lines = file.split(/[\r\n]/).filter(l => l.length > 0) @@ -54,17 +54,28 @@ export const uploadMovimentacoesRequest = async ctx => { const header = lines.shift() if (header.split(/[,;]/).length < 7) throw new Error('Incorrect column count') ctx.logger.info('Proper column count. Start processing...') - const result = await uploadMovimentacoes({id, header, lines}) - ctx.body = {message: 'processed', result} + const result = await uploadMovimentacoes({ id, header, lines }) + ctx.body = { message: 'processed', result } } export const downloadMovimentacoesRequest = async ctx => { - const {usuario_id: id} = ctx.request.params - const {conta_id, data_inicio, data_fim} = ctx.request.query + const { usuario_id: id } = ctx.request.params + const { conta_id, data_inicio, data_fim } = ctx.request.query if (!conta_id) throw new Error('account not found') if (!data_inicio || !data_fim) throw new Error('must provide date interval (data_inicio/data_fim)') // if (!data_inicio.match(/\d{4}-\d{2}-\d{2}/)) throw new Error("invalid date format for data_inicio") // if (!data_fim.match(/\d{4}-\d{2}-\d{2}/)) throw new Error("invalid date format for data_fim") - const csv = await downloadMovimentacoes({id, conta_id, data_inicio, data_fim}) - ctx.body = {csv} + const csv = await downloadMovimentacoes({ id, conta_id, data_inicio, data_fim }) + ctx.body = { csv } +} + +export const transferenciaRequest = async ctx => { + const { usuario_id, conta_id: conta_origem_id, conta_destino_id } = ctx.request.params + const { valor, vencimento } = ctx.request.body + const origem = await findConta({ id: conta_origem_id, usuario_id }) + const destino = await findConta({ id: conta_destino_id, usuario_id }) + if (!origem) return ctx.throw(400, 'conta origem não encontrada') + if (!destino) return ctx.throw(400, 'conta destino não encontrada') + const result = await transferencia({ usuario_id, origem, destino, valor, vencimento }) + ctx.body = result } diff --git a/service-node-koa/app/main.mjs b/service-node-koa/app/main.mjs index 7d0cda0..06aa672 100644 --- a/service-node-koa/app/main.mjs +++ b/service-node-koa/app/main.mjs @@ -1,7 +1,7 @@ -import Koa from "koa"; -import cors from "@koa/cors"; -import Router from "@koa/router"; -import bodyParser from "koa-bodyparser"; +import Koa from 'koa' +import cors from '@koa/cors' +import Router from '@koa/router' +import bodyParser from 'koa-bodyparser' import { delCategoriaRequest, @@ -22,7 +22,7 @@ import { listMovimentacaoRequest, listPlanejamentoRequest, listRecorrenciaRequest, - removeMovimentacaoRequest, + removeMovimentacaoRequest, transferenciaRequest, updateCategoriaRequest, updateContaRequest, updateMovimentacaoRequest, @@ -31,87 +31,88 @@ import { userLoginRequest, userSignupRequest } from './controllers/index.mjs' -import {listModelocategoria, listTipoConta, listTipoMovimentacao, listTipoRecorrencia} from "./services/index.mjs"; -import {contaOwnedBy, ifAuthenticated} from "./config/security/index.mjs"; +import { listModelocategoria, listTipoConta, listTipoMovimentacao, listTipoRecorrencia } from './services/index.mjs' +import { contaOwnedBy, ifAuthenticated } from './config/security/index.mjs' -import ApiBuilder from "koa-api-builder"; -import {errHandler} from './config/default-error-handler.mjs' -import {cabin} from "./config/base-logging.mjs"; +import ApiBuilder from 'koa-api-builder' +import { errHandler } from './config/default-error-handler.mjs' +import { cabin } from './config/base-logging.mjs' -export const app = new Koa(); -const router = new Router(); +export const app = new Koa() +const router = new Router() -app.use(cabin.middleware).use(errHandler).use(cors()).use(bodyParser()); +app.use(cabin.middleware).use(errHandler).use(cors()).use(bodyParser()) -new ApiBuilder({router}).path(b => { - b.get("/status", async ctx => ctx.body = "ONLINE"); - b.get("/tipo-conta", async ctx => ctx.body = await listTipoConta()); - b.get("/modelocategoria", async ctx => ctx.body = await listModelocategoria()); - b.get("/tipo-recorrencia", async ctx => ctx.body = await listTipoRecorrencia()); - b.get("/tipo-movimentacao", async ctx => ctx.body = await listTipoMovimentacao()); +new ApiBuilder({ router }).path(b => { + b.get('/status', async ctx => ctx.body = 'ONLINE') + b.get('/tipo-conta', async ctx => ctx.body = await listTipoConta()) + b.get('/modelocategoria', async ctx => ctx.body = await listModelocategoria()) + b.get('/tipo-recorrencia', async ctx => ctx.body = await listTipoRecorrencia()) + b.get('/tipo-movimentacao', async ctx => ctx.body = await listTipoMovimentacao()) - b.post("/login", userLoginRequest); - b.post("/signup", userSignupRequest); + b.post('/login', userLoginRequest) + b.post('/signup', userSignupRequest) - b.path("/:usuario_id", ifAuthenticated, b => { - b.del("/removeAccount", delUsuarioRequest); + b.path('/:usuario_id', ifAuthenticated, b => { + b.del('/removeAccount', delUsuarioRequest) - b.path("/categoria", b => { - b.get(listCategoriasRequest); - b.post(insertCategoriaRequest); - b.path("/:id", b => { - b.get(findCategoriaRequest); - b.put(updateCategoriaRequest); - b.del(delCategoriaRequest); + b.path('/categoria', b => { + b.get(listCategoriasRequest) + b.post(insertCategoriaRequest) + b.path('/:id', b => { + b.get(findCategoriaRequest) + b.put(updateCategoriaRequest) + b.del(delCategoriaRequest) }) - }); + }) - b.path("/conta", b => { - b.get(listContasRequest); - b.post(insertContaRequest); - b.path("/:id", b => { - b.get(findContaRequest); - b.put(updateContaRequest); - b.del(delContaRequest); - }); - }); + b.path('/conta', b => { + b.get(listContasRequest) + b.post(insertContaRequest) + b.path('/:id', b => { + b.get(findContaRequest) + b.put(updateContaRequest) + b.del(delContaRequest) + }) + }) - b.path("/movimentacao", b => { - b.get(listMovimentacaoRequest); - b.get("/download", downloadMovimentacoesRequest); - b.post("/upload", uploadMovimentacoesRequest); - b.path("/:conta_id", contaOwnedBy, b => { - b.post(insertMovimentacaoRequest); - b.path("/:id", b => { - b.get(findMovimentacaoRequest); - b.put(updateMovimentacaoRequest); - b.del(removeMovimentacaoRequest); - }); - }); - }); + b.path('/movimentacao', b => { + b.get(listMovimentacaoRequest) + b.get('/download', downloadMovimentacoesRequest) + b.post('/upload', uploadMovimentacoesRequest) + b.path('/:conta_id', contaOwnedBy, b => { + b.post(insertMovimentacaoRequest) + b.post('/transferir/:conta_destino_id', transferenciaRequest) + b.path('/:id', b => { + b.get(findMovimentacaoRequest) + b.put(updateMovimentacaoRequest) + b.del(removeMovimentacaoRequest) + }) + }) + }) - b.path("/planejamento", b => { + b.path('/planejamento', b => { b.get(listPlanejamentoRequest) b.post(insertPlanejamentoRequest) - b.path("/:id", b => { + b.path('/:id', b => { b.del(delPlanejamentoRequest) b.put(updatePlanejamentoRequest) - }); - }); + }) + }) - b.path("/recorrencia", b => { + b.path('/recorrencia', b => { b.get(listRecorrenciaRequest) b.post(insertRecorrenciaRequest) - b.path("/:id", b => { + b.path('/:id', b => { b.get(findRecorrenciaRequest) b.put(updateRecorrenciaRequest) b.del(delRecorrenciaRequest) - b.get("/lancamentos", geraLancamentosRequest) + b.get('/lancamentos', geraLancamentosRequest) }) - }); + }) - b.get("/dashboard", getDashboardRequest) - }); -}).build(); + b.get('/dashboard', getDashboardRequest) + }) +}).build() -app.use(router.routes()).use(router.allowedMethods()); +app.use(router.routes()).use(router.allowedMethods()) diff --git a/service-node-koa/app/services/movimentacao.mjs b/service-node-koa/app/services/movimentacao.mjs index 6fe11cd..313b375 100644 --- a/service-node-koa/app/services/movimentacao.mjs +++ b/service-node-koa/app/services/movimentacao.mjs @@ -17,7 +17,6 @@ export const listMovimentacaoByUsuario = async (params) => { knex('conta').where({ usuario_id }).select('id')) } - export const listMovimentacaoByConta = async (params) => { const { conta_id = -1 @@ -117,6 +116,11 @@ export const removeMovimentacao = async (id = -1) => .where({ id }) .del() +export const transferencia = async ({usuario_id, origem, destino, valor, vencimento}) => { + + return ["wip"] +} + export const uploadMovimentacoes = async ({ id, header, lines }) => { const headerMap = { tipo: -1, conta: -1, categoria: -1, vencimento: -1, efetivada: -1, valor: -1, 'descrição': -1 } header.toLowerCase().replace(/"/g, '').split(/[,;]/).forEach((h, i) => { diff --git a/web-app-vue/src/pages/pagamento/pagamento-page.vue b/web-app-vue/src/pages/pagamento/pagamento-page.vue index f8d7049..473c866 100644 --- a/web-app-vue/src/pages/pagamento/pagamento-page.vue +++ b/web-app-vue/src/pages/pagamento/pagamento-page.vue @@ -1,9 +1,6 @@ - + diff --git a/web-app-vue/src/pages/pagamento/transferencia-form.vue b/web-app-vue/src/pages/pagamento/transferencia-form.vue index 896663e..98330f6 100644 --- a/web-app-vue/src/pages/pagamento/transferencia-form.vue +++ b/web-app-vue/src/pages/pagamento/transferencia-form.vue @@ -58,6 +58,9 @@ import { numberRule, requiredRule } from '@/services/basic-rules' import { router } from '@/services/router' import ContaAutocomplete from '@/shared/conta-autocomplete.vue' import ChipDate from '@/shared/chip-date.vue' +import { useMovimentacaoStore } from '@/stores/movimentacaoStore' + +const movimentacaoStore = useMovimentacaoStore() const valid = ref(false) const formTransferencia = reactive({ @@ -67,9 +70,15 @@ const formTransferencia = reactive({ vencimento: Date.now() }) -const transferir = () => { - if (!valid.value) return console.log('invalid form state') - console.log('save save save') +const transferir = async () => { + try { + if (!valid.value) return console.log('invalid form state') + await movimentacaoStore.transferir({ ...formTransferencia }) + alert('transferência criada com sucesso') + } catch (e) { + console.log(e) + alert('Não foi possível realizar a transferência') + } }