Primeiro commit

This commit is contained in:
2025-10-14 14:04:17 -03:00
commit 33d8645eb4
109 changed files with 55424 additions and 0 deletions

View File

@@ -0,0 +1,15 @@
-- =====================================================
-- ADICIONAR CAMPO DESCRIÇÃO NA TABELA PRODUTOS
-- =====================================================
-- Adicionar campo descrição na tabela produtos
ALTER TABLE produtos ADD COLUMN IF NOT EXISTS descricao TEXT;
-- Comentário para documentar o campo
COMMENT ON COLUMN produtos.descricao IS 'Descrição detalhada do produto, pode ser gerada automaticamente via ChatGPT';
-- Verificar se o campo foi adicionado
SELECT column_name, data_type, is_nullable
FROM information_schema.columns
WHERE table_name = 'produtos'
AND column_name = 'descricao';

View File

@@ -0,0 +1,22 @@
-- Adicionar coluna id_cliente na tabela clientes (numérico)
ALTER TABLE clientes ADD COLUMN IF NOT EXISTS id_cliente VARCHAR(10);
-- Criar índice para melhor performance
CREATE INDEX IF NOT EXISTS idx_clientes_id_cliente ON clientes(id_cliente);
-- Gerar IDs numéricos sequenciais para clientes existentes (se houver)
WITH numbered_clients AS (
SELECT id, ROW_NUMBER() OVER (ORDER BY created_at) as row_num
FROM clientes
WHERE id_cliente IS NULL
)
UPDATE clientes
SET id_cliente = numbered_clients.row_num::TEXT
FROM numbered_clients
WHERE clientes.id = numbered_clients.id;
-- Tornar a coluna NOT NULL após popular os dados existentes
ALTER TABLE clientes ALTER COLUMN id_cliente SET NOT NULL;
-- Adicionar constraint de unicidade
ALTER TABLE clientes ADD CONSTRAINT unique_id_cliente UNIQUE (id_cliente);

View File

@@ -0,0 +1,13 @@
-- Adicionar coluna id_venda na tabela vendas
ALTER TABLE vendas ADD COLUMN IF NOT EXISTS id_venda VARCHAR(20);
-- Adicionar coluna data_primeiro_vencimento na tabela vendas
ALTER TABLE vendas ADD COLUMN IF NOT EXISTS data_primeiro_vencimento DATE;
-- Criar índice para busca rápida por ID da venda
CREATE INDEX IF NOT EXISTS idx_vendas_id_venda ON vendas(id_venda);
-- Atualizar vendas existentes com ID gerado (usando created_at se existir)
UPDATE vendas
SET id_venda = 'VD' || TO_CHAR(COALESCE(created_at, NOW()), 'YYYYMMDDHH24MISS')
WHERE id_venda IS NULL;

17
sql/add-pix-fields.sql Normal file
View File

@@ -0,0 +1,17 @@
-- Adicionar campos PIX na tabela vendas
ALTER TABLE vendas ADD COLUMN IF NOT EXISTS status_pagamento VARCHAR(20) DEFAULT 'pendente';
ALTER TABLE vendas ADD COLUMN IF NOT EXISTS data_pagamento TIMESTAMP;
ALTER TABLE vendas ADD COLUMN IF NOT EXISTS pix_payment_id VARCHAR(100);
ALTER TABLE vendas ADD COLUMN IF NOT EXISTS pix_qr_code TEXT;
ALTER TABLE vendas ADD COLUMN IF NOT EXISTS metodo_pagamento VARCHAR(20) DEFAULT 'dinheiro';
-- Criar índices para performance
CREATE INDEX IF NOT EXISTS idx_vendas_status_pagamento ON vendas(status_pagamento);
CREATE INDEX IF NOT EXISTS idx_vendas_pix_payment_id ON vendas(pix_payment_id);
-- Comentários para documentação
COMMENT ON COLUMN vendas.status_pagamento IS 'Status do pagamento: pendente, pago, cancelado, expirado';
COMMENT ON COLUMN vendas.data_pagamento IS 'Data e hora da confirmação do pagamento';
COMMENT ON COLUMN vendas.pix_payment_id IS 'ID do pagamento no Mercado Pago';
COMMENT ON COLUMN vendas.pix_qr_code IS 'Código PIX para copiar e colar';
COMMENT ON COLUMN vendas.metodo_pagamento IS 'Método: dinheiro, cartao, pix, transferencia';

View File

@@ -0,0 +1,11 @@
-- Adicionar coluna valor_custo na tabela produtos para controle de custos
ALTER TABLE produtos ADD COLUMN IF NOT EXISTS valor_custo DECIMAL(10,2) DEFAULT 0;
-- Comentário para documentação
COMMENT ON COLUMN produtos.valor_custo IS 'Valor de custo do produto para cálculo de lucro real';
-- Atualizar produtos existentes com valor de custo baseado no valor de compra (se existir)
-- Se não existir valor_compra, usar 60% do valor_revenda como estimativa
UPDATE produtos
SET valor_custo = COALESCE(valor_compra, valor_revenda * 0.6)
WHERE valor_custo = 0 OR valor_custo IS NULL;

View File

@@ -0,0 +1,37 @@
-- =====================================================
-- ALTERAÇÃO DA TABELA DESPESAS PARA CAMPOS LIVRES
-- =====================================================
-- Adicionar novos campos de texto livre
ALTER TABLE despesas ADD COLUMN IF NOT EXISTS tipo_nome TEXT;
ALTER TABLE despesas ADD COLUMN IF NOT EXISTS fornecedor_nome TEXT;
-- Migrar dados existentes (se houver)
UPDATE despesas
SET tipo_nome = (
SELECT nome FROM tipos_despesas
WHERE tipos_despesas.id = despesas.tipo_despesa_id
)
WHERE tipo_despesa_id IS NOT NULL AND tipo_nome IS NULL;
UPDATE despesas
SET fornecedor_nome = (
SELECT razao_social FROM fornecedores
WHERE fornecedores.id = despesas.fornecedor_id
)
WHERE fornecedor_id IS NOT NULL AND fornecedor_nome IS NULL;
-- Remover as constraints das chaves estrangeiras (se existirem)
ALTER TABLE despesas DROP CONSTRAINT IF EXISTS despesas_tipo_despesa_id_fkey;
ALTER TABLE despesas DROP CONSTRAINT IF EXISTS despesas_fornecedor_id_fkey;
-- Tornar os campos antigos opcionais (para compatibilidade)
ALTER TABLE despesas ALTER COLUMN tipo_despesa_id DROP NOT NULL;
-- Criar índice nos novos campos para performance
CREATE INDEX IF NOT EXISTS idx_despesas_tipo_nome ON despesas(tipo_nome);
CREATE INDEX IF NOT EXISTS idx_despesas_fornecedor_nome ON despesas(fornecedor_nome);
-- Comentários para documentação
COMMENT ON COLUMN despesas.tipo_nome IS 'Nome do tipo de despesa (campo livre)';
COMMENT ON COLUMN despesas.fornecedor_nome IS 'Nome do fornecedor (campo livre)';

View File

