- Add GetProformaIssuanceReadinessUseCase to check proforma issuance readiness. - Create GetProformaIssuanceReadinessController to handle requests and responses. - Introduce request and response DTOs for proforma issuance readiness. - Develop tests for the use case and controller to ensure functionality. - Implement adapter and hooks for integrating issuance readiness in the web application. - Create UI components for displaying issuance readiness alerts and help popover. - Add utility functions for translating blocker messages and details.
2.7 KiB
2.7 KiB
Contrato de readiness de emisión de proformas
Objetivo
La readiness de emisión es una lectura informativa del estado persistido de una proforma.
Su propósito es responder:
¿Puede emitirse esta proforma ahora mismo?
No sustituye la validación transaccional final de:
PUT /proformas/:id/issue
La emisión sigue revalidando siempre en backend para cubrir concurrencia y cambios entre consulta y submit.
Endpoint vigente
GET /proformas/:proforma_id/issuance-readiness
Comportamiento:
- 200 cuando la proforma existe dentro del scope de company
- 200 aunque can_issue sea false
- blockers con códigos estables orientados a frontend
- sin textos i18n en backend
No se expone readiness completa en el listado de proformas para evitar N+1 HTTP y resolución externa por fila.
Contrato HTTP
{
"can_issue": false,
"blockers": [
{ "code": "missing_operation_date" },
{ "code": "missing_description" }
]
}
Códigos públicos
| Code | Significado |
|---|---|
already_issued |
La proforma ya tiene emisión materializada o enlazada. |
invalid_status |
El estado actual no permite emitir; hoy debe estar aprobada. |
missing_description |
Falta la descripción obligatoria para emitir. |
missing_operation_date |
Falta la fecha de operación. |
incomplete_recipient |
Faltan datos fiscales mínimos del destinatario. |
missing_items |
No existen líneas de detalle persistidas. |
missing_payment_method |
Falta la forma de pago. |
missing_tax_regime |
Falta el régimen fiscal. |
payment_method_unavailable |
La referencia company-scoped de forma de pago no se puede resolver. |
payment_method_inactive |
La forma de pago resuelta existe, pero está inactiva. |
Fuente de verdad
La semántica se reparte de forma explícita pero sin duplicar reglas:
Proforma.getIssuanceBlockers()
-> blockers internos de dominio
Proforma.validateCanBeIssued()
-> consume el primer blocker compatible con el contrato legacy de error
ProformaIssuanceReadinessChecker
-> añade blockers externos dependientes de catálogos
Esto permite:
readiness
-> enumerar blockers útiles
issue
-> seguir fallando de forma autoritativa
Semántica importante en frontend
- La readiness representa el estado guardado en backend.
- Los cambios no guardados del editor no alteran este read model.
- Tras guardar, cambiar estado o emitir, la query de readiness debe invalidarse.
Pendientes fuera de esta fase
- exponer readiness en listado sin introducir N+1;
- migrar la ruta legacy de emisión de
PUTa un contrato nuevo si se aprueba; - deep-link o focus directo al campo bloqueado desde frontend.