From 64d4397847ca09f4fe5c7e6d632e2882167f64f6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alessandro=20Gon=C3=A7aalves?= Date: Wed, 19 Nov 2025 17:31:54 -0300 Subject: [PATCH] =?UTF-8?q?fix:=20corre=C3=A7=C3=A3o=20da=20ordena=C3=A7?= =?UTF-8?q?=C3=A3o=20por=20CODGRUPO?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/app/dre-entidade/teste.tsx | 254 +++++++++++++++++++-------------- 1 file changed, 146 insertions(+), 108 deletions(-) diff --git a/src/app/dre-entidade/teste.tsx b/src/app/dre-entidade/teste.tsx index ea368d5..0c02732 100644 --- a/src/app/dre-entidade/teste.tsx +++ b/src/app/dre-entidade/teste.tsx @@ -474,7 +474,7 @@ export default function Teste() { entidadeFiltro, diretoIndiretoFiltro, centroCustoFiltro, - codigoContaFiltro, + codigoContaFiltro, tipoLinha: row.type, rowData: { entidade: row.entidade, @@ -563,9 +563,9 @@ export default function Teste() { const newExpanded = new Set(prev); if (newExpanded.has(entidade)) { newExpanded.delete(entidade); - } else { + } else { newExpanded.add(entidade); - } + } return newExpanded; }); }, []); @@ -587,9 +587,9 @@ export default function Teste() { const newExpanded = new Set(prev); if (newExpanded.has(chave)) { newExpanded.delete(chave); - } else { + } else { newExpanded.add(chave); - } + } return newExpanded; }); }, []); @@ -775,23 +775,41 @@ export default function Teste() { const rows: HierarchicalRow[] = []; // Nova hierarquia: [entidade, direto/indireto, cc, conta] - // Agrupar por entidade - const entidades = data.reduce((acc, item) => { + // Agrupar primeiro por CODGRUPO, depois por entidade + const gruposPorCodigo = data.reduce((acc, item) => { + const codgrupo = item.codgrupo || ""; + if (!codgrupo) return acc; + if (!acc[codgrupo]) { + acc[codgrupo] = {}; + } const entidade = item.entidades || ""; if (!entidade) return acc; - if (!acc[entidade]) { - acc[entidade] = []; + if (!acc[codgrupo][entidade]) { + acc[codgrupo][entidade] = []; } - acc[entidade].push(item); + acc[codgrupo][entidade].push(item); return acc; - }, {} as Record); + }, {} as Record>); - // Ordenar entidades alfabeticamente - const sortedEntidades = Object.entries(entidades).sort(([entA], [entB]) => - entA.localeCompare(entB) - ); + // Ordenar por CODGRUPO (numericamente), depois por entidade (alfabeticamente) + const sortedGrupos = Object.entries(gruposPorCodigo).sort(([codA], [codB]) => { + // Ordenar numericamente por CODGRUPO + const numA = parseInt(codA) || 0; + const numB = parseInt(codB) || 0; + if (numA !== numB) { + return numA - numB; + } + // Se não for numérico, ordenar alfabeticamente + return codA.localeCompare(codB); + }); - sortedEntidades.forEach(([entidade, items]) => { + sortedGrupos.forEach(([codgrupo, entidades]) => { + // Ordenar entidades dentro do grupo alfabeticamente + const sortedEntidades = Object.entries(entidades).sort(([entA], [entB]) => + entA.localeCompare(entB) + ); + + sortedEntidades.forEach(([entidade, items]) => { const totalEntidade = items.reduce((sum, item) => sum + parseFloat(item.valor), 0); const valoresEntidadePorMes = calcularValoresPorMes(items); @@ -819,8 +837,8 @@ export default function Teste() { acc[subgrupo] = []; } acc[subgrupo].push(item); - return acc; - }, {} as Record); + return acc; + }, {} as Record); // Ordenar: DIRETO primeiro, depois INDIRETO const sortedDiretoIndireto = Object.entries(diretoIndireto).sort(([a], [b]) => { @@ -833,9 +851,9 @@ export default function Teste() { sortedDiretoIndireto.forEach(([diretoIndireto, diretoIndiretoItems]) => { const totalDiretoIndireto = diretoIndiretoItems.reduce( - (sum, item) => sum + parseFloat(item.valor), - 0 - ); + (sum, item) => sum + parseFloat(item.valor), + 0 + ); const valoresDiretoIndiretoPorMes = calcularValoresPorMes(diretoIndiretoItems); // Verificar se direto/indireto contém faturamento líquido @@ -843,9 +861,9 @@ export default function Teste() { const codgrupoParaCalculoDI = temFaturamentoLiquidoDI ? "00" : ""; // Linha direto/indireto (Level 1) - sempre expandida - rows.push({ + rows.push({ type: "direto_indireto", - level: 1, + level: 1, entidade, direto_indireto: diretoIndireto, total: totalDiretoIndireto, @@ -863,27 +881,27 @@ export default function Teste() { acc[centro] = []; } acc[centro].push(item); - return acc; - }, {} as Record); + return acc; + }, {} as Record); - // 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 || ""; + // 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( - (sum, item) => sum + parseFloat(item.valor), - 0 - ); - const valoresCentroPorMes = calcularValoresPorMes(centroItems); + sortedCentros.forEach(([centro, centroItems]) => { + const totalCentro = centroItems.reduce( + (sum, item) => sum + parseFloat(item.valor), + 0 + ); + const valoresCentroPorMes = calcularValoresPorMes(centroItems); // Verificar se centro de custo contém faturamento líquido const temFaturamentoLiquidoCC = centroItems.some(item => item.codgrupo === "00"); @@ -953,8 +971,9 @@ export default function Teste() { percentuaisPorMes: calcularPercentuaisPorMes(valoresContaPorMes, codgrupoParaCalculoConta), percentualTotal: calcularPercentualTotal(totalConta, codgrupoParaCalculoConta), }); - }); - }); + }); + }); + }); }); }); @@ -983,7 +1002,7 @@ export default function Teste() { setExpandedEntidades(new Set(todasEntidades)); setExpandedDiretoIndireto(new Set(todosDiretoIndireto)); - setExpandedCentros(new Set(todosCentros)); + setExpandedCentros(new Set(todosCentros)); setIsAllExpanded(true); }); @@ -1577,23 +1596,41 @@ export default function Teste() { const rows: HierarchicalRow[] = []; // Nova hierarquia: [entidade, direto/indireto, cc, conta] - // Agrupar por entidade - const entidades = data.reduce((acc, item) => { + // Agrupar primeiro por CODGRUPO, depois por entidade + const gruposPorCodigo = data.reduce((acc, item) => { + const codgrupo = item.codgrupo || ""; + if (!codgrupo) return acc; + if (!acc[codgrupo]) { + acc[codgrupo] = {}; + } const entidade = item.entidades || ""; if (!entidade) return acc; - if (!acc[entidade]) { - acc[entidade] = []; + if (!acc[codgrupo][entidade]) { + acc[codgrupo][entidade] = []; } - acc[entidade].push(item); + acc[codgrupo][entidade].push(item); return acc; - }, {} as Record); + }, {} as Record>); - // Ordenar entidades alfabeticamente - const sortedEntidades = Object.entries(entidades).sort(([entA], [entB]) => - entA.localeCompare(entB) - ); + // Ordenar por CODGRUPO (numericamente), depois por entidade (alfabeticamente) + const sortedGrupos = Object.entries(gruposPorCodigo).sort(([codA], [codB]) => { + // Ordenar numericamente por CODGRUPO + const numA = parseInt(codA) || 0; + const numB = parseInt(codB) || 0; + if (numA !== numB) { + return numA - numB; + } + // Se não for numérico, ordenar alfabeticamente + return codA.localeCompare(codB); + }); - sortedEntidades.forEach(([entidade, items]) => { + sortedGrupos.forEach(([codgrupo, entidades]) => { + // Ordenar entidades dentro do grupo alfabeticamente + const sortedEntidades = Object.entries(entidades).sort(([entA], [entB]) => + entA.localeCompare(entB) + ); + + sortedEntidades.forEach(([entidade, items]) => { // Calcular total da entidade const totalEntidade = items.reduce( (sum, item) => sum + parseFloat(item.valor), @@ -1675,44 +1712,44 @@ export default function Teste() { return acc; }, {} as Record); - // 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); - }); + // 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( - (sum, item) => sum + parseFloat(item.valor), - 0 - ); + sortedCentros.forEach(([centro, centroItems]) => { + const totalCentro = centroItems.reduce( + (sum, item) => sum + parseFloat(item.valor), + 0 + ); const valoresCentroPorMes = calcularValoresPorMes(centroItems); // Verificar se centro de custo contém faturamento líquido const temFaturamentoLiquidoCC = centroItems.some(item => item.codgrupo === "00"); const codgrupoParaCalculoCC = temFaturamentoLiquidoCC ? "00" : ""; - // Linha do centro de custo (Level 2) + // Linha do centro de custo (Level 2) const chaveCentro = `${entidade}-${diretoIndireto}-${centro}`; - rows.push({ - type: "centro_custo", - level: 2, + rows.push({ + type: "centro_custo", + level: 2, entidade, direto_indireto: diretoIndireto, - centro_custo: centro, - codigo_centro_custo: centroItems[0].codigo_centro_custo, - total: totalCentro, + centro_custo: centro, + codigo_centro_custo: centroItems[0].codigo_centro_custo, + total: totalCentro, isExpanded: expandedCentros.has(chaveCentro), - valoresPorMes: valoresCentroPorMes, + valoresPorMes: valoresCentroPorMes, percentuaisPorMes: calcularPercentuaisPorMes(valoresCentroPorMes, codgrupoParaCalculoCC), percentualTotal: calcularPercentualTotal(totalCentro, codgrupoParaCalculoCC), }); @@ -1729,19 +1766,19 @@ export default function Teste() { return acc; }, {} as Record); - // 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); + // 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]) => { @@ -1757,7 +1794,7 @@ export default function Teste() { // Linha da conta (Level 3) rows.push({ - type: "conta", + type: "conta", level: 3, entidade, direto_indireto: diretoIndireto, @@ -1774,8 +1811,9 @@ export default function Teste() { } }); } - }); - } + }); + } + }); }); return rows; @@ -1873,13 +1911,13 @@ export default function Teste() {