diff --git a/src/app/api/analitico-filial-oracle/route.ts b/src/app/api/analitico-filial-oracle/route.ts
new file mode 100644
index 0000000..7d415af
--- /dev/null
+++ b/src/app/api/analitico-filial-oracle/route.ts
@@ -0,0 +1,278 @@
+import { NextRequest, NextResponse } from 'next/server';
+import { executeOracleQuery } from '@/db/oracle';
+
+export async function GET(request: NextRequest) {
+ try {
+ console.log('🔄 Buscando dados analíticos do Oracle (Filial)...');
+ console.log('📋 URL completa:', request.url);
+ console.log('🔍 Query params:', request.nextUrl.searchParams.toString());
+ console.log('📊 Headers:', Object.fromEntries(request.headers.entries()));
+
+ // Extrair parâmetros de query
+ const searchParams = request.nextUrl.searchParams;
+ const dataInicio = searchParams.get('dataInicio');
+ const dataFim = searchParams.get('dataFim');
+ const centroCusto = searchParams.get('centroCusto');
+ const codigoGrupo = searchParams.get('codigoGrupo');
+ const codigoSubgrupo = searchParams.get('codigoSubgrupo');
+ const codigoConta = searchParams.get('codigoConta');
+ const codFilial = searchParams.get('codFilial');
+
+ // Parâmetros para exclusão de valores específicos
+ const excluirCentroCusto = searchParams.get('excluirCentroCusto');
+ const excluirCodigoConta = searchParams.get('excluirCodigoConta');
+
+ // Novos parâmetros para códigos selecionados no filtro
+ const codigosCentrosCustoSelecionados = searchParams.get('codigosCentrosCustoSelecionados');
+ const codigosContasSelecionadas = searchParams.get('codigosContasSelecionadas');
+
+ console.log('🎯 Filtros recebidos na API:', {
+ dataInicio,
+ dataFim,
+ centroCusto,
+ codigoGrupo,
+ codigoSubgrupo,
+ codigoConta,
+ codFilial,
+ excluirCentroCusto,
+ excluirCodigoConta,
+ codigosCentrosCustoSelecionados,
+ codigosContasSelecionadas
+ });
+ console.log('🔍 Verificação específica de centroCusto:', {
+ centroCusto,
+ tipo: typeof centroCusto,
+ vazio: centroCusto === null || centroCusto === undefined || centroCusto === '',
+ codigosCentrosCustoSelecionados,
+ codigosCentrosCustoSelecionadosVazio: !codigosCentrosCustoSelecionados || codigosCentrosCustoSelecionados === ''
+ });
+
+ // Construir query SQL com filtros usando a view VB_DRE_FILIAL_DESPESA_ANALITICO
+ // Fazer JOIN com FILIAL_CC quando houver filtro por filial
+ let sql = '';
+ const params: any[] = [];
+ let paramIndex = 1;
+
+ // Se houver filtro por filial, fazer JOIN com FILIAL_CC
+ if (codFilial) {
+ sql = `SELECT FC.CODFILIAL, VB.*
+FROM VB_DRE_FILIAL_DESPESA_ANALITICO VB
+INNER JOIN FILIAL_CC FC ON FC.CC = VB.CODIGOCENTROCUSTO
+WHERE 1=1`;
+ } else {
+ sql = `SELECT * FROM VB_DRE_FILIAL_DESPESA_ANALITICO WHERE 1=1`;
+ }
+
+ // Filtro por filial (usando JOIN com FILIAL_CC)
+ if (codFilial) {
+ sql += ` AND FC.CODFILIAL = :${paramIndex}`;
+ params.push(codFilial);
+ paramIndex++;
+ console.log('🏢 Adicionando filtro de filial (CODFILIAL):', codFilial);
+ }
+
+ // Filtro por período (usando ANOMESCOMP)
+ if (dataInicio && dataFim) {
+ sql += ` AND VB.ANOMESCOMP >= :${paramIndex} AND VB.ANOMESCOMP <= :${paramIndex + 1}`;
+ params.push(dataInicio, dataFim);
+ paramIndex += 2;
+ console.log('📅 Adicionando filtro de período:', dataInicio, 'a', dataFim);
+ }
+
+ // Filtro por código do grupo
+ if (codigoGrupo) {
+ sql += ` AND VB.CODGRUPO = :${paramIndex}`;
+ params.push(codigoGrupo);
+ paramIndex++;
+ console.log('📊 Adicionando filtro de grupo:', codigoGrupo);
+ }
+
+ // Filtro por subgrupo (DIRETO, INDIRETO, SEM CC, etc.)
+ if (codigoSubgrupo) {
+ sql += ` AND VB.SUBGRUPO = :${paramIndex}`;
+ params.push(codigoSubgrupo);
+ paramIndex++;
+ console.log('📊 Adicionando filtro de subgrupo:', codigoSubgrupo);
+ }
+
+ // Filtro por código da conta
+ if (codigoConta) {
+ sql += ` AND VB.CODCONTA = :${paramIndex}`;
+ params.push(codigoConta);
+ paramIndex++;
+ console.log('💰 Adicionando filtro de conta:', codigoConta);
+ }
+
+ // Filtro por códigos de centros de custo selecionados no filtro
+ // Se houver codigosCentrosCustoSelecionados E centroCusto individual, incluir ambos
+ console.log('🔍 Antes de aplicar filtro de centro de custo:', {
+ codigosCentrosCustoSelecionados,
+ centroCusto,
+ codigosCentrosCustoSelecionadosVazio: !codigosCentrosCustoSelecionados || codigosCentrosCustoSelecionados.trim() === '',
+ centroCustoVazio: !centroCusto || centroCusto.trim() === '',
+ centroCustoLength: centroCusto?.length,
+ codigosCentrosCustoSelecionadosLength: codigosCentrosCustoSelecionados?.length
+ });
+
+ // IMPORTANTE: Quando centroCusto individual é fornecido (clique na célula), ele tem PRIORIDADE ABSOLUTA
+ // e deve filtrar APENAS por ele, ignorando codigosCentrosCustoSelecionados do filtro geral
+ if (centroCusto && centroCusto.trim() !== '') {
+ // Quando há centroCusto individual (clique na célula), usar APENAS ele
+ // Ignorar codigosCentrosCustoSelecionados do filtro geral para garantir filtro preciso
+ sql += ` AND VB.CODIGOCENTROCUSTO = :${paramIndex}`;
+ params.push(centroCusto);
+ paramIndex++;
+ console.log('🏢 PRIORIDADE: Filtrando APENAS por centroCusto individual (clique na célula):', centroCusto);
+ console.log('⚠️ Ignorando codigosCentrosCustoSelecionados do filtro geral quando há centroCusto individual');
+ console.log('📝 SQL após adicionar filtro =:', sql.substring(0, 200) + '...');
+ } else if (codigosCentrosCustoSelecionados && codigosCentrosCustoSelecionados.trim() !== '') {
+ // Se só codigosCentrosCustoSelecionados existe (sem clique na célula), usar ele
+ const codigosArray = codigosCentrosCustoSelecionados.split(',').filter(c => c.trim() !== '');
+ if (codigosArray.length > 0) {
+ const placeholders = codigosArray.map(() => `:${paramIndex++}`).join(',');
+ sql += ` AND VB.CODIGOCENTROCUSTO IN (${placeholders})`;
+ params.push(...codigosArray);
+ console.log('🏢 Filtrando por códigos de centros de custo selecionados (filtro geral):', codigosArray);
+ console.log('📝 SQL após adicionar filtro IN:', sql.substring(0, 200) + '...');
+ }
+ } else {
+ console.log('⚠️ Nenhum filtro de centro de custo aplicado - ambos estão vazios');
+ }
+
+ // Exclusão de centro de custo específico (quando desmarcado)
+ // Só aplicar se não houver codigosCentrosCustoSelecionados, para evitar conflito
+ if (excluirCentroCusto && !codigosCentrosCustoSelecionados) {
+ sql += ` AND VB.CODIGOCENTROCUSTO != :${paramIndex}`;
+ params.push(excluirCentroCusto);
+ paramIndex++;
+ console.log('🚫 Excluindo centro de custo:', excluirCentroCusto);
+ }
+
+ // Exclusão de código de conta específico (quando desmarcado)
+ if (excluirCodigoConta) {
+ sql += ` AND VB.CODCONTA != :${paramIndex}`;
+ params.push(excluirCodigoConta);
+ paramIndex++;
+ console.log('🚫 Excluindo código de conta:', excluirCodigoConta);
+ }
+
+ // Filtro por códigos de contas selecionadas no filtro
+ if (codigosContasSelecionadas) {
+ const codigosArray = codigosContasSelecionadas.split(',');
+ const placeholders = codigosArray.map(() => `:${paramIndex++}`).join(',');
+ sql += ` AND VB.CODCONTA IN (${placeholders})`;
+ params.push(...codigosArray);
+ console.log('💰 Filtrando por códigos de contas:', codigosArray);
+ }
+
+ sql += ` ORDER BY VB.DTVENC, VB.CODFORNEC, VB.CODCONTA`;
+
+ // Log detalhado da query SQL final
+ console.log('═══════════════════════════════════════════════════════════════');
+ console.log('🗄️ QUERY SQL FINAL:');
+ console.log('═══════════════════════════════════════════════════════════════');
+ console.log(sql);
+ console.log('═══════════════════════════════════════════════════════════════');
+ console.log('📋 PARÂMETROS FINAIS (na ordem dos placeholders :1, :2, :3, ...):');
+ console.log('═══════════════════════════════════════════════════════════════');
+ params.forEach((param, index) => {
+ console.log(` :${index + 1} = ${param} (${typeof param})`);
+ });
+ console.log('═══════════════════════════════════════════════════════════════');
+ console.log('📊 RESUMO DOS FILTROS APLICADOS:');
+ console.log('═══════════════════════════════════════════════════════════════');
+ console.log({
+ temPeriodo: dataInicio && dataFim,
+ periodo: dataInicio && dataFim ? `${dataInicio} a ${dataFim}` : 'N/A',
+ temCodigoGrupo: !!codigoGrupo,
+ codigoGrupo: codigoGrupo || 'N/A',
+ temCodigoSubgrupo: !!codigoSubgrupo,
+ codigoSubgrupo: codigoSubgrupo || 'N/A',
+ temCentroCusto: !!centroCusto,
+ centroCusto: centroCusto || 'N/A',
+ temCodigosCentrosCustoSelecionados: !!codigosCentrosCustoSelecionados,
+ codigosCentrosCustoSelecionados: codigosCentrosCustoSelecionados || 'N/A',
+ temCodigoConta: !!codigoConta,
+ codigoConta: codigoConta || 'N/A',
+ temCodFilial: !!codFilial,
+ codFilial: codFilial || 'N/A',
+ temCodigosContasSelecionadas: !!codigosContasSelecionadas,
+ codigosContasSelecionadas: codigosContasSelecionadas || 'N/A',
+ temExcluirCentroCusto: !!excluirCentroCusto,
+ excluirCentroCusto: excluirCentroCusto || 'N/A',
+ temExcluirCodigoConta: !!excluirCodigoConta,
+ excluirCodigoConta: excluirCodigoConta || 'N/A'
+ });
+ console.log('═══════════════════════════════════════════════════════════════');
+
+ // Se há centroCusto individual, destacar especialmente
+ if (centroCusto && centroCusto.trim() !== '') {
+ console.log('🎯 FILTRO INDIVIDUAL DE CENTRO DE CUSTO ATIVO (clique na célula)');
+ console.log(` Centro de Custo: ${centroCusto}`);
+ console.log(' ⚠️ Este filtro tem PRIORIDADE sobre codigosCentrosCustoSelecionados');
+ }
+ console.log('═══════════════════════════════════════════════════════════════');
+
+ const data = await executeOracleQuery(sql, params);
+
+ console.log('✅ Query executada com sucesso:', data.length, 'registros encontrados');
+ console.log('📝 Primeiros 3 registros:', data.slice(0, 3));
+
+ // Transformar os dados do Oracle para o formato esperado pelo componente
+ // Usando a view VB_DRE_FILIAL_DESPESA_ANALITICO
+ const transformedData = data.map((item: any) => {
+ return {
+ codigo_grupo: item.CODGRUPO || "",
+ codigo_subgrupo: item.SUBGRUPO || "", // SUBGRUPO existe na nova view
+ codigo_fornecedor: item.CODFORNEC || "",
+ nome_fornecedor: item.FORNECEDOR || "",
+ id: item.NUMLANC || 0,
+ codfilial: item.CODFILIAL || item.FILIAL || "001", // Usar CODFILIAL do JOIN ou FILIAL da view
+ recnum: item.NUMLANC || 0,
+ data_competencia: item.ANOMESCOMP || "",
+ data_vencimento: item.DTVENC ? new Date(item.DTVENC).toISOString().split('T')[0] : "",
+ data_pagamento: item.DTPAGTO ? new Date(item.DTPAGTO).toISOString().split('T')[0] : "",
+ data_caixa: item.DTCAIXA ? new Date(item.DTCAIXA).toISOString().split('T')[0] : "",
+ codigo_conta: item.CODCONTA || "",
+ conta: item.CONTA || "",
+ codigo_centrocusto: item.CODIGOCENTROCUSTO || "",
+ centro_custo: item.CENTROCUSTO || "",
+ valor: item.VLREALIZADO !== null && item.VLREALIZADO !== undefined ? Number(item.VLREALIZADO) : 0,
+ historico: item.HISTORICO || "",
+ historico2: item.HISTORICO2 || "",
+ created_at: new Date().toISOString(),
+ updated_at: new Date().toISOString(),
+ // Campos adicionais do Oracle
+ entidade: item.ENTIDADE || "",
+ tipo_parceiro: item.TIPOPARCEIRO || "",
+ valor_previsto: item.VLPREVISTO !== null && item.VLPREVISTO !== undefined ? Number(item.VLPREVISTO) : 0,
+ valor_confirmado: item.VLCONFIRMADO !== null && item.VLCONFIRMADO !== undefined ? Number(item.VLCONFIRMADO) : 0,
+ valor_pago: item.VLPAGO !== null && item.VLPAGO !== undefined ? Number(item.VLPAGO) : 0,
+ numero_lancamento: item.NUMLANC || 0,
+ ano_mes_comp: item.ANOMESCOMP || "",
+ codgrupo: item.CODGRUPO || "",
+ // Novos campos
+ data_lancamento: item.DTLANC ? new Date(item.DTLANC).toISOString().split('T')[0] : "",
+ data_compensacao: item.DTCOMPENSACAO ? new Date(item.DTCOMPENSACAO).toISOString().split('T')[0] : "",
+ data_pagto: item.DTPAGTO ? new Date(item.DTPAGTO).toISOString().split('T')[0] : ""
+ };
+ });
+
+ console.log('🔄 Dados transformados:', transformedData.length, 'registros');
+ console.log('📝 Primeiros 3 transformados:', transformedData.slice(0, 3));
+
+ return NextResponse.json(transformedData);
+
+ } catch (error) {
+ console.error('❌ Erro ao buscar dados analíticos do Oracle (Filial):', error);
+
+ return NextResponse.json(
+ {
+ success: false,
+ error: error instanceof Error ? error.message : 'Erro desconhecido',
+ details: error instanceof Error ? error.stack : undefined
+ },
+ { status: 500 }
+ );
+ }
+}
diff --git a/src/app/api/dre-filial-oracle/route.ts b/src/app/api/dre-filial-oracle/route.ts
new file mode 100644
index 0000000..c4ae29a
--- /dev/null
+++ b/src/app/api/dre-filial-oracle/route.ts
@@ -0,0 +1,102 @@
+import { NextRequest, NextResponse } from 'next/server';
+import { executeOracleQuery } from '@/db/oracle';
+
+export async function GET(request: NextRequest) {
+ try {
+ console.log('🔄 Buscando dados DRE do Oracle (Filial) - Views VB_DRE_FILIAL_*...');
+
+ // Query para buscar dados das views VB_DRE_FILIAL_CMV, VB_DRE_FILIAL_DESPESA e VB_DRE_FILIAL_FATLIQ
+ const sql = `SELECT *
+FROM (
+ SELECT 'CMV' AS TIPO,
+ "DATA",
+ CODGRUPO, GRUPO, FILIAL, CODCONTA, CONTA, VALOR
+ FROM SEVEN.VB_DRE_FILIAL_CMV
+ UNION ALL
+ SELECT 'DESPESA' AS TIPO,
+ "DATA",
+ CODGRUPO, GRUPO, FILIAL, CODCONTA, CONTA, VALOR
+ FROM SEVEN.VB_DRE_FILIAL_DESPESA
+ UNION ALL
+ SELECT 'FATLIQ' AS TIPO,
+ "DATA",
+ CODGRUPO, GRUPO, FILIAL, CODCONTA, CONTA, VALOR
+ FROM SEVEN.VB_DRE_FILIAL_FATLIQ
+) X
+ORDER BY CODGRUPO, CODCONTA`;
+
+ const data = await executeOracleQuery(sql);
+
+ console.log('✅ Query executada com sucesso:', data.length, 'registros encontrados');
+
+ // Debug: Verificar estrutura dos dados
+ if (data.length > 0) {
+ console.log('🔍 Primeiro registro do Oracle:', Object.keys(data[0]));
+ console.log('🔍 Primeiro registro completo:', data[0]);
+ console.log('🔍 Valores únicos de CODGRUPO:', [...new Set(data.map((item: any) => item.CODGRUPO).filter(Boolean))]);
+ console.log('🔍 Valores únicos de FILIAL:', [...new Set(data.map((item: any) => item.FILIAL).filter(Boolean))]);
+ }
+
+ // Transformar os dados do Oracle para o formato esperado pelo componente
+ const transformedData = data.map((item: any) => {
+ // Converter DATA para formato YYYY-MM se necessário
+ let dataCompetencia = item.DATA;
+ if (dataCompetencia) {
+ // Se DATA for uma string no formato YYYY-MM, usar diretamente
+ if (typeof dataCompetencia === 'string' && dataCompetencia.match(/^\d{4}-\d{2}$/)) {
+ // Já está no formato correto
+ } else if (dataCompetencia instanceof Date) {
+ // Se for Date, converter para YYYY-MM
+ const year = dataCompetencia.getFullYear();
+ const month = String(dataCompetencia.getMonth() + 1).padStart(2, '0');
+ dataCompetencia = `${year}-${month}`;
+ } else {
+ // Tentar converter string de data para YYYY-MM
+ try {
+ const date = new Date(dataCompetencia);
+ const year = date.getFullYear();
+ const month = String(date.getMonth() + 1).padStart(2, '0');
+ dataCompetencia = `${year}-${month}`;
+ } catch (e) {
+ console.warn('⚠️ Erro ao converter DATA:', dataCompetencia);
+ dataCompetencia = "2023-03"; // Valor padrão
+ }
+ }
+ } else {
+ dataCompetencia = "2023-03"; // Valor padrão
+ }
+
+ return {
+ codfilial: item.FILIAL || "001",
+ data_competencia: dataCompetencia,
+ data_cai: dataCompetencia,
+ grupo: item.GRUPO || "", // GRUPO (nome)
+ codigo_grupo: item.CODGRUPO || "", // CODGRUPO (código)
+ codigo_conta: parseInt(item.CODCONTA) || 0, // Converter CODCONTA para número
+ conta: item.CONTA || "", // CONTA
+ valor: item.VALOR?.toString() || "0", // Converter VALOR para string
+ codgrupo: item.CODGRUPO || "", // CODGRUPO
+ tipo: item.TIPO || "", // TIPO (CMV, DESPESA, FATLIQ)
+ filial: item.FILIAL || "", // FILIAL
+ };
+ });
+
+ console.log('✅ Dados transformados:', transformedData.length, 'registros');
+ console.log('🔍 Exemplo de registro transformado:', transformedData[0]);
+
+ return NextResponse.json(transformedData);
+
+ } catch (error) {
+ console.error('❌ Erro ao buscar dados DRE do Oracle:', error);
+
+ return NextResponse.json(
+ {
+ success: false,
+ error: error instanceof Error ? error.message : 'Erro desconhecido',
+ details: error instanceof Error ? error.stack : undefined
+ },
+ { status: 500 }
+ );
+ }
+}
+
diff --git a/src/app/dre-entidade/teste.tsx b/src/app/dre-entidade/teste.tsx
index 1bc9c2b..6310086 100644
--- a/src/app/dre-entidade/teste.tsx
+++ b/src/app/dre-entidade/teste.tsx
@@ -2368,7 +2368,7 @@ export default function Teste() {
))}
-
+