Skip to content

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.

bash
docker compose exec backend php artisan migrate --seed

Usuarios de prueba

EmailPasswordRolAlcance
backoffice@cislatam.testBackoffice123!BackofficeSolo GT-CAP-001
supervisor@cislatam.testSuper123!SupervisorGT-CAP-001 + GT-QUE-002
admin@cislatam.testAdmin123!AdminGuatemala, todos los PDVs

1. Base en verde antes de tocar nada

#PasoResultado esperado
1.1Correr 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.2Correr docker compose exec frontend npm run testLos 51 tests de frontend pasan (incluye PagoView.spec.ts, que renderiza DocumentacionPago)
1.3Correr docker compose exec frontend npm run buildCompila sin errores de TypeScript (vue-tsc -b)

2. El stepper visual — no bloqueante

#PasoResultado esperado
2.1Como 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.2Mirar los círculos de un documento ya subido vs. uno pendiente y obligatorio vs. la selfie sin subirSubido: 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.3Subir los documentos fuera de orden (ej. el 5° antes que el 1°)Sube sin problema — ningún paso bloquea a otro
2.4Con documentos faltantes, mirar si hay algún botón "Siguiente" o similar deshabilitadoNo existe tal botón — cada casillero tiene su propio Subir/Reemplazar, independiente de los demás
2.5Con 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.6Subir todos los obligatorios (4 en efectivo)El badge pasa de Faltan N a Completa

3. Subida y preview de los 9 tipos

#PasoResultado esperado
3.1Subir un PDF (ej. Carta de Soterex)Se guarda, aparece el nombre del archivo debajo del tipo, círculo pasa a verde con tilde
3.2Click en el nombre del archivo PDF subidoAbre un modal de preview con un <iframe> — confirmar en DevTools o Network que el src es blob:..., nunca una URL directa al archivo
3.3Subir una imagen (JPG o PNG, ej. Identificación anverso)Igual que 3.1
3.4Click en el nombre de la imagen subidaPreview en <img>, también con src blob:...
3.5Cerrar 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.6Subir la selfieSe 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.7Cambiar "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.8Subir los 4 tipos de transferenciaIgual que 3.1/3.3 — PDF o imagen, cualquiera de los dos formatos anda
3.9Con los 8 obligatorios + selfie subidosBadge Completa
3.10Reemplazar 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.11Subir 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.12Como Supervisor o usuario sin permiso de escritura, mirar la secciónModo 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

#PasoResultado esperado
4.1Despué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.2Después de los previews de 3.2/3.4Una 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.

#BugCómo se veíaFix
5.1El badge Faltan N no se recalculaba al cambiar el medio de pago en la misma sesiónDespué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 subidawatch sobre deliveryType que vuelve a pedir el estado al backend
5.2Al 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 anteriorBuscar 0000000001 (completa) y después 0000000002 (sin documentos) mostraba "Completa" con los archivos de la primerawatch sobre transactionId (agrupado con 5.1) que vuelve a pedir el estado y cierra cualquier preview abierto
5.3Si 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 404Como 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_type al 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.

Documentación viva — se actualiza junto con el código, no es un anexo aparte.