@@ -0,0 +1,27 @@
-- Criar tabela de devoluções e trocas
CREATE TABLE IF NOT EXISTS devolucoes (
id UUID DEFAULT gen_random_uuid() PRIMARY KEY,
venda_id UUID NOT NULL REFERENCES vendas(id) ON DELETE CASCADE,
item_id UUID NOT NULL REFERENCES venda_itens(id) ON DELETE CASCADE,
quantidade_devolvida INTEGER NOT NULL CHECK (quantidade_devolvida > 0),
valor_devolucao DECIMAL(10,2) NOT NULL CHECK (valor_devolucao >= 0),
tipo_operacao VARCHAR(20) DEFAULT 'devolucao' CHECK (tipo_operacao IN ('devolucao', 'troca')),
motivo TEXT,
data_devolucao DATE NOT NULL DEFAULT CURRENT_DATE,
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
);
-- Criar índices para performance
CREATE INDEX IF NOT EXISTS idx_devolucoes_venda_id ON devolucoes(venda_id);
CREATE INDEX IF NOT EXISTS idx_devolucoes_item_id ON devolucoes(item_id);
CREATE INDEX IF NOT EXISTS idx_devolucoes_data ON devolucoes(data_devolucao);
-- Comentários para documentação
COMMENT ON TABLE devolucoes IS 'Registro de devoluções de produtos vendidos';
COMMENT ON COLUMN devolucoes.venda_id IS 'ID da venda original';
COMMENT ON COLUMN devolucoes.item_id IS 'ID do item da venda que foi devolvido';
COMMENT ON COLUMN devolucoes.quantidade_devolvida IS 'Quantidade de itens devolvidos';
COMMENT ON COLUMN devolucoes.valor_devolucao IS 'Valor total da devolução';
COMMENT ON COLUMN devolucoes.motivo IS 'Motivo da devolução';
COMMENT ON COLUMN devolucoes.data_devolucao IS 'Data em que a devolução foi processada';

View File

@@ -0,0 +1,38 @@
-- Criar tabela para histórico de mensagens WhatsApp
CREATE TABLE IF NOT EXISTS mensagens_whatsapp (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
telefone_cliente VARCHAR(20) NOT NULL,
cliente_nome VARCHAR(255),
mensagem TEXT NOT NULL,
tipo VARCHAR(20) NOT NULL CHECK (tipo IN ('enviada', 'recebida')),
status VARCHAR(20) DEFAULT 'enviada' CHECK (status IN ('enviando', 'enviada', 'entregue', 'lida', 'erro')),
evolution_message_id VARCHAR(255),
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
);
-- Índices para performance
CREATE INDEX IF NOT EXISTS idx_mensagens_telefone ON mensagens_whatsapp(telefone_cliente);
CREATE INDEX IF NOT EXISTS idx_mensagens_created_at ON mensagens_whatsapp(created_at);
CREATE INDEX IF NOT EXISTS idx_mensagens_tipo ON mensagens_whatsapp(tipo);
-- Trigger para atualizar updated_at
CREATE OR REPLACE FUNCTION update_mensagens_whatsapp_updated_at()
RETURNS TRIGGER AS $$
BEGIN
NEW.updated_at = NOW();
RETURN NEW;
END;
$$ language 'plpgsql';
CREATE TRIGGER update_mensagens_whatsapp_updated_at
BEFORE UPDATE ON mensagens_whatsapp
FOR EACH ROW
EXECUTE FUNCTION update_mensagens_whatsapp_updated_at();
-- Comentários para documentação
COMMENT ON TABLE mensagens_whatsapp IS 'Histórico de mensagens WhatsApp enviadas e recebidas';
COMMENT ON COLUMN mensagens_whatsapp.telefone_cliente IS 'Número do telefone do cliente (apenas números)';
COMMENT ON COLUMN mensagens_whatsapp.tipo IS 'Tipo da mensagem: enviada (pelo sistema) ou recebida (do cliente)';
COMMENT ON COLUMN mensagens_whatsapp.status IS 'Status da mensagem: enviando, enviada, entregue, lida, erro';
COMMENT ON COLUMN mensagens_whatsapp.evolution_message_id IS 'ID da mensagem na Evolution API para tracking';

View File

@@ -0,0 +1,56 @@
-- =====================================================
-- SCRIPT DE CRIAÇÃO DAS TABELAS - LIBERI KIDS ESTOQUE
-- VERSÃO SEGURA (SEM CONFLITOS)
-- =====================================================
-- 9. TABELA DE CONFIGURAÇÕES (NOVA)
CREATE TABLE IF NOT EXISTS configuracoes (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
tipo TEXT NOT NULL UNIQUE,
configuracao JSONB NOT NULL,
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
);
-- =====================================================
-- ÍNDICES PARA A NOVA TABELA
-- =====================================================
CREATE INDEX IF NOT EXISTS idx_configuracoes_tipo ON configuracoes(tipo);
-- =====================================================
-- TRIGGER PARA UPDATED_AT (APENAS PARA NOVA TABELA)
-- =====================================================
-- Criar trigger apenas se não existir
DO $$
BEGIN
IF NOT EXISTS (
SELECT 1 FROM pg_trigger
WHERE tgname = 'update_configuracoes_updated_at'
) THEN
CREATE TRIGGER update_configuracoes_updated_at
BEFORE UPDATE ON configuracoes
FOR EACH ROW EXECUTE FUNCTION update_updated_at_column();
END IF;
END $$;
-- =====================================================
-- RLS PARA A NOVA TABELA
-- =====================================================
-- Habilitar RLS
ALTER TABLE configuracoes ENABLE ROW LEVEL SECURITY;
-- Criar política apenas se não existir
DO $$
BEGIN
IF NOT EXISTS (
SELECT 1 FROM pg_policies
WHERE tablename = 'configuracoes'
AND policyname = 'Enable all operations for authenticated users'
) THEN
CREATE POLICY "Enable all operations for authenticated users"
ON configuracoes FOR ALL USING (true);
END IF;
END $$;

190
sql/create-tables.sql Normal file
View File

@@ -0,0 +1,190 @@
-- =====================================================
-- SCRIPT DE CRIAÇÃO DAS TABELAS - LIBERI KIDS ESTOQUE
-- =====================================================
-- 1. TABELA DE FORNECEDORES
CREATE TABLE IF NOT EXISTS fornecedores (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
razao_social TEXT NOT NULL,
telefone TEXT,
whatsapp TEXT,
endereco TEXT,
email TEXT,
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
);
-- 2. TABELA DE PRODUTOS
CREATE TABLE IF NOT EXISTS produtos (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
id_produto TEXT,
marca TEXT NOT NULL,
nome TEXT NOT NULL,
estacao TEXT NOT NULL,
genero TEXT DEFAULT 'Unissex',
fornecedor_id UUID REFERENCES fornecedores(id),
valor_compra DECIMAL(10,2) NOT NULL,
valor_revenda DECIMAL(10,2) NOT NULL,
foto_principal_url TEXT,
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
);
-- 3. TABELA DE VARIAÇÕES DE PRODUTOS
CREATE TABLE IF NOT EXISTS produto_variacoes (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
produto_id UUID NOT NULL REFERENCES produtos(id) ON DELETE CASCADE,
tamanho TEXT NOT NULL,
cor TEXT NOT NULL,
quantidade INTEGER NOT NULL DEFAULT 0,
foto_url TEXT,
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
);
-- 4. TABELA DE CLIENTES
CREATE TABLE IF NOT EXISTS clientes (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
nome_completo TEXT NOT NULL,
email TEXT,
telefone TEXT,
whatsapp TEXT,
endereco TEXT,
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
);
-- 5. TABELA DE TIPOS DE DESPESAS
CREATE TABLE IF NOT EXISTS tipos_despesas (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
nome TEXT NOT NULL UNIQUE,
descricao TEXT,
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
);
-- 6. TABELA DE DESPESAS
CREATE TABLE IF NOT EXISTS despesas (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
tipo_despesa_id UUID NOT NULL REFERENCES tipos_despesas(id),
fornecedor_id UUID REFERENCES fornecedores(id),
data_despesa DATE NOT NULL,
valor DECIMAL(10,2) NOT NULL,
descricao TEXT,
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
);
-- 7. TABELA DE VENDAS
CREATE TABLE IF NOT EXISTS vendas (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
cliente_id UUID REFERENCES clientes(id),
tipo_pagamento TEXT NOT NULL CHECK (tipo_pagamento IN ('vista', 'parcelado')),
valor_total DECIMAL(10,2) NOT NULL,
desconto DECIMAL(10,2) DEFAULT 0,
parcelas INTEGER DEFAULT 1,
valor_parcela DECIMAL(10,2) DEFAULT 0,
data_venda DATE NOT NULL,
observacoes TEXT,
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
);
-- 8. TABELA DE ITENS DE VENDA
CREATE TABLE IF NOT EXISTS venda_itens (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
venda_id UUID NOT NULL REFERENCES vendas(id) ON DELETE CASCADE,
produto_id UUID NOT NULL REFERENCES produtos(id),
variacao_id UUID REFERENCES produto_variacoes(id),
quantidade INTEGER NOT NULL,
valor_unitario DECIMAL(10,2) NOT NULL,
valor_total DECIMAL(10,2) NOT NULL,
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
);
-- 9. TABELA DE CONFIGURAÇÕES
CREATE TABLE IF NOT EXISTS configuracoes (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
tipo TEXT NOT NULL UNIQUE,
configuracao JSONB NOT NULL,
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
);
-- =====================================================
-- ÍNDICES PARA PERFORMANCE
-- =====================================================
CREATE INDEX IF NOT EXISTS idx_produtos_fornecedor ON produtos(fornecedor_id);
CREATE INDEX IF NOT EXISTS idx_produto_variacoes_produto ON produto_variacoes(produto_id);
CREATE INDEX IF NOT EXISTS idx_despesas_tipo ON despesas(tipo_despesa_id);
CREATE INDEX IF NOT EXISTS idx_despesas_fornecedor ON despesas(fornecedor_id);
CREATE INDEX IF NOT EXISTS idx_despesas_data ON despesas(data_despesa);
CREATE INDEX IF NOT EXISTS idx_vendas_cliente ON vendas(cliente_id);
CREATE INDEX IF NOT EXISTS idx_vendas_data ON vendas(data_venda);
CREATE INDEX IF NOT EXISTS idx_venda_itens_venda ON venda_itens(venda_id);
CREATE INDEX IF NOT EXISTS idx_venda_itens_produto ON venda_itens(produto_id);
CREATE INDEX IF NOT EXISTS idx_configuracoes_tipo ON configuracoes(tipo);
-- =====================================================
-- TRIGGERS PARA UPDATED_AT
-- =====================================================
-- Função para atualizar updated_at
CREATE OR REPLACE FUNCTION update_updated_at_column()
RETURNS TRIGGER AS $$
BEGIN
NEW.updated_at = NOW();
RETURN NEW;
END;
$$ language 'plpgsql';
-- Triggers para as tabelas
CREATE TRIGGER update_fornecedores_updated_at BEFORE UPDATE ON fornecedores FOR EACH ROW EXECUTE FUNCTION update_updated_at_column();
CREATE TRIGGER update_produtos_updated_at BEFORE UPDATE ON produtos FOR EACH ROW EXECUTE FUNCTION update_updated_at_column();
CREATE TRIGGER update_produto_variacoes_updated_at BEFORE UPDATE ON produto_variacoes FOR EACH ROW EXECUTE FUNCTION update_updated_at_column();
CREATE TRIGGER update_clientes_updated_at BEFORE UPDATE ON clientes FOR EACH ROW EXECUTE FUNCTION update_updated_at_column();
CREATE TRIGGER update_despesas_updated_at BEFORE UPDATE ON despesas FOR EACH ROW EXECUTE FUNCTION update_updated_at_column();
CREATE TRIGGER update_vendas_updated_at BEFORE UPDATE ON vendas FOR EACH ROW EXECUTE FUNCTION update_updated_at_column();
CREATE TRIGGER update_configuracoes_updated_at BEFORE UPDATE ON configuracoes FOR EACH ROW EXECUTE FUNCTION update_updated_at_column();
-- =====================================================
-- DADOS INICIAIS
-- =====================================================
-- Inserir tipos de despesas padrão
INSERT INTO tipos_despesas (nome, descricao) VALUES
('Aluguel', 'Despesas com aluguel do estabelecimento'),
('Energia Elétrica', 'Conta de luz'),
('Água', 'Conta de água'),
('Internet', 'Serviços de internet e telefone'),
('Marketing', 'Despesas com publicidade e marketing'),
('Transporte', 'Combustível, manutenção de veículos'),
('Materiais', 'Materiais de escritório e loja'),
('Outros', 'Outras despesas diversas')
ON CONFLICT (nome) DO NOTHING;
-- =====================================================
-- POLÍTICAS RLS (Row Level Security)
-- =====================================================
-- Habilitar RLS nas tabelas
ALTER TABLE fornecedores ENABLE ROW LEVEL SECURITY;
ALTER TABLE produtos ENABLE ROW LEVEL SECURITY;
ALTER TABLE produto_variacoes ENABLE ROW LEVEL SECURITY;
ALTER TABLE clientes ENABLE ROW LEVEL SECURITY;
ALTER TABLE tipos_despesas ENABLE ROW LEVEL SECURITY;
ALTER TABLE despesas ENABLE ROW LEVEL SECURITY;
ALTER TABLE vendas ENABLE ROW LEVEL SECURITY;
ALTER TABLE venda_itens ENABLE ROW LEVEL SECURITY;
ALTER TABLE configuracoes ENABLE ROW LEVEL SECURITY;
-- Políticas para permitir todas as operações (ajuste conforme necessário)
CREATE POLICY "Enable all operations for authenticated users" ON fornecedores FOR ALL USING (true);
CREATE POLICY "Enable all operations for authenticated users" ON produtos FOR ALL USING (true);
CREATE POLICY "Enable all operations for authenticated users" ON produto_variacoes FOR ALL USING (true);
CREATE POLICY "Enable all operations for authenticated users" ON clientes FOR ALL USING (true);
CREATE POLICY "Enable all operations for authenticated users" ON tipos_despesas FOR ALL USING (true);
CREATE POLICY "Enable all operations for authenticated users" ON despesas FOR ALL USING (true);
CREATE POLICY "Enable all operations for authenticated users" ON vendas FOR ALL USING (true);
CREATE POLICY "Enable all operations for authenticated users" ON venda_itens FOR ALL USING (true);
CREATE POLICY "Enable all operations for authenticated users" ON configuracoes FOR ALL USING (true);

