Easily turn a Ruby Hash to QuickBooks XML
I recently released a new Gem called to_qbxml
. I created it in response to the current de facto Ruby Gem, Qbxml. Let me state right off the bat that I used much of that Gem's code for to_qbxml
and want to thank the author, Alexsey, for all his OSS QuickBooks contributions.
Here are some of the issues I had with the Qbxml
Gem:
- QBXML requires repeatable nodes such as the
InvoiceLineAdd
node in the sample below but I had no idea how to do this with theQbxml
Gem. - Reliance on ActiveSupport::Inflector to handle QBXML case conversions Since Inflector is used within Rails autoload this can adversely effect autoloading when included into an existing Rails app. Instead,
- Built-in validation is not needed. In my experience, it is best to use the OCR docs and the QBXML validator and SDKTest utilities that come bundled with the standard QBSDK installation.
- Turning QBXML into a Ruby hash is not useful when it comes to reading QBXML Instead use the rich parsing and searching of Nokogiri. With
<?xml version="1.0" encoding="utf-8"?> <?qbxml version="7.0"?> <QBXML> <QBXMLMsgsRq onError="stopOnError"> <InvoiceAddRq requestID="1"> <InvoiceAdd> <InvoiceLineAdd> <!-- omitted --> </InvoiceLineAdd> <InvoiceLineAdd> <!-- omitted --> </InvoiceLineAdd> </InvoiceAdd> </InvoiceAddRq> </QBXMLMsgsRq> </QBXML>I am sure that
Qbxml
Gem does support this as it is a crucial part of creating valid QBXML but instead I created a solution that uses a reserved hash key, repeat
, that can be passed an array of hashes to create the above XML.
# ---- # to_qbxml gem example of creating repeatable nodes # ---- def line_item(line_number) { invoice_line_add: { item_ref: { list_id: '3243' }, desc: "Line #{line_number}", amount: 10.99, is_taxable: true, quantity: 3, rate_percent: 0, repeat: [{ line: { desc: 'inside' } }] } } end hash = { repeat: [ line_item(1), line_item(2) ] } xml = ToQbxml.new(hash).make(:invoice)
to_qbxml
removes that dependency and uses a simple regular expression to achieve the same result.
to_qbxml
you can return a Nokogiri document back to by passing doc: true
into the initialization options. Below is an example of using Nokogiri's rich CSS selector support to parse QBXML.
n = ToQbxml.new(hash, doc: true).make(:invoice, action: :query) expect(n.at('InvoiceQueryRq > IncludeLineItems').content).to eq 'true' expect(n.at('InvoiceQueryRq > ModifiedDateRangeFilter > FromModifiedDate').content).to eq hash[:modified_date_range_filter][:from_modified_date] expect(n.at('InvoiceQueryRq > ModifiedDateRangeFilter > ToModifiedDate').content).to eq hash[:modified_date_range_filter][:to_modified_date] end
Hence a new Gem is born
Therefore, I ripped out these and some other "features" to create a lightweight and flexible but yet powerful Ruby Hash to QBXML library. Enjoy, and check out the screencast for more commentary.
- Pushed on 10/07/2014 by Christian
- QuickBooks Integration Consulting