Plan de Pruebas — E5: Pago con documentos (stepper visual)
Fecha: 2026-09-11 Alcance: doc/plans/2026-09-11-stepper-documentos-pago-y-validacion.md — stepper visual en DocumentacionPago.vue + validación de subida/preview de los 9 tipos de documento. Ambiente: Dev local (./start-dev.sh) — http://localhost:5173
Antes de empezar
La base trae, entre otras, dos transacciones PAID fijas de prueba: MTCN 0000000001 (José Ramírez, PDV GT-CAP-001) y MTCN 0000000002 (Ana Toledo, PDV GT-QUE-002). Este plan las usa tal cual vienen del seed — no hace falta ningún dato extra.
docker compose exec backend php artisan migrate --seedUsuarios de prueba
| Password | Rol | Alcance | |
|---|---|---|---|
backoffice@cislatam.test | Backoffice123! | Backoffice | Solo GT-CAP-001 |
supervisor@cislatam.test | Super123! | Supervisor | GT-CAP-001 + GT-QUE-002 |
admin@cislatam.test | Admin123! | Admin | Guatemala, todos los PDVs |
1. Base en verde antes de tocar nada
| # | Paso | Resultado esperado |
|---|---|---|
| 1.1 | Correr docker compose exec backend php artisan test (o el filtro --filter=TransactionDocumentApiTest) | Los 12 tests de TransactionDocumentApiTest pasan, y la suite completa de backend (287 tests) también |
| 1.2 | Correr docker compose exec frontend npm run test | Los 51 tests de frontend pasan (incluye PagoView.spec.ts, que renderiza DocumentacionPago) |
| 1.3 | Correr docker compose exec frontend npm run build | Compila sin errores de TypeScript (vue-tsc -b) |
2. El stepper visual — no bloqueante
| # | Paso | Resultado esperado |
|---|---|---|
| 2.1 | Como Backoffice, buscar 0000000001 (PAID, tu PDV) | Se ve el formulario "Datos del pago" y, debajo, "Documentación del pago" como una secuencia de círculos numerados 1, 2, 3... conectados por una línea vertical neutra — no una lista plana de casilleros |
| 2.2 | Mirar los círculos de un documento ya subido vs. uno pendiente y obligatorio vs. la selfie sin subir | Subido: círculo verde con tilde. Pendiente y obligatorio: círculo con borde de alerta y el número. Selfie sin subir: círculo con borde neutro y el número — nunca de alerta |
| 2.3 | Subir los documentos fuera de orden (ej. el 5° antes que el 1°) | Sube sin problema — ningún paso bloquea a otro |
| 2.4 | Con documentos faltantes, mirar si hay algún botón "Siguiente" o similar deshabilitado | No existe tal botón — cada casillero tiene su propio Subir/Reemplazar, independiente de los demás |
| 2.5 | Con documentos faltantes, leer el texto debajo del stepper | "El pago ya quedó registrado. Podés completar los soportes que falten desde acá cuando los tengas — no hace falta rehacer nada." |
| 2.6 | Subir todos los obligatorios (4 en efectivo) | El badge pasa de Faltan N a Completa |
3. Subida y preview de los 9 tipos
| # | Paso | Resultado esperado |
|---|---|---|
| 3.1 | Subir un PDF (ej. Carta de Soterex) | Se guarda, aparece el nombre del archivo debajo del tipo, círculo pasa a verde con tilde |
| 3.2 | Click en el nombre del archivo PDF subido | Abre un modal de preview con un <iframe> — confirmar en DevTools o Network que el src es blob:..., nunca una URL directa al archivo |
| 3.3 | Subir una imagen (JPG o PNG, ej. Identificación anverso) | Igual que 3.1 |
| 3.4 | Click en el nombre de la imagen subida | Preview en <img>, también con src blob:... |
| 3.5 | Cerrar el preview (botón × o click afuera) | El modal se cierra y el blob: URL queda revocado (un fetch posterior a esa URL falla) — no queda memoria colgada |
| 3.6 | Subir la selfie | Se guarda igual que cualquier otro tipo, pero nunca cuenta para Faltan N ni para Completa — subida o no, el badge no cambia por ella |
| 3.7 | Cambiar "Medio de pago" a Transferencia bancaria y click en "Guardar datos" | Aparecen los 4 casilleros nuevos (Formulario de enrolamiento, Cartola bancaria, Solicitud de pago por transferencia, Confirmación de acreditación) como pasos 6 a 9, y el badge se recalcula al toque (ver bug fijado en §5.1 — antes quedaba con el valor viejo hasta la próxima subida) |
| 3.8 | Subir los 4 tipos de transferencia | Igual que 3.1/3.3 — PDF o imagen, cualquiera de los dos formatos anda |
| 3.9 | Con los 8 obligatorios + selfie subidos | Badge Completa |
| 3.10 | Reemplazar un documento ya subido (botón Reemplazar del mismo tipo) | El nuevo archivo pasa a ser el vigente en pantalla; el anterior no se borra — sigue en la base y el disco (no hay endpoint de baja, R8) |
| 3.11 | Subir un archivo inválido (ej. un ejecutable renombrado a .pdf, o cualquier archivo que no sea PDF/JPG/PNG real) | Notificación roja: "El archivo no es válido: tiene que ser PDF, JPG o PNG, de hasta 10 MB." — no el error crudo del backend. El documento previamente subido en ese casillero (si había) sigue intacto |
| 3.12 | Como Supervisor o usuario sin permiso de escritura, mirar la sección | Modo consulta: se ven los documentos y se puede abrir el preview, pero no aparece ningún botón Subir/Reemplazar (canUpload=false) |
4. Auditoría
| # | Paso | Resultado esperado |
|---|---|---|
| 4.1 | Después de las subidas de la sección 3, revisar Auditoría (o la tabla audit_logs) | Una entrada TRANSACTION_DOCUMENT_UPLOADED por cada subida (incluida cada reemplazo) |
| 4.2 | Después de los previews de 3.2/3.4 | Una entrada TRANSACTION_DOCUMENT_VIEWED por cada documento abierto — la lectura queda auditada, no solo la subida |
5. Bugs encontrados en este QA y su estado
Los primeros tres se encontraron probando este mismo cambio y se arreglaron en este PR (están dentro de DocumentacionPago.vue, el archivo que este plan tenía que tocar). El cuarto es preexistente, de otro componente, y queda documentado sin arreglar — ver la nota al final.
| # | Bug | Cómo se veía | Fix |
|---|---|---|---|
| 5.1 | El badge Faltan N no se recalculaba al cambiar el medio de pago en la misma sesión | Después de guardar "Transferencia bancaria", la lista de casilleros pasaba a 9 tipos pero el badge seguía mostrando el conteo de efectivo (4) hasta la próxima subida | watch sobre deliveryType que vuelve a pedir el estado al backend |
| 5.2 | Al buscar otra transacción sin recargar la pantalla, DocumentacionPago no se remontaba (mismo v-if="PAID") y quedaban los documentos/badge de la transacción anterior | Buscar 0000000001 (completa) y después 0000000002 (sin documentos) mostraba "Completa" con los archivos de la primera | watch sobre transactionId (agrupado con 5.1) que vuelve a pedir el estado y cierra cualquier preview abierto |
| 5.3 | Si el GET de documentos fallaba (ej. 404 por PDV fuera de alcance — ver 5.4), el catch dejaba faltan/completa en su valor inicial ([]/false) y la pantalla mostraba Faltan 0 — parecía decir "no falta nada" | Buscar 0000000002 como Backoffice de GT-CAP-001 (ver 5.4) | Estado de error explícito: en vez del stepper y el badge, un texto "No se pudo cargar la documentación de esta transacción." |
| 5.4 | (Preexistente, disparador de 5.3, comportamiento correcto de backend) La búsqueda de Pago no acota por PDV, pero el endpoint de documentos sí (§1.6 del Análisis Funcional) — una transacción PAID de otro PDV aparece en el resultado de búsqueda pero sus documentos dan 404 | Como Backoffice (GT-CAP-001), buscar 0000000002 (PDV GT-QUE-002) | No es un bug de este PR — es la regla intencional de §1.6. Lo que sí era un bug era cómo el frontend mostraba ese 404 (ver 5.3, ya arreglado) |
Limitación conocida — no arreglada en este PR
Al volver a buscar una transacción cuyo delivery_type ya estaba guardado (ej. TRANSFERENCIA), el formulario "Datos del pago" no lo recupera — el combo "Medio de pago" aparece en blanco y el stepper vuelve a mostrar solo los 4 tipos de efectivo, escondiendo los 4 de transferencia que sí hacen falta (aunque el badge Faltan N, que sale de otro endpoint, siga siendo correcto si no se cambia nada). La causa: PagoSearchResource excluye a propósito los campos de "Datos del pago" (Backoffice tampoco tiene permiso de lectura general de transacciones para pedirlos por otra vía). Arreglarlo de raíz implica tocar el backend (exponer esos campos) o el modelo de permisos — explícitamente fuera del alcance de este plan ("cambio de UI puro", "no tocar el backend"). Queda para un plan aparte.
6. Qué NO es parte de este cambio (no reportar como bug)
- El wizard de bloqueo por documentos no existe a propósito — es la regla R3/§1.4, no un faltante.
- El borrado de documentos no existe a propósito (R8) — reemplazar es la única forma de corregir un escaneo mal subido.
- La limitación de §5 (recuperar
delivery_typeal re-buscar) es conocida, ver arriba.
Cómo reportarme el feedback
Para cada punto que falle, con el número de la tabla alcanza (ej. "3.11 no mostró el mensaje traducido"). Si es algo visual, una captura ayuda pero no es obligatoria.

