const pool = require('../../../database/mysql'); function resolverCampoData(dataCampo) { const camposPermitidos = { dataentrada: 'cp.dataentrada', datavencimento: 'cp.datavencimento', databaixa: 'cp.databaixa', insert_date: 'cp.insert_date', update_date: 'cp.update_date', }; return camposPermitidos[dataCampo] || 'cp.datavencimento'; } function montarWhereRelatorio(filtros = {}) { const where = []; const params = []; const campoData = resolverCampoData(filtros.dataCampo); if (filtros.dataInicio) { where.push(`DATE(${campoData}) >= ?`); params.push(filtros.dataInicio); } if (filtros.dataFim) { where.push(`DATE(${campoData}) <= ?`); params.push(filtros.dataFim); } if (filtros.movimento) { where.push('cp.movimento = ?'); params.push(filtros.movimento); } if (filtros.status) { where.push('cp.status = ?'); params.push(filtros.status); } if (filtros.idbancos) { where.push('cp.idbancos = ?'); params.push(Number(filtros.idbancos)); } if (filtros.idcentrodecustos) { where.push('cp.idcentrodecustos = ?'); params.push(Number(filtros.idcentrodecustos)); } if (filtros.idclientes) { where.push('cp.idclientes = ?'); params.push(Number(filtros.idclientes)); } const whereSql = where.length > 0 ? `WHERE ${where.join(' AND ')}` : ''; return { campoData, whereSql, params, }; } async function buscarResumo(filtros = {}) { const { whereSql, params } = montarWhereRelatorio(filtros); const [rows] = await pool.query( ` SELECT COUNT(*) AS quantidade, COALESCE(SUM(CASE WHEN cp.movimento = 'Entrada' THEN cp.valor ELSE 0 END), 0) AS totalEntradas, COALESCE(SUM(CASE WHEN cp.movimento = 'Saida' THEN cp.valor ELSE 0 END), 0) AS totalSaidas, COALESCE(SUM(CASE WHEN cp.movimento = 'Sangria' THEN cp.valor ELSE 0 END), 0) AS totalSangrias, COALESCE(SUM(CASE WHEN cp.movimento = 'Estorno' THEN cp.valor ELSE 0 END), 0) AS totalEstornos, COALESCE(SUM(CASE WHEN cp.status = 'Pago' THEN cp.valor ELSE 0 END), 0) AS totalPago, COALESCE(SUM(CASE WHEN cp.status = 'A pagar' THEN cp.valor ELSE 0 END), 0) AS totalAPagar, COALESCE(SUM(CASE WHEN cp.status = 'Recebido' THEN cp.valor ELSE 0 END), 0) AS totalRecebido, COALESCE(SUM(CASE WHEN cp.status = 'A receber' THEN cp.valor ELSE 0 END), 0) AS totalAReceber, COALESCE(SUM( CASE WHEN cp.movimento IN ('Entrada', 'Estorno') THEN cp.valor WHEN cp.movimento IN ('Saida', 'Sangria') THEN -cp.valor ELSE 0 END ), 0) AS saldo FROM contasapagar cp ${whereSql} `, params ); const item = rows[0] || {}; return { quantidade: Number(item.quantidade || 0), totalEntradas: Number(item.totalEntradas || 0), totalSaidas: Number(item.totalSaidas || 0), totalSangrias: Number(item.totalSangrias || 0), totalEstornos: Number(item.totalEstornos || 0), totalPago: Number(item.totalPago || 0), totalAPagar: Number(item.totalAPagar || 0), totalRecebido: Number(item.totalRecebido || 0), totalAReceber: Number(item.totalAReceber || 0), saldo: Number(item.saldo || 0), }; } async function buscarEvolucao(filtros = {}) { const { campoData, whereSql, params } = montarWhereRelatorio(filtros); const [rows] = await pool.query( ` SELECT DATE_FORMAT(${campoData}, '%Y-%m') AS periodo, COALESCE(SUM(CASE WHEN cp.movimento = 'Entrada' THEN cp.valor ELSE 0 END), 0) AS entradas, COALESCE(SUM(CASE WHEN cp.movimento IN ('Saida', 'Sangria') THEN cp.valor ELSE 0 END), 0) AS saidas, COALESCE(SUM(CASE WHEN cp.movimento = 'Estorno' THEN cp.valor ELSE 0 END), 0) AS estornos, COALESCE(SUM( CASE WHEN cp.movimento IN ('Entrada', 'Estorno') THEN cp.valor WHEN cp.movimento IN ('Saida', 'Sangria') THEN -cp.valor ELSE 0 END ), 0) AS saldo FROM contasapagar cp ${whereSql} GROUP BY DATE_FORMAT(${campoData}, '%Y-%m') ORDER BY periodo ASC `, params ); return rows.map((item) => ({ periodo: item.periodo, entradas: Number(item.entradas || 0), saidas: Number(item.saidas || 0), estornos: Number(item.estornos || 0), saldo: Number(item.saldo || 0), })); } async function buscarPorCentroCusto(filtros = {}) { const { whereSql, params } = montarWhereRelatorio(filtros); const [rows] = await pool.query( ` SELECT COALESCE(cc.descricao, 'Sem centro de custo') AS descricao, COUNT(*) AS quantidade, COALESCE(SUM(cp.valor), 0) AS total FROM contasapagar cp LEFT JOIN centrodecustos cc ON cc.idcentrodecustos = cp.idcentrodecustos ${whereSql} GROUP BY COALESCE(cc.descricao, 'Sem centro de custo') ORDER BY total DESC LIMIT 10 `, params ); return rows.map((item) => ({ descricao: item.descricao, quantidade: Number(item.quantidade || 0), total: Number(item.total || 0), })); } async function buscarPorBanco(filtros = {}) { const { whereSql, params } = montarWhereRelatorio(filtros); const [rows] = await pool.query( ` SELECT COALESCE(b.descricao, 'Sem banco/carteira') AS descricao, COUNT(*) AS quantidade, COALESCE(SUM(cp.valor), 0) AS total FROM contasapagar cp LEFT JOIN bancos b ON b.idbancos = cp.idbancos ${whereSql} GROUP BY COALESCE(b.descricao, 'Sem banco/carteira') ORDER BY total DESC LIMIT 10 `, params ); return rows.map((item) => ({ descricao: item.descricao, quantidade: Number(item.quantidade || 0), total: Number(item.total || 0), })); } async function buscarPorStatus(filtros = {}) { const { whereSql, params } = montarWhereRelatorio(filtros); const [rows] = await pool.query( ` SELECT COALESCE(cp.status, 'Sem situação') AS descricao, COUNT(*) AS quantidade, COALESCE(SUM(cp.valor), 0) AS total FROM contasapagar cp ${whereSql} GROUP BY COALESCE(cp.status, 'Sem situação') ORDER BY total DESC `, params ); return rows.map((item) => ({ descricao: item.descricao, quantidade: Number(item.quantidade || 0), total: Number(item.total || 0), })); } async function buscarPorMovimento(filtros = {}) { const { whereSql, params } = montarWhereRelatorio(filtros); const [rows] = await pool.query( ` SELECT COALESCE(cp.movimento, 'Sem movimento') AS descricao, COUNT(*) AS quantidade, COALESCE(SUM(cp.valor), 0) AS total FROM contasapagar cp ${whereSql} GROUP BY COALESCE(cp.movimento, 'Sem movimento') ORDER BY total DESC `, params ); return rows.map((item) => ({ descricao: item.descricao, quantidade: Number(item.quantidade || 0), total: Number(item.total || 0), })); } async function buscarDashboardRelatorios(filtros = {}) { const [ resumo, evolucao, porCentroCusto, porBanco, porStatus, porMovimento, ] = await Promise.all([ buscarResumo(filtros), buscarEvolucao(filtros), buscarPorCentroCusto(filtros), buscarPorBanco(filtros), buscarPorStatus(filtros), buscarPorMovimento(filtros), ]); return { resumo, evolucao, porCentroCusto, porBanco, porStatus, porMovimento, }; } module.exports = { buscarDashboardRelatorios, };