From 3aa3da3f4b68c180c57a49dbdd0b29f87aef124f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alessandro=20Gon=C3=A7aalves?= Date: Mon, 22 Dec 2025 15:23:51 -0300 Subject: [PATCH] =?UTF-8?q?hotfix:=20Ajuste=20na=20exporta=C3=A7=C3=A3o=20?= =?UTF-8?q?da=20da=20DRE=20Sint=C3=A9tica?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/app/dre-filial/teste.tsx | 209 +++++++++++++++++++++++++++++++++-- 1 file changed, 202 insertions(+), 7 deletions(-) diff --git a/src/app/dre-filial/teste.tsx b/src/app/dre-filial/teste.tsx index 76dc341..c63cffd 100644 --- a/src/app/dre-filial/teste.tsx +++ b/src/app/dre-filial/teste.tsx @@ -1172,13 +1172,191 @@ export default function Teste() { carregarPeriodosDisponiveis(); }; + // Função para construir dados hierárquicos completamente expandidos (para exportação XLSX) + // Usa a mesma lógica de buildHierarchicalData mas sempre expandido + const buildHierarchicalDataCompleta = (): HierarchicalRow[] => { + const rows: HierarchicalRow[] = []; + + // Hierarquia simplificada: [grupo, conta] + // Agrupar por CODGRUPO + const gruposPorCodigo = data.reduce((acc, item) => { + const codgrupo = item.codgrupo || item.codigo_grupo || ""; + if (!codgrupo) return acc; + if (!acc[codgrupo]) { + acc[codgrupo] = []; + } + acc[codgrupo].push(item); + return acc; + }, {} as Record); + + // Calcular valores por grupo para linhas calculadas + const valoresPorGrupo: Record> = {}; + Object.keys(gruposPorCodigo).forEach(codgrupo => { + valoresPorGrupo[codgrupo] = calcularValoresPorMes(gruposPorCodigo[codgrupo]); + }); + + // Ordenar por CODGRUPO (numericamente) + const sortedGrupos = Object.entries(gruposPorCodigo).sort(([codA], [codB]) => { + const numA = parseInt(codA) || 0; + const numB = parseInt(codB) || 0; + if (numA !== numB) { + return numA - numB; + } + return codA.localeCompare(codB); + }); + + sortedGrupos.forEach(([codgrupo, items], index) => { + // Calcular total do grupo + const totalGrupo = items.reduce( + (sum, item) => sum + parseFloat(item.valor), + 0 + ); + const valoresGrupoPorMes = calcularValoresPorMes(items); + const valoresGrupoPorMesPorFilial = calcularValoresPorMesPorFilial(items); + + // Linha do grupo (Level 0) - sempre expandida + rows.push({ + type: "grupo", + level: 0, + grupo: items[0]?.grupo || codgrupo, + codigo_grupo: codgrupo, + total: totalGrupo, + isExpanded: true, // Sempre expandido na exportação + valoresPorMes: valoresGrupoPorMes, + valoresPorMesPorFilial: valoresGrupoPorMesPorFilial, + percentuaisPorMes: calcularPercentuaisPorMes(valoresGrupoPorMes, codgrupo), + percentuaisPorMesPorFilial: calcularPercentuaisPorMesPorFilial(valoresGrupoPorMesPorFilial, codgrupo), + percentualTotal: calcularPercentualTotal(totalGrupo, codgrupo), + }); + + // Sempre expandir grupos na exportação (não verificar expandedGrupos) + // Agrupar por conta dentro do grupo + const contas = items.reduce((acc, item) => { + const conta = item.conta || ""; + if (!conta) return acc; + if (!acc[conta]) { + acc[conta] = []; + } + acc[conta].push(item); + 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; + } + + return contaA.localeCompare(contaB); + }); + + sortedContas.forEach(([conta, contaItems]) => { + const totalConta = contaItems.reduce( + (sum, item) => sum + parseFloat(item.valor), + 0 + ); + const valoresContaPorMes = calcularValoresPorMes(contaItems); + const valoresContaPorMesPorFilial = calcularValoresPorMesPorFilial(contaItems); + + // Linha da conta (Level 1) - sempre incluída na exportação + rows.push({ + type: "conta", + level: 1, + grupo: items[0]?.grupo || codgrupo, + codigo_grupo: codgrupo, + conta, + codigo_conta: contaItems[0]?.codigo_conta, + total: totalConta, + isExpanded: false, + valoresPorMes: valoresContaPorMes, + valoresPorMesPorFilial: valoresContaPorMesPorFilial, + percentuaisPorMes: calcularPercentuaisPorMes(valoresContaPorMes, codgrupo), + percentuaisPorMesPorFilial: calcularPercentuaisPorMesPorFilial(valoresContaPorMesPorFilial, codgrupo), + percentualTotal: calcularPercentualTotal(totalConta, codgrupo), + }); + }); + + // Adicionar linha calculada "MARGEM DE LOJA" após o grupo 02 + // Verificar se é o último grupo ou se o próximo grupo é maior que 02 + const proximoCodigo = sortedGrupos[index + 1]?.[0]; + const proximoNumero = proximoCodigo ? parseInt(proximoCodigo) : 999; + + if (codgrupo === "02" || (parseInt(codgrupo) === 2 && proximoNumero > 2)) { + // Calcular MARGEM DE LOJA = CODGRUPO 01 - CODGRUPO 02 + const valoresGrupo01 = valoresPorGrupo["01"] || {}; + const valoresGrupo02 = valoresPorGrupo["02"] || {}; + + // Calcular valores por mês para MARGEM DE LOJA + const valoresMargemPorMes: Record = {}; + mesesDisponiveis.forEach(mes => { + const valor01 = valoresGrupo01[mes] || 0; + const valor02 = valoresGrupo02[mes] || 0; + valoresMargemPorMes[mes] = valor01 - valor02; + }); + + // Calcular valores por mês e por filial para MARGEM DE LOJA + const valoresMargemPorMesPorFilial: Record> = {}; + const valoresGrupo01PorFilial = gruposPorCodigo["01"] ? calcularValoresPorMesPorFilial(gruposPorCodigo["01"]) : {}; + const valoresGrupo02PorFilial = gruposPorCodigo["02"] ? calcularValoresPorMesPorFilial(gruposPorCodigo["02"]) : {}; + + // Extrair filiais únicas dos valores calculados + const primeiroMes = mesesDisponiveis[0] || ""; + const filiaisDisponiveis = [...new Set([ + ...Object.keys(valoresGrupo01PorFilial[primeiroMes] || {}), + ...Object.keys(valoresGrupo02PorFilial[primeiroMes] || {}) + ])]; + + mesesDisponiveis.forEach(mes => { + valoresMargemPorMesPorFilial[mes] = {}; + filiaisDisponiveis.forEach(filial => { + const valor01 = valoresGrupo01PorFilial[mes]?.[filial] || 0; + const valor02 = valoresGrupo02PorFilial[mes]?.[filial] || 0; + valoresMargemPorMesPorFilial[mes][filial] = valor01 - valor02; + }); + }); + + // Calcular total + const totalMargem = Object.values(valoresMargemPorMes).reduce((sum, val) => sum + val, 0); + + // Adicionar linha calculada + rows.push({ + type: "calculado", + level: 0, + grupo: "MARGEM DE LOJA", + codigo_grupo: "MARGEM", + total: totalMargem, + isExpanded: false, + valoresPorMes: valoresMargemPorMes, + valoresPorMesPorFilial: valoresMargemPorMesPorFilial, + percentuaisPorMes: calcularPercentuaisPorMes(valoresMargemPorMes, "MARGEM"), + percentuaisPorMesPorFilial: calcularPercentuaisPorMesPorFilial(valoresMargemPorMesPorFilial, "MARGEM"), + percentualTotal: calcularPercentualTotal(totalMargem, "MARGEM"), + isCalculado: true, + }); + } + }); + + return rows; + }; + const exportarXLSX = () => { if (!data.length) { console.log('⚠️ Nenhum dado para exportar'); return; } - const dadosCompletosExpandidos = buildHierarchicalData(); + console.log('📊 Exportando TODOS os dados expandidos para XLSX...'); + + // Criar uma versão completamente expandida dos dados hierárquicos + const dadosCompletosExpandidos = buildHierarchicalDataCompleta(); + + // Extrair filiais únicas para exportação + const filiaisParaExportacao = (filtrosAplicados && filiaisSelecionadas.length > 0) + ? filiaisSelecionadas + : (opcoesFiliais.length > 0 ? opcoesFiliais : []); const dadosExportacao = dadosCompletosExpandidos.map((row, index) => { const linha: any = { @@ -1192,11 +1370,21 @@ export default function Teste() { 'Total': row.total || 0, }; + // Adicionar colunas por mês e por filial mesesDisponiveis.forEach(mes => { - const valor = row.valoresPorMes?.[mes] || 0; - const percentual = row.percentuaisPorMes?.[mes] || 0; - linha[`Valor ${mes}`] = valor; - linha[`% ${mes}`] = percentual; + // Colunas por filial para este mês + filiaisParaExportacao.forEach((filial: string) => { + const valorFilial = row.valoresPorMesPorFilial?.[mes]?.[filial] || 0; + const percentualFilial = row.percentuaisPorMesPorFilial?.[mes]?.[filial] || 0; + linha[`${mes} FILIAL - ${filial} R$`] = valorFilial; + linha[`${mes} FILIAL - ${filial} %`] = percentualFilial; + }); + + // Colunas de totalizador para este mês + const valorTotal = row.valoresPorMes?.[mes] || 0; + const percentualTotal = row.percentuaisPorMes?.[mes] || 0; + linha[`${mes} Total R$`] = valorTotal; + linha[`${mes} Total %`] = percentualTotal; }); return linha; @@ -1216,9 +1404,16 @@ export default function Teste() { { wch: 15 }, // Total ]; + // Adicionar larguras para colunas por mês, filial e totalizador mesesDisponiveis.forEach(() => { - colWidths.push({ wch: 15 }); // Valor - colWidths.push({ wch: 10 }); // % + // Colunas por filial (R$ e %) + filiaisParaExportacao.forEach(() => { + colWidths.push({ wch: 15 }); // Valor R$ por filial + colWidths.push({ wch: 10 }); // % por filial + }); + // Colunas de totalizador (R$ e %) + colWidths.push({ wch: 15 }); // Valor R$ total + colWidths.push({ wch: 10 }); // % total }); ws['!cols'] = colWidths;