TiFacturaOnline · Gateway de facturación electrónica AFIP

Versionado y guía de actualización

Registro de releases QA/PROD desde qa-20260825 hasta qa-20260907c, y el anexo con los pasos de actualización acumulados.

Releases: 5 Suite: 615 → 650 (0 fallas · 24 skipped) Actual: qa-20260907c · main 85b14fd Repo: tipre/TIFacturaOnlineNext

Resumen — novedades de qa-20260907c

Historial de releases

qa-20260907cActual650/0/242026-09-07 20:52

Barrido de numeración + KPI RG 5.616 + PDF dedup / 552

  • Barrido de numeración — recupera CAE/NC autorizados por ARCA con respuesta perdida (nunca emite NC); gateado OFF, corre antes del job de NC. (Plan 027)
  • KPI RG 5.616 — mide comprobantes sin condición IVA del receptor; solo medición.
  • Dedup PDF (−92 %/−95 %, sin pérdida) y guarda SMTP 5xx no reintentable.

Aplicar: swap de jar. KPI y PDF/email quedan activos solos; el barrido, inerte hasta cargar su fila en Tareas y prender los flags.

qa-20260907b625/0/242026-09-07 17:20

Libro de IVA completo + cockpit email / descarga

  • #119 Libro de IVA completoGET /api/libro-iva (X-Api-Key): todos los comprobantes autorizados del período (CAE + CAEA + NC/ND). Formatos arca (RG 4597), csv y json.
  • #120 Descarga desde el cockpit (filtros + botón) → /api/cockpit/libro-iva.
  • #118 Cockpit email: KPI “aprobados ARCA no enviados” y el botón Reenviar ahora pide el mail.

Aplicar: swap de jar. Sin DDL. Endpoints read-only.

qa-20260907623/0/242026-09-07 14:34

Email guard (solo aprobados ARCA) + BootUI 1.16

  • #117 Regla de oro del email — solo se envían comprobantes aprobados por ARCA (resultado='A' y cae != null); si no, ERROR terminal EMAIL_NO_APROBADO. Candado único de las 4 vías de envío.
  • #116 BootUI 1.14 → 1.16 (paneles Fault Tolerance y WebSockets). Trae OpenTelemetry al classpath, dejado inerte (management.tracing.enabled=false).

Aplicar: swap de jar. Sin DDL. Config: agrega management.tracing.enabled=false y logging.pattern.correlation="" (ver anexo).

qa-20260904622/0/242026-09-04 23:41

Ajustes de contingencia: detalle impositivo + formato Libro de IVA

  • #114 /api/ajustes-contingencia: detalle impositivo completo por comprobante (impuestos + alícuotas + tributos + datos del receptor). Aditivo.
  • #115 Parámetro ?formato=libro-iva — registros de ancho fijo del Libro de IVA Digital (RG 4597), verificados contra el PDF de AFIP.

Aplicar: swap de jar. Sin DDL. Endpoints read-only.

qa-20260825615/0/242026-08-25 19:47

Filtro cuit/nroSucursal + log limpio + flush AUTO

  • #112 /api/ajustes-contingencia acepta cuit y nroSucursal como filtros. Log más limpio (se vacía logging.pattern.correlation).
  • #111/#97 Se acepta flush AUTO como invariante real; se quita el setFlushMode(COMMIT) NO-OP. Sin cambio de comportamiento.

Aplicar: swap de jar. Sin DDL. Punto de partida de esta guía.

APIs de integración

Todas read-only, no tocan el money-path de emisión. Fechas en YYYYMMDD. Reemplazá HOST y <api-key> por los de tu entorno.

A. Ajustes de contingencia — tripla CAE + NC/ND + CAEA

Los comprobantes que el gateway emitió por su cuenta y el BackOffice necesita para cerrar su Libro de IVA: el CAE original (duplicado), la NC/ND que lo anula, y el CAEA que es la venta real impresa. El neteo cierra (CAE + CAEA − NC = CAEA); el valor es de registro. Cada comprobante trae su detalle impositivo completo.

GET /api/ajustes-contingencia

Auth: header X-Api-Key: <api-key> · ventana máx. 92 días.

Parámetros

ParámetroReq.Descripción
desdeInicio del período (YYYYMMDD).
hastaFin del período (YYYYMMDD).
cuitFiltra por comercio (con o sin guiones; se normaliza a dígitos).
nroSucursalFiltra por sucursal.
enteFiltra por id interno de EnteFacturador (compatibilidad).
formatojson (default) · libro-iva (registros ancho fijo RG 4597).

Ejemplo — request

curl -H "X-Api-Key: <api-key>" \
  "https://HOST/api/ajustes-contingencia?desde=20260901&hasta=20260930&cuit=30712434763"

