Update with QB Desktop connection
This commit is contained in:
@@ -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.")
|
||||
Reference in New Issue
Block a user