123 lines
3.8 KiB
PL/PgSQL
123 lines
3.8 KiB
PL/PgSQL
|
|
-- Criar função para verificar disponibilidade de peças antes de inserir/atualizar itens de prioridade
|
|
CREATE OR REPLACE FUNCTION verificar_disponibilidade_peca(
|
|
p_peca_id uuid,
|
|
p_quantidade_adicional numeric,
|
|
p_item_id uuid DEFAULT NULL -- Para updates, excluir o próprio item do cálculo
|
|
)
|
|
RETURNS boolean
|
|
LANGUAGE plpgsql
|
|
SECURITY DEFINER
|
|
AS $$
|
|
DECLARE
|
|
quantidade_total_peca numeric;
|
|
quantidade_ja_priorizada numeric;
|
|
quantidade_disponivel numeric;
|
|
BEGIN
|
|
-- Buscar quantidade total da peça
|
|
SELECT quantidade INTO quantidade_total_peca
|
|
FROM pecas
|
|
WHERE id = p_peca_id;
|
|
|
|
IF quantidade_total_peca IS NULL THEN
|
|
RAISE EXCEPTION 'Peça não encontrada';
|
|
END IF;
|
|
|
|
-- Calcular quantidade já priorizada (excluindo o item atual se for update)
|
|
SELECT COALESCE(SUM(quantidade_priorizada), 0) INTO quantidade_ja_priorizada
|
|
FROM itens_prioridade_fabricacao
|
|
WHERE peca_id = p_peca_id
|
|
AND (p_item_id IS NULL OR id != p_item_id);
|
|
|
|
-- Calcular quantidade disponível
|
|
quantidade_disponivel := quantidade_total_peca - quantidade_ja_priorizada;
|
|
|
|
-- Verificar se a quantidade adicional não excede o disponível
|
|
IF p_quantidade_adicional > quantidade_disponivel THEN
|
|
RAISE EXCEPTION 'Quantidade solicitada (%) excede o disponível (%) para esta peça',
|
|
p_quantidade_adicional, quantidade_disponivel;
|
|
END IF;
|
|
|
|
RETURN true;
|
|
END;
|
|
$$;
|
|
|
|
-- Criar trigger para validar inserções
|
|
CREATE OR REPLACE FUNCTION trigger_validar_item_prioridade()
|
|
RETURNS trigger
|
|
LANGUAGE plpgsql
|
|
AS $$
|
|
BEGIN
|
|
-- Validar na inserção
|
|
IF TG_OP = 'INSERT' THEN
|
|
PERFORM verificar_disponibilidade_peca(NEW.peca_id, NEW.quantidade_priorizada);
|
|
RETURN NEW;
|
|
END IF;
|
|
|
|
-- Validar na atualização
|
|
IF TG_OP = 'UPDATE' THEN
|
|
PERFORM verificar_disponibilidade_peca(NEW.peca_id, NEW.quantidade_priorizada, NEW.id);
|
|
RETURN NEW;
|
|
END IF;
|
|
|
|
RETURN NULL;
|
|
END;
|
|
$$;
|
|
|
|
-- Aplicar o trigger na tabela
|
|
DROP TRIGGER IF EXISTS trigger_validar_disponibilidade_item_prioridade ON itens_prioridade_fabricacao;
|
|
CREATE TRIGGER trigger_validar_disponibilidade_item_prioridade
|
|
BEFORE INSERT OR UPDATE ON itens_prioridade_fabricacao
|
|
FOR EACH ROW
|
|
EXECUTE FUNCTION trigger_validar_item_prioridade();
|
|
|
|
-- Criar função otimizada para buscar peças disponíveis
|
|
CREATE OR REPLACE FUNCTION buscar_pecas_disponiveis_para_prioridade(
|
|
p_of_number text,
|
|
p_etapa_fase text
|
|
)
|
|
RETURNS TABLE(
|
|
id uuid,
|
|
marca text,
|
|
descricao text,
|
|
peso_unitario numeric,
|
|
quantidade numeric,
|
|
of_number text,
|
|
etapa_fase text,
|
|
quantidade_disponivel numeric,
|
|
user_id uuid,
|
|
created_at timestamp with time zone,
|
|
updated_at timestamp with time zone
|
|
)
|
|
LANGUAGE sql
|
|
SECURITY DEFINER
|
|
AS $$
|
|
WITH pecas_com_prioridades AS (
|
|
SELECT
|
|
p.*,
|
|
COALESCE(SUM(ipf.quantidade_priorizada), 0) as quantidade_total_priorizada
|
|
FROM pecas p
|
|
LEFT JOIN itens_prioridade_fabricacao ipf ON p.id = ipf.peca_id
|
|
LEFT JOIN prioridades_fabricacao pf ON ipf.prioridade_fabricacao_id = pf.id
|
|
WHERE p.of_number = p_of_number
|
|
AND p.etapa_fase = p_etapa_fase
|
|
GROUP BY p.id, p.marca, p.descricao, p.peso_unitario, p.quantidade,
|
|
p.of_number, p.etapa_fase, p.user_id, p.created_at, p.updated_at
|
|
)
|
|
SELECT
|
|
pcp.id,
|
|
pcp.marca,
|
|
pcp.descricao,
|
|
pcp.peso_unitario,
|
|
pcp.quantidade,
|
|
pcp.of_number,
|
|
pcp.etapa_fase,
|
|
(pcp.quantidade - pcp.quantidade_total_priorizada) as quantidade_disponivel,
|
|
pcp.user_id,
|
|
pcp.created_at,
|
|
pcp.updated_at
|
|
FROM pecas_com_prioridades pcp
|
|
WHERE (pcp.quantidade - pcp.quantidade_total_priorizada) > 0
|
|
ORDER BY pcp.marca ASC;
|
|
$$;
|