Ejemplo — respuesta (json, un ajuste)

[
  {
    "ticket": { "suc": 1, "pos": 2, "nroTicket": "T-0001" },
    "caeOriginal": {
      "ptoVta": 559, "nro": 301882, "fecha": "20260901",
      "cae": "75130212345601", "tipoComprobante": 6, "importeTotal": 1234.56,
      "docTipo": 99, "docNro": 0, "condicionIvaReceptorId": 5,
      "impuestos": {
        "netoGravado": 1020.30, "noGravado": 0.0, "exento": 0.0,
        "iva": 214.26, "tributos": 0.0, "total": 1234.56,
        "ivaAlicuotas": [ { "id": 5, "baseImponible": 1020.30, "importe": 214.26 } ],
        "tributosDetalle": []
      }
    },
    "ncAnulacion": { "ptoVta": 559, "nro": 45, "fecha": "20260902", "cae": "75130298765401",
                     "tipoComprobante": 8, "importeTotal": 1234.56, "docTipo": 99, "docNro": 0,
                     "condicionIvaReceptorId": 5, "impuestos": { "…": "idem estructura" } },
    "caeaImpreso": { "ptoVta": 560, "nro": 12000, "caea": "26123456789012",
                     "fchTope": "20260910", "estadoInforme": "INFORMADO",
                     "impuestos": { "…": "idem estructura" } },
    "motivo": "doble facturación CAE+CAEA de contingencia",
    "crossPeriodo": false,
    "estado": "CERRADO"
  }
]

Ids AFIP: tipoComprobante 6=Fac B, 8=NC B (1/3=A, 11/13=C, 51/53=M) · alícuota IVA 3=0%, 4=10,5%, 5=21%, 6=27%, 8=5%, 9=2,5% · docTipo 80=CUIT, 96=DNI, 99=Cons.Final.

Opción ?formato=libro-iva

Mismos filtros; devuelve los registros de ancho fijo del Libro de IVA Digital (RG 4597):

curl -H "X-Api-Key: <api-key>" \
  "https://HOST/api/ajustes-contingencia?desde=20260901&hasta=20260930&formato=libro-iva"

→ { "ventasCbte":      [ "…registro de 266 caracteres por comprobante…" ],
    "ventasAlicuotas": [ "…registro de 62 caracteres por alícuota…" ] }

B. Libro de IVA completo — todos los comprobantes del período

A diferencia de (A), devuelve todos los comprobantes autorizados por AFIP (CAE online + CAEA offline + NC/ND), no solo la tripla de contingencia. Fuente: la tabla Trx (canal único).

GET /api/libro-iva

Auth: header X-Api-Key: <api-key> · ventana máx. 366 días.

Parámetros

ParámetroReq.Descripción
desdeInicio del período (YYYYMMDD).
hastaFin del período (YYYYMMDD).
cuitFiltra por comercio (con o sin guiones).
nroSucursalFiltra por sucursal.
enteFiltra por id interno de EnteFacturador.
formatoVer opciones abajo.

Opciones de formato

  • arca (default) — JSON con las líneas de ancho fijo RG 4597 (ventasCbte 266 / ventasAlicuotas 62).
  • json — un objeto estructurado por comprobante (ver ejemplo).
  • csv — adjunto .zip con ventas_cbte.csv + ventas_alicuotas.csv.

Ejemplo — formato=json

curl -H "X-Api-Key: <api-key>" \
  "https://HOST/api/libro-iva?desde=20260901&hasta=20260930&formato=json"

→ [
    {
      "fecha": "20260901", "tipoComprobante": 6, "ptoVta": 559, "nroComprobante": 301882,
      "tipofacturacion": "CAE", "cae": "75130212345601", "caea": null,
      "docTipo": 99, "docNro": 0, "razonSocial": "Consumidor Final",
      "importeNeto": 1020.30, "importeNoGravado": 0.0, "importeExento": 0.0,
      "importeIva": 214.26, "importeTributos": 0.0, "importeTotal": 1234.56,
      "iva": [ { "id": 5, "baseImponible": 1020.30, "importe": 214.26 } ]
    }
  ]

Ejemplo — formato=csv (baja un .zip)

curl -H "X-Api-Key: <api-key>" -OJ \
  "https://HOST/api/libro-iva?desde=20260901&hasta=20260930&formato=csv"
# → libro-iva-20260901-20260930.zip  (ventas_cbte.csv + ventas_alicuotas.csv)

C. Descarga del Libro de IVA desde el cockpit

Mismo contenido que (B) pero con la auth normal del cockpit (sesión), sin la X-Api-Key. Siempre devuelve un archivo descargable. Es lo que usa el botón “Descargar” de la sección Libro de IVA (ventas).

GET /api/cockpit/libro-iva

