-- =============================================================
-- ARCHIVO: 23-purchases.sql
-- DESCRIPCION: Ordenes de compra
-- VERSION: 1.0.0
-- PROYECTO: ERP-Core V2
-- FECHA: 2026-01-13
-- DEPENDE DE: 16-partners.sql, 17-products.sql, 18-warehouses.sql
-- =============================================================

-- =====================
-- SCHEMA: purchases
-- =====================
CREATE SCHEMA IF NOT EXISTS purchases;

-- =====================
-- TABLA: purchase_orders
-- Ordenes de compra a proveedores
-- =====================
CREATE TABLE IF NOT EXISTS purchases.purchase_orders (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    tenant_id UUID NOT NULL REFERENCES auth.tenants(id) ON DELETE CASCADE,

    -- Identificacion
    order_number VARCHAR(30) NOT NULL,

    -- Proveedor
    supplier_id UUID NOT NULL REFERENCES partners.partners(id) ON DELETE RESTRICT,
    supplier_name VARCHAR(200),
    supplier_email VARCHAR(255),

    -- Direcciones
    shipping_address JSONB,       -- Direccion de recepcion

    -- Fechas
    order_date DATE NOT NULL DEFAULT CURRENT_DATE,
    expected_date DATE,           -- Fecha esperada de recepcion
    received_date DATE,

    -- Comprador
    buyer_id UUID REFERENCES auth.users(id),

    -- Almacen destino
    warehouse_id UUID REFERENCES inventory.warehouses(id),

    -- Totales
    currency VARCHAR(3) DEFAULT 'MXN',
    subtotal DECIMAL(15, 2) NOT NULL DEFAULT 0,
    tax_amount DECIMAL(15, 2) NOT NULL DEFAULT 0,
    discount_amount DECIMAL(15, 2) NOT NULL DEFAULT 0,
    shipping_amount DECIMAL(15, 2) DEFAULT 0,
    total DECIMAL(15, 2) NOT NULL DEFAULT 0,

    -- Terminos
    payment_term_days INTEGER DEFAULT 0,
    payment_method VARCHAR(50),
    incoterm VARCHAR(10),         -- FOB, CIF, EXW, etc.

    -- Estado
    status VARCHAR(20) NOT NULL DEFAULT 'draft', -- draft, sent, confirmed, partial, received, cancelled

    -- Referencia del proveedor
    supplier_reference VARCHAR(100),

    -- Notas
    notes TEXT,
    internal_notes TEXT,

    -- Metadata
    created_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP,
    created_by UUID REFERENCES auth.users(id),
    updated_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP,
    updated_by UUID REFERENCES auth.users(id),
    deleted_at TIMESTAMPTZ,

    UNIQUE(tenant_id, order_number)
);

-- Indices para purchase_orders
CREATE INDEX IF NOT EXISTS idx_purchase_orders_tenant ON purchases.purchase_orders(tenant_id);
CREATE INDEX IF NOT EXISTS idx_purchase_orders_number ON purchases.purchase_orders(order_number);
CREATE INDEX IF NOT EXISTS idx_purchase_orders_supplier ON purchases.purchase_orders(supplier_id);
CREATE INDEX IF NOT EXISTS idx_purchase_orders_status ON purchases.purchase_orders(status);
CREATE INDEX IF NOT EXISTS idx_purchase_orders_date ON purchases.purchase_orders(order_date);
CREATE INDEX IF NOT EXISTS idx_purchase_orders_expected ON purchases.purchase_orders(expected_date);
CREATE INDEX IF NOT EXISTS idx_purchase_orders_warehouse ON purchases.purchase_orders(warehouse_id);
CREATE INDEX IF NOT EXISTS idx_purchase_orders_buyer ON purchases.purchase_orders(buyer_id);

-- =====================
-- TABLA: purchase_order_items
-- Lineas de orden de compra
-- =====================
CREATE TABLE IF NOT EXISTS purchases.purchase_order_items (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    order_id UUID NOT NULL REFERENCES purchases.purchase_orders(id) ON DELETE CASCADE,
    product_id UUID REFERENCES products.products(id) ON DELETE SET NULL,

    -- Linea
    line_number INTEGER NOT NULL DEFAULT 1,

    -- Producto
    product_sku VARCHAR(50),
    product_name VARCHAR(200) NOT NULL,
    supplier_sku VARCHAR(50),     -- SKU del proveedor
    description TEXT,

    -- Cantidad
    quantity DECIMAL(15, 4) NOT NULL DEFAULT 1,
    quantity_received DECIMAL(15, 4) DEFAULT 0,
    quantity_returned DECIMAL(15, 4) DEFAULT 0,
    uom VARCHAR(20) DEFAULT 'PZA',

    -- Precio
    unit_price DECIMAL(15, 4) NOT NULL DEFAULT 0,

    -- Descuentos
    discount_percent DECIMAL(5, 2) DEFAULT 0,
    discount_amount DECIMAL(15, 2) DEFAULT 0,

    -- Impuestos
    tax_rate DECIMAL(5, 2) DEFAULT 16.00,
    tax_amount DECIMAL(15, 2) DEFAULT 0,

    -- Totales
    subtotal DECIMAL(15, 2) NOT NULL DEFAULT 0,
    total DECIMAL(15, 2) NOT NULL DEFAULT 0,

    -- Lote/Serie
    lot_number VARCHAR(50),
    expiry_date DATE,

    -- Estado
    status VARCHAR(20) DEFAULT 'pending', -- pending, partial, received, cancelled

    -- Metadata
    created_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP,
    updated_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP
);

