345 lines
15 KiB
PL/PgSQL
345 lines
15 KiB
PL/PgSQL
-- =============================================
|
|
-- CONFIGURAÇÃO COMPLETA DO SUPABASE
|
|
-- Sistema de Estoque Liberi Kids
|
|
-- =============================================
|
|
|
|
-- Habilitar extensões necessárias
|
|
CREATE EXTENSION IF NOT EXISTS "uuid-ossp";
|
|
|
|
-- =============================================
|
|
-- 1. TABELA DE CLIENTES
|
|
-- =============================================
|
|
CREATE TABLE IF NOT EXISTS clientes (
|
|
id UUID DEFAULT uuid_generate_v4() PRIMARY KEY,
|
|
nome_completo VARCHAR(255) NOT NULL,
|
|
email VARCHAR(255) UNIQUE,
|
|
whatsapp VARCHAR(20) NOT NULL UNIQUE, -- Login será por WhatsApp
|
|
telefone VARCHAR(20),
|
|
endereco TEXT,
|
|
cidade VARCHAR(100),
|
|
estado VARCHAR(50),
|
|
cep VARCHAR(10),
|
|
data_nascimento DATE,
|
|
observacoes TEXT,
|
|
ativo BOOLEAN DEFAULT true,
|
|
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
|
|
updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
|
|
);
|
|
|
|
-- =============================================
|
|
-- 2. TABELA DE FORNECEDORES
|
|
-- =============================================
|
|
CREATE TABLE IF NOT EXISTS fornecedores (
|
|
id UUID DEFAULT uuid_generate_v4() PRIMARY KEY,
|
|
nome VARCHAR(255) NOT NULL,
|
|
cnpj VARCHAR(18),
|
|
email VARCHAR(255),
|
|
telefone VARCHAR(20),
|
|
endereco TEXT,
|
|
cidade VARCHAR(100),
|
|
estado VARCHAR(50),
|
|
cep VARCHAR(10),
|
|
observacoes TEXT,
|
|
ativo BOOLEAN DEFAULT true,
|
|
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
|
|
updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
|
|
);
|
|
|
|
-- =============================================
|
|
-- 3. TABELA DE PRODUTOS
|
|
-- =============================================
|
|
CREATE TABLE IF NOT EXISTS produtos (
|
|
id UUID DEFAULT uuid_generate_v4() PRIMARY KEY,
|
|
id_produto VARCHAR(50) UNIQUE, -- Código do produto
|
|
marca VARCHAR(100) NOT NULL,
|
|
nome VARCHAR(255) NOT NULL,
|
|
descricao TEXT,
|
|
estacao VARCHAR(50) CHECK (estacao IN ('Verão', 'Inverno', 'Meia Estação')),
|
|
genero VARCHAR(20) CHECK (genero IN ('Masculino', 'Feminino', 'Unissex')),
|
|
fornecedor_id UUID REFERENCES fornecedores(id),
|
|
valor_compra DECIMAL(10,2),
|
|
valor_revenda DECIMAL(10,2),
|
|
foto_principal TEXT, -- URL da foto principal
|
|
ativo BOOLEAN DEFAULT true,
|
|
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
|
|
updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
|
|
);
|
|
|
|
-- =============================================
|
|
-- 4. TABELA DE VARIAÇÕES DE PRODUTOS
|
|
-- =============================================
|
|
CREATE TABLE IF NOT EXISTS produto_variacoes (
|
|
id UUID DEFAULT uuid_generate_v4() PRIMARY KEY,
|
|
produto_id UUID NOT NULL REFERENCES produtos(id) ON DELETE CASCADE,
|
|
tamanho VARCHAR(10) NOT NULL,
|
|
cor VARCHAR(50) NOT NULL,
|
|
quantidade INTEGER NOT NULL DEFAULT 0,
|
|
fotos TEXT[], -- Array de URLs das fotos
|
|
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
|
|
updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
|
|
UNIQUE(produto_id, tamanho, cor)
|
|
);
|
|
|
|
-- =============================================
|
|
-- 5. TABELA DE VENDAS
|
|
-- =============================================
|
|
CREATE TABLE IF NOT EXISTS vendas (
|
|
id UUID DEFAULT uuid_generate_v4() PRIMARY KEY,
|
|
id_venda VARCHAR(50) UNIQUE, -- Código da venda
|
|
cliente_id UUID REFERENCES clientes(id),
|
|
tipo_pagamento VARCHAR(20) CHECK (tipo_pagamento IN ('vista', 'parcelado', 'prazo')),
|
|
valor_total DECIMAL(10,2) NOT NULL,
|
|
desconto DECIMAL(10,2) DEFAULT 0,
|
|
parcelas INTEGER DEFAULT 1,
|
|
valor_parcela DECIMAL(10,2),
|
|
data_venda DATE NOT NULL,
|
|
data_primeiro_vencimento DATE,
|
|
observacoes TEXT,
|
|
status VARCHAR(20) DEFAULT 'concluida' CHECK (status IN ('concluida', 'cancelada', 'pendente')),
|
|
origem VARCHAR(20) DEFAULT 'loja' CHECK (origem IN ('loja', 'catalogo')), -- Nova coluna para origem
|
|
eh_troca_devolucao BOOLEAN DEFAULT false, -- Para identificar trocas/devoluções
|
|
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
|
|
updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
|
|
);
|
|
|
|
-- =============================================
|
|
-- 6. TABELA DE ITENS DA VENDA
|
|
-- =============================================
|
|
CREATE TABLE IF NOT EXISTS venda_itens (
|
|
id UUID DEFAULT uuid_generate_v4() PRIMARY KEY,
|
|
venda_id UUID NOT NULL REFERENCES vendas(id) ON DELETE CASCADE,
|
|
produto_id UUID NOT NULL REFERENCES produtos(id),
|
|
produto_variacao_id UUID NOT NULL REFERENCES produto_variacoes(id),
|
|
quantidade INTEGER NOT NULL,
|
|
valor_unitario DECIMAL(10,2) NOT NULL,
|
|
valor_total DECIMAL(10,2) NOT NULL,
|
|
status_item VARCHAR(20) DEFAULT 'vendido' CHECK (status_item IN ('vendido', 'trocado', 'devolvido')),
|
|
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
|
|
);
|
|
|
|
-- =============================================
|
|
-- 7. TABELA DE PARCELAS
|
|
-- =============================================
|
|
CREATE TABLE IF NOT EXISTS parcelas (
|
|
id UUID DEFAULT uuid_generate_v4() PRIMARY KEY,
|
|
venda_id UUID NOT NULL REFERENCES vendas(id) ON DELETE CASCADE,
|
|
numero_parcela INTEGER NOT NULL,
|
|
valor DECIMAL(10,2) NOT NULL,
|
|
data_vencimento DATE NOT NULL,
|
|
data_pagamento DATE,
|
|
status VARCHAR(20) DEFAULT 'pendente' CHECK (status IN ('pendente', 'paga', 'vencida')),
|
|
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
|
|
updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
|
|
);
|
|
|
|
-- =============================================
|
|
-- 8. TABELA DE DEVOLUÇÕES/TROCAS
|
|
-- =============================================
|
|
CREATE TABLE IF NOT EXISTS devolucoes (
|
|
id UUID DEFAULT uuid_generate_v4() 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()
|
|
);
|
|
|
|
-- =============================================
|
|
-- 9. TABELA DE DESPESAS
|
|
-- =============================================
|
|
CREATE TABLE IF NOT EXISTS despesas (
|
|
id UUID DEFAULT uuid_generate_v4() PRIMARY KEY,
|
|
tipo_despesa_id UUID REFERENCES tipos_despesa(id),
|
|
descricao VARCHAR(255) NOT NULL,
|
|
valor DECIMAL(10,2) NOT NULL,
|
|
data_despesa DATE NOT NULL,
|
|
observacoes TEXT,
|
|
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
|
|
updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
|
|
);
|
|
|
|
-- =============================================
|
|
-- 10. TABELA DE TIPOS DE DESPESA
|
|
-- =============================================
|
|
CREATE TABLE IF NOT EXISTS tipos_despesa (
|
|
id UUID DEFAULT uuid_generate_v4() PRIMARY KEY,
|
|
nome VARCHAR(100) NOT NULL UNIQUE,
|
|
descricao TEXT,
|
|
ativo BOOLEAN DEFAULT true,
|
|
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
|
|
updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
|
|
);
|
|
|
|
-- =============================================
|
|
-- 11. TABELA DE PEDIDOS DO CATÁLOGO
|
|
-- =============================================
|
|
CREATE TABLE IF NOT EXISTS pedidos_catalogo (
|
|
id UUID DEFAULT uuid_generate_v4() PRIMARY KEY,
|
|
cliente_id UUID NOT NULL REFERENCES clientes(id),
|
|
status VARCHAR(20) DEFAULT 'pendente' CHECK (status IN ('pendente', 'processando', 'concluido', 'cancelado')),
|
|
valor_total DECIMAL(10,2) NOT NULL,
|
|
observacoes TEXT,
|
|
data_pedido TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
|
|
data_processamento TIMESTAMP WITH TIME ZONE,
|
|
venda_id UUID REFERENCES vendas(id), -- Referência para a venda criada no app
|
|
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
|
|
updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
|
|
);
|
|
|
|
-- =============================================
|
|
-- 12. TABELA DE ITENS DO PEDIDO CATÁLOGO
|
|
-- =============================================
|
|
CREATE TABLE IF NOT EXISTS pedido_catalogo_itens (
|
|
id UUID DEFAULT uuid_generate_v4() PRIMARY KEY,
|
|
pedido_id UUID NOT NULL REFERENCES pedidos_catalogo(id) ON DELETE CASCADE,
|
|
produto_id UUID NOT NULL REFERENCES produtos(id),
|
|
produto_variacao_id UUID NOT NULL 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()
|
|
);
|
|
|
|
-- =============================================
|
|
-- 13. TABELA DE CONFIGURAÇÕES
|
|
-- =============================================
|
|
CREATE TABLE IF NOT EXISTS configuracoes (
|
|
id UUID DEFAULT uuid_generate_v4() PRIMARY KEY,
|
|
chave VARCHAR(100) NOT NULL UNIQUE,
|
|
valor TEXT,
|
|
tipo VARCHAR(50) DEFAULT 'string',
|
|
descricao TEXT,
|
|
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
|
|
updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
|
|
);
|
|
|
|
-- =============================================
|
|
-- ÍNDICES PARA PERFORMANCE
|
|
-- =============================================
|
|
|
|
-- Clientes
|
|
CREATE INDEX IF NOT EXISTS idx_clientes_whatsapp ON clientes(whatsapp);
|
|
CREATE INDEX IF NOT EXISTS idx_clientes_email ON clientes(email);
|
|
|
|
-- Produtos
|
|
CREATE INDEX IF NOT EXISTS idx_produtos_marca ON produtos(marca);
|
|
CREATE INDEX IF NOT EXISTS idx_produtos_nome ON produtos(nome);
|
|
CREATE INDEX IF NOT EXISTS idx_produtos_ativo ON produtos(ativo);
|
|
|
|
-- Variações
|
|
CREATE INDEX IF NOT EXISTS idx_variacoes_produto ON produto_variacoes(produto_id);
|
|
CREATE INDEX IF NOT EXISTS idx_variacoes_estoque ON produto_variacoes(quantidade);
|
|
|
|
-- Vendas
|
|
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_vendas_status ON vendas(status);
|
|
CREATE INDEX IF NOT EXISTS idx_vendas_origem ON vendas(origem);
|
|
|
|
-- Itens da 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);
|
|
|
|
-- Parcelas
|
|
CREATE INDEX IF NOT EXISTS idx_parcelas_venda ON parcelas(venda_id);
|
|
CREATE INDEX IF NOT EXISTS idx_parcelas_vencimento ON parcelas(data_vencimento);
|
|
CREATE INDEX IF NOT EXISTS idx_parcelas_status ON parcelas(status);
|
|
|
|
-- Pedidos catálogo
|
|
CREATE INDEX IF NOT EXISTS idx_pedidos_cliente ON pedidos_catalogo(cliente_id);
|
|
CREATE INDEX IF NOT EXISTS idx_pedidos_status ON pedidos_catalogo(status);
|
|
CREATE INDEX IF NOT EXISTS idx_pedidos_data ON pedidos_catalogo(data_pedido);
|
|
|
|
-- =============================================
|
|
-- 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';
|
|
|
|
-- Aplicar trigger em todas as tabelas relevantes
|
|
CREATE TRIGGER update_clientes_updated_at BEFORE UPDATE ON clientes FOR EACH ROW EXECUTE FUNCTION update_updated_at_column();
|
|
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_vendas_updated_at BEFORE UPDATE ON vendas FOR EACH ROW EXECUTE FUNCTION update_updated_at_column();
|
|
CREATE TRIGGER update_parcelas_updated_at BEFORE UPDATE ON parcelas FOR EACH ROW EXECUTE FUNCTION update_updated_at_column();
|
|
CREATE TRIGGER update_devolucoes_updated_at BEFORE UPDATE ON devolucoes 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_tipos_despesa_updated_at BEFORE UPDATE ON tipos_despesa FOR EACH ROW EXECUTE FUNCTION update_updated_at_column();
|
|
CREATE TRIGGER update_pedidos_catalogo_updated_at BEFORE UPDATE ON pedidos_catalogo 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();
|
|
|
|
-- =============================================
|
|
-- INSERIR DADOS INICIAIS
|
|
-- =============================================
|
|
|
|
-- Tipos de despesa padrão
|
|
INSERT INTO tipos_despesa (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 telefonia'),
|
|
('Marketing', 'Gastos com publicidade e marketing'),
|
|
('Transporte', 'Combustível, manutenção de veículos'),
|
|
('Materiais', 'Materiais de escritório e limpeza'),
|
|
('Outros', 'Outras despesas diversas')
|
|
ON CONFLICT (nome) DO NOTHING;
|
|
|
|
-- Configurações padrão do sistema
|
|
INSERT INTO configuracoes (chave, valor, tipo, descricao) VALUES
|
|
('sistema_nome', 'Liberi Kids', 'string', 'Nome do sistema'),
|
|
('catalogo_ativo', 'true', 'boolean', 'Se o catálogo online está ativo'),
|
|
('whatsapp_alertas', 'false', 'boolean', 'Se os alertas por WhatsApp estão ativos'),
|
|
('chatgpt_ativo', 'false', 'boolean', 'Se a integração com ChatGPT está ativa'),
|
|
('evolution_api_ativo', 'false', 'boolean', 'Se a Evolution API está ativa')
|
|
ON CONFLICT (chave) DO NOTHING;
|
|
|
|
-- =============================================
|
|
-- POLÍTICAS DE SEGURANÇA (RLS)
|
|
-- =============================================
|
|
|
|
-- Habilitar RLS nas tabelas principais
|
|
ALTER TABLE clientes ENABLE ROW LEVEL SECURITY;
|
|
ALTER TABLE produtos ENABLE ROW LEVEL SECURITY;
|
|
ALTER TABLE produto_variacoes ENABLE ROW LEVEL SECURITY;
|
|
ALTER TABLE vendas ENABLE ROW LEVEL SECURITY;
|
|
ALTER TABLE pedidos_catalogo ENABLE ROW LEVEL SECURITY;
|
|
|
|
-- Política para permitir leitura pública de produtos (para o catálogo)
|
|
CREATE POLICY "Produtos são visíveis publicamente" ON produtos FOR SELECT USING (ativo = true);
|
|
CREATE POLICY "Variações são visíveis publicamente" ON produto_variacoes FOR SELECT USING (true);
|
|
|
|
-- Política para clientes (podem ver apenas seus próprios dados)
|
|
CREATE POLICY "Clientes podem ver seus próprios dados" ON clientes FOR SELECT USING (auth.uid()::text = id::text);
|
|
CREATE POLICY "Clientes podem atualizar seus próprios dados" ON clientes FOR UPDATE USING (auth.uid()::text = id::text);
|
|
|
|
-- Política para pedidos (clientes podem ver apenas seus próprios pedidos)
|
|
CREATE POLICY "Clientes podem ver seus próprios pedidos" ON pedidos_catalogo FOR SELECT USING (auth.uid()::text = cliente_id::text);
|
|
CREATE POLICY "Clientes podem criar pedidos" ON pedidos_catalogo FOR INSERT WITH CHECK (auth.uid()::text = cliente_id::text);
|
|
|
|
-- =============================================
|
|
-- COMENTÁRIOS PARA DOCUMENTAÇÃO
|
|
-- =============================================
|
|
|
|
COMMENT ON TABLE clientes IS 'Cadastro de clientes da loja e do catálogo online';
|
|
COMMENT ON TABLE produtos IS 'Catálogo de produtos com informações básicas';
|
|
COMMENT ON TABLE produto_variacoes IS 'Variações dos produtos (tamanho, cor, estoque)';
|
|
COMMENT ON TABLE vendas IS 'Registro de todas as vendas (loja física e catálogo)';
|
|
COMMENT ON TABLE pedidos_catalogo IS 'Pedidos realizados através do catálogo online';
|
|
COMMENT ON TABLE configuracoes IS 'Configurações gerais do sistema';
|
|
|
|
COMMENT ON COLUMN vendas.origem IS 'Origem da venda: loja (física) ou catalogo (online)';
|
|
COMMENT ON COLUMN clientes.whatsapp IS 'Número do WhatsApp usado para login no catálogo';
|
|
COMMENT ON COLUMN pedidos_catalogo.venda_id IS 'ID da venda criada no app após processar o pedido';
|