Caso de uso - Consultar qué facturas tienen CAE desde la grilla

Uso de Guest code con bproc de viewer

Este documento muestra cómo utilizar la herramienta guest code y un bproc de tipo viewer para consultar qué facturas tienen CAE desde la grilla de facturas de venta.

Descripción del caso

El caso consiste en poder consultar, desde la grilla, qué facturas tienen CAE y cuáles no

Configuraciones

Se debe configurar

1 - Guest code: Para realizar el script utilizamos la IA Fini. Se le indica la necesidad junto con el contexto necesario y luego de algunas iteraciones se obtiene el script deseado:

# Script para Finnegans GO Guest Code 
# Verificación de CAE en Facturas de Venta
# Fix: reemplaza os + requests por obtener_entidad de finnegans.api


import json


from finnegans.scripting import request, HTTPResponse
from finnegans.api import obtener_entidad, ApiException


# ─────────────────────────────────────────────
# CONFIGURACIÓN
# ─────────────────────────────────────────────
INVOICE_API = "facturaVenta"
CAE_FIELD = "CAE"




# ─────────────────────────────────────────────
# HELPERS — LECTURA DEL REQUEST
# ─────────────────────────────────────────────
def _get_selected_records() -> list:
    """
    Lee los registros seleccionados desde el body del request.
    Soporta payload list[dict] o dict directamente.
    """
    body_bytes = request.get_body()
    if not body_bytes:
        return []
    try:
        payload = json.loads(body_bytes.decode("utf-8"))
        if isinstance(payload, list) and payload:
            return payload[0].get("selectedRecords", [])
        if isinstance(payload, dict):
            return payload.get("selectedRecords", [])
    except Exception:
        pass
    return []




# ─────────────────────────────────────────────
# HELPERS — CLASIFICACIÓN
# ─────────────────────────────────────────────
def _clasificar_facturas(records: list) -> tuple:
    """
    Para cada registro obtiene la factura de venta via obtener_entidad
    y la clasifica según la presencia del campo CAE.
    Retorna: (con_cae, sin_cae, errores)
    """
    con_cae = []
    sin_cae = []
    errores = []


    for record in records:
        transaccion_id = str(record.get("TRANSACCIONID", "")).strip()
        numero_doc = record.get("DOCUMENTO") or transaccion_id


        if not transaccion_id:
            errores.append(("?", "No se encontro TRANSACCIONID en el registro"))
            continue


        try:
            factura = obtener_entidad(INVOICE_API, numero_doc)
            cae_val = factura.get(CAE_FIELD, "") if isinstance(factura, dict) else ""
            if cae_val and str(cae_val).strip():
                con_cae.append((transaccion_id, str(numero_doc), str(cae_val).strip()))
            else:
                sin_cae.append((transaccion_id, str(numero_doc)))
        except ApiException as e:
            errores.append((transaccion_id, f"ApiException: {str(e)}"))
        except Exception as e:
            errores.append((transaccion_id, str(e)))


    return con_cae, sin_cae, errores




# ─────────────────────────────────────────────
# HELPERS — CONSTRUCCIÓN HTML
# ─────────────────────────────────────────────
def _build_html(con_cae: list, sin_cae: list, errores: list) -> str:
    total = len(con_cae) + len(sin_cae) + len(errores)


    filas_con = "".join(
        "<tr><td>" + fid + "</td><td>" + num + "</td>"
        "<td style='color:#1a7f3c;font-weight:bold'>" + cae + "</td></tr>"
        for fid, num, cae in con_cae
    )
    filas_sin = "".join(
        "<tr><td>" + fid + "</td><td>" + num + "</td>"
        "<td style='color:#c0392b;font-weight:bold'>Sin CAE</td></tr>"
        for fid, num in sin_cae
    )
    filas_err = "".join(
        "<tr><td>" + fid + "</td>"
        "<td colspan='2' style='color:#e67e22'>" + err + "</td></tr>"
        for fid, err in errores
    )


    seccion_con = (
        "<h3 style='color:#1a7f3c'>Facturas CON CAE (" + str(len(con_cae)) + ")</h3>"
        "<table><thead><tr><th>ID</th><th>Numero Comprobante</th><th>CAE</th></tr></thead>"
        "<tbody>" + filas_con + "</tbody></table>"
    ) if con_cae else ""


    seccion_sin = (
        "<h3 style='color:#c0392b'>Facturas SIN CAE (" + str(len(sin_cae)) + ")</h3>"
        "<table><thead><tr><th>ID</th><th>Numero Comprobante</th><th>Estado</th></tr></thead>"
        "<tbody>" + filas_sin + "</tbody></table>"
    ) if sin_cae else ""


    seccion_err = (
        "<h3 style='color:#e67e22'>Errores (" + str(len(errores)) + ")</h3>"
        "<table><thead><tr><th>ID</th><th colspan='2'>Detalle</th></tr></thead>"
        "<tbody>" + filas_err + "</tbody></table>"
    ) if errores else ""


    badge_err = (
        "<span style='color:#e67e22'> Errores: <strong>" + str(len(errores)) + "</strong></span>"
    ) if errores else ""


    return (
        "<!DOCTYPE html><html lang='es'><head><meta charset='UTF-8'>"
        "<style>"
        "body{font-family:Arial,sans-serif;padding:24px;color:#333}"
        "h2{color:#2c3e50;border-bottom:2px solid #4a90d9;padding-bottom:6px}"
        "h3{margin-top:28px}"
        ".resumen{background:#eaf2fb;border-left:5px solid #4a90d9;"
        "padding:14px 18px;border-radius:4px;margin-bottom:24px}"
        ".resumen span{margin-right:20px;font-size:1.05em}"
        "table{border-collapse:collapse;width:100%;margin-top:8px}"
        "th{background:#4a90d9;color:#fff;padding:9px 14px;text-align:left}"
        "td{padding:8px 14px;border-bottom:1px solid #dde4ec}"
        "tr:hover td{background:#f4f8fe}"
        "</style></head><body>"
        "<h2>Verificacion de CAE - Facturas de Venta</h2>"
        "<div class='resumen'>"
        "<span>Total procesadas: <strong>" + str(total) + "</strong></span>"
        "<span style='color:#1a7f3c'>Con CAE: <strong>" + str(len(con_cae)) + "</strong></span>"
        "<span style='color:#c0392b'>Sin CAE: <strong>" + str(len(sin_cae)) + "</strong></span>"
        + badge_err +
        "</div>"
        + seccion_con + seccion_sin + seccion_err +
        "</body></html>"
    )




# ─────────────────────────────────────────────
# PUNTO DE ENTRADA
# ─────────────────────────────────────────────
def main():
    # 1. Leer registros seleccionados del body
    records = _get_selected_records()


    if not records:
        return HTTPResponse(
            400,
            body=json.dumps(
                {"error": "No se recibieron registros. Selecciona al menos una factura antes de ejecutar."},
                ensure_ascii=False,
            ),
        )


    # 2. Clasificar según presencia de CAE
    con_cae, sin_cae, errores = _clasificar_facturas(records)


    # 3. Construir y retornar respuesta HTML
    html = _build_html(con_cae, sin_cae, errores)


    return HTTPResponse(200, body=html)

2 - Bproc: En este caso se utilizó un bproc de tipo viewer y se seleccionó la viewer Facturas de Venta


En el campo URL se pega la obtenida en el guest code

Resultado

Desde la grilla de facturas de venta se seleccionan las facturas que se quieren consultar si tienen cae.

Se presiona el botón consultar cae