- 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.
210 lines
4.7 KiB
Markdown
210 lines
4.7 KiB
Markdown
# 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.
|