Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
262 lines
12 KiB
Python
262 lines
12 KiB
Python
from fastapi import APIRouter, Request, Form, Depends
|
|
from fastapi.responses import RedirectResponse, JSONResponse
|
|
from app.database import get_connection
|
|
from app.auth import get_current_user
|
|
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, 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, 1),
|
|
("042", "", "07", "AXA COLPATRIA HYC", 1, 0, 1),
|
|
("050", "", "12", "PARTICULAR COLEGAS", 0, 0, 0),
|
|
]
|
|
|
|
|
|
def ensure_defaults():
|
|
conn = get_connection()
|
|
for nc, nit, tu, desc, excluir, sin_contrato, excluir_ventas in _SEED:
|
|
exists = conn.execute(
|
|
"SELECT id FROM contratos WHERE numero_contrato = ?", (nc,)
|
|
).fetchone()
|
|
if not exists:
|
|
conn.execute(
|
|
"INSERT INTO contratos (numero_contrato, nit_empresa, tipo_usuario, descripcion, excluir, sin_contrato, excluir_ventas) VALUES (?,?,?,?,?,?,?)",
|
|
(nc, nit, tu, desc, excluir, sin_contrato, excluir_ventas),
|
|
)
|
|
else:
|
|
# Solo actualiza datos descriptivos; los toggles (excluir/sin_contrato/excluir_ventas)
|
|
# se conservan tal como el usuario los dejó desde la UI
|
|
conn.execute(
|
|
"UPDATE contratos SET nit_empresa=?, tipo_usuario=?, descripcion=? WHERE numero_contrato=?",
|
|
(nit, tu, desc, nc),
|
|
)
|
|
conn.commit()
|
|
conn.close()
|
|
|
|
|
|
def load_contrato_map() -> dict:
|
|
"""Devuelve {numero_contrato: tipo_usuario} incluyendo variante sin ceros a la izquierda."""
|
|
conn = get_connection()
|
|
rows = conn.execute("SELECT numero_contrato, tipo_usuario FROM contratos").fetchall()
|
|
conn.close()
|
|
result = {}
|
|
for r in rows:
|
|
nc = r["numero_contrato"].strip()
|
|
tu = r["tipo_usuario"].strip()
|
|
result[nc] = tu
|
|
nc_s = nc.lstrip("0") or nc
|
|
if nc_s != nc:
|
|
result[nc_s] = tu
|
|
return result
|
|
|
|
|
|
def load_sin_contrato_set() -> set:
|
|
"""Devuelve set de numero_contrato marcados como sin_contrato=1 (se envían con numeroContrato: null)."""
|
|
conn = get_connection()
|
|
rows = conn.execute("SELECT numero_contrato FROM contratos WHERE sin_contrato=1").fetchall()
|
|
conn.close()
|
|
result = set()
|
|
for r in rows:
|
|
nc = r["numero_contrato"].strip()
|
|
result.add(nc)
|
|
nc_s = nc.lstrip("0") or nc
|
|
if nc_s != nc:
|
|
result.add(nc_s)
|
|
return result
|
|
|
|
|
|
def load_excluded_set() -> set:
|
|
"""Devuelve set de numero_contrato marcados como excluir=1 (bloqueados para RDA)."""
|
|
conn = get_connection()
|
|
rows = conn.execute("SELECT numero_contrato FROM contratos WHERE excluir=1").fetchall()
|
|
conn.close()
|
|
result = set()
|
|
for r in rows:
|
|
nc = r["numero_contrato"].strip()
|
|
result.add(nc)
|
|
nc_s = nc.lstrip("0") or nc
|
|
if nc_s != nc:
|
|
result.add(nc_s)
|
|
return result
|
|
|
|
|
|
def load_excluded_ventas_set() -> set:
|
|
"""Devuelve set de numero_contrato marcados como excluir_ventas=1 (bloqueados para Ventas)."""
|
|
conn = get_connection()
|
|
rows = conn.execute("SELECT numero_contrato FROM contratos WHERE excluir_ventas=1").fetchall()
|
|
conn.close()
|
|
result = set()
|
|
for r in rows:
|
|
nc = r["numero_contrato"].strip()
|
|
result.add(nc)
|
|
nc_s = nc.lstrip("0") or nc
|
|
if nc_s != nc:
|
|
result.add(nc_s)
|
|
return result
|
|
|
|
|
|
@router.get("")
|
|
async def contratos_page(request: Request, user: dict = Depends(get_current_user)):
|
|
conn = get_connection()
|
|
rows = conn.execute("SELECT * FROM contratos ORDER BY numero_contrato").fetchall()
|
|
conn.close()
|
|
return request.app.state.templates.TemplateResponse("contratos.html", {
|
|
"request": request, "user": user, "contratos": rows,
|
|
})
|
|
|
|
|
|
@router.post("/create")
|
|
async def contrato_create(
|
|
request: Request,
|
|
user: dict = Depends(get_current_user),
|
|
numero_contrato: str = Form(...),
|
|
nit_empresa: str = Form(""),
|
|
tipo_usuario: str = Form(...),
|
|
descripcion: str = Form(""),
|
|
excluir: str = Form("0"),
|
|
sin_contrato: str = Form("0"),
|
|
excluir_ventas: str = Form("0"),
|
|
):
|
|
conn = get_connection()
|
|
try:
|
|
conn.execute(
|
|
"INSERT INTO contratos (numero_contrato, nit_empresa, tipo_usuario, descripcion, excluir, sin_contrato, excluir_ventas) VALUES (?,?,?,?,?,?,?)",
|
|
(numero_contrato.strip(), nit_empresa.strip(), tipo_usuario.strip(), descripcion.strip(), int(excluir), int(sin_contrato), int(excluir_ventas)),
|
|
)
|
|
conn.commit()
|
|
log_activity(user["user_id"], user["username"], "contrato_creado",
|
|
f"Contrato {numero_contrato.strip()} — {descripcion.strip()}", get_ip(request))
|
|
except Exception:
|
|
pass
|
|
conn.close()
|
|
return RedirectResponse("/contratos", status_code=302)
|
|
|
|
|
|
@router.post("/update/{contrato_id}")
|
|
async def contrato_update(
|
|
contrato_id: int,
|
|
request: Request,
|
|
user: dict = Depends(get_current_user),
|
|
numero_contrato: str = Form(...),
|
|
nit_empresa: str = Form(""),
|
|
tipo_usuario: str = Form(...),
|
|
descripcion: str = Form(""),
|
|
excluir: str = Form("0"),
|
|
sin_contrato: str = Form("0"),
|
|
excluir_ventas: str = Form("0"),
|
|
):
|
|
conn = get_connection()
|
|
conn.execute(
|
|
"UPDATE contratos SET numero_contrato=?, nit_empresa=?, tipo_usuario=?, descripcion=?, excluir=?, sin_contrato=?, excluir_ventas=? WHERE id=?",
|
|
(numero_contrato.strip(), nit_empresa.strip(), tipo_usuario.strip(), descripcion.strip(), int(excluir), int(sin_contrato), int(excluir_ventas), contrato_id),
|
|
)
|
|
conn.commit()
|
|
log_activity(user["user_id"], user["username"], "contrato_editado",
|
|
f"Contrato {numero_contrato.strip()} — {descripcion.strip()}", get_ip(request))
|
|
conn.close()
|
|
return RedirectResponse("/contratos", status_code=302)
|
|
|
|
|
|
@router.post("/toggle-excluir/{contrato_id}")
|
|
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=?",
|
|
(contrato_id,)
|
|
)
|
|
conn.commit()
|
|
row = conn.execute("SELECT numero_contrato, excluir FROM contratos WHERE id=?", (contrato_id,)).fetchone()
|
|
if row:
|
|
estado = "excluido" if row["excluir"] else "activado"
|
|
log_activity(user["user_id"], user["username"], "contrato_toggle",
|
|
f"Contrato {row['numero_contrato']} → {estado}", get_ip(request))
|
|
conn.close()
|
|
return RedirectResponse("/contratos", status_code=302)
|
|
|
|
|
|
@router.post("/toggle-sin-contrato/{contrato_id}")
|
|
async def toggle_sin_contrato(contrato_id: int, request: Request, user: dict = Depends(get_current_user)):
|
|
conn = get_connection()
|
|
conn.execute(
|
|
"UPDATE contratos SET sin_contrato = CASE WHEN sin_contrato=1 THEN 0 ELSE 1 END WHERE id=?",
|
|
(contrato_id,)
|
|
)
|
|
conn.commit()
|
|
row = conn.execute("SELECT numero_contrato, sin_contrato FROM contratos WHERE id=?", (contrato_id,)).fetchone()
|
|
if row:
|
|
log_activity(user["user_id"], user["username"], "contrato_toggle_sin_contrato",
|
|
f"Contrato {row['numero_contrato']} sin_contrato→{row['sin_contrato']}", get_ip(request))
|
|
conn.close()
|
|
return RedirectResponse("/contratos", status_code=302)
|
|
|
|
|
|
@router.post("/toggle-excluir-ventas/{contrato_id}")
|
|
async def toggle_excluir_ventas(contrato_id: int, request: Request, user: dict = Depends(get_current_user)):
|
|
conn = get_connection()
|
|
conn.execute(
|
|
"UPDATE contratos SET excluir_ventas = CASE WHEN excluir_ventas=1 THEN 0 ELSE 1 END WHERE id=?",
|
|
(contrato_id,)
|
|
)
|
|
conn.commit()
|
|
row = conn.execute("SELECT numero_contrato, excluir_ventas FROM contratos WHERE id=?", (contrato_id,)).fetchone()
|
|
if row:
|
|
log_activity(user["user_id"], user["username"], "contrato_toggle_ventas",
|
|
f"Contrato {row['numero_contrato']} excluir_ventas→{row['excluir_ventas']}", get_ip(request))
|
|
conn.close()
|
|
return RedirectResponse("/contratos", status_code=302)
|
|
|
|
|
|
@router.post("/delete/{contrato_id}")
|
|
async def contrato_delete(contrato_id: int, user: dict = Depends(get_current_user)):
|
|
conn = get_connection()
|
|
conn.execute("DELETE FROM contratos WHERE id = ?", (contrato_id,))
|
|
conn.commit()
|
|
conn.close()
|
|
return RedirectResponse("/contratos", status_code=302)
|