# Plan: Módulo Importaciones v1

**Fecha**: Abril 2026
**Perfil v1**: Autos Korea / Japón
**Perfil v2**: Consumo masivo China (base genérica incluida desde v1)
**Estado**: Definición completada — pendiente implementación

---

## Decisiones de diseño

| # | Decisión | Resolución |
|---|---|---|
| 1 | Alcance v1 | Solo perfil **AUTOS**. Base genérica para v2 sin cambios radicales. |
| 2 | Tabla de ítems | **Una sola tabla** `imp_embarque_items` con campos nullable por perfil. |
| 3 | Ubicación UI | **Página propia** "Importaciones" en el menú principal. |
| 4 | Inventario | Al cerrar despacho se crea producto en `productos` (código=chasis, stock=1, costo=calculado). |
| 5 | Escribanías | Flujo **manual desde Importaciones**. No se dispara desde Facturación. |
| 6 | Tipo de cambio | **Híbrido**: cada componente permite cotización propia (sugerida desde `cont_tipo_cambio`). Al cerrar despacho se congela la cotización de cada componente. |
| 7 | ISC vehículos | Tabla administrable desde **Configuraciones** con rangos de cilindrada y año. |
| 8 | Gastos extras | **Administración los carga** con motivo obligatorio. Quedan auditados. Sin flujo de aprobación formal. |
| 9 | Despacho parcial | **Un despacho por embarque** en v1. |
| 10 | Chapa / cédula verde | **Sub-trámites dentro de la transferencia** (checklist de etapas, no trámites separados). |
| 11 | Tesorería / CxP | **Reutilizar `cuentas_pagar`** agregando `embarque_id` FK nullable. |
| 12 | SLA escribanías | **Configurable por empresa** en el módulo Configuraciones. |
| 13 | Tabla ISC | **Administrable desde Configuraciones** (rangos cc + año → tasa %). |
| 14 | Sync estado vehículo | **Automático**: al emitir factura de venta de un chasis, `imp_embarque_items.estado` pasa a `VENDIDO`. |
| 15 | Proveedor extranjero | **Reutilizar `proveedores`** existente. Extender con campos si es necesario (país, SWIFT, banco corresponsal). |

---

## Extensiones a tablas existentes

### `proveedores`
```sql
ALTER TABLE proveedores
  ADD COLUMN IF NOT EXISTS pais VARCHAR(3),         -- ISO 3166 (KR, JP, CN, etc.)
  ADD COLUMN IF NOT EXISTS swift VARCHAR(20),
  ADD COLUMN IF NOT EXISTS banco_corresponsal VARCHAR(200),
  ADD COLUMN IF NOT EXISTS es_extranjero BOOLEAN DEFAULT false;
```

### `cuentas_pagar`
```sql
ALTER TABLE cuentas_pagar
  ADD COLUMN IF NOT EXISTS embarque_id UUID REFERENCES imp_embarques(id);

CREATE INDEX IF NOT EXISTS idx_cxp_embarque ON cuentas_pagar(embarque_id);
```

---

## Modelo de datos — tablas nuevas

### `imp_embarques` — Cabecera del expediente
```sql
CREATE TABLE imp_embarques (
  id                    UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
  empresa_id            UUID NOT NULL REFERENCES empresas(id),
  numero                VARCHAR(20) UNIQUE NOT NULL,    -- IMP-2026-000001
  perfil                VARCHAR(20) NOT NULL,           -- AUTOS | CONSUMO_MASIVO
  proveedor_id          UUID REFERENCES proveedores(id),
  origen_pais           VARCHAR(3),                     -- KR, JP, CN
  origen_puerto         VARCHAR(100),
  destino_puerto        VARCHAR(100) DEFAULT 'Villeta',
  modalidad             VARCHAR(20),                    -- RoRo, FCL20, FCL40, FCL40HQ, LCL
  booking               VARCHAR(100),
  bill_of_lading        VARCHAR(100),
  fecha_embarque        DATE,
  fecha_eta             DATE,
  fecha_arribo_real     DATE,
  cotizacion_cierre     DECIMAL(18,2),                  -- congelada al cerrar despacho
  estado                VARCHAR(30) NOT NULL DEFAULT 'BORRADOR',
  -- BORRADOR → EN_TRANSITO → ARRIBADO → EN_DESPACHO → DESPACHADO → LIBERADO → CERRADO → SELLADO
  notas                 TEXT,
  usuario_id            UUID,
  created_at            TIMESTAMP DEFAULT NOW(),
  updated_at            TIMESTAMP DEFAULT NOW()
);
```

### `imp_embarque_items` — Ítems (vehículos en v1, SKUs en v2)
```sql
CREATE TABLE imp_embarque_items (
  id                    UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
  embarque_id           UUID NOT NULL REFERENCES imp_embarques(id) ON DELETE CASCADE,
  empresa_id            UUID NOT NULL REFERENCES empresas(id),
  perfil                VARCHAR(20) NOT NULL,           -- AUTOS | CONSUMO_MASIVO

  -- ── Campos comunes ────────────────────────────────────────────
  estado                VARCHAR(30) NOT NULL DEFAULT 'PENDIENTE_EMBARQUE',
  -- Autos: PENDIENTE_EMBARQUE → EN_TRANSITO → ARRIBADO → DISPONIBLE → RESERVADO → VENDIDO → ENTREGADO
  -- Consumo masivo (v2): PENDIENTE_MAPEO → DISPONIBLE → VENDIDO
  costo_unitario_gs     DECIMAL(18,2),                  -- calculado
  producto_id           UUID REFERENCES productos(id),  -- creado al cerrar despacho
  orden                 INT DEFAULT 0,

  -- ── Campos perfil AUTOS (nullable en consumo masivo) ──────────
  chasis                VARCHAR(17) UNIQUE,
  motor                 VARCHAR(100),
  marca                 VARCHAR(100),
  modelo                VARCHAR(100),
  version               VARCHAR(100),
  anio                  INT,
  cilindrada_cc         INT,
  kilometraje           INT,
  color                 VARCHAR(50),
  subasta_lote          VARCHAR(100),
  precio_fob_usd        DECIMAL(12,2),
  inland_origen_usd     DECIMAL(10,2),
  cantidad_duenios      INT,

  -- ── Campos perfil CONSUMO_MASIVO (nullable en autos, v2) ──────
  sku_proveedor         VARCHAR(100),
  sku_interno_id        UUID REFERENCES productos(id),
  descripcion_origen    TEXT,
  cantidad              DECIMAL(12,2),
  unidad                VARCHAR(10),                    -- PCS, PAR, SET, CJ, KG
  peso_unit_kg          DECIMAL(10,4),
  cbm_unit              DECIMAL(10,4),
  fob_unit_usd          DECIMAL(12,2),
  ncm                   VARCHAR(20),
  arancel_pct           DECIMAL(5,2),
  isc_pct               DECIMAL(5,2),
  mapeo_resuelto        BOOLEAN DEFAULT false,

  created_at            TIMESTAMP DEFAULT NOW(),
  updated_at            TIMESTAMP DEFAULT NOW()
);

CREATE INDEX idx_imp_items_embarque ON imp_embarque_items(embarque_id);
CREATE INDEX idx_imp_items_chasis ON imp_embarque_items(chasis) WHERE chasis IS NOT NULL;
CREATE INDEX idx_imp_items_estado ON imp_embarque_items(estado);
```

### `imp_conceptos_costo` — Catálogo configurable de conceptos
```sql
CREATE TABLE imp_conceptos_costo (
  id                UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
  empresa_id        UUID REFERENCES empresas(id),       -- NULL = concepto del sistema
  nombre            VARCHAR(150) NOT NULL,
  grupo             VARCHAR(50),                        -- ORIGEN, TRANSITO, ADUANA, LOGISTICA, FINANCIERO
  moneda_default    VARCHAR(3) DEFAULT 'USD',           -- USD | GS
  imputacion        VARCHAR(20) DEFAULT 'COMPARTIDO',  -- DIRECTO | COMPARTIDO
  criterio_default  VARCHAR(20),                       -- FOB | PESO | CBM | CANTIDAD | IGUAL
  aplica_perfil     VARCHAR(20),                       -- AUTOS | CONSUMO_MASIVO | NULL=ambos
  activo            BOOLEAN DEFAULT true,
  es_sistema        BOOLEAN DEFAULT false,
  orden             INT DEFAULT 0,
  created_at        TIMESTAMP DEFAULT NOW()
);
```

