commit 48ea9e6d907fa012182e658150e74ffbb699f9ab Author: Juan M. Ley Date: Thu Feb 19 15:34:40 2026 -0600 primer commit diff --git a/main.py b/main.py new file mode 100644 index 0000000..aceaacb --- /dev/null +++ b/main.py @@ -0,0 +1,750 @@ +import json +from datetime import datetime +import pandas as pd + +ruta = "./estado.json" +IVA_RATE = 0.16 # 16% de IVA +LIMITE_EFECTIVO = 2000.0 + +def sumatoriaContable(cuentas: list[float]): + """Suma todos los elementos de la lista de cuentas""" + sumatoria = 0.0 + for valor in cuentas: + if isinstance(valor, (int, float)): + sumatoria += valor + return sumatoria + +def sumatoriaContableActivos(): + """Calcula la suma total de activos""" + estado['activo']['suma_activos'] = ( + estado['activo']['circulantes']['suma_activos_circulantes'] + + estado['activo']['no_circulantes']['suma_activos_no_circulantes'] + ) + +def sumatoriaContablePasivos(): + """Calcula la suma total de pasivos""" + suma_corto = sumatoriaContable([ + estado['pasivos']['corto_plazo']['acreedores'], + estado['pasivos']['corto_plazo']['documentos_por_pagar'], + estado['pasivos']['corto_plazo']['anticipo_de_clientes'], + estado['pasivos']['corto_plazo']['iva_trasladado'] + ]) + estado['pasivos']['suma_pasivos'] = suma_corto + +def actualizarSumasActivos(): + """Actualiza todas las sumas de activos circulantes y no circulantes""" + estado['activo']['circulantes']['suma_activos_circulantes'] = sumatoriaContable([ + estado['activo']['circulantes']['caja'], + estado['activo']['circulantes']['bancos'], + estado['activo']['circulantes']['inventarios'], + estado['activo']['circulantes']['iva_acreditado'], + estado['activo']['circulantes']['iva_por_acreditar'] + ]) + + estado['activo']['no_circulantes']['suma_activos_no_circulantes'] = sumatoriaContable([ + estado['activo']['no_circulantes']['edificios'], + estado['activo']['no_circulantes']['mobiliario'], + estado['activo']['no_circulantes']['papeleria'], + estado['activo']['no_circulantes']['computo'], + estado['activo']['no_circulantes']['rentas_pagadas_por_adelantado'] + ]) + + sumatoriaContableActivos() + sumatoriaContablePasivos() + +def abono(ruta_cuenta: str, monto: float): + """ + Realiza un abono a una cuenta específica usando la ruta como string + Ejemplo: abono('activo.circulantes.caja', 100.0) + """ + claves = ruta_cuenta.split('.') + cuenta = estado + + for clave in claves[:-1]: + cuenta = cuenta[clave] + + cuenta[claves[-1]] += monto + +def asientoApertura(): + """Permite ingresar fondos iniciales de las cuentas de activo""" + sel0 = 'y' + while sel0.lower() == 'y': + print("\n¿A qué cuenta deseas añadir fondos?") + print("Circulantes: \n a11 - Caja\n a12 - Bancos\n a13 - Inventarios") + print("No Circulantes: \n a21 - Edificios\n a22 - Mobiliario\n a23 - Papelería\n a24 - Cómputo\n a25 - Rentas pagadas por adelantado") + + sel1 = input("Elije: ").lower().strip() + + try: + sel2 = float(input("¿De cuánto es tu abono?: ")) + if sel2 < 0: + print("El monto debe ser positivo") + continue + except ValueError: + print("Por favor ingresa un número válido") + continue + + rutas = { + "a11": "activo.circulantes.caja", + "a12": "activo.circulantes.bancos", + "a13": "activo.circulantes.inventarios", + "a21": "activo.no_circulantes.edificios", + "a22": "activo.no_circulantes.mobiliario", + "a23": "activo.no_circulantes.papeleria", + "a24": "activo.no_circulantes.computo", + "a25": "activo.no_circulantes.rentas_pagadas_por_adelantado" + } + + if sel1 in rutas: + abono(rutas[sel1], sel2) + actualizarSumasActivos() + estado['capital_contable']['contribuido']['capital_social'] = estado['activo']['suma_activos'] + print(f"✓ Abono registrado correctamente") + else: + print("Opción no válida, intenta de nuevo") + continue + + sel0 = input("\n¿Deseas añadir algo más? (y/n): ").lower().strip() + +def obtenerCuentaBien(): + """Permite al usuario elegir qué cuenta de activo afectar con la compra""" + print("\n¿Qué tipo de bien está comprando?") + print("1 - Inventarios (mercancías)") + print("2 - Papelería") + print("3 - Cómputo") + print("4 - Mobiliario") + print("5 - Edificios") + + opcion = input("Elija: ").strip() + + rutas = { + "1": "activo.circulantes.inventarios", + "2": "activo.no_circulantes.papeleria", + "3": "activo.no_circulantes.computo", + "4": "activo.no_circulantes.mobiliario", + "5": "activo.no_circulantes.edificios" + } + + return rutas.get(opcion, None) + +def obtenerCuentaPago(monto): + """Determina de dónde se pagará según el monto""" + if monto > LIMITE_EFECTIVO: + print(f"\nMonto mayor a ${LIMITE_EFECTIVO}, el pago será desde Bancos") + return "activo.circulantes.bancos" + else: + print(f"\nMonto menor o igual a ${LIMITE_EFECTIVO}") + print("1 - Caja") + print("2 - Bancos") + opcion = input("¿De dónde desea pagar?: ").strip() + + if opcion == "2": + return "activo.circulantes.bancos" + else: + return "activo.circulantes.caja" + +def compraEfectivo(): + """ + Compra pagada en efectivo/bancos + - Aumenta cuenta del bien por subtotal + - Disminuye bancos/caja por total (subtotal + IVA) + - Aumenta IVA acreditable por monto del IVA + """ + print("\n" + "="*50) + print("COMPRA EN EFECTIVO/CONTADO") + print("="*50) + + try: + subtotal = float(input("Ingrese el subtotal de la compra: $")) + if subtotal <= 0: + print("❌ El monto debe ser positivo") + return + + iva = subtotal * IVA_RATE + total = subtotal + iva + + print(f"\nSubtotal: ${subtotal:.2f}") + print(f"IVA (16%): ${iva:.2f}") + print(f"Total: ${total:.2f}") + + cuenta_bien = obtenerCuentaBien() + if not cuenta_bien: + print("❌ Opción de bien no válida") + return + + cuenta_pago = obtenerCuentaPago(total) + + # Asientos contables + abono(cuenta_bien, subtotal) # Aumenta bien + abono(cuenta_pago, -total) # Disminuye efectivo/banco + abono("activo.circulantes.iva_acreditado", iva) # Aumenta IVA acreditable + + actualizarSumasActivos() + guardarEstado() + + print("\n✓ Compra registrada correctamente") + print(f" - Bien: +${subtotal:.2f}") + print(f" - Bancos/Caja: -${total:.2f}") + print(f" - IVA Acreditable: +${iva:.2f}") + + except ValueError: + print("❌ Ingrese valores numéricos válidos") + +def compraACredito(): + """ + Compra a crédito + - Aumenta cuenta del bien por subtotal + - Aumenta pasivo Acreedores por total + - Aumenta IVA por acreditar (no acreditable hasta pagar) + """ + print("\n" + "="*50) + print("COMPRA A CRÉDITO") + print("="*50) + + try: + subtotal = float(input("Ingrese el subtotal de la compra: $")) + if subtotal <= 0: + print("❌ El monto debe ser positivo") + return + + iva = subtotal * IVA_RATE + total = subtotal + iva + + print(f"\nSubtotal: ${subtotal:.2f}") + print(f"IVA (16%): ${iva:.2f}") + print(f"Total: ${total:.2f}") + + cuenta_bien = obtenerCuentaBien() + if not cuenta_bien: + print("❌ Opción de bien no válida") + return + + # Asientos contables + abono(cuenta_bien, subtotal) # Aumenta bien + abono("pasivos.corto_plazo.acreedores", total) # Aumenta pasivo + abono("activo.circulantes.iva_por_acreditar", iva) # Aumenta IVA por acreditar + + actualizarSumasActivos() + guardarEstado() + + print("\n✓ Compra a crédito registrada correctamente") + print(f" - Bien: +${subtotal:.2f}") + print(f" - Acreedores: +${total:.2f}") + print(f" - IVA por Acreditar: +${iva:.2f}") + + except ValueError: + print("❌ Ingrese valores numéricos válidos") + +def compraCombinada(): + """ + Compra combinada (parte en contado, parte a crédito) + - Aumenta bien por subtotal + - Disminuye bancos/caja por parte de contado (con IVA) + - Aumenta Documentos por Pagar por parte a crédito (con IVA) + - Aumenta IVA acreditable e IVA por acreditar proporcionalmente + """ + print("\n" + "="*50) + print("COMPRA COMBINADA (CONTADO + CRÉDITO)") + print("="*50) + + try: + subtotal = float(input("Ingrese el subtotal de la compra: $")) + if subtotal <= 0: + print("❌ El monto debe ser positivo") + return + + porcentaje_contado = float(input("¿Qué porcentaje es de contado? (0-100): ")) + if not (0 <= porcentaje_contado <= 100): + print("❌ El porcentaje debe estar entre 0 y 100") + return + + porcentaje_credito = 100 - porcentaje_contado + + subtotal_contado = subtotal * (porcentaje_contado / 100) + subtotal_credito = subtotal * (porcentaje_credito / 100) + + iva_total = subtotal * IVA_RATE + iva_contado = iva_total * (porcentaje_contado / 100) + iva_credito = iva_total * (porcentaje_credito / 100) + + total_contado = subtotal_contado + iva_contado + total_credito = subtotal_credito + iva_credito + + print(f"\n--- Parte Contado ({porcentaje_contado}%) ---") + print(f"Subtotal: ${subtotal_contado:.2f}") + print(f"IVA: ${iva_contado:.2f}") + print(f"Total: ${total_contado:.2f}") + + print(f"\n--- Parte Crédito ({porcentaje_credito}%) ---") + print(f"Subtotal: ${subtotal_credito:.2f}") + print(f"IVA: ${iva_credito:.2f}") + print(f"Total: ${total_credito:.2f}") + + cuenta_bien = obtenerCuentaBien() + if not cuenta_bien: + print("❌ Opción de bien no válida") + return + + cuenta_pago = obtenerCuentaPago(total_contado) + + # Asientos contables + abono(cuenta_bien, subtotal) # Aumenta bien por subtotal total + abono(cuenta_pago, -total_contado) # Disminuye bancos/caja + abono("pasivos.corto_plazo.documentos_por_pagar", total_credito) # Documentos por pagar + abono("activo.circulantes.iva_acreditado", iva_contado) # IVA acreditable + abono("activo.circulantes.iva_por_acreditar", iva_credito) # IVA por acreditar + + actualizarSumasActivos() + guardarEstado() + + print("\n✓ Compra combinada registrada correctamente") + print(f" - Bien: +${subtotal:.2f}") + print(f" - Bancos/Caja: -${total_contado:.2f}") + print(f" - Documentos por Pagar: +${total_credito:.2f}") + print(f" - IVA Acreditable: +${iva_contado:.2f}") + print(f" - IVA por Acreditar: +${iva_credito:.2f}") + + except ValueError: + print("❌ Ingrese valores numéricos válidos") + +def anticipoClientes(): + """ + Anticipo de clientes (venta futura) + - Aumenta Bancos por el total del anticipo + - Aumenta pasivo Anticipo de Clientes por subtotal + - Aumenta pasivo IVA Trasladado por el IVA + """ + print("\n" + "="*50) + print("ANTICIPO DE CLIENTES") + print("="*50) + + try: + subtotal = float(input("Ingrese el subtotal del anticipo: $")) + if subtotal <= 0: + print("❌ El monto debe ser positivo") + return + + iva = subtotal * IVA_RATE + total = subtotal + iva + + print(f"\nSubtotal: ${subtotal:.2f}") + print(f"IVA Trasladado (16%): ${iva:.2f}") + print(f"Total: ${total:.2f}") + + # Asientos contables + abono("activo.circulantes.bancos", total) # Aumenta bancos + abono("pasivos.corto_plazo.anticipo_de_clientes", subtotal) # Pasivo anticipo + abono("pasivos.corto_plazo.iva_trasladado", iva) # Pasivo IVA trasladado + + actualizarSumasActivos() + guardarEstado() + + print("\n✓ Anticipo de cliente registrado correctamente") + print(f" - Bancos: +${total:.2f}") + print(f" - Anticipo de Clientes: +${subtotal:.2f}") + print(f" - IVA Trasladado: +${iva:.2f}") + + except ValueError: + print("❌ Ingrese valores numéricos válidos") + +def pagoRentasAdelantadas(): + """ + Pago de rentas adelantadas + - Disminuye Bancos/Caja por el total + - Aumenta Rentas Pagadas por Adelantado por subtotal + - Aumenta IVA Acreditable por el IVA + - Aumenta pasivo Documentos por Pagar (si hay crédito del arrendador) + """ + print("\n" + "="*50) + print("PAGO DE RENTAS ADELANTADAS") + print("="*50) + + try: + subtotal = float(input("Ingrese el subtotal de la renta: $")) + if subtotal <= 0: + print("❌ El monto debe ser positivo") + return + + iva = subtotal * IVA_RATE + total = subtotal + iva + + print(f"\nSubtotal: ${subtotal:.2f}") + print(f"IVA (16%): ${iva:.2f}") + print(f"Total: ${total:.2f}") + + # Preguntar si hay crédito del arrendador + tiene_credito = input("\n¿Parte de la renta es a crédito? (s/n): ").lower().strip() + + if tiene_credito == 's': + try: + porcentaje_contado = float(input("¿Qué porcentaje es de contado? (0-100): ")) + if not (0 <= porcentaje_contado <= 100): + print("❌ El porcentaje debe estar entre 0 y 100") + return + porcentaje_credito = 100 - porcentaje_contado + except ValueError: + print("❌ Ingrese un porcentaje válido") + return + else: + porcentaje_contado = 100 + porcentaje_credito = 0 + + subtotal_contado = subtotal * (porcentaje_contado / 100) + subtotal_credito = subtotal * (porcentaje_credito / 100) + iva_contado = iva * (porcentaje_contado / 100) + iva_credito = iva * (porcentaje_credito / 100) + total_contado = subtotal_contado + iva_contado + total_credito = subtotal_credito + iva_credito + + cuenta_pago = obtenerCuentaPago(total_contado) + + # Asientos contables + abono(cuenta_pago, -total_contado) # Disminuye bancos/caja por parte contado + abono("activo.no_circulantes.rentas_pagadas_por_adelantado", subtotal) # Aumenta rentas + abono("activo.circulantes.iva_acreditado", iva_contado) # IVA acreditable + + if porcentaje_credito > 0: + abono("pasivos.corto_plazo.documentos_por_pagar", total_credito) # Documentos por pagar + print(f" - IVA por Acreditar: +${iva_credito:.2f}") + abono("activo.circulantes.iva_por_acreditar", iva_credito) + + actualizarSumasActivos() + guardarEstado() + + print("\n✓ Pago de renta adelantada registrado correctamente") + print(f" - Bancos/Caja: -${total_contado:.2f}") + print(f" - Rentas Pagadas por Adelantado: +${subtotal:.2f}") + print(f" - IVA Acreditable: +${iva_contado:.2f}") + if porcentaje_credito > 0: + print(f" - Documentos por Pagar: +${total_credito:.2f}") + + except ValueError: + print("❌ Ingrese valores numéricos válidos") + +def guardarEstado(): + """Guarda el estado actual en el archivo JSON""" + with open(ruta, "w", encoding="utf-8") as estado_file: + json.dump(estado, estado_file, indent=4, ensure_ascii=False, default=str) + estado_file.close() + +def guardarEstadoCSV(): + """ + Guarda el Estado de Situación Financiera en formato CSV lado a lado + Crea un archivo con el nombre: EMPRESA_ESTADO_FINANCIERO_FECHA.csv + Activos en columnas 1-2, Pasivos+Capital en columnas 3-4 + """ + try: + fecha_archivo = datetime.now().strftime("%Y-%m-%d_%H-%M-%S") + nombre_empresa = estado['Empresa'].replace(" ", "_").replace("/", "-") + nombre_archivo = f"{nombre_empresa}_ESTADO_FINANCIERO_{fecha_archivo}.csv" + + fecha_actual = datetime.now().strftime("%d de %B de %Y") + + # Preparar líneas de activos y pasivos + lineas_activos = [] + lineas_pasivos = [] + + # COLUMNA IZQUIERDA - ACTIVOS + lineas_activos.append(["Activo", ""]) + lineas_activos.append(["", ""]) + lineas_activos.append([" Circulantes", ""]) + lineas_activos.append([" Caja", f"${estado['activo']['circulantes']['caja']:,.2f}"]) + lineas_activos.append([" Bancos", f"${estado['activo']['circulantes']['bancos']:,.2f}"]) + lineas_activos.append([" Inventarios", f"${estado['activo']['circulantes']['inventarios']:,.2f}"]) + lineas_activos.append([" IVA Acreditable", f"${estado['activo']['circulantes']['iva_acreditado']:,.2f}"]) + lineas_activos.append([" IVA por Acreditar", f"${estado['activo']['circulantes']['iva_por_acreditar']:,.2f}"]) + lineas_activos.append(["", ""]) + lineas_activos.append([" Suma activos circulantes", f"${estado['activo']['circulantes']['suma_activos_circulantes']:,.2f}"]) + lineas_activos.append(["", ""]) + + lineas_activos.append([" No circulantes", ""]) + lineas_activos.append([" Edificios", f"${estado['activo']['no_circulantes']['edificios']:,.2f}"]) + lineas_activos.append([" Mobiliario", f"${estado['activo']['no_circulantes']['mobiliario']:,.2f}"]) + lineas_activos.append([" Papelería", f"${estado['activo']['no_circulantes']['papeleria']:,.2f}"]) + lineas_activos.append([" Cómputo", f"${estado['activo']['no_circulantes']['computo']:,.2f}"]) + lineas_activos.append([" Rentas pagadas adelantado", f"${estado['activo']['no_circulantes']['rentas_pagadas_por_adelantado']:,.2f}"]) + lineas_activos.append(["", ""]) + lineas_activos.append([" Suma activos no circulantes", f"${estado['activo']['no_circulantes']['suma_activos_no_circulantes']:,.2f}"]) + lineas_activos.append(["", ""]) + lineas_activos.append(["Suma activos", f"${estado['activo']['suma_activos']:,.2f}"]) + + # COLUMNA DERECHA - PASIVOS Y CAPITAL + lineas_pasivos.append(["Pasivos", ""]) + lineas_pasivos.append(["", ""]) + lineas_pasivos.append([" Corto Plazo", ""]) + lineas_pasivos.append([" Acreedores", f"${estado['pasivos']['corto_plazo']['acreedores']:,.2f}"]) + lineas_pasivos.append([" Documentos por pagar", f"${estado['pasivos']['corto_plazo']['documentos_por_pagar']:,.2f}"]) + lineas_pasivos.append([" IVA Trasladable", f"${estado['pasivos']['corto_plazo']['iva_trasladado']:,.2f}"]) + lineas_pasivos.append(["", ""]) + lineas_pasivos.append([" Anticipo Clientes", f"${estado['pasivos']['corto_plazo']['anticipo_de_clientes']:,.2f}"]) + lineas_pasivos.append(["", ""]) + lineas_pasivos.append([" Largo plazo", ""]) + lineas_pasivos.append(["", ""]) + total_pas = estado['pasivos']['suma_pasivos'] + lineas_pasivos.append(["Suma pasivos", f"${total_pas:,.2f}"]) + lineas_pasivos.append(["", ""]) + + lineas_pasivos.append(["Capital contable", ""]) + lineas_pasivos.append(["", ""]) + lineas_pasivos.append([" contribuido", ""]) + total_capital = estado['capital_contable']['contribuido']['capital_social'] + lineas_pasivos.append([" Capital social", f"${total_capital:,.2f}"]) + lineas_pasivos.append(["", ""]) + lineas_pasivos.append(["", ""]) + total_pasivo_capital = total_pas + total_capital + lineas_pasivos.append(["Total capital contable + Pasivos", f"${total_pasivo_capital:,.2f}"]) + + # Preparar datos para CSV lado a lado + datos = [] + + # Encabezados + datos.append([estado['Empresa'], "", estado['Empresa'], ""]) + datos.append(["ESTADO DE SITUACIÓN FINANCIERA A " + fecha_actual.upper(), "", "ESTADO DE SITUACIÓN FINANCIERA A " + fecha_actual.upper(), ""]) + datos.append(["", "", "", ""]) + + # Combinar líneas de activos y pasivos lado a lado + max_lineas = max(len(lineas_activos), len(lineas_pasivos)) + + for i in range(max_lineas): + if i < len(lineas_activos): + linea_izq = lineas_activos[i] + else: + linea_izq = ["", ""] + + if i < len(lineas_pasivos): + linea_der = lineas_pasivos[i] + else: + linea_der = ["", ""] + + datos.append([linea_izq[0], linea_izq[1], linea_der[0], linea_der[1]]) + + # Verificación de ecuación contable + datos.append(["", "", "", ""]) + diferencia = abs(estado['activo']['suma_activos'] - total_pasivo_capital) + if diferencia < 0.01: + datos.append(["ECUACIÓN CONTABLE BALANCEADA", "", "", ""]) + datos.append(["Activo = Pasivo + Capital", "", "", ""]) + else: + datos.append([f"ADVERTENCIA: Diferencia de ${diferencia:,.2f}", "", "", ""]) + + # Firmas + datos.append(["", "", "", ""]) + datos.append(["", "", "", ""]) + datos.append(["PROPIETARIO", "", "SUPERVISÓ", ""]) + datos.append([estado['firmas']['propietario'], "", estado['firmas']['superviso'], ""]) + + # Crear DataFrame y guardar CSV + df = pd.DataFrame(datos) + df.to_csv(nombre_archivo, index=False, header=False, encoding='utf-8') + + print(f"\n✓ Estado de Situación Financiera guardado en: {nombre_archivo}") + return True + + except Exception as e: + print(f"\n❌ Error al guardar CSV: {str(e)}") + return False + +def mostrarEstado(): + """ + Muestra el Estado de Situación Financiera en formato profesional + Activos a la izquierda | Pasivos + Capital a la derecha (lado a lado) + Sigue estructura jerárquica con espaciados adecuados + """ + fecha_actual = datetime.now().strftime("%d de %B de %Y") + empresa = estado['Empresa'] + ancho_col = 48 + + # Encabezado + print("\n" + "="*100) + print(f"{empresa.upper()}".center(100)) + print(f"ESTADO DE SITUACIÓN FINANCIERA A {fecha_actual.upper()}".center(100)) + print("="*100) + + # Recolectar datos para mostrar lado a lado + lineas_activos = [] + lineas_pasivos = [] + + # COLUMNA IZQUIERDA - ACTIVOS + lineas_activos.append("Activo") + lineas_activos.append("") + lineas_activos.append(" Circulantes") + lineas_activos.append(f" Caja ${estado['activo']['circulantes']['caja']:>13,.2f}") + lineas_activos.append(f" Bancos ${estado['activo']['circulantes']['bancos']:>13,.2f}") + lineas_activos.append(f" Inventarios ${estado['activo']['circulantes']['inventarios']:>13,.2f}") + lineas_activos.append(f" IVA Acreditable ${estado['activo']['circulantes']['iva_acreditado']:>13,.2f}") + lineas_activos.append(f" IVA por Acreditar ${estado['activo']['circulantes']['iva_por_acreditar']:>13,.2f}") + lineas_activos.append("") + total_circ = estado['activo']['circulantes']['suma_activos_circulantes'] + lineas_activos.append(f" Suma activos circulantes ${total_circ:>13,.2f}") + lineas_activos.append("") + lineas_activos.append(" No circulantes") + lineas_activos.append(f" Edificios ${estado['activo']['no_circulantes']['edificios']:>13,.2f}") + lineas_activos.append(f" Mobiliario ${estado['activo']['no_circulantes']['mobiliario']:>13,.2f}") + lineas_activos.append(f" Papelería ${estado['activo']['no_circulantes']['papeleria']:>13,.2f}") + lineas_activos.append(f" Cómputo ${estado['activo']['no_circulantes']['computo']:>13,.2f}") + lineas_activos.append(f" Rentas pagadas adelant. ${estado['activo']['no_circulantes']['rentas_pagadas_por_adelantado']:>11,.2f}") + lineas_activos.append("") + total_no_circ = estado['activo']['no_circulantes']['suma_activos_no_circulantes'] + lineas_activos.append(f" Suma activos no circulantes ${total_no_circ:>13,.2f}") + lineas_activos.append("") + total_act = estado['activo']['suma_activos'] + lineas_activos.append(f"Suma activos ${total_act:>13,.2f}") + + # COLUMNA DERECHA - PASIVOS Y CAPITAL + lineas_pasivos.append("Pasivos") + lineas_pasivos.append("") + lineas_pasivos.append(" Corto Plazo") + lineas_pasivos.append(f" Acreedores ${estado['pasivos']['corto_plazo']['acreedores']:>13,.2f}") + lineas_pasivos.append(f" Documentos por pagar ${estado['pasivos']['corto_plazo']['documentos_por_pagar']:>13,.2f}") + lineas_pasivos.append(f" IVA Trasladable ${estado['pasivos']['corto_plazo']['iva_trasladado']:>13,.2f}") + lineas_pasivos.append("") + lineas_pasivos.append(" Anticipo Clientes") + lineas_pasivos.append(f" ${estado['pasivos']['corto_plazo']['anticipo_de_clientes']:>13,.2f}") + lineas_pasivos.append("") + lineas_pasivos.append(" Largo plazo") + lineas_pasivos.append("") + total_pas = estado['pasivos']['suma_pasivos'] + lineas_pasivos.append(f"Suma pasivos ${total_pas:>13,.2f}") + lineas_pasivos.append("") + lineas_pasivos.append("Capital contable") + lineas_pasivos.append("") + lineas_pasivos.append(" contribuido") + total_cap = estado['capital_contable']['contribuido']['capital_social'] + lineas_pasivos.append(f" Capital social ${total_cap:>13,.2f}") + lineas_pasivos.append("") + lineas_pasivos.append("") + total_pas_cap = total_pas + total_cap + lineas_pasivos.append(f"Total capital contable + Pasivos ${total_pas_cap:>13,.2f}") + + # Mostrar lado a lado + print("\n") + max_lineas = max(len(lineas_activos), len(lineas_pasivos)) + + for i in range(max_lineas): + linea_izq = lineas_activos[i] if i < len(lineas_activos) else "" + linea_der = lineas_pasivos[i] if i < len(lineas_pasivos) else "" + + # Ajustar ancho de la columna izquierda + print(f"{linea_izq:<{ancho_col}} {linea_der}") + + # Verificar ecuación contable + diferencia = abs(total_act - total_pas_cap) + print("\n") + if diferencia < 0.01: + print("✓ ECUACIÓN CONTABLE BALANCEADA: Activo = Pasivo + Capital".center(100)) + else: + print(f"⚠ ADVERTENCIA: Diferencia de ${diferencia:,.2f}".center(100)) + + # Pie de firma + print("\n") + print(" " * 20 + "_" * 30 + " " * 20 + "_" * 30) + print(" " * 20 + "PROPIETARIO" + " " * 32 + "SUPERVISÓ") + print(f"{estado['firmas']['propietario']:^52} {estado['firmas']['superviso']:^48}") + print("\n" + "="*100 + "\n") + +def menu(): + """Menú principal de operaciones""" + conti = 'y' + while conti.lower() == 'y': + print("\n" + "="*50) + print("¿QUÉ OPERACIÓN DESEA HACER?") + print("="*50) + print("1. Compra en efectivo/contado") + print("2. Compra a crédito") + print("3. Compra combinada (contado + crédito)") + print("4. Anticipo de clientes") + print("5. Pago de rentas adelantadas") + print("6. Ver estado actual") + print("7. Guardar estado en CSV") + print("8. Salir") + + try: + sel0 = int(input("\nElija una opción (1-8): ").strip()) + + match (sel0): + case 1: + compraEfectivo() + case 2: + compraACredito() + case 3: + compraCombinada() + case 4: + anticipoClientes() + case 5: + pagoRentasAdelantadas() + case 6: + mostrarEstado() + case 7: + guardarEstadoCSV() + case 8: + conti = 'n' + case _: + print("❌ Opción no válida, intente de nuevo") + continue + + if sel0 != 8 and sel0 != 6: + conti = input("\n¿Desea realizar otra operación? (y/n): ").lower().strip() + + except ValueError: + print("❌ Por favor ingrese un número válido") + +# Programa principal +try: + with open(ruta, "r", encoding="utf-8") as estado_file: + print("✓ Archivo encontrado, leyendo...") + estado = json.load(estado_file) + estado_file.close() + menu() +except FileNotFoundError: + print("Archivo no encontrado, creando uno nuevo\n") + empresa = input("¿Cómo se llama su empresa?: ").strip() + empresario = input("¿Cómo se llama usted?: ").strip() + + estado = { + "Empresa": empresa, + "Fecha": datetime.now().strftime("%Y-%m-%d %H:%M:%S"), + "activo": { + "circulantes": { + "caja": 0.0, + "bancos": 0.0, + "inventarios": 0.0, + "iva_acreditado": 0.0, + "iva_por_acreditar": 0.0, + "suma_activos_circulantes": 0.0 + }, + "no_circulantes": { + "edificios": 0.0, + "mobiliario": 0.0, + "papeleria": 0.0, + "computo": 0.0, + "rentas_pagadas_por_adelantado": 0.0, + "suma_activos_no_circulantes": 0.0 + }, + "suma_activos": 0.0 + }, + "pasivos": { + "corto_plazo": { + "acreedores": 0.0, + "documentos_por_pagar": 0.0, + "anticipo_de_clientes": 0.0, + "iva_trasladado": 0.0 + }, + "largo_plazo": {}, + "suma_pasivos": 0.0 + }, + "capital_contable": { + "contribuido": { + "capital_social": 0.0 + } + }, + "suma_pasivos_mas_capital_contable": 0.0, + "firmas": { + "propietario": empresario, + "superviso": "NGZ" + } + } + + asientoApertura() + guardarEstado() + print("\n✓ Archivo creado y guardado exitosamente") + menu()