Wednesday, January 5, 2011

How to get Python to talk to QuickBooks Pro 2008 using QBFC

You can import/export and change most QuickBooks data (including most transactions) using the qbXML and QBFC methods. Quickbooks has a built-in COM listener, and it's possible for other applications to login through this interface...even if QB is not running.

Prerequisites


  • Python COM: The pywin32 module enables python to talk COM. Look for the file matching your architecture AND python version. The downloaded .exe file should automatically install on your Windows system. You need pywin32 for both the QBFC method and the qbXML method.

  • QBFC10.dll: The QBFC10.dll file, and the installer for it, is not included with Quickbooks, so you need to get it from the Quickbooks SDK available at http://developer.intuit.com, which means you'll need to register at that site.
    This prerequisite only applies to QBFC. qbXML uses QBXMLRP2.dll, which is already included with Quickbooks.


Using qbXML



QBFC is just a thin object-oriented wrapper around qbXML, so the best way to understand QBFC is to look at some qbXML first.

#SAMPLE QBXML
<QBXML>                                   # XML container
   <QBXMLMsgsRq>                          # Container for multiple transaction types
      <InventoryAdjustmentQueryRs>        # List of transactions
         <InventoryAdjustmentRet>         # Container for each transaction
            <TxnID>12345</TxnID>          # Transaction detail
            <Memo>Something to say</Memo> # Transaction detail
         </InventoryAdjustmentRet>
      </InventoryAdjustmentQueryRs>
   </QBXMLMsgsRq> 
</QBXML>



As you see, getting transaction information in qbXML is like peeling an onion - layer after layer of containers. Here's how to do qbXML using Python 2.6:

#!usr/bin/python
import win32com.client
import xml.etree.ElementTree

# Connect to Quickbooks
sessionManager = win32com.client.Dispatch("QBXMLRP2.RequestProcessor")    
sessionManager.OpenConnection('', 'Test qbXML Request')
ticket = sessionManager.BeginSession("", 0)

# Send query and receive response
qbxml_query = """
<?qbxml version="6.0"?>
<QBXML>
   <QBXMLMsgsRq onError="stopOnError"> 
      <InventoryAdjustmentQueryRq metaData="MetaDataAndResponseData">
      </InventoryAdjustmentQueryRq>
   </QBXMLMsgsRq> 
</QBXML>
"""
response_string = sessionManager.ProcessRequest(ticket, qbxml_query)

# Disconnect from Quickbooks
sessionManager.EndSession(ticket)     # Close the company file
sessionManager.CloseConnection()      # Close the connection

# Parse the response into an Element Tree and peel away the layers of response
QBXML = xml.etree.ElementTree.fromstring(response_string)
QBXMLMsgsRs = QBXML.find('QBXMLMsgsRs')
InventoryAdjustmentQueryRs = QBXMLMsgsRs.getiterator("InventoryAdjustmentRet")
for InvAdjRet in InventoryAdjustmentQueryRs:
    txnid = InvAdjRet.find('TxnID').text
    memo = InvAdjRet.find('memo').text



See how each container needs to be opened to get to the bottommost data?

It's about the same in both qbXML and QBFC.


Using QBFC



Here's the same query in QBFC using Python 2.6:

#!usr/bin/python
import win32com.client
#No ElementTree needed, since no raw XML

# Open a QB Session
sessionManager = win32com.client.Dispatch("QBFC10.QBSessionManager")    
sessionManager.OpenConnection('', 'Test QBFC Request')
# No ticket needed in QBFC
sessionManager.BeginSession("", 0)

# Send query and receive response
requestMsgSet = sessionManager.CreateMsgSetRequest("US", 6, 0)
requestMsgSet.AppendInventoryAdjustmentQueryRq()
responseMsgSet = sessionManager.DoRequests(requestMsgSet)

# Disconnect from Quickbooks
sessionManager.EndSession()           # Close the company file (no ticket needed)
sessionManager.CloseConnection()      # Close the connection

# Peel away the layers of response
QBXML = responseMsgSet
QBXMLMsgsRq = QBXML.ResponseList
InventoryAdjustmentQueryRs = QBXMLMsgsRq.GetAt(0)
for x in range(0, len(InventoryAdjustmentQueryRs.Detail)):
    InventoryAdjustmentRet = QueryRs.Detail.GetAt(x)
    txnid = InventoryAdjustmentRet.TxnID.GetValue()
    memo = InventoryAdjustmentRet.Memo.GetValue()

The two small advantages of QBFC are:
  1. Each transaction is a single variable with all the data appended at attributes. That seems slightly easier to deal with than using ElementTree to convert each transaction into a dict. But not much.

  2. QBFC transactions seem to be about 20% faster than equivalent qbXML

Saturday, April 3, 2010

Installing a NAS (D-link DNS-321)

I added a DNS-321 NAS to my home network. Here's how I installed it using Ubuntu 9.10:

  1. Install the 3.5" SATA drives. They aren't included. I used 2x 1TB drives.
  2. Add it to the local wired network. Turn it on.
  3. Log in to the router to figure out the NAS IP address. Remember the IP address!
  4. Log into the NAS' buit-in web server (username ADMIN, no password) to format the drives, configure all the access, and learn the top-level-folder name.
  5. Create user accounts for all access

Here's how I access it using Ubuntu 9.10:

  • Get the Samba packages: sudo apt-get install samba smbfs

  • Create a mount point: sudo mkdir /media/Sharedrive

  • Add the following line to fstab: sudo nano /etc/fstab
    //192.168.1.102/Top-Level-Folder /media/Sharedrive/ cifs nounix,uid=ubuntu_account_username,gid=ubuntu_account_username,file_mode=0777,dir_mode=0777,username=my_NAS_account_name,password=my_NAS_account_password 0 0
    # Your IP address and top-level-folder are very likely to be different.
    # Your uid and gid should be your Ubuntu username/groupname (your Ubuntu machine login name)
    # Your username and password are almost certainly different. 
    

  • Mount the new share using sudo mount -a

  • Unmount the new share using sudo umount /media/Sharedrive

  • Optional: Create a shortcut in the File Manager to make easy access to the mount point.

  • I haven't investigated automounting upon startup yet.

    Monday, February 8, 2010

    Using a US DOD CAC Card with Ubuntu 9.10

    Superseded by http://cheesehead-techblog.blogspot.com/2015/10/cac-on-firefox-using-ubuntu-1504.html

    Adding a CAC Card reader and using a CAC card with Ubuntu used to be bloody hard. Getting the hardware recognized, getting the add-ons to Firefox and Evolution, installing the certificates, what a pain!
    Well, I tried agin, using the Ubuntu help center instructions at https://help.ubuntu.com/community/CommonAccessCard
    Result: I can log into AKO using my CAC Card! After four years of hoping. Hooray!

    Friday, November 27, 2009

    Quick and Easy CD-ripping

    Ripping a CD to add to my music collection using the command-line application abcde.

    To install abcde, use sudo apt-get abcde

    To rip a CD, insert the CD and use the terminal. This will rip the CD to FLAC (lossless) format, and eject the CD when complete:

    cd Music
    abcde -x -o flac

    Sunday, November 15, 2009

    Linux converter for Microsoft .lit files

    .lit is a proprietary format, and must be converted using the C-lit application, included in the 'epub-utils' package. It can then be read with the 'fbreader' e-book reader.

    To install epub-utils and fbreader, use sudo apt-get epub-utils fbreader

    To convert a book file, use lit2epub /path/to/book.lit


    To read a converted book, open fbreader and point it to /path/to/book.epub

    Monday, July 13, 2009

    Video, photos, and music sharing with my phone

    I have a snazzy new geek-phone, a Shuttle from Virgin Mobile. It has a 4GB MicroSD slot so files can be exchanged with my Xubuntu system.

    • Phone Video is in .3G2 format. The video plays in Totem, but the sound doesn't. YouTube properly uploads and converts the .3G2 videos (no need to share by e-mail). I plan to archive the .3G2 videos in their original format. This command successfully converts the .3G2 to a .avi for viewing by totem:
      $ mencoder media/disk/my_flix/inputfile.3g2 -ovc lavc -lavcopts vcodec=msmpeg4v2 -oac mp3lame -lameopts vbr=3 -o Videos/outputfile.avi
    • Computer Video Haven't figured out the right command to convert movies to .3G2 yet.
    • Phone Pictures are in .jpg format. Xubuntu's standard Image Viewer is very effective for weeding through them.
    • Computer Pictures Large pictures take a long time to show up - a 2.4 MB image froze the phone for 30 seconds. The following script uses Imagemagick to resize the photos to a smaller size:
      $ convert Pictures/filename -size 320x240 /media/disk/my_pix/filename.jpg
      
    • Computer Music My FLAC music needs to be converted to .mp3 to play on the phone. Soundconverter does it, but some results refuse to play...haven't figured out the pattern yet.
    • Important information-
      UUID=5D18-F276  # The 4GB MicroSD Card's UUID. Find using syslog after plugging it in
      /media/disk     # Default mount point
      /dev/sdb1       # Device location
      /dev/sdb1 /media/disk vfat rw,nosuid,nodev,uhelper=hal,utf8,shortname=winnt,uid=1000 0 0   # /etc/mtab entry for the disk
      
      /media/disk/my_flix   /media/disk/my_music   /media/disk/my_pix    # Available folders
      
      Camera Resolutions: 1280x960 1024x768 640x480 320x240 176x144 160x120
      Video Camera Resolution: 176x144
      Screen Resolution: 220x176, 262k colors
      

    Thursday, July 9, 2009

    Installing Xubuntu 9.04 on an emachines E625-5192

    Received my new laptop today - I need it for the fall, and got it a little early due to a sale.

    What went well: I created a set of Restore DVDs (in case I want Windows back), then removed windows and installed Xubuntu 9.04 full-disk. Copied over my old /home directory, and installed all my favorite apps. E-mail, web, games, .bashrc, most dektop settings, etc. transferred without a hiccup. Recreated my crontab. Wireless networking and video work great. Built-in card reader reads all cards from my cameras and phone. Machine is noticeably faster. FN-key brightness control works. FN-key multimedia controls work.


    Solved Problems:

  • Sound was tinny and a bit faint. Headphone jack works, not tinny, but low volume. Solution: Adding the following lines to /etc/modprobe.d/alsa-base.conf
    somwhat improved speakers and fixed the headphone jack.
    # Added by me on <date> while troubleshooting audio
    options snd-hda-intel model=6stack
    

  • The Volume-FN keys didn't work. Solution: Mapped FN-audio up, down, and mute keys by mapping them to aumix using these instructions.

  • The suspend FN-key didn't work. Solution: Enabled it in the gnome-power-manager preferences. It was set up to work out-of-the-box, but disabled by default.

  • DVD: DVDs play only after changing CDROM permissions after each disc insertion. Workaround: Created an alias in .bashrc as the 'fixcd' command

  • TomTom GPS automatic update doesn't work on Linux - Win and OSX only. Department of Defense forms and other applications are Windows-specific. Workaround: Installed a Virtual Machine (VM) to host an occasional-use XP instance.

  • Phone-made .3g2 video files play with weird audio - need a way to convert them. Computer .wma songs don't play on phone - need a lossless storage format, and a way to convert them to .mp3. Workaround: Upload videos to YouTube instead of the local hard drive.

  • Need password to restore from suspend (Xubuntu issue, not hardware-related). Workaround: Remove the screensaver package.

  • Unsolved Problems: No built-in webcam. Keyboard is different, and will take time to get used to - many typos in the meantime.