fix(producao): liberacao automatica de pecas na solda por kits completos no corte

This commit is contained in:
2026-10-26 11:59:05 -03:00
parent 1e191fe562
commit ea447df298
6 changed files with 580 additions and 146 deletions
@@ -24,6 +24,7 @@ import { useAuth } from '@/hooks/useAuth';
import { smartAudio } from '@/utils/smartAudio';
import { toast } from 'sonner';
import { PecaKitInfo, ComponenteKitInfo } from '@/hooks/useKitsProducao';
import { sincronizarPecaKitNoCorte } from '@/utils/sincronizacaoKitsCorte';
interface SmartComponentesCorteModalProps {
open: boolean;
@@ -122,9 +123,23 @@ export const SmartComponentesCorteModal: React.FC<SmartComponentesCorteModalProp
const { error } = await supabase.from('apontamentos_producao').insert(batchPayloads);
if (error) throw error;
// Sincronizar liberação de kits completos da peça mestre no Corte para a Solda
const resSync = await sincronizarPecaKitNoCorte({
ofNumber,
pecaId: pecaKit.peca_id,
processoCorteId,
userId: user?.id,
usuarioNome: nomeUsuario,
dataApontamento: hoje,
});
smartAudio.playSuccess();
const infoLiberado =
resSync && resSync.delta_liberado > 0
? ` (+${resSync.delta_liberado} peça(s) liberada(s) para Solda)`
: '';
toast.success(
`✅ ${multiplicadorKits} Kit Completo da peça ${pecaKit.marca} cortado com sucesso! (+${pesoTotalKg.toFixed(1)} kg)`
`✅ ${multiplicadorKits} Kit Completo da peça ${pecaKit.marca} cortado com sucesso! (+${pesoTotalKg.toFixed(1)} kg)${infoLiberado}`
);
onApontamentoSalvo();
@@ -165,11 +180,27 @@ export const SmartComponentesCorteModal: React.FC<SmartComponentesCorteModalProp
const { error } = await supabase.from('apontamentos_producao').insert(payload);
if (error) throw error;
// Sincronizar se este corte completou novos kits completos (respeitando estritamente o gargalo de todos os componentes)
const resSync = await sincronizarPecaKitNoCorte({
ofNumber,
pecaId: pecaKit.peca_id,
processoCorteId,
userId: user?.id,
usuarioNome: nomeUsuario,
dataApontamento: hoje,
});
const pesoKg = qtd * (comp.peso_unitario || 0);
smartAudio.playSuccess();
toast.success(
`✂️ Apontado no Corte: ${qtd}x ${comp.marca_componente} (+${pesoKg.toFixed(1)} kg)`
);
if (resSync && resSync.delta_liberado > 0) {
toast.success(
`✂️ Apontado no Corte: ${qtd}x ${comp.marca_componente} (+${pesoKg.toFixed(1)} kg) • ⚡ Kit completo formado: +${resSync.delta_liberado} un de ${pecaKit.marca} liberada(s) para Solda!`
);
} else {
toast.success(
`✂️ Apontado no Corte: ${qtd}x ${comp.marca_componente} (+${pesoKg.toFixed(1)} kg)`
);
}
// Limpar valor digitado
setQuantidadesManual((prev) => {
@@ -29,6 +29,7 @@ import { SmartForcarApontamentoModal } from './SmartForcarApontamentoModal';
import { calcularKitsOF, PecaKitInfo } from '@/hooks/useKitsProducao';
import { MapaTermicoKitsModal } from '@/components/apontamento/kits/MapaTermicoKitsModal';
import { SmartComponentesCorteModal } from './SmartComponentesCorteModal';
import { sincronizarTodosKitsOFCorte } from '@/utils/sincronizacaoKitsCorte';
interface SmartProducaoFlowProps {
obra: OFAtiva;
@@ -384,7 +385,7 @@ export const SmartProducaoFlow: React.FC<SmartProducaoFlowProps> = ({
if (a.saldo === 0 && b.saldo > 0) return 1;
return a.marca.localeCompare(b.marca, undefined, { numeric: true, sensitivity: 'base' });
});
}, [pecas, faseSelecionada, processoSelecionado, mapaProducao, processos, pecasPendentesMap]);
}, [pecas, faseSelecionada, processoSelecionado, mapaProducao, processos, pecasPendentesMap, mapaKits]);
// Helper de ícone por processo
const getIconeProcesso = (nome: string) => {
@@ -403,6 +404,23 @@ export const SmartProducaoFlow: React.FC<SmartProducaoFlowProps> = ({
smartAudio.playClick();
setProcessoSelecionado(proc);
setEtapaAtual('fase');
// Ao selecionar Solda ou Montagem, rodar sincronização preventiva de kits da OF
const nomeP = (proc.nome || '').toLowerCase();
if ((nomeP.includes('solda') || nomeP.includes('montag')) && procCorteId && obra.of_number) {
sincronizarTodosKitsOFCorte({
ofNumber: obra.of_number,
processoCorteId: procCorteId,
userId: user?.id,
usuarioNome: user?.name || user?.username || 'Operador',
})
.then((res) => {
if (res.some((r) => r.delta_liberado > 0)) {
carregarDadosOF();
}
})
.catch((e) => console.warn('Erro na sincronização preventiva de kits:', e));
}
};
const handleEscolherFase = (fase: string) => {