ajustado resumo

This commit is contained in:
Diego Freitas 2026-07-04 12:27:41 -03:00
parent 36aba1c646
commit f085f2623d
2 changed files with 534 additions and 677 deletions

View File

@ -159,79 +159,41 @@ async function buscarCardsMovimentos(idUsuario, dataInicio, dataFim) {
SELECT
COALESCE(SUM(
CASE
/* Entradas e estornos normais */
WHEN cp.movimento IN ('Entrada', 'Estorno')
AND banco_origem.idusuarios = ?
THEN cp.valor
/* Sangria recebida de outro usuário */
WHEN cp.movimento = 'Sangria'
AND banco_destino.idusuarios = ?
AND (
banco_origem.idusuarios IS NULL
OR banco_origem.idusuarios <> ?
)
THEN cp.valor
WHEN base_resumo.direcao_financeira = 'entrada'
THEN base_resumo.valor
ELSE 0
END
), 0) AS entradas,
COALESCE(SUM(
CASE
/* Saída operacional normal */
WHEN cp.movimento = 'Saida'
AND banco_origem.idusuarios = ?
AND COALESCE(cc.investimento, 0) = 0
THEN cp.valor
/* Sangria enviada para outro usuário */
WHEN cp.movimento = 'Sangria'
AND banco_origem.idusuarios = ?
AND (
banco_destino.idusuarios IS NULL
OR banco_destino.idusuarios <> ?
)
THEN cp.valor
WHEN base_resumo.direcao_financeira = 'saida'
THEN base_resumo.valor
ELSE 0
END
), 0) AS saidas,
COALESCE(SUM(
CASE
/* Saída marcada como investimento pelo centro de custo */
WHEN cp.movimento = 'Saida'
AND banco_origem.idusuarios = ?
AND COALESCE(cc.investimento, 0) = 1
THEN cp.valor
/* Transferência para banco de investimento do próprio usuário */
WHEN cp.movimento = 'Sangria'
AND banco_origem.idusuarios = ?
AND banco_destino.idusuarios = ?
AND COALESCE(banco_destino.investimento, 0) = 1
THEN cp.valor
WHEN base_resumo.direcao_financeira = 'investimento'
THEN base_resumo.valor
ELSE 0
END
), 0) AS investimentos,
COALESCE(SUM(
CASE
WHEN cp.status = 'A receber'
AND cp.movimento IN ('Entrada', 'Estorno')
AND banco_origem.idusuarios = ?
THEN cp.valor
WHEN base_resumo.direcao_financeira = 'entrada'
AND base_resumo.status IN ('A receber', 'A pagar')
THEN base_resumo.valor
ELSE 0
END
), 0) AS abertoEntradas,
COUNT(
CASE
WHEN cp.status = 'A receber'
AND cp.movimento IN ('Entrada', 'Estorno')
AND banco_origem.idusuarios = ?
WHEN base_resumo.direcao_financeira = 'entrada'
AND base_resumo.status IN ('A receber', 'A pagar')
THEN 1
ELSE NULL
END
@ -239,21 +201,17 @@ async function buscarCardsMovimentos(idUsuario, dataInicio, dataFim) {
COALESCE(SUM(
CASE
WHEN cp.status = 'A pagar'
AND cp.movimento = 'Saida'
AND banco_origem.idusuarios = ?
AND COALESCE(cc.investimento, 0) = 0
THEN cp.valor
WHEN base_resumo.direcao_financeira = 'saida'
AND base_resumo.status IN ('A pagar', 'A receber')
THEN base_resumo.valor
ELSE 0
END
), 0) AS abertoSaidas,
COUNT(
CASE
WHEN cp.status = 'A pagar'
AND cp.movimento = 'Saida'
AND banco_origem.idusuarios = ?
AND COALESCE(cc.investimento, 0) = 0
WHEN base_resumo.direcao_financeira = 'saida'
AND base_resumo.status IN ('A pagar', 'A receber')
THEN 1
ELSE NULL
END
@ -261,21 +219,17 @@ async function buscarCardsMovimentos(idUsuario, dataInicio, dataFim) {
COALESCE(SUM(
CASE
WHEN cp.status = 'A pagar'
AND cp.movimento = 'Saida'
AND banco_origem.idusuarios = ?
AND COALESCE(cc.investimento, 0) = 1
THEN cp.valor
WHEN base_resumo.direcao_financeira = 'investimento'
AND base_resumo.status IN ('A pagar', 'A receber')
THEN base_resumo.valor
ELSE 0
END
), 0) AS abertoInvestimentos,
COUNT(
CASE
WHEN cp.status = 'A pagar'
AND cp.movimento = 'Saida'
AND banco_origem.idusuarios = ?
AND COALESCE(cc.investimento, 0) = 1
WHEN base_resumo.direcao_financeira = 'investimento'
AND base_resumo.status IN ('A pagar', 'A receber')
THEN 1
ELSE NULL
END
@ -283,32 +237,75 @@ async function buscarCardsMovimentos(idUsuario, dataInicio, dataFim) {
COALESCE(SUM(
CASE
WHEN cp.status IN ('Pago', 'Recebido')
AND (
cp.movimento <> 'Sangria'
OR (
cp.movimento = 'Sangria'
AND banco_origem.idusuarios = ?
AND (
banco_destino.idusuarios IS NULL
OR banco_destino.idusuarios <> ?
)
)
OR (
cp.movimento = 'Sangria'
AND banco_destino.idusuarios = ?
AND banco_origem.idusuarios <> ?
)
)
THEN cp.valor
WHEN base_resumo.direcao_financeira IN ('entrada', 'saida', 'investimento')
AND base_resumo.status IN ('Pago', 'Recebido')
THEN base_resumo.valor
ELSE 0
END
), 0) AS baixado,
COUNT(*) AS quantidadeMovimentos
FROM (
SELECT
cp.idcontasapagar,
cp.movimento,
cp.status,
cp.valor,
CASE
WHEN cp.status IN ('Pago', 'Recebido')
AND cp.databaixa IS NOT NULL
THEN cp.databaixa
ELSE COALESCE(cp.dataentrada, cp.insert_date)
END AS data_dashboard,
CASE
WHEN cp.movimento IN ('Entrada', 'Estorno')
AND banco_origem.idusuarios = contexto.idUsuario
THEN 'entrada'
WHEN cp.movimento = 'Saida'
AND banco_origem.idusuarios = contexto.idUsuario
AND COALESCE(cc.investimento, 0) = 0
THEN 'saida'
WHEN cp.movimento = 'Saida'
AND banco_origem.idusuarios = contexto.idUsuario
AND COALESCE(cc.investimento, 0) = 1
THEN 'investimento'
WHEN cp.movimento = 'Sangria'
AND banco_origem.idusuarios = contexto.idUsuario
AND banco_destino.idusuarios = contexto.idUsuario
AND COALESCE(banco_destino.investimento, 0) = 1
THEN 'investimento'
WHEN cp.movimento = 'Sangria'
AND banco_origem.idusuarios = contexto.idUsuario
AND banco_destino.idusuarios = contexto.idUsuario
THEN 'transferencia_interna'
WHEN cp.movimento = 'Sangria'
AND banco_origem.idusuarios = contexto.idUsuario
AND (
banco_destino.idusuarios IS NULL
OR banco_destino.idusuarios <> contexto.idUsuario
)
THEN 'saida'
WHEN cp.movimento = 'Sangria'
AND banco_destino.idusuarios = contexto.idUsuario
AND (
banco_origem.idusuarios IS NULL
OR banco_origem.idusuarios <> contexto.idUsuario
)
THEN 'entrada'
ELSE 'neutro'
END AS direcao_financeira
FROM contasapagar cp
INNER JOIN bancos banco_origem
@ -320,59 +317,22 @@ async function buscarCardsMovimentos(idUsuario, dataInicio, dataFim) {
LEFT JOIN centrodecustos cc
ON cc.idcentrodecustos = cp.idcentrodecustos
CROSS JOIN (
SELECT ? AS idUsuario
) contexto
WHERE cp.deleted_at IS NULL
AND (
banco_origem.idusuarios = ?
OR banco_destino.idusuarios = ?
banco_origem.idusuarios = contexto.idUsuario
OR banco_destino.idusuarios = contexto.idUsuario
)
AND DATE(COALESCE(cp.dataentrada, cp.insert_date))
) base_resumo
WHERE DATE(base_resumo.data_dashboard)
BETWEEN ? AND ?
`,
[
/* entradas */
idUsuario,
idUsuario,
idUsuario,
/* saídas */
idUsuario,
idUsuario,
idUsuario,
/* investimentos */
idUsuario,
idUsuario,
idUsuario,
/* abertoEntradas */
idUsuario,
/* quantidadeAbertoEntradas */
idUsuario,
/* abertoSaidas */
idUsuario,
/* quantidadeAbertoSaidas */
idUsuario,
/* abertoInvestimentos */
idUsuario,
/* quantidadeAbertoInvestimentos */
idUsuario,
/* baixado */
idUsuario,
idUsuario,
idUsuario,
idUsuario,
/* usuário na origem ou destino */
idUsuario,
idUsuario,
/* período */
dataInicio,
dataFim,
]
@ -819,64 +779,69 @@ async function buscarUltimosMovimentos(idUsuario) {
banco_destino.descricao AS banco_destino_descricao,
banco_destino.debito AS banco_destino_debito,
banco_destino.idusuarios AS idusuario_destino,
banco_destino.investimento AS banco_destino_investimento,
usuario_destino.nome AS usuario_destino_nome,
cp.idcentrodecustos,
cc.descricao AS centro_custo_descricao,
CASE
/*
* Movimento normal:
* mantém o tipo original.
*/
WHEN cp.movimento = 'Saida'
AND banco_origem.idusuarios = contexto.idUsuario
AND COALESCE(cc.investimento, 0) = 1
THEN 'Investimento'
WHEN cp.movimento <> 'Sangria'
THEN cp.movimento
/*
* Origem e destino pertencem ao usuário:
* transferência interna.
*/
WHEN banco_origem.idusuarios = ?
AND banco_destino.idusuarios = ?
WHEN cp.movimento = 'Sangria'
AND banco_origem.idusuarios = contexto.idUsuario
AND banco_destino.idusuarios = contexto.idUsuario
AND COALESCE(banco_destino.investimento, 0) = 1
THEN 'Investimento'
WHEN cp.movimento = 'Sangria'
AND banco_origem.idusuarios = contexto.idUsuario
AND banco_destino.idusuarios = contexto.idUsuario
THEN 'TransferenciaInterna'
/*
* Usuário é o dono do banco de origem:
* dinheiro saiu para outro usuário.
*/
WHEN banco_origem.idusuarios = ?
WHEN cp.movimento = 'Sangria'
AND banco_origem.idusuarios = contexto.idUsuario
THEN 'Saida'
/*
* Usuário é o dono do banco de destino:
* dinheiro entrou vindo de outro usuário.
*/
WHEN banco_destino.idusuarios = ?
WHEN cp.movimento = 'Sangria'
AND banco_destino.idusuarios = contexto.idUsuario
THEN 'Entrada'
ELSE cp.movimento
END AS movimento_dashboard,
CASE
WHEN cp.movimento <> 'Sangria'
AND cp.movimento IN ('Entrada', 'Estorno')
WHEN cp.movimento IN ('Entrada', 'Estorno')
AND banco_origem.idusuarios = contexto.idUsuario
THEN 'entrada'
WHEN cp.movimento <> 'Sangria'
AND cp.movimento = 'Saida'
WHEN cp.movimento = 'Saida'
AND banco_origem.idusuarios = contexto.idUsuario
THEN 'saida'
WHEN cp.movimento = 'Sangria'
AND banco_origem.idusuarios = ?
AND banco_destino.idusuarios = ?
AND banco_origem.idusuarios = contexto.idUsuario
AND banco_destino.idusuarios = contexto.idUsuario
AND COALESCE(banco_destino.investimento, 0) = 1
THEN 'saida'
WHEN cp.movimento = 'Sangria'
AND banco_origem.idusuarios = contexto.idUsuario
AND banco_destino.idusuarios = contexto.idUsuario
THEN 'transferencia_interna'
WHEN cp.movimento = 'Sangria'
AND banco_origem.idusuarios = ?
AND banco_origem.idusuarios = contexto.idUsuario
THEN 'saida'
WHEN cp.movimento = 'Sangria'
AND banco_destino.idusuarios = ?
AND banco_destino.idusuarios = contexto.idUsuario
THEN 'entrada'
ELSE 'neutro'
@ -884,12 +849,28 @@ async function buscarUltimosMovimentos(idUsuario) {
CASE
WHEN cp.movimento = 'Sangria'
AND banco_origem.idusuarios = ?
AND banco_destino.idusuarios = ?
AND banco_origem.idusuarios = contexto.idUsuario
AND banco_destino.idusuarios = contexto.idUsuario
AND COALESCE(banco_destino.investimento, 0) = 0
THEN 1
ELSE 0
END AS transferencia_interna
END AS transferencia_interna,
CASE
WHEN cp.movimento = 'Saida'
AND banco_origem.idusuarios = contexto.idUsuario
AND COALESCE(cc.investimento, 0) = 1
THEN 1
WHEN cp.movimento = 'Sangria'
AND banco_origem.idusuarios = contexto.idUsuario
AND banco_destino.idusuarios = contexto.idUsuario
AND COALESCE(banco_destino.investimento, 0) = 1
THEN 1
ELSE 0
END AS investimento_dashboard
FROM contasapagar cp
@ -908,10 +889,14 @@ async function buscarUltimosMovimentos(idUsuario) {
LEFT JOIN centrodecustos cc
ON cc.idcentrodecustos = cp.idcentrodecustos
CROSS JOIN (
SELECT ? AS idUsuario
) contexto
WHERE cp.deleted_at IS NULL
AND (
banco_origem.idusuarios = ?
OR banco_destino.idusuarios = ?
banco_origem.idusuarios = contexto.idUsuario
OR banco_destino.idusuarios = contexto.idUsuario
)
ORDER BY
@ -921,24 +906,6 @@ async function buscarUltimosMovimentos(idUsuario) {
LIMIT 10
`,
[
/* movimento_dashboard */
idUsuario,
idUsuario,
idUsuario,
idUsuario,
/* direcao_dashboard */
idUsuario,
idUsuario,
idUsuario,
idUsuario,
/* transferencia_interna */
idUsuario,
idUsuario,
/* WHERE */
idUsuario,
idUsuario,
]
);
@ -950,28 +917,61 @@ async function buscarUltimosMovimentos(idUsuario) {
transferencia_interna:
Number(item.transferencia_interna || 0) === 1,
investimento_dashboard:
Number(item.investimento_dashboard || 0) === 1,
}));
}
async function buscarGraficos(idUsuario, dataInicio, dataFim) {
/*
* Gastos por centro de custo
*
* Aqui entram:
* - Saídas normais do usuário;
* - Sangrias enviadas para outro usuário;
*
* Não entram:
* - Sangrias entre bancos do próprio usuário;
* - Sangrias recebidas;
* - Movimentos classificados como investimento.
*/
const [centrosRows] = await pool.query(
`
SELECT
base_gastos.idcentrodecustos,
base_gastos.descricao,
COALESCE(SUM(base_gastos.valor), 0) AS valor
FROM (
SELECT
cp.idcentrodecustos,
COALESCE(cc.descricao, 'Sem centro de custo') AS descricao,
COALESCE(SUM(cp.valor), 0) AS valor
cp.valor,
CASE
WHEN cp.status IN ('Pago', 'Recebido')
AND cp.databaixa IS NOT NULL
THEN cp.databaixa
ELSE COALESCE(cp.dataentrada, cp.insert_date)
END AS data_dashboard,
CASE
WHEN cp.movimento = 'Saida'
AND banco_origem.idusuarios = contexto.idUsuario
AND COALESCE(cc.investimento, 0) = 0
THEN 'saida'
WHEN cp.movimento = 'Sangria'
AND banco_origem.idusuarios = contexto.idUsuario
AND banco_destino.idusuarios = contexto.idUsuario
AND COALESCE(banco_destino.investimento, 0) = 1
THEN 'investimento'
WHEN cp.movimento = 'Sangria'
AND banco_origem.idusuarios = contexto.idUsuario
AND banco_destino.idusuarios = contexto.idUsuario
THEN 'transferencia_interna'
WHEN cp.movimento = 'Sangria'
AND banco_origem.idusuarios = contexto.idUsuario
AND (
banco_destino.idusuarios IS NULL
OR banco_destino.idusuarios <> contexto.idUsuario
)
THEN 'saida'
ELSE 'neutro'
END AS direcao_financeira
FROM contasapagar cp
@ -984,32 +984,24 @@ async function buscarGraficos(idUsuario, dataInicio, dataFim) {
LEFT JOIN centrodecustos cc
ON cc.idcentrodecustos = cp.idcentrodecustos
CROSS JOIN (
SELECT ? AS idUsuario
) contexto
WHERE cp.deleted_at IS NULL
AND DATE(COALESCE(cp.dataentrada, cp.insert_date))
AND (
banco_origem.idusuarios = contexto.idUsuario
OR banco_destino.idusuarios = contexto.idUsuario
)
) base_gastos
WHERE DATE(base_gastos.data_dashboard)
BETWEEN ? AND ?
AND COALESCE(cc.investimento, 0) = 0
AND (
(
cp.movimento = 'Saida'
AND banco_origem.idusuarios = ?
)
OR
(
cp.movimento = 'Sangria'
AND banco_origem.idusuarios = ?
AND (
banco_destino.idusuarios IS NULL
OR banco_destino.idusuarios <> ?
)
)
)
AND base_gastos.direcao_financeira = 'saida'
GROUP BY
cp.idcentrodecustos,
COALESCE(cc.descricao, 'Sem centro de custo')
base_gastos.idcentrodecustos,
base_gastos.descricao
HAVING valor > 0
@ -1018,91 +1010,95 @@ async function buscarGraficos(idUsuario, dataInicio, dataFim) {
LIMIT 8
`,
[
idUsuario,
dataInicio,
dataFim,
idUsuario,
idUsuario,
idUsuario,
]
);
/*
* Resumo de entradas, saídas e investimentos.
*
* Para sangria:
* - destino é do usuário e origem é de outro usuário = entrada;
* - origem é do usuário e destino é de outro usuário = saída;
* - origem e destino são do usuário = transferência interna, ignorada.
*/
const [entradasSaidasRows] = await pool.query(
`
SELECT
COALESCE(
SUM(
COALESCE(SUM(
CASE
/* Entrada ou estorno normal */
WHEN cp.movimento IN ('Entrada', 'Estorno')
AND banco_origem.idusuarios = ?
THEN cp.valor
/* Sangria recebida de outro usuário */
WHEN cp.movimento = 'Sangria'
AND banco_destino.idusuarios = ?
AND banco_origem.idusuarios <> ?
THEN cp.valor
WHEN base_resumo.direcao_financeira = 'entrada'
THEN base_resumo.valor
ELSE 0
END
),
0
) AS entradas,
), 0) AS entradas,
COALESCE(
SUM(
COALESCE(SUM(
CASE
/* Saída normal */
WHEN cp.movimento = 'Saida'
AND banco_origem.idusuarios = ?
AND COALESCE(cc.investimento, 0) = 0
THEN cp.valor
WHEN base_resumo.direcao_financeira = 'saida'
THEN base_resumo.valor
ELSE 0
END
), 0) AS saidas,
COALESCE(SUM(
CASE
WHEN base_resumo.direcao_financeira = 'investimento'
THEN base_resumo.valor
ELSE 0
END
), 0) AS investimentos
FROM (
SELECT
cp.valor,
CASE
WHEN cp.status IN ('Pago', 'Recebido')
AND cp.databaixa IS NOT NULL
THEN cp.databaixa
ELSE COALESCE(cp.dataentrada, cp.insert_date)
END AS data_dashboard,
CASE
WHEN cp.movimento IN ('Entrada', 'Estorno')
AND banco_origem.idusuarios = contexto.idUsuario
THEN 'entrada'
WHEN cp.movimento = 'Saida'
AND banco_origem.idusuarios = contexto.idUsuario
AND COALESCE(cc.investimento, 0) = 0
THEN 'saida'
WHEN cp.movimento = 'Saida'
AND banco_origem.idusuarios = contexto.idUsuario
AND COALESCE(cc.investimento, 0) = 1
THEN 'investimento'
/* Sangria enviada para outro usuário */
WHEN cp.movimento = 'Sangria'
AND banco_origem.idusuarios = ?
AND banco_origem.idusuarios = contexto.idUsuario
AND banco_destino.idusuarios = contexto.idUsuario
AND COALESCE(banco_destino.investimento, 0) = 1
THEN 'investimento'
WHEN cp.movimento = 'Sangria'
AND banco_origem.idusuarios = contexto.idUsuario
AND banco_destino.idusuarios = contexto.idUsuario
THEN 'transferencia_interna'
WHEN cp.movimento = 'Sangria'
AND banco_origem.idusuarios = contexto.idUsuario
AND (
banco_destino.idusuarios IS NULL
OR banco_destino.idusuarios <> ?
OR banco_destino.idusuarios <> contexto.idUsuario
)
AND COALESCE(cc.investimento, 0) = 0
THEN cp.valor
ELSE 0
END
),
0
) AS saidas,
COALESCE(
SUM(
CASE
WHEN cp.movimento = 'Saida'
AND banco_origem.idusuarios = ?
AND COALESCE(cc.investimento, 0) = 1
THEN cp.valor
THEN 'saida'
WHEN cp.movimento = 'Sangria'
AND banco_origem.idusuarios = ?
AND banco_destino.idusuarios = ?
AND COALESCE(banco_destino.investimento, 0) = 1
THEN cp.valor
AND banco_destino.idusuarios = contexto.idUsuario
AND (
banco_origem.idusuarios IS NULL
OR banco_origem.idusuarios <> contexto.idUsuario
)
THEN 'entrada'
ELSE 0
END
),
0
) AS investimentos
ELSE 'neutro'
END AS direcao_financeira
FROM contasapagar cp
@ -1115,38 +1111,24 @@ async function buscarGraficos(idUsuario, dataInicio, dataFim) {
LEFT JOIN centrodecustos cc
ON cc.idcentrodecustos = cp.idcentrodecustos
WHERE cp.deleted_at IS NULL
AND DATE(COALESCE(cp.dataentrada, cp.insert_date))
BETWEEN ? AND ?
CROSS JOIN (
SELECT ? AS idUsuario
) contexto
WHERE cp.deleted_at IS NULL
AND (
banco_origem.idusuarios = ?
OR banco_destino.idusuarios = ?
banco_origem.idusuarios = contexto.idUsuario
OR banco_destino.idusuarios = contexto.idUsuario
)
) base_resumo
WHERE DATE(base_resumo.data_dashboard)
BETWEEN ? AND ?
`,
[
/* Entradas */
idUsuario,
idUsuario,
idUsuario,
/* Saídas */
idUsuario,
idUsuario,
idUsuario,
/* Investimentos */
idUsuario,
idUsuario,
idUsuario,
/* Período */
dataInicio,
dataFim,
/* Usuário presente em uma das pontas */
idUsuario,
idUsuario,
]
);

View File

@ -193,9 +193,12 @@ function enriquecerMovimentoParaUsuario(item, idUsuario) {
const usuarioAtual = Number(idUsuario);
const usuarioOrigem = Number(item.idusuario_origem);
const usuarioDestino = Number(item.idusuario_destino);
const destinoInvestimento = Number(item.banco_destino_investimento || 0) === 1;
let movimentoDashboard = item.movimento;
let direcaoDashboard = 'neutro';
let transferenciaInterna = false;
let investimentoDashboard = false;
if (
item.movimento === 'Entrada'
@ -205,16 +208,21 @@ function enriquecerMovimentoParaUsuario(item, idUsuario) {
} else if (item.movimento === 'Saida') {
direcaoDashboard = 'saida';
} else if (item.movimento === 'Sangria') {
if (
usuarioOrigem === usuarioAtual
&& usuarioDestino === usuarioAtual
) {
const origemEhUsuario = usuarioOrigem === usuarioAtual;
const destinoEhUsuario = usuarioDestino === usuarioAtual;
if (origemEhUsuario && destinoEhUsuario && destinoInvestimento) {
movimentoDashboard = 'Investimento';
direcaoDashboard = 'saida';
investimentoDashboard = true;
} else if (origemEhUsuario && destinoEhUsuario) {
movimentoDashboard = 'TransferenciaInterna';
direcaoDashboard = 'transferencia_interna';
} else if (usuarioOrigem === usuarioAtual) {
transferenciaInterna = true;
} else if (origemEhUsuario) {
movimentoDashboard = 'Saida';
direcaoDashboard = 'saida';
} else if (usuarioDestino === usuarioAtual) {
} else if (destinoEhUsuario) {
movimentoDashboard = 'Entrada';
direcaoDashboard = 'entrada';
}
@ -226,14 +234,8 @@ function enriquecerMovimentoParaUsuario(item, idUsuario) {
movimento_dashboard: movimentoDashboard,
direcao_dashboard: direcaoDashboard,
transferencia_interna:
movimentoDashboard === 'TransferenciaInterna',
investimento_dashboard:
item.movimento === 'Sangria'
&& usuarioOrigem === usuarioAtual
&& usuarioDestino === usuarioAtual
&& Number(item.banco_destino_investimento || 0) === 1,
transferencia_interna: transferenciaInterna,
investimento_dashboard: investimentoDashboard,
};
}
@ -351,15 +353,26 @@ async function buscarResumoMovimentos(
const paramsWhere = [...base.params];
/*
* No extrato financeiro, entradas, saídas e investimentos
* pertencem ao período de realização do movimento.
* No extrato financeiro, o ideal é usar a data de baixa
* quando o movimento foi realizado.
*
* Na tabela comum, o resumo respeita o campo de data
* selecionado pelo usuário.
* Isso evita o caso clássico:
* - movimento lançado em um mês
* - pago/baixado em outro
* - aparece no extrato pela baixa
* - mas não entra no summary porque o summary olhava dataentrada
*/
const campoDataSql =
opcoes.modoExtrato === true
? 'COALESCE(cp.dataentrada, cp.insert_date)'
? `
CASE
WHEN cp.status IN ('Pago', 'Recebido')
AND cp.databaixa IS NOT NULL
THEN cp.databaixa
ELSE COALESCE(cp.dataentrada, cp.insert_date)
END
`
: resolverCampoData(filtros.dataCampo);
if (filtros.dataInicio) {
@ -381,94 +394,198 @@ async function buscarResumoMovimentos(
SELECT
COUNT(*) AS quantidade,
/* ==================================================
* ENTRADAS
* ================================================== */
COALESCE(SUM(
CASE
WHEN cp.movimento IN ('Entrada', 'Estorno')
AND b.idusuarios = ?
THEN cp.valor
WHEN cp.movimento = 'Sangria'
AND bp.idusuarios = ?
AND (
b.idusuarios IS NULL
OR b.idusuarios <> ?
)
THEN cp.valor
WHEN base_resumo.direcao_financeira = 'entrada'
THEN base_resumo.valor
ELSE 0
END
), 0) AS totalEntradas,
COALESCE(SUM(
CASE
WHEN cp.movimento IN ('Entrada', 'Estorno')
AND b.idusuarios = ?
AND cp.status = 'Recebido'
THEN cp.valor
WHEN cp.movimento = 'Sangria'
AND bp.idusuarios = ?
AND (
b.idusuarios IS NULL
OR b.idusuarios <> ?
)
AND cp.status IN ('Pago', 'Recebido')
THEN cp.valor
WHEN base_resumo.direcao_financeira = 'entrada'
AND base_resumo.status IN ('Recebido', 'Pago')
THEN base_resumo.valor
ELSE 0
END
), 0) AS entradasRecebidas,
COALESCE(SUM(
CASE
WHEN cp.movimento IN ('Entrada', 'Estorno')
AND b.idusuarios = ?
AND cp.status = 'A receber'
THEN cp.valor
WHEN cp.movimento = 'Sangria'
AND bp.idusuarios = ?
AND (
b.idusuarios IS NULL
OR b.idusuarios <> ?
)
AND cp.status IN ('A receber', 'A pagar')
THEN cp.valor
WHEN base_resumo.direcao_financeira = 'entrada'
AND base_resumo.status IN ('A receber', 'A pagar')
THEN base_resumo.valor
ELSE 0
END
), 0) AS entradasPendentes,
COUNT(
CASE
WHEN cp.movimento IN ('Entrada', 'Estorno')
AND b.idusuarios = ?
AND cp.status = 'Recebido'
WHEN base_resumo.direcao_financeira = 'entrada'
AND base_resumo.status IN ('Recebido', 'Pago')
THEN 1
WHEN cp.movimento = 'Sangria'
AND bp.idusuarios = ?
AND (
b.idusuarios IS NULL
OR b.idusuarios <> ?
)
AND cp.status IN ('Pago', 'Recebido')
THEN 1
ELSE NULL
END
) AS quantidadeEntradasRecebidas,
COUNT(
CASE
WHEN base_resumo.direcao_financeira = 'entrada'
AND base_resumo.status IN ('A receber', 'A pagar')
THEN 1
ELSE NULL
END
) AS quantidadeEntradasPendentes,
COALESCE(SUM(
CASE
WHEN base_resumo.direcao_financeira = 'saida'
THEN base_resumo.valor
ELSE 0
END
), 0) AS totalSaidas,
COALESCE(SUM(
CASE
WHEN base_resumo.direcao_financeira = 'saida'
AND base_resumo.status IN ('Pago', 'Recebido')
THEN base_resumo.valor
ELSE 0
END
), 0) AS saidasPagas,
COALESCE(SUM(
CASE
WHEN base_resumo.direcao_financeira = 'saida'
AND base_resumo.status IN ('A pagar', 'A receber')
THEN base_resumo.valor
ELSE 0
END
), 0) AS saidasPendentes,
COUNT(
CASE
WHEN base_resumo.direcao_financeira = 'saida'
AND base_resumo.status IN ('Pago', 'Recebido')
THEN 1
ELSE NULL
END
) AS quantidadeSaidasPagas,
COUNT(
CASE
WHEN base_resumo.direcao_financeira = 'saida'
AND base_resumo.status IN ('A pagar', 'A receber')
THEN 1
ELSE NULL
END
) AS quantidadeSaidasPendentes,
COALESCE(SUM(
CASE
WHEN base_resumo.direcao_financeira = 'investimento'
THEN base_resumo.valor
ELSE 0
END
), 0) AS totalInvestimentos,
COALESCE(SUM(
CASE
WHEN base_resumo.direcao_financeira = 'investimento'
AND base_resumo.status IN ('Pago', 'Recebido')
THEN base_resumo.valor
ELSE 0
END
), 0) AS investimentosRealizados,
COALESCE(SUM(
CASE
WHEN base_resumo.direcao_financeira = 'investimento'
AND base_resumo.status IN ('A pagar', 'A receber')
THEN base_resumo.valor
ELSE 0
END
), 0) AS investimentosPendentes,
COUNT(
CASE
WHEN base_resumo.direcao_financeira = 'investimento'
AND base_resumo.status IN ('Pago', 'Recebido')
THEN 1
ELSE NULL
END
) AS quantidadeInvestimentosRealizados,
COUNT(
CASE
WHEN base_resumo.direcao_financeira = 'investimento'
AND base_resumo.status IN ('A pagar', 'A receber')
THEN 1
ELSE NULL
END
) AS quantidadeInvestimentosPendentes,
COALESCE(SUM(
CASE
WHEN base_resumo.movimento = 'Estorno'
AND base_resumo.idusuario_origem = ?
THEN base_resumo.valor
ELSE 0
END
), 0) AS totalEstornos,
COALESCE(SUM(
CASE
WHEN base_resumo.saldo_processado = 1
THEN 1
ELSE 0
END
), 0) AS saldoProcessado
FROM (
SELECT
cp.idcontasapagar,
cp.movimento,
cp.status,
cp.valor,
cp.saldo_processado,
b.idusuarios AS idusuario_origem,
bp.idusuarios AS idusuario_destino,
CASE
WHEN cp.movimento IN ('Entrada', 'Estorno')
AND b.idusuarios = ?
AND cp.status = 'A receber'
THEN 1
THEN 'entrada'
WHEN cp.movimento = 'Saida'
AND b.idusuarios = ?
AND COALESCE(cc.investimento, 0) = 0
THEN 'saida'
WHEN cp.movimento = 'Saida'
AND b.idusuarios = ?
AND COALESCE(cc.investimento, 0) = 1
THEN 'investimento'
WHEN cp.movimento = 'Sangria'
AND b.idusuarios = ?
AND bp.idusuarios = ?
AND COALESCE(bp.investimento, 0) = 1
THEN 'investimento'
WHEN cp.movimento = 'Sangria'
AND b.idusuarios = ?
AND bp.idusuarios = ?
THEN 'transferencia_interna'
WHEN cp.movimento = 'Sangria'
AND b.idusuarios = ?
AND (
bp.idusuarios IS NULL
OR bp.idusuarios <> ?
)
THEN 'saida'
WHEN cp.movimento = 'Sangria'
AND bp.idusuarios = ?
@ -476,267 +593,29 @@ async function buscarResumoMovimentos(
b.idusuarios IS NULL
OR b.idusuarios <> ?
)
AND cp.status IN ('A receber', 'A pagar')
THEN 1
THEN 'entrada'
ELSE NULL
END
) AS quantidadeEntradasPendentes,
/* ==================================================
* SAÍDAS OPERACIONAIS
* ================================================== */
COALESCE(SUM(
CASE
WHEN cp.movimento = 'Saida'
AND b.idusuarios = ?
AND COALESCE(cc.investimento, 0) = 0
THEN cp.valor
WHEN cp.movimento = 'Sangria'
AND b.idusuarios = ?
AND (
bp.idusuarios IS NULL
OR bp.idusuarios <> ?
)
THEN cp.valor
ELSE 0
END
), 0) AS totalSaidas,
COALESCE(SUM(
CASE
WHEN cp.movimento = 'Saida'
AND b.idusuarios = ?
AND COALESCE(cc.investimento, 0) = 0
AND cp.status = 'Pago'
THEN cp.valor
WHEN cp.movimento = 'Sangria'
AND b.idusuarios = ?
AND (
bp.idusuarios IS NULL
OR bp.idusuarios <> ?
)
AND cp.status IN ('Pago', 'Recebido')
THEN cp.valor
ELSE 0
END
), 0) AS saidasPagas,
COALESCE(SUM(
CASE
WHEN cp.movimento = 'Saida'
AND b.idusuarios = ?
AND COALESCE(cc.investimento, 0) = 0
AND cp.status = 'A pagar'
THEN cp.valor
WHEN cp.movimento = 'Sangria'
AND b.idusuarios = ?
AND (
bp.idusuarios IS NULL
OR bp.idusuarios <> ?
)
AND cp.status IN ('A pagar', 'A receber')
THEN cp.valor
ELSE 0
END
), 0) AS saidasPendentes,
COUNT(
CASE
WHEN cp.movimento = 'Saida'
AND b.idusuarios = ?
AND COALESCE(cc.investimento, 0) = 0
AND cp.status = 'Pago'
THEN 1
WHEN cp.movimento = 'Sangria'
AND b.idusuarios = ?
AND (
bp.idusuarios IS NULL
OR bp.idusuarios <> ?
)
AND cp.status IN ('Pago', 'Recebido')
THEN 1
ELSE NULL
END
) AS quantidadeSaidasPagas,
COUNT(
CASE
WHEN cp.movimento = 'Saida'
AND b.idusuarios = ?
AND COALESCE(cc.investimento, 0) = 0
AND cp.status = 'A pagar'
THEN 1
WHEN cp.movimento = 'Sangria'
AND b.idusuarios = ?
AND (
bp.idusuarios IS NULL
OR bp.idusuarios <> ?
)
AND cp.status IN ('A pagar', 'A receber')
THEN 1
ELSE NULL
END
) AS quantidadeSaidasPendentes,
/* ==================================================
* INVESTIMENTOS
* ================================================== */
COALESCE(SUM(
CASE
WHEN cp.movimento = 'Saida'
AND b.idusuarios = ?
AND COALESCE(cc.investimento, 0) = 1
THEN cp.valor
WHEN cp.movimento = 'Sangria'
AND b.idusuarios = ?
AND bp.idusuarios = ?
AND COALESCE(bp.investimento, 0) = 1
THEN cp.valor
ELSE 0
END
), 0) AS totalInvestimentos,
COALESCE(SUM(
CASE
WHEN cp.movimento = 'Saida'
AND b.idusuarios = ?
AND COALESCE(cc.investimento, 0) = 1
AND cp.status = 'Pago'
THEN cp.valor
WHEN cp.movimento = 'Sangria'
AND b.idusuarios = ?
AND bp.idusuarios = ?
AND COALESCE(bp.investimento, 0) = 1
AND cp.status IN ('Pago', 'Recebido')
THEN cp.valor
ELSE 0
END
), 0) AS investimentosRealizados,
COALESCE(SUM(
CASE
WHEN cp.movimento = 'Saida'
AND b.idusuarios = ?
AND COALESCE(cc.investimento, 0) = 1
AND cp.status = 'A pagar'
THEN cp.valor
WHEN cp.movimento = 'Sangria'
AND b.idusuarios = ?
AND bp.idusuarios = ?
AND COALESCE(bp.investimento, 0) = 1
AND cp.status IN ('A pagar', 'A receber')
THEN cp.valor
ELSE 0
END
), 0) AS investimentosPendentes,
COUNT(
CASE
WHEN cp.movimento = 'Saida'
AND b.idusuarios = ?
AND COALESCE(cc.investimento, 0) = 1
AND cp.status = 'Pago'
THEN 1
WHEN cp.movimento = 'Sangria'
AND b.idusuarios = ?
AND bp.idusuarios = ?
AND COALESCE(bp.investimento, 0) = 1
AND cp.status IN ('Pago', 'Recebido')
THEN 1
ELSE NULL
END
) AS quantidadeInvestimentosRealizados,
COUNT(
CASE
WHEN cp.movimento = 'Saida'
AND b.idusuarios = ?
AND COALESCE(cc.investimento, 0) = 1
AND cp.status = 'A pagar'
THEN 1
WHEN cp.movimento = 'Sangria'
AND b.idusuarios = ?
AND bp.idusuarios = ?
AND COALESCE(bp.investimento, 0) = 1
AND cp.status IN ('A pagar', 'A receber')
THEN 1
ELSE NULL
END
) AS quantidadeInvestimentosPendentes,
/* ==================================================
* INFORMAÇÕES AUXILIARES
* ================================================== */
COALESCE(SUM(
CASE
WHEN cp.movimento = 'Estorno'
AND b.idusuarios = ?
THEN cp.valor
ELSE 0
END
), 0) AS totalEstornos,
COALESCE(SUM(
CASE
WHEN cp.saldo_processado = 1
THEN 1
ELSE 0
END
), 0) AS saldoProcessado
ELSE 'neutro'
END AS direcao_financeira
${FROM_MOVIMENTO_JOIN}
${whereSql}
) base_resumo
`,
[
/* Entradas: total, recebido, pendente e quantidades */
idUsuario, idUsuario, idUsuario,
idUsuario, idUsuario, idUsuario,
idUsuario, idUsuario, idUsuario,
idUsuario, idUsuario, idUsuario,
idUsuario, idUsuario, idUsuario,
/* Saídas: total, pago, pendente e quantidades */
idUsuario, idUsuario, idUsuario,
idUsuario, idUsuario, idUsuario,
idUsuario, idUsuario, idUsuario,
idUsuario, idUsuario, idUsuario,
idUsuario, idUsuario, idUsuario,
/* Investimentos: total, realizado, pendente e quantidades */
idUsuario, idUsuario, idUsuario,
idUsuario, idUsuario, idUsuario,
idUsuario, idUsuario, idUsuario,
idUsuario, idUsuario, idUsuario,
idUsuario, idUsuario, idUsuario,
/* Estornos */
/* totalEstornos */
idUsuario,
/* Filtros */
/* direcao_financeira */
idUsuario,
idUsuario,
idUsuario,
idUsuario, idUsuario,
idUsuario, idUsuario,
idUsuario, idUsuario,
idUsuario, idUsuario,
/* filtros */
...paramsWhere,
]
);
@ -856,10 +735,6 @@ async function buscarResumoMovimentos(
saldo,
/*
* Campos antigos neutralizados temporariamente.
* Podem ser removidos após o front ser atualizado.
*/
totalSangrias: 0,
totalBaixado: 0,
totalAberto: 0,