michangarrito/database/schemas/06-sales.sql
rckrdmrd 97f407c661 [MIGRATION-V2] feat: Migrar michangarrito a estructura v2
- Prefijo v2: MCH
- TRACEABILITY-MASTER.yml creado
- Listo para integracion como submodulo

Workspace: v2.0.0 | SIMCO: v4.0.0
2026-01-10 11:28:54 -06:00

149 lines
4.5 KiB
SQL

-- =============================================================================
-- MICHANGARRITO - 06 SALES
-- =============================================================================
-- Ventas, pagos y cortes de caja
-- =============================================================================
-- Ventas
CREATE TABLE IF NOT EXISTS sales.sales (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
tenant_id UUID NOT NULL REFERENCES public.tenants(id) ON DELETE CASCADE,
ticket_number VARCHAR(20) NOT NULL,
subtotal DECIMAL(10,2) NOT NULL,
discount_amount DECIMAL(10,2) DEFAULT 0,
discount_percent DECIMAL(5,2) DEFAULT 0,
tax_amount DECIMAL(10,2) DEFAULT 0,
total DECIMAL(10,2) NOT NULL,
payment_method VARCHAR(20) NOT NULL,
payment_status VARCHAR(20) DEFAULT 'completed',
payment_reference TEXT,
cash_received DECIMAL(10,2),
change_amount DECIMAL(10,2),
customer_id UUID,
is_fiado BOOLEAN DEFAULT false,
fiado_id UUID,
created_by UUID REFERENCES auth.users(id),
notes TEXT,
status VARCHAR(20) DEFAULT 'completed',
cancelled_at TIMESTAMPTZ,
cancelled_reason TEXT,
created_at TIMESTAMPTZ DEFAULT NOW(),
updated_at TIMESTAMPTZ DEFAULT NOW()
);
CREATE INDEX idx_sales_tenant ON sales.sales(tenant_id);
CREATE INDEX idx_sales_ticket ON sales.sales(tenant_id, ticket_number);
CREATE INDEX idx_sales_date ON sales.sales(tenant_id, created_at);
CREATE INDEX idx_sales_customer ON sales.sales(customer_id);
CREATE TRIGGER update_sales_updated_at
BEFORE UPDATE ON sales.sales
FOR EACH ROW EXECUTE FUNCTION update_updated_at();
-- Items de venta
CREATE TABLE IF NOT EXISTS sales.sale_items (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
sale_id UUID NOT NULL REFERENCES sales.sales(id) ON DELETE CASCADE,
product_id UUID REFERENCES catalog.products(id),
product_name VARCHAR(100) NOT NULL,
product_sku VARCHAR(50),
quantity DECIMAL(10,3) NOT NULL,
unit_price DECIMAL(10,2) NOT NULL,
discount_amount DECIMAL(10,2) DEFAULT 0,
subtotal DECIMAL(10,2) NOT NULL,
created_at TIMESTAMPTZ DEFAULT NOW()
);
CREATE INDEX idx_sale_items_sale ON sales.sale_items(sale_id);
CREATE INDEX idx_sale_items_product ON sales.sale_items(product_id);
-- Trigger para actualizar inventario en ventas
CREATE TRIGGER update_inventory_on_sale
AFTER INSERT ON sales.sale_items
FOR EACH ROW EXECUTE FUNCTION inventory.update_stock_on_sale();
-- Pagos
CREATE TABLE IF NOT EXISTS sales.payments (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
tenant_id UUID NOT NULL REFERENCES public.tenants(id) ON DELETE CASCADE,
sale_id UUID REFERENCES sales.sales(id),
fiado_id UUID,
subscription_id UUID,
method VARCHAR(20) NOT NULL,
provider VARCHAR(20),
amount DECIMAL(10,2) NOT NULL,
fee_amount DECIMAL(10,2) DEFAULT 0,
net_amount DECIMAL(10,2),
external_id TEXT,
external_status VARCHAR(20),
receipt_url TEXT,
status VARCHAR(20) DEFAULT 'pending',
metadata JSONB,
created_at TIMESTAMPTZ DEFAULT NOW(),
updated_at TIMESTAMPTZ DEFAULT NOW()
);
CREATE INDEX idx_payments_tenant ON sales.payments(tenant_id);
CREATE INDEX idx_payments_sale ON sales.payments(sale_id);
CREATE INDEX idx_payments_external ON sales.payments(external_id);
CREATE TRIGGER update_payments_updated_at
BEFORE UPDATE ON sales.payments
FOR EACH ROW EXECUTE FUNCTION update_updated_at();
-- Cortes de caja
CREATE TABLE IF NOT EXISTS sales.daily_closures (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
tenant_id UUID NOT NULL REFERENCES public.tenants(id) ON DELETE CASCADE,
closure_date DATE NOT NULL,
opened_at TIMESTAMPTZ,
closed_at TIMESTAMPTZ,
expected_cash DECIMAL(10,2) DEFAULT 0,
expected_card DECIMAL(10,2) DEFAULT 0,
expected_other DECIMAL(10,2) DEFAULT 0,
expected_total DECIMAL(10,2) DEFAULT 0,
actual_cash DECIMAL(10,2),
actual_card DECIMAL(10,2),
actual_other DECIMAL(10,2),
actual_total DECIMAL(10,2),
cash_difference DECIMAL(10,2),
total_sales INTEGER DEFAULT 0,
total_cancelled INTEGER DEFAULT 0,
total_fiados DECIMAL(10,2) DEFAULT 0,
closed_by UUID REFERENCES auth.users(id),
notes TEXT,
status VARCHAR(20) DEFAULT 'open',
created_at TIMESTAMPTZ DEFAULT NOW(),
updated_at TIMESTAMPTZ DEFAULT NOW(),
UNIQUE(tenant_id, closure_date)
);
CREATE TRIGGER update_daily_closures_updated_at
BEFORE UPDATE ON sales.daily_closures
FOR EACH ROW EXECUTE FUNCTION update_updated_at();