# Arquitectura Multi-Nivel para Sistema ERP

## Modelo de Negocio: Holding → Reseller → Subsidiario

### 1. EXTENSIONES A TABLAS EXISTENTES

#### A. Tabla `empresas` - Aprovechar campos existentes y agregar nuevos:

```sql
-- USAR CAMPOS EXISTENTES:
-- parent_id (ya existe) - Para jerarquía padre-hijo
-- type (ya existe) - Valores: 'holding', 'reseller', 'subsidiario'

-- AGREGAR NUEVOS CAMPOS:
ALTER TABLE empresas ADD COLUMN comision_porcentaje DECIMAL(5,2) DEFAULT 0;
-- Porcentaje de comisión que cobra esta empresa a sus hijos

ALTER TABLE empresas ADD COLUMN activo_para_ventas BOOLEAN DEFAULT true;
-- Si puede vender suscripciones

ALTER TABLE empresas ADD COLUMN limite_subsidiarios INTEGER DEFAULT NULL;
-- Límite de subsidiarios que puede manejar un reseller

ALTER TABLE empresas ADD COLUMN holding_empresa_id UUID REFERENCES empresas(id);
-- Referencia directa al holding (para optimizar consultas)

ALTER TABLE empresas ADD COLUMN canal_venta VARCHAR(20) DEFAULT 'directo';
-- Valores: 'directo' (holding→subsidiario), 'reseller' (holding→reseller→subsidiario)
```

#### B. Tabla `suscripciones` - Agregar campos:

```sql
ALTER TABLE suscripciones ADD COLUMN vendida_por_empresa_id UUID REFERENCES empresas(id);
-- Quién vendió esta suscripción (reseller o holding)

ALTER TABLE suscripciones ADD COLUMN comision_aplicada DECIMAL(5,2) DEFAULT 0;
-- Porcentaje de comisión aplicado en esta venta

ALTER TABLE suscripciones ADD COLUMN precio_venta DECIMAL(10,2);
-- Precio al que se vendió (puede ser diferente al precio base del plan)

ALTER TABLE suscripciones ADD COLUMN precio_costo DECIMAL(10,2);
-- Costo base del plan (para calcular comisiones)
```

### 2. NUEVAS TABLAS REQUERIDAS

#### A. Tabla `comisiones`

```sql
CREATE TABLE comisiones (
  id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
  suscripcion_id UUID REFERENCES suscripciones(id),
  empresa_beneficiaria_id UUID REFERENCES empresas(id), -- Quien recibe la comisión
  empresa_pagadora_id UUID REFERENCES empresas(id), -- Quien paga la comisión
  tipo_comision VARCHAR(20), -- 'venta_inicial', 'renovacion', 'upgrade'
  porcentaje DECIMAL(5,2),
  monto_base DECIMAL(10,2), -- Sobre qué monto se calcula
  monto_comision DECIMAL(10,2), -- Monto final de comisión
  periodo_inicio DATE,
  periodo_fin DATE,
  estado VARCHAR(20) DEFAULT 'pendiente', -- 'pendiente', 'pagada', 'cancelada'
  fecha_pago DATE,
  observaciones TEXT,
  created_at TIMESTAMP DEFAULT NOW(),
  updated_at TIMESTAMP DEFAULT NOW()
);
```

#### B. Tabla `precios_reseller`

```sql
CREATE TABLE precios_reseller (
  id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
  plan_id UUID REFERENCES planes(id),
  reseller_empresa_id UUID REFERENCES empresas(id),
  precio_reseller DECIMAL(10,2), -- Precio especial para este reseller
  descuento_porcentaje DECIMAL(5,2), -- Descuento sobre precio base
  activo BOOLEAN DEFAULT true,
  fecha_inicio DATE,
  fecha_fin DATE,
  created_at TIMESTAMP DEFAULT NOW(),
  updated_at TIMESTAMP DEFAULT NOW(),

  UNIQUE(plan_id, reseller_empresa_id, fecha_inicio)
);
```

#### C. Tabla `limites_reseller`

```sql
CREATE TABLE limites_reseller (
  id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
  reseller_empresa_id UUID REFERENCES empresas(id),
  max_subsidiarios INTEGER DEFAULT NULL,
  max_suscripciones_activas INTEGER DEFAULT NULL,
  planes_permitidos UUID[], -- Array de IDs de planes que puede vender
  modulos_permitidos UUID[], -- Array de IDs de módulos que puede vender
  activo BOOLEAN DEFAULT true,
  created_at TIMESTAMP DEFAULT NOW(),
  updated_at TIMESTAMP DEFAULT NOW()
);
```

### 3. MODELO DE COMISIONES RECOMENDADO

#### Estructura de Comisiones:

1. **Holding → Reseller**: 10-20% de comisión por venta
2. **Reseller → Subsidiario**: Precio libre (markup sobre costo)
3. **Comisiones Recurrentes**: % sobre pagos mensuales

#### Tipos de Comisión:

- `venta_inicial`: Comisión por primera venta
- `renovacion`: Comisión por renovaciones
- `upgrade`: Comisión por upgrades de plan
- `referido`: Comisión por referir nuevos resellers

### 4. FLUJO DE VENTAS PROPUESTO (MODELO HÍBRIDO)

#### Escenario A: Venta Directa (Holding → Subsidiario)

```
1. Holding vende directamente a subsidiario
2. No hay comisiones intermedias
3. Precio completo para el holding
4. Subsidiario.parent_id = holding.id
5. Subsidiario.canal_venta = 'directo'
```

#### Escenario B: Venta por Reseller (Holding → Reseller → Subsidiario)

```
1. Holding define:
   - Precios base de planes
   - Comisiones para resellers (15-25%)
   - Límites por reseller

2. Reseller puede:
   - Ver sus precios con descuento
   - Definir precios de venta a subsidiarios
   - Gestionar sus subsidiarios
   - Ver sus comisiones

3. Subsidiario:
   - Ve precios definidos por su reseller
   - Paga a su reseller
   - Reseller paga comisión al holding
   - Subsidiario.parent_id = reseller.id
   - Subsidiario.canal_venta = 'reseller'
```

#### Jerarquía Resultante:

```
HOLDING (type='holding')
├── Subsidiario Directo 1 (parent_id=holding, canal_venta='directo')
├── Subsidiario Directo 2 (parent_id=holding, canal_venta='directo')
├── Reseller A (parent_id=holding, type='reseller')
│   ├── Subsidiario A1 (parent_id=reseller_a, canal_venta='reseller')
│   └── Subsidiario A2 (parent_id=reseller_a, canal_venta='reseller')
└── Reseller B (parent_id=holding, type='reseller')
    ├── Subsidiario B1 (parent_id=reseller_b, canal_venta='reseller')
    └── Subsidiario B2 (parent_id=reseller_b, canal_venta='reseller')
```

### 5. SERVICIOS A IMPLEMENTAR

#### A. `ComisionesService`

```typescript
class ComisionesService {
  async calcularComision(suscripcionId: string);
  async generarComisionesPendientes();
  async pagarComision(comisionId: string);
  async getComisionesByEmpresa(empresaId: string);
}
```

#### B. `JerarquiaEmpresasService`

```typescript
class JerarquiaEmpresasService {
  async getHijos(empresaId: string);
  async getJerarquiaCompleta(empresaId: string);
  async validarLimites(resellerEmpresaId: string);
  async asignarReseller(subsidiarioId: string, resellerId: string);
}
```

#### C. `PreciosResellerService`

```typescript
class PreciosResellerService {
  async getPrecioParaReseller(planId: string, resellerId: string);
  async setPrecioReseller(planId: string, resellerId: string, precio: number);
  async getPlanesDisponibles(resellerId: string);
}
```

### 6. DASHBOARD RECOMENDADO

#### Para Holding:

- Lista de resellers y sus métricas
- Comisiones por pagar/pagadas
- Ingresos totales por canal
- Gestión de precios y límites

#### Para Reseller:

- Lista de subsidiarios
- Comisiones ganadas
- Ventas realizadas
- Gestión de precios a subsidiarios

#### Para Subsidiario:

- Su suscripción actual
- Historial de pagos
- Información de su reseller

### 7. CONSIDERACIONES DE SEGURIDAD

1. **Aislamiento de datos**: Cada nivel solo ve sus datos
2. **Validación de jerarquía**: Verificar permisos en cada operación
3. **Auditoría**: Log de todas las operaciones de comisiones
4. **Límites**: Validar límites antes de crear suscripciones

### 8. MIGRACIÓN GRADUAL

1. **Fase 1**: Agregar campos a tablas existentes
2. **Fase 2**: Crear nuevas tablas
3. **Fase 3**: Implementar servicios básicos
4. **Fase 4**: Crear dashboards
5. **Fase 5**: Migrar datos existentes
