fix: organização dos grupos por cod_grupo
This commit is contained in:
parent
a1d22d3ac6
commit
6f14b655f5
|
|
@ -14,6 +14,8 @@ interface DREItem {
|
||||||
codigo_conta: number;
|
codigo_conta: number;
|
||||||
conta: string;
|
conta: string;
|
||||||
valor: string;
|
valor: string;
|
||||||
|
codgrupo?: string;
|
||||||
|
isCalculado?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface HierarchicalRow {
|
interface HierarchicalRow {
|
||||||
|
|
@ -257,38 +259,33 @@ export default function Teste() {
|
||||||
const buildHierarchicalData = (): HierarchicalRow[] => {
|
const buildHierarchicalData = (): HierarchicalRow[] => {
|
||||||
const rows: HierarchicalRow[] = [];
|
const rows: HierarchicalRow[] = [];
|
||||||
|
|
||||||
// Agrupar por grupo, mas tratar grupo 05 como subgrupo do grupo 04
|
// Agrupar por grupo
|
||||||
const grupos = data.reduce((acc, item) => {
|
const grupos = data.reduce((acc, item) => {
|
||||||
// Se for grupo 05, adicionar ao grupo 04 como subgrupo
|
|
||||||
if (item.grupo.includes("05")) {
|
|
||||||
// Encontrar grupo 04 existente ou criar um
|
|
||||||
const grupo04Key = Object.keys(acc).find((key) => key.includes("04"));
|
|
||||||
if (grupo04Key) {
|
|
||||||
acc[grupo04Key].push(item);
|
|
||||||
} else {
|
|
||||||
// Se não existe grupo 04, criar um grupo especial
|
|
||||||
const grupo04Nome =
|
|
||||||
Object.keys(acc).find((key) => key.includes("04")) ||
|
|
||||||
"04 - GRUPO 04";
|
|
||||||
if (!acc[grupo04Nome]) {
|
|
||||||
acc[grupo04Nome] = [];
|
|
||||||
}
|
|
||||||
acc[grupo04Nome].push(item);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// Para outros grupos, agrupar normalmente
|
|
||||||
if (!acc[item.grupo]) {
|
if (!acc[item.grupo]) {
|
||||||
acc[item.grupo] = [];
|
acc[item.grupo] = [];
|
||||||
}
|
}
|
||||||
acc[item.grupo].push(item);
|
acc[item.grupo].push(item);
|
||||||
}
|
|
||||||
return acc;
|
return acc;
|
||||||
}, {} as Record<string, DREItem[]>);
|
}, {} as Record<string, DREItem[]>);
|
||||||
|
|
||||||
// Ordenar grupos
|
// Ordenar grupos pelo CODGRUPO numérico
|
||||||
const sortedGrupos = Object.entries(grupos).sort(([a], [b]) =>
|
const sortedGrupos = Object.entries(grupos).sort(([grupoA, itemsA], [grupoB, itemsB]) => {
|
||||||
a.localeCompare(b)
|
// Pegar o CODGRUPO do primeiro item de cada grupo
|
||||||
);
|
const codgrupoA = itemsA[0]?.codgrupo || "";
|
||||||
|
const codgrupoB = itemsB[0]?.codgrupo || "";
|
||||||
|
|
||||||
|
// Se ambos têm CODGRUPO, ordenar numericamente
|
||||||
|
if (codgrupoA && codgrupoB) {
|
||||||
|
return parseInt(codgrupoA) - parseInt(codgrupoB);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Se apenas um tem CODGRUPO, ele vem primeiro
|
||||||
|
if (codgrupoA && !codgrupoB) return -1;
|
||||||
|
if (!codgrupoA && codgrupoB) return 1;
|
||||||
|
|
||||||
|
// Se nenhum tem CODGRUPO, ordenar alfabeticamente
|
||||||
|
return grupoA.localeCompare(grupoB);
|
||||||
|
});
|
||||||
|
|
||||||
sortedGrupos.forEach(([grupo, items]) => {
|
sortedGrupos.forEach(([grupo, items]) => {
|
||||||
const totalGrupo = items.reduce(
|
const totalGrupo = items.reduce(
|
||||||
|
|
@ -461,8 +458,25 @@ export default function Teste() {
|
||||||
" bg-gradient-to-r from-blue-100 to-indigo-100 border-l-4 border-blue-500 shadow-lg";
|
" bg-gradient-to-r from-blue-100 to-indigo-100 border-l-4 border-blue-500 shadow-lg";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Verificar se é um grupo calculado
|
||||||
|
const isCalculado = row.grupo?.includes("CALCULADO") ||
|
||||||
|
row.grupo?.includes("FATURAMENTO LÍQUIDO") ||
|
||||||
|
row.grupo?.includes("LUCRO BRUTO") ||
|
||||||
|
row.grupo?.includes("MARGEM LOJA") ||
|
||||||
|
row.grupo?.includes("RESULTADO OPERACIONAL") ||
|
||||||
|
row.grupo?.includes("RESULTADO FINANCEIRO") ||
|
||||||
|
row.grupo?.includes("OUTRAS RECEITAS / DESPESAS") ||
|
||||||
|
row.grupo?.includes("LAIR") ||
|
||||||
|
row.grupo?.includes("IR") ||
|
||||||
|
row.grupo?.includes("CSLL") ||
|
||||||
|
row.grupo?.includes("LUCRO LÍQUIDO") ||
|
||||||
|
row.grupo?.includes("EBITDA");
|
||||||
|
|
||||||
switch (row.type) {
|
switch (row.type) {
|
||||||
case "grupo":
|
case "grupo":
|
||||||
|
if (isCalculado) {
|
||||||
|
return `${style} bg-gradient-to-r from-green-50/30 to-emerald-50/20 font-bold text-gray-900 border-b-2 border-green-200 border-l-4 border-green-400`;
|
||||||
|
}
|
||||||
return `${style} bg-gradient-to-r from-blue-50/20 to-indigo-50/20 font-bold text-gray-900 border-b-2 border-blue-200`;
|
return `${style} bg-gradient-to-r from-blue-50/20 to-indigo-50/20 font-bold text-gray-900 border-b-2 border-blue-200`;
|
||||||
case "subgrupo":
|
case "subgrupo":
|
||||||
return `${style} bg-gradient-to-r from-gray-50/30 to-blue-50/20 font-semibold text-gray-800`;
|
return `${style} bg-gradient-to-r from-gray-50/30 to-blue-50/20 font-semibold text-gray-800`;
|
||||||
|
|
@ -480,6 +494,20 @@ export default function Teste() {
|
||||||
};
|
};
|
||||||
|
|
||||||
const renderCellContent = (row: HierarchicalRow) => {
|
const renderCellContent = (row: HierarchicalRow) => {
|
||||||
|
// Verificar se é um grupo calculado
|
||||||
|
const isCalculado = row.grupo?.includes("CALCULADO") ||
|
||||||
|
row.grupo?.includes("FATURAMENTO LÍQUIDO") ||
|
||||||
|
row.grupo?.includes("LUCRO BRUTO") ||
|
||||||
|
row.grupo?.includes("MARGEM LOJA") ||
|
||||||
|
row.grupo?.includes("RESULTADO OPERACIONAL") ||
|
||||||
|
row.grupo?.includes("RESULTADO FINANCEIRO") ||
|
||||||
|
row.grupo?.includes("OUTRAS RECEITAS / DESPESAS") ||
|
||||||
|
row.grupo?.includes("LAIR") ||
|
||||||
|
row.grupo?.includes("IR") ||
|
||||||
|
row.grupo?.includes("CSLL") ||
|
||||||
|
row.grupo?.includes("LUCRO LÍQUIDO") ||
|
||||||
|
row.grupo?.includes("EBITDA");
|
||||||
|
|
||||||
switch (row.type) {
|
switch (row.type) {
|
||||||
case "grupo":
|
case "grupo":
|
||||||
return (
|
return (
|
||||||
|
|
@ -498,7 +526,17 @@ export default function Teste() {
|
||||||
onClick={() => handleRowClick(row)}
|
onClick={() => handleRowClick(row)}
|
||||||
className="flex-1 text-left hover:bg-blue-50/50 p-2 rounded-lg cursor-pointer transition-all duration-200 truncate"
|
className="flex-1 text-left hover:bg-blue-50/50 p-2 rounded-lg cursor-pointer transition-all duration-200 truncate"
|
||||||
>
|
>
|
||||||
<span className="font-bold text-gray-900">{row.grupo}</span>
|
<div className="flex items-center gap-2">
|
||||||
|
{isCalculado && (
|
||||||
|
<span className="text-green-600 font-bold text-sm">⚡</span>
|
||||||
|
)}
|
||||||
|
<span className={`font-bold ${isCalculado ? 'text-green-800' : 'text-gray-900'}`}>
|
||||||
|
{row.grupo}
|
||||||
|
</span>
|
||||||
|
{isCalculado && (
|
||||||
|
<span className="text-xs text-green-600 font-medium">(CALCULADO)</span>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -13,19 +13,31 @@ export async function GET(request: NextRequest) {
|
||||||
console.log('✅ Query executada com sucesso:', data.length, 'registros encontrados');
|
console.log('✅ Query executada com sucesso:', data.length, 'registros encontrados');
|
||||||
|
|
||||||
// Transformar os dados do Oracle para o formato esperado pelo componente
|
// Transformar os dados do Oracle para o formato esperado pelo componente
|
||||||
const transformedData = data.map((item: any) => ({
|
const transformedData = data.map((item: any) => {
|
||||||
|
const codgrupo = item.CODGRUPO || "";
|
||||||
|
const nomeGrupo = item.GRUPO || "";
|
||||||
|
|
||||||
|
return {
|
||||||
codfilial: "001", // Valor padrão
|
codfilial: "001", // Valor padrão
|
||||||
data_competencia: item.DATA || "2023-03", // Usar DATA do Oracle
|
data_competencia: item.DATA || "2023-03", // Usar DATA do Oracle
|
||||||
data_cai: item.DATA || "2023-03", // Usar DATA do Oracle
|
data_cai: item.DATA || "2023-03", // Usar DATA do Oracle
|
||||||
grupo: item.GRUPO || "", // Usar GRUPO do Oracle
|
grupo: codgrupo ? `${codgrupo} - ${nomeGrupo}` : nomeGrupo, // Concatenar código + nome
|
||||||
subgrupo: item.CENTROCUSTO || "", // Usar CENTROCUSTO como subgrupo
|
subgrupo: item.CENTROCUSTO || "", // Usar CENTROCUSTO como subgrupo
|
||||||
centro_custo: item.CODIGOCENTROCUSTO || "", // Usar CODIGOCENTROCUSTO
|
centro_custo: item.CODIGOCENTROCUSTO || "", // Usar CODIGOCENTROCUSTO
|
||||||
codigo_conta: parseInt(item.CODCONTA) || 0, // Converter CODCONTA para número
|
codigo_conta: parseInt(item.CODCONTA) || 0, // Converter CODCONTA para número
|
||||||
conta: item.CONTA || "", // Usar CONTA do Oracle
|
conta: item.CONTA || "", // Usar CONTA do Oracle
|
||||||
valor: item.VALOR?.toString() || "0", // Converter VALOR para string
|
valor: item.VALOR?.toString() || "0", // Converter VALOR para string
|
||||||
}));
|
codgrupo: codgrupo, // Adicionar código do grupo para cálculos
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
return NextResponse.json(transformedData);
|
// Criar grupos calculados que não existem no Oracle
|
||||||
|
const gruposCalculados = criarGruposCalculados(transformedData);
|
||||||
|
|
||||||
|
// Combinar dados originais com grupos calculados
|
||||||
|
const dadosCompletos = [...transformedData, ...gruposCalculados];
|
||||||
|
|
||||||
|
return NextResponse.json(dadosCompletos);
|
||||||
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('❌ Erro ao buscar dados DRE do Oracle:', error);
|
console.error('❌ Erro ao buscar dados DRE do Oracle:', error);
|
||||||
|
|
@ -40,3 +52,230 @@ export async function GET(request: NextRequest) {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function criarGruposCalculados(dados: any[]) {
|
||||||
|
const gruposCalculados: any[] = [];
|
||||||
|
|
||||||
|
// Agrupar dados por mês para cálculos
|
||||||
|
const dadosPorMes = dados.reduce((acc, item) => {
|
||||||
|
const mes = item.data_competencia;
|
||||||
|
if (!acc[mes]) acc[mes] = [];
|
||||||
|
acc[mes].push(item);
|
||||||
|
return acc;
|
||||||
|
}, {} as Record<string, any[]>);
|
||||||
|
|
||||||
|
// Para cada mês, criar os grupos calculados
|
||||||
|
Object.keys(dadosPorMes).forEach(mes => {
|
||||||
|
const dadosMes = dadosPorMes[mes];
|
||||||
|
|
||||||
|
// Calcular valores por grupo usando código numérico
|
||||||
|
const valoresPorGrupo = dadosMes.reduce((acc, item) => {
|
||||||
|
const codgrupo = item.codgrupo;
|
||||||
|
if (!acc[codgrupo]) acc[codgrupo] = 0;
|
||||||
|
acc[codgrupo] += parseFloat(item.valor);
|
||||||
|
return acc;
|
||||||
|
}, {} as Record<string, number>);
|
||||||
|
|
||||||
|
// 03 - Faturamento Líquido (01 + 02)
|
||||||
|
const faturamentoBruto = valoresPorGrupo['01'] || 0;
|
||||||
|
const devolucao = valoresPorGrupo['02'] || 0;
|
||||||
|
const faturamentoLiquido = faturamentoBruto + devolucao;
|
||||||
|
|
||||||
|
gruposCalculados.push({
|
||||||
|
codfilial: "001",
|
||||||
|
data_competencia: mes,
|
||||||
|
data_cai: mes,
|
||||||
|
grupo: "03 - FATURAMENTO LÍQUIDO",
|
||||||
|
subgrupo: "CALCULADO",
|
||||||
|
centro_custo: "CALCULADO",
|
||||||
|
codigo_conta: 0,
|
||||||
|
conta: "FATURAMENTO LÍQUIDO",
|
||||||
|
valor: faturamentoLiquido.toString(),
|
||||||
|
codgrupo: "03",
|
||||||
|
isCalculado: true
|
||||||
|
});
|
||||||
|
|
||||||
|
// 05 - Lucro Bruto (03 + 04)
|
||||||
|
const cmv = valoresPorGrupo['04'] || 0;
|
||||||
|
const lucroBruto = faturamentoLiquido + cmv;
|
||||||
|
|
||||||
|
gruposCalculados.push({
|
||||||
|
codfilial: "001",
|
||||||
|
data_competencia: mes,
|
||||||
|
data_cai: mes,
|
||||||
|
grupo: "05 - LUCRO BRUTO",
|
||||||
|
subgrupo: "CALCULADO",
|
||||||
|
centro_custo: "CALCULADO",
|
||||||
|
codigo_conta: 0,
|
||||||
|
conta: "LUCRO BRUTO",
|
||||||
|
valor: lucroBruto.toString(),
|
||||||
|
codgrupo: "05",
|
||||||
|
isCalculado: true
|
||||||
|
});
|
||||||
|
|
||||||
|
// 07 - Margem Loja (05 + 06)
|
||||||
|
const receitasGastosDiretos = valoresPorGrupo['06'] || 0;
|
||||||
|
const margemLoja = lucroBruto + receitasGastosDiretos;
|
||||||
|
|
||||||
|
gruposCalculados.push({
|
||||||
|
codfilial: "001",
|
||||||
|
data_competencia: mes,
|
||||||
|
data_cai: mes,
|
||||||
|
grupo: "07 - MARGEM LOJA",
|
||||||
|
subgrupo: "CALCULADO",
|
||||||
|
centro_custo: "CALCULADO",
|
||||||
|
codigo_conta: 0,
|
||||||
|
conta: "MARGEM LOJA",
|
||||||
|
valor: margemLoja.toString(),
|
||||||
|
codgrupo: "07",
|
||||||
|
isCalculado: true
|
||||||
|
});
|
||||||
|
|
||||||
|
// 10 - Resultado Operacional (07 + 08 + 09)
|
||||||
|
const verba = valoresPorGrupo['08'] || 0;
|
||||||
|
const receitasGastosIndiretos = valoresPorGrupo['09'] || 0;
|
||||||
|
const resultadoOperacional = margemLoja + verba + receitasGastosIndiretos;
|
||||||
|
|
||||||
|
gruposCalculados.push({
|
||||||
|
codfilial: "001",
|
||||||
|
data_competencia: mes,
|
||||||
|
data_cai: mes,
|
||||||
|
grupo: "10 - RESULTADO OPERACIONAL",
|
||||||
|
subgrupo: "CALCULADO",
|
||||||
|
centro_custo: "CALCULADO",
|
||||||
|
codigo_conta: 0,
|
||||||
|
conta: "RESULTADO OPERACIONAL",
|
||||||
|
valor: resultadoOperacional.toString(),
|
||||||
|
codgrupo: "10",
|
||||||
|
isCalculado: true
|
||||||
|
});
|
||||||
|
|
||||||
|
// 13 - Resultado Financeiro (11 + 12)
|
||||||
|
const receitaFinanceira = valoresPorGrupo['11'] || 0;
|
||||||
|
const despesaFinanceira = valoresPorGrupo['12'] || 0;
|
||||||
|
const resultadoFinanceiro = receitaFinanceira + despesaFinanceira;
|
||||||
|
|
||||||
|
gruposCalculados.push({
|
||||||
|
codfilial: "001",
|
||||||
|
data_competencia: mes,
|
||||||
|
data_cai: mes,
|
||||||
|
grupo: "13 - RESULTADO FINANCEIRO",
|
||||||
|
subgrupo: "CALCULADO",
|
||||||
|
centro_custo: "CALCULADO",
|
||||||
|
codigo_conta: 0,
|
||||||
|
conta: "RESULTADO FINANCEIRO",
|
||||||
|
valor: resultadoFinanceiro.toString(),
|
||||||
|
codgrupo: "13",
|
||||||
|
isCalculado: true
|
||||||
|
});
|
||||||
|
|
||||||
|
// 18 - Outras Receitas / Despesas (14 + 15 + 16 + 17)
|
||||||
|
const prejuizosPerdas = valoresPorGrupo['14'] || 0;
|
||||||
|
const inativas = valoresPorGrupo['15'] || 0;
|
||||||
|
const diretoria = valoresPorGrupo['16'] || 0;
|
||||||
|
const lancamentosSemCC = valoresPorGrupo['17'] || 0;
|
||||||
|
const outrasReceitasDespesas = prejuizosPerdas + inativas + diretoria + lancamentosSemCC;
|
||||||
|
|
||||||
|
gruposCalculados.push({
|
||||||
|
codfilial: "001",
|
||||||
|
data_competencia: mes,
|
||||||
|
data_cai: mes,
|
||||||
|
grupo: "18 - OUTRAS RECEITAS / DESPESAS",
|
||||||
|
subgrupo: "CALCULADO",
|
||||||
|
centro_custo: "CALCULADO",
|
||||||
|
codigo_conta: 0,
|
||||||
|
conta: "OUTRAS RECEITAS / DESPESAS",
|
||||||
|
valor: outrasReceitasDespesas.toString(),
|
||||||
|
codgrupo: "18",
|
||||||
|
isCalculado: true
|
||||||
|
});
|
||||||
|
|
||||||
|
// 19 - LAIR (10 + 13 + 18)
|
||||||
|
const lair = resultadoOperacional + resultadoFinanceiro + outrasReceitasDespesas;
|
||||||
|
|
||||||
|
gruposCalculados.push({
|
||||||
|
codfilial: "001",
|
||||||
|
data_competencia: mes,
|
||||||
|
data_cai: mes,
|
||||||
|
grupo: "19 - LAIR",
|
||||||
|
subgrupo: "CALCULADO",
|
||||||
|
centro_custo: "CALCULADO",
|
||||||
|
codigo_conta: 0,
|
||||||
|
conta: "LAIR",
|
||||||
|
valor: lair.toString(),
|
||||||
|
codgrupo: "19",
|
||||||
|
isCalculado: true
|
||||||
|
});
|
||||||
|
|
||||||
|
// 20 - IR (se LAIR > 0 calcular 20% e resultado negativo, se não 0)
|
||||||
|
const ir = lair > 0 ? -(lair * 0.20) : 0;
|
||||||
|
|
||||||
|
gruposCalculados.push({
|
||||||
|
codfilial: "001",
|
||||||
|
data_competencia: mes,
|
||||||
|
data_cai: mes,
|
||||||
|
grupo: "20 - IR",
|
||||||
|
subgrupo: "CALCULADO",
|
||||||
|
centro_custo: "CALCULADO",
|
||||||
|
codigo_conta: 0,
|
||||||
|
conta: "IMPOSTO DE RENDA",
|
||||||
|
valor: ir.toString(),
|
||||||
|
codgrupo: "20",
|
||||||
|
isCalculado: true
|
||||||
|
});
|
||||||
|
|
||||||
|
// 21 - CSLL (se LAIR > 0 calcular 9% e resultado negativo, se não 0)
|
||||||
|
const csll = lair > 0 ? -(lair * 0.09) : 0;
|
||||||
|
|
||||||
|
gruposCalculados.push({
|
||||||
|
codfilial: "001",
|
||||||
|
data_competencia: mes,
|
||||||
|
data_cai: mes,
|
||||||
|
grupo: "21 - CSLL",
|
||||||
|
subgrupo: "CALCULADO",
|
||||||
|
centro_custo: "CALCULADO",
|
||||||
|
codigo_conta: 0,
|
||||||
|
conta: "CONTRIBUIÇÃO SOCIAL SOBRE LUCRO LÍQUIDO",
|
||||||
|
valor: csll.toString(),
|
||||||
|
codgrupo: "21",
|
||||||
|
isCalculado: true
|
||||||
|
});
|
||||||
|
|
||||||
|
// 22 - Lucro Líquido (19 + 20 + 21)
|
||||||
|
const lucroLiquido = lair + ir + csll;
|
||||||
|
|
||||||
|
gruposCalculados.push({
|
||||||
|
codfilial: "001",
|
||||||
|
data_competencia: mes,
|
||||||
|
data_cai: mes,
|
||||||
|
grupo: "22 - LUCRO LÍQUIDO",
|
||||||
|
subgrupo: "CALCULADO",
|
||||||
|
centro_custo: "CALCULADO",
|
||||||
|
codigo_conta: 0,
|
||||||
|
conta: "LUCRO LÍQUIDO",
|
||||||
|
valor: lucroLiquido.toString(),
|
||||||
|
codgrupo: "22",
|
||||||
|
isCalculado: true
|
||||||
|
});
|
||||||
|
|
||||||
|
// 24 - EBITDA (19 - (13 + 18 + 23))
|
||||||
|
const despesaTributaria = valoresPorGrupo['23'] || 0;
|
||||||
|
const ebitda = lair - (resultadoFinanceiro + outrasReceitasDespesas + despesaTributaria);
|
||||||
|
|
||||||
|
gruposCalculados.push({
|
||||||
|
codfilial: "001",
|
||||||
|
data_competencia: mes,
|
||||||
|
data_cai: mes,
|
||||||
|
grupo: "24 - EBITDA",
|
||||||
|
subgrupo: "CALCULADO",
|
||||||
|
centro_custo: "CALCULADO",
|
||||||
|
codigo_conta: 0,
|
||||||
|
conta: "EBITDA",
|
||||||
|
valor: ebitda.toString(),
|
||||||
|
codgrupo: "24",
|
||||||
|
isCalculado: true
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
return gruposCalculados;
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue