# Firma posterior al guardado de formularios

Actualización: el [historial anual](formularios-anuales.md) conserva cada período por separado y bloquea las modificaciones de formularios finalizados. Sus reglas prevalecen sobre el comportamiento de reenvío descrito originalmente aquí.

El flujo se aplica a cliente persona natural, cliente persona jurídica y proveedor persona natural. El sistema todavía no dispone de un formulario para proveedor persona jurídica.

1. «Guardar y continuar a firma» valida y guarda toda la información, conserva una copia fija del PDF y redirige a la pantalla de firma. Estado: `PENDIENTE_FIRMA`.
2. El usuario descarga el PDF completo, con los datos, declaraciones aceptadas e inventario de adjuntos. El PDF tiene tantas páginas como sean necesarias; los archivos de respaldo se conservan por separado.
3. En la misma pantalla carga el PDF firmado (hasta 10 MB) y confirma que corresponde a la versión descargada. Se guarda en el disco privado `local`.
4. Después de guardar el archivo se habilita «Finalizar». El servidor también impide finalizar sin archivo, con una versión anterior o después de haber finalizado.
5. «Finalizar» cambia el estado a `ENVIADO`, registra la fecha y muestra el comprobante con las descargas disponibles.

Los borradores de clientes continúan funcionando. Volver a guardar información genera otra versión y exige cargar nuevamente su PDF firmado. Los documentos anteriores al cambio mantienen su estado; comienzan este flujo cuando se vuelve a guardar el formulario. La pantalla permite retomar el proceso mediante un enlace desde el formulario y usa el logo y los colores configurados para la empresa.

La carga verifica el tipo PDF, tamaño, acceso y versión del formulario, y exige la confirmación del usuario. No certifica criptográficamente la firma electrónica ni compara el contenido del PDF firmado con el original.

## Archivos para producción

- `database/migrations/2026_09_13_000007_add_form_signing.php`
- `app/Http/Controllers/Cliente/FormSigningController.php`
- `app/Http/Controllers/Cliente/NaturalClientFormController.php`
- `app/Http/Controllers/Cliente/LegalClientFormController.php`
- `app/Http/Controllers/Proveedor/PN/FormularioProveedorNaturalController.php`
- `app/Http/Requests/Cliente/SaveNaturalClientFormRequest.php`
- `app/Models/Proveedor/PN/ProveedorNaturalFormulario.php`
- `app/Services/Clientes/FormSigningPdf.php`
- `resources/data/supplier-natural-legal.php`
- `resources/views/cliente/firma.blade.php`
- `resources/views/cliente/natural/form.blade.php`
- `resources/views/cliente/juridica/form.blade.php`
- `resources/views/proveedor/pn/formulario.blade.php`
- `routes/web.php`

Desde la raíz del proyecto en la terminal de cPanel, usando el PHP configurado para esta aplicación:

```sh
php artisan migrate --path=database/migrations/2026_09_13_000007_add_form_signing.php --force
php artisan route:clear
php artisan view:clear
```

La migración agrega columnas y conserva los datos existentes. El directorio de almacenamiento privado debe permitir escritura. Para archivos de 10 MB, `upload_max_filesize` debe permitir al menos 10 MB y `post_max_size` debe ser mayor (por ejemplo, 16 MB).

## Verificación

Pruebas de los tres formularios: guardado, redirección, PDF, bloqueo sin documento, rechazo de archivos no PDF, versión anterior, carga, finalización, descargas privadas, acceso ajeno y nuevo guardado. Se comprobó además un PDF de cinco páginas con un lector PDF independiente: texto completo, acentos y última sección conservados.

Las 6 pruebas específicas pasaron con 212 aserciones. La ampliación a los módulos de portal y maestro produjo 30 pruebas correctas y una falla en `CompanyMasterTest::test_all_existing_and_new_companies_appear_without_duplicate_customer_records`: espera que una empresa inactiva sea visible, mientras la regla actual oculta las empresas inactivas. Ese módulo y su prueba no se modificaron en este cambio.
