0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0

I began a project using node.js just to get a feel of it. I am writing this post so that it serves as a development log and reference for myself. It could also help you if you work with Quickbooks and node.js.

The objective is to create an interface for viewing reports from Quickbooks.

The code lives here: Finance App
The premise is simple enough for me to start using a framework and there is already an API wrapper for me to experiment with.1 Based on the requirements of the project, I broke down it's implementation into the following parts:

Part I
1. Connect to the API
2. Retrieve the report data
3. Display it

Part II
1. Add custom fields to the report
2. Save the customized report to a local database
3. Sync the custom report data with the online report

Part III
1. Add the ability to add/remove date ranges for forecast reports
2. Add custom filters to get specific views of the reports
3. Writing the report data back to Quickbooks

I am currently focussing on Part I, as it is sufficiently involved. I started off with all the code in one file, following this guide2 step-by-step. This guide helped me organize my project files better. The project is still nowhere near organized as it should be, but it gave me a place to start.

I am using Jade as my template engine and Express framework for Node.js

Getting connected to the API was easy. You need a developer account with Intuit Partner Platform3. Then you are asked to create an app and enter the URLs for the landing page, callback and authentication. Quickbooks Online uses OAuth for authentication. Upon providing a consumerKey and a consumerSecret, the API will give you an accessToken and accessTokenSecret that you will have to store locally so it is available to the app session-wide.

Once connection is established, I instantiate a QuickBooks object like so:

1
2
3
4
5
6
qbo = new QuickBooks(creds.consumerKey,
                         creds.consumerSecret,
                         accessToken.oauth_token,
                         accessToken.oauth_token_secret,
                         postBody.oauth.realmId,
                         true); 

Now, I have access to the various API endpoints to send/receive data.
I make calls to the API by writing routes that correspond to specific reports that I want the data for.

Here's an example:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
app.get('/vendorbalancedetail', express.bodyParser(), function(req, res) {
    qbo.reportVendorBalanceDetail({
        date_macro: 'This Month-to-date',
        appaid: 'Unpaid'
    }, function(_, report) {

        //console.log(report)
        res.render('vendorbalancedetail.jade', {
            title: "Report Detail",
            reportname: report["Header"]['ReportName'],
            daterange: "From:" + report["Header"]["StartPeriod"] + " to: " + report["Header"]["EndPeriod"],
            alldata: report,
            columns: report["Columns"],
            rowsperclient: report["Rows"]
        });
    })
})

Let's break it down.

1
2
3
4
5
6
app.get('/vendorbalancedetail', express.bodyParser(), function(req, res) {
            qbo.reportVendorBalanceDetail({
                        date_macro: 'This Month-to-date',
                        appaid: 'Unpaid'
                    }, function(_, report)

I initiate a GET request invoked as a method on the app variable which is a reference to an instance of the express server. I want this request to be made if the user navigates to the /vendorbalancedetail location of the app.

1
2
3
4
5
qbo.reportVendorBalanceDetail({
            date_macro: 'This Month-to-date',
            appaid: 'Unpaid'
        }, function(_, report))

This is an API call that requests the VendorBalanceDetail report for this month to date. It also returns only those transactions that have been marked as 'unpaid.' The call also makes the report object available so I can pass JSON to the view.

That is done like so:

1
2
3
4
5
6
7
8
res.render('vendorbalancedetail.jade', {
    title: "Report Detail",
    reportname: report["Header"]['ReportName'],
    daterange: "From:" + report["Header"]["StartPeriod"] + " to:     " + report["Header"]["EndPeriod"],
    alldata: report,
    columns: report["Columns"],
    rowsperclient: report["Rows"]
});

This is self-explanatory. I render the response from the API call to a view called vendorbalancedetail.jade and make all the variables available inside it.

The tricky part is working with the JSON returned by the API and displaying it in a row/column format. I have used tables for my approach. If you think of a better solution, do let me know. The code for the view would be too much for this post. You can check it out on the Github page.

More to come.