102
sql/emprestimos-tables.sql Normal file
View File

@@ -0,0 +1,102 @@
-- =====================================================
-- TABELAS PARA SISTEMA DE EMPRÉSTIMOS
-- =====================================================
-- 1. TABELA DE EMPRÉSTIMOS
CREATE TABLE IF NOT EXISTS emprestimos (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
pessoa VARCHAR(100) NOT NULL DEFAULT 'Maiara',
valor_total DECIMAL(10,2) NOT NULL,
valor_restante DECIMAL(10,2) NOT NULL,
descricao TEXT,
data_emprestimo DATE NOT NULL DEFAULT CURRENT_DATE,
status VARCHAR(20) NOT NULL DEFAULT 'ativo' CHECK (status IN ('ativo', 'quitado', 'cancelado')),
created_at TIMESTAMP DEFAULT NOW(),
updated_at TIMESTAMP DEFAULT NOW()
);
-- 2. TABELA DE DEVOLUÇÕES/PARCELAS
CREATE TABLE IF NOT EXISTS emprestimo_devolucoes (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
emprestimo_id UUID NOT NULL REFERENCES emprestimos(id) ON DELETE CASCADE,
valor_devolvido DECIMAL(10,2) NOT NULL,
data_devolucao DATE NOT NULL DEFAULT CURRENT_DATE,
observacoes TEXT,
created_at TIMESTAMP DEFAULT NOW(),
updated_at TIMESTAMP DEFAULT NOW()
);
-- =====================================================
-- ÍNDICES
-- =====================================================
CREATE INDEX IF NOT EXISTS idx_emprestimos_pessoa ON emprestimos(pessoa);
CREATE INDEX IF NOT EXISTS idx_emprestimos_status ON emprestimos(status);
CREATE INDEX IF NOT EXISTS idx_emprestimos_data ON emprestimos(data_emprestimo);
CREATE INDEX IF NOT EXISTS idx_devolucoes_emprestimo ON emprestimo_devolucoes(emprestimo_id);
CREATE INDEX IF NOT EXISTS idx_devolucoes_data ON emprestimo_devolucoes(data_devolucao);
-- =====================================================
-- TRIGGERS PARA UPDATED_AT
-- =====================================================
CREATE TRIGGER update_emprestimos_updated_at
BEFORE UPDATE ON emprestimos
FOR EACH ROW EXECUTE FUNCTION update_updated_at_column();
CREATE TRIGGER update_emprestimo_devolucoes_updated_at
BEFORE UPDATE ON emprestimo_devolucoes
FOR EACH ROW EXECUTE FUNCTION update_updated_at_column();
-- =====================================================
-- FUNÇÃO PARA ATUALIZAR VALOR RESTANTE
-- =====================================================
CREATE OR REPLACE FUNCTION atualizar_valor_restante_emprestimo()
RETURNS TRIGGER AS $$
BEGIN
-- Atualizar valor restante do empréstimo
UPDATE emprestimos
SET valor_restante = valor_total - (
SELECT COALESCE(SUM(valor_devolvido), 0)
FROM emprestimo_devolucoes
WHERE emprestimo_id = NEW.emprestimo_id
),
status = CASE
WHEN (valor_total - (
SELECT COALESCE(SUM(valor_devolvido), 0)
FROM emprestimo_devolucoes
WHERE emprestimo_id = NEW.emprestimo_id
)) <= 0 THEN 'quitado'
ELSE 'ativo'
END,
updated_at = NOW()
WHERE id = NEW.emprestimo_id;
RETURN NEW;
END;
$$ LANGUAGE plpgsql;
-- Trigger para atualizar automaticamente quando há devolução
CREATE TRIGGER trigger_atualizar_valor_restante
AFTER INSERT OR UPDATE OR DELETE ON emprestimo_devolucoes
FOR EACH ROW EXECUTE FUNCTION atualizar_valor_restante_emprestimo();
-- =====================================================
-- POLÍTICAS RLS (ROW LEVEL SECURITY)
-- =====================================================
ALTER TABLE emprestimos ENABLE ROW LEVEL SECURITY;
ALTER TABLE emprestimo_devolucoes ENABLE ROW LEVEL SECURITY;
-- Políticas para permitir todas as operações (ajuste conforme necessário)
CREATE POLICY "Enable all operations for authenticated users" ON emprestimos FOR ALL USING (true);
CREATE POLICY "Enable all operations for authenticated users" ON emprestimo_devolucoes FOR ALL USING (true);
-- =====================================================
-- DADOS INICIAIS (OPCIONAL)
-- =====================================================
-- Exemplo de empréstimo inicial (remover se não quiser)
-- INSERT INTO emprestimos (pessoa, valor_total, valor_restante, descricao, data_emprestimo)
-- VALUES ('Maiara', 500.00, 500.00, 'Empréstimo inicial para teste', CURRENT_DATE);

16
sql/functions.sql Normal file
View File

@@ -0,0 +1,16 @@
-- =====================================================
-- FUNÇÕES SQL PARA O SISTEMA LIBERI KIDS
-- =====================================================
-- Função para atualizar estoque após venda
CREATE OR REPLACE FUNCTION update_estoque_variacao(
variacao_id UUID,
quantidade_vendida INTEGER
)
RETURNS VOID AS $$
BEGIN
UPDATE produto_variacoes
SET quantidade = GREATEST(0, quantidade - quantidade_vendida)
WHERE id = variacao_id;
END;
$$ LANGUAGE plpgsql;