financeiro/financeiro-api/src/modules/bancos/services/bancos.service.js

306 lines
6.0 KiB
JavaScript

const pool = require('../../../database/mysql');
const CAMPOS_BANCO_SELECT = `
idbancos,
descricao,
saldo,
debito,
habilitado,
insert_date,
update_date
`;
function normalizarTextoOuNull(valor) {
if (valor === undefined || valor === null || valor === '') {
return null;
}
return String(valor).trim();
}
function normalizarNumero(valor, padrao = 0) {
if (valor === undefined || valor === null || valor === '') {
return padrao;
}
const numero = Number(valor);
if (!Number.isFinite(numero)) {
return padrao;
}
return numero;
}
function limitarNumero(valor, padrao, minimo, maximo) {
const numero = Number(valor);
if (!Number.isFinite(numero)) {
return padrao;
}
if (numero < minimo) {
return minimo;
}
if (numero > maximo) {
return maximo;
}
return numero;
}
function resolverOrdenacao(orderBy) {
const camposPermitidos = {
idbancos: 'idbancos',
descricao: 'descricao',
saldo: 'saldo',
debito: 'debito',
habilitado: 'habilitado',
insert_date: 'insert_date',
update_date: 'update_date',
};
return camposPermitidos[orderBy] || 'descricao';
}
function resolverDirecao(orderDirection) {
return String(orderDirection || '').toUpperCase() === 'DESC' ? 'DESC' : 'ASC';
}
function montarWhereBancos(filtros = {}) {
const where = [];
const params = [];
if (filtros.debito !== undefined && filtros.debito !== null && filtros.debito !== '') {
where.push('debito = ?');
params.push(Number(filtros.debito));
}
if (filtros.habilitado !== undefined && filtros.habilitado !== null && filtros.habilitado !== '') {
where.push('habilitado = ?');
params.push(Number(filtros.habilitado));
}
if (filtros.busca) {
where.push(`
(
descricao LIKE ?
)
`);
const termo = `%${String(filtros.busca).trim()}%`;
params.push(termo);
}
const whereSql = where.length > 0 ? `WHERE ${where.join(' AND ')}` : '';
return {
whereSql,
params,
};
}
async function listarBancos(filtros = {}) {
const limite = limitarNumero(filtros.limite, 20, 1, 100);
const page = limitarNumero(filtros.page, 1, 1, 999999);
const offset = filtros.offset !== undefined
? limitarNumero(filtros.offset, 0, 0, 999999999)
: (page - 1) * limite;
const orderBy = resolverOrdenacao(filtros.orderBy);
const orderDirection = resolverDirecao(filtros.orderDirection);
const { whereSql, params } = montarWhereBancos(filtros);
const [rows] = await pool.query(
`
SELECT
${CAMPOS_BANCO_SELECT}
FROM bancos
${whereSql}
ORDER BY ${orderBy} ${orderDirection}, idbancos ASC
LIMIT ? OFFSET ?
`,
[...params, limite, offset]
);
const [countRows] = await pool.query(
`
SELECT COUNT(*) AS total
FROM bancos
${whereSql}
`,
params
);
const [summaryRows] = await pool.query(
`
SELECT
COUNT(*) AS quantidade,
COALESCE(SUM(saldo), 0) AS saldoTotal,
COALESCE(SUM(CASE WHEN debito = 0 THEN saldo ELSE 0 END), 0) AS saldoCarteiras,
COALESCE(SUM(CASE WHEN debito = 1 THEN saldo ELSE 0 END), 0) AS saldoDebito
FROM bancos
${whereSql}
`,
params
);
const total = Number(countRows[0]?.total || 0);
const totalPages = Math.max(1, Math.ceil(total / limite));
return {
data: rows,
pagination: {
total,
limite,
offset,
page: Math.floor(offset / limite) + 1,
totalPages,
},
summary: {
quantidade: Number(summaryRows[0]?.quantidade || 0),
saldoTotal: Number(summaryRows[0]?.saldoTotal || 0),
saldoCarteiras: Number(summaryRows[0]?.saldoCarteiras || 0),
saldoDebito: Number(summaryRows[0]?.saldoDebito || 0),
},
};
}
async function buscarBancoPorId(id) {
const [rows] = await pool.query(
`
SELECT
${CAMPOS_BANCO_SELECT}
FROM bancos
WHERE idbancos = ?
LIMIT 1
`,
[id]
);
return rows[0] || null;
}
async function criarBanco(dados) {
const {
descricao,
saldo,
debito,
habilitado,
} = dados;
const [result] = await pool.query(
`
INSERT INTO bancos (
descricao,
saldo,
debito,
habilitado,
insert_date,
update_date
) VALUES (?, ?, ?, ?, NOW(), NOW())
`,
[
normalizarTextoOuNull(descricao),
normalizarNumero(saldo, 0),
Number(debito || 0),
habilitado === undefined || habilitado === null || habilitado === ''
? 1
: Number(habilitado),
]
);
return buscarBancoPorId(result.insertId);
}
async function atualizarBanco(id, dados) {
const bancoAtual = await buscarBancoPorId(id);
if (!bancoAtual) {
return null;
}
const {
descricao,
saldo,
debito,
habilitado,
} = dados;
await pool.query(
`
UPDATE bancos
SET
descricao = ?,
saldo = ?,
debito = ?,
habilitado = ?,
update_date = NOW()
WHERE idbancos = ?
`,
[
normalizarTextoOuNull(descricao),
normalizarNumero(saldo, 0),
Number(debito || 0),
habilitado === undefined || habilitado === null || habilitado === ''
? 1
: Number(habilitado),
id,
]
);
return buscarBancoPorId(id);
}
async function alterarHabilitadoBanco(id, habilitado) {
const bancoAtual = await buscarBancoPorId(id);
if (!bancoAtual) {
return null;
}
await pool.query(
`
UPDATE bancos
SET
habilitado = ?,
update_date = NOW()
WHERE idbancos = ?
`,
[
Number(habilitado),
id,
]
);
return buscarBancoPorId(id);
}
async function deletarBanco(id) {
const bancoAtual = await buscarBancoPorId(id);
if (!bancoAtual) {
return false;
}
await pool.query(
`
DELETE FROM bancos
WHERE idbancos = ?
`,
[id]
);
return true;
}
module.exports = {
listarBancos,
buscarBancoPorId,
criarBanco,
atualizarBanco,
alterarHabilitadoBanco,
deletarBanco,
};