Update with QB Desktop connection

This commit is contained in:
2026-02-16 12:15:16 -05:00
parent 2f4326ec15
commit dedb2db026
5 changed files with 2256 additions and 315 deletions
+188
View File
@@ -0,0 +1,188 @@
#!/usr/bin/env python3
"""
QuickBooks Desktop Connection Test Script
Run this directly on your Windows machine to test the connection.
Usage:
python test_qbd_connection.py
"""
import sys
import time
print("=" * 60)
print("QuickBooks Desktop Connection Test")
print("=" * 60)
# Check platform
print(f"\n1. Platform: {sys.platform}")
if sys.platform != 'win32':
print(" ERROR: This script must be run on Windows!")
sys.exit(1)
print(" OK: Running on Windows")
# Check pywin32
print("\n2. Checking pywin32...")
try:
import pythoncom
from win32com.client import Dispatch
print(" OK: pywin32 is installed")
except ImportError as e:
print(f" ERROR: pywin32 not installed: {e}")
print(" Run: pip install pywin32")
sys.exit(1)
# Initialize COM
print("\n3. Initializing COM...")
try:
pythoncom.CoInitialize()
print(" OK: COM initialized")
except Exception as e:
print(f" ERROR: Failed to initialize COM: {e}")
sys.exit(1)
# Create RequestProcessor
print("\n4. Creating QBXMLRP2.RequestProcessor...")
try:
rp = Dispatch("QBXMLRP2.RequestProcessor")
print(" OK: RequestProcessor created")
except Exception as e:
print(f" ERROR: Failed to create RequestProcessor: {e}")
print("\n This usually means:")
print(" - QuickBooks Desktop is not installed")
print(" - QuickBooks SDK components are not registered")
print(" - Try: regsvr32 \"C:\\Program Files (x86)\\Common Files\\Intuit\\QuickBooks\\qbxmlrp2.dll\"")
pythoncom.CoUninitialize()
sys.exit(1)
# Open Connection
print("\n5. Opening connection (OpenConnection2)...")
try:
# Connection types:
# 1 = localQBD (local QuickBooks Desktop)
# 2 = remoteQBD (remote QuickBooks Desktop)
# 3 = localQBDLaunchUI (launch QB if not running)
rp.OpenConnection2("", "QBD Test Script", 1)
print(" OK: Connection opened")
except Exception as e:
print(f" ERROR: OpenConnection2 failed: {e}")
pythoncom.CoUninitialize()
sys.exit(1)
# Begin Session - THIS IS WHERE IT USUALLY HANGS
print("\n6. Beginning session (BeginSession)...")
print(" NOTE: If this hangs, check QuickBooks for an authorization dialog!")
print(" Also check: Edit > Preferences > Integrated Applications > Company Preferences")
print(" Make sure 'Don't allow any applications...' is UNCHECKED")
print("")
print(" Attempting BeginSession with timeout indicator...")
print(" (If you see dots appearing, the call is hanging)")
# Start time
start_time = time.time()
# We can't easily timeout a COM call, but we can show progress
import threading
stop_dots = False
def print_dots():
count = 0
while not stop_dots:
time.sleep(1)
count += 1
print(f" ... waiting {count}s", end='\r')
if count > 30:
print("\n WARNING: BeginSession is taking too long (>30s)")
print(" This usually means QuickBooks is waiting for user input")
print(" CHECK QUICKBOOKS FOR A DIALOG BOX!")
dot_thread = threading.Thread(target=print_dots)
dot_thread.daemon = True
dot_thread.start()
try:
# File modes:
# 0 = qbFileOpenDoNotCare
# 1 = qbFileOpenSingleUser
# 2 = qbFileOpenMultiUser
ticket = rp.BeginSession("", 0) # Empty string = currently open file
stop_dots = True
elapsed = time.time() - start_time
print(f"\n OK: Session started in {elapsed:.2f}s")
print(f" Session ticket: {ticket[:30]}...")
except Exception as e:
stop_dots = True
elapsed = time.time() - start_time
print(f"\n ERROR: BeginSession failed after {elapsed:.2f}s: {e}")
error_msg = str(e)
if "80040408" in error_msg:
print("\n DIAGNOSIS: QuickBooks is not running or no company file is open")
elif "80040416" in error_msg or "80040417" in error_msg:
print("\n DIAGNOSIS: Access denied - need to authorize in QuickBooks")
elif "80040422" in error_msg:
print("\n DIAGNOSIS: No company file is open")
elif "80040423" in error_msg:
print("\n DIAGNOSIS: Company file is in single-user mode by another user")
try:
rp.CloseConnection()
except:
pass
pythoncom.CoUninitialize()
sys.exit(1)
# If we got here, try a simple query
print("\n7. Testing with a simple Company query...")
try:
# Build a simple QBXML request
request = '''<?xml version="1.0" encoding="utf-8"?>
<?qbxml version="13.0"?>
<QBXML>
<QBXMLMsgsRq onError="stopOnError">
<CompanyQueryRq>
</CompanyQueryRq>
</QBXMLMsgsRq>
</QBXML>'''
response = rp.ProcessRequest(ticket, request)
print(" OK: Query executed successfully")
# Parse response to get company name
import xml.etree.ElementTree as ET
root = ET.fromstring(response)
company_name = root.find(".//CompanyName")
if company_name is not None:
print(f" Company Name: {company_name.text}")
except Exception as e:
print(f" ERROR: Query failed: {e}")
# End session
print("\n8. Ending session...")
try:
rp.EndSession(ticket)
print(" OK: Session ended")
except Exception as e:
print(f" WARNING: EndSession failed: {e}")
# Close connection
print("\n9. Closing connection...")
try:
rp.CloseConnection()
print(" OK: Connection closed")
except Exception as e:
print(f" WARNING: CloseConnection failed: {e}")
# Uninitialize COM
try:
pythoncom.CoUninitialize()
except:
pass
print("\n" + "=" * 60)
print("TEST COMPLETED SUCCESSFULLY!")
print("=" * 60)
print("\nQuickBooks Desktop connection is working properly.")
print("If the web app still doesn't work, the issue may be with")
print("Flask session handling or threading.")