Appearance
Diagrama de Flujo — Eliminar Recibo y Orden de Pago
⚠️ DOCUMENTACIÓN RETROSPECTIVA — Generada a partir de código implementado el 2026-06-18
Módulo: CtaCte Tipo: Diagrama de flujo Estado: Implementado Fecha: 2026-06-18
Referencia: eliminar-recibo-orden-pago-process.md
Diagrama
mermaid
flowchart TD
START(["Inicio: DELETE /recibos/id"]) --> LOAD["1. Cargar ordcta por ID"]
LOAD --> NOTFOUND{"ordcta existe?"}
NOTFOUND -->|No| EX404(["ReciboNoEncontradoException<br/>HTTP 404"])
NOTFOUND -->|"Sí"| RECMODE["2. assertRecordMode<br/>prueba / oficial"]
RECMODE --> MODEMATCH{"modo sesión<br/>= modo registro?"}
MODEMATCH -->|No| EX400MODE(["RecordModeMismatchException<br/>HTTP 400"])
MODEMATCH -->|"Sí"| DISCOVER["3. Descubrir relaciones<br/>recfac · recche · rectra<br/>multi-schema"]
DISCOVER --> BLOCKCHECK["4. Pre-mutation block checks"]
subgraph BLOCKS["Bloqueos pre-mutación"]
BLOCKCHECK --> PARCIAL{"¿Existe pago posterior<br/>para algún comprobante?"}
PARCIAL -->|"Sí"| EXPARCIAL(["PagoParcialNoUltimoException<br/>HTTP 400"])
PARCIAL -->|No| TIPOCUENTA{"¿Tipo cuenta?"}
TIPOCUENTA -->|ACREEDOR| CONCIL{"¿Cheque propio<br/>conciliado en iteban?"}
CONCIL -->|"Sí"| EXCONCIL(["ChequePropioConciliadoException<br/>HTTP 400"])
CONCIL -->|No| REUSED{"¿Cheque tercero<br/>reutilizado en orden<br/>fecha mayor o igual?"}
REUSED -->|"Sí"| EXREUSED(["ChequeTerceroReusadoException<br/>HTTP 400"])
REUSED -->|No| W1GATE
TIPOCUENTA -->|DEUDOR| W1GATE
end
W1GATE["5. W1 Gate — confirmClosedCaja"] --> CAJACERRADA{"¿Algún movimi en<br/>caja cerrada Y<br/>confirmClosedCaja = false?"}
CAJACERRADA -->|"Sí"| EX400CAJA(["BadRequest: caja cerrada<br/>no confirmada<br/>HTTP 400"])
CAJACERRADA -->|No| BEGINTX
subgraph TX["Transacción"]
BEGINTX(["6. beginTransaction<br/>principal + oficial"]) --> SALDOS
SALDOS["7. Restaurar saldos comprobantes"] --> SALDOSDETAIL["Para cada recfac:<br/>setSchemaContext(recfac._schema)<br/>saldo = recfac.saldo<br/>pago = NULL"]
SALDOSDETAIL --> RETPATH{"¿Tipo cuenta?"}
subgraph RETENTIONS["8. Reversión de retenciones"]
RETPATH -->|DEUDOR| RECRET["Deudor: para cada recret<br/>delete movimi egreso<br/>(open: delete / closed: contra-asiento)<br/>delete ordcta HABER"]
RETPATH -->|ACREEDOR| DETGAN["Acreedor: para cada detgan<br/>reverse movimi ingreso<br/>(open: delete / closed: contra-asiento)<br/>delete ordcta DEBE<br/>decrementar acugan.monret<br/>Final: deleteDetallesByOrden"]
NORET["Sin retenciones: skip"]
RECRET --> TESORERIA
DETGAN --> TESORERIA
NORET --> TESORERIA
end
RETPATH -->|"Sin retenciones"| NORET
subgraph TESORERIA_BLOCK["9. Reversión Tesorería"]
TESORERIA["Para cada movimi de la orden"] --> MODULO_TES{"¿Módulo TESORERÍA<br/>activo?"}
MODULO_TES -->|No| SKIP_TES["Skip"]
MODULO_TES -->|"Sí"| CAJAABIERTA{"¿Caja abierta?"}
CAJAABIERTA -->|"Sí"| HARDDELETE["Hard delete movimi"]
CAJAABIERTA -->|No| CONTRAASIENTO["insertReversal:<br/>nuevo movimi con<br/>tipo invertido E vs S<br/>fecha = hoy"]
end
HARDDELETE --> CHEQUES_BLOCK
CONTRAASIENTO --> CHEQUES_BLOCK
SKIP_TES --> CHEQUES_BLOCK
subgraph CHEQUES_BLOCK["10. Manejo de cheques de terceros"]
CHEQUES["¿Hay cheques de terceros?"] --> NOCHEQUE{"¿Sin cheques?"}
NOCHEQUE -->|"Sí"| SKIP_CHE["Skip"]
NOCHEQUE -->|No| TIPOCHE{"¿Tipo cuenta?"}
TIPOCHE -->|DEUDOR| EGRESADO{"¿terceros.fecegr<br/>es NULL?"}
EGRESADO -->|"Sí - no egresado"| DEL_TERCEROS["Eliminar terceros + recche"]
EGRESADO -->|"No - egresado"| DECISION{"¿chequeDecision?"}
DECISION -->|discard| DEL_TERCEROS2["Eliminar terceros + recche"]
DECISION -->|"keep / null"| KEEP_TERCEROS["Solo eliminar recche<br/>terceros permanece"]
TIPOCHE -->|ACREEDOR| RETURN_CARTERA["returnToCartera:<br/>terceros.fecegr = NULL<br/>terceros.prov = NULL<br/>+ eliminar recche"]
end
DEL_TERCEROS --> DELREL
DEL_TERCEROS2 --> DELREL
KEEP_TERCEROS --> DELREL
RETURN_CARTERA --> DELREL
SKIP_CHE --> DELREL
subgraph DELREL_BLOCK["11. Eliminar filas hijas"]
DELREL["Orden: hijos antes que padre"] --> DELRET["1. recret - schema por defecto"]
DELRET --> DELFAC["2. recfac - per recfac._schema"]
DELFAC --> DELCHE["3. recche - per recche._schema"]
DELCHE --> DELTRA["4. rectra - per rectra._schema"]
DELTRA --> DELCOM["5. reccom - schema por defecto"]
end
DELCOM --> DELPARENT["12. deleteOrdcta<br/>ordcta en schema_origen"]
DELPARENT --> AUDIT["13. registrarAuditoria<br/>DELETE - RECIBO - ORDEN_PAGO - id"]
AUDIT --> COMMIT
COMMIT(["14. COMMIT"]) --> SUCCESS
end
SUCCESS(["Respuesta 200<br/>deleted: true"])
classDef exception fill:#ff6b6b,color:#fff
classDef success fill:#51cf66,color:#fff
classDef txboundary fill:#339af0,color:#fff
class EX404,EX400MODE,EXPARCIAL,EXCONCIL,EXREUSED,EX400CAJA exception
class SUCCESS success
class BEGINTX,COMMIT txboundaryLeyenda
| Elemento | Significado |
|---|---|
| Rectángulo | Acción / paso del pipeline |
Rombo {...} | Decisión |
| Óvalo rojo | Excepción — operación bloqueada |
| Óvalo verde | Fin exitoso |
| Subgrafo | Agrupación de pasos relacionados |
Notas sobre el diagrama
- Pasos 1–5 y el W1 Gate ocurren fuera de la transacción. Si alguno lanza excepción, no hay nada que revertir.
- El rollback se activa automáticamente ante cualquier excepción dentro del subgrafo "Transacción" (pasos 6–14).
- Cross-schema: el diagrama muestra
per recfac._schemapara indicar que cada iteración cambia elsearch_pathantes de operar y lo restaura enfinally. - Módulo COMPRAS (retenciones Acreedor) y módulo TESORERÍA (movimientos de caja y cheques) son verificados con
moduloActivo()antes de intentar acceder a sus tablas. - El bloqueo por cheque propio conciliado y cheque tercero reutilizado aplica únicamente al path Acreedor.
Referencias
- Proceso: eliminar-recibo-orden-pago-process.md
- Spec SDD:
openspec/changes/eliminar-recibos-ordenes-pago-ctacte/specs/ctacte/spec.md - Servicio abstract:
service/CtaCte/AbstractReciboDeleteService.php
⚠️ NOTA IMPORTANTE: Validar con stakeholders antes de considerar final. Esta documentación fue generada retrospectivamente a partir del código implementado en la rama
feature/recibos-ctacte-pr1-tesoreria.