# Plan — Artículos: empaques en editor + compatibilidades por catálogo

**Fecha**: 2026-05-21
**Rama propuesta**: `feature/articulos-empaques-compat` (parte desde `feature/wms-refactor` en ambos repos: `api-a-conta` y `aconta`).
**Sin push, sin merge a develop/main hasta cerrar A-5.**

## Motivación

Dos cambios pedidos por el usuario sobre el módulo de Artículos (`pages/pos/inventario/articulos/index.vue`):

1. **Empaques en el editor de artículo**: hoy los empaques (`wms_articulo_empaques`) solo se gestionan desde el módulo standalone `pages/pos/wms/empaques/index.vue`, que pide elegir artículo del dropdown — fricción cuando el flujo natural es "creo artículo → configuro su empaque". Hay que poder crear y editar empaques desde el propio editor de artículo. **El módulo standalone se mantiene sin cambios visuales** — solo se agrega un segundo punto de entrada.

2. **Compatibilidades con catálogo**: al marcar un modelo del catálogo en "Modelos por marca", hoy se heredan del catálogo años, VIN, versión, motor y combustible. El usuario quiere que los **años queden vacíos** para indicarlos manualmente, conservando el resto del comportamiento.

## Alcance — qué entra

### Cambio 1 — Empaques en editor de artículo

- Nueva pestaña **"Empaques"** en el editor de artículo, visible **siempre desde el inicio** (no oculta tras `es_repuesto`, a diferencia de Códigos / Compatibilidades / Imágenes).
- La pestaña aplica para `tipo = simple` y `tipo = pack` — muestra 4 cards (primario, interno, caja, pallet) con resumen o botón "Configurar".
- Cuando `tipo = variante`, la pestaña **no se muestra**. En su lugar, en la tabla de variedades del tab General (columnas Presentación, SKU, Codebar, Precio venta, Stock mínimo + botón `+`), cada fila lleva un botón "Empaque" al lado del `+` que abre el modal de empaques apuntando al `pos_articulo_id` de esa variante.
- Componente compartido `components/wms/EmpaqueForm.vue` reutilizado por:
  - Módulo standalone existente.
  - Pestaña Empaques (simple/pack).
  - Modal por variante (tab General de un artículo padre `variante`).

### Cambio 2 — Compatibilidades, años vacíos en catálogo

- Modificar `armarCompatDesdeCatalogo()` (línea 1177-1193 de `pages/pos/inventario/articulos/index.vue`): forzar `anio_desde: null, anio_hasta: null`. Resto del campos (VIN, versión, motor, combustible) sigue heredando del catálogo igual que hoy.
- **No tocar** el form "agregar nueva compatibilidad" (`compatNueva`), ni `agregarCompatibilidadRepuesto()`, ni `editarCompatModelo()`.
- Tabla de "Modelos por marca" ya muestra `-` cuando los años son null, así que no hay cambio de template.

## Alcance — qué NO entra

- **Backend sin cambios estructurales**. `WmsArticuloEmpaqueController` ya cubre los casos (cada empaque vive contra un `pos_articulo_id`, sea artículo simple, pack o variante hija).
- No se valida nada nuevo sobre compatibilidades sin años/VIN — se mantiene el comportamiento actual de aceptar la compat si tiene al menos uno de modelo/VIN/año.
- No se refactoriza el módulo standalone de empaques más allá de empezar a consumir el componente compartido.
- No se tocan migraciones.

## Decisiones de diseño no obvias

- **Empaques se guardan vía endpoints existentes** (`POST/PUT /wmsArticuloEmpaques`), no como parte del payload de `PosArticuloController::update`. Razones: (1) reusa endpoint sin tocar backend, (2) evita inflar payload del artículo, (3) cada empaque es independiente — guardar uno no debería depender de guardar el artículo entero.
- **Pestaña Empaques se deshabilita cuando el artículo aún no tiene `id`** (modo "nuevo" sin guardar). Mensaje claro: "guarda el artículo primero para configurar empaques".
- **Modal por variante** se habilita solo cuando la variante ya está persistida (tiene `id`). Si la variante es nueva sin guardar, el botón "Empaque" queda deshabilitado.
- **Cambio mínimo en compatibilidades**: solo `armarCompatDesdeCatalogo` (2 líneas). Pedido explícito del usuario de no tocar el resto.

