-- =============================================================
-- ARCHIVO: 18-warehouses.sql
-- DESCRIPCION: Almacenes y ubicaciones
-- VERSION: 1.0.0
-- PROYECTO: ERP-Core V2
-- FECHA: 2026-01-13
-- =============================================================

-- =====================
-- SCHEMA: inventory (compartido con 19-inventory.sql)
-- =====================
CREATE SCHEMA IF NOT EXISTS inventory;

-- =====================
-- TABLA: warehouses
-- Almacenes/bodegas para inventario
-- =====================
CREATE TABLE IF NOT EXISTS inventory.warehouses (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    tenant_id UUID NOT NULL REFERENCES auth.tenants(id) ON DELETE CASCADE,
    branch_id UUID REFERENCES core.branches(id) ON DELETE SET NULL,

    -- Identificacion
    code VARCHAR(20) NOT NULL,
    name VARCHAR(100) NOT NULL,
    description TEXT,

    -- Tipo
    warehouse_type VARCHAR(20) DEFAULT 'standard', -- standard, transit, returns, quarantine, virtual

    -- Direccion
    address_line1 VARCHAR(200),
    address_line2 VARCHAR(200),
    city VARCHAR(100),
    state VARCHAR(100),
    postal_code VARCHAR(20),
    country VARCHAR(3) DEFAULT 'MEX',

    -- Contacto
    manager_name VARCHAR(100),
    phone VARCHAR(30),
    email VARCHAR(255),

    -- Geolocalizacion
    latitude DECIMAL(10, 8),
    longitude DECIMAL(11, 8),

    -- Capacidad
    capacity_units INTEGER,       -- Capacidad en unidades
    capacity_volume DECIMAL(10, 4), -- Capacidad en m3
    capacity_weight DECIMAL(10, 4), -- Capacidad en kg

    -- Configuracion
    settings JSONB DEFAULT '{}',
    -- Ejemplo: {"allow_negative": false, "auto_reorder": true}

    -- Estado
    is_active BOOLEAN DEFAULT TRUE,
    is_default BOOLEAN DEFAULT FALSE,

    -- 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, code)
);

-- Indices para warehouses
CREATE INDEX IF NOT EXISTS idx_warehouses_tenant ON inventory.warehouses(tenant_id);
CREATE INDEX IF NOT EXISTS idx_warehouses_branch ON inventory.warehouses(branch_id);
CREATE INDEX IF NOT EXISTS idx_warehouses_code ON inventory.warehouses(code);
CREATE INDEX IF NOT EXISTS idx_warehouses_type ON inventory.warehouses(warehouse_type);
CREATE INDEX IF NOT EXISTS idx_warehouses_active ON inventory.warehouses(is_active) WHERE is_active = TRUE;
CREATE INDEX IF NOT EXISTS idx_warehouses_default ON inventory.warehouses(tenant_id, is_default) WHERE is_default = TRUE;

-- =====================
-- TABLA: warehouse_locations
-- Ubicaciones dentro de almacenes (pasillos, racks, estantes)
-- =====================
CREATE TABLE IF NOT EXISTS inventory.warehouse_locations (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    warehouse_id UUID NOT NULL REFERENCES inventory.warehouses(id) ON DELETE CASCADE,
    parent_id UUID REFERENCES inventory.warehouse_locations(id) ON DELETE SET NULL,

    -- Identificacion
    code VARCHAR(30) NOT NULL,
    name VARCHAR(100) NOT NULL,
    barcode VARCHAR(50),

    -- Tipo de ubicacion
    location_type VARCHAR(20) DEFAULT 'shelf', -- zone, aisle, rack, shelf, bin

    -- Jerarquia
    hierarchy_path TEXT,         -- /warehouse-01/zone-a/rack-1/shelf-2
    hierarchy_level INTEGER DEFAULT 0,

    -- Coordenadas dentro del almacen
    aisle VARCHAR(10),
    rack VARCHAR(10),
    shelf VARCHAR(10),
    bin VARCHAR(10),

    -- Capacidad
    capacity_units INTEGER,
    capacity_volume DECIMAL(10, 4),
    capacity_weight DECIMAL(10, 4),

    -- Restricciones
    allowed_product_types TEXT[] DEFAULT '{}', -- Tipos de producto permitidos
    temperature_range JSONB,     -- {"min": -20, "max": 4} para productos refrigerados
    humidity_range JSONB,        -- {"min": 30, "max": 50}

    -- Estado
    is_active BOOLEAN DEFAULT TRUE,
    is_pickable BOOLEAN DEFAULT TRUE,    -- Se puede tomar inventario
    is_receivable BOOLEAN DEFAULT TRUE,  -- Se puede recibir inventario

    -- Metadata
    created_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP,
    updated_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP,
    deleted_at TIMESTAMPTZ,

    UNIQUE(warehouse_id, code)
);

