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;
|
cronograma?: CronogramaOf | null;
|
||||||
onClose: () => void;
|
onClose: () => void;
|
||||||
isOpen: boolean;
|
isOpen: boolean;
|
||||||
|
onSaveSuccess?: () => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
const processosDefault = [
|
const processosDefault = [
|
||||||
@@ -30,7 +31,7 @@ const processosDefault = [
|
|||||||
'Aceite/DB'
|
'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 { saveCronograma, getCronogramaPorOf } = useCronogramaOperations();
|
||||||
const [formData, setFormData] = useState({
|
const [formData, setFormData] = useState({
|
||||||
of_id: '',
|
of_id: '',
|
||||||
@@ -228,6 +229,9 @@ export const CronogramaForm: React.FC<CronogramaFormProps> = ({ cronograma, onCl
|
|||||||
setLoading(false);
|
setLoading(false);
|
||||||
|
|
||||||
if (success) {
|
if (success) {
|
||||||
|
if (onSaveSuccess) {
|
||||||
|
onSaveSuccess();
|
||||||
|
}
|
||||||
onClose();
|
onClose();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,249 +1 @@
|
|||||||
|
export { useCronogramas as useCronogramaOperations } from './useCronogramas';
|
||||||
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
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|||||||
@@ -47,7 +47,7 @@ export const useCronogramas = () => {
|
|||||||
descritivo,
|
descritivo,
|
||||||
peso_total
|
peso_total
|
||||||
),
|
),
|
||||||
profiles!gestor_id (
|
profiles!cronogramas_of_gestor_id_fkey (
|
||||||
full_name,
|
full_name,
|
||||||
email
|
email
|
||||||
)
|
)
|
||||||
@@ -89,23 +89,50 @@ export const useCronogramas = () => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const saveCronograma = async (cronograma: Omit<CronogramaOf, 'id'>) => {
|
const saveCronograma = async (cronograma: Partial<CronogramaOf> & { processos: ProcessoCronograma[] }) => {
|
||||||
try {
|
try {
|
||||||
if (!user) throw new Error('Usuário não autenticado');
|
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
|
const { data: existingCronograma } = await supabase
|
||||||
.from('cronogramas_of')
|
.from('cronogramas_of')
|
||||||
.select('id, revisao')
|
.select('id, revisao')
|
||||||
.eq('of_id', cronograma.of_id)
|
.eq('of_id', cronograma.of_id)
|
||||||
.single();
|
.maybeSingle();
|
||||||
|
|
||||||
let cronogramaId: string;
|
|
||||||
let novaRevisao = 1;
|
|
||||||
|
|
||||||
if (existingCronograma) {
|
if (existingCronograma) {
|
||||||
// Atualizar cronograma existente
|
// Atualizar cronograma existente
|
||||||
novaRevisao = existingCronograma.revisao + 1;
|
const novaRevisao = (existingCronograma.revisao || 1) + 1;
|
||||||
|
|
||||||
const { data: updatedCronograma, error: updateError } = await supabase
|
const { data: updatedCronograma, error: updateError } = await supabase
|
||||||
.from('cronogramas_of')
|
.from('cronogramas_of')
|
||||||
@@ -144,14 +171,16 @@ export const useCronogramas = () => {
|
|||||||
if (insertError) throw insertError;
|
if (insertError) throw insertError;
|
||||||
cronogramaId = newCronograma.id;
|
cronogramaId = newCronograma.id;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Inserir novos processos
|
// 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,
|
cronograma_id: cronogramaId,
|
||||||
nome_processo: processo.nome_processo,
|
nome_processo: processo.nome_processo,
|
||||||
data_inicio: processo.data_inicio,
|
data_inicio: processo.data_inicio,
|
||||||
data_fim: processo.data_fim,
|
data_fim: processo.data_fim,
|
||||||
ordem: processo.ordem
|
ordem: processo.ordem || idx + 1
|
||||||
}));
|
}));
|
||||||
|
|
||||||
const { error: processosError } = await supabase
|
const { error: processosError } = await supabase
|
||||||
@@ -159,13 +188,15 @@ export const useCronogramas = () => {
|
|||||||
.insert(processosParaInserir);
|
.insert(processosParaInserir);
|
||||||
|
|
||||||
if (processosError) throw processosError;
|
if (processosError) throw processosError;
|
||||||
|
}
|
||||||
|
|
||||||
toast.success('Cronograma salvo com sucesso!');
|
toast.success('Cronograma salvo com sucesso!');
|
||||||
loadCronogramas();
|
await loadCronogramas();
|
||||||
return true;
|
return true;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Erro ao salvar cronograma:', 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;
|
return false;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -180,7 +211,7 @@ export const useCronogramas = () => {
|
|||||||
if (error) throw error;
|
if (error) throw error;
|
||||||
|
|
||||||
toast.success('Cronograma removido com sucesso!');
|
toast.success('Cronograma removido com sucesso!');
|
||||||
loadCronogramas();
|
await loadCronogramas();
|
||||||
return true;
|
return true;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Erro ao deletar cronograma:', error);
|
console.error('Erro ao deletar cronograma:', error);
|
||||||
@@ -200,16 +231,15 @@ export const useCronogramas = () => {
|
|||||||
descritivo,
|
descritivo,
|
||||||
peso_total
|
peso_total
|
||||||
),
|
),
|
||||||
profiles!gestor_id (
|
profiles!cronogramas_of_gestor_id_fkey (
|
||||||
full_name,
|
full_name,
|
||||||
email
|
email
|
||||||
)
|
)
|
||||||
`)
|
`)
|
||||||
.eq('of_id', ofId)
|
.eq('of_id', ofId)
|
||||||
.single();
|
.maybeSingle();
|
||||||
|
|
||||||
if (error && error.code !== 'PGRST116') throw error;
|
|
||||||
|
|
||||||
|
if (error) throw error;
|
||||||
if (!cronograma) return null;
|
if (!cronograma) return null;
|
||||||
|
|
||||||
const { data: processos, error: processosError } = await supabase
|
const { data: processos, error: processosError } = await supabase
|
||||||
|
|||||||
@@ -68,6 +68,11 @@ const CronogramaOF = () => {
|
|||||||
setSelectedCronograma(null);
|
setSelectedCronograma(null);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const handleSaveSuccess = () => {
|
||||||
|
loadCronogramas();
|
||||||
|
setActiveTab('cronogramas');
|
||||||
|
};
|
||||||
|
|
||||||
const handleCloseGanttChart = () => {
|
const handleCloseGanttChart = () => {
|
||||||
setShowGanttChart(false);
|
setShowGanttChart(false);
|
||||||
setCronogramaForGantt(null);
|
setCronogramaForGantt(null);
|
||||||
@@ -285,6 +290,7 @@ const CronogramaOF = () => {
|
|||||||
cronograma={selectedCronograma}
|
cronograma={selectedCronograma}
|
||||||
onClose={handleCloseCronogramaForm}
|
onClose={handleCloseCronogramaForm}
|
||||||
isOpen={showCronogramaForm}
|
isOpen={showCronogramaForm}
|
||||||
|
onSaveSuccess={handleSaveSuccess}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user