FactuGES_ERP/docs/customer-invoices/settings/frontend-erp-settings-verifactu-design.md
david 45200284ed feat(verifactu): add company Verifactu profile management features
- Implemented API for updating company Verifactu profile.
- Created entities for company Verifactu profile and defaults.
- Developed hooks for querying and updating the company Verifactu profile.
- Added UI components for displaying and editing company Verifactu settings.
- Introduced validation and error handling for profile updates.
- Created utility functions for building form data and handling feedback states.
- Added tests for utility functions and error handling.
2026-08-12 13:31:31 +02:00

210 lines
4.7 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Frontend ERP – Settings VeriFactu
## Estado
Implementado en V1 como primera pantalla funcional del sistema modular de Settings:
```txt
/settings/billing/verifactu
```
## Arquitectura real
```txt
CustomerInvoicesModuleManifest.settings.entries
│
├── SettingsNavigation
└── buildSettingsRoute(pathPrefix="settings")
│
▼
customer-invoices route: settings/billing/verifactu
│
▼
Page Controller
├── useCompanyVerifactuProfileQuery
└── useCompanyVerifactuProfileController
│
▼
UI sections
├── status
├── configuration
└── defaults
```
## Integración con Settings
- El módulo `customer-invoices` publica una única entry de Settings:
```ts
{
id: "verifactu",
sectionId: "billing",
labelKey: "settings.verifactu.title",
path: "/settings/billing/verifactu",
}
```
- La pantalla se registra como ruta modular del propio módulo con `path: "settings/billing/verifactu"`.
- No se modificó el shell de Settings para esta feature.
## Capa de datos
Estructura implementada:
```txt
API
→ DTO common
→ adapter
→ Entity
→ React Query hook
→ controller
→ page controller
→ UI
```
Archivos clave:
```txt
modules/customer-invoices/src/web/settings/verifactu/shared/
modules/customer-invoices/src/web/settings/verifactu/controllers/
modules/customer-invoices/src/web/settings/verifactu/ui/
```
## DTOs reutilizados
Se reutilizan los DTOs publicados por `@erp/customer-invoices/common`:
- `CompanyVerifactuProfileResponseDTO`
- `UpdateCompanyVerifactuProfileRequestDTO`
- `UpdateCompanyVerifactuProfileRequestSchema`
No se usan DTOs `snake_case` directamente en UI.
## Entity frontend
```ts
interface CompanyVerifactuProfile {
profileStatus:
| "not_configured"
| "exempt"
| "obligated_without_verifactu"
| "obligated_with_verifactu";
configured: boolean;
usesVerifactu: boolean;
exemptionReasonCode: string | null;
exemptionReasonDetail: string | null;
verifactuEffectiveAt: string | null;
autoRenewMode: "disabled" | "enabled" | null;
defaults: {
taxRegimeCode: string | null;
operationQualificationCode: string | null;
exemptionReasonCode: string | null;
};
updatedAt: string | null;
}
```
## Form model
Se mantiene la separación:
```txt
Form ≠ Entity ≠ DTO ≠ Params
```
El formulario:
- usa `camelCase`;
- convierte `updatedAt` fuera del form;
- guarda `verifactuEffectiveAt` como fecha civil `yyyy-MM-dd`;
- normaliza strings vacíos a `null` en el builder de salida.
## Reglas implementadas en frontend
### Estado `not_configured`
- no muestra una opción explícita de radio;
- se usa como estado técnico inicial;
- al guardar se obliga al usuario a elegir un estado configurado real;
- limpia defaults y campos de exención/VeriFactu.
### Estado `exempt`
- muestra solo detalle libre de exención;
- no muestra activación VeriFactu;
- no inventa catálogo de motivos de exención.
### Estado `obligated_without_verifactu`
- limpia `verifactuEffectiveAt`;
- limpia `autoRenewMode`.
### Estado `obligated_with_verifactu`
- muestra `verifactuEffectiveAt`;
- muestra `autoRenewMode`;
- requiere fecha efectiva en Zod.
## Catálogos
### Reutilizado
- `taxRegimeCode` usa el catálogo real existente a través de:
```txt
@erp/catalogs/client/tax-regimes
```
### No implementado todavía
- `operationQualificationCode`
- `defaults.exemptionReasonCode`
- `exemptionReasonCode` como catálogo legal
En V1 no se inventan selects vacíos ni códigos ficticios. Se documenta la limitación en la propia UI.
## UX implementada
La pantalla se resuelve como editor único, no wizard:
```txt
1. Situación
2. Configuración VeriFactu
3. Valores por defecto
4. Footer sticky con guardar/restaurar
```
Se priorizó una primera versión estable y verificable.
## Errores y loading
- Carga inicial con skeleton.
- Error de carga con `PageErrorState`.
- Error de guardado con `ErrorAlert` y toasts.
- Validación de form con foco al primer error.
## Cambio de empresa
No se añadió lógica específica.
La feature depende del comportamiento global ya existente:
- tenant context del ERP;
- reset global de React Query al cambiar de empresa;
- `form.reset(...)` al recibir el nuevo perfil.
## Tests añadidos
- adapter `snake_case -> camelCase`
- builder de `Form -> Update params`
- page error view model
- page feedback state
- manifest/routing básico del módulo
## Limitaciones reales de esta V1
- no hay wizard inicial;
- no hay catálogo backend para `operationQualificationCode` ni para motivos de exención;
- no se implementa ninguna UI de certificados;
- no se integra con `IssuedInvoice` ni con estados operativos AEAT.