fix: calculo conceitual de percentual e meta de solda baseado no peso de pecas com componentes

This commit is contained in:
2026-09-09 21:12:05 +00:00
parent aa457ffa0c
commit 6d47f7eac9
3 changed files with 96 additions and 56 deletions
+8 -1
View File
@@ -85,6 +85,10 @@ export const useDashboardProducao = (ofNumber: string) => {
total + (peca.quantidade * (peca.peso_unitario || 0)), 0
);
const pesoTotalSoldavel = pecasData.filter(p => p.tem_componentes === true).reduce((total, peca) =>
total + (peca.quantidade * (peca.peso_unitario || 0)), 0
) || pesoTotalPlanejado;
const pesoTotalFabricado = apontamentosData.reduce((total, apontamento) =>
total + (apontamento.quantidade_produzida * (apontamento.peca?.peso_unitario || 0)), 0
);
@@ -98,7 +102,10 @@ export const useDashboardProducao = (ofNumber: string) => {
total + (a.quantidade_produzida * (a.peca?.peso_unitario || 0)), 0
);
const progressoReal = pesoTotalPlanejado > 0 ? (pesoFabricadoProcesso / pesoTotalPlanejado) * 100 : 0;
const isProcessoSolda = processo.nome.toLowerCase().includes('solda');
const pesoBase = isProcessoSolda && pesoTotalSoldavel > 0 ? pesoTotalSoldavel : pesoTotalPlanejado;
const progressoReal = pesoBase > 0 ? (pesoFabricadoProcesso / pesoBase) * 100 : 0;
// Calcular progresso esperado baseado na data atual
const hoje = new Date();
+48 -37
View File
@@ -83,46 +83,54 @@ export const useDashboardProducaoOtimizado = (ofNumber: string) => {
}
}
// 3. Se ainda não temos peso, calcular das peças cadastradas
// 3. Buscar peças cadastradas para calcular peso total e peso soldável (peças com componentes)
const { data: pecasData, error: pecasError } = await supabase
.from('pecas')
.select('peso_unitario, quantidade, tem_componentes')
.eq('of_number', ofNumber);
if (pecasError) {
console.error('Erro ao buscar peças:', pecasError);
throw pecasError;
}
const pesoBrutoPecas = (pecasData || []).reduce((total, peca) => {
const pesoUnitario = peca.peso_unitario || 0;
const quantidade = peca.quantidade || 0;
return total + (pesoUnitario * quantidade);
}, 0);
// Peso soldável: apenas peças que possuem componentes (peças soltas não vão para solda)
let pesoTotalSoldavel = (pecasData || []).filter(p => p.tem_componentes === true).reduce((total, peca) => {
const pesoUnitario = peca.peso_unitario || 0;
const quantidade = peca.quantidade || 0;
return total + (pesoUnitario * quantidade);
}, 0);
if (!pesoTotalPlanejado) {
const { data: pecasData, error: pecasError } = await supabase
.from('pecas')
.select('peso_unitario, quantidade')
.eq('of_number', ofNumber);
if (pecasError) {
console.error('Erro ao buscar peças:', pecasError);
throw pecasError;
}
pesoTotalPlanejado = pecasData.reduce((total, peca) => {
const pesoUnitario = peca.peso_unitario || 0;
const quantidade = peca.quantidade || 0;
return total + (pesoUnitario * quantidade);
}, 0);
pesoTotalPlanejado = pesoBrutoPecas;
}
// CORREÇÃO AUTOMÁTICA: Evita que erros de digitação (ex: digitar 1.856 ao invés de 1856 kg na OF)
// causem porcentagens irreais (ex: 100000%). Compara com a soma real das peças.
if (pesoTotalPlanejado > 0) {
const { data: pecasVerificar } = await supabase.from('pecas').select('peso_unitario, quantidade').eq('of_number', ofNumber);
if (pecasVerificar && pecasVerificar.length > 0) {
const pesoBrutoPecas = pecasVerificar.reduce((sum, p) => sum + ((p.peso_unitario || 0) * (p.quantidade || 0)), 0);
if (pesoBrutoPecas > pesoTotalPlanejado * 50) {
console.log(`Corrigindo erro de digitação de peso da OF. Planejado original: ${pesoTotalPlanejado} kg, Soma das peças: ${pesoBrutoPecas} kg`);
// Se for um erro típico de 1000x (usou ponto para separar milhar)
if (pesoBrutoPecas <= pesoTotalPlanejado * 3000 && pesoBrutoPecas >= pesoTotalPlanejado * 500) {
pesoTotalPlanejado = pesoTotalPlanejado * 1000;
} else {
// Se for outro erro grosseiro, assume que o peso correto é o das peças
pesoTotalPlanejado = pesoBrutoPecas;
}
}
if (pesoTotalPlanejado > 0 && pesoBrutoPecas > 0) {
if (pesoBrutoPecas > pesoTotalPlanejado * 50) {
console.log(`Corrigindo erro de digitação de peso da OF. Planejado original: ${pesoTotalPlanejado} kg, Soma das peças: ${pesoBrutoPecas} kg`);
if (pesoBrutoPecas <= pesoTotalPlanejado * 3000 && pesoBrutoPecas >= pesoTotalPlanejado * 500) {
pesoTotalPlanejado = pesoTotalPlanejado * 1000;
} else {
pesoTotalPlanejado = pesoBrutoPecas;
}
}
}
// Se todas as peças têm componentes ou nenhuma tem flag marcada, fallback para o peso total
if (pesoTotalSoldavel <= 0 && pesoTotalPlanejado > 0) {
pesoTotalSoldavel = pesoTotalPlanejado;
}
console.log('Peso total planejado (BASE DE TODOS OS CÁLCULOS):', pesoTotalPlanejado, 'kg');
console.log('Peso total soldável (apenas peças com componentes):', pesoTotalSoldavel, 'kg');
// 4. Buscar apontamentos da OF com joins corretos
const { data: apontamentosData, error: apontamentosError } = await supabase
@@ -329,9 +337,12 @@ export const useDashboardProducaoOtimizado = (ofNumber: string) => {
pesoFabricadoProcesso += pesoUnitario * Number(a.quantidade_produzida);
});
const progressoReal = pesoTotalPlanejado > 0 ? (pesoFabricadoProcesso / pesoTotalPlanejado) * 100 : 0;
const isProcessoSolda = processo.nome.toLowerCase().includes('solda');
const pesoBaseProcesso = isProcessoSolda && pesoTotalSoldavel > 0 ? pesoTotalSoldavel : pesoTotalPlanejado;
const progressoReal = pesoBaseProcesso > 0 ? (pesoFabricadoProcesso / pesoBaseProcesso) * 100 : 0;
console.log(`PROCESSO ${processo.nome}: ${pesoFabricadoProcesso} kg fabricado / ${pesoTotalPlanejado} kg planejado = ${progressoReal.toFixed(2)}%`);
console.log(`PROCESSO ${processo.nome}: ${pesoFabricadoProcesso} kg fabricado / ${pesoBaseProcesso} kg planejado (base ${isProcessoSolda ? 'soldável' : 'total'}) = ${progressoReal.toFixed(2)}%`);
// Calcular progresso esperado usando as datas do cronograma
const progressoEsperado = calcularProgressoEsperado(processo.nome);
@@ -444,10 +455,10 @@ export const useDashboardProducaoOtimizado = (ofNumber: string) => {
if (data >= dataInicioProcesso && data <= dataFimProcesso) {
const diasDecorridos = Math.floor((Math.min(data.getTime(), dataFimProcesso.getTime()) - dataInicioProcesso.getTime()) / MS_PER_DAY) + 1;
const percentualDias = diasDecorridos / diasTotaisProcesso;
planejado = percentualDias * pesoTotalPlanejado;
planejado = percentualDias * pesoBaseProcesso;
} else if (data > dataFimProcesso) {
// Após o fim planejado, manter o peso total planejado
planejado = pesoTotalPlanejado;
// Após o fim planejado, manter o peso base do processo
planejado = pesoBaseProcesso;
}
// Antes do início planejado, o planejado fica 0
@@ -480,7 +491,7 @@ export const useDashboardProducaoOtimizado = (ofNumber: string) => {
return {
id: processo.id,
nome: processo.nome,
pesoTotal: pesoTotalPlanejado, // SEMPRE o peso total da OF/ficha técnica
pesoTotal: pesoBaseProcesso, // Peso alvo do processo (soldável para solda, total para os demais)
pesoFabricado: pesoFabricadoProcesso,
progressoReal,
progressoEsperado,
+40 -18
View File
@@ -118,30 +118,52 @@ export const useProcessChartData = (ofNumber: string) => {
.eq('num_of', ofNumber)
.single();
let pesoTotalPlanejado = ofData?.peso_total || 0;
if (!pesoTotalPlanejado) {
const { data: fichaTecnica } = await supabase
.from('ficha_tecnica_contratos')
.select('quantidade')
.eq('of_number', ofNumber)
.maybeSingle();
const isProcessoSolda = processName.toLowerCase().includes('solda');
if (fichaTecnica?.quantidade) {
pesoTotalPlanejado = fichaTecnica.quantidade;
let pesoTotalPlanejado = 0;
// Se for solda, a meta deve ser calculada estritamente sobre as peças que possuem componentes
if (isProcessoSolda) {
const { data: pecasSolda } = await supabase
.from('pecas')
.select('peso_unitario, quantidade, tem_componentes')
.eq('of_number', ofNumber)
.eq('tem_componentes', true);
if (pecasSolda && pecasSolda.length > 0) {
pesoTotalPlanejado = pecasSolda.reduce((total, peca) => {
return total + ((peca.peso_unitario || 0) * (peca.quantidade || 0));
}, 0);
}
}
// Se não for solda ou se não encontrou peças específicas de solda, busca peso total geral
if (!pesoTotalPlanejado) {
const { data: pecasData } = await supabase
.from('pecas')
.select('peso_unitario, quantidade')
.eq('of_number', ofNumber);
pesoTotalPlanejado = ofData?.peso_total || 0;
if (!pesoTotalPlanejado) {
const { data: fichaTecnica } = await supabase
.from('ficha_tecnica_contratos')
.select('quantidade')
.eq('of_number', ofNumber)
.maybeSingle();
if (pecasData) {
pesoTotalPlanejado = pecasData.reduce((total, peca) => {
return total + ((peca.peso_unitario || 0) * (peca.quantidade || 0));
}, 0);
if (fichaTecnica?.quantidade) {
pesoTotalPlanejado = fichaTecnica.quantidade;
}
}
if (!pesoTotalPlanejado) {
const { data: pecasData } = await supabase
.from('pecas')
.select('peso_unitario, quantidade')
.eq('of_number', ofNumber);
if (pecasData) {
pesoTotalPlanejado = pecasData.reduce((total, peca) => {
return total + ((peca.peso_unitario || 0) * (peca.quantidade || 0));
}, 0);
}
}
}