Skip to content

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 txboundary

Leyenda

ElementoSignificado
RectánguloAcción / paso del pipeline
Rombo {...}Decisión
Óvalo rojoExcepción — operación bloqueada
Óvalo verdeFin exitoso
SubgrafoAgrupació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._schema para indicar que cada iteración cambia el search_path antes de operar y lo restaura en finally.
  • 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.