fix(cronograma): corrigir salvamento e atualizacao automatica da lista de cronogramas
This commit is contained in:
@@ -20,6 +20,7 @@ interface CronogramaFormProps {
|
||||
cronograma?: CronogramaOf | null;
|
||||
onClose: () => void;
|
||||
isOpen: boolean;
|
||||
onSaveSuccess?: () => void;
|
||||
}
|
||||
|
||||
const processosDefault = [
|
||||
@@ -30,7 +31,7 @@ const processosDefault = [
|
||||
'Aceite/DB'
|
||||
];
|
||||
|
||||
export const CronogramaForm: React.FC<CronogramaFormProps> = ({ cronograma, onClose, isOpen }) => {
|
||||
export const CronogramaForm: React.FC<CronogramaFormProps> = ({ cronograma, onClose, isOpen, onSaveSuccess }) => {
|
||||
const { saveCronograma, getCronogramaPorOf } = useCronogramaOperations();
|
||||
const [formData, setFormData] = useState({
|
||||
of_id: '',
|
||||
@@ -228,6 +229,9 @@ export const CronogramaForm: React.FC<CronogramaFormProps> = ({ cronograma, onCl
|
||||
setLoading(false);
|
||||
|
||||
if (success) {
|
||||
if (onSaveSuccess) {
|
||||
onSaveSuccess();
|
||||
}
|
||||
onClose();
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1,249 +1 @@
|
||||
|
||||
import { useState, useEffect } from 'react';
|
||||
import { supabase } from '@/integrations/supabase/client';
|
||||
import { toast } from 'sonner';
|
||||
import { useAuth } from './useAuth';
|
||||
import { CronogramaOf } from '@/types/cronograma';
|
||||
|
||||
export const useCronogramaOperations = () => {
|
||||
const { user } = useAuth();
|
||||
const [cronogramas, setCronogramas] = useState<CronogramaOf[]>([]);
|
||||
const [loading, setLoading] = useState(false);
|
||||
|
||||
const loadCronogramas = async () => {
|
||||
try {
|
||||
setLoading(true);
|
||||
|
||||
const { data: cronogramasData, error: cronogramasError } = await supabase
|
||||
.from('cronogramas_of')
|
||||
.select(`
|
||||
*,
|
||||
ordens_fabricacao (
|
||||
num_of,
|
||||
descritivo
|
||||
),
|
||||
profiles!cronogramas_of_gestor_id_fkey (
|
||||
full_name,
|
||||
email
|
||||
)
|
||||
`)
|
||||
.order('created_at', { ascending: false });
|
||||
|
||||
if (cronogramasError) throw cronogramasError;
|
||||
|
||||
// Carregar processos para cada cronograma
|
||||
const cronogramasComProcessos = await Promise.all(
|
||||
(cronogramasData || []).map(async (cronograma) => {
|
||||
const { data: processos, error: processosError } = await supabase
|
||||
.from('processos_cronograma')
|
||||
.select('*')
|
||||
.eq('cronograma_id', cronograma.id)
|
||||
.order('ordem');
|
||||
|
||||
if (processosError) throw processosError;
|
||||
|
||||
return {
|
||||
id: cronograma.id,
|
||||
of_id: cronograma.of_id,
|
||||
gestor_id: cronograma.gestor_id,
|
||||
revisao: cronograma.revisao,
|
||||
processos: processos || [],
|
||||
ordem_fabricacao: cronograma.ordens_fabricacao,
|
||||
gestor_profile: cronograma.profiles
|
||||
} as CronogramaOf;
|
||||
})
|
||||
);
|
||||
|
||||
setCronogramas(cronogramasComProcessos);
|
||||
} catch (error) {
|
||||
console.error('Erro ao carregar cronogramas:', error);
|
||||
toast.error('Erro ao carregar cronogramas');
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
};
|
||||
|
||||
const saveCronograma = async (cronograma: Partial<CronogramaOf> & { processos: any[] }) => {
|
||||
try {
|
||||
if (!user) throw new Error('Usuário não autenticado');
|
||||
|
||||
let cronogramaId: string;
|
||||
|
||||
if (cronograma.id) {
|
||||
// Atualizar cronograma existente
|
||||
const novaRevisao = cronograma.revisao ? cronograma.revisao + 1 : 1;
|
||||
|
||||
const { data: updatedCronograma, error: updateError } = await supabase
|
||||
.from('cronogramas_of')
|
||||
.update({
|
||||
gestor_id: cronograma.gestor_id,
|
||||
revisao: novaRevisao,
|
||||
updated_at: new Date().toISOString()
|
||||
})
|
||||
.eq('id', cronograma.id)
|
||||
.select()
|
||||
.single();
|
||||
|
||||
if (updateError) throw updateError;
|
||||
cronogramaId = updatedCronograma.id;
|
||||
|
||||
// Deletar processos antigos
|
||||
const { error: deleteError } = await supabase
|
||||
.from('processos_cronograma')
|
||||
.delete()
|
||||
.eq('cronograma_id', cronogramaId);
|
||||
|
||||
if (deleteError) throw deleteError;
|
||||
} else {
|
||||
// Verificar se já existe cronograma para esta OF
|
||||
const { data: existingCronograma } = await supabase
|
||||
.from('cronogramas_of')
|
||||
.select('id, revisao')
|
||||
.eq('of_id', cronograma.of_id)
|
||||
.single();
|
||||
|
||||
if (existingCronograma) {
|
||||
// Atualizar cronograma existente
|
||||
const novaRevisao = existingCronograma.revisao + 1;
|
||||
|
||||
const { data: updatedCronograma, error: updateError } = await supabase
|
||||
.from('cronogramas_of')
|
||||
.update({
|
||||
gestor_id: cronograma.gestor_id,
|
||||
revisao: novaRevisao,
|
||||
updated_at: new Date().toISOString()
|
||||
})
|
||||
.eq('id', existingCronograma.id)
|
||||
.select()
|
||||
.single();
|
||||
|
||||
if (updateError) throw updateError;
|
||||
cronogramaId = updatedCronograma.id;
|
||||
|
||||
// Deletar processos antigos
|
||||
const { error: deleteError } = await supabase
|
||||
.from('processos_cronograma')
|
||||
.delete()
|
||||
.eq('cronograma_id', cronogramaId);
|
||||
|
||||
if (deleteError) throw deleteError;
|
||||
} else {
|
||||
// Criar novo cronograma
|
||||
const { data: newCronograma, error: insertError } = await supabase
|
||||
.from('cronogramas_of')
|
||||
.insert({
|
||||
of_id: cronograma.of_id,
|
||||
gestor_id: cronograma.gestor_id,
|
||||
revisao: 1,
|
||||
created_by: user.id
|
||||
})
|
||||
.select()
|
||||
.single();
|
||||
|
||||
if (insertError) throw insertError;
|
||||
cronogramaId = newCronograma.id;
|
||||
}
|
||||
}
|
||||
|
||||
// Inserir novos processos
|
||||
const processosParaInserir = cronograma.processos.map(processo => ({
|
||||
cronograma_id: cronogramaId,
|
||||
nome_processo: processo.nome_processo,
|
||||
data_inicio: processo.data_inicio,
|
||||
data_fim: processo.data_fim,
|
||||
ordem: processo.ordem
|
||||
}));
|
||||
|
||||
const { error: processosError } = await supabase
|
||||
.from('processos_cronograma')
|
||||
.insert(processosParaInserir);
|
||||
|
||||
if (processosError) throw processosError;
|
||||
|
||||
toast.success('Cronograma salvo com sucesso!');
|
||||
loadCronogramas();
|
||||
return true;
|
||||
} catch (error) {
|
||||
console.error('Erro ao salvar cronograma:', error);
|
||||
toast.error('Erro ao salvar cronograma');
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
const deleteCronograma = async (cronogramaId: string) => {
|
||||
try {
|
||||
const { error } = await supabase
|
||||
.from('cronogramas_of')
|
||||
.delete()
|
||||
.eq('id', cronogramaId);
|
||||
|
||||
if (error) throw error;
|
||||
|
||||
toast.success('Cronograma removido com sucesso!');
|
||||
loadCronogramas();
|
||||
return true;
|
||||
} catch (error) {
|
||||
console.error('Erro ao deletar cronograma:', error);
|
||||
toast.error('Erro ao remover cronograma');
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
const getCronogramaPorOf = async (ofId: string) => {
|
||||
try {
|
||||
const { data: cronograma, error } = await supabase
|
||||
.from('cronogramas_of')
|
||||
.select(`
|
||||
*,
|
||||
ordens_fabricacao (
|
||||
num_of,
|
||||
descritivo
|
||||
),
|
||||
profiles!cronogramas_of_gestor_id_fkey (
|
||||
full_name,
|
||||
email
|
||||
)
|
||||
`)
|
||||
.eq('of_id', ofId)
|
||||
.single();
|
||||
|
||||
if (error && error.code !== 'PGRST116') throw error;
|
||||
|
||||
if (!cronograma) return null;
|
||||
|
||||
const { data: processos, error: processosError } = await supabase
|
||||
.from('processos_cronograma')
|
||||
.select('*')
|
||||
.eq('cronograma_id', cronograma.id)
|
||||
.order('ordem');
|
||||
|
||||
if (processosError) throw processosError;
|
||||
|
||||
return {
|
||||
id: cronograma.id,
|
||||
of_id: cronograma.of_id,
|
||||
gestor_id: cronograma.gestor_id,
|
||||
revisao: cronograma.revisao,
|
||||
processos: processos || [],
|
||||
ordem_fabricacao: cronograma.ordens_fabricacao,
|
||||
gestor_profile: cronograma.profiles
|
||||
} as CronogramaOf;
|
||||
} catch (error) {
|
||||
console.error('Erro ao buscar cronograma:', error);
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
loadCronogramas();
|
||||
}, []);
|
||||
|
||||
return {
|
||||
cronogramas,
|
||||
loading,
|
||||
loadCronogramas,
|
||||
saveCronograma,
|
||||
deleteCronograma,
|
||||
getCronogramaPorOf
|
||||
};
|
||||
};
|
||||
export { useCronogramas as useCronogramaOperations } from './useCronogramas';
|
||||
|
||||
@@ -47,7 +47,7 @@ export const useCronogramas = () => {
|
||||
descritivo,
|
||||
peso_total
|
||||
),
|
||||
profiles!gestor_id (
|
||||
profiles!cronogramas_of_gestor_id_fkey (
|
||||
full_name,
|
||||
email
|
||||
)
|
||||
@@ -89,23 +89,50 @@ export const useCronogramas = () => {
|
||||
}
|
||||
};
|
||||
|
||||
const saveCronograma = async (cronograma: Omit<CronogramaOf, 'id'>) => {
|
||||
const saveCronograma = async (cronograma: Partial<CronogramaOf> & { processos: ProcessoCronograma[] }) => {
|
||||
try {
|
||||
if (!user) throw new Error('Usuário não autenticado');
|
||||
if (!cronograma.of_id) throw new Error('Selecione uma Ordem de Fabricação');
|
||||
if (!cronograma.gestor_id) throw new Error('Selecione o gestor responsável');
|
||||
|
||||
// Verificar se já existe cronograma para esta OF
|
||||
let cronogramaId: string;
|
||||
|
||||
if (cronograma.id) {
|
||||
// Atualizar cronograma existente por ID
|
||||
const novaRevisao = cronograma.revisao ? cronograma.revisao + 1 : 1;
|
||||
|
||||
const { data: updatedCronograma, error: updateError } = await supabase
|
||||
.from('cronogramas_of')
|
||||
.update({
|
||||
gestor_id: cronograma.gestor_id,
|
||||
revisao: novaRevisao,
|
||||
updated_at: new Date().toISOString()
|
||||
})
|
||||
.eq('id', cronograma.id)
|
||||
.select()
|
||||
.single();
|
||||
|
||||
if (updateError) throw updateError;
|
||||
cronogramaId = updatedCronograma.id;
|
||||
|
||||
// Deletar processos antigos
|
||||
const { error: deleteError } = await supabase
|
||||
.from('processos_cronograma')
|
||||
.delete()
|
||||
.eq('cronograma_id', cronogramaId);
|
||||
|
||||
if (deleteError) throw deleteError;
|
||||
} else {
|
||||
// Verificar se já existe cronograma para esta OF (usando maybeSingle para evitar erro PGRST116)
|
||||
const { data: existingCronograma } = await supabase
|
||||
.from('cronogramas_of')
|
||||
.select('id, revisao')
|
||||
.eq('of_id', cronograma.of_id)
|
||||
.single();
|
||||
|
||||
let cronogramaId: string;
|
||||
let novaRevisao = 1;
|
||||
.maybeSingle();
|
||||
|
||||
if (existingCronograma) {
|
||||
// Atualizar cronograma existente
|
||||
novaRevisao = existingCronograma.revisao + 1;
|
||||
const novaRevisao = (existingCronograma.revisao || 1) + 1;
|
||||
|
||||
const { data: updatedCronograma, error: updateError } = await supabase
|
||||
.from('cronogramas_of')
|
||||
@@ -144,14 +171,16 @@ export const useCronogramas = () => {
|
||||
if (insertError) throw insertError;
|
||||
cronogramaId = newCronograma.id;
|
||||
}
|
||||
}
|
||||
|
||||
// Inserir novos processos
|
||||
const processosParaInserir = cronograma.processos.map(processo => ({
|
||||
if (cronograma.processos && cronograma.processos.length > 0) {
|
||||
const processosParaInserir = cronograma.processos.map((processo, idx) => ({
|
||||
cronograma_id: cronogramaId,
|
||||
nome_processo: processo.nome_processo,
|
||||
data_inicio: processo.data_inicio,
|
||||
data_fim: processo.data_fim,
|
||||
ordem: processo.ordem
|
||||
ordem: processo.ordem || idx + 1
|
||||
}));
|
||||
|
||||
const { error: processosError } = await supabase
|
||||
@@ -159,13 +188,15 @@ export const useCronogramas = () => {
|
||||
.insert(processosParaInserir);
|
||||
|
||||
if (processosError) throw processosError;
|
||||
}
|
||||
|
||||
toast.success('Cronograma salvo com sucesso!');
|
||||
loadCronogramas();
|
||||
await loadCronogramas();
|
||||
return true;
|
||||
} catch (error) {
|
||||
console.error('Erro ao salvar cronograma:', error);
|
||||
toast.error('Erro ao salvar cronograma');
|
||||
const errMsg = error instanceof Error ? error.message : 'Erro ao salvar cronograma';
|
||||
toast.error(errMsg);
|
||||
return false;
|
||||
}
|
||||
};
|
||||
@@ -180,7 +211,7 @@ export const useCronogramas = () => {
|
||||
if (error) throw error;
|
||||
|
||||
toast.success('Cronograma removido com sucesso!');
|
||||
loadCronogramas();
|
||||
await loadCronogramas();
|
||||
return true;
|
||||
} catch (error) {
|
||||
console.error('Erro ao deletar cronograma:', error);
|
||||
@@ -200,16 +231,15 @@ export const useCronogramas = () => {
|
||||
descritivo,
|
||||
peso_total
|
||||
),
|
||||
profiles!gestor_id (
|
||||
profiles!cronogramas_of_gestor_id_fkey (
|
||||
full_name,
|
||||
email
|
||||
)
|
||||
`)
|
||||
.eq('of_id', ofId)
|
||||
.single();
|
||||
|
||||
if (error && error.code !== 'PGRST116') throw error;
|
||||
.maybeSingle();
|
||||
|
||||
if (error) throw error;
|
||||
if (!cronograma) return null;
|
||||
|
||||
const { data: processos, error: processosError } = await supabase
|
||||
|
||||
@@ -68,6 +68,11 @@ const CronogramaOF = () => {
|
||||
setSelectedCronograma(null);
|
||||
};
|
||||
|
||||
const handleSaveSuccess = () => {
|
||||
loadCronogramas();
|
||||
setActiveTab('cronogramas');
|
||||
};
|
||||
|
||||
const handleCloseGanttChart = () => {
|
||||
setShowGanttChart(false);
|
||||
setCronogramaForGantt(null);
|
||||
@@ -285,6 +290,7 @@ const CronogramaOF = () => {
|
||||
cronograma={selectedCronograma}
|
||||
onClose={handleCloseCronogramaForm}
|
||||
isOpen={showCronogramaForm}
|
||||
onSaveSuccess={handleSaveSuccess}
|
||||
/>
|
||||
)}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user