### `imp_componentes_costo` — Líneas de costo del embarque
```sql
CREATE TABLE imp_componentes_costo (
  id                    UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
  embarque_id           UUID NOT NULL REFERENCES imp_embarques(id) ON DELETE CASCADE,
  empresa_id            UUID NOT NULL REFERENCES empresas(id),
  concepto_id           UUID REFERENCES imp_conceptos_costo(id),
  item_id               UUID REFERENCES imp_embarque_items(id), -- si es directo al ítem
  descripcion           VARCHAR(200),                  -- libre si no usa catálogo
  moneda                VARCHAR(3) NOT NULL DEFAULT 'USD',
  importe               DECIMAL(18,2) NOT NULL,
  cotizacion            DECIMAL(18,2),                 -- sugerida desde cont_tipo_cambio, editable
  importe_gs            DECIMAL(18,2),                 -- calculado = importe * cotizacion
  es_directo            BOOLEAN NOT NULL DEFAULT false,
  criterio_prorrateo    VARCHAR(20),                   -- FOB | PESO | CBM | CANTIDAD | IGUAL
  proveedor_id          UUID REFERENCES proveedores(id),
  numero_factura        VARCHAR(100),
  fecha_devengo         DATE,
  fecha_pago            DATE,
  estado                VARCHAR(20) DEFAULT 'BORRADOR', -- BORRADOR | CONFIRMADO | CONTABILIZADO
  es_posterior_cierre   BOOLEAN DEFAULT false,          -- dispara recostificación
  es_gasto_extra        BOOLEAN DEFAULT false,          -- "gastos extras de gestión"
  motivo_gasto_extra    TEXT,                           -- obligatorio si es_gasto_extra
  usuario_carga_id      UUID,
  cuenta_pagar_id       UUID REFERENCES cuentas_pagar(id), -- CxP generada
  created_at            TIMESTAMP DEFAULT NOW(),
  updated_at            TIMESTAMP DEFAULT NOW()
);

CREATE INDEX idx_imp_costos_embarque ON imp_componentes_costo(embarque_id);
CREATE INDEX idx_imp_costos_item ON imp_componentes_costo(item_id) WHERE item_id IS NOT NULL;
```

### `imp_despachos` — Datos del despacho aduanero
```sql
CREATE TABLE imp_despachos (
  id                    UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
  embarque_id           UUID NOT NULL REFERENCES imp_embarques(id),
  empresa_id            UUID NOT NULL REFERENCES empresas(id),
  numero_despacho       VARCHAR(100) NOT NULL,
  fecha_despacho        DATE NOT NULL,
  despachante_id        UUID REFERENCES proveedores(id),
  -- Liquidación impositiva
  arancel_gs            DECIMAL(18,2) DEFAULT 0,
  iva_importacion_gs    DECIMAL(18,2) DEFAULT 0,
  isc_gs                DECIMAL(18,2) DEFAULT 0,
  inc_gs                DECIMAL(18,2) DEFAULT 0,
  anticipo_ire_gs       DECIMAL(18,2) DEFAULT 0,
  tasa_ana_gs           DECIMAL(18,2) DEFAULT 0,
  total_tributos_gs     DECIMAL(18,2) DEFAULT 0,       -- calculado
  cotizacion_usada      DECIMAL(18,2),                 -- congelada al confirmar
  notas                 TEXT,
  usuario_id            UUID,
  confirmado_at         TIMESTAMP,
  created_at            TIMESTAMP DEFAULT NOW(),
  updated_at            TIMESTAMP DEFAULT NOW()
);
```

### `imp_recostificaciones` — Historial de ajustes de costo
```sql
CREATE TABLE imp_recostificaciones (
  id                  UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
  embarque_id         UUID NOT NULL REFERENCES imp_embarques(id),
  item_id             UUID REFERENCES imp_embarque_items(id),
  componente_id       UUID REFERENCES imp_componentes_costo(id),
  costo_anterior_gs   DECIMAL(18,2),
  costo_nuevo_gs      DECIMAL(18,2),
  diferencial_gs      DECIMAL(18,2),
  motivo              TEXT,
  ajuste_contable_id  UUID,                            -- FK asiento si aplica
  usuario_id          UUID,
  created_at          TIMESTAMP DEFAULT NOW()
);
```

### `imp_escribanias` — Maestro de escribanías
```sql
CREATE TABLE imp_escribanias (
  id                          UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
  empresa_id                  UUID NOT NULL REFERENCES empresas(id),
  razon_social                VARCHAR(200) NOT NULL,
  escribano_titular           VARCHAR(200),
  ruc                         VARCHAR(20),
  matricula                   VARCHAR(50),
  telefono                    VARCHAR(50),
  email                       VARCHAR(150),
  activa                      BOOLEAN DEFAULT true,
  -- Tarifario (congelado al asignar trámite)
  tarifa_transferencia_gs          DECIMAL(18,2),
  tarifa_transferencia_prenda_gs   DECIMAL(18,2),
  tarifa_primera_inscripcion_gs    DECIMAL(18,2),
  tarifa_chapa_gs                  DECIMAL(18,2),
  tarifa_cedula_verde_gs           DECIMAL(18,2),
  observaciones               TEXT,
  created_at                  TIMESTAMP DEFAULT NOW(),
  updated_at                  TIMESTAMP DEFAULT NOW()
);
```

### `imp_tramites_transferencia` — Trámites vinculados a ventas
```sql
CREATE TABLE imp_tramites_transferencia (
  id                      UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
  empresa_id              UUID NOT NULL REFERENCES empresas(id),
  item_id                 UUID NOT NULL REFERENCES imp_embarque_items(id),
  factura_venta_id        UUID REFERENCES factura_cab(id),
  cliente_id              UUID REFERENCES clientes(id),
  escribania_id           UUID REFERENCES imp_escribanias(id),
  es_escribania_adhoc     BOOLEAN DEFAULT false,       -- escribanía propuesta por el cliente
  motivo_adhoc            TEXT,
  tipo_tramite            VARCHAR(50) NOT NULL,        -- TRANSFERENCIA | TRANSFERENCIA_PRENDA | PRIMERA_INSCRIPCION
  monto_honorarios_gs     DECIMAL(18,2),               -- congelado al asignar
  -- Sub-trámites (checklist)
  fecha_asignacion        DATE,
  fecha_firma             DATE,
  fecha_inscripcion_racpr DATE,
  fecha_gestion_chapa     DATE,
  fecha_cedula_verde      DATE,
  fecha_entrega_docs      DATE,
  -- Estado general
  estado                  VARCHAR(30) DEFAULT 'ASIGNADO',
  -- ASIGNADO → EN_CURSO → FIRMADO → INSCRITO → ENTREGADO
  contrato_prendario_adj  BOOLEAN DEFAULT false,       -- requerido si TRANSFERENCIA_PRENDA
  notas                   TEXT,
  alerta_sla              BOOLEAN DEFAULT false,       -- calculado por job
  ultimo_movimiento_at    TIMESTAMP,
  usuario_id              UUID,
  created_at              TIMESTAMP DEFAULT NOW(),
  updated_at              TIMESTAMP DEFAULT NOW()
);

CREATE INDEX idx_imp_tramites_item ON imp_tramites_transferencia(item_id);
CREATE INDEX idx_imp_tramites_estado ON imp_tramites_transferencia(estado);
CREATE INDEX idx_imp_tramites_escribania ON imp_tramites_transferencia(escribania_id);
```

### `imp_isc_vehiculos` — Tabla ISC administrable desde Configuraciones
```sql
CREATE TABLE imp_isc_vehiculos (
  id              UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
  empresa_id      UUID REFERENCES empresas(id),        -- NULL = tabla del sistema
  anio_desde      INT NOT NULL,
  anio_hasta      INT NOT NULL,
  cc_desde        INT NOT NULL,
  cc_hasta        INT NOT NULL,
  tasa_isc_pct    DECIMAL(5,2) NOT NULL,
  descripcion     VARCHAR(200),
  vigente_desde   DATE NOT NULL,
  vigente_hasta   DATE,
  activo          BOOLEAN DEFAULT true,
  created_at      TIMESTAMP DEFAULT NOW()
);
```

### `imp_sku_alias_proveedor` — Memoria de mapeo SKU (v2, tabla lista desde v1)
```sql
CREATE TABLE imp_sku_alias_proveedor (
  id                UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
  empresa_id        UUID NOT NULL REFERENCES empresas(id),
  proveedor_id      UUID REFERENCES proveedores(id),
  sku_proveedor     VARCHAR(100) NOT NULL,
  descripcion_origen TEXT,
  producto_id       UUID NOT NULL REFERENCES productos(id),
  confirmado        BOOLEAN DEFAULT true,
  created_at        TIMESTAMP DEFAULT NOW(),
  UNIQUE(empresa_id, proveedor_id, sku_proveedor)
);
```

---

## Estados del embarque

```
BORRADOR → EN_TRANSITO → ARRIBADO → EN_DESPACHO → DESPACHADO → LIBERADO → CERRADO → SELLADO
```

## Estados del ítem (vehículo)

```
PENDIENTE_EMBARQUE → EN_TRANSITO → ARRIBADO → DISPONIBLE → RESERVADO → VENDIDO → ENTREGADO
```

---

## Integraciones con módulos existentes

| Módulo | Integración | Trigger |
|---|---|---|
| `productos` | Crear producto (chasis) al liberar despacho | `estado = LIBERADO` |
| `productos` | Actualizar costo del producto si hay recostificación | `imp_recostificaciones` |
| `cuentas_pagar` | Generar CxP por componente de costo pagable | Manual desde componente |
| `cont_tipo_cambio` | Sugerir cotización al cargar componente USD | Al seleccionar moneda USD |
| `ContabilidadIntegracionService` | Asiento al cerrar despacho | `estado = DESPACHADO` |
| `factura_cab` | Detectar venta de chasis → actualizar estado ítem a VENDIDO | Al confirmar factura |
| `Configuraciones` | Tabla ISC, SLA escribanías | Administrable por empresa |

---

## Algoritmo de costeo

Para cada ítem `i`:

```
Cu_i [Gs.] = Σ(costos_directos_i × cotizacion) + Σ(costo_compartido_k × cotizacion_k × f_i_k)

Donde f_i_k = Base_i / ΣBase  (según criterio: FOB, PESO, CBM, CANTIDAD, IGUAL)
```

El cálculo se ejecuta en memoria en tiempo real y se persiste en `imp_embarque_items.costo_unitario_gs` al cerrar el despacho.

---

## Fases de implementación

### Fase 1 — Base del módulo (semanas 1-3)
- Migraciones SQL y schema Prisma
- `ImportacionesModule` en AppModule
- CRUD embarques (cabecera + estado + bitácora)
- CRUD ítems perfil AUTOS (chasis, datos técnicos)
- Catálogo de conceptos de costo (seed inicial)
- CRUD componentes de costo con cotización
- Cálculo de costo unitario en tiempo real
- UI: página Importaciones + lista embarques + detalle con tabs

### Fase 2 — Despacho y contabilidad (semanas 4-5)
- CRUD despacho aduanero con liquidación impositiva
- Tabla ISC administrable desde Configuraciones
- Cierre de despacho → crear producto en `productos`
- Integración contable (`ContabilidadIntegracionService`)
- Generación de CxP en `cuentas_pagar` desde componentes
- Gastos extras de gestión con motivo obligatorio

### Fase 3 — Escribanías y ventas (semanas 6-7)
- CRUD maestro de escribanías con tarifario
- CRUD trámites de transferencia (checklist sub-trámites)
- SLA configurable + job de alerta
- Sync automático: factura emitida → ítem VENDIDO
- Panel de trámites con semáforo de SLA

### Fase 4 — Reportes y ajustes (semana 8)
- Reporte liquidación de embarque (PDF + XLSX)
- Recostificación: gasto posterior al cierre → historial + ajuste
- Sellado de embarque con permiso `IMP_SELLAR_COSTO`
- Dashboard: embarques por estado, costo promedio, gastos extras % FOB
- Piloto con cliente real

---

## Permisos del módulo

| Código | Descripción |
|---|---|
| `IMP_VER` | Ver embarques, ítems, costos |
| `IMP_CREAR_EMBARQUE` | Crear embarques e ítems |
| `IMP_EDITAR_EMBARQUE` | Editar cabecera e ítems |
| `IMP_CERRAR_DESPACHO` | Confirmar despacho y disparar cierre |
| `IMP_GESTIONAR_COSTOS` | Crear/editar componentes de costo |
| `IMP_GESTIONAR_ESCRIBANIAS` | Crear escribanías y trámites |
| `IMP_SELLAR_COSTO` | Sellar/desbloquear embarque cerrado |
| `IMP_VER_REPORTES` | Ver reportes del módulo |
| `IMP_CONFIG` | Configurar ISC, SLA y conceptos |

---

## Preguntas abiertas resueltas

| Q | Pregunta | Resolución |
|---|---|---|
| Q-02 | ¿ISC según tabla SET o manual? | Tabla administrable desde Configuraciones |
| Q-03 | ¿Tipo de cambio para IVA: despacho o pago? | Híbrido: cotización por componente, congelada al cierre |
| Q-05 | ¿Chapa como trámite independiente o sub-trámite? | Sub-trámite (checklist dentro de transferencia) |
| Q-06 | ¿Quién autoriza gastos extras? | Administración los carga, sin aprobación formal |
| Q-07 | ¿Despacho parcial en v1? | No, un despacho por embarque |

## Preguntas aún abiertas (definir con cliente)

| Q | Pregunta | Bloqueante |
|---|---|---|
| Q-01 | ¿Costo específico por chasis o promedio ponderado para inventario? | Sí |
| Q-04 | ¿Multi-moneda EUR en el futuro? | No |
| Q-08 | ¿Múltiples proveedores por SKU en v2? | No |

---

## Fuera de alcance v1

- Integración con Sofia / MIC / DTA
- Parser automático de PDF del despachante
- Tracking marítimo en tiempo real (AIS)
- Subastas Korea/Japón en vivo
- Firma digital con escribanía
- Marketplace de vehículos
- Perfil consumo masivo (v2)
