# Endurecimiento CXP multi-tenant

## Migraciones

Ejecutar en ambiente local/staging antes de produccion:

```bash
composer install
php bin/console doctrine:migrations:migrate --no-interaction
```

Migraciones agregadas:

- `Version20260624120000`: protege `regimenes_fiscales` globales, agrega `cliente_id`, `es_sistema`, `bloqueado`, indice por cliente y unicidad por alcance mediante `cliente_scope_id`.
- `Version20260624121000`: convierte `documentos_cxp.observaciones` a `TEXT` y crea `documento_observacion_historial`.

Los regimenes existentes quedan con `cliente_id NULL`, `es_sistema = 1` y `bloqueado = 1`.

## Regimen global vs cliente

- Global/sistema: visible para todos los clientes, no editable ni eliminable por UI ni por POST directo.
- Configuracion por cliente: se guarda en `regimen_fiscal_configs` y puede apuntar a IVA, ISR, retencion IVA e IDP para ese cliente.
- Variante cliente: usar `Duplicar para cliente` o crear un regimen personalizado. Queda asociado al cliente activo y solo aparece para ese cliente.
- Unicidad: `codigo` se valida en backend y base de datos por alcance (`codigo`, cliente o global).

## Pagos y documentos cross-site

Los listados de Documentos CXP y Pagos tienen filtro `Todos autorizados` por defecto. Las consultas desactivan temporalmente el `TenantFilter` solo dentro del controlador y vuelven a aplicar explicitamente:

- `cliente_id = cliente activo`
- `sitio_id IN sitios autorizados del cliente`

La creacion de documentos y pagos sigue usando el sitio activo como sitio propietario.

## Observaciones

La pantalla de documento incluye un guardado rapido para observaciones:

- Endpoint: `POST /documentos/{id}/observaciones`
- CSRF: `documento_observaciones_{id}`
- No recalcula lineas, impuestos, retenciones ni saldos.
- Registra historial en `documento_observacion_historial`.
- No acepta requests sin el campo `observaciones`, para evitar sobrescrituras accidentales por formularios incompletos.

## Validaciones recomendadas

```bash
php -l src/Controller/RegimenFiscalController.php
php -l src/Controller/DocumentoController.php
php -l src/Controller/PagoController.php
php bin/console lint:twig templates
php bin/console lint:yaml config translations
composer phpstan
vendor/bin/phpunit
```

Pruebas manuales clave:

- Intentar editar/eliminar un regimen global por UI y por POST directo.
- Duplicar un regimen global para un cliente y verificar que no aparece en otro cliente.
- Configurar presets de un regimen global para un cliente y validar calculo de IVA/retenciones en proveedor/documento.
- Abrir Documentos/Pagos en modo todos los sitios y verificar que solo aparecen sitios autorizados.
- Guardar observaciones desde el detalle de factura y recargar la pantalla.

## Pendientes de segunda fase

No se implementaron aun por alcance y riesgo:

- `PagoVoucher` como fuente unica de voucher/pago.
- Exportacion de voucher a Excel/PDF.
- Adaptador real/cola para Google Sheets.
- Editor drag and drop de formatos de cheque.
- Symfony Messenger/worker completo para procesos pesados.
- Desbloqueo operativo: implementado con `ROLE_DESBLOQUEAR_FACTURA`, historial auditable y sin cambios de saldos/estado fiscal.
- Documento relacionado: implementado con campo explicito, busqueda bajo demanda y auditoria de consultas/cambios.

Estos puntos requieren diseno transaccional adicional y pruebas funcionales con datos reales para no introducir duplicidad de pagos o cambios fiscales involuntarios.