-- Indices para purchase_order_items
CREATE INDEX IF NOT EXISTS idx_purchase_order_items_order ON purchases.purchase_order_items(order_id);
CREATE INDEX IF NOT EXISTS idx_purchase_order_items_product ON purchases.purchase_order_items(product_id);
CREATE INDEX IF NOT EXISTS idx_purchase_order_items_line ON purchases.purchase_order_items(order_id, line_number);
CREATE INDEX IF NOT EXISTS idx_purchase_order_items_status ON purchases.purchase_order_items(status);

-- =====================
-- TABLA: purchase_receipts
-- Recepciones de mercancia
-- =====================
CREATE TABLE IF NOT EXISTS purchases.purchase_receipts (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    tenant_id UUID NOT NULL REFERENCES auth.tenants(id) ON DELETE CASCADE,
    order_id UUID NOT NULL REFERENCES purchases.purchase_orders(id) ON DELETE RESTRICT,

    -- Identificacion
    receipt_number VARCHAR(30) NOT NULL,

    -- Recepcion
    receipt_date DATE NOT NULL DEFAULT CURRENT_DATE,
    received_by UUID REFERENCES auth.users(id),

    -- Almacen
    warehouse_id UUID REFERENCES inventory.warehouses(id),
    location_id UUID REFERENCES inventory.warehouse_locations(id),

    -- Documentos del proveedor
    supplier_delivery_note VARCHAR(100),
    supplier_invoice_number VARCHAR(100),

    -- Estado
    status VARCHAR(20) NOT NULL DEFAULT 'draft', -- draft, confirmed, cancelled

    -- Notas
    notes TEXT,

    -- Metadata
    created_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP,
    created_by UUID REFERENCES auth.users(id),
    updated_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP,

    UNIQUE(tenant_id, receipt_number)
);

-- Indices para purchase_receipts
CREATE INDEX IF NOT EXISTS idx_purchase_receipts_tenant ON purchases.purchase_receipts(tenant_id);
CREATE INDEX IF NOT EXISTS idx_purchase_receipts_order ON purchases.purchase_receipts(order_id);
CREATE INDEX IF NOT EXISTS idx_purchase_receipts_number ON purchases.purchase_receipts(receipt_number);
CREATE INDEX IF NOT EXISTS idx_purchase_receipts_date ON purchases.purchase_receipts(receipt_date);
CREATE INDEX IF NOT EXISTS idx_purchase_receipts_status ON purchases.purchase_receipts(status);

-- =====================
-- TABLA: purchase_receipt_items
-- Lineas de recepcion
-- =====================
CREATE TABLE IF NOT EXISTS purchases.purchase_receipt_items (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    receipt_id UUID NOT NULL REFERENCES purchases.purchase_receipts(id) ON DELETE CASCADE,
    order_item_id UUID REFERENCES purchases.purchase_order_items(id),
    product_id UUID REFERENCES products.products(id) ON DELETE SET NULL,

    -- Cantidad
    quantity_expected DECIMAL(15, 4),
    quantity_received DECIMAL(15, 4) NOT NULL,
    quantity_rejected DECIMAL(15, 4) DEFAULT 0,

    -- Lote/Serie
    lot_number VARCHAR(50),
    serial_number VARCHAR(50),
    expiry_date DATE,

    -- Ubicacion de almacenamiento
    location_id UUID REFERENCES inventory.warehouse_locations(id),

    -- Control de calidad
    quality_status VARCHAR(20) DEFAULT 'pending', -- pending, approved, rejected, quarantine
    quality_notes TEXT,

    -- Metadata
    created_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP,
    updated_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP
);

-- Indices para purchase_receipt_items
CREATE INDEX IF NOT EXISTS idx_purchase_receipt_items_receipt ON purchases.purchase_receipt_items(receipt_id);
CREATE INDEX IF NOT EXISTS idx_purchase_receipt_items_order_item ON purchases.purchase_receipt_items(order_item_id);
CREATE INDEX IF NOT EXISTS idx_purchase_receipt_items_product ON purchases.purchase_receipt_items(product_id);
CREATE INDEX IF NOT EXISTS idx_purchase_receipt_items_lot ON purchases.purchase_receipt_items(lot_number);

-- =====================
-- COMENTARIOS
-- =====================
COMMENT ON TABLE purchases.purchase_orders IS 'Ordenes de compra a proveedores';
COMMENT ON COLUMN purchases.purchase_orders.status IS 'Estado: draft, sent, confirmed, partial (parcialmente recibido), received, cancelled';
COMMENT ON COLUMN purchases.purchase_orders.incoterm IS 'Termino de comercio internacional: FOB, CIF, EXW, etc.';

COMMENT ON TABLE purchases.purchase_order_items IS 'Lineas de detalle de ordenes de compra';
COMMENT ON COLUMN purchases.purchase_order_items.supplier_sku IS 'Codigo del producto segun el proveedor';
COMMENT ON COLUMN purchases.purchase_order_items.quantity_received IS 'Cantidad ya recibida de esta linea';

COMMENT ON TABLE purchases.purchase_receipts IS 'Documentos de recepcion de mercancia';
COMMENT ON COLUMN purchases.purchase_receipts.status IS 'Estado: draft, confirmed, cancelled';

COMMENT ON TABLE purchases.purchase_receipt_items IS 'Lineas de detalle de recepciones';
COMMENT ON COLUMN purchases.purchase_receipt_items.quality_status IS 'Estado QC: pending, approved, rejected, quarantine';
