# Plan: Migración Access → Novasis ERP

## Estado actual

Script funcional con pruebas sobre IDs individuales. Pendiente ejecutar migración masiva.

## Archivos clave

- **Script**: `scripts/migrate-access/migrate.ts`
- **Datos**: `data_exportar/clientes.xlsx` + `data_exportar/facturas.xlsx`
- **Logs**: `scripts/migrate-access/reporte-YYYY-MM-DDTHH-MM-SS.log`

## Cómo ejecutar

```bash
cd /var/www/html/proyectos/smartfactvoice-backend

# Probar registro específico (modo seco, no escribe)
npx ts-node --transpile-only scripts/migrate-access/migrate.ts --dry --ids=31

# Probar registro específico (escribe real)
npx ts-node --transpile-only scripts/migrate-access/migrate.ts --ids=31

# Probar varios IDs
npx ts-node --transpile-only scripts/migrate-access/migrate.ts --dry --ids=31,32,34

# Migración completa
npx ts-node --transpile-only scripts/migrate-access/migrate.ts
```

## Qué hace el script

### Paso 1 — Clientes

- Lee `clientes.xlsx`, deduplica por cédula (campo `Cedula`)
- Busca persona existente por `nro_documento` → si no existe la crea
- Busca cliente vinculado a esa persona → si no existe lo crea
- Idempotente: no duplica si ya existe

### Paso 2 — Facturas, CxC y Cuotas

- Lee `facturas.xlsx`, agrupa pagos por `Id` de venta
- **Idempotencia**: carga todas las `dinfadic LIKE '%MIGRADO_ACCESS%'` al inicio → saltea las ya migradas
- Por cada venta válida crea:
  - `factura_cab` (con `dinfadic = "MIGRADO_ACCESS | Id:X | ..."`)
  - `factura_det` (producto genérico `GEN0001`, artículo del Excel en `ddesproser`)
  - `factura_subtotales` (IVA 10%)
  - `cuentas_cobrar`
  - `factura_cuotas` (proyectadas desde hoy)
  - Incrementa `clientes.saldo_pendiente`

## Lógica de cuotas (Opción C)

```
cantCuotasBase = floor(saldo / montoCuota)
residuo        = saldo - cantCuotasBase * montoCuota
cantCuotas     = residuo > 0 ? cantCuotasBase + 1 : cantCuotasBase
```

- Las primeras N cuotas tienen `dmoncuota = montoCuota`
- La última cuota (si hay residuo) tiene `dmoncuota = residuo`
- Garantiza que la suma de cuotas = saldo exacto

## Cálculo de monto de cuota (moda)

```
1. Filtrar filas de facturas.xlsx con Abono1 > 0 (ignorar filas saldo)
2. Calcular la moda de los abonos
3. Si maxFrecuencia == 1 (todos distintos) → usar el mínimo como fallback
```

Ejemplo ID=32: abonos [220k, 220k, 550k] → moda = 220k ✓

## Filtros de importación (CONFIG.FILTROS)

```typescript
FORMA_PAGO_PERMITIDAS: ['', 'Contado', 'Crédito', 'Precio Contado', 'Precio contado'];
TIPO_CLIENTE_PERMITIDOS: ['Mensual', 'Quincenal', 'Semanal', 'Cliente Casual'];
EXCLUIR_FORMA_PAGO: ['ANULADO', 'Cancelado', 'Cancelado++', 'Clavos', 'Informconf'];
```

- Forma de pago vacía (`''`) se acepta → se trata como crédito por defecto
- `Contado` y `Precio contado` fueron quitados de EXCLUIR (contradicción anterior corregida)

## IDs de referencia (CONFIG)

Todos los UUIDs de empresa, vendedor, cobrador, producto genérico, etc. están hardcodeados
en el bloque `CONFIG` al inicio del script. Actualizar si cambia el entorno (staging → prod).

## Pendientes antes de migración masiva

- [ ] Probar 5-10 IDs variados con `--ids=` y verificar en DB (cuotas, saldos, datos del cliente)
- [ ] Revisar que `CONFIG.VENDEDOR_ID` y `CONFIG.COBRADOR_ID` sean correctos en producción
- [ ] Confirmar que el producto `GEN0001` existe en la empresa destino
- [ ] Backup de DB antes de correr masivo
- [ ] Ejecutar masivo y revisar log de errores

## Notas

- `--transpile-only` en ts-node es necesario para saltear chequeo de tipos y arrancar rápido
- El log se guarda en `scripts/migrate-access/` con timestamp en el nombre
- Si se interrumpe, se puede volver a correr — la idempotencia evita duplicados
