feat: paso 4 ventas en automation + fixes varios
- Automation: agrega Paso 4 (Ventas/Crear) con fetch _SQL_VENTAS, filtro por excluded_ventas_set, loop de envío y log de actividad - Automation: _guardar_envio ahora almacena idrecepcion y contrato para que /ventas reconozca registros enviados por automation - Contratos: corrige NameError en toggle_excluir (faltaba request: Request) - Ventas: agrega check if not q en send_one y send para evitar TypeError - Ventas HTML: agrega columna Contrato en la tabla de facturas - json_generator: normaliza etnia >2 chars a '99' (ej: 999 → 99) - json_generator: agrega campo ciudadExp usando el mismo cod_ciudad Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 4.6
parent
21eb99d18d
commit
73062af8bc
+114
-9
@@ -11,10 +11,11 @@ from app.services.json_generator import (
|
||||
generar_tercero_api,
|
||||
generar_rda_paciente,
|
||||
agrupar_por_recepcion,
|
||||
generar_factura_venta,
|
||||
)
|
||||
from app.services.api_client import get_tns_token, TNS_BASE
|
||||
from app.services.whatsapp_sync import sync_paciente, sync_todos, guardar_sync_log
|
||||
from app.routes.contratos import load_contrato_map, load_excluded_set, load_sin_contrato_set
|
||||
from app.routes.contratos import load_contrato_map, load_excluded_set, load_sin_contrato_set, load_excluded_ventas_set
|
||||
from app.utils.activity import log_activity, get_ip
|
||||
|
||||
router = APIRouter(prefix="/automation", tags=["automation"])
|
||||
@@ -152,6 +153,31 @@ ORDER BY ps.ID_PS, rel.COD_EXAMEN
|
||||
"""
|
||||
|
||||
|
||||
_SQL_VENTAS = """
|
||||
SELECT
|
||||
r.IDRECEPCION,
|
||||
r.PREFIJO,
|
||||
r.NUM_FACTURA,
|
||||
r.FECHA_RECEPCION,
|
||||
r.COD_PACIENTE,
|
||||
r.NIT_EMPRESA,
|
||||
r.VALORTOTAL,
|
||||
r.VALORDESC,
|
||||
rel.COD_EXAMEN,
|
||||
COALESCE(NULLIF(TRIM(ex.NUM_ISS), ''), TRIM(rel.COD_EXAMEN)) AS CUPS,
|
||||
rel.PRECIO,
|
||||
COALESCE(t.VALOR, rel.PRECIO) AS PRECIO_TARIFA,
|
||||
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
|
||||
ORDER BY r.IDRECEPCION
|
||||
"""
|
||||
|
||||
|
||||
def _agrupar_por_presserv(rows: list) -> dict:
|
||||
"""Agrupa filas de pre-servicios por ID_PS."""
|
||||
from collections import defaultdict
|
||||
@@ -267,11 +293,17 @@ async def preview_automation(
|
||||
return JSONResponse({"success": False, "message": f"Error BD RDA: {err2}"})
|
||||
|
||||
ok3, err3, rows_ps = fb.execute_query(_SQL_PRESERV, {"fecha_ini": fecha_ini, "fecha_fin": fecha_fin})
|
||||
fb.disconnect()
|
||||
if not ok3:
|
||||
fb.disconnect()
|
||||
return JSONResponse({"success": False, "message": f"Error BD Pre-servicios: {err3}"})
|
||||
|
||||
ok4, err4, rows_vta = fb.execute_query(_SQL_VENTAS, {"fecha_ini": fecha_ini, "fecha_fin": fecha_fin})
|
||||
fb.disconnect()
|
||||
if not ok4:
|
||||
return JSONResponse({"success": False, "message": f"Error BD Ventas: {err4}"})
|
||||
|
||||
excluded = load_excluded_set()
|
||||
excluded_ventas = load_excluded_ventas_set()
|
||||
|
||||
grupos_all = agrupar_por_recepcion(rows_rda)
|
||||
grupos = {k: v for k, v in grupos_all.items()
|
||||
@@ -345,6 +377,25 @@ async def preview_automation(
|
||||
if rda_por_pac.get(str(p.get("CODIGO", "")))
|
||||
]
|
||||
|
||||
grupos_vta_all = agrupar_por_recepcion(rows_vta)
|
||||
grupos_vta = {k: v for k, v in grupos_vta_all.items()
|
||||
if str(v[0].get("CODCONTRATO") or "").strip() not in excluded_ventas}
|
||||
|
||||
ventas_preview = []
|
||||
for id_rec, grupo_rows in grupos_vta.items():
|
||||
num_fac = str(grupo_rows[0].get("NUM_FACTURA") or "").strip()
|
||||
prefijo = str(grupo_rows[0].get("PREFIJO") or "").strip()
|
||||
venta_json = generar_factura_venta(grupo_rows, default_vendedor="00",
|
||||
default_prefijo=prefijo_def, numero_override=num_fac)
|
||||
ventas_preview.append({
|
||||
"factura": f"{prefijo}-{num_fac}",
|
||||
"paciente": str(grupo_rows[0].get("COD_PACIENTE", "")),
|
||||
"fecha": str(grupo_rows[0].get("FECHA_RECEPCION", ""))[:10],
|
||||
"contrato": str(grupo_rows[0].get("CODCONTRATO") or "").strip(),
|
||||
"examenes": len(grupo_rows),
|
||||
"json": venta_json,
|
||||
})
|
||||
|
||||
return JSONResponse({
|
||||
"success": True,
|
||||
"fecha": fecha,
|
||||
@@ -353,8 +404,10 @@ async def preview_automation(
|
||||
"examenes": total_examenes,
|
||||
"excluidos": excluidos_count,
|
||||
"preservicios": len(grupos_ps),
|
||||
"ventas": len(grupos_vta),
|
||||
"pacientes_preview": pacientes_preview,
|
||||
"preservicios_preview": preservicios_preview,
|
||||
"ventas_preview": ventas_preview,
|
||||
})
|
||||
|
||||
|
||||
@@ -401,15 +454,21 @@ async def run_automation(
|
||||
|
||||
# ── Pacientes EPS (para registrar terceros en paso 1) ─────────────────────
|
||||
ok4, err4, rows_pac_eps = fb.execute_query(_SQL_PACIENTES_EPS, {"fecha_ini": fecha_ini, "fecha_fin": fecha_fin})
|
||||
fb.disconnect()
|
||||
if not ok4:
|
||||
fb.disconnect()
|
||||
return JSONResponse({"success": False, "message": f"Error Firebird pacientes EPS: {err4}"})
|
||||
|
||||
# ── Ventas (Factura Venta) ────────────────────────────────────────────────
|
||||
ok5, err5, rows_vta = fb.execute_query(_SQL_VENTAS, {"fecha_ini": fecha_ini, "fecha_fin": fecha_fin})
|
||||
fb.disconnect()
|
||||
if not ok5:
|
||||
return JSONResponse({"success": False, "message": f"Error Firebird Ventas: {err5}"})
|
||||
|
||||
# Fusionar pacientes: particulares + EPS, deduplicando por CODIGO
|
||||
codigos_vistos = {str(r.get("CODIGO")) for r in rows_pac}
|
||||
rows_pac_todos = list(rows_pac) + [r for r in rows_pac_eps if str(r.get("CODIGO")) not in codigos_vistos]
|
||||
|
||||
if not rows_pac_todos and not rows_rda and not rows_ps:
|
||||
if not rows_pac_todos and not rows_rda and not rows_ps and not rows_vta:
|
||||
return JSONResponse({"success": False, "message": f"No hay datos para la fecha {fecha}"})
|
||||
|
||||
# ── Login TNS ─────────────────────────────────────────────────────────────
|
||||
@@ -430,6 +489,7 @@ async def run_automation(
|
||||
"paso1_terceros": {"enviados": 0, "errores": 0, "detalle": []},
|
||||
"paso2_rda": {"enviados": 0, "errores": 0, "detalle": []},
|
||||
"paso3_preserv": {"enviados": 0, "errores": 0, "detalle": []},
|
||||
"paso4_ventas": {"enviados": 0, "errores": 0, "detalle": []},
|
||||
}
|
||||
|
||||
# ── PASO 1: Enviar Terceros (particulares + EPS) ─────────────────────────
|
||||
@@ -558,27 +618,72 @@ async def run_automation(
|
||||
fecha_inicio=fecha, fecha_fin=fecha,
|
||||
servicios=len(grupo_rows))
|
||||
|
||||
# ── PASO 4: Enviar Facturas Venta ─────────────────────────────────────────
|
||||
excluded_ventas = load_excluded_ventas_set()
|
||||
grupos_vta_all = agrupar_por_recepcion(rows_vta)
|
||||
grupos_vta = {k: v for k, v in grupos_vta_all.items()
|
||||
if str(v[0].get("CODCONTRATO") or "").strip() not in excluded_ventas}
|
||||
resultado["paso4_ventas"]["excluidos"] = len(grupos_vta_all) - len(grupos_vta)
|
||||
|
||||
endpoint_venta = f"{TNS_BASE}/v2/facturacion/Ventas/Crear"
|
||||
async with httpx.AsyncClient(timeout=timeout) as client:
|
||||
for id_rec, grupo_rows in grupos_vta.items():
|
||||
num_fac = str(grupo_rows[0].get("NUM_FACTURA") or "").strip()
|
||||
prefijo = str(grupo_rows[0].get("PREFIJO") or "").strip()
|
||||
venta_json = generar_factura_venta(grupo_rows, default_vendedor="00",
|
||||
default_prefijo=prefijo_def, numero_override=num_fac)
|
||||
factura_display = f"{prefijo}-{num_fac}"
|
||||
contrato_vta = str(grupo_rows[0].get("CODCONTRATO") or "").strip()
|
||||
try:
|
||||
resp = await client.post(endpoint_venta, json=venta_json, headers=headers)
|
||||
ok = resp.is_success
|
||||
msg = resp.json().get("message", "") if ok else resp.text[:200]
|
||||
except Exception as e:
|
||||
ok = False
|
||||
msg = str(e)
|
||||
|
||||
if ok:
|
||||
resultado["paso4_ventas"]["enviados"] += 1
|
||||
else:
|
||||
resultado["paso4_ventas"]["errores"] += 1
|
||||
|
||||
resultado["paso4_ventas"]["detalle"].append({
|
||||
"factura": factura_display,
|
||||
"paciente": str(grupo_rows[0].get("COD_PACIENTE", "")),
|
||||
"examenes": len(grupo_rows),
|
||||
"ok": ok, "msg": msg,
|
||||
})
|
||||
|
||||
_guardar_envio(user["user_id"], "ventas", factura_display, venta_json, msg, ok,
|
||||
fecha_inicio=fecha, fecha_fin=fecha, servicios=len(grupo_rows),
|
||||
idrecepcion=id_rec, contrato=contrato_vta)
|
||||
|
||||
r1 = resultado["paso1_terceros"]
|
||||
r2 = resultado["paso2_rda"]
|
||||
r3 = resultado["paso3_preserv"]
|
||||
r4 = resultado["paso4_ventas"]
|
||||
log_activity(user["user_id"], user["username"], "automation_run",
|
||||
f"Fecha {fecha} | Terceros: {r1['enviados']} OK/{r1['errores']} err | "
|
||||
f"RDA: {r2['enviados']} OK/{r2['errores']} err | "
|
||||
f"PreServ: {r3['enviados']} OK/{r3['errores']} err",
|
||||
f"PreServ: {r3['enviados']} OK/{r3['errores']} err | "
|
||||
f"Ventas: {r4['enviados']} OK/{r4['errores']} err",
|
||||
get_ip(request))
|
||||
return JSONResponse({"success": True, "resultado": resultado})
|
||||
|
||||
|
||||
def _guardar_envio(user_id, tipo, factura, json_data, respuesta, ok,
|
||||
fecha_inicio=None, fecha_fin=None, servicios=0):
|
||||
fecha_inicio=None, fecha_fin=None, servicios=0,
|
||||
idrecepcion=None, contrato=None):
|
||||
try:
|
||||
conn = get_connection()
|
||||
conn.execute("""
|
||||
INSERT INTO envios (user_id, tipo, factura, fecha_inicio, fecha_fin,
|
||||
INSERT INTO envios (user_id, tipo, factura, idrecepcion, contrato,
|
||||
fecha_inicio, fecha_fin,
|
||||
pacientes_count, servicios_count, status, json_enviado, respuesta_api, created_at)
|
||||
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
||||
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
||||
""", (
|
||||
user_id, tipo, factura, fecha_inicio, fecha_fin,
|
||||
user_id, tipo, factura, idrecepcion, contrato,
|
||||
fecha_inicio, fecha_fin,
|
||||
1, servicios,
|
||||
"success" if ok else "error",
|
||||
json_lib.dumps(json_data, indent=2, ensure_ascii=False)[:10000],
|
||||
|
||||
+46
-45
@@ -7,52 +7,53 @@ from app.utils.activity import log_activity, get_ip
|
||||
router = APIRouter(prefix="/contratos", tags=["contratos"])
|
||||
|
||||
# (numero_contrato, nit_empresa, tipo_usuario, descripcion, excluir_rda, sin_contrato, excluir_ventas)
|
||||
# excluir_ventas=0 → activo para Ventas/Crear | excluir_ventas=1 → bloqueado para ventas
|
||||
_SEED = [
|
||||
("001", "860078828", "11", "EPS SANITAS", 0, 0, 0),
|
||||
("002", "830054904", "11", "EPS COMPENSAR", 0, 0, 0),
|
||||
("003", "900278729", "12", "PARTICULAR", 0, 0, 0),
|
||||
("004", "800106339", "11", "EPS NUEVA EPS", 0, 0, 0),
|
||||
("005", "800153424", "11", "EPS SURA", 0, 0, 0),
|
||||
("006", "805009741", "11", "EPS COOMEVA", 0, 0, 0),
|
||||
("007", "860002183", "11", "EPS FAMISANAR", 0, 0, 0),
|
||||
("008", "860002503", "11", "EPS CRUZ BLANCA", 0, 0, 0),
|
||||
("009", "860027404", "11", "EPS COLSANITAS", 0, 0, 0),
|
||||
("010", "860039988", "11", "EPS SALUD TOTAL", 0, 0, 0),
|
||||
("011", "890903790", "11", "EPS SAVIA SALUD", 0, 0, 0),
|
||||
("012", "900178724", "11", "EPS MUTUAL SER", 0, 0, 0),
|
||||
("034", "860078828", "11", "EPS SANITAS (alt)", 0, 0, 0),
|
||||
("035", "860078828", "11", "EPS SANITAS (alt)", 0, 0, 0),
|
||||
("036", "860078828", "11", "EPS SANITAS (alt)", 0, 0, 0),
|
||||
("20062026", "800182856", "01", "SUBSIDIADO", 0, 0, 0),
|
||||
("CW225489", "899999068", "07", "POLIZA / SEGURO", 0, 0, 0),
|
||||
# Contratos excluidos del envío TNS
|
||||
("013", "", "11", "MEDILAVORO S.A.S", 0, 0, 0),
|
||||
("014", "", "11", "LABORATORIO UROCLINICO",0, 0, 0),
|
||||
("015", "", "11", "ANDRES AFANADOR VILLAMIZAR", 1, 0, 0),
|
||||
("016", "", "11", "OMAR FERNANDO RIBERO GOMEZ", 1, 0, 0),
|
||||
("017", "", "11", "CLAUDIA BELEN JULIO SEPULVEDA", 1, 0, 0),
|
||||
("018", "", "11", "LABORATORIO MICROBIOLOGICO - MARGIE OJEDA", 1, 0, 0),
|
||||
("019", "", "11", "LABORATORIO TOXICOLOGICO - MARTHA MORALES", 1, 0, 0),
|
||||
("020", "", "11", "MARTHA LUCIA GALLARDO", 1, 0, 0),
|
||||
("021", "", "11", "LABORATORIO VILMA OROZCO AYALA", 1, 0, 0),
|
||||
("022", "", "11", "CLINICA SAN JOSE DE CUCUTA", 1, 0, 0),
|
||||
("023", "", "11", "URONORTE S.A", 1, 0, 0),
|
||||
("024", "", "11", "LABORATORIO CLINICO BIOLAB S.A.S", 1, 0, 0),
|
||||
("025", "", "11", "JOEL LEONARDO CARRILLO CORREDOR", 1, 0, 0),
|
||||
("026", "", "11", "ROLANDO IVAN PENARANDA DEVIA", 1, 0, 0),
|
||||
("027", "", "11", "JOSE WILMER GARCIA CALDERON", 1, 0, 0),
|
||||
("028", "", "11", "ONCOMEDICAL IPS S.A.S", 1, 0, 0),
|
||||
("029", "", "11", "GENETIX S.A.S", 1, 0, 0),
|
||||
("030", "", "11", "NORFETUS S.A.S", 1, 0, 0),
|
||||
("031", "", "11", "TBTB GLOBAL LAB S.A.S", 1, 0, 0),
|
||||
("032", "", "11", "COLGENES S.A.S", 1, 0, 0),
|
||||
("033", "", "11", "IPS FIGURAS SPA CUCUTA S.A.S", 1, 0, 0),
|
||||
("037", "", "11", "CLINICA URGENCIAS LA MERCED", 1, 0, 0),
|
||||
("038", "", "11", "CLINICA COLSANITAS S.A.", 1, 0, 0),
|
||||
("039", "", "11", "GOMEZ GIL JOSE JESUS", 1, 0, 0),
|
||||
("001", "860078828", "11", "EPS SANITAS", 0, 0, 1),
|
||||
("002", "830054904", "11", "EPS COMPENSAR", 0, 0, 1),
|
||||
("003", "900278729", "12", "PARTICULAR", 0, 0, 1),
|
||||
("004", "800106339", "11", "EPS NUEVA EPS", 0, 0, 1),
|
||||
("005", "800153424", "11", "EPS SURA", 0, 0, 1),
|
||||
("006", "805009741", "11", "EPS COOMEVA", 0, 0, 1),
|
||||
("007", "860002183", "11", "EPS FAMISANAR", 0, 0, 1),
|
||||
("008", "860002503", "11", "EPS CRUZ BLANCA", 0, 0, 1),
|
||||
("009", "860027404", "11", "EPS COLSANITAS", 0, 0, 1),
|
||||
("010", "860039988", "11", "EPS SALUD TOTAL", 0, 0, 1),
|
||||
("011", "890903790", "11", "EPS SAVIA SALUD", 0, 0, 1),
|
||||
("012", "900178724", "11", "EPS MUTUAL SER", 0, 0, 1),
|
||||
("034", "860078828", "11", "EPS SANITAS (alt)", 0, 0, 1),
|
||||
("035", "860078828", "11", "EPS SANITAS (alt)", 0, 0, 1),
|
||||
("036", "860078828", "11", "EPS SANITAS (alt)", 0, 0, 1),
|
||||
("20062026", "800182856", "01", "SUBSIDIADO", 0, 0, 1),
|
||||
("CW225489", "899999068", "07", "POLIZA / SEGURO", 0, 0, 1),
|
||||
# Contratos excluidos del envío RDA
|
||||
("013", "", "11", "MEDILAVORO S.A.S", 0, 0, 1),
|
||||
("014", "", "11", "LABORATORIO UROCLINICO",0, 0, 1),
|
||||
("015", "", "11", "ANDRES AFANADOR VILLAMIZAR", 1, 0, 1),
|
||||
("016", "", "11", "OMAR FERNANDO RIBERO GOMEZ", 1, 0, 1),
|
||||
("017", "", "11", "CLAUDIA BELEN JULIO SEPULVEDA", 1, 0, 1),
|
||||
("018", "", "11", "LABORATORIO MICROBIOLOGICO - MARGIE OJEDA", 1, 0, 1),
|
||||
("019", "", "11", "LABORATORIO TOXICOLOGICO - MARTHA MORALES", 1, 0, 1),
|
||||
("020", "", "11", "MARTHA LUCIA GALLARDO", 1, 0, 1),
|
||||
("021", "", "11", "LABORATORIO VILMA OROZCO AYALA", 1, 0, 1),
|
||||
("022", "", "11", "CLINICA SAN JOSE DE CUCUTA", 1, 0, 1),
|
||||
("023", "", "11", "URONORTE S.A", 1, 0, 1),
|
||||
("024", "", "11", "LABORATORIO CLINICO BIOLAB S.A.S", 1, 0, 1),
|
||||
("025", "", "11", "JOEL LEONARDO CARRILLO CORREDOR", 1, 0, 1),
|
||||
("026", "", "11", "ROLANDO IVAN PENARANDA DEVIA", 1, 0, 1),
|
||||
("027", "", "11", "JOSE WILMER GARCIA CALDERON", 1, 0, 1),
|
||||
("028", "", "11", "ONCOMEDICAL IPS S.A.S", 1, 0, 1),
|
||||
("029", "", "11", "GENETIX S.A.S", 1, 0, 1),
|
||||
("030", "", "11", "NORFETUS S.A.S", 1, 0, 1),
|
||||
("031", "", "11", "TBTB GLOBAL LAB S.A.S", 1, 0, 1),
|
||||
("032", "", "11", "COLGENES S.A.S", 1, 0, 1),
|
||||
("033", "", "11", "IPS FIGURAS SPA CUCUTA S.A.S", 1, 0, 1),
|
||||
("037", "", "11", "CLINICA URGENCIAS LA MERCED", 1, 0, 1),
|
||||
("038", "", "11", "CLINICA COLSANITAS S.A.", 1, 0, 1),
|
||||
("039", "", "11", "GOMEZ GIL JOSE JESUS", 1, 0, 1),
|
||||
("040", "", "11", "MARTHA LILIANA SALGAR GALLEGO", 1, 1, 0),
|
||||
("041", "", "11", "GENCELL PHARMA S.A.S", 1, 0, 0),
|
||||
("042", "", "07", "AXA COLPATRIA HYC", 1, 0, 0),
|
||||
("041", "", "11", "GENCELL PHARMA S.A.S", 1, 0, 1),
|
||||
("042", "", "07", "AXA COLPATRIA HYC", 1, 0, 1),
|
||||
]
|
||||
|
||||
|
||||
@@ -200,7 +201,7 @@ async def contrato_update(
|
||||
|
||||
|
||||
@router.post("/toggle-excluir/{contrato_id}")
|
||||
async def toggle_excluir(contrato_id: int, user: dict = Depends(get_current_user)):
|
||||
async def toggle_excluir(contrato_id: int, request: Request, user: dict = Depends(get_current_user)):
|
||||
conn = get_connection()
|
||||
conn.execute(
|
||||
"UPDATE contratos SET excluir = CASE WHEN excluir=1 THEN 0 ELSE 1 END WHERE id=?",
|
||||
|
||||
@@ -188,7 +188,7 @@ ORDER BY ps.ID_PS, rel.COD_EXAMEN""",
|
||||
"description": "Pre-servicio por número PS (buscar RCXC05291 → escribe solo el número)"
|
||||
},
|
||||
{
|
||||
"name": "Factura Venta 040 por fecha",
|
||||
"name": "Factura Venta por fecha",
|
||||
"query_type": "ventas",
|
||||
"query_text": """SELECT
|
||||
r.IDRECEPCION,
|
||||
@@ -203,19 +203,18 @@ ORDER BY ps.ID_PS, rel.COD_EXAMEN""",
|
||||
COALESCE(NULLIF(TRIM(ex.NUM_ISS), ''), TRIM(rel.COD_EXAMEN)) AS CUPS,
|
||||
rel.PRECIO,
|
||||
COALESCE(t.VALOR, rel.PRECIO) AS PRECIO_TARIFA,
|
||||
e.CODCONTRATO
|
||||
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 TRIM(e.CODCONTRATO) = '040'
|
||||
ORDER BY r.IDRECEPCION""",
|
||||
"description": "Facturas de venta contrato 040 en un rango de fechas"
|
||||
"description": "Facturas de venta en un rango de fechas (filtra por excluir_ventas en /contratos)"
|
||||
},
|
||||
{
|
||||
"name": "Factura Venta 040 por número",
|
||||
"name": "Factura Venta por número",
|
||||
"query_type": "ventas",
|
||||
"query_text": """SELECT
|
||||
r.IDRECEPCION,
|
||||
@@ -230,15 +229,14 @@ ORDER BY r.IDRECEPCION""",
|
||||
COALESCE(NULLIF(TRIM(ex.NUM_ISS), ''), TRIM(rel.COD_EXAMEN)) AS CUPS,
|
||||
rel.PRECIO,
|
||||
COALESCE(t.VALOR, rel.PRECIO) AS PRECIO_TARIFA,
|
||||
e.CODCONTRATO
|
||||
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.NUM_FACTURA = :num_factura
|
||||
AND TRIM(e.CODCONTRATO) = '040'""",
|
||||
"description": "Factura de venta contrato 040 por número de factura"
|
||||
WHERE r.NUM_FACTURA = :num_factura""",
|
||||
"description": "Factura de venta por número (filtra por excluir_ventas en /contratos)"
|
||||
},
|
||||
]
|
||||
|
||||
|
||||
@@ -188,6 +188,8 @@ async def send_one(
|
||||
q = conn.execute("SELECT * FROM queries WHERE id = ?", (query_id,)).fetchone()
|
||||
cfg = {r["key"]: r["value"] for r in conn.execute("SELECT * FROM config").fetchall()}
|
||||
conn.close()
|
||||
if not q:
|
||||
return JSONResponse({"success": False, "message": "Consulta no encontrada"})
|
||||
|
||||
rows, err = _query_rows(cfg, q["query_text"], factura, fecha_inicio, fecha_fin)
|
||||
if rows is None:
|
||||
@@ -243,6 +245,8 @@ async def send_ventas(
|
||||
q = conn.execute("SELECT * FROM queries WHERE id = ?", (query_id,)).fetchone()
|
||||
cfg = {r["key"]: r["value"] for r in conn.execute("SELECT * FROM config").fetchall()}
|
||||
conn.close()
|
||||
if not q:
|
||||
return JSONResponse({"success": False, "message": "Consulta no encontrada"})
|
||||
|
||||
rows, err = _query_rows(cfg, q["query_text"], factura, fecha_inicio, fecha_fin)
|
||||
if rows is None:
|
||||
|
||||
Reference in New Issue
Block a user