diff --git a/src/app/api/analitico-filial-oracle/route.ts b/src/app/api/analitico-filial-oracle/route.ts index 7d415af..6dae070 100644 --- a/src/app/api/analitico-filial-oracle/route.ts +++ b/src/app/api/analitico-filial-oracle/route.ts @@ -53,8 +53,13 @@ export async function GET(request: NextRequest) { const params: any[] = []; let paramIndex = 1; + // Verificar se há múltiplas filiais (separadas por vírgula) + const filiaisArray = codFilial ? codFilial.split(',').map(f => f.trim()).filter(f => f !== '') : []; + const temJoin = filiaisArray.length > 0; + const prefixo = temJoin ? 'VB.' : ''; // Usar prefixo apenas quando há JOIN + // Se houver filtro por filial, fazer JOIN com FILIAL_CC - if (codFilial) { + if (temJoin) { sql = `SELECT FC.CODFILIAL, VB.* FROM VB_DRE_FILIAL_DESPESA_ANALITICO VB INNER JOIN FILIAL_CC FC ON FC.CC = VB.CODIGOCENTROCUSTO @@ -64,16 +69,26 @@ 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); + // Se houver múltiplas filiais, usar IN; caso contrário, usar = + if (temJoin) { + if (filiaisArray.length === 1) { + // Uma única filial - usar = + sql += ` AND FC.CODFILIAL = :${paramIndex}`; + params.push(filiaisArray[0]); + paramIndex++; + console.log('🏢 Adicionando filtro de filial única (CODFILIAL):', filiaisArray[0]); + } else { + // Múltiplas filiais - usar IN + const placeholders = filiaisArray.map(() => `:${paramIndex++}`).join(','); + sql += ` AND FC.CODFILIAL IN (${placeholders})`; + params.push(...filiaisArray); + console.log('🏢 Adicionando filtro de múltiplas filiais (CODFILIAL IN):', filiaisArray); + } } // Filtro por período (usando ANOMESCOMP) if (dataInicio && dataFim) { - sql += ` AND VB.ANOMESCOMP >= :${paramIndex} AND VB.ANOMESCOMP <= :${paramIndex + 1}`; + sql += ` AND ${prefixo}ANOMESCOMP >= :${paramIndex} AND ${prefixo}ANOMESCOMP <= :${paramIndex + 1}`; params.push(dataInicio, dataFim); paramIndex += 2; console.log('📅 Adicionando filtro de período:', dataInicio, 'a', dataFim); @@ -81,7 +96,7 @@ WHERE 1=1`; // Filtro por código do grupo if (codigoGrupo) { - sql += ` AND VB.CODGRUPO = :${paramIndex}`; + sql += ` AND ${prefixo}CODGRUPO = :${paramIndex}`; params.push(codigoGrupo); paramIndex++; console.log('📊 Adicionando filtro de grupo:', codigoGrupo); @@ -89,7 +104,7 @@ WHERE 1=1`; // Filtro por subgrupo (DIRETO, INDIRETO, SEM CC, etc.) if (codigoSubgrupo) { - sql += ` AND VB.SUBGRUPO = :${paramIndex}`; + sql += ` AND ${prefixo}SUBGRUPO = :${paramIndex}`; params.push(codigoSubgrupo); paramIndex++; console.log('📊 Adicionando filtro de subgrupo:', codigoSubgrupo); @@ -97,11 +112,11 @@ WHERE 1=1`; // Filtro por código da conta if (codigoConta) { - sql += ` AND VB.CODCONTA = :${paramIndex}`; + sql += ` AND ${prefixo}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 @@ -119,7 +134,7 @@ WHERE 1=1`; 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}`; + sql += ` AND ${prefixo}CODIGOCENTROCUSTO = :${paramIndex}`; params.push(centroCusto); paramIndex++; console.log('🏢 PRIORIDADE: Filtrando APENAS por centroCusto individual (clique na célula):', centroCusto); @@ -130,7 +145,7 @@ WHERE 1=1`; const codigosArray = codigosCentrosCustoSelecionados.split(',').filter(c => c.trim() !== ''); if (codigosArray.length > 0) { const placeholders = codigosArray.map(() => `:${paramIndex++}`).join(','); - sql += ` AND VB.CODIGOCENTROCUSTO IN (${placeholders})`; + sql += ` AND ${prefixo}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) + '...'); @@ -142,7 +157,7 @@ WHERE 1=1`; // 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}`; + sql += ` AND ${prefixo}CODIGOCENTROCUSTO != :${paramIndex}`; params.push(excluirCentroCusto); paramIndex++; console.log('🚫 Excluindo centro de custo:', excluirCentroCusto); @@ -150,7 +165,7 @@ WHERE 1=1`; // Exclusão de código de conta específico (quando desmarcado) if (excluirCodigoConta) { - sql += ` AND VB.CODCONTA != :${paramIndex}`; + sql += ` AND ${prefixo}CODCONTA != :${paramIndex}`; params.push(excluirCodigoConta); paramIndex++; console.log('🚫 Excluindo código de conta:', excluirCodigoConta); @@ -160,12 +175,12 @@ WHERE 1=1`; if (codigosContasSelecionadas) { const codigosArray = codigosContasSelecionadas.split(','); const placeholders = codigosArray.map(() => `:${paramIndex++}`).join(','); - sql += ` AND VB.CODCONTA IN (${placeholders})`; + sql += ` AND ${prefixo}CODCONTA IN (${placeholders})`; params.push(...codigosArray); console.log('💰 Filtrando por códigos de contas:', codigosArray); } - sql += ` ORDER BY VB.DTVENC, VB.CODFORNEC, VB.CODCONTA`; + sql += ` ORDER BY ${prefixo}DTVENC, ${prefixo}CODFORNEC, ${prefixo}CODCONTA`; // Log detalhado da query SQL final console.log('═══════════════════════════════════════════════════════════════'); diff --git a/src/app/dre-filial/teste.tsx b/src/app/dre-filial/teste.tsx index 44e706c..c95f67e 100644 --- a/src/app/dre-filial/teste.tsx +++ b/src/app/dre-filial/teste.tsx @@ -102,42 +102,97 @@ const TableRow = memo(({ {/* Colunas de valores por mês e por filial - cada filial tem suas próprias colunas */} - {mesesDisponiveis.map((mes) => - ((filtrosAplicados && filiaisSelecionadas.length > 0) ? filiaisSelecionadas : (opcoesFiliais.length > 0 ? opcoesFiliais : [''])).map((filial: string) => { - // Só exibir se a filial estiver selecionada ou se não houver filtros aplicados - if (filtrosAplicados && filiaisSelecionadas.length > 0 && !filiaisSelecionadas.includes(filial)) { - return null; - } - return ( - - handleRowClick(row, mes, filial)} - title={ - filial && row.valoresPorMesPorFilial?.[mes]?.[filial] !== undefined - ? formatCurrency(row.valoresPorMesPorFilial[mes][filial]) - : row.valoresPorMes?.[mes] !== undefined - ? formatCurrency(row.valoresPorMes[mes]) - : "-" + {mesesDisponiveis.map((mes) => { + const filiaisParaMes = (filtrosAplicados && filiaisSelecionadas.length > 0) + ? filiaisSelecionadas + : (opcoesFiliais.length > 0 ? opcoesFiliais : ['']); + + return ( + + {/* Colunas de filiais para este mês */} + {filiaisParaMes.map((filial: string) => { + // Só exibir se a filial estiver selecionada ou se não houver filtros aplicados + if (filtrosAplicados && filiaisSelecionadas.length > 0 && !filiaisSelecionadas.includes(filial)) { + return null; } + return ( + + handleRowClick(row, mes, filial)} + title={ + filial && row.valoresPorMesPorFilial?.[mes]?.[filial] !== undefined + ? formatCurrency(row.valoresPorMesPorFilial[mes][filial]) + : row.valoresPorMes?.[mes] !== undefined + ? formatCurrency(row.valoresPorMes[mes]) + : "-" + } + > + {filial && row.valoresPorMesPorFilial?.[mes]?.[filial] !== undefined && row.valoresPorMesPorFilial[mes][filial] !== 0 ? ( + (() => { + const valor = row.valoresPorMesPorFilial[mes][filial]; + const { formatted, isNegative } = formatCurrencyWithColor(valor); + return ( + + {formatted} + + ); + })() + ) : !filial && row.valoresPorMes?.[mes] !== undefined ? ( + (() => { + const { formatted, isNegative } = formatCurrencyWithColor(row.valoresPorMes[mes]); + return ( + + {formatted} + + ); + })() + ) : ( + - + )} + + handleRowClick(row, mes, filial)} + title={ + filial && row.percentuaisPorMesPorFilial?.[mes]?.[filial] !== undefined + ? `${row.percentuaisPorMesPorFilial[mes][filial].toFixed(1)}%` + : row.percentuaisPorMes?.[mes] !== undefined + ? `${row.percentuaisPorMes[mes].toFixed(1)}%` + : "-" + } + > + {filial && row.percentuaisPorMesPorFilial?.[mes]?.[filial] !== undefined && row.percentuaisPorMesPorFilial[mes][filial] !== 0 ? ( + `${row.percentuaisPorMesPorFilial[mes][filial].toFixed(1)}%` + ) : !filial && row.percentuaisPorMes?.[mes] !== undefined ? ( + `${row.percentuaisPorMes[mes].toFixed(1)}%` + ) : ( + - + )} + + + ); + })} + + {/* Colunas de totalizador para este mês */} + handleRowClick(row, mes)} + title={row.valoresPorMes?.[mes] !== undefined ? formatCurrency(row.valoresPorMes[mes]) : "-"} > - {filial && row.valoresPorMesPorFilial?.[mes]?.[filial] !== undefined && row.valoresPorMesPorFilial[mes][filial] !== 0 ? ( - (() => { - const valor = row.valoresPorMesPorFilial[mes][filial]; - const { formatted, isNegative } = formatCurrencyWithColor(valor); - return ( - - {formatted} - - ); - })() - ) : !filial && row.valoresPorMes?.[mes] !== undefined ? ( + {row.valoresPorMes?.[mes] !== undefined ? ( (() => { const { formatted, isNegative } = formatCurrencyWithColor(row.valoresPorMes[mes]); return ( @@ -145,7 +200,7 @@ const TableRow = memo(({ className={ isNegative ? "text-red-600 font-bold" - : "text-gray-900" + : "text-green-700 font-bold" } > {formatted} @@ -157,28 +212,21 @@ const TableRow = memo(({ )} handleRowClick(row, mes, filial)} + className="px-2 py-1 text-center font-bold cursor-pointer hover:bg-green-50/50 transition-colors duration-200 whitespace-nowrap overflow-hidden w-[100px] min-w-[100px] bg-green-50/30" + onClick={() => handleRowClick(row, mes)} title={ - filial && row.percentuaisPorMesPorFilial?.[mes]?.[filial] !== undefined - ? `${row.percentuaisPorMesPorFilial[mes][filial].toFixed(1)}%` - : row.percentuaisPorMes?.[mes] !== undefined + row.percentuaisPorMes?.[mes] !== undefined ? `${row.percentuaisPorMes[mes].toFixed(1)}%` : "-" } > - {filial && row.percentuaisPorMesPorFilial?.[mes]?.[filial] !== undefined && row.percentuaisPorMesPorFilial[mes][filial] !== 0 ? ( - `${row.percentuaisPorMesPorFilial[mes][filial].toFixed(1)}%` - ) : !filial && row.percentuaisPorMes?.[mes] !== undefined ? ( - `${row.percentuaisPorMes[mes].toFixed(1)}%` - ) : ( - - - )} + {row.percentuaisPorMes?.[mes] !== undefined + ? `${row.percentuaisPorMes[mes].toFixed(1)}%` + : -} ); - }) - )} + })} {/* Coluna Total */} { console.log('🖱️ Clique na linha:', row); console.log('📅 Mês selecionado:', mesSelecionado); + console.log('🏢 Filial selecionada:', filialSelecionada); // Linhas calculadas não devem abrir o componente analítico if (row.type === "calculado") { @@ -405,6 +454,15 @@ export default function Teste() { return false; } + // Se é um totalizador (mesSelecionado presente mas filialSelecionada não), não filtrar por filial + // Caso contrário, filtrar por filial se especificada + if (filialSelecionada) { + const itemFilial = item.filial || item.codfilial || ""; + if (itemFilial !== filialSelecionada) { + return false; + } + } + if (row.type === "grupo") { return item.codigo_grupo === row.codigo_grupo || item.codgrupo === row.codigo_grupo; } else if (row.type === "conta") { @@ -427,6 +485,7 @@ export default function Teste() { } // Determinar CODFILIAL baseado na filial selecionada + // Se é um totalizador (mesSelecionado presente mas filialSelecionada não), incluir todas as filiais selecionadas let codFilialFiltro = ""; if (filialSelecionada) { // Se a filial selecionada já é um código numérico, usar diretamente @@ -446,6 +505,29 @@ export default function Teste() { codFilialFiltro = filialSelecionada; } } + } else if (mesSelecionado) { + // Se mesSelecionado está presente mas filialSelecionada não, é um totalizador + // Incluir todas as filiais selecionadas (ou todas disponíveis se nenhuma estiver selecionada) + const filiaisParaTotalizador = filiaisSelecionadas.length > 0 + ? filiaisSelecionadas + : opcoesFiliais; + + // Converter nomes de filiais para códigos CODFILIAL + const codigosFiliais = filiaisParaTotalizador.map(filial => { + if (/^\d+$/.test(filial)) { + return filial; + } else { + const itemComFilial = data.find((item: DREItem) => { + const itemFilial = item.filial || item.codfilial || ""; + return itemFilial === filial; + }); + return itemComFilial?.codfilial || filial; + } + }).filter(Boolean); + + // Passar como string separada por vírgula para a API processar com IN + codFilialFiltro = codigosFiliais.join(','); + console.log('📊 Totalizador: incluindo todas as filiais selecionadas:', codigosFiliais); } const novosFiltros = { @@ -455,7 +537,7 @@ export default function Teste() { codigoGrupo: codigoGrupoFiltro, codigoSubgrupo: "", // Não aplicável na hierarquia filial codigoConta: codigoContaFiltro, - codFilial: codFilialFiltro, + codFilial: codFilialFiltro, // Vazio para totalizador = todas as filiais do mês linhaSelecionada: row.grupo || row.conta || "", excluirCentroCusto: "", excluirCodigoConta: "", @@ -464,8 +546,9 @@ export default function Teste() { }; console.log('🎯 Novos filtros para analítico:', novosFiltros); + console.log('📊 É totalizador?', mesSelecionado && !filialSelecionada ? 'SIM' : 'NÃO'); setAnaliticoFiltros(novosFiltros); - }, [data]); + }, [data, filiaisSelecionadas, opcoesFiliais]); const toggleGrupo = useCallback((codigoGrupo: string) => { setExpandedGrupos(prev => { @@ -1431,20 +1514,39 @@ export default function Teste() { Descrição - {mesesDisponiveis.map((mes) => - ((filtrosAplicados && filiaisSelecionadas.length > 0) ? filiaisSelecionadas : (opcoesFiliais.length > 0 ? opcoesFiliais : [''])).map((filial: string) => ( - - - {mes}{filial && <>
- Filial - {filial}} + {mesesDisponiveis.map((mes) => { + const filiaisParaMes = (filtrosAplicados && filiaisSelecionadas.length > 0) + ? filiaisSelecionadas + : (opcoesFiliais.length > 0 ? opcoesFiliais : ['']); + + return ( + + {/* Cabeçalhos de filiais para este mês */} + {filiaisParaMes.map((filial: string) => ( + + + {mes}{filial && <>
+ Filial - {filial}} + + + %{filial && <>
+ Filial - {filial}} + +
+ ))} + + {/* Cabeçalhos de totalizador para este mês */} + + {mes}
+ Total - - %{filial && <>
- Filial - {filial}} + + %
+ Total
- )) - )} + ); + })} Total