diff --git a/app/routes/debug_fb.py b/app/routes/debug_fb.py index 6cebcf8..08e0f7e 100644 --- a/app/routes/debug_fb.py +++ b/app/routes/debug_fb.py @@ -267,6 +267,88 @@ async def debug_cmxc( return JSONResponse({"ok": False, "traceback": traceback.format_exc()}) +@router.get("/preview-ventas") +async def debug_preview_ventas( + fecha: str = Query(default="", description="YYYY-MM-DD"), + user: dict = Depends(get_current_user), +): + """Corre la lógica completa de ventas del preview y muestra cada paso.""" + from datetime import date as date_cls + from collections import defaultdict + if not fecha: + fecha = date_cls.today().isoformat() + fecha_ini = f"{fecha} 00:00:00" + fecha_fin = f"{fecha} 23:59:59" + try: + conn = get_connection() + cfg = {r["key"]: r["value"] for r in conn.execute("SELECT * FROM config").fetchall()} + excluded_ventas = set( + r["numero_contrato"] + for r in conn.execute("SELECT numero_contrato FROM contratos WHERE excluir_ventas=1").fetchall() + ) + conn.close() + + fb, ok, msg = get_firebird_from_config(cfg) + if not ok: + return JSONResponse({"ok": False, "error": msg}) + + ok_vta, err_vta, rows_vta = fb.execute_query(""" + SELECT + r.IDRECEPCION, r.PREFIJO, r.NUM_FACTURA, + r.COD_PACIENTE, r.NIT_EMPRESA, r.VALORTOTAL, + rel.COD_EXAMEN, + TRIM(e.CODCONTRATO) AS CODCONTRATO + FROM RECEPCION r + JOIN RELACION rel ON rel.IDRECEPCION = r.IDRECEPCION + LEFT JOIN EXAMEN ex ON TRIM(ex.CODIGO) = TRIM(rel.COD_EXAMEN) + LEFT JOIN EMPRESA e ON e.NIT = r.NIT_EMPRESA + LEFT JOIN TARIFA t ON TRIM(t.COD_EXAMEN) = TRIM(rel.COD_EXAMEN) AND t.TARIFA = e.TARIFA + WHERE r.FECHA_RECEPCION BETWEEN :fecha_ini AND :fecha_fin + AND r.PREFIJO = 'CMXC' + ORDER BY r.IDRECEPCION + """, {"fecha_ini": fecha_ini, "fecha_fin": fecha_fin}) + fb.disconnect() + + if not ok_vta: + return JSONResponse({"ok": False, "sql_error": err_vta}) + + # Agrupar por NUM_FACTURA + grupos: dict = defaultdict(list) + for row in (rows_vta or []): + key = str(row.get("NUM_FACTURA") or "") + grupos[key].append(dict(row)) + + pasos = [] + grupos_finales = {} + for k, v in grupos.items(): + paso = {"key": k, "filas": len(v), + "num_factura": v[0].get("NUM_FACTURA"), + "codcontrato": v[0].get("CODCONTRATO"), + "es_lista": isinstance(v, list), + "motivo_exclusion": None} + if not isinstance(v, list) or not v: + paso["motivo_exclusion"] = "no_es_lista_o_vacia" + elif int(v[0].get("NUM_FACTURA") or 0) == 0: + paso["motivo_exclusion"] = "num_factura_cero" + elif str(v[0].get("CODCONTRATO") or "").strip() in excluded_ventas: + paso["motivo_exclusion"] = f"contrato_excluido ({v[0].get('CODCONTRATO')})" + else: + grupos_finales[k] = v + pasos.append(paso) + + return JSONResponse({ + "ok": True, + "fecha": fecha, + "rows_vta_count": len(rows_vta or []), + "grupos_count": len(grupos), + "grupos_finales_count": len(grupos_finales), + "pasos": pasos, + "excluded_ventas_set": sorted(excluded_ventas), + }) + except Exception: + return JSONResponse({"ok": False, "traceback": traceback.format_exc()}) + + @router.get("/cups") async def find_cups(request: Request, user: dict = Depends(get_current_user)): try: