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

4.7 KiB
Raw Blame History

Frontend ERP – Settings VeriFactu

Estado

Implementado en V1 como primera pantalla funcional del sistema modular de Settings:

/settings/billing/verifactu

Arquitectura real

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:
{
  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:

API
→ DTO common
→ adapter
→ Entity
→ React Query hook
→ controller
→ page controller
→ UI

Archivos clave:

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

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:

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:
@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:

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.