-- v2.1_suppliers.sql -- Mejora #3: Proveedores y Órdenes de Compra -- -- Adds supplier management and purchase order workflow to tenant databases. -- -- Workflow: -- 1. Create supplier (suppliers table) -- 2. Create PO with items (purchase_orders + purchase_order_items) -- 3. Send PO to supplier (status = 'sent') -- 4. Receive partial or full delivery (status = 'partial' | 'received') -- → On receive: update stock via inventory_engine.record_purchase() -- → On receive: create accounting entry via record_purchase_entry() -- ═══════════════════════════════════════════════════════════════════════════ -- SUPPLIERS -- ═══════════════════════════════════════════════════════════════════════════ CREATE TABLE IF NOT EXISTS suppliers ( id SERIAL PRIMARY KEY, name VARCHAR(200) NOT NULL, contact_name VARCHAR(200), phone VARCHAR(50), email VARCHAR(200), rfc VARCHAR(13), address TEXT, payment_terms VARCHAR(100), -- e.g., "30 dias", "contado" notes TEXT, is_active BOOLEAN DEFAULT true, created_at TIMESTAMPTZ DEFAULT NOW(), updated_at TIMESTAMPTZ DEFAULT NOW() ); CREATE INDEX IF NOT EXISTS idx_suppliers_active ON suppliers(is_active); CREATE INDEX IF NOT EXISTS idx_suppliers_name ON suppliers(name); -- ═══════════════════════════════════════════════════════════════════════════ -- PURCHASE ORDERS -- ═══════════════════════════════════════════════════════════════════════════ CREATE TABLE IF NOT EXISTS purchase_orders ( id SERIAL PRIMARY KEY, supplier_id INTEGER REFERENCES suppliers(id) ON DELETE SET NULL, branch_id INTEGER REFERENCES branches(id), employee_id INTEGER REFERENCES employees(id), status VARCHAR(20) DEFAULT 'draft' NOT NULL, -- draft, sent, partial, received, cancelled subtotal NUMERIC(12,2) DEFAULT 0 NOT NULL, tax_total NUMERIC(12,2) DEFAULT 0 NOT NULL, total NUMERIC(12,2) DEFAULT 0 NOT NULL, currency VARCHAR(3) DEFAULT 'MXN', exchange_rate NUMERIC(12,6) DEFAULT 1.0, notes TEXT, supplier_invoice VARCHAR(100), expected_date DATE, sent_at TIMESTAMPTZ, received_at TIMESTAMPTZ, cancelled_at TIMESTAMPTZ, created_at TIMESTAMPTZ DEFAULT NOW() ); CREATE INDEX IF NOT EXISTS idx_po_supplier ON purchase_orders(supplier_id); CREATE INDEX IF NOT EXISTS idx_po_status ON purchase_orders(status); CREATE INDEX IF NOT EXISTS idx_po_branch ON purchase_orders(branch_id); CREATE INDEX IF NOT EXISTS idx_po_created ON purchase_orders(created_at DESC); -- ═══════════════════════════════════════════════════════════════════════════ -- PURCHASE ORDER ITEMS -- ═══════════════════════════════════════════════════════════════════════════ CREATE TABLE IF NOT EXISTS purchase_order_items ( id SERIAL PRIMARY KEY, po_id INTEGER NOT NULL REFERENCES purchase_orders(id) ON DELETE CASCADE, inventory_id INTEGER REFERENCES inventory(id) ON DELETE SET NULL, part_number VARCHAR(100), name VARCHAR(300), quantity INTEGER NOT NULL DEFAULT 1, received_qty INTEGER DEFAULT 0, unit_price NUMERIC(12,2) NOT NULL DEFAULT 0, subtotal NUMERIC(12,2) NOT NULL DEFAULT 0, notes TEXT, created_at TIMESTAMPTZ DEFAULT NOW() ); CREATE INDEX IF NOT EXISTS idx_poi_po ON purchase_order_items(po_id); CREATE INDEX IF NOT EXISTS idx_poi_inventory ON purchase_order_items(inventory_id);