Auth: sesión del cockpit (no requiere X-Api-Key ni el secret del ABM).

Parámetros

Iguales a (B): desde, hasta (req.), cuit, nroSucursal, ente, formato.

  • arca / csv → descarga .zip.
  • json → descarga .json.

Anexo — Pasos de actualización desde qa-20260825

Actualización acumulada qa-20260825 → qa-20260907c. Todas las releases intermedias son swap de jar: no hay ninguna migración de DDL ni cambio de WSDL. La única base de datos que se toca es un INSERT de datos (fila en Tareas), y solo si se activa el barrido.

  1. Swap del jar

    Descargar el asset tifactura-spring-20260907c.jar de la release y renombrarlo a tifactura-spring.jar.

    nssm stop TipreTiFactura
    copy /y D:\...\tifactura-spring.jar D:\...\backup\tifactura-spring.PREV-<fecha>.jar
    :: reemplazar el jar por el nuevo
    nssm start TipreTiFactura
  2. Configuración (application.yml / variables de entorno)

    Para actualizar no hace falta cambiar nada si usás el deploy/application.yml de esta versión: ya trae todo. Si mantenés tu YAML externo anterior (de qa-20260825), agregá estas dos claves que entraron con BootUI 1.16 (qa-20260907):

    management:
      tracing:
        enabled: false          # BootUI 1.16 trae OpenTelemetry; lo dejamos inerte
    logging:
      pattern:
        correlation: ""         # evita el bloque [ ] vacío en cada línea de log

    El bloque numeracion.barrido.* solo hace falta si vas a activar el barrido (paso 4). Si no está, aplican los valores por default (todo OFF).

  3. SQL a correr

    Ninguno es obligatorio — esta actualización no tiene DDL. El único script existe para el barrido (paso 4) y es un INSERT de datos, no un cambio de esquema.

  4. Activar el barrido de numeración (opcional, cuando se decida)

    Si no se hace nada de esto, el barrido queda inerte. Para activarlo, en orden:

    a. Correr el INSERT en Tareas (una vez). El script está en el repo o dentro del jar:

    jar xf tifactura-spring.jar BOOT-INF/classes/db/migration/schedule-barrido-numeracion-job.sql

    b. La sección de config es numeracion.barrido en application.yml — así viene por default (cada clave enlazada a una variable de entorno con su valor por default):

    numeracion:
      barrido:
        detectar-enabled:  ${BARRIDO_NUM_DETECTAR:false}     # Fase A: detecta + alerta (solo lectura)
        recuperar-enabled: ${BARRIDO_NUM_RECUPERAR:false}    # Fase B: recupera (escribe) — requiere Fase A
        ventana-dias:      ${BARRIDO_NUM_VENTANA_DIAS:35}    # días hacia atrás por comprobanteFecha
        max-por-corrida:   ${BARRIDO_NUM_MAX:200}            # tope de consultas a ARCA por corrida

    Cada clave se puede prender de dos formas equivalentes (elegí una):

    • Por variable de entorno (recomendado, sin editar el yml): BARRIDO_NUM_DETECTAR=true, luego BARRIDO_NUM_RECUPERAR=true.
    • Editando el yml: poné detectar-enabled: true y luego recuperar-enabled: true en ese bloque.

    c. Secuencia: primero Fase A (detectar-enabled=true, recuperar en false) → reiniciar → mirar la tarjeta “Barrido de numeración” del cockpit y las alertas unos días. Después Fase B (recuperar-enabled=true) → reiniciar.

  5. Verificación

    • La app levanta sin errores de configuración.
    • En el cockpit aparecen las tarjetas “Barrido de numeración” y “Condición IVA del receptor (RG 5.616)”.
    • GET /api/cockpit/barrido-numeracion y GET /api/cockpit/condicion-iva-receptor devuelven JSON.
    • Los mails de facturas ahora pesan poco (probar reenviar uno que antes rebotaba con 552).
  6. Rollback

    Restaurar el jar de backup y reiniciar. Si se activó el barrido y se quiere revertir, apagar los flags o quitar la fila de Tareas; los comprobantes ya recuperados quedan (son válidos).

Sin cambios de esquema. Regla del proyecto: hbm2ddl=none, el esquema lo administra el cliente. Los .sql de db/migration/ son scripts de referencia que aplica el DBA; esta actualización no requiere ninguno (salvo el INSERT opcional del barrido).

Anexo — Respuestas de error al cliente

Catálogo de las respuestas con error que recibe el cliente (SOAP faults + Response con resultado=R), el faultstring de cada caso (CAE/AFIP + mail, con el fix de claridad aplicado) y el diagrama del flujo de envío de email. Documento self-contained; también suelto en docs/errores-respuesta-cliente.html.