ajustes na exportacao e ordenacao de grid

This commit is contained in:
Felipe Batista 2025-12-22 19:25:22 -03:00
parent 28e51c87d4
commit 06c0773cfe
2 changed files with 984 additions and 507 deletions

File diff suppressed because it is too large Load Diff

View File

@ -1459,13 +1459,335 @@ export default function Teste() {
carregarPeriodosDisponiveis();
};
// Função para construir dados hierárquicos completamente expandidos (para exportação)
const buildHierarchicalDataCompleta =
React.useCallback((): 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<string, DREItem[]>);
// Calcular valores por grupo para linhas calculadas
const valoresPorGrupo: Record<string, Record<string, number>> = {};
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);
}
);
// Variáveis para armazenar valores da MARGEM BRUTA (para uso no RESULTADO LOJA)
let valoresMargemBrutaPorMes: Record<string, number> | null = null;
let valoresMargemBrutaPorMesPorFilial: Record<
string,
Record<string, number>
> | null = null;
let totalMargemBruta: number | null = null;
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)
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 incluir todas as contas (não depende de 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<string, DREItem[]>);
// 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)
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 BRUTA" 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 BRUTA = CODGRUPO 01 + CODGRUPO 02
const valoresGrupo01 = valoresPorGrupo['01'] || {};
const valoresGrupo02 = valoresPorGrupo['02'] || {};
// Calcular valores por mês para MARGEM BRUTA
const valoresMargemPorMes: Record<string, number> = {};
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 BRUTA
const valoresMargemPorMesPorFilial: Record<
string,
Record<string, number>
> = {};
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
);
// Armazenar valores da MARGEM BRUTA para uso posterior no RESULTADO LOJA
valoresMargemBrutaPorMes = valoresMargemPorMes;
valoresMargemBrutaPorMesPorFilial = valoresMargemPorMesPorFilial;
totalMargemBruta = totalMargem;
// Adicionar linha calculada
rows.push({
type: 'calculado',
level: 0,
grupo: 'MARGEM BRUTA',
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,
});
}
// Adicionar linha calculada "RESULTADO LOJA" após o grupo 04 (DESPESAS)
// Verificar se é o último grupo ou se o próximo grupo é maior que 04
const proximoCodigoDespesas = sortedGrupos[index + 1]?.[0];
const proximoNumeroDespesas = proximoCodigoDespesas
? parseInt(proximoCodigoDespesas)
: 999;
if (
(codgrupo === '04' ||
(parseInt(codgrupo) === 4 && proximoNumeroDespesas > 4)) &&
valoresMargemBrutaPorMes !== null &&
valoresMargemBrutaPorMesPorFilial !== null &&
totalMargemBruta !== null
) {
// Calcular RESULTADO LOJA = MARGEM BRUTA + DESPESAS (grupo 04)
const valoresGrupo04 = valoresPorGrupo['04'] || {};
// Calcular valores por mês para RESULTADO LOJA
const valoresResultadoPorMes: Record<string, number> = {};
mesesDisponiveis.forEach((mes) => {
const valorMargem = valoresMargemBrutaPorMes![mes] || 0;
const valorDespesas = valoresGrupo04[mes] || 0;
valoresResultadoPorMes[mes] = valorMargem + valorDespesas;
});
// Calcular valores por mês e por filial para RESULTADO LOJA
const valoresResultadoPorMesPorFilial: Record<
string,
Record<string, number>
> = {};
const valoresGrupo04PorFilial = gruposPorCodigo['04']
? calcularValoresPorMesPorFilial(gruposPorCodigo['04'])
: {};
// Extrair filiais únicas dos valores calculados
const primeiroMes = mesesDisponiveis[0] || '';
const filiaisDisponiveis = [
...new Set([
...Object.keys(
valoresMargemBrutaPorMesPorFilial![primeiroMes] || {}
),
...Object.keys(valoresGrupo04PorFilial[primeiroMes] || {}),
]),
];
mesesDisponiveis.forEach((mes) => {
valoresResultadoPorMesPorFilial[mes] = {};
filiaisDisponiveis.forEach((filial) => {
const valorMargem =
valoresMargemBrutaPorMesPorFilial![mes]?.[filial] || 0;
const valorDespesas = valoresGrupo04PorFilial[mes]?.[filial] || 0;
valoresResultadoPorMesPorFilial[mes][filial] =
valorMargem + valorDespesas;
});
});
// Calcular total
const totalResultado = Object.values(valoresResultadoPorMes).reduce(
(sum, val) => sum + val,
0
);
// Adicionar linha calculada
rows.push({
type: 'calculado',
level: 0,
grupo: 'RESULTADO LOJA',
codigo_grupo: 'RESULTADO',
total: totalResultado,
isExpanded: false,
valoresPorMes: valoresResultadoPorMes,
valoresPorMesPorFilial: valoresResultadoPorMesPorFilial,
percentuaisPorMes: calcularPercentuaisPorMes(
valoresResultadoPorMes,
'RESULTADO'
),
percentuaisPorMesPorFilial: calcularPercentuaisPorMesPorFilial(
valoresResultadoPorMesPorFilial,
'RESULTADO'
),
percentualTotal: calcularPercentualTotal(
totalResultado,
'RESULTADO'
),
isCalculado: true,
});
}
});
return rows;
}, [
data,
mesesDisponiveis,
calcularValoresPorMes,
calcularValoresPorMesPorFilial,
calcularPercentuaisPorMes,
calcularPercentuaisPorMesPorFilial,
calcularPercentualTotal,
]);
const exportarXLSX = () => {
if (!data.length) {
console.log('⚠️ Nenhum dado para exportar');
return;
}
const dadosCompletosExpandidos = buildHierarchicalData();
console.log('📊 Exportando TODOS os dados expandidos para XLSX...');
const dadosCompletosExpandidos = buildHierarchicalDataCompleta();
const dadosExportacao = dadosCompletosExpandidos.map((row, index) => {
const linha: any = {