## Sesiones

| S | Tema | Alcance | Riesgo |
|---|---|---|---|
| **A-1** | Extraer `EmpaqueForm.vue` | Sacar el modal del form de `pages/pos/wms/empaques/index.vue` a `components/wms/EmpaqueForm.vue` con props `pos_articulo_id` (req), `tipo` (opc, pre-selecciona y bloquea), `empaque` (opc, modo edición). Standalone empieza a consumirlo. Sin cambio visual para el usuario. | Bajo — refactor puro |
| **A-2** | Pestaña Empaques en editor (simple + pack) | Nueva pestaña visible siempre, junto a "General". Render condicional: 4 cards solo si `tipo='simple' \|\| tipo='pack'`. Para variantes, mensaje "configura el empaque en la tabla de variedades del tab General". GET inicial al endpoint por `pos_articulo_id`. Click en card → modal `EmpaqueForm`. Deshabilitada (con mensaje) cuando el artículo no tiene `id`. | Medio — nueva UI |
| **A-3** | Modal de empaque por variante | En la tabla de variedades del tab General, agregar botón "Empaque" en cada fila al lado del `+`. Modal con 4 cards usando `EmpaqueForm`. Solo se habilita cuando la variante tiene `id` persistido. | Medio — requiere coordinar guardado de variantes para que tengan id antes del modal |
| **A-4** | Compatibilidades — años vacíos al heredar de catálogo | Modificar `armarCompatDesdeCatalogo` (línea 1183-1184) → `anio_desde: null, anio_hasta: null`. Smoke: marcar modelo del catálogo, verificar que años quedan `-` en la tabla; editarlos manualmente sigue funcionando. | Bajo — 2 líneas |
| **A-5** | Validación en navegador (responsabilidad del user) | Checklist al pie de este doc. | Bajo |

Cada sesión se hace como sub-rama `feature/articulos-{tema}` → merge `--no-ff` a `feature/articulos-empaques-compat`. Sub-ramas se borran tras merge.

**Orden**: A-1 primero (habilita A-2 y A-3). A-4 independiente. A-5 al cierre.

## Checklist S-A5 (validación en navegador)

- [ ] Editor de artículo `tipo='simple'`: pestaña Empaques visible. Configurar empaque primario → guardar → recargar página → verificar que persiste.
- [ ] Mismo flujo en `tipo='pack'`.
- [ ] Editor de artículo `tipo='variante'`: pestaña Empaques NO visible. En tab General → tabla de variedades → botón Empaque por fila → configurar empaque primario en una variante → guardar → verificar que persiste solo en esa variante.
- [ ] Editor de artículo con artículo nuevo sin guardar: pestaña Empaques aparece pero deshabilitada con mensaje claro.
- [ ] Módulo standalone `pages/pos/wms/empaques/index.vue` sigue funcionando idéntico (lista, crear, editar, eliminar).
- [ ] Compatibilidades: en "Modelos por marca" marcar un modelo cuyo catálogo tenga años (ej. Toyota Corolla 2010-2015). Verificar que en la tabla de modelos los años quedan `-` (no se heredaron). VIN del catálogo sí aparece.
- [ ] Editar ese modelo desde el botón "Editar" → poner años manualmente → guardar artículo → verificar persistencia.
- [ ] Form "agregar nueva compatibilidad" sigue comportándose igual que antes (año desde/hasta vacíos al inicio, VIN editable).

## Estado git al cierre (se llena al cerrar A-5)

_Pendiente._
