Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import mysql.connector
- from collections import defaultdict
- def conectar_db():
- """
- Conecta a la base de datos acu_v2.
- Ajusta host, user, password y database según tu entorno real.
- """
- try:
- conexion = mysql.connector.connect(
- host="192.168.1.2",
- user="root",
- password="Perla17*+",
- database="acu_v2"
- )
- return conexion
- except mysql.connector.Error as err:
- print(f"Error al conectar a la base de datos: {err}")
- return None
- def obtener_datos_por_dni(dni):
- """
- Retorna todos los puestos (activos) asociados al DNI dado,
- junto con el nombre completo del socio y otros datos.
- Si no hay resultados, retorna lista vacía.
- """
- if dni == "0":
- return "atras"
- conexion = conectar_db()
- if not conexion:
- return []
- cursor = conexion.cursor(dictionary=True)
- query = """
- SELECT
- g_persona.ndoc,
- g_persona.nomcompleto,
- p_puesto.codigo,
- p_puesto.codigo_ant,
- p_giro.des_giro
- FROM g_persona
- INNER JOIN p_puesto_socio
- ON p_puesto_socio.idsocio = g_persona.idpersona
- INNER JOIN p_puesto
- ON p_puesto.idpuesto = p_puesto_socio.idpuesto
- INNER JOIN p_giro
- ON p_puesto.idgiro = p_giro.idgiro
- WHERE
- g_persona.ndoc = %s
- AND p_puesto.activo = 1
- AND p_puesto_socio.activo = 1
- """
- cursor.execute(query, (dni,))
- resultados = cursor.fetchall()
- cursor.close()
- conexion.close()
- return resultados
- def obtener_deuda_detallada(codigo_puesto):
- """
- Retorna el detalle de las deudas activas para el puesto cuyo 'codigo_puesto' se indica,
- usando LEFT JOIN con d_periodo para permitir idperiodo NULL y filtrando por saldo > 0,
- estado <> 'BA' y condicion = 1.
- """
- conexion = conectar_db()
- if not conexion:
- return []
- cursor = conexion.cursor(dictionary=True)
- query = """
- SELECT
- c.descripcion AS CONCEPTO,
- p.anio AS ANIO,
- p.nperiodo AS NPERIODO,
- p.fini AS FINI, -- Puede ser NULL si no hay periodo
- p.ffin AS FFIN, -- Puede ser NULL si no hay periodo
- d.cargo AS CARGO,
- d.saldo AS SALDO,
- d.moneda AS MONEDA,
- pp.codigo AS CODIGO,
- pp.codigo_ant AS CODIGO_ANT,
- gp.nomcompleto AS NOMBRE
- FROM d_deuda d
- INNER JOIN d_deuda_puesto dp
- ON d.ideuda = dp.ideuda
- INNER JOIN p_puesto pp
- ON dp.idpuesto = pp.idpuesto
- INNER JOIN p_puesto_socio pps
- ON pp.idpuesto = pps.idpuesto
- AND d.idpersona = pps.idsocio
- INNER JOIN g_persona gp
- ON d.idpersona = gp.idpersona
- INNER JOIN d_concepto c
- ON d.idconcepto = c.idconcepto
- -- IMPORTANTE: LEFT JOIN para permitir idperiodo NULL
- LEFT JOIN d_periodo p
- ON d.idperiodo = p.idperiodo
- WHERE
- pp.codigo = %s
- AND pp.activo = 1
- AND pps.activo = 1
- AND d.estado <> 'BA'
- AND d.condicion = 1
- AND d.saldo > 0
- ORDER BY
- p.anio DESC,
- p.nperiodo DESC
- """
- cursor.execute(query, (codigo_puesto,))
- filas = cursor.fetchall()
- cursor.close()
- conexion.close()
- return filas
- def mostrar_deuda_detallada(filas):
- """
- Muestra la deuda agrupada por 'CONCEPTO' (columna 'descripcion' de d_concepto),
- con subtotales y un total general. Maneja p.anio, p.nperiodo, p.fini, p.ffin si son NULL.
- """
- if not filas:
- print("No se encontraron deudas activas para este puesto.")
- return
- # Agrupamos las filas por 'CONCEPTO'
- agrupado = defaultdict(list)
- for f in filas:
- # Si no existe 'CONCEPTO', usamos un valor por defecto
- concepto = f.get('CONCEPTO', 'SIN_CONCEPTO')
- agrupado[concepto].append(f)
- total_general = 0.0
- # Recorremos cada grupo de concepto
- for concepto, items in agrupado.items():
- # Encabezado para cada concepto
- print(f"\n{concepto.upper()}")
- # Cabecera de columnas
- print("ANIO | NPERIODO | FINI | FFIN | CARGO | SALDO | MONEDA | CODIGO | CODIGO_ANT | NOMBRE")
- subtotal = 0.0
- for it in items:
- anio = it.get('ANIO') or '' # Manejo de NULL
- nperiodo = it.get('NPERIODO') or ''
- fini = str(it.get('FINI') or '')
- ffin = str(it.get('FFIN') or '')
- cargo = it.get('CARGO', 0.0)
- saldo = it.get('SALDO', 0.0)
- moneda = it.get('MONEDA', '')
- codigo = it.get('CODIGO', '')
- codigo_ant = it.get('CODIGO_ANT', '')
- nombre = it.get('NOMBRE', '')
- print(f"{anio:<5} | {nperiodo:<9} | {fini:<10} | {ffin:<10} | "
- f"{cargo:7.2f} | {saldo:7.2f} | {moneda:<6} | {codigo} | {codigo_ant} | {nombre}")
- subtotal += saldo
- print(f"SUB TOTAL: {subtotal:10.2f}")
- total_general += subtotal
- print(f"\nTOTAL GENERAL: {total_general:10.2f}")
- def menu():
- """
- Menú principal de búsqueda:
- 1) Solicita DNI, lista los puestos activos asociados,
- y permite seleccionar uno para ver su detalle de deudas (agrupadas por concepto).
- 2) Salir
- """
- while True:
- print("\n=== MENÚ DE CONSULTA DE DEUDAS ===")
- print("1. Buscar puestos por DNI")
- print("2. Salir")
- opcion = input("Seleccione una opción: ").strip()
- if opcion == "1":
- while True:
- print("\n(Ingrese 0 para volver al menú principal)")
- dni = input("Ingrese el DNI: ").strip()
- if dni == "0":
- break
- puestos = obtener_datos_por_dni(dni)
- if puestos == "atras" or not puestos:
- print("NO ES SOCIO o no hay puestos activos asociados a este DNI.")
- continue
- # Listar todos los puestos asociados a ese DNI
- print("\nSe encontraron los siguientes puestos activos para este DNI:")
- for i, reg in enumerate(puestos, start=1):
- print(f"{i}. Código: {reg['codigo']} - Nombre: {reg['nomcompleto']}")
- eleccion = input("Seleccione el número del puesto para ver sus deudas (0 para cancelar): ").strip()
- if eleccion == "0":
- break
- if not eleccion.isdigit():
- print("Opción no válida. Intente nuevamente.")
- continue
- idx = int(eleccion)
- if idx < 1 or idx > len(puestos):
- print("Número fuera de rango. Intente nuevamente.")
- continue
- # Obtener el código del puesto seleccionado
- puesto_sel = puestos[idx - 1]
- codigo_puesto = puesto_sel['codigo']
- print(f"\nConsultando deudas para el puesto: {codigo_puesto} ...")
- filas_deuda = obtener_deuda_detallada(codigo_puesto)
- mostrar_deuda_detallada(filas_deuda)
- break
- elif opcion == "2":
- print("Saliendo del programa.")
- break
- else:
- print("Opción no válida. Intente nuevamente.")
- if __name__ == "__main__":
- menu()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement