fix: handle Firebird Decimal and datetime types in JSON serialization

- PRECIO and VALORTOTAL are Decimal from fdb driver; convert via _safe_num()
- HORAINICIORECEPCION is a datetime object; use _fmt_hora_str() for HH:MM:SS
- _parse_hora() now handles datetime objects directly (no str() roundtrip)
- Same fixes applied to pacientes.py exam builder
- sync-now endpoint catches exceptions and returns traceback as JSON

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Lizandro Guarnizo
2026-07-17 09:10:41 -05:00
co-authored by Claude Sonnet 4.6
parent fc18acc761
commit 863e012c12
3 changed files with 65 additions and 12 deletions
+25 -5
View File
@@ -113,10 +113,12 @@ async def examenes_paciente(request: Request, cedula: str = ""):
def parse_hora(raw) -> datetime | None:
if not raw:
return None
if isinstance(raw, datetime):
return ahora.replace(hour=raw.hour, minute=raw.minute, second=raw.second, microsecond=0)
s = str(raw)
try:
if "T" in s:
dt = datetime.fromisoformat(s)
if len(s) > 10 and (s[10] == "T" or s[10] == " "):
dt = datetime.fromisoformat(s.replace(" ", "T"))
return ahora.replace(hour=dt.hour, minute=dt.minute, second=dt.second, microsecond=0)
partes = s.split(":")
return ahora.replace(hour=int(partes[0]), minute=int(partes[1]),
@@ -124,6 +126,24 @@ async def examenes_paciente(request: Request, cedula: str = ""):
except Exception:
return None
def safe_num(val):
if val is None:
return None
try:
return float(val)
except Exception:
return None
def fmt_hora_str(val) -> str:
if not val:
return ""
if isinstance(val, datetime):
return val.strftime("%H:%M:%S")
s = str(val)
if len(s) > 10 and (s[10] == "T" or s[10] == " "):
return s[11:19]
return s[:8]
examenes = []
for row in rows:
hora_dt = parse_hora(row.get("HORAINICIORECEPCION"))
@@ -131,16 +151,16 @@ async def examenes_paciente(request: Request, cedula: str = ""):
continue
examenes.append({
"recepcion_id": row.get("IDRECEPCION"),
"hora": row.get("HORAINICIORECEPCION"),
"hora": fmt_hora_str(row.get("HORAINICIORECEPCION")),
"cod_examen": (row.get("COD_EXAMEN") or "").strip(),
"nombre": (row.get("NOM_EXAMEN") or "").strip(),
"cups": (row.get("CUPS") or "").strip(),
"precio": row.get("PRECIO"),
"precio": safe_num(row.get("PRECIO")),
"diagnostico_cod": (row.get("DIAG_PPAL") or "").strip(),
"diagnostico_nombre": (row.get("DIAG_CONCEPTO") or "").strip(),
"medico_docidmedico": (row.get("DOCIDMEDICO") or "").strip(),
"nit_empresa": (row.get("NIT_EMPRESA") or "").strip(),
"valor_total": row.get("VALORTOTAL"),
"valor_total": safe_num(row.get("VALORTOTAL")),
})
return JSONResponse({"ok": True, "examenes": examenes})