-- Indices para warehouse_locations
CREATE INDEX IF NOT EXISTS idx_warehouse_locations_warehouse ON inventory.warehouse_locations(warehouse_id);
CREATE INDEX IF NOT EXISTS idx_warehouse_locations_parent ON inventory.warehouse_locations(parent_id);
CREATE INDEX IF NOT EXISTS idx_warehouse_locations_code ON inventory.warehouse_locations(code);
CREATE INDEX IF NOT EXISTS idx_warehouse_locations_type ON inventory.warehouse_locations(location_type);
CREATE INDEX IF NOT EXISTS idx_warehouse_locations_hierarchy ON inventory.warehouse_locations(hierarchy_path);
CREATE INDEX IF NOT EXISTS idx_warehouse_locations_active ON inventory.warehouse_locations(is_active) WHERE is_active = TRUE;
CREATE INDEX IF NOT EXISTS idx_warehouse_locations_barcode ON inventory.warehouse_locations(barcode);

-- =====================
-- TABLA: warehouse_zones
-- Zonas logicas de almacen (para organizacion)
-- =====================
CREATE TABLE IF NOT EXISTS inventory.warehouse_zones (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    warehouse_id UUID NOT NULL REFERENCES inventory.warehouses(id) ON DELETE CASCADE,

    -- Identificacion
    code VARCHAR(20) NOT NULL,
    name VARCHAR(100) NOT NULL,
    description TEXT,
    color VARCHAR(20),

    -- Tipo de zona
    zone_type VARCHAR(20) DEFAULT 'storage', -- storage, picking, packing, shipping, receiving, quarantine

    -- Estado
    is_active BOOLEAN DEFAULT TRUE,

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

    UNIQUE(warehouse_id, code)
);

-- Indices para warehouse_zones
CREATE INDEX IF NOT EXISTS idx_warehouse_zones_warehouse ON inventory.warehouse_zones(warehouse_id);
CREATE INDEX IF NOT EXISTS idx_warehouse_zones_type ON inventory.warehouse_zones(zone_type);

-- =====================
-- COMENTARIOS
-- =====================
COMMENT ON TABLE inventory.warehouses IS 'Almacenes y bodegas para gestion de inventario';
COMMENT ON COLUMN inventory.warehouses.warehouse_type IS 'Tipo: standard, transit (en transito), returns (devoluciones), quarantine (cuarentena), virtual';
COMMENT ON COLUMN inventory.warehouses.is_default IS 'Almacen por defecto para operaciones';

COMMENT ON TABLE inventory.warehouse_locations IS 'Ubicaciones fisicas dentro de almacenes (racks, estantes, bins)';
COMMENT ON COLUMN inventory.warehouse_locations.location_type IS 'Tipo: zone, aisle, rack, shelf, bin';
COMMENT ON COLUMN inventory.warehouse_locations.is_pickable IS 'Se puede hacer picking desde esta ubicacion';
COMMENT ON COLUMN inventory.warehouse_locations.is_receivable IS 'Se puede recibir inventario en esta ubicacion';

COMMENT ON TABLE inventory.warehouse_zones IS 'Zonas logicas para organizar el almacen';
COMMENT ON COLUMN inventory.warehouse_zones.zone_type IS 'Tipo: storage, picking, packing, shipping, receiving, quarantine';
