Files
tracksteel_app/supabase/migrations/20250705173428-b7d62162-4ff6-468e-8bd0-c267105e5cf9.sql

119 lines
4.6 KiB
PL/PgSQL

-- Primeiro, vamos alterar a tabela estoque_materiais para garantir que o lote seja obrigatório e único por material
ALTER TABLE estoque_materiais
ALTER COLUMN lote_atual SET NOT NULL,
ADD CONSTRAINT unique_material_lote UNIQUE (descricao, lote_atual);
-- Criar índice para melhor performance nas consultas por lote
CREATE INDEX idx_estoque_materiais_lote ON estoque_materiais(lote_atual);
-- Alterar a tabela movimentacoes_estoque para incluir o campo certificado
ALTER TABLE movimentacoes_estoque
ADD COLUMN certificado text,
ADD COLUMN user_name text;
-- Criar função para buscar o nome do usuário logado
CREATE OR REPLACE FUNCTION get_user_name(user_id uuid)
RETURNS text
LANGUAGE sql
STABLE
AS $$
SELECT COALESCE(full_name, email, 'Usuário não identificado')
FROM profiles
WHERE id = user_id;
$$;
-- Atualizar função de processamento de movimentação para incluir validações
CREATE OR REPLACE FUNCTION processar_movimentacao_estoque()
RETURNS trigger
LANGUAGE plpgsql
AS $function$
DECLARE
material_record estoque_materiais%ROWTYPE;
BEGIN
-- Buscar o material
SELECT * INTO material_record
FROM estoque_materiais
WHERE id = NEW.material_id;
IF NOT FOUND THEN
RAISE EXCEPTION 'Material não encontrado';
END IF;
-- Validar e processar cada tipo de movimentação
IF NEW.tipo_movimentacao = 'entrada' THEN
UPDATE estoque_materiais
SET quantidade_total = quantidade_total + NEW.quantidade,
quantidade_disponivel = quantidade_disponivel + NEW.quantidade
WHERE id = NEW.material_id;
ELSIF NEW.tipo_movimentacao = 'saida' THEN
-- Validar se há quantidade suficiente
IF material_record.quantidade_disponivel < NEW.quantidade THEN
RAISE EXCEPTION 'Quantidade insuficiente para saída. Disponível: %, Solicitado: %',
material_record.quantidade_disponivel, NEW.quantidade;
END IF;
UPDATE estoque_materiais
SET quantidade_total = quantidade_total - NEW.quantidade,
quantidade_disponivel = quantidade_disponivel - NEW.quantidade
WHERE id = NEW.material_id;
ELSIF NEW.tipo_movimentacao = 'ajuste' THEN
-- Para ajuste, definir a quantidade total como o valor informado
UPDATE estoque_materiais
SET quantidade_total = NEW.quantidade,
quantidade_disponivel = NEW.quantidade - quantidade_empenhada
WHERE id = NEW.material_id;
ELSIF NEW.tipo_movimentacao = 'empenho' THEN
-- Validar se há quantidade disponível suficiente
IF material_record.quantidade_disponivel < NEW.quantidade THEN
RAISE EXCEPTION 'Quantidade insuficiente para empenho. Disponível: %, Solicitado: %',
material_record.quantidade_disponivel, NEW.quantidade;
END IF;
-- Validar se OF foi informada
IF NEW.of_vinculada IS NULL OR NEW.of_vinculada = '' THEN
RAISE EXCEPTION 'OF vinculada é obrigatória para movimentações de empenho';
END IF;
UPDATE estoque_materiais
SET quantidade_disponivel = quantidade_disponivel - NEW.quantidade,
quantidade_empenhada = quantidade_empenhada + NEW.quantidade
WHERE id = NEW.material_id;
ELSIF NEW.tipo_movimentacao = 'desempenho' THEN
-- Validar se há quantidade empenhada suficiente
IF material_record.quantidade_empenhada < NEW.quantidade THEN
RAISE EXCEPTION 'Quantidade insuficiente para desempenho. Empenhado: %, Solicitado: %',
material_record.quantidade_empenhada, NEW.quantidade;
END IF;
-- Validar se OF foi informada
IF NEW.of_vinculada IS NULL OR NEW.of_vinculada = '' THEN
RAISE EXCEPTION 'OF vinculada é obrigatória para movimentações de desempenho';
END IF;
UPDATE estoque_materiais
SET quantidade_disponivel = quantidade_disponivel + NEW.quantidade,
quantidade_empenhada = quantidade_empenhada - NEW.quantidade
WHERE id = NEW.material_id;
ELSIF NEW.tipo_movimentacao = 'transferencia' THEN
-- Para transferência, apenas atualizamos a localização se informada
-- A quantidade permanece a mesma
NULL; -- Não altera quantidades na transferência
END IF;
RETURN NEW;
END;
$function$;
-- Garantir que o trigger existe
DROP TRIGGER IF EXISTS trigger_processar_movimentacao_estoque ON movimentacoes_estoque;
CREATE TRIGGER trigger_processar_movimentacao_estoque
AFTER INSERT ON movimentacoes_estoque
FOR EACH ROW
EXECUTE FUNCTION processar_movimentacao_estoque();