From 75e452312cd7cfe4c8fae70a3d9d61e8f3b92936 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alessandro=20Gon=C3=A7aalves?= Date: Wed, 22 Oct 2025 12:49:04 -0300 Subject: [PATCH] =?UTF-8?q?fix:=20dupla=20vis=C3=A3o?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/app/DRE/teste.tsx | 416 +++++++++++++++----------------- src/app/api/dre-oracle/route.ts | 3 +- 2 files changed, 191 insertions(+), 228 deletions(-) diff --git a/src/app/DRE/teste.tsx b/src/app/DRE/teste.tsx index 7f05b55..ceb74be 100644 --- a/src/app/DRE/teste.tsx +++ b/src/app/DRE/teste.tsx @@ -31,6 +31,7 @@ interface DREItem { grupo: string; subgrupo: string; centro_custo: string; + codigo_centro_custo: string; codigo_conta: number; conta: string; valor: string; @@ -44,6 +45,7 @@ interface HierarchicalRow { grupo?: string; subgrupo?: string; centro_custo?: string; + codigo_centro_custo?: string; conta?: string; codigo_conta?: number; total?: number; @@ -58,7 +60,6 @@ const TableRow = memo(({ row, index, toggleGroup, - toggleSubgrupo, toggleCentro, handleRowClick, getRowStyle, @@ -71,7 +72,6 @@ const TableRow = memo(({ row: HierarchicalRow; index: number; toggleGroup: (grupo: string) => void; - toggleSubgrupo: (subgrupo: string) => void; toggleCentro: (centro: string) => void; handleRowClick: (row: HierarchicalRow, mes?: string) => void; getRowStyle: (row: HierarchicalRow) => string; @@ -175,9 +175,6 @@ export default function Teste() { const [loading, setLoading] = useState(false); const [error, setError] = useState(null); const [expandedGroups, setExpandedGroups] = useState>(new Set()); - const [expandedSubgrupos, setExpandedSubgrupos] = useState>( - new Set() - ); const [expandedCentros, setExpandedCentros] = useState>( new Set() ); @@ -384,7 +381,7 @@ export default function Teste() { const novosFiltros = { dataInicio: dataInicioFiltro, dataFim: dataFimFiltro, - centroCusto: row.centro_custo || "", + centroCusto: row.codigo_centro_custo || "", // ✅ Usar código do centro de custo codigoGrupo, codigoSubgrupo, codigoConta: row.codigo_conta?.toString() || "", @@ -407,17 +404,6 @@ export default function Teste() { }); }, []); - const toggleSubgrupo = useCallback((subgrupo: string) => { - setExpandedSubgrupos(prev => { - const newExpanded = new Set(prev); - if (newExpanded.has(subgrupo)) { - newExpanded.delete(subgrupo); - } else { - newExpanded.add(subgrupo); - } - return newExpanded; - }); - }, []); const toggleCentro = useCallback((centro: string) => { setExpandedCentros(prev => { @@ -443,7 +429,7 @@ export default function Teste() { setCentrosCustoSelecionados(prev => { if (prev.includes(centro)) { return prev.filter(c => c !== centro); - } else { + } else { return [...prev, centro]; } }); @@ -453,7 +439,7 @@ export default function Teste() { setContasSelecionadas(prev => { if (prev.includes(conta)) { return prev.filter(c => c !== conta); - } else { + } else { return [...prev, conta]; } }); @@ -480,24 +466,30 @@ export default function Teste() { // Recolher tudo - usar startTransition para atualizações não urgentes startTransition(() => { setExpandedGroups(new Set()); - setExpandedSubgrupos(new Set()); setExpandedCentros(new Set()); setIsAllExpanded(false); }); } else { - // Expandir todos os grupos usando dados originais - usar startTransition para atualizações não urgentes + // Expandir todos os grupos e contas usando dados originais - usar startTransition para atualizações não urgentes startTransition(() => { const todosGrupos = [...new Set(data.map(item => item.grupo))]; - const todosSubgrupos = [...new Set(data.map(item => `${item.grupo}-${item.subgrupo}`))]; - const todosCentros = [...new Set(data.map(item => `${item.grupo}-${item.subgrupo}-${item.centro_custo}`))]; - setExpandedGroups(new Set(todosGrupos)); - setExpandedSubgrupos(new Set(todosSubgrupos)); - setExpandedCentros(new Set(todosCentros)); + if (ordemHierarquiaContasPrimeiro) { + // Nova ordem: expandir grupos e contas + const todasContas = [...new Set(data.map(item => `${item.grupo}-${item.conta}`))]; + setExpandedGroups(new Set(todosGrupos)); + setExpandedCentros(new Set(todasContas)); + } else { + // Ordem original: expandir grupos e centros de custo + const todosCentros = [...new Set(data.map(item => `${item.grupo}-${item.centro_custo}`))]; + setExpandedGroups(new Set(todosGrupos)); + setExpandedCentros(new Set(todosCentros)); + } + setIsAllExpanded(true); }); } - }, [isAllExpanded, data]); + }, [isAllExpanded, data, ordemHierarquiaContasPrimeiro]); const limparFiltros = () => { const agora = new Date(); @@ -741,99 +733,59 @@ export default function Teste() { }); if (expandedGroups.has(grupo)) { - // Agrupar por subgrupo dentro do grupo - const subgrupos = items.reduce((acc, item) => { - // Se o item originalmente era do grupo 05, agrupar tudo sob o nome do grupo 05 - if (item.grupo.includes("05")) { - const subgrupoKey = item.grupo; // Usar o nome completo do grupo 05 - if (!acc[subgrupoKey]) { - acc[subgrupoKey] = []; + if (ordemHierarquiaContasPrimeiro) { + // ORDEM: Grupos → Contas → Centros de Custo + + // Agrupar por conta dentro do grupo + const contas = items.reduce((acc, item) => { + if (!acc[item.conta]) { + acc[item.conta] = []; } - acc[subgrupoKey].push(item); - } else { - // Para outros itens, agrupar normalmente por subgrupo - if (!acc[item.subgrupo]) { - acc[item.subgrupo] = []; - } - acc[item.subgrupo].push(item); - } + acc[item.conta].push(item); return acc; }, {} as Record); - // Ordenar subgrupos - const sortedSubgrupos = Object.entries(subgrupos).sort(([a], [b]) => - a.localeCompare(b) - ); + // Ordenar contas por CODCONTA + const sortedContas = Object.entries(contas).sort(([contaA, itemsA], [contaB, itemsB]) => { + const codcontaA = itemsA[0]?.codigo_conta || 0; + const codcontaB = itemsB[0]?.codigo_conta || 0; + + if (codcontaA && codcontaB) { + return codcontaA - codcontaB; + } + + if (codcontaA && !codcontaB) return -1; + if (!codcontaA && codcontaB) return 1; + + return contaA.localeCompare(contaB); + }); - sortedSubgrupos.forEach(([subgrupo, subgrupoItems]) => { - const totalSubgrupo = subgrupoItems.reduce( + sortedContas.forEach(([conta, contaItems]) => { + const totalConta = contaItems.reduce( (sum, item) => sum + parseFloat(item.valor), 0 ); - // Linha do subgrupo - const valoresSubgrupoPorMes = calcularValoresPorMes(subgrupoItems); + // Linha da conta (Level 1) + const valoresContaPorMes = calcularValoresPorMes(contaItems); rows.push({ - type: "subgrupo", + type: "conta", level: 1, grupo, - subgrupo, - total: totalSubgrupo, - isExpanded: expandedSubgrupos.has(`${grupo}-${subgrupo}`), - valoresPorMes: valoresSubgrupoPorMes, + conta, + codigo_conta: contaItems[0].codigo_conta, + total: totalConta, + isExpanded: expandedCentros.has(`${grupo}-${conta}`), + valoresPorMes: valoresContaPorMes, percentuaisPorMes: calcularPercentuaisPorMes( - valoresSubgrupoPorMes, + valoresContaPorMes, grupo ), }); - if (expandedSubgrupos.has(`${grupo}-${subgrupo}`)) { - if (ordemHierarquiaContasPrimeiro) { - // NOVA ORDEM: Contas primeiro, depois Centros de Custo - - // Agrupar por conta dentro do subgrupo - const contas = subgrupoItems.reduce((acc, item) => { - if (!acc[item.conta]) { - acc[item.conta] = []; - } - acc[item.conta].push(item); - return acc; - }, {} as Record); - - // Ordenar contas - const sortedContas = Object.entries(contas).sort(([a], [b]) => - a.localeCompare(b) - ); - - sortedContas.forEach(([conta, contaItems]) => { - const totalConta = contaItems.reduce( - (sum, item) => sum + parseFloat(item.valor), - 0 - ); - - // Linha da conta (Level 2 - antes era Level 3) - const valoresContaPorMes = calcularValoresPorMes(contaItems); - rows.push({ - type: "conta", - level: 2, - grupo, - subgrupo, - conta, - codigo_conta: contaItems[0].codigo_conta, - total: totalConta, - isExpanded: expandedCentros.has( - `${grupo}-${subgrupo}-${conta}` - ), - valoresPorMes: valoresContaPorMes, - percentuaisPorMes: calcularPercentuaisPorMes( - valoresContaPorMes, - grupo - ), - }); - - if (expandedCentros.has(`${grupo}-${subgrupo}-${conta}`)) { - // Agrupar por centro de custo dentro da conta - const centros = contaItems.reduce((acc, item) => { + if (expandedCentros.has(`${grupo}-${conta}`)) { + // Agrupar por centro de custo dentro da conta + const centros = contaItems.reduce((acc, item) => { if (!acc[item.centro_custo]) { acc[item.centro_custo] = []; } @@ -841,52 +793,72 @@ export default function Teste() { return acc; }, {} as Record); - // Ordenar centros de custo - const sortedCentros = Object.entries(centros).sort(([a], [b]) => - a.localeCompare(b) - ); + // Ordenar centros de custo por CODIGOCENTROCUSTO + const sortedCentros = Object.entries(centros).sort(([centroA, itemsA], [centroB, itemsB]) => { + const codigoA = itemsA[0]?.codigo_centro_custo || ""; + const codigoB = itemsB[0]?.codigo_centro_custo || ""; + + if (codigoA && codigoB) { + return codigoA.localeCompare(codigoB); + } + + if (codigoA && !codigoB) return -1; + if (!codigoA && codigoB) return 1; + + return centroA.localeCompare(centroB); + }); - sortedCentros.forEach(([centro, centroItems]) => { - const totalCentro = centroItems.reduce( + sortedCentros.forEach(([centro, centroItems]) => { + const totalCentro = centroItems.reduce( (sum, item) => sum + parseFloat(item.valor), 0 ); - // Linha do centro de custo (Level 3 - antes era Level 2) - const valoresCentroPorMes = calcularValoresPorMes(centroItems); - rows.push({ - type: "centro_custo", - level: 3, - grupo, - subgrupo, - centro_custo: centro, - conta, - total: totalCentro, - valoresPorMes: valoresCentroPorMes, - percentuaisPorMes: calcularPercentuaisPorMes( - valoresCentroPorMes, - grupo - ), - }); - }); - } + // Linha do centro de custo (Level 2) + const valoresCentroPorMes = calcularValoresPorMes(centroItems); + rows.push({ + type: "centro_custo", + level: 2, + grupo, + centro_custo: centro, + conta, + codigo_centro_custo: centroItems[0].codigo_centro_custo, + total: totalCentro, + valoresPorMes: valoresCentroPorMes, + percentuaisPorMes: calcularPercentuaisPorMes( + valoresCentroPorMes, + grupo + ), + }); }); - } else { - // ORDEM ORIGINAL: Centros de Custo primeiro, depois Contas - - // Agrupar por centro de custo dentro do subgrupo - const centros = subgrupoItems.reduce((acc, item) => { - if (!acc[item.centro_custo]) { - acc[item.centro_custo] = []; - } - acc[item.centro_custo].push(item); - return acc; - }, {} as Record); + } + }); + } else { + // ORDEM ORIGINAL: Grupos → Centros de Custo → Contas + + // Agrupar por centro de custo dentro do grupo + const centros = items.reduce((acc, item) => { + if (!acc[item.centro_custo]) { + acc[item.centro_custo] = []; + } + acc[item.centro_custo].push(item); + return acc; + }, {} as Record); - // Ordenar centros de custo - const sortedCentros = Object.entries(centros).sort(([a], [b]) => - a.localeCompare(b) - ); + // Ordenar centros de custo por CODIGOCENTROCUSTO + const sortedCentros = Object.entries(centros).sort(([centroA, itemsA], [centroB, itemsB]) => { + const codigoA = itemsA[0]?.codigo_centro_custo || ""; + const codigoB = itemsB[0]?.codigo_centro_custo || ""; + + if (codigoA && codigoB) { + return codigoA.localeCompare(codigoB); + } + + if (codigoA && !codigoB) return -1; + if (!codigoA && codigoB) return 1; + + return centroA.localeCompare(centroB); + }); sortedCentros.forEach(([centro, centroItems]) => { const totalCentro = centroItems.reduce( @@ -894,18 +866,16 @@ export default function Teste() { 0 ); - // Linha do centro de custo + // Linha do centro de custo (Level 1) const valoresCentroPorMes = calcularValoresPorMes(centroItems); rows.push({ - type: "centro_custo", - level: 2, + type: "centro_custo", + level: 1, grupo, - subgrupo, centro_custo: centro, + codigo_centro_custo: centroItems[0].codigo_centro_custo, total: totalCentro, - isExpanded: expandedCentros.has( - `${grupo}-${subgrupo}-${centro}` - ), + isExpanded: expandedCentros.has(`${grupo}-${centro}`), valoresPorMes: valoresCentroPorMes, percentuaisPorMes: calcularPercentuaisPorMes( valoresCentroPorMes, @@ -913,7 +883,7 @@ export default function Teste() { ), }); - if (expandedCentros.has(`${grupo}-${subgrupo}-${centro}`)) { + if (expandedCentros.has(`${grupo}-${centro}`)) { // Agrupar por conta dentro do centro de custo const contas = centroItems.reduce((acc, item) => { if (!acc[item.conta]) { @@ -923,10 +893,20 @@ export default function Teste() { return acc; }, {} as Record); - // Ordenar contas - const sortedContas = Object.entries(contas).sort(([a], [b]) => - a.localeCompare(b) - ); + // Ordenar contas por CODCONTA + const sortedContas = Object.entries(contas).sort(([contaA, itemsA], [contaB, itemsB]) => { + const codcontaA = itemsA[0]?.codigo_conta || 0; + const codcontaB = itemsB[0]?.codigo_conta || 0; + + if (codcontaA && codcontaB) { + return codcontaA - codcontaB; + } + + if (codcontaA && !codcontaB) return -1; + if (!codcontaA && codcontaB) return 1; + + return contaA.localeCompare(contaB); + }); sortedContas.forEach(([conta, contaItems]) => { const totalConta = contaItems.reduce( @@ -934,13 +914,12 @@ export default function Teste() { 0 ); - // Linha da conta + // Linha da conta (Level 2) const valoresContaPorMes = calcularValoresPorMes(contaItems); rows.push({ - type: "conta", - level: 3, + type: "conta", + level: 2, grupo, - subgrupo, centro_custo: centro, conta, codigo_conta: contaItems[0].codigo_conta, @@ -954,9 +933,7 @@ export default function Teste() { }); } }); - } } - }); } }); @@ -1032,78 +1009,19 @@ export default function Teste() { {row.grupo} {isCalculado && ( - // - <> + )} ); - case "subgrupo": - return ( -
- - -
- ); - case "centro_custo": - return ( -
- {ordemHierarquiaContasPrimeiro ? ( - // Nova ordem: Centro de custo é level 3 (sem botão de toggle) -
- -
- ) : ( - // Ordem original: Centro de custo é level 2 (com botão de toggle) - - )} - -
- ); case "conta": return (
{ordemHierarquiaContasPrimeiro ? ( - // Nova ordem: Conta é level 2 (com botão de toggle) - + ) : ( - // Ordem original: Conta é level 3 (sem botão de toggle) + // Ordem original: Conta é level 2 (sem botão de toggle)
@@ -1122,7 +1040,52 @@ export default function Teste() { onClick={() => handleRowClick(row)} className="flex-1 text-left hover:bg-blue-50/50 p-2 rounded-lg cursor-pointer transition-all duration-200 truncate" > - {row.conta} +
+ + {row.conta} + + {row.codigo_conta && ( + + {row.codigo_conta} + + )} +
+ +
+ ); + case "centro_custo": + return ( +
+ {ordemHierarquiaContasPrimeiro ? ( + // Nova ordem: Centro de custo é level 2 (sem botão de toggle) +
+ +
+ ) : ( + // Ordem original: Centro de custo é level 1 (com botão de toggle) + + )} +
); @@ -1527,7 +1490,6 @@ export default function Teste() { row={row} index={index} toggleGroup={toggleGroup} - toggleSubgrupo={toggleSubgrupo} toggleCentro={toggleCentro} handleRowClick={handleRowClick} getRowStyle={getRowStyle} diff --git a/src/app/api/dre-oracle/route.ts b/src/app/api/dre-oracle/route.ts index 463dd89..4509281 100644 --- a/src/app/api/dre-oracle/route.ts +++ b/src/app/api/dre-oracle/route.ts @@ -23,7 +23,8 @@ export async function GET(request: NextRequest) { data_cai: item.DATA || "2023-03", // Usar DATA do Oracle grupo: codgrupo ? `${codgrupo} - ${nomeGrupo}` : nomeGrupo, // Concatenar código + nome subgrupo: item.CENTROCUSTO || "", // Usar CENTROCUSTO como subgrupo - centro_custo: item.CODIGOCENTROCUSTO || "", // Usar CODIGOCENTROCUSTO + centro_custo: item.CENTROCUSTO || "", // Usar CENTROCUSTO (nome do centro) + codigo_centro_custo: item.CODIGOCENTROCUSTO || "", // Usar CODIGOCENTROCUSTO (código do centro) codigo_conta: parseInt(item.CODCONTA) || 0, // Converter CODCONTA para número conta: item.CONTA || "", // Usar CONTA do Oracle valor: item.VALOR?.toString() || "0", // Converter VALOR para string