ocomsoft / grails-quickbooks-online

Grails plugin for the QuickBooks Online API.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

grails-quickbooks-online Build Status

Grails plugin for the QuickBooksOnline API. This plugin includes an OAuth provider and utilities for working with the QuickBooks Online API.

Contents

Pre-requisites

  1. You have signed-up to the Intuit Partner Platform (IPP) at https://developer.intuit.com/.
  2. You have created a new QuickBooks API app in https://developer.intuit.com/.

Installation

Update grails-app/config/BuildConfig.groovy to include:

plugins {
	...
	compile ":quick-books-online:1.0"   
	...

Note that the version (1.0 in the example above) should be changed to reflect the version you would like to use.

Dependencies

This plugin depends on Grails Oauth plugin (>= 2.5).

The OAuth 2.5 plugin requires Scribe 1.3.6 which is not currently available via Maven. A workaround for this is to force the use of Scribe 1.3.5 instead.

The BuildConfig.groovy should be as follows:

	repositories {
		...
		mavenRepo "http://repo.desirableobjects.co.uk/"
		...
	}

	dependencies {
  	...
		runtime "org.scribe:scribe:1.3.5"
		...
	}

	plugins {
		...
		compile (":oauth:2.5") {
			exclude "scribe"  // Ignore the version of scribe defined by the plugin
	  }
		...
	}

Configuration

OAuth Configuration

Add the following (changing where necessary) to grails-app/config/Config.groovy:

import mcomp.grails.quickbooksonline.oauth.QuickBooksOnlineApi

...

oauth {
	providers {
		intuit {
			api     = QuickBooksOnlineApi
			key     = "APP OAUTH CONSUMER KEY"
			secret  = "APP OAUTH CONSUMER SECRET"
			successUri  = '/success'
			failureUri  = '/failure'
			callback    = "http://HOST.NAME.DOMAIN:8080/APP_CONTEXT/oauth/intuit/callback"
		}
	}
	debug = true
}

The key and secret values for your app are provided at https://developer.intuit.com/Application/List (or My Apps > Manage Apps > [App Name]).

The callback url should use the same Host Name Domain defined in Manage Apps and NOT localhost. Editing your hosts file is an easy way to achieve this during development.

An example callback URL is: http://mytestapp.co.uk:8080/QuickbooksDemo1/oauth/intuit/callback

If in doubt, test the callback, success and failure URLs using a browser.

Additional Configuration

Add the following to grails-app/config/Config.groovy:

quickbooksonline {
	api {
		baseurl = "https://qb.sbfinance.intuit.com/v3"
	}
}

Usage

Please also see the Intuit Partner Platform documentation:

Sample Controller

@Mixin(QuickBooksControllerMixin)		// 1. Add mixin
class MyController {

	def quickBooksService			// 2. Add service which is used by the mixin
	
	def index() {}

	def listCustomers() {

		// Redirect to connect page if no access token is available.
		if (!accessToken) {
			flash.message = "Please connect to Quickbooks"
			redirect action:"index"
			return
		}
		debug(accessToken)
		debugSession()

		// Get Customers. 		// 3. Execute query
		Response res = getJsonResponseForQuery("SELECT Id, DisplayName, Active, Balance FROM Customer")
		debug(res)

		def customers = []
		if (res.isSuccessful()) {
						// 4. Parse JSON response
			def result = new JsonSlurper().parseText(res.body)
			customers = result."QueryResponse"."Customer"
		}

		[res: res, customers: customers]

	}

	def listInvoices() {
		if (!accessToken) {
			....
		}

		def filter = params.customerId ? "WHERE CustomerRef='${params.customerId}'" : ""
		Response res = getJsonResponseForQuery("SELECT TxnDate, Id, DocNumber, CustomerRef, TotalAmt, Balance, Line FROM Invoice ${filter} ORDERBY TxnDate DESC")

		def invoices = []
		if (res.isSuccessful()) {
			def result = new JsonSlurper().parseText(res.body)
			invoices = result."QueryResponse"."Invoice"
		}

		[res: res, invoices: invoices]

	}

	def showCustomer() {
		if (!accessToken) {
			...
		}

		Response res = getJsonResponseForCustomer(params.customerId)
		def customer
		if (res.isSuccessful()) {
			def result = new JsonSlurper().parseText(res.body)
			customer = result."Customer"
		}

		[res: res, customer: customer]

	}

}

Sample View

<html>
<head>
	<meta name="layout" content="main"/>
</head>
<body>

<h1>Quickbooks Demo </h1>
<h2>Welcome</h2>

<g:if test="${flash.message}">
	<div class="message" style="display: block">${flash.message}</div>
</g:if>

<!-- Connect to Quickbooks Link - this will return to the 'callback' url specified in the config -->
<oauth:connect provider="intuit">Connect to Quickbooks...</oauth:connect>

...

<hr />
Response status: ${res?.code}
<hr />

<h2>Invoices (${invoices?.size})</h2>
<table>
	<thead>
	<tr>
		<th>ID</th>
		<th>Date</th>
		<th>Doc Number</th>
		<th>Customer</th>
		<th>Total</th>
		<th>Balance</th>
		<th>Lines</th>
	</tr>
	</thead>
	<tbody>
	<g:each in="${invoices}" var="invoice">
		<tr>
			<td>${invoice.Id}</td>
			<td><g:formatDate date="${dateFormat.parse(invoice.TxnDate)}" type="date" dateStyle="medium" /></td>
			<td>${invoice.DocNumber}</td>
			<td><g:link action="showCustomer" params="${[customerId:invoice.CustomerRef.value]}">${invoice.CustomerRef.name}</g:link></td>
			<td><g:formatNumber number="${invoice.TotalAmt}" currencyCode="GBP" type="currency" /></td>
			<td><g:formatNumber number="${invoice.Balance}" currencyCode="GBP" type="currency" /></td>
			<td>
				<ol>
				<g:each in="${invoice.Line}" var="line">
					<li>${line}</li>
				</g:each>
				</ol>
			</td>
		</tr>
	</g:each>
	</tbody>
</table>

</body>
</html>

Persisting OAuth Details

The plugin provides a Spring bean called quickBooksSessionManager which can be used to read and write the session variables required by QuickBooks Online. This means that it is possible to capture the configuration after successfully 'Authorizing' with QuickBooks Online and store the results so that authorisation is not required for future sessions.

Please see the example domain and controller below.

Example Domain Class

(In production systems, values should be encrypted/decrypted on save/load.)

import mcomp.grails.quickbooksonline.QuickBooksSessionConfig
import org.scribe.model.Token

class QuickBooksSession {
	
	// Non-QBO field
	String username

  // QBO fields
	String accessToken
	String accessTokenSecret
	String companyId
	String dataSource
	String provider

	Date dateCreated
	Date lastUpdated

	QuickBooksSession() {}

	QuickBooksSession(String username, QuickBooksSessionConfig config) {
		this.username           = username
		this.accessToken        = config.accessToken.token
		this.accessTokenSecret  = config.accessToken.secret
		this.companyId          = config.companyId
		this.dataSource         = config.dataSource
		this.provider           = config.provider
	}

	QuickBooksSessionConfig getQuickBooksSessionConfig() {
		new QuickBooksSessionConfig(
			accessToken:    new Token(accessToken, accessTokenSecret),
			companyId:      companyId,
			dataSource:     dataSource,
			provider:       provider
		)
	}

}

Example Controller Class

import grails.plugin.springsecurity.SpringSecurityService
import mcomp.grails.quickbooksonline.QuickBooksSessionConfig
import mcomp.grails.quickbooksonline.QuickBooksSessionManager

class QuickBooksSessionController {

	static scaffold = true

	SpringSecurityService       springSecurityService
	QuickBooksSessionManager    quickBooksSessionManager

	def saveSession() {
		QuickBooksSessionConfig config = quickBooksSessionManager.getSessionConfig(session)
		String username = springSecurityService.principal.username
		def qboSession = new QuickBooksSession(username, config)
		if (qboSession.save(flush: true)) {
			flash.message = "Successfully saved QuickBooks Online session."
		} else {
			flash.message = "Failed to save QuickBooks Online session."
			log.warn "Failed to save QuickBooks session. Errors: ${qboSession.errors}"
		}
		redirect(action: "list")
	}

	def loadSession(String username) {
		def qboSession = QuickBooksSession.findByUsername(username)
		if (!qboSession) {
			flash.message = "No quickbooks session found for $username."
			redirect(action: "list")
			return
		} else {
			quickBooksSessionManager.initSession(session, qboSession.quickBooksSessionConfig)
			flash.message = "Loaded existing session for $username."
		}
		redirect(controller: "home")
	}

}

About

Grails plugin for the QuickBooks Online API.

License:MIT License


Languages

Language:Groovy 83.6%Language:Batchfile 16.4%