diff --git a/src/hooks/useApontamentosProducao.tsx b/src/hooks/useApontamentosProducao.tsx index ec04341..9f1de0c 100644 --- a/src/hooks/useApontamentosProducao.tsx +++ b/src/hooks/useApontamentosProducao.tsx @@ -381,9 +381,12 @@ interface InsertApontamentoData { toast.success('Apontamento registrado com sucesso!'); return { success: true }; - } catch (error) { + } catch (error: any) { console.error('❌ Erro ao criar apontamento:', error); - const errorMessage = error instanceof Error ? error.message : String(error); + const isConflict = error?.status === 409 || error?.code === '23505' || String(error?.message || '').includes('409'); + const errorMessage = isConflict + ? 'Este item ou processo já teve o apontamento registrado por outro usuário ou os dados em cache estão desatualizados. Por favor, clique em "Limpar" no cache e atualize a página.' + : (error instanceof Error ? error.message : String(error)); toast.error('Erro ao registrar apontamento: ' + errorMessage); return { success: false, error }; } diff --git a/supabase/migrations/20260831204500_fix_apontamentos_trigger_conflict.sql b/supabase/migrations/20260831204500_fix_apontamentos_trigger_conflict.sql new file mode 100644 index 0000000..7b2db06 --- /dev/null +++ b/supabase/migrations/20260831204500_fix_apontamentos_trigger_conflict.sql @@ -0,0 +1,52 @@ +-- Migration para corrigir a trigger atualizar_datas_reais_processo e prevenir erros 409 (Conflict) em inserções concorrentes de apontamentos + +CREATE OR REPLACE FUNCTION public.atualizar_datas_reais_processo() +RETURNS TRIGGER AS $$ +DECLARE + total_produzido NUMERIC; + total_planejado NUMERIC; +BEGIN + -- Se peca_id for nulo (ex: apontamento de componente sem peca_id vinculada), ignorar processamento de datas por peça + IF NEW.peca_id IS NULL THEN + RETURN NEW; + END IF; + + -- Buscar quantidade total planejada da peça + SELECT COALESCE(quantidade, 0) INTO total_planejado + FROM public.pecas + WHERE id = NEW.peca_id; + + -- Inserir novo registro ou atualizar existente usando ON CONFLICT para evitar erro 409 (Constraint UNIQUE peca_id + processo_id) + INSERT INTO public.processos_pecas_datas ( + peca_id, + processo_id, + data_inicio_real, + quantidade_total_planejada, + quantidade_total_produzida + ) VALUES ( + NEW.peca_id, + NEW.processo_id, + NEW.data_apontamento, + total_planejado, + NEW.quantidade_produzida + ) + ON CONFLICT (peca_id, processo_id) DO UPDATE + SET + quantidade_total_produzida = ( + SELECT COALESCE(SUM(quantidade_produzida), 0) + FROM public.apontamentos_producao + WHERE peca_id = NEW.peca_id AND processo_id = NEW.processo_id + ), + data_conclusao_real = CASE + WHEN ( + SELECT COALESCE(SUM(quantidade_produzida), 0) + FROM public.apontamentos_producao + WHERE peca_id = NEW.peca_id AND processo_id = NEW.processo_id + ) >= processos_pecas_datas.quantidade_total_planejada THEN NEW.data_apontamento + ELSE processos_pecas_datas.data_conclusao_real + END, + updated_at = now(); + + RETURN NEW; +END; +$$ LANGUAGE plpgsql;