# WMS — Pendientes del refactor + rescatables del módulo previo

> **Estado:** 2026-05-16 — **9 sesiones R-1 a R-9 cerradas en una sola pasada**. Ver detalle en [PLAN_EJECUCION.md](PLAN_EJECUCION.md#rescate--9-sesiones-r-1-a-r-9-cerradas-2026-05-16). Lo que sigue en este doc es **referencia histórica**; el estado vigente de cada ítem está marcado con ✅ / ⏭️ / 🔄 abajo.
>
> **Estado original (pre-rescate):** documento vivo, abierto el 2026-05-16 al cierre del refactor (Bloque A + B + C).
>
> **Propósito:** consolidar en un solo lugar (a) lo que el refactor dejó sin terminar y (b) lo que se borró antes del refactor cuya reincorporación amerita evaluación. Cada ítem tiene una recomendación de **factibilidad** y **prioridad**.
>
> **Convención:**
> - 🔴 Alta prioridad — bloquea uso real del módulo.
> - 🟡 Media prioridad — mejora UX o cubre casos de uso reales pero no bloquea.
> - 🟢 Baja prioridad — nice-to-have, postergable.

---

## Índice

- [1. Pendientes del refactor (no se hicieron, pero estaban planificados)](#1-pendientes-del-refactor)
- [2. Backend borrado que vale la pena rescatar](#2-backend-borrado-que-vale-la-pena-rescatar)
- [3. Frontend borrado que vale la pena rescatar](#3-frontend-borrado-que-vale-la-pena-rescatar)
- [4. Backend/Frontend borrado que NO conviene rescatar](#4-borrado-que-no-conviene-rescatar)
- [5. Plan de rescate sugerido (priorizado)](#5-plan-de-rescate-sugerido)

---

## 1. Pendientes del refactor

Cosas mencionadas en sesiones previas que quedaron documentadas pero no implementadas. Están listadas también en `docs/wms/PLAN_EJECUCION.md` al cierre de B-5b/5c/C.

### 1.1 Integración con `PosVentaController` y `PosCompraController` 🔴 ✅ R-3

**Qué:** el `PosInventarioObserver` ya está restaurado y crea `WmsTarea pick_list`/`put_list` cuando llega un `pos_inventarios` con `requiere_gestion_wms=true`. **Falta verificar** que los controllers POS estén creando esos `pos_inventarios` con la columna `wms_movimiento_id=null` al cerrar venta/compra (porque si viene no-null, el observer no dispara — protección contra loops).

**Factibilidad:** alta — solo es agregar/revisar 2-3 líneas en cada controller.

**Pendiente concreto:**
- Leer `PosVentaController::ejecutar` (o el método donde se crea `pos_inventarios` en la venta) y confirmar que el flag se setea correcto.
- Idem `PosCompraController::ejecutar`.
- Test E2E manual: crear venta de un artículo con `requiere_gestion_wms=true` y verificar que aparece tarea pendiente en `/pos/wms/operaciones/tareas`.

### 1.2 Validación cruzada de `lote` para método contable "Identificación específica" 🟡 ⏭️ Diferido

**Qué:** cuando `par_empresas.metodo_inventario_id = 4`, la venta exige `lote_id`. Hoy el sistema NO valida que ese `lote_id` exista físicamente en `wms_ubicacion_stocks` con stock disponible. Pueden divergir el lote contable (FIFO/LIFO/PMP no lo exigen) y el lote físico.

**Factibilidad:** media — agregar validación en `WmsTareaController::completarLinea` o pre-validación en venta.

**Acción:** rechazar (o avisar) al completar línea si `lote != null` y `wms_ubicacion_stocks.lote` no coincide.

### 1.3 Autoconfiguración de `wms_regla_slottings.estrategia` 🟢 ✅ R-8

**Qué:** al crear una `wms_regla_slottings` nueva, sugerir un default según `par_empresas.metodo_inventario_id` de la empresa de la bodega. Pseudo-código documentado en `docs/wms/RELACION_SLOTTING_CONTABILIDAD.md`.

**Factibilidad:** baja complejidad — modificar `WmsReglaSlottingController::store`.

### 1.4 Reporte de costo contable vs costo físico 🟢 ⏭️ Diferido

**Qué:** dashboard que muestre diferencias entre `pos_inventarios.c_unitario` (calculado por `InventoryCostService` según método contable) y el `costo_unitario` de `wms_ubicacion_stocks` realmente tocado al completar la tarea. Permite auditar el "match" entre libros y operación.

**Factibilidad:** media — endpoint nuevo + tabla en UI.

### 1.5 Niveles/divisiones/subdivisiones manualmente desde la UI 🟡 ✅ R-5 (parcial — niveles sí, subdivisiones no)

**Qué:** hoy crear un rack genera N niveles + N ubicaciones (1 por nivel, sin divisiones). Para racks tipo drive-in o push-back que necesitan múltiples posiciones por nivel, no hay UI para subdividir.

**Factibilidad:** media — vista lateral del rack + endpoint adicional `POST /wmsRackNiveles/{id}/subdividir`.

### 1.6 PUT snapshot endpoint `/wmsBodegaLayouts/{id}/dibujo` 🟢 ✅ R-9

**Qué:** GET ya existe (lee todo el dibujo en una request). PUT permitiría editar el dibujo entero en una transacción, útil para "deshacer cambios masivos" o "importar layout desde JSON". Hoy cada acción es un POST/PUT/DELETE individual.

**Factibilidad:** alta complejidad — diff entre estado actual y nuevo, upsert/delete por tipo de entidad. No urgente.

### 1.7 Validación del editor en navegador 🔴 🔄 Pendiente

**Qué:** durante toda la sesión NO se probó el editor en navegador. Solo lint + smoke tests via tinker. Falta validación humana real del flujo completo en `/pos/wms/layout/{bodegaId}` y `/pos/wms/operaciones/tareas`.

**Pendiente:** el usuario lo está revisando ahora.

---

## 2. Backend borrado que vale la pena rescatar

### 2.1 `WmsReporteController.php` (Reportes ocupación / rotación / vencimientos) 🔴 ✅ R-1

**Estado original:** borrado en el commit `44ceee2` del refactor. Apuntaba al modelo viejo (`wms_zonas`, `wms_racks` viejos).

**Por qué rescatar:** son 3 reportes operativos clave para un WMS productivo:
- **Ocupación**: % usado por rack / nivel / zona (peso y unidades).
- **Rotación**: top SKUs por unidades despachadas en un rango.
- **Próximos vencimientos**: lotes que vencen en N días.

Los datos siguen disponibles — solo hay que refactorizar las queries al nuevo modelo (las tablas `wms_racks`, `wms_rack_niveles`, `wms_ubicaciones`, `wms_ubicacion_stocks`, `wms_movimientos`, `wms_clasificacion_abcs` existen).

**Factibilidad:** media. ~150 líneas en el controller (lo borrado tenía ~320). Las queries son similares; cambios: `wms_movimientos.tipo = 'picking'` en vez del enum viejo, los rack tienen ahora `wms_habitacion_id`/`wms_zona_id` opcionales.

**Acción concreta:**
1. Recuperar el archivo con `git show 6460c2f:app/Http/Controllers/Wms/WmsReporteController.php > app/Http/Controllers/Wms/WmsReporteController.php` (referencia: commit antes del reset).
2. Ajustar queries al nuevo modelo.
3. Re-registrar rutas en `routes/api.php`.
4. Crear páginas en frontend (ver 3.3).

### 2.2 `ReconcileStockCommand.php` (`wms:reconcile`) 🟡 ✅ R-4 (sin `--fix`)

**Estado original:** borrado.

**Por qué rescatar:** verifica la invariante crítica documentada en el plan: `SUM(wms_ubicacion_stocks.stock_unidades por bodega+artículo) = pos_bodega_articulos.stock`. Permite detectar divergencias entre contabilidad de stock POS y operación WMS. Indispensable como sanity check periódico.

**Factibilidad:** media. El comando original tenía lógica para crear ubicaciones AJUSTE si encontraba diferencias — se puede simplificar a "solo reporta, no toca".

**Acción:** recuperar y limpiar lógica de auto-corrección; dejar solo el reporte.

### 2.3 `WmsUbicacionStockController.php` (ajustes manuales de stock) 🟡 ✅ R-4

**Estado original:** borrado.

**Por qué rescatar:** un caso real en almacenes es el "ajuste manual" — un operario encuentra que físicamente hay 5 unidades pero el sistema dice 7. Necesita poder ajustar la ubicación sin pasar por una tarea (que requiere pos_inventario).

**Factibilidad:** baja complejidad. CRUD simple sobre `wms_ubicacion_stocks` con `WmsMovimiento tipo=ajuste` registrando el delta.

**Acción:** restaurar con cambios mínimos + rutas + crear movimiento de auditoría en cada update.

### 2.4 `WmsRackNivelController.php` (editar nivel específico) 🟢 ✅ R-5

**Estado original:** borrado.

**Por qué rescatar:** permite editar `capacidad_kg`, `tipo_almacen`, `divisiones` de un nivel concreto sin regenerar el rack entero. Hoy todos los niveles se generan iguales por `WmsRackController::store`.

**Factibilidad:** baja. CRUD limitado a update.

### 2.5 `WmsSlottingController::sugerencia` y `::recalcularAbc` 🟢 ✅ R-8

**Estado original:** borrado.

**Por qué rescatar:**
- `/wmsSlotting/sugerencia?articulo_id=X&bodega_id=Y&cantidad=N` — útil para preview UI antes de confirmar venta ("¿de dónde va a salir si vendo esto?").
- `/wmsSlotting/recalcularAbc` — dispara el `RecalcularAbcJob` manualmente (el job ya existe y corre semanal).

**Factibilidad:** baja. ~30 líneas envolviendo `WmsSlottingService` y disparando el job.

### 2.6 `WmsCapacidadService.php` (cálculo de capacidad) 🟢 ⏭️ Diferido (no necesario tras adaptación de R-1 y R-4)

**Estado original:** borrado.

**Por qué rescatar:** cálculos de capacidad usados por los reportes de ocupación. Si se rescata `WmsReporteController`, puede que tenga sentido también.

**Factibilidad:** media — la lógica original calcula peso ocupado vs capacidad. Puede inlinear-se en `WmsReporteController` o quedar separado.

---

## 3. Frontend borrado que vale la pena rescatar

### 3.1 `RackElevation.vue` + `pages/pos/wms/racks/[id]/elevacion.vue` 🔴 ✅ R-2

**Estado original:** borrados.

**Por qué rescatar:** vista lateral del rack (de frente) mostrando los niveles apilados. Indispensable para visualizar capacidad por nivel y subdivisiones. La vista 2D top-down no comunica la dimensión vertical.

**Factibilidad:** media. ~200 líneas Konva en el componente original. Adaptarlo al nuevo modelo (los niveles ahora vienen del snapshot endpoint).

**Acción:**
1. Recuperar `RackElevation.vue` con `git show 6460c2f:components/wms/canvas/RackElevation.vue` (en `aconta/`).
2. Refactor del componente para consumir el modelo nuevo (rack.niveles con sus ubicaciones).
3. Crear página `/pos/wms/racks/[id]/elevacion.vue`.
4. Agregar link en el modal info del rack (en el editor) → "Ver vista lateral".

### 3.2 `pages/pos/wms/racks/index.vue` (listado de racks) 🟡 ✅ R-5

**Estado original:** borrado.

**Por qué rescatar:** una vista de tabla de todos los racks con filtros (bodega/zona/material/tipo), búsqueda y acceso rápido a elevación o edición. Hoy los racks solo se ven desde el editor.

**Factibilidad:** baja. Página estándar de listado.

### 3.3 `pages/pos/wms/reportes/{ocupacion,rotacion,vencimientos}.vue` 🔴 ✅ R-1

**Estado:** las 3 borradas.

**Por qué rescatar:** son páginas operativas. Sin reportes el módulo es un editor sin retorno operativo visible.

**Factibilidad:** media. Cada una ~100-150 líneas. Depende de que `WmsReporteController` esté restaurado (ver 2.1).

### 3.4 `ScannerQR.vue` 🟡 ✅ R-6

**Estado original:** borrado.

**Por qué rescatar:** componente para escanear códigos QR/barras desde la cámara del operario móvil al completar picking/putaway. Acelera el flujo en almacén real.

**Factibilidad:** media. El componente usa una librería de QR (verificar cuál). Se integraría en el modal de "completar línea" en `tareas.vue`.

### 3.5 `PanelOcupacion.vue` + `PanelArticulosDisponibles.vue` 🟢 ✅ R-9 (PanelArticulos no montado)

**Estado original:** borrados.

**Por qué rescatar:**
- **PanelOcupacion**: muestra % ocupación en tiempo real mientras editas el layout. Útil para detectar racks vacíos o sobrecargados.
- **PanelArticulosDisponibles**: lista de artículos sin ubicar (recibidos pero no put-away). Útil para arrastrar visualmente al canvas.

**Factibilidad:** media. Reincorporar como panels colapsables en el editor.

### 3.6 `pages/pos/wms/operaciones/conteo.vue` (conteo cíclico) 🟢 ✅ R-7

**Estado original:** borrado.

**Por qué rescatar:** el conteo cíclico es un proceso periódico donde el operario verifica unidades físicas vs sistema. El enum `wms_tareas.tipo` ya soporta `conteo`. Hoy `tareas.vue` no diferencia el manejo de conteo vs pick/put — al completar línea sólo descuenta o agrega.

**Factibilidad:** media. Requiere lógica nueva: comparar `unidades_realizadas` (lo contado) vs `unidades_solicitadas` (lo esperado), crear `WmsMovimiento tipo=ajuste` por el delta.

### 3.7 `pages/pos/wms/pisos/index.vue` (CRUD de pisos) 🟢 ✅ R-8

**Estado original:** borrado.

**Por qué rescatar:** layouts multi-piso necesitan administración de pisos (crear, eliminar, renumerar). Hoy solo se pueden ver/crear desde el editor (no implementado en el MVP del editor) o vía API directamente.

**Factibilidad:** baja. CRUD simple.

---

## 4. Borrado que NO conviene rescatar

Lista de archivos cuya función está completamente cubierta por el refactor o no aplica al modelo nuevo. **No rescatar.**

### Backend
- `MigrateUbicacionesCommand.php` — la tabla `pos_bodega_articulo_ubicaciones` ya no existe.
- `WmsLayoutService.php` — lógica del editor viejo, reemplazado por composables `useCadDraw`/`useCadSnap`.
- `WmsMovimientoService.php` — la lógica relevante ya vive en `WmsTareaController::completarLinea` (descuenta stock + crea movimiento).
- Migrations viejas — reemplazadas por el set `2026_05_16_*`.

### Frontend
- `LayoutTopDown.vue`, `HabitacionRect.vue`, `ZonaPolygon.vue`, `RackShape.vue`, `RackForm.vue`, `ToolbarLayout.vue`, `GridBackground.vue` — reemplazados por la familia `cad/*` y la toolbar del editor nuevo.
- `RackPropuesto.vue` — era para "modo asistido" (heurística automática de layout). Es feature avanzado, no rescatar hasta que el resto del editor esté completo.
- `composables/useWmsCanvas.ts` — reemplazado por `useCadDraw` + `useCadSnap`.
- `pages/pos/wms/zonas/index.vue` — las zonas ya se gestionan dentro del editor (modo `add-zone`).
- `pages/pos/wms/operaciones/picking.vue` y `putaway.vue` — consolidados en `tareas.vue`.

---

## 5. Plan de rescate sugerido

Ordenado por prioridad y dependencias. Cada bloque es una sesión independiente.

### Sesión R-1: Reportes (🔴 alta) — 1 sesión

**Entrega:**
1. Restaurar `WmsReporteController` con queries adaptadas al modelo nuevo.
2. Restaurar las 3 páginas: `pages/pos/wms/reportes/{ocupacion,rotacion,vencimientos}.vue` adaptadas.
3. Registrar rutas en `routes/api.php` y en el aside (`menuOptions.js` + seeder).
4. Agregar las 3 entradas a `WmsMenusSeeder`.

**Dependencia:** ninguna. Datos en BD ya existen.

### Sesión R-2: Vista de elevación del rack (🔴 alta) — 0.5 sesión

**Entrega:**
1. Restaurar `RackElevation.vue` adaptado al modelo nuevo.
2. Crear `pages/pos/wms/racks/[id]/elevacion.vue`.
3. Link en el modal info del rack (en el editor).

### Sesión R-3: Integración POS↔WMS (🔴 alta) — 1 sesión

**Entrega:**
1. Verificar que `PosVentaController` y `PosCompraController` crean `pos_inventarios` con flags correctos para disparar el observer.
2. Test E2E en navegador: vender un artículo con `requiere_gestion_wms=true`, ver tarea creada, completar línea, verificar stock descontado y movimiento creado.
3. Si hay bugs, arreglarlos.

**Dependencia:** validación humana del editor primero.

### Sesión R-4: Ajustes manuales + Reconcile (🟡 media) — 0.5 sesión

**Entrega:**
1. Restaurar `WmsUbicacionStockController` con creación de movimiento de auditoría tipo `ajuste`.
2. Restaurar `ReconcileStockCommand` simplificado (solo reporta, no auto-corrige).
3. Crear página simple `/pos/wms/operaciones/ajustes-stock` (o agregar acción en `tareas.vue`).

### Sesión R-5: Listado de racks + CRUD niveles (🟡 media) — 0.5 sesión

**Entrega:**
1. Restaurar `pages/pos/wms/racks/index.vue`.
2. Restaurar `WmsRackNivelController` (PUT para editar capacidad/divisiones de un nivel).
3. Link en `tareas.vue` o en el modal de rack para editar nivel.

### Sesión R-6: ScannerQR + flujo móvil (🟡 media) — 1 sesión

**Entrega:**
1. Restaurar `ScannerQR.vue` y verificar lib usada.
2. Integrar en modal de "completar línea" de `tareas.vue`.
3. Test en navegador mobile.

### Sesión R-7: Conteo cíclico (🟢 baja) — 1 sesión

**Entrega:**
1. Lógica de tarea tipo `conteo` en `WmsTareaController::completarLinea` (genera ajuste si delta).
2. Página `pages/pos/wms/operaciones/conteo.vue` para crear tareas de conteo masivas.

### Sesión R-8: CRUD pisos + endpoint sugerencia + autoconfig slotting (🟢 baja) — 0.5 sesión

**Entrega:**
1. Restaurar `pages/pos/wms/pisos/index.vue`.
2. Restaurar `WmsSlottingController::sugerencia` y `::recalcularAbc`.
3. Autoconfig en `WmsReglaSlottingController::store`.

### Sesión R-9: PUT snapshot endpoint + Panels en editor (🟢 baja) — 1 sesión

**Entrega:**
1. `PUT /wmsBodegaLayouts/{id}/dibujo` con diff/upsert/delete transaccional.
2. `PanelOcupacion.vue` y `PanelArticulosDisponibles.vue` reincorporados al editor.

---

## Resumen rápido

| # | Sesión | Prioridad | Estado | Notas |
|---|---|---|---|---|
| R-1 | Reportes | 🔴 | ✅ Cerrado 2026-05-16 | 3 endpoints + 3 páginas + exporter |
| R-2 | Elevación rack | 🔴 | ✅ Cerrado 2026-05-16 | Vista simplificada; drag-drop quedó fuera (vive en R-9 si se reincorpora) |
| R-3 | Integración POS | 🔴 | ✅ Cerrado 2026-05-16 | Sin edits en POS — el código ya estaba alineado; quedó comando `wms:verificar-integracion` para diagnóstico |
| R-4 | Ajustes + Reconcile | 🟡 | ✅ Cerrado 2026-05-16 | Reconcile sin `--fix` (decisión: enmascaraba inconsistencias) |
| R-5 | Lista racks + niveles | 🟡 | ✅ Cerrado 2026-05-16 | Modal editor de niveles; sin crear nuevo nivel (eso pasa por `WmsRackController::update`) |
| R-6 | ScannerQR | 🟡 | ✅ Cerrado 2026-05-16 | Overlay sobre Swal en tareas.vue |
| R-7 | Conteo cíclico | 🟢 | ✅ Cerrado 2026-05-16 | Switch en `completarLinea` + página dedicada |
| R-8 | Pisos + slotting | 🟢 | ✅ Cerrado 2026-05-16 | Autoconfig de estrategia según `metodo_inventario_id` |
| R-9 | Snapshot PUT + panels | 🟢 | ✅ Cerrado 2026-05-16 | PUT con diff/upsert/delete + bump version; PanelArticulos no montado |

**Total real:** 9 sub-ramas mergeadas a `feature/wms-refactor` en una sola sesión (`wms-rescate-R1`..`R9`).

### Pendiente real post-rescate

Quedan fuera del scope del rescate (mencionados como futuro en R-1..R-9):

1. **Validación cruzada de lote para método contable ID específica** (1.2): no implementado — requiere reglas adicionales en `WmsTareaController::completarLinea`.
2. **Reporte costo contable vs costo físico** (1.4): no implementado — endpoint + UI nuevos.
3. **Drag-drop de artículos desde `PanelArticulosDisponibles` al canvas**: componente restaurado pero no montado — el flujo operativo va por R-7 (conteo) + R-4 (ajustes manuales).
4. **Validación en navegador**: el usuario no validó el editor antes del rescate; todas las verificaciones del rescate son lint + smoke vía tinker. Probar `/pos/wms/{reportes,operaciones,racks,pisos}/*` en navegador para confirmar UI.

### Próximos pasos sugeridos

1. Validar en navegador las 9 sesiones del rescate (especialmente R-2 elevación, R-7 conteo, R-9 PUT del editor).
2. Si todo OK, push de `feature/wms-refactor` y merge a `feature/wms`.
3. Decidir si seguir con los 4 ítems pendientes o iniciar nuevo ciclo de feedback con usuarios reales.
