-- =============================================================
-- ARCHIVO: 56-financial-taxes.sql
-- DESCRIPCION: Impuestos contables (IVA, retenciones, etc.)
-- VERSION: 1.0.0
-- PROYECTO: ERP-Core V2
-- FECHA: 2026-01-20
-- DEPENDE DE: 50-financial-schema.sql, 51-financial-accounts.sql
-- =============================================================

-- =====================
-- TABLA: taxes
-- Catalogo de impuestos
-- =====================
CREATE TABLE IF NOT EXISTS financial.taxes (
    id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),

    -- Multi-tenant
    tenant_id UUID NOT NULL REFERENCES auth.tenants(id) ON DELETE CASCADE,
    company_id UUID,

    -- Identificacion
    name VARCHAR(100) NOT NULL,  -- Ej: "IVA 16%", "Retencion ISR 10%"
    code VARCHAR(20) NOT NULL,   -- Ej: "IVA16", "RET_ISR10"

    -- Tipo de impuesto
    tax_type financial.tax_type_enum NOT NULL DEFAULT 'all',

    -- Tasa
    amount DECIMAL(5, 2) NOT NULL,  -- Porcentaje (ej: 16.00 para 16%)

    -- Configuracion
    included_in_price BOOLEAN DEFAULT FALSE,  -- TRUE si el precio ya incluye el impuesto

    -- Estado
    active BOOLEAN DEFAULT TRUE,

    -- Cuentas contables asociadas (opcional)
    account_id UUID REFERENCES financial.accounts(id) ON DELETE SET NULL,  -- Cuenta de impuesto
    refund_account_id UUID REFERENCES financial.accounts(id) ON DELETE SET NULL,  -- Cuenta para devoluciones

    -- Audit columns
    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),

    -- Unicidad por tenant
    UNIQUE(tenant_id, code)
);

-- Indices para taxes
CREATE INDEX IF NOT EXISTS idx_financial_taxes_tenant ON financial.taxes(tenant_id);
CREATE INDEX IF NOT EXISTS idx_financial_taxes_company ON financial.taxes(company_id);
CREATE INDEX IF NOT EXISTS idx_financial_taxes_code ON financial.taxes(code);
CREATE INDEX IF NOT EXISTS idx_financial_taxes_type ON financial.taxes(tax_type);
CREATE INDEX IF NOT EXISTS idx_financial_taxes_active ON financial.taxes(tenant_id) WHERE active = TRUE;
CREATE INDEX IF NOT EXISTS idx_financial_taxes_sales ON financial.taxes(tenant_id, tax_type) WHERE tax_type IN ('sales', 'all') AND active = TRUE;
CREATE INDEX IF NOT EXISTS idx_financial_taxes_purchase ON financial.taxes(tenant_id, tax_type) WHERE tax_type IN ('purchase', 'all') AND active = TRUE;
CREATE INDEX IF NOT EXISTS idx_financial_taxes_account ON financial.taxes(account_id) WHERE account_id IS NOT NULL;

-- =====================
-- TABLA: tax_groups (opcional, para agrupar impuestos)
-- Grupos de impuestos para aplicacion conjunta
-- =====================
CREATE TABLE IF NOT EXISTS financial.tax_groups (
    id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),

    -- Multi-tenant
    tenant_id UUID NOT NULL REFERENCES auth.tenants(id) ON DELETE CASCADE,

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

    -- Descripcion
    description TEXT,

    -- Impuestos en el grupo (array de IDs)
    tax_ids UUID[] DEFAULT '{}',

    -- Estado
    active BOOLEAN DEFAULT TRUE,

    -- Audit columns
    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),

    UNIQUE(tenant_id, code)
);

-- Indices para tax_groups
CREATE INDEX IF NOT EXISTS idx_financial_tax_groups_tenant ON financial.tax_groups(tenant_id);
CREATE INDEX IF NOT EXISTS idx_financial_tax_groups_code ON financial.tax_groups(code);
CREATE INDEX IF NOT EXISTS idx_financial_tax_groups_active ON financial.tax_groups(tenant_id) WHERE active = TRUE;
CREATE INDEX IF NOT EXISTS idx_financial_tax_groups_tax_ids ON financial.tax_groups USING GIN(tax_ids);

-- =====================
-- DATOS SEMILLA: Impuestos comunes de Mexico
-- =====================
-- Nota: Estos se insertan condicionalmente. En produccion, los impuestos
-- se crean por tenant desde la aplicacion.

-- Funcion para insertar impuestos semilla
CREATE OR REPLACE FUNCTION financial.seed_default_taxes(p_tenant_id UUID)
RETURNS void AS $$
BEGIN
    -- IVA 16% (tasa general)
    INSERT INTO financial.taxes (tenant_id, code, name, tax_type, amount, included_in_price, active)
    VALUES (p_tenant_id, 'IVA16', 'IVA 16%', 'all', 16.00, FALSE, TRUE)
    ON CONFLICT (tenant_id, code) DO NOTHING;

    -- IVA 8% (frontera)
    INSERT INTO financial.taxes (tenant_id, code, name, tax_type, amount, included_in_price, active)
    VALUES (p_tenant_id, 'IVA8', 'IVA 8% (Frontera)', 'all', 8.00, FALSE, TRUE)
    ON CONFLICT (tenant_id, code) DO NOTHING;

    -- IVA 0% (tasa cero)
    INSERT INTO financial.taxes (tenant_id, code, name, tax_type, amount, included_in_price, active)
    VALUES (p_tenant_id, 'IVA0', 'IVA 0%', 'all', 0.00, FALSE, TRUE)
    ON CONFLICT (tenant_id, code) DO NOTHING;

    -- IVA Exento
    INSERT INTO financial.taxes (tenant_id, code, name, tax_type, amount, included_in_price, active)
    VALUES (p_tenant_id, 'EXENTO', 'Exento de IVA', 'all', 0.00, FALSE, TRUE)
    ON CONFLICT (tenant_id, code) DO NOTHING;

    -- Retencion ISR 10%
    INSERT INTO financial.taxes (tenant_id, code, name, tax_type, amount, included_in_price, active)
    VALUES (p_tenant_id, 'RET_ISR10', 'Retencion ISR 10%', 'purchase', -10.00, FALSE, TRUE)
    ON CONFLICT (tenant_id, code) DO NOTHING;

    -- Retencion IVA 10.67%
    INSERT INTO financial.taxes (tenant_id, code, name, tax_type, amount, included_in_price, active)
    VALUES (p_tenant_id, 'RET_IVA', 'Retencion IVA 2/3', 'purchase', -10.67, FALSE, TRUE)
    ON CONFLICT (tenant_id, code) DO NOTHING;
END;
$$ LANGUAGE plpgsql;

-- =====================
-- COMENTARIOS
-- =====================
COMMENT ON TABLE financial.taxes IS 'Catalogo de impuestos (IVA, retenciones, etc.)';
COMMENT ON COLUMN financial.taxes.code IS 'Codigo unico del impuesto (ej: IVA16, RET_ISR10)';
COMMENT ON COLUMN financial.taxes.tax_type IS 'Aplicacion: sales (solo ventas), purchase (solo compras), all (ambos)';
COMMENT ON COLUMN financial.taxes.amount IS 'Tasa del impuesto en porcentaje (ej: 16.00 para 16%). Negativo para retenciones.';
COMMENT ON COLUMN financial.taxes.included_in_price IS 'TRUE si el precio del producto ya incluye este impuesto';
COMMENT ON COLUMN financial.taxes.account_id IS 'Cuenta contable donde se registra el impuesto';
COMMENT ON COLUMN financial.taxes.refund_account_id IS 'Cuenta contable para devoluciones/notas de credito';

COMMENT ON TABLE financial.tax_groups IS 'Grupos de impuestos para aplicacion conjunta (ej: IVA + Retenciones)';
COMMENT ON COLUMN financial.tax_groups.tax_ids IS 'Array de IDs de impuestos que componen el grupo';

COMMENT ON FUNCTION financial.seed_default_taxes(UUID) IS 'Inserta impuestos predeterminados de Mexico para un tenant';
