Advertisement
kuroshan1104

get deuda activo por puesto

Mar 6th, 2025
89
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 7.75 KB | Source Code | 0 0
  1. import mysql.connector
  2. from collections import defaultdict
  3.  
  4. def conectar_db():
  5.     """
  6.    Conecta a la base de datos acu_v2.
  7.    Ajusta host, user, password y database según tu entorno real.
  8.    """
  9.     try:
  10.         conexion = mysql.connector.connect(
  11.             host="192.168.1.2",
  12.             user="root",
  13.             password="Perla17*+",
  14.             database="acu_v2"
  15.         )
  16.         return conexion
  17.     except mysql.connector.Error as err:
  18.         print(f"Error al conectar a la base de datos: {err}")
  19.         return None
  20.  
  21. def obtener_datos_por_dni(dni):
  22.     """
  23.    Retorna todos los puestos (activos) asociados al DNI dado,
  24.    junto con el nombre completo del socio y otros datos.
  25.    Si no hay resultados, retorna lista vacía.
  26.    """
  27.     if dni == "0":
  28.         return "atras"
  29.  
  30.     conexion = conectar_db()
  31.     if not conexion:
  32.         return []
  33.  
  34.     cursor = conexion.cursor(dictionary=True)
  35.     query = """
  36.        SELECT  
  37.            g_persona.ndoc,
  38.            g_persona.nomcompleto,
  39.            p_puesto.codigo,
  40.            p_puesto.codigo_ant,
  41.            p_giro.des_giro
  42.        FROM g_persona
  43.        INNER JOIN p_puesto_socio
  44.            ON p_puesto_socio.idsocio = g_persona.idpersona
  45.        INNER JOIN p_puesto
  46.            ON p_puesto.idpuesto = p_puesto_socio.idpuesto
  47.        INNER JOIN p_giro
  48.            ON p_puesto.idgiro = p_giro.idgiro
  49.        WHERE
  50.            g_persona.ndoc = %s
  51.            AND p_puesto.activo = 1
  52.            AND p_puesto_socio.activo = 1
  53.    """
  54.     cursor.execute(query, (dni,))
  55.     resultados = cursor.fetchall()
  56.     cursor.close()
  57.     conexion.close()
  58.     return resultados
  59.  
  60. def obtener_deuda_detallada(codigo_puesto):
  61.     """
  62.    Retorna el detalle de las deudas activas para el puesto cuyo 'codigo_puesto' se indica,
  63.    usando LEFT JOIN con d_periodo para permitir idperiodo NULL y filtrando por saldo > 0,
  64.    estado <> 'BA' y condicion = 1.
  65.    """
  66.     conexion = conectar_db()
  67.     if not conexion:
  68.         return []
  69.  
  70.     cursor = conexion.cursor(dictionary=True)
  71.     query = """
  72.        SELECT
  73.            c.descripcion       AS CONCEPTO,
  74.            p.anio              AS ANIO,
  75.            p.nperiodo          AS NPERIODO,
  76.            p.fini              AS FINI,       -- Puede ser NULL si no hay periodo
  77.            p.ffin              AS FFIN,       -- Puede ser NULL si no hay periodo
  78.            d.cargo             AS CARGO,
  79.            d.saldo             AS SALDO,
  80.            d.moneda            AS MONEDA,
  81.            pp.codigo           AS CODIGO,
  82.            pp.codigo_ant       AS CODIGO_ANT,
  83.            gp.nomcompleto      AS NOMBRE
  84.        FROM d_deuda d
  85.        INNER JOIN d_deuda_puesto dp
  86.            ON d.ideuda = dp.ideuda
  87.        INNER JOIN p_puesto pp
  88.            ON dp.idpuesto = pp.idpuesto
  89.        INNER JOIN p_puesto_socio pps
  90.            ON pp.idpuesto = pps.idpuesto
  91.            AND d.idpersona = pps.idsocio
  92.        INNER JOIN g_persona gp
  93.            ON d.idpersona = gp.idpersona
  94.        INNER JOIN d_concepto c
  95.            ON d.idconcepto = c.idconcepto
  96.        -- IMPORTANTE: LEFT JOIN para permitir idperiodo NULL
  97.        LEFT JOIN d_periodo p
  98.            ON d.idperiodo = p.idperiodo
  99.        WHERE
  100.            pp.codigo = %s
  101.            AND pp.activo = 1
  102.            AND pps.activo = 1
  103.            AND d.estado <> 'BA'
  104.            AND d.condicion = 1
  105.            AND d.saldo > 0
  106.        ORDER BY
  107.            p.anio DESC,
  108.            p.nperiodo DESC
  109.    """
  110.     cursor.execute(query, (codigo_puesto,))
  111.     filas = cursor.fetchall()
  112.     cursor.close()
  113.     conexion.close()
  114.     return filas
  115.  
  116. def mostrar_deuda_detallada(filas):
  117.     """
  118.    Muestra la deuda agrupada por 'CONCEPTO' (columna 'descripcion' de d_concepto),
  119.    con subtotales y un total general. Maneja p.anio, p.nperiodo, p.fini, p.ffin si son NULL.
  120.    """
  121.     if not filas:
  122.         print("No se encontraron deudas activas para este puesto.")
  123.         return
  124.  
  125.     # Agrupamos las filas por 'CONCEPTO'
  126.     agrupado = defaultdict(list)
  127.     for f in filas:
  128.         # Si no existe 'CONCEPTO', usamos un valor por defecto
  129.         concepto = f.get('CONCEPTO', 'SIN_CONCEPTO')
  130.         agrupado[concepto].append(f)
  131.  
  132.     total_general = 0.0
  133.  
  134.     # Recorremos cada grupo de concepto
  135.     for concepto, items in agrupado.items():
  136.         # Encabezado para cada concepto
  137.         print(f"\n{concepto.upper()}")
  138.  
  139.         # Cabecera de columnas
  140.         print("ANIO  | NPERIODO | FINI       | FFIN       | CARGO   | SALDO   | MONEDA | CODIGO  | CODIGO_ANT  | NOMBRE")
  141.        
  142.         subtotal = 0.0
  143.         for it in items:
  144.             anio       = it.get('ANIO') or ''       # Manejo de NULL
  145.             nperiodo   = it.get('NPERIODO') or ''
  146.             fini       = str(it.get('FINI') or '')
  147.             ffin       = str(it.get('FFIN') or '')
  148.             cargo      = it.get('CARGO', 0.0)
  149.             saldo      = it.get('SALDO', 0.0)
  150.             moneda     = it.get('MONEDA', '')
  151.             codigo     = it.get('CODIGO', '')
  152.             codigo_ant = it.get('CODIGO_ANT', '')
  153.             nombre     = it.get('NOMBRE', '')
  154.  
  155.             print(f"{anio:<5} | {nperiodo:<9} | {fini:<10} | {ffin:<10} | "
  156.                   f"{cargo:7.2f} | {saldo:7.2f} | {moneda:<6} | {codigo} | {codigo_ant} | {nombre}")
  157.  
  158.             subtotal += saldo
  159.  
  160.         print(f"SUB TOTAL: {subtotal:10.2f}")
  161.         total_general += subtotal
  162.  
  163.     print(f"\nTOTAL GENERAL: {total_general:10.2f}")
  164.  
  165. def menu():
  166.     """
  167.    Menú principal de búsqueda:
  168.    1) Solicita DNI, lista los puestos activos asociados,
  169.       y permite seleccionar uno para ver su detalle de deudas (agrupadas por concepto).
  170.    2) Salir
  171.    """
  172.     while True:
  173.         print("\n=== MENÚ DE CONSULTA DE DEUDAS ===")
  174.         print("1. Buscar puestos por DNI")
  175.         print("2. Salir")
  176.         opcion = input("Seleccione una opción: ").strip()
  177.  
  178.         if opcion == "1":
  179.             while True:
  180.                 print("\n(Ingrese 0 para volver al menú principal)")
  181.                 dni = input("Ingrese el DNI: ").strip()
  182.                 if dni == "0":
  183.                     break
  184.  
  185.                 puestos = obtener_datos_por_dni(dni)
  186.                 if puestos == "atras" or not puestos:
  187.                     print("NO ES SOCIO o no hay puestos activos asociados a este DNI.")
  188.                     continue
  189.  
  190.                 # Listar todos los puestos asociados a ese DNI
  191.                 print("\nSe encontraron los siguientes puestos activos para este DNI:")
  192.                 for i, reg in enumerate(puestos, start=1):
  193.                     print(f"{i}. Código: {reg['codigo']} - Nombre: {reg['nomcompleto']}")
  194.  
  195.                 eleccion = input("Seleccione el número del puesto para ver sus deudas (0 para cancelar): ").strip()
  196.                 if eleccion == "0":
  197.                     break
  198.                 if not eleccion.isdigit():
  199.                     print("Opción no válida. Intente nuevamente.")
  200.                     continue
  201.  
  202.                 idx = int(eleccion)
  203.                 if idx < 1 or idx > len(puestos):
  204.                     print("Número fuera de rango. Intente nuevamente.")
  205.                     continue
  206.  
  207.                 # Obtener el código del puesto seleccionado
  208.                 puesto_sel = puestos[idx - 1]
  209.                 codigo_puesto = puesto_sel['codigo']
  210.  
  211.                 print(f"\nConsultando deudas para el puesto: {codigo_puesto} ...")
  212.                 filas_deuda = obtener_deuda_detallada(codigo_puesto)
  213.                 mostrar_deuda_detallada(filas_deuda)
  214.                 break
  215.  
  216.         elif opcion == "2":
  217.             print("Saliendo del programa.")
  218.             break
  219.         else:
  220.             print("Opción no válida. Intente nuevamente.")
  221.  
  222. if __name__ == "__main__":
  223.     menu()
  224.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement