119 lines
4.6 KiB
PL/PgSQL
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();
|