feat(contratos): gestión de códigos de pago + asignación por contrato
- Nueva tabla SQLite codigos_pago (codigo, nombre) con seed CIAC/CR/MU - Columna cod_forma_pago en contratos (override por contrato) - Página contratos: tarjeta para agregar/eliminar códigos, select inline por fila - generar_factura_venta acepta forma_pago_override; si asignado lo usa, sino auto CIAC/CR - Rutas: /codigos-pago/create, /codigos-pago/delete, /set-forma-pago Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 4.6
parent
551dec9c11
commit
91dbcc8135
+64
-2
@@ -141,13 +141,30 @@ def load_excluded_ventas_set() -> set:
|
||||
return result
|
||||
|
||||
|
||||
def load_forma_pago_map() -> dict:
|
||||
"""Devuelve {numero_contrato: cod_forma_pago} para contratos con forma de pago asignada."""
|
||||
conn = get_connection()
|
||||
rows = conn.execute("SELECT numero_contrato, cod_forma_pago FROM contratos WHERE cod_forma_pago != ''").fetchall()
|
||||
conn.close()
|
||||
result = {}
|
||||
for r in rows:
|
||||
nc = r["numero_contrato"].strip()
|
||||
result[nc] = r["cod_forma_pago"].strip()
|
||||
nc_s = nc.lstrip("0") or nc
|
||||
if nc_s != nc:
|
||||
result[nc_s] = r["cod_forma_pago"].strip()
|
||||
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()
|
||||
codigos_pago = conn.execute("SELECT * FROM codigos_pago ORDER BY codigo").fetchall()
|
||||
conn.close()
|
||||
return request.app.state.templates.TemplateResponse("contratos.html", {
|
||||
"request": request, "user": user, "contratos": rows,
|
||||
"codigos_pago": codigos_pago,
|
||||
})
|
||||
|
||||
|
||||
@@ -190,11 +207,12 @@ async def contrato_update(
|
||||
excluir: str = Form("0"),
|
||||
sin_contrato: str = Form("0"),
|
||||
excluir_ventas: str = Form("0"),
|
||||
cod_forma_pago: str = Form(""),
|
||||
):
|
||||
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),
|
||||
"UPDATE contratos SET numero_contrato=?, nit_empresa=?, tipo_usuario=?, descripcion=?, excluir=?, sin_contrato=?, excluir_ventas=?, cod_forma_pago=? WHERE id=?",
|
||||
(numero_contrato.strip(), nit_empresa.strip(), tipo_usuario.strip(), descripcion.strip(), int(excluir), int(sin_contrato), int(excluir_ventas), cod_forma_pago.strip(), contrato_id),
|
||||
)
|
||||
conn.commit()
|
||||
log_activity(user["user_id"], user["username"], "contrato_editado",
|
||||
@@ -252,6 +270,50 @@ async def toggle_excluir_ventas(contrato_id: int, request: Request, user: dict =
|
||||
return RedirectResponse("/contratos", status_code=302)
|
||||
|
||||
|
||||
@router.post("/set-forma-pago/{contrato_id}")
|
||||
async def set_forma_pago(
|
||||
contrato_id: int, request: Request, user: dict = Depends(get_current_user),
|
||||
cod_forma_pago: str = Form(""),
|
||||
):
|
||||
conn = get_connection()
|
||||
conn.execute("UPDATE contratos SET cod_forma_pago=? WHERE id=?", (cod_forma_pago.strip(), contrato_id))
|
||||
conn.commit()
|
||||
row = conn.execute("SELECT numero_contrato FROM contratos WHERE id=?", (contrato_id,)).fetchone()
|
||||
if row:
|
||||
log_activity(user["user_id"], user["username"], "contrato_forma_pago",
|
||||
f"Contrato {row['numero_contrato']} forma_pago→{cod_forma_pago.strip() or '(auto)'}",
|
||||
get_ip(request))
|
||||
conn.close()
|
||||
return RedirectResponse("/contratos", status_code=302)
|
||||
|
||||
|
||||
@router.post("/codigos-pago/create")
|
||||
async def codigo_pago_create(
|
||||
request: Request, user: dict = Depends(get_current_user),
|
||||
codigo: str = Form(...), nombre: str = Form(""),
|
||||
):
|
||||
conn = get_connection()
|
||||
try:
|
||||
conn.execute("INSERT INTO codigos_pago (codigo, nombre) VALUES (?,?)",
|
||||
(codigo.strip().upper(), nombre.strip()))
|
||||
conn.commit()
|
||||
log_activity(user["user_id"], user["username"], "codigo_pago_creado",
|
||||
f"{codigo.strip().upper()} — {nombre.strip()}", get_ip(request))
|
||||
except Exception:
|
||||
pass
|
||||
conn.close()
|
||||
return RedirectResponse("/contratos", status_code=302)
|
||||
|
||||
|
||||
@router.post("/codigos-pago/delete/{cp_id}")
|
||||
async def codigo_pago_delete(cp_id: int, user: dict = Depends(get_current_user)):
|
||||
conn = get_connection()
|
||||
conn.execute("DELETE FROM codigos_pago WHERE id=?", (cp_id,))
|
||||
conn.commit()
|
||||
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()
|
||||
|
||||
Reference in New Issue
Block a user