fix(producao): liberacao automatica de pecas na solda por kits completos no corte
This commit is contained in:
@@ -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) => {
|
||||
|
||||
Reference in New Issue
Block a user