├── .gitignore ├── README.md ├── app.js ├── archive.zip ├── bin └── www ├── helpers ├── maptoqbase.js ├── qbo_setup.js └── quickbase_setup.js ├── images ├── auth.png ├── auth.wsd ├── authz.png └── authz.wsd ├── keys.js ├── license ├── models ├── index.js ├── quickbase_model.js └── quickbooks_model.js ├── package.json ├── properties ├── public └── stylesheets │ └── style.css ├── quickbooks_index.js ├── routes ├── foo ├── importdata.js ├── index.js ├── intuit.js ├── quickbase_route.js └── quickbooks.js ├── test └── test.js └── views ├── error.jade ├── failedlogin.jade ├── importdata.jade ├── index.jade ├── intuit.jade ├── layout.jade ├── qboauth.jade ├── qbodatadisplay.jade ├── quickbase.jade └── quickbooks.jade /.gitignore: -------------------------------------------------------------------------------- 1 | .* 2 | !/.gitignore 3 | node_modules/ 4 | .idea/ 5 | .idea/workspace.xml 6 | 7 | 8 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Intuit Developer with NodeJS Demystified 2 | ======== 3 | 4 | Developers need to grapple with a number of new technologies when they onboard to Intuit's Developer Platform. This includes OpenID and OAuth - essential for ensuring that applications are authorized to access data, and users are able to use the Intuit Credentials to sign in to the application. 5 | 6 | While OpenID and Oauth are essential to ensure proper operation with the Intuit Platform, it is hardly the main problem developers come to the Intuit Platform for. They are interested in using Intuit's Platform capabilities and data to help their customers. This repository shows how you can easily put all the 'plumbing' together so you can focus on developing your awesome App. 7 | 8 | The example here is in Node: But it can of course to reused using your favorite programming language. Where possible, we like using SDK's. In this example, we use mcohen's excellent wrapper around the QuickBooks API to get bootstrapped. 9 | 10 | Node makes it easy to build applications that use OpenID and OAuth, thanks to the QuickBooks API, [mcohen's Node SDK](https://github.com/mcohen01/node-quickbooks, "quickbooks node") and [Jared Hansson's ](https://github.com/jaredhanson/passport-intuit, "passport-intuit") SDK, which makes 11 | it easy to integrate with OpenID. We will use all of the above. 12 | 13 | You will need to store some data returned from the OpenID protocols and OAuth. We are using mongo in this example. 14 | 15 | A quick overview 16 | ========== 17 | 18 | There are two things that need to happen to for an IPP app to get bootstrapped 19 | 20 | 1. You need to have your customer log in and get validated with the Intuit system 21 | 2. You need to get the customers permission to access their data 22 | 23 | (1) Corresponds to OpenID. (2) corresponds to OAuth. 24 | 25 | In short, OpenID is used for _authentication_ and OAuth is used for _authorization_. You need to use both in order to log in and then access customer data 26 | 27 | Once you have completed (1) and (2) you will get some data in return - which is valid for a certain amount of time. Once that time expires, you have to repeat the procedure. 28 | 29 | Intuit also provides a widget to start the _authorization_ flow from any site. You can read more about this widget known as "Intuit Anywhere" [here](https://developer.intuit.com/docs/0150_payments/0060_authentication_and_authorization/widgets) 30 | 31 | OAuth Tokens are valid for 6 months. They can be revoked by the user at any time. 32 | 33 | How it all works together 34 | ============== 35 | 36 | >Please keep in mind that the example below are meant to be high level and glosses over some details. I encourage 37 | >you to read the references at the bottom for more normative information on the protocols. 38 | 39 | Lets assume that you are a developer, and run a company, Catmandu LLC. You specialize in the food industry. You analyze money movement for catering companies and need access 40 | to QuickBooks data for doing so. 41 | 42 | Jane is the owner of Kayser's Cakes, LLC. She is interested in trying out Catmandu's analysis engine. 43 | 44 | First, Jane needs to authenticate with Intuit. Catmandu needs to get her credentials from Intuit. 45 | 46 | 47 | 48 | Authentication 49 | --------- 50 | The sequence diagram below shows what happens in the authentication (openid) part of the flows; 51 | 52 | ![OpenID with Intuit](/images/auth.png) 53 | 54 | 55 | Authorization 56 | ------------- 57 | 58 | Once authenticated, Catmandu needs to ask Jane for authorization to access her Keyser's Cake, LLC company data. 59 | Keep in mind that Jane may have several companies that she runs: _One user credential can be associated with multiple realms_ 60 | So you have to ask for permission for each company file. Access to one does not imply access to another. Jane has to give permission to access each 61 | company individually. 62 | 63 | Intuit does authorization using the OAuth 1.0 protocol. In order to use OAuth, you need to visit 64 | [The Intuit Developer portal](http://developer.intuit.com/ "Intuit") and get keys for your application. 65 | You need an App Token, a consumer Key and a Consumer Secret. You will need to store this securely. (note that 66 | you need seperate keys for the development and the production environments) 67 | 68 | Once you have these, you use the standard OAuth flows to get authorization. A great resource for understanding OAuth 69 | in depth is [Understanding OAuth](http://www.cubrid.org/blog/dev-platform/dancing-with-oauth-understanding-how-authorization-works/ "OAuth Explained") 70 | 71 | The sequence diagram below shows the flows: 72 | 73 | 74 | ![Oauth with Intuit](/images/authz.png) 75 | 76 | 77 | A note on security 78 | --------------- 79 | 80 | OAuth tokens should be considered secure data, and be encrypted in your storage (_review intuit security guidelines_) 81 | 82 | Plumbing using NodeJS 83 | ----- 84 | 85 | One of the really nice things about node is npm. In particular, [Jared Hanson's passport-intuit](https://github.com/jaredhanson/passport-intuit "passport-intuit") make life very easy. 86 | You do not need to deep dive into OpenID and OAuth - you can just use passport-intuit for openid, and [mcohen's QuickBooks SDK](https://github.com/mcohen01/node-quickbooks "QuickBooks Node SDK") 87 | 88 | 89 | Setup 90 | ---- 91 | - download and run mongodb. Note its port number (27017 by default) 92 | - run 'npm install' to install the packages in package.json 93 | - set NODE_ENV=development 94 | - create a file named properties in the root directory. Add the following information to it, in the format shown 95 | * consumerKey = _your_consumer_key_from_developer.intuit.com_ 96 | * consumerSecret = _your_consumer_secret_from_developer.intuit.com_ 97 | 98 | USAGE 99 | ---- 100 | start mongod. you may need to provide it a data directory (suggested: ../data) 101 | use nodemon to run. (nodemon bin/www). 102 | After starting. navigate to localhost:3000 103 | 104 | ### Usage of passport-intuit 105 | 106 | 107 | The work of interacting with openid.intuit.com for authentication is done via intuit.js, which uses passport-intuit. 108 | 109 | This code in particular shows does all the work: 110 | 111 | 112 | // GET / 113 | // Use passport.authenticate() as route middleware to authenticate the 114 | // request. The first step in Intuit authentication will involve redirecting 115 | // the user to intuit.com. After authenticating, Intuit will redirect the 116 | // user back to this application at /auth/intuit/return 117 | router.get('/', 118 | passport.authenticate('intuit', {failureRedirect: '/failedlogin', failureFlash: true }), 119 | function(req, res) { 120 | console.log("+++++++++++in func"); 121 | res.redirect('/'); 122 | }); 123 | 124 | // GET /return 125 | // Use passport.authenticate() as route middleware to authenticate the 126 | // request. If authentication fails, the user will be redirected back to the 127 | // login page. Otherwise, the primary route function function will be called, 128 | // which, in this example, will redirect the user to the home page. 129 | router.get('/return', 130 | passport.authenticate('intuit', { failureRedirect: '/failedlogin' }), 131 | function(req, res) { 132 | console.log("in return", req, res); 133 | res.redirect('/quickbooks'); 134 | }); 135 | 136 | 137 | Note the reference to /quickbooks - that is the redirect to do OAuth, if necessary (your OAuth tokens are valid for a long time, 138 | and you need to redo OAuth only when the expire) _what is the duration? 6 months_? 139 | 140 | ### /quickbooks does the following: It starts with the requestToken. Once we have the requestToken, we exchange it for the 141 | oauth_token in /callback. the call to qboSetup stores the token and secret in mongo. (that part should be replaced 142 | with a call to your database if you are not using mongo) 143 | 144 | 145 | 146 | 147 | outer.get('/requestToken', function (req, res) { 148 | var postBody = { 149 | url: QuickBooks.REQUEST_TOKEN_URL, 150 | oauth: { 151 | callback: 'http://localhost:' + port + '/quickbooks/callback/', 152 | consumer_key: consumerKey, 153 | consumer_secret: consumerSecret 154 | } 155 | }; 156 | request.post(postBody, function (e, r, data) { 157 | var requestToken = qs.parse(data); 158 | req.session.oauth_token_secret = requestToken.oauth_token_secret; 159 | console.log(requestToken); 160 | res.redirect(QuickBooks.APP_CENTER_URL + requestToken.oauth_token) 161 | }); 162 | }); 163 | 164 | /** 165 | * callback when flows are completed 166 | */ 167 | 168 | router.get('/callback', function (req, res) { 169 | var postBody = { 170 | url: QuickBooks.ACCESS_TOKEN_URL, 171 | oauth: { 172 | consumer_key: consumerKey, 173 | consumer_secret: consumerSecret, 174 | token: req.query.oauth_token, 175 | token_secret: req.session.oauth_token_secret, 176 | verifier: req.query.oauth_verifier, 177 | realmId: req.query.realmId 178 | } 179 | } 180 | request.post(postBody, function (e, r, data) { 181 | var accessToken = qs.parse(data); 182 | console.log ("CALLBACK====================") 183 | console.log(accessToken); 184 | console.log(postBody.oauth.realmId); 185 | 186 | // save the access token somewhere on behalf of the logged in user 187 | qbosetup.qboSetup( accessToken.oauth_token, accessToken.oauth_token_secret, postBody.oauth.realmId, req.session.email, function(qboa) { 188 | console.log ("++++ QBO set", qboa); 189 | res.render('importdata'); 190 | }); 191 | 192 | 193 | //res.render("importdata"); 194 | }); 195 | // res.send('') 196 | 197 | }); 198 | 199 | ### /importdata 200 | 201 | we use mcohen's wrapper around the Intuit API's to fetch the accounts of the company file that we have permission for. 202 | Once the setup in the previous steps are completed, it becomes easy enough. In qbo_setup, a QuickBooks Object is created: 203 | 204 | qboauth = new QuickBooks( 205 | consumerKey, 206 | consumerSecret, 207 | token, 208 | secret, 209 | realm, 210 | false, // use the Sandbox 211 | true); // turn debugging 212 | console.log ("QBOAUTH is ", qboauth); 213 | 214 | 215 | Using this, we can easily use methods on the quickbooks API, like looking up accounts (importdata.js) 216 | 217 | 218 | qboauth.findAccounts(function (_, accounts) { 219 | req.session.accounts = accounts; 220 | 221 | 222 | //console.log(accounts); 223 | //accounts.QueryResponse.Account.forEach(function (account) { 224 | // console.log(account.Name) 225 | //}); 226 | res.render("qbodatadisplay", { accounts: accounts}); 227 | }); 228 | 229 | -------------------------------------------------------------------------------- /app.js: -------------------------------------------------------------------------------- 1 | var express = require('express'); 2 | var path = require('path'); 3 | var favicon = require('serve-favicon'); 4 | var logger = require('morgan'); 5 | var cookieParser = require('cookie-parser'); 6 | var bodyParser = require('body-parser'); 7 | var session = require ('express-session'); 8 | //var router = require ('express-router'); 9 | var routes = require('./routes/index'); 10 | var quickbooks = require('./routes/quickbooks'); 11 | var intuit = require('./routes/intuit'); 12 | var importdata = require('./routes/importdata'); 13 | var quickbase = require('./routes/quickbase_route'); 14 | var mongoose = require('mongoose'); 15 | var passport = require('passport'); 16 | var IntuitStrategy = require('passport-intuit').Strategy; 17 | 18 | var app = express(); 19 | 20 | // view engine setup 21 | app.set('views', path.join(__dirname, 'views')); 22 | app.set('view engine', 'jade'); 23 | 24 | 25 | // Passport session setup. 26 | // To support persistent login sessions, Passport needs to be able to 27 | // serialize users into and deserialize users out of the session. Typically, 28 | // this will be as simple as storing the user ID when serializing, and finding 29 | // the user by ID when deserializing. However, since this example does not 30 | // have a database of user records, the complete Intuit profile is serialized 31 | // and deserialized. 32 | passport.serializeUser(function(user, done) { 33 | done(null, user); 34 | }); 35 | 36 | passport.deserializeUser(function(obj, done) { 37 | done(null, obj); 38 | }); 39 | 40 | 41 | passport.use(new IntuitStrategy({ 42 | returnURL: 'http://localhost:3000/intuit/return', 43 | realm: 'http://localhost:3000/', 44 | stateless: true 45 | }, 46 | function(identifier, profile, done) { 47 | // asynchronous verification, for effect... 48 | process.nextTick(function () { 49 | 50 | // To keep the example simple, the user's Intuit profile is returned to 51 | // represent the logged-in user. In a typical application, you would want 52 | // to associate the Intuit account with a user record in your database, 53 | // and return that user instead. 54 | profile.identifier = identifier; 55 | // console.log ("+++++", profile); 56 | return done(null, profile); 57 | }); 58 | } 59 | )); 60 | 61 | // uncomment after placing your favicon in /public 62 | //app.use(favicon(path.join(__dirname, 'public', 'favicon.ico'))); 63 | app.use(logger('dev')); 64 | app.use(bodyParser.json()); 65 | app.use(bodyParser.urlencoded({ extended: false })); 66 | app.use(cookieParser()); 67 | app.use(express.static(path.join(__dirname, 'public'))); 68 | app.use(session({secret: 'smith', resave: false, saveUninitialized: true})); 69 | app.use(passport.initialize()); 70 | app.use(passport.session()); 71 | 72 | //app.use(router()); 73 | 74 | app.use('/', routes); // default to index.js 75 | app.use ('/quickbooks',quickbooks); 76 | app.use ('/intuit', intuit); 77 | app.use ('/importdata', importdata); 78 | app.use ('/quickbase', quickbase); 79 | 80 | 81 | app.get('/logout', function(req, res){ 82 | req.logout(); 83 | res.redirect('/'); 84 | }); 85 | 86 | // Simple route middleware to ensure user is authenticated. 87 | // Use this route middleware on any resource that needs to be protected. If 88 | // the request is authenticated (typically via a persistent login session), 89 | // the request will proceed. Otherwise, the user will be redirected to the 90 | // login page. 91 | function ensureAuthenticated(req, res, next) { 92 | if (req.isAuthenticated()) { return next(); } 93 | res.redirect('/login') 94 | } 95 | 96 | 97 | 98 | 99 | // catch 404 and forward to error handler 100 | app.use(function(req, res, next) { 101 | var err = new Error('Not Found'); 102 | err.status = 404; 103 | next(err); 104 | }); 105 | 106 | // error handlers 107 | 108 | // development error handler 109 | // will print stacktrace 110 | if (app.get('env') === 'development') { 111 | app.use(function(err, req, res, next) { 112 | res.status(err.status || 500); 113 | res.render('error', { 114 | message: err.message, 115 | error: err 116 | }); 117 | }); 118 | mongoose.connect('mongodb://localhost:27017/qbtest'); 119 | } 120 | 121 | // production error handler 122 | // no stacktraces leaked to user 123 | app.use(function(err, req, res, next) { 124 | res.status(err.status || 500); 125 | res.render('error', { 126 | message: err.message, 127 | error: {} 128 | }); 129 | }); 130 | 131 | 132 | module.exports = app; 133 | -------------------------------------------------------------------------------- /archive.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/intuit/intuit-developer-nodejs/86dd8a7f19914e90536264ccf6847301ee5481d3/archive.zip -------------------------------------------------------------------------------- /bin/www: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | /** 4 | * Module dependencies. 5 | */ 6 | 7 | var app = require('../app'); 8 | var debug = require('debug')('cancan2:server'); 9 | var http = require('http'); 10 | 11 | /** 12 | * Get port from environment and store in Express. 13 | */ 14 | 15 | var port = normalizePort(process.env.PORT || '3000'); 16 | app.set('port', port); 17 | 18 | /** 19 | * Create HTTP server. 20 | */ 21 | 22 | var server = http.createServer(app); 23 | 24 | /** 25 | * Listen on provided port, on all network interfaces. 26 | */ 27 | 28 | server.listen(port); 29 | server.on('error', onError); 30 | server.on('listening', onListening); 31 | 32 | /** 33 | * Normalize a port into a number, string, or false. 34 | */ 35 | 36 | function normalizePort(val) { 37 | var port = parseInt(val, 10); 38 | 39 | if (isNaN(port)) { 40 | // named pipe 41 | return val; 42 | } 43 | 44 | if (port >= 0) { 45 | // port number 46 | return port; 47 | } 48 | 49 | return false; 50 | } 51 | 52 | /** 53 | * Event listener for HTTP server "error" event. 54 | */ 55 | 56 | function onError(error) { 57 | if (error.syscall !== 'listen') { 58 | throw error; 59 | } 60 | 61 | var bind = typeof port === 'string' 62 | ? 'Pipe ' + port 63 | : 'Port ' + port; 64 | 65 | // handle specific listen errors with friendly messages 66 | switch (error.code) { 67 | case 'EACCES': 68 | console.error(bind + ' requires elevated privileges'); 69 | process.exit(1); 70 | break; 71 | case 'EADDRINUSE': 72 | console.error(bind + ' is already in use'); 73 | process.exit(1); 74 | break; 75 | default: 76 | throw error; 77 | } 78 | } 79 | 80 | /** 81 | * Event listener for HTTP server "listening" event. 82 | */ 83 | 84 | function onListening() { 85 | var addr = server.address(); 86 | var bind = typeof addr === 'string' 87 | ? 'pipe ' + addr 88 | : 'port ' + addr.port; 89 | debug('Listening on ' + bind); 90 | } 91 | -------------------------------------------------------------------------------- /helpers/maptoqbase.js: -------------------------------------------------------------------------------- 1 | 2 | 3 | /** 4 | * Maps data from QBO to quickbase 5 | * @type {*|exports|module.exports} 6 | */ 7 | 8 | 9 | /** 10 | * Takes a QBO account object, maps and stores it in QuickBase 11 | * @param account 12 | */ 13 | function accountMapper(account) { 14 | 15 | } 16 | 17 | 18 | module.exports.accountMapper = accountMapper; -------------------------------------------------------------------------------- /helpers/qbo_setup.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by sram on 7/13/15. 3 | */ 4 | 5 | var PropertyReader = require('properties-reader'); 6 | var properties = PropertyReader("./properties"); 7 | var QuickBooks = require('../quickbooks_index'); 8 | var qbModel = require ('../models/quickbooks_model'); 9 | 10 | var qboauth; 11 | 12 | function qboSetup (token, secret, realm, email, callback) { 13 | var consumerKey = properties.get('consumerKey'); 14 | var consumerSecret = properties.get('consumerSecret'); 15 | console.log ("----------QBOSETUP CREATED-----------"); 16 | qboauth = new QuickBooks( 17 | consumerKey, 18 | consumerSecret, 19 | token, 20 | secret, 21 | realm, 22 | false, // use the Sandbox 23 | true); // turn debugging 24 | console.log ("QBOAUTH is ", qboauth); 25 | 26 | /** 27 | * store the credentials in the db 28 | */ 29 | qbModel.qbo.findOneAndUpdate( 30 | {email: email}, 31 | { 32 | userid: email, 33 | realmid: realm, 34 | tokenSecret: secret, 35 | token: token 36 | }, 37 | {upsert: true}, 38 | function(err, numberAffected, raw) { 39 | console.log(err, numberAffected, raw) 40 | } 41 | ); 42 | callback(qboauth); 43 | 44 | } 45 | 46 | function qboAuth () { 47 | console.log ("returning..", qboauth); 48 | return qboauth; 49 | } 50 | 51 | module.exports.qboAuth = qboAuth; 52 | module.exports.qboSetup = qboSetup; -------------------------------------------------------------------------------- /helpers/quickbase_setup.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by sram on 7/10/15. 3 | */ 4 | 5 | var PropertyReader = require('properties-reader'); 6 | var properties = PropertyReader("./properties"); 7 | var QuickBase = require('quickbase'); 8 | var mongoose = require ('mongoose'); 9 | var quickbase_schema= require('../models').quickbaseModel; 10 | var quickbase_ticket = null; 11 | var appToken = null; 12 | var retval = {}; 13 | 14 | function setupQuickBase(callback) { 15 | appToken = properties.get('quickbase-apptoken'); 16 | console.log(isEmpty(retval)); 17 | if (!isEmpty(retval)) { 18 | // quickbase already initialized 19 | console.log ("quickbase initialized already..") 20 | callback(retval); 21 | } 22 | quickbase = new QuickBase({ 23 | realm: 'intuitcorp', 24 | appToken: appToken 25 | }); 26 | console.log("apptoken", appToken); 27 | username = properties.get('quickbase-username'); 28 | password = properties.get('quickbase-password'); 29 | quickbase.api('API_Authenticate', { 30 | username: username, 31 | password: password 32 | }).then(function (r) { 33 | quickbase_ticket = r.ticket; 34 | console.log("^^^", quickbase_ticket); 35 | retval.response = r; 36 | retval.quickbase = quickbase; 37 | callback(retval); 38 | }); 39 | //console.log("--",quickbase); 40 | //return quickbase; 41 | } 42 | 43 | function isEmpty(theobject) { 44 | return !Boolean(Object.keys(theobject).length); //returns 0 if empty or an integer > 0 if non-empty 45 | } 46 | 47 | 48 | 49 | function mapDB(r) { 50 | var qbase_schema = mongoose.model('quickbaseMeta'); 51 | var meta = new quickbase_schema.quickbase( 52 | { 53 | 54 | } 55 | ); 56 | 57 | console.log("created"); 58 | 59 | for (i = 0; i < r.table.chdbids.length; i++) { 60 | meta.tables.push( 61 | { 62 | tablename: r.table.chdbids[i].$.name, 63 | tableid: r.table.chdbids[i]._ 64 | } 65 | ); 66 | console.log(r.table.chdbids[i].$.name, r.table.chdbids[i]._); 67 | } 68 | quickbase_schema.quickbase.findOneAndUpdate( 69 | {table_id: r.table.original.table_id}, 70 | { 71 | name: r.table.name, 72 | table_id: r.table.original.table_id, 73 | app_id: r.table.original.app_id, 74 | tables: meta.tables 75 | }, 76 | {upsert: true}, 77 | function(err, numberAffected, raw) { 78 | console.log(err, numberAffected, raw) 79 | } 80 | ); 81 | } 82 | 83 | 84 | module.exports.setup = setupQuickBase; 85 | module.exports.mapDB = mapDB; -------------------------------------------------------------------------------- /images/auth.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/intuit/intuit-developer-nodejs/86dd8a7f19914e90536264ccf6847301ee5481d3/images/auth.png -------------------------------------------------------------------------------- /images/auth.wsd: -------------------------------------------------------------------------------- 1 | title Authentication Sequence 2 | 3 | Jane->Catmandu: visit home page 4 | Jane->Catmandu: Agree to sign up 5 | Catmandu->Jane: redirect to openid.intuit.com 6 | Jane->Intuit: Sign in using Intuit credentials 7 | Intuit->Catmandu: redirect Jane back to Catmandu with OpenID assertion. 8 | note right of Catmandu 9 | At this point OpenID authentication flow is complete. 10 | Catmandu receives the following as part of the OpenID assertion: 11 | Email ID,Full Name, First Name, Last Name. 12 | end note 13 | 14 | note right of Catmandu 15 | Catmandu uses the OpenID assertion to provision Jane as a user in its system. 16 | end note 17 | -------------------------------------------------------------------------------- /images/authz.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/intuit/intuit-developer-nodejs/86dd8a7f19914e90536264ccf6847301ee5481d3/images/authz.png -------------------------------------------------------------------------------- /images/authz.wsd: -------------------------------------------------------------------------------- 1 | title Authorization Sequence 2 | 3 | Catmandu->Intuit: Request Request Token 4 | Intuit->Catmandu: Grant Request Token (oauth token, oauth token secret) 5 | Catmandu->Intuit: Request Access Token 6 | Catmandu->Intuit: Redirect Jane to Realm Selector from Intuit 7 | note left of Jane: Jane selects 'Keyser's Cakes' company 8 | Intuit->Catmandu: Redirect Jane back to Catmandu 9 | Intuit->Catmandu: Grant Access Token 10 | Intuit->Catmandu: redirect Jane back to Catmandu. 11 | note right of Catmandu: At this point, OAuth flows are complete. 12 | note right of Catmandu: Catmandu has the oauth Consumer Key and OAuth Token 13 | -------------------------------------------------------------------------------- /keys.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by sram on 7/6/15. 3 | */ 4 | var config = {}; 5 | 6 | // DEPRECATED. DO NOT USE> CREATE A LOCAL PROPERTIES FILE 7 | 8 | module.exports = config; -------------------------------------------------------------------------------- /license: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 Intuit 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /models/index.js: -------------------------------------------------------------------------------- 1 | // export everything in the models directory 2 | // add other files you create here and require just this file 3 | 4 | /** 5 | * load just this file to get all the models in your code 6 | * @type {exports|module.exports} 7 | */ 8 | exports.quickbooksModel = require('./quickbooks_model'); 9 | exports.quickbaseModel = require('./quickbase_model'); 10 | 11 | -------------------------------------------------------------------------------- /models/quickbase_model.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by sram on 7/10/15. 3 | */ 4 | 5 | 6 | var mongoose = require('mongoose'); 7 | var Schema = mongoose.Schema; 8 | 9 | /** 10 | * Stores quickbase info, like the table id's which are needed 11 | * to push data and read from the table 12 | */ 13 | 14 | var quickbaseDetails = new Schema({ 15 | tablename: String, 16 | tableid: String 17 | }); 18 | 19 | var quickbaseMeta = new Schema({ 20 | name: String, 21 | table_id: String, 22 | app_id: String, 23 | tables: [quickbaseDetails] 24 | }); 25 | 26 | module.exports.quickbase = mongoose.model('quickbaseMeta', quickbaseMeta); 27 | 28 | -------------------------------------------------------------------------------- /models/quickbooks_model.js: -------------------------------------------------------------------------------- 1 | 2 | 3 | var mongoose = require('mongoose'); 4 | var Schema = mongoose.Schema; 5 | /** 6 | * Stores information about the quickbooks auth tokens 7 | */ 8 | 9 | var quickbooksSchema = new Schema({ 10 | userid: String, 11 | realmid: String, 12 | token: String, 13 | tokenSecret: String 14 | }); 15 | 16 | module.exports.qbo = mongoose.model('quickbooks', quickbooksSchema); 17 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "cancanv2", 3 | "version": "0.0.1", 4 | "private": true, 5 | "scripts": { 6 | "start": "node ./bin/www" 7 | }, 8 | "dependencies": { 9 | "body-parser": "~1.18.3", 10 | "cookie-parser": "~1.4.4", 11 | "debug": "~4.1.1", 12 | "express": "~4.16.4", 13 | "jade": "~1.11.0", 14 | "morgan": "~1.9.1", 15 | "serve-favicon": "~2.5.0", 16 | "node-quickbooks": "2.0.29", 17 | "quickbase": "2.10.2", 18 | "request": "2.88.0", 19 | "uuid": "*", 20 | "node-uuid": "*", 21 | "request-debug": "0.2.0", 22 | "moment": "2.24.0", 23 | "underscore": "1.9.1", 24 | "express-session": "1.15.6", 25 | "express-router": "0.0.1", 26 | "mongoose": "5.4.20", 27 | "passport-intuit": "0.2.0", 28 | "passport": "0.4.0", 29 | "properties-reader": "0.0.16", 30 | "mocha": "6.0.2", 31 | "superagent": "4.1.0", 32 | "chai": "*" 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /properties: -------------------------------------------------------------------------------- 1 | consumerKey = 2 | consumerSecret = 3 | -------------------------------------------------------------------------------- /public/stylesheets/style.css: -------------------------------------------------------------------------------- 1 | body { 2 | padding: 50px; 3 | font: 14px "Lucida Grande", Helvetica, Arial, sans-serif; 4 | } 5 | 6 | a { 7 | color: #00B7FF; 8 | } -------------------------------------------------------------------------------- /quickbooks_index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @file Node.js client for QuickBooks V3 API 3 | * @name node-quickbooks 4 | * @author Michael Cohen 5 | * @license ISC 6 | * @copyright 2014 Michael Cohen 7 | */ 8 | 9 | var request = require('request'), 10 | uuid = require('node-uuid'), 11 | debug = require('request-debug'), 12 | util = require('util'), 13 | moment = require('moment'), 14 | _ = require('underscore'), 15 | version = require('./package.json').version 16 | 17 | module.exports = QuickBooks 18 | 19 | QuickBooks.REQUEST_TOKEN_URL = 'https://oauth.intuit.com/oauth/v1/get_request_token' 20 | QuickBooks.ACCESS_TOKEN_URL = 'https://oauth.intuit.com/oauth/v1/get_access_token' 21 | QuickBooks.APP_CENTER_BASE = 'https://appcenter.intuit.com' 22 | QuickBooks.APP_CENTER_URL = QuickBooks.APP_CENTER_BASE + '/Connect/Begin?oauth_token=' 23 | QuickBooks.V3_ENDPOINT_BASE_URL = 'https://sandbox-quickbooks.api.intuit.com/v3/company/' 24 | QuickBooks.PAYMENTS_API_BASE_URL = 'https://sandbox.api.intuit.com/quickbooks/v4/payments' 25 | QuickBooks.QUERY_OPERATORS = ['=', 'IN', '<', '>', '<=', '>=', 'LIKE'] 26 | 27 | /** 28 | * Node.js client encapsulating access to the QuickBooks V3 Rest API. An instance 29 | * of this class should be instantiated on behalf of each user accessing the api. 30 | * 31 | * @param consumerKey - application key 32 | * @param consumerSecret - application password 33 | * @param token - the OAuth generated user-specific key 34 | * @param tokenSecret - the OAuth generated user-specific password 35 | * @param realmId - QuickBooks companyId, returned as a request parameter when the user is redirected to the provided callback URL following authentication 36 | * @param useSandbox - boolean - See https://developer.intuit.com/v2/blog/2014/10/24/intuit-developer-now-offers-quickbooks-sandboxes 37 | * @param debug - boolean flag to turn on logging of HTTP requests, including headers and body 38 | * @constructor 39 | */ 40 | function QuickBooks(consumerKey, consumerSecret, token, tokenSecret, realmId, useSandbox, debug) { 41 | var prefix = _.isObject(consumerKey) ? 'consumerKey.' : '' 42 | this.consumerKey = eval(prefix + 'consumerKey') 43 | this.consumerSecret = eval(prefix + 'consumerSecret') 44 | this.token = eval(prefix + 'token') 45 | this.tokenSecret = eval(prefix + 'tokenSecret') 46 | this.realmId = eval(prefix + 'realmId') 47 | this.useSandbox = eval(prefix + 'useSandbox') 48 | this.debug = eval(prefix + 'debug') 49 | this.endpoint = this.useSandbox ? QuickBooks.V3_ENDPOINT_BASE_URL : QuickBooks.V3_ENDPOINT_BASE_URL.replace('sandbox-', '') 50 | this.paymentEndpoint = this.useSandbox ? QuickBooks.PAYMENTS_API_BASE_URL : QuickBooks.PAYMENTS_API_BASE_URL.replace('sandbox.', '') 51 | } 52 | 53 | /** 54 | * Batch operation to enable an application to perform multiple operations in a single request. 55 | * The following batch items are supported: 56 | create 57 | update 58 | delete 59 | query 60 | * The maximum number of batch items in a single request is 25. 61 | * 62 | * @param {object} items - JavaScript array of batch items 63 | * @param {function} callback - Callback function which is called with any error and list of BatchItemResponses 64 | */ 65 | QuickBooks.prototype.batch = function(items, callback) { 66 | module.request(this, 'post', {url: '/batch'}, {BatchItemRequest: items}, callback) 67 | } 68 | 69 | /** 70 | * The change data capture (CDC) operation returns a list of entities that have changed since a specified time. 71 | * 72 | * @param {object} entities - Comma separated list or JavaScript array of entities to search for changes 73 | * @param {object} since - JavaScript Date or string representation of the form '2012-07-20T22:25:51-07:00' to look back for changes until 74 | * @param {function} callback - Callback function which is called with any error and list of changes 75 | */ 76 | QuickBooks.prototype.changeDataCapture = function(entities, since, callback) { 77 | var url = '/cdc?entities=' 78 | url += typeof entities === 'string' ? entities : entities.join(',') 79 | url += '&changedSince=' 80 | url += typeof since === 'string' ? since : moment(since).format() 81 | module.request(this, 'get', {url: url}, null, callback) 82 | } 83 | 84 | 85 | // ********************** Charge Api ********************** 86 | 87 | QuickBooks.prototype.cardToken = function(card, callback) { 88 | module.request(this, 'post', { 89 | url: '/tokens', 90 | headers: { 91 | company_id: this.realmId 92 | } 93 | }, card, callback) 94 | } 95 | 96 | 97 | /** 98 | * Process a credit card charge using card details or token. 99 | * Can capture funds or just authorize. 100 | * 101 | * @param {object} charge - details, amount, currency etc. of charge to be processed 102 | * @param callback - Callback function which is called with any error or the saved Charge 103 | */ 104 | QuickBooks.prototype.charge = function(charge, callback) { 105 | module.request(this, 'post', { 106 | url: '/charges', 107 | headers: { 108 | company_id: this.realmId 109 | } 110 | }, charge, callback) 111 | } 112 | 113 | /** 114 | * Get details of charge. 115 | * 116 | * @param {string} chargeId - of previously created charge 117 | * @param callback - Callback function which is called with any error or the Charge 118 | */ 119 | QuickBooks.prototype.getCharge = function(chargeId, callback) { 120 | module.request(this, 'get', { 121 | url: '/charges/' + chargeId, 122 | headers: { 123 | company_id: this.realmId 124 | } 125 | }, null, callback) 126 | } 127 | 128 | /** 129 | * Allows you to capture funds for an existing charge that was intended to be captured at a later time. 130 | * 131 | * @param {string} chargeId - of previously created charge 132 | * @param {object} charge - details, amount, currency to capture 133 | * @param callback - Callback function which is called with any error or the capture description 134 | */ 135 | QuickBooks.prototype.capture = function(chargeId, capture, callback) { 136 | module.request(this, 'post', { 137 | url: '/charges/' + chargeId + '/capture', 138 | headers: { 139 | company_id: this.realmId 140 | } 141 | }, capture, callback) 142 | } 143 | 144 | /** 145 | * Allows you to refund an existing charge. Full and partial refund are supported. 146 | * 147 | * @param {string} chargeId - of previously created charge 148 | * @param {object} refund - details, amount, currency to refund 149 | * @param callback - Callback function which is called with any error or the refund description 150 | */ 151 | QuickBooks.prototype.refund = function(chargeId, refund, callback) { 152 | module.request(this, 'post', { 153 | url: '/charges/' + chargeId + '/refunds', 154 | headers: { 155 | company_id: this.realmId 156 | } 157 | }, refund, callback) 158 | } 159 | 160 | /** 161 | * Retrieves the Refund for the given refund id 162 | * 163 | * @param {string} chargeId - id of previously created charge 164 | * @param {string} refundId - id of previously created Refund 165 | * @param callback - Callback function which is called with any error or the Refund 166 | */ 167 | QuickBooks.prototype.getRefund = function(chargeId, refundId, callback) { 168 | module.request(this, 'get', { 169 | url: '/charges/' + chargeId + '/refunds/' + refundId, 170 | headers: { 171 | company_id: this.realmId 172 | } 173 | }, null, callback) 174 | } 175 | 176 | /** 177 | * Creates the Account in QuickBooks 178 | * 179 | * @param {object} account - The unsaved account, to be persisted in QuickBooks 180 | * @param {function} callback - Callback function which is called with any error and the persistent Account 181 | */ 182 | QuickBooks.prototype.createAccount = function(account, callback) { 183 | module.create(this, 'account', account, callback) 184 | } 185 | 186 | /** 187 | * Creates the Attachable in QuickBooks 188 | * 189 | * @param {object} attachable - The unsaved attachable, to be persisted in QuickBooks 190 | * @param {function} callback - Callback function which is called with any error and the persistent Attachable 191 | */ 192 | QuickBooks.prototype.createAttachable = function(attachable, callback) { 193 | module.create(this, 'attachable', attachable, callback) 194 | } 195 | 196 | /** 197 | * Creates the Bill in QuickBooks 198 | * 199 | * @param {object} bill - The unsaved bill, to be persisted in QuickBooks 200 | * @param {function} callback - Callback function which is called with any error and the persistent Bill 201 | */ 202 | QuickBooks.prototype.createBill = function(bill, callback) { 203 | module.create(this, 'bill', bill, callback) 204 | } 205 | 206 | /** 207 | * Creates the BillPayment in QuickBooks 208 | * 209 | * @param {object} billPayment - The unsaved billPayment, to be persisted in QuickBooks 210 | * @param {function} callback - Callback function which is called with any error and the persistent BillPayment 211 | */ 212 | QuickBooks.prototype.createBillPayment = function(billPayment, callback) { 213 | module.create(this, 'billPayment', billPayment, callback) 214 | } 215 | 216 | /** 217 | * Creates the Class in QuickBooks 218 | * 219 | * @param {object} class - The unsaved class, to be persisted in QuickBooks 220 | * @param {function} callback - Callback function which is called with any error and the persistent Class 221 | */ 222 | QuickBooks.prototype.createClass = function(klass, callback) { 223 | module.create(this, 'class', klass, callback) 224 | } 225 | 226 | /** 227 | * Creates the CreditMemo in QuickBooks 228 | * 229 | * @param {object} creditMemo - The unsaved creditMemo, to be persisted in QuickBooks 230 | * @param {function} callback - Callback function which is called with any error and the persistent CreditMemo 231 | */ 232 | QuickBooks.prototype.createCreditMemo = function(creditMemo, callback) { 233 | module.create(this, 'creditMemo', creditMemo, callback) 234 | } 235 | 236 | /** 237 | * Creates the Customer in QuickBooks 238 | * 239 | * @param {object} customer - The unsaved customer, to be persisted in QuickBooks 240 | * @param {function} callback - Callback function which is called with any error and the persistent Customer 241 | */ 242 | QuickBooks.prototype.createCustomer = function(customer, callback) { 243 | module.create(this, 'customer', customer, callback) 244 | } 245 | 246 | /** 247 | * Creates the Department in QuickBooks 248 | * 249 | * @param {object} department - The unsaved department, to be persisted in QuickBooks 250 | * @param {function} callback - Callback function which is called with any error and the persistent Department 251 | */ 252 | QuickBooks.prototype.createDepartment = function(department, callback) { 253 | module.create(this, 'department', department, callback) 254 | } 255 | 256 | /** 257 | * Creates the Employee in QuickBooks 258 | * 259 | * @param {object} employee - The unsaved employee, to be persisted in QuickBooks 260 | * @param {function} callback - Callback function which is called with any error and the persistent Employee 261 | */ 262 | QuickBooks.prototype.createEmployee = function(employee, callback) { 263 | module.create(this, 'employee', employee, callback) 264 | } 265 | 266 | /** 267 | * Creates the Estimate in QuickBooks 268 | * 269 | * @param {object} estimate - The unsaved estimate, to be persisted in QuickBooks 270 | * @param {function} callback - Callback function which is called with any error and the persistent Estimate 271 | */ 272 | QuickBooks.prototype.createEstimate = function(estimate, callback) { 273 | module.create(this, 'estimate', estimate, callback) 274 | } 275 | 276 | /** 277 | * Creates the Invoice in QuickBooks 278 | * 279 | * @param {object} invoice - The unsaved invoice, to be persisted in QuickBooks 280 | * @param {function} callback - Callback function which is called with any error and the persistent Invoice 281 | */ 282 | QuickBooks.prototype.createInvoice = function(invoice, callback) { 283 | module.create(this, 'invoice', invoice, callback) 284 | } 285 | 286 | /** 287 | * Creates the Item in QuickBooks 288 | * 289 | * @param {object} item - The unsaved item, to be persisted in QuickBooks 290 | * @param {function} callback - Callback function which is called with any error and the persistent Item 291 | */ 292 | QuickBooks.prototype.createItem = function(item, callback) { 293 | module.create(this, 'item', item, callback) 294 | } 295 | 296 | /** 297 | * Creates the JournalEntry in QuickBooks 298 | * 299 | * @param {object} journalEntry - The unsaved journalEntry, to be persisted in QuickBooks 300 | * @param {function} callback - Callback function which is called with any error and the persistent JournalEntry 301 | */ 302 | QuickBooks.prototype.createJournalEntry = function(journalEntry, callback) { 303 | module.create(this, 'journalEntry', journalEntry, callback) 304 | } 305 | 306 | /** 307 | * Creates the Payment in QuickBooks 308 | * 309 | * @param {object} payment - The unsaved payment, to be persisted in QuickBooks 310 | * @param {function} callback - Callback function which is called with any error and the persistent Payment 311 | */ 312 | QuickBooks.prototype.createPayment = function(payment, callback) { 313 | module.create(this, 'payment', payment, callback) 314 | } 315 | 316 | /** 317 | * Creates the PaymentMethod in QuickBooks 318 | * 319 | * @param {object} paymentMethod - The unsaved paymentMethod, to be persisted in QuickBooks 320 | * @param {function} callback - Callback function which is called with any error and the persistent PaymentMethod 321 | */ 322 | QuickBooks.prototype.createPaymentMethod = function(paymentMethod, callback) { 323 | module.create(this, 'paymentMethod', paymentMethod, callback) 324 | } 325 | 326 | /** 327 | * Creates the Purchase in QuickBooks 328 | * 329 | * @param {object} purchase - The unsaved purchase, to be persisted in QuickBooks 330 | * @param {function} callback - Callback function which is called with any error and the persistent Purchase 331 | */ 332 | QuickBooks.prototype.createPurchase = function(purchase, callback) { 333 | module.create(this, 'purchase', purchase, callback) 334 | } 335 | 336 | /** 337 | * Creates the PurchaseOrder in QuickBooks 338 | * 339 | * @param {object} purchaseOrder - The unsaved purchaseOrder, to be persisted in QuickBooks 340 | * @param {function} callback - Callback function which is called with any error and the persistent PurchaseOrder 341 | */ 342 | QuickBooks.prototype.createPurchaseOrder = function(purchaseOrder, callback) { 343 | module.create(this, 'purchaseOrder', purchaseOrder, callback) 344 | } 345 | 346 | /** 347 | * Creates the RefundReceipt in QuickBooks 348 | * 349 | * @param {object} refundReceipt - The unsaved refundReceipt, to be persisted in QuickBooks 350 | * @param {function} callback - Callback function which is called with any error and the persistent RefundReceipt 351 | */ 352 | QuickBooks.prototype.createRefundReceipt = function(refundReceipt, callback) { 353 | module.create(this, 'refundReceipt', refundReceipt, callback) 354 | } 355 | 356 | /** 357 | * Creates the SalesReceipt in QuickBooks 358 | * 359 | * @param {object} salesReceipt - The unsaved salesReceipt, to be persisted in QuickBooks 360 | * @param {function} callback - Callback function which is called with any error and the persistent SalesReceipt 361 | */ 362 | QuickBooks.prototype.createSalesReceipt = function(salesReceipt, callback) { 363 | module.create(this, 'salesReceipt', salesReceipt, callback) 364 | } 365 | 366 | /** 367 | * Creates the TaxAgency in QuickBooks 368 | * 369 | * @param {object} taxAgency - The unsaved taxAgency, to be persisted in QuickBooks 370 | * @param {function} callback - Callback function which is called with any error and the persistent TaxAgency 371 | */ 372 | QuickBooks.prototype.createTaxAgency = function(taxAgency, callback) { 373 | module.create(this, 'taxAgency', taxAgency, callback) 374 | } 375 | 376 | /** 377 | * Creates the TaxService in QuickBooks 378 | * 379 | * @param {object} taxService - The unsaved taxService, to be persisted in QuickBooks 380 | * @param {function} callback - Callback function which is called with any error and the persistent TaxService 381 | */ 382 | QuickBooks.prototype.createTaxService = function(taxService, callback) { 383 | module.create(this, 'taxService', taxService, callback) 384 | } 385 | 386 | /** 387 | * Creates the Term in QuickBooks 388 | * 389 | * @param {object} term - The unsaved term, to be persisted in QuickBooks 390 | * @param {function} callback - Callback function which is called with any error and the persistent Term 391 | */ 392 | QuickBooks.prototype.createTerm = function(term, callback) { 393 | module.create(this, 'term', term, callback) 394 | } 395 | 396 | /** 397 | * Creates the TimeActivity in QuickBooks 398 | * 399 | * @param {object} timeActivity - The unsaved timeActivity, to be persisted in QuickBooks 400 | * @param {function} callback - Callback function which is called with any error and the persistent TimeActivity 401 | */ 402 | QuickBooks.prototype.createTimeActivity = function(timeActivity, callback) { 403 | module.create(this, 'timeActivity', timeActivity, callback) 404 | } 405 | 406 | /** 407 | * Creates the Vendor in QuickBooks 408 | * 409 | * @param {object} vendor - The unsaved vendor, to be persisted in QuickBooks 410 | * @param {function} callback - Callback function which is called with any error and the persistent Vendor 411 | */ 412 | QuickBooks.prototype.createVendor = function(vendor, callback) { 413 | module.create(this, 'vendor', vendor, callback) 414 | } 415 | 416 | /** 417 | * Creates the VendorCredit in QuickBooks 418 | * 419 | * @param {object} vendorCredit - The unsaved vendorCredit, to be persisted in QuickBooks 420 | * @param {function} callback - Callback function which is called with any error and the persistent VendorCredit 421 | */ 422 | QuickBooks.prototype.createVendorCredit = function(vendorCredit, callback) { 423 | module.create(this, 'vendorCredit', vendorCredit, callback) 424 | } 425 | 426 | 427 | 428 | /** 429 | * Retrieves the Account from QuickBooks 430 | * 431 | * @param {string} Id - The Id of persistent Account 432 | * @param {function} callback - Callback function which is called with any error and the persistent Account 433 | */ 434 | QuickBooks.prototype.getAccount = function(id, callback) { 435 | module.read(this, 'account', id, callback) 436 | } 437 | 438 | /** 439 | * Retrieves the Attachable from QuickBooks 440 | * 441 | * @param {string} Id - The Id of persistent Attachable 442 | * @param {function} callback - Callback function which is called with any error and the persistent Attachable 443 | */ 444 | QuickBooks.prototype.getAttachable = function(id, callback) { 445 | module.read(this, 'attachable', id, callback) 446 | } 447 | 448 | /** 449 | * Retrieves the Bill from QuickBooks 450 | * 451 | * @param {string} Id - The Id of persistent Bill 452 | * @param {function} callback - Callback function which is called with any error and the persistent Bill 453 | */ 454 | QuickBooks.prototype.getBill = function(id, callback) { 455 | module.read(this, 'bill', id, callback) 456 | } 457 | 458 | /** 459 | * Retrieves the BillPayment from QuickBooks 460 | * 461 | * @param {string} Id - The Id of persistent BillPayment 462 | * @param {function} callback - Callback function which is called with any error and the persistent BillPayment 463 | */ 464 | QuickBooks.prototype.getBillPayment = function(id, callback) { 465 | module.read(this, 'billPayment', id, callback) 466 | } 467 | 468 | /** 469 | * Retrieves the Class from QuickBooks 470 | * 471 | * @param {string} Id - The Id of persistent Class 472 | * @param {function} callback - Callback function which is called with any error and the persistent Class 473 | */ 474 | QuickBooks.prototype.getClass = function(id, callback) { 475 | module.read(this, 'class', id, callback) 476 | } 477 | 478 | /** 479 | * Retrieves the CompanyInfo from QuickBooks 480 | * 481 | * @param {string} Id - The Id of persistent CompanyInfo 482 | * @param {function} callback - Callback function which is called with any error and the persistent CompanyInfo 483 | */ 484 | QuickBooks.prototype.getCompanyInfo = function(id, callback) { 485 | module.read(this, 'companyInfo', id, callback) 486 | } 487 | 488 | /** 489 | * Retrieves the CreditMemo from QuickBooks 490 | * 491 | * @param {string} Id - The Id of persistent CreditMemo 492 | * @param {function} callback - Callback function which is called with any error and the persistent CreditMemo 493 | */ 494 | QuickBooks.prototype.getCreditMemo = function(id, callback) { 495 | module.read(this, 'creditMemo', id, callback) 496 | } 497 | 498 | /** 499 | * Retrieves the Customer from QuickBooks 500 | * 501 | * @param {string} Id - The Id of persistent Customer 502 | * @param {function} callback - Callback function which is called with any error and the persistent Customer 503 | */ 504 | QuickBooks.prototype.getCustomer = function(id, callback) { 505 | module.read(this, 'customer', id, callback) 506 | } 507 | 508 | /** 509 | * Retrieves the Department from QuickBooks 510 | * 511 | * @param {string} Id - The Id of persistent Department 512 | * @param {function} callback - Callback function which is called with any error and the persistent Department 513 | */ 514 | QuickBooks.prototype.getDepartment = function(id, callback) { 515 | module.read(this, 'department', id, callback) 516 | } 517 | 518 | /** 519 | * Retrieves the Employee from QuickBooks 520 | * 521 | * @param {string} Id - The Id of persistent Employee 522 | * @param {function} callback - Callback function which is called with any error and the persistent Employee 523 | */ 524 | QuickBooks.prototype.getEmployee = function(id, callback) { 525 | module.read(this, 'employee', id, callback) 526 | } 527 | 528 | /** 529 | * Retrieves the Estimate from QuickBooks 530 | * 531 | * @param {string} Id - The Id of persistent Estimate 532 | * @param {function} callback - Callback function which is called with any error and the persistent Estimate 533 | */ 534 | QuickBooks.prototype.getEstimate = function(id, callback) { 535 | module.read(this, 'estimate', id, callback) 536 | } 537 | 538 | /** 539 | * Retrieves the Invoice from QuickBooks 540 | * 541 | * @param {string} Id - The Id of persistent Invoice 542 | * @param {function} callback - Callback function which is called with any error and the persistent Invoice 543 | */ 544 | QuickBooks.prototype.getInvoice = function(id, callback) { 545 | module.read(this, 'invoice', id, callback) 546 | } 547 | 548 | /** 549 | * Retrieves the Invoice PDF from QuickBooks 550 | * 551 | * @param {string} Id - The Id of persistent Invoice 552 | * @param {function} callback - Callback function which is called with any error and the Invoice PDF 553 | */ 554 | QuickBooks.prototype.getInvoicePdf = function(id, callback) { 555 | module.read(this, 'Invoice', id + '/pdf', callback) 556 | } 557 | 558 | /** 559 | * Emails the Invoice PDF from QuickBooks to the address supplied in Invoice.BillEmail.EmailAddress 560 | * or the specified 'sendTo' address 561 | * 562 | * @param {string} Id - The Id of persistent Invoice 563 | * @param {string} sendTo - optional email address to send the PDF to. If not provided, address supplied in Invoice.BillEmail.EmailAddress will be used 564 | * @param {function} callback - Callback function which is called with any error and the Invoice PDF 565 | */ 566 | QuickBooks.prototype.sendInvoicePdf = function(id, sendTo, callback) { 567 | var path = '/invoice/' + id + '/send' 568 | callback = _.isFunction(sendTo) ? sendTo : callback 569 | if (sendTo && ! _.isFunction(sendTo)) { 570 | path += '?sendTo=' + sendTo 571 | } 572 | module.request(this, 'post', {url: path}, null, module.unwrap(callback, 'Invoice')) 573 | } 574 | 575 | /** 576 | * Retrieves the Item from QuickBooks 577 | * 578 | * @param {string} Id - The Id of persistent Item 579 | * @param {function} callback - Callback function which is called with any error and the persistent Item 580 | */ 581 | QuickBooks.prototype.getItem = function(id, callback) { 582 | module.read(this, 'item', id, callback) 583 | } 584 | 585 | /** 586 | * Retrieves the JournalEntry from QuickBooks 587 | * 588 | * @param {string} Id - The Id of persistent JournalEntry 589 | * @param {function} callback - Callback function which is called with any error and the persistent JournalEntry 590 | */ 591 | QuickBooks.prototype.getJournalEntry = function(id, callback) { 592 | module.read(this, 'journalEntry', id, callback) 593 | } 594 | 595 | /** 596 | * Retrieves the Payment from QuickBooks 597 | * 598 | * @param {string} Id - The Id of persistent Payment 599 | * @param {function} callback - Callback function which is called with any error and the persistent Payment 600 | */ 601 | QuickBooks.prototype.getPayment = function(id, callback) { 602 | module.read(this, 'payment', id, callback) 603 | } 604 | 605 | /** 606 | * Retrieves the PaymentMethod from QuickBooks 607 | * 608 | * @param {string} Id - The Id of persistent PaymentMethod 609 | * @param {function} callback - Callback function which is called with any error and the persistent PaymentMethod 610 | */ 611 | QuickBooks.prototype.getPaymentMethod = function(id, callback) { 612 | module.read(this, 'paymentMethod', id, callback) 613 | } 614 | 615 | /** 616 | * Retrieves the Preferences from QuickBooks 617 | * 618 | * @param {string} Id - The Id of persistent Preferences 619 | * @param {function} callback - Callback function which is called with any error and the persistent Preferences 620 | */ 621 | QuickBooks.prototype.getPreferences = function(id, callback) { 622 | module.read(this, 'preferences', id, callback) 623 | } 624 | 625 | /** 626 | * Retrieves the Purchase from QuickBooks 627 | * 628 | * @param {string} Id - The Id of persistent Purchase 629 | * @param {function} callback - Callback function which is called with any error and the persistent Purchase 630 | */ 631 | QuickBooks.prototype.getPurchase = function(id, callback) { 632 | module.read(this, 'purchase', id, callback) 633 | } 634 | 635 | /** 636 | * Retrieves the PurchaseOrder from QuickBooks 637 | * 638 | * @param {string} Id - The Id of persistent PurchaseOrder 639 | * @param {function} callback - Callback function which is called with any error and the persistent PurchaseOrder 640 | */ 641 | QuickBooks.prototype.getPurchaseOrder = function(id, callback) { 642 | module.read(this, 'purchaseOrder', id, callback) 643 | } 644 | 645 | /** 646 | * Retrieves the RefundReceipt from QuickBooks 647 | * 648 | * @param {string} Id - The Id of persistent RefundReceipt 649 | * @param {function} callback - Callback function which is called with any error and the persistent RefundReceipt 650 | */ 651 | QuickBooks.prototype.getRefundReceipt = function(id, callback) { 652 | module.read(this, 'refundReceipt', id, callback) 653 | } 654 | 655 | /** 656 | * Retrieves the Reports from QuickBooks 657 | * 658 | * @param {string} Id - The Id of persistent Reports 659 | * @param {function} callback - Callback function which is called with any error and the persistent Reports 660 | */ 661 | QuickBooks.prototype.getReports = function(id, callback) { 662 | module.read(this, 'reports', id, callback) 663 | } 664 | 665 | /** 666 | * Retrieves the SalesReceipt from QuickBooks 667 | * 668 | * @param {string} Id - The Id of persistent SalesReceipt 669 | * @param {function} callback - Callback function which is called with any error and the persistent SalesReceipt 670 | */ 671 | QuickBooks.prototype.getSalesReceipt = function(id, callback) { 672 | module.read(this, 'salesReceipt', id, callback) 673 | } 674 | 675 | /** 676 | * Retrieves the SalesReceipt PDF from QuickBooks 677 | * 678 | * @param {string} Id - The Id of persistent SalesReceipt 679 | * @param {function} callback - Callback function which is called with any error and the SalesReceipt PDF 680 | */ 681 | QuickBooks.prototype.getSalesReceiptPdf = function(id, callback) { 682 | module.read(this, 'salesReceipt', id + '/pdf', callback) 683 | } 684 | 685 | /** 686 | * Emails the SalesReceipt PDF from QuickBooks to the address supplied in SalesReceipt.BillEmail.EmailAddress 687 | * or the specified 'sendTo' address 688 | * 689 | * @param {string} Id - The Id of persistent SalesReceipt 690 | * @param {string} sendTo - optional email address to send the PDF to. If not provided, address supplied in SalesReceipt.BillEmail.EmailAddress will be used 691 | * @param {function} callback - Callback function which is called with any error and the SalesReceipt PDF 692 | */ 693 | QuickBooks.prototype.sendSalesReceiptPdf = function(id, sendTo, callback) { 694 | var path = '/salesreceipt/' + id + '/send' 695 | callback = _.isFunction(sendTo) ? sendTo : callback 696 | if (sendTo && ! _.isFunction(sendTo)) { 697 | path += '?sendTo=' + sendTo 698 | } 699 | module.request(this, 'post', {url: path}, null, module.unwrap(callback, 'SalesReceipt')) 700 | } 701 | 702 | /** 703 | * Retrieves the TaxAgency from QuickBooks 704 | * 705 | * @param {string} Id - The Id of persistent TaxAgency 706 | * @param {function} callback - Callback function which is called with any error and the persistent TaxAgency 707 | */ 708 | QuickBooks.prototype.getTaxAgency = function(id, callback) { 709 | module.read(this, 'taxAgency', id, callback) 710 | } 711 | 712 | /** 713 | * Retrieves the TaxCode from QuickBooks 714 | * 715 | * @param {string} Id - The Id of persistent TaxCode 716 | * @param {function} callback - Callback function which is called with any error and the persistent TaxCode 717 | */ 718 | QuickBooks.prototype.getTaxCode = function(id, callback) { 719 | module.read(this, 'taxCode', id, callback) 720 | } 721 | 722 | /** 723 | * Retrieves the TaxRate from QuickBooks 724 | * 725 | * @param {string} Id - The Id of persistent TaxRate 726 | * @param {function} callback - Callback function which is called with any error and the persistent TaxRate 727 | */ 728 | QuickBooks.prototype.getTaxRate = function(id, callback) { 729 | module.read(this, 'taxRate', id, callback) 730 | } 731 | 732 | /** 733 | * Retrieves the Term from QuickBooks 734 | * 735 | * @param {string} Id - The Id of persistent Term 736 | * @param {function} callback - Callback function which is called with any error and the persistent Term 737 | */ 738 | QuickBooks.prototype.getTerm = function(id, callback) { 739 | module.read(this, 'term', id, callback) 740 | } 741 | 742 | /** 743 | * Retrieves the TimeActivity from QuickBooks 744 | * 745 | * @param {string} Id - The Id of persistent TimeActivity 746 | * @param {function} callback - Callback function which is called with any error and the persistent TimeActivity 747 | */ 748 | QuickBooks.prototype.getTimeActivity = function(id, callback) { 749 | module.read(this, 'timeActivity', id, callback) 750 | } 751 | 752 | /** 753 | * Retrieves the Vendor from QuickBooks 754 | * 755 | * @param {string} Id - The Id of persistent Vendor 756 | * @param {function} callback - Callback function which is called with any error and the persistent Vendor 757 | */ 758 | QuickBooks.prototype.getVendor = function(id, callback) { 759 | module.read(this, 'vendor', id, callback) 760 | } 761 | 762 | /** 763 | * Retrieves the VendorCredit from QuickBooks 764 | * 765 | * @param {string} Id - The Id of persistent VendorCredit 766 | * @param {function} callback - Callback function which is called with any error and the persistent VendorCredit 767 | */ 768 | QuickBooks.prototype.getVendorCredit = function(id, callback) { 769 | module.read(this, 'vendorCredit', id, callback) 770 | } 771 | 772 | 773 | 774 | /** 775 | * Updates QuickBooks version of Account 776 | * 777 | * @param {object} account - The persistent Account, including Id and SyncToken fields 778 | * @param {function} callback - Callback function which is called with any error and the persistent Account 779 | */ 780 | QuickBooks.prototype.updateAccount = function(account, callback) { 781 | module.update(this, 'account', account, callback) 782 | } 783 | 784 | /** 785 | * Updates QuickBooks version of Attachable 786 | * 787 | * @param {object} attachable - The persistent Attachable, including Id and SyncToken fields 788 | * @param {function} callback - Callback function which is called with any error and the persistent Attachable 789 | */ 790 | QuickBooks.prototype.updateAttachable = function(attachable, callback) { 791 | module.update(this, 'attachable', attachable, callback) 792 | } 793 | 794 | /** 795 | * Updates QuickBooks version of Bill 796 | * 797 | * @param {object} bill - The persistent Bill, including Id and SyncToken fields 798 | * @param {function} callback - Callback function which is called with any error and the persistent Bill 799 | */ 800 | QuickBooks.prototype.updateBill = function(bill, callback) { 801 | module.update(this, 'bill', bill, callback) 802 | } 803 | 804 | /** 805 | * Updates QuickBooks version of BillPayment 806 | * 807 | * @param {object} billPayment - The persistent BillPayment, including Id and SyncToken fields 808 | * @param {function} callback - Callback function which is called with any error and the persistent BillPayment 809 | */ 810 | QuickBooks.prototype.updateBillPayment = function(billPayment, callback) { 811 | module.update(this, 'billPayment', billPayment, callback) 812 | } 813 | 814 | /** 815 | * Updates QuickBooks version of Class 816 | * 817 | * @param {object} class - The persistent Class, including Id and SyncToken fields 818 | * @param {function} callback - Callback function which is called with any error and the persistent Class 819 | */ 820 | QuickBooks.prototype.updateClass = function(klass, callback) { 821 | module.update(this, 'class', klass, callback) 822 | } 823 | 824 | /** 825 | * Updates QuickBooks version of CompanyInfo 826 | * 827 | * @param {object} companyInfo - The persistent CompanyInfo, including Id and SyncToken fields 828 | * @param {function} callback - Callback function which is called with any error and the persistent CompanyInfo 829 | */ 830 | QuickBooks.prototype.updateCompanyInfo = function(companyInfo, callback) { 831 | module.update(this, 'companyInfo', companyInfo, callback) 832 | } 833 | 834 | /** 835 | * Updates QuickBooks version of CreditMemo 836 | * 837 | * @param {object} creditMemo - The persistent CreditMemo, including Id and SyncToken fields 838 | * @param {function} callback - Callback function which is called with any error and the persistent CreditMemo 839 | */ 840 | QuickBooks.prototype.updateCreditMemo = function(creditMemo, callback) { 841 | module.update(this, 'creditMemo', creditMemo, callback) 842 | } 843 | 844 | /** 845 | * Updates QuickBooks version of Customer 846 | * 847 | * @param {object} customer - The persistent Customer, including Id and SyncToken fields 848 | * @param {function} callback - Callback function which is called with any error and the persistent Customer 849 | */ 850 | QuickBooks.prototype.updateCustomer = function(customer, callback) { 851 | module.update(this, 'customer', customer, callback) 852 | } 853 | 854 | /** 855 | * Updates QuickBooks version of Department 856 | * 857 | * @param {object} department - The persistent Department, including Id and SyncToken fields 858 | * @param {function} callback - Callback function which is called with any error and the persistent Department 859 | */ 860 | QuickBooks.prototype.updateDepartment = function(department, callback) { 861 | module.update(this, 'department', department, callback) 862 | } 863 | 864 | /** 865 | * Updates QuickBooks version of Employee 866 | * 867 | * @param {object} employee - The persistent Employee, including Id and SyncToken fields 868 | * @param {function} callback - Callback function which is called with any error and the persistent Employee 869 | */ 870 | QuickBooks.prototype.updateEmployee = function(employee, callback) { 871 | module.update(this, 'employee', employee, callback) 872 | } 873 | 874 | /** 875 | * Updates QuickBooks version of Estimate 876 | * 877 | * @param {object} estimate - The persistent Estimate, including Id and SyncToken fields 878 | * @param {function} callback - Callback function which is called with any error and the persistent Estimate 879 | */ 880 | QuickBooks.prototype.updateEstimate = function(estimate, callback) { 881 | module.update(this, 'estimate', estimate, callback) 882 | } 883 | 884 | /** 885 | * Updates QuickBooks version of Invoice 886 | * 887 | * @param {object} invoice - The persistent Invoice, including Id and SyncToken fields 888 | * @param {function} callback - Callback function which is called with any error and the persistent Invoice 889 | */ 890 | QuickBooks.prototype.updateInvoice = function(invoice, callback) { 891 | module.update(this, 'invoice', invoice, callback) 892 | } 893 | 894 | /** 895 | * Updates QuickBooks version of Item 896 | * 897 | * @param {object} item - The persistent Item, including Id and SyncToken fields 898 | * @param {function} callback - Callback function which is called with any error and the persistent Item 899 | */ 900 | QuickBooks.prototype.updateItem = function(item, callback) { 901 | module.update(this, 'item', item, callback) 902 | } 903 | 904 | /** 905 | * Updates QuickBooks version of JournalEntry 906 | * 907 | * @param {object} journalEntry - The persistent JournalEntry, including Id and SyncToken fields 908 | * @param {function} callback - Callback function which is called with any error and the persistent JournalEntry 909 | */ 910 | QuickBooks.prototype.updateJournalEntry = function(journalEntry, callback) { 911 | module.update(this, 'journalEntry', journalEntry, callback) 912 | } 913 | 914 | /** 915 | * Updates QuickBooks version of Payment 916 | * 917 | * @param {object} payment - The persistent Payment, including Id and SyncToken fields 918 | * @param {function} callback - Callback function which is called with any error and the persistent Payment 919 | */ 920 | QuickBooks.prototype.updatePayment = function(payment, callback) { 921 | module.update(this, 'payment', payment, callback) 922 | } 923 | 924 | /** 925 | * Updates QuickBooks version of PaymentMethod 926 | * 927 | * @param {object} paymentMethod - The persistent PaymentMethod, including Id and SyncToken fields 928 | * @param {function} callback - Callback function which is called with any error and the persistent PaymentMethod 929 | */ 930 | QuickBooks.prototype.updatePaymentMethod = function(paymentMethod, callback) { 931 | module.update(this, 'paymentMethod', paymentMethod, callback) 932 | } 933 | 934 | /** 935 | * Updates QuickBooks version of Preferences 936 | * 937 | * @param {object} preferences - The persistent Preferences, including Id and SyncToken fields 938 | * @param {function} callback - Callback function which is called with any error and the persistent Preferences 939 | */ 940 | QuickBooks.prototype.updatePreferences = function(preferences, callback) { 941 | module.update(this, 'preferences', preferences, callback) 942 | } 943 | 944 | /** 945 | * Updates QuickBooks version of Purchase 946 | * 947 | * @param {object} purchase - The persistent Purchase, including Id and SyncToken fields 948 | * @param {function} callback - Callback function which is called with any error and the persistent Purchase 949 | */ 950 | QuickBooks.prototype.updatePurchase = function(purchase, callback) { 951 | module.update(this, 'purchase', purchase, callback) 952 | } 953 | 954 | /** 955 | * Updates QuickBooks version of PurchaseOrder 956 | * 957 | * @param {object} purchaseOrder - The persistent PurchaseOrder, including Id and SyncToken fields 958 | * @param {function} callback - Callback function which is called with any error and the persistent PurchaseOrder 959 | */ 960 | QuickBooks.prototype.updatePurchaseOrder = function(purchaseOrder, callback) { 961 | module.update(this, 'purchaseOrder', purchaseOrder, callback) 962 | } 963 | 964 | /** 965 | * Updates QuickBooks version of RefundReceipt 966 | * 967 | * @param {object} refundReceipt - The persistent RefundReceipt, including Id and SyncToken fields 968 | * @param {function} callback - Callback function which is called with any error and the persistent RefundReceipt 969 | */ 970 | QuickBooks.prototype.updateRefundReceipt = function(refundReceipt, callback) { 971 | module.update(this, 'refundReceipt', refundReceipt, callback) 972 | } 973 | 974 | /** 975 | * Updates QuickBooks version of SalesReceipt 976 | * 977 | * @param {object} salesReceipt - The persistent SalesReceipt, including Id and SyncToken fields 978 | * @param {function} callback - Callback function which is called with any error and the persistent SalesReceipt 979 | */ 980 | QuickBooks.prototype.updateSalesReceipt = function(salesReceipt, callback) { 981 | module.update(this, 'salesReceipt', salesReceipt, callback) 982 | } 983 | 984 | /** 985 | * Updates QuickBooks version of TaxAgency 986 | * 987 | * @param {object} taxAgency - The persistent TaxAgency, including Id and SyncToken fields 988 | * @param {function} callback - Callback function which is called with any error and the persistent TaxAgency 989 | */ 990 | QuickBooks.prototype.updateTaxAgency = function(taxAgency, callback) { 991 | module.update(this, 'taxAgency', taxAgency, callback) 992 | } 993 | 994 | /** 995 | * Updates QuickBooks version of TaxCode 996 | * 997 | * @param {object} taxCode - The persistent TaxCode, including Id and SyncToken fields 998 | * @param {function} callback - Callback function which is called with any error and the persistent TaxCode 999 | */ 1000 | QuickBooks.prototype.updateTaxCode = function(taxCode, callback) { 1001 | module.update(this, 'taxCode', taxCode, callback) 1002 | } 1003 | 1004 | /** 1005 | * Updates QuickBooks version of TaxRate 1006 | * 1007 | * @param {object} taxRate - The persistent TaxRate, including Id and SyncToken fields 1008 | * @param {function} callback - Callback function which is called with any error and the persistent TaxRate 1009 | */ 1010 | QuickBooks.prototype.updateTaxRate = function(taxRate, callback) { 1011 | module.update(this, 'taxRate', taxRate, callback) 1012 | } 1013 | 1014 | /** 1015 | * Updates QuickBooks version of TaxService 1016 | * 1017 | * @param {object} taxService - The persistent TaxService, including Id and SyncToken fields 1018 | * @param {function} callback - Callback function which is called with any error and the persistent TaxService 1019 | */ 1020 | QuickBooks.prototype.updateTaxService = function(taxService, callback) { 1021 | module.update(this, 'taxService', taxService, callback) 1022 | } 1023 | 1024 | /** 1025 | * Updates QuickBooks version of Term 1026 | * 1027 | * @param {object} term - The persistent Term, including Id and SyncToken fields 1028 | * @param {function} callback - Callback function which is called with any error and the persistent Term 1029 | */ 1030 | QuickBooks.prototype.updateTerm = function(term, callback) { 1031 | module.update(this, 'term', term, callback) 1032 | } 1033 | 1034 | /** 1035 | * Updates QuickBooks version of TimeActivity 1036 | * 1037 | * @param {object} timeActivity - The persistent TimeActivity, including Id and SyncToken fields 1038 | * @param {function} callback - Callback function which is called with any error and the persistent TimeActivity 1039 | */ 1040 | QuickBooks.prototype.updateTimeActivity = function(timeActivity, callback) { 1041 | module.update(this, 'timeActivity', timeActivity, callback) 1042 | } 1043 | 1044 | /** 1045 | * Updates QuickBooks version of Vendor 1046 | * 1047 | * @param {object} vendor - The persistent Vendor, including Id and SyncToken fields 1048 | * @param {function} callback - Callback function which is called with any error and the persistent Vendor 1049 | */ 1050 | QuickBooks.prototype.updateVendor = function(vendor, callback) { 1051 | module.update(this, 'vendor', vendor, callback) 1052 | } 1053 | 1054 | /** 1055 | * Updates QuickBooks version of VendorCredit 1056 | * 1057 | * @param {object} vendorCredit - The persistent VendorCredit, including Id and SyncToken fields 1058 | * @param {function} callback - Callback function which is called with any error and the persistent VendorCredit 1059 | */ 1060 | QuickBooks.prototype.updateVendorCredit = function(vendorCredit, callback) { 1061 | module.update(this, 'vendorCredit', vendorCredit, callback) 1062 | } 1063 | 1064 | 1065 | 1066 | /** 1067 | * Deletes the Attachable from QuickBooks 1068 | * 1069 | * @param {object} idOrEntity - The persistent Attachable to be deleted, or the Id of the Attachable, in which case an extra GET request will be issued to first retrieve the Attachable 1070 | * @param {function} callback - Callback function which is called with any error and the status of the persistent Attachable 1071 | */ 1072 | QuickBooks.prototype.deleteAttachable = function(idOrEntity, callback) { 1073 | module.delete(this, 'attachable', idOrEntity, callback) 1074 | } 1075 | 1076 | /** 1077 | * Deletes the Bill from QuickBooks 1078 | * 1079 | * @param {object} idOrEntity - The persistent Bill to be deleted, or the Id of the Bill, in which case an extra GET request will be issued to first retrieve the Bill 1080 | * @param {function} callback - Callback function which is called with any error and the status of the persistent Bill 1081 | */ 1082 | QuickBooks.prototype.deleteBill = function(idOrEntity, callback) { 1083 | module.delete(this, 'bill', idOrEntity, callback) 1084 | } 1085 | 1086 | /** 1087 | * Deletes the BillPayment from QuickBooks 1088 | * 1089 | * @param {object} idOrEntity - The persistent BillPayment to be deleted, or the Id of the BillPayment, in which case an extra GET request will be issued to first retrieve the BillPayment 1090 | * @param {function} callback - Callback function which is called with any error and the status of the persistent BillPayment 1091 | */ 1092 | QuickBooks.prototype.deleteBillPayment = function(idOrEntity, callback) { 1093 | module.delete(this, 'billPayment', idOrEntity, callback) 1094 | } 1095 | 1096 | /** 1097 | * Deletes the CreditMemo from QuickBooks 1098 | * 1099 | * @param {object} idOrEntity - The persistent CreditMemo to be deleted, or the Id of the CreditMemo, in which case an extra GET request will be issued to first retrieve the CreditMemo 1100 | * @param {function} callback - Callback function which is called with any error and the status of the persistent CreditMemo 1101 | */ 1102 | QuickBooks.prototype.deleteCreditMemo = function(idOrEntity, callback) { 1103 | module.delete(this, 'creditMemo', idOrEntity, callback) 1104 | } 1105 | 1106 | /** 1107 | * Deletes the Estimate from QuickBooks 1108 | * 1109 | * @param {object} idOrEntity - The persistent Estimate to be deleted, or the Id of the Estimate, in which case an extra GET request will be issued to first retrieve the Estimate 1110 | * @param {function} callback - Callback function which is called with any error and the status of the persistent Estimate 1111 | */ 1112 | QuickBooks.prototype.deleteEstimate = function(idOrEntity, callback) { 1113 | module.delete(this, 'estimate', idOrEntity, callback) 1114 | } 1115 | 1116 | /** 1117 | * Deletes the Invoice from QuickBooks 1118 | * 1119 | * @param {object} idOrEntity - The persistent Invoice to be deleted, or the Id of the Invoice, in which case an extra GET request will be issued to first retrieve the Invoice 1120 | * @param {function} callback - Callback function which is called with any error and the status of the persistent Invoice 1121 | */ 1122 | QuickBooks.prototype.deleteInvoice = function(idOrEntity, callback) { 1123 | module.delete(this, 'invoice', idOrEntity, callback) 1124 | } 1125 | 1126 | /** 1127 | * Deletes the JournalEntry from QuickBooks 1128 | * 1129 | * @param {object} idOrEntity - The persistent JournalEntry to be deleted, or the Id of the JournalEntry, in which case an extra GET request will be issued to first retrieve the JournalEntry 1130 | * @param {function} callback - Callback function which is called with any error and the status of the persistent JournalEntry 1131 | */ 1132 | QuickBooks.prototype.deleteJournalEntry = function(idOrEntity, callback) { 1133 | module.delete(this, 'journalEntry', idOrEntity, callback) 1134 | } 1135 | 1136 | /** 1137 | * Deletes the Payment from QuickBooks 1138 | * 1139 | * @param {object} idOrEntity - The persistent Payment to be deleted, or the Id of the Payment, in which case an extra GET request will be issued to first retrieve the Payment 1140 | * @param {function} callback - Callback function which is called with any error and the status of the persistent Payment 1141 | */ 1142 | QuickBooks.prototype.deletePayment = function(idOrEntity, callback) { 1143 | module.delete(this, 'payment', idOrEntity, callback) 1144 | } 1145 | 1146 | /** 1147 | * Deletes the Purchase from QuickBooks 1148 | * 1149 | * @param {object} idOrEntity - The persistent Purchase to be deleted, or the Id of the Purchase, in which case an extra GET request will be issued to first retrieve the Purchase 1150 | * @param {function} callback - Callback function which is called with any error and the status of the persistent Purchase 1151 | */ 1152 | QuickBooks.prototype.deletePurchase = function(idOrEntity, callback) { 1153 | module.delete(this, 'purchase', idOrEntity, callback) 1154 | } 1155 | 1156 | /** 1157 | * Deletes the PurchaseOrder from QuickBooks 1158 | * 1159 | * @param {object} idOrEntity - The persistent PurchaseOrder to be deleted, or the Id of the PurchaseOrder, in which case an extra GET request will be issued to first retrieve the PurchaseOrder 1160 | * @param {function} callback - Callback function which is called with any error and the status of the persistent PurchaseOrder 1161 | */ 1162 | QuickBooks.prototype.deletePurchaseOrder = function(idOrEntity, callback) { 1163 | module.delete(this, 'purchaseOrder', idOrEntity, callback) 1164 | } 1165 | 1166 | /** 1167 | * Deletes the RefundReceipt from QuickBooks 1168 | * 1169 | * @param {object} idOrEntity - The persistent RefundReceipt to be deleted, or the Id of the RefundReceipt, in which case an extra GET request will be issued to first retrieve the RefundReceipt 1170 | * @param {function} callback - Callback function which is called with any error and the status of the persistent RefundReceipt 1171 | */ 1172 | QuickBooks.prototype.deleteRefundReceipt = function(idOrEntity, callback) { 1173 | module.delete(this, 'refundReceipt', idOrEntity, callback) 1174 | } 1175 | 1176 | /** 1177 | * Deletes the SalesReceipt from QuickBooks 1178 | * 1179 | * @param {object} idOrEntity - The persistent SalesReceipt to be deleted, or the Id of the SalesReceipt, in which case an extra GET request will be issued to first retrieve the SalesReceipt 1180 | * @param {function} callback - Callback function which is called with any error and the status of the persistent SalesReceipt 1181 | */ 1182 | QuickBooks.prototype.deleteSalesReceipt = function(idOrEntity, callback) { 1183 | module.delete(this, 'salesReceipt', idOrEntity, callback) 1184 | } 1185 | 1186 | /** 1187 | * Deletes the TimeActivity from QuickBooks 1188 | * 1189 | * @param {object} idOrEntity - The persistent TimeActivity to be deleted, or the Id of the TimeActivity, in which case an extra GET request will be issued to first retrieve the TimeActivity 1190 | * @param {function} callback - Callback function which is called with any error and the status of the persistent TimeActivity 1191 | */ 1192 | QuickBooks.prototype.deleteTimeActivity = function(idOrEntity, callback) { 1193 | module.delete(this, 'timeActivity', idOrEntity, callback) 1194 | } 1195 | 1196 | /** 1197 | * Deletes the VendorCredit from QuickBooks 1198 | * 1199 | * @param {object} idOrEntity - The persistent VendorCredit to be deleted, or the Id of the VendorCredit, in which case an extra GET request will be issued to first retrieve the VendorCredit 1200 | * @param {function} callback - Callback function which is called with any error and the status of the persistent VendorCredit 1201 | */ 1202 | QuickBooks.prototype.deleteVendorCredit = function(idOrEntity, callback) { 1203 | module.delete(this, 'vendorCredit', idOrEntity, callback) 1204 | } 1205 | 1206 | 1207 | 1208 | /** 1209 | * Finds all Accounts in QuickBooks, optionally matching the specified criteria 1210 | * 1211 | * @param {object} criteria - (Optional) String or single-valued map converted to a where clause of the form "where key = 'value'" 1212 | * @param {function} callback - Callback function which is called with any error and the list of Account 1213 | */ 1214 | QuickBooks.prototype.findAccounts = function (criteria,callback) { 1215 | module.query(this, 'account', criteria, callback) 1216 | } 1217 | 1218 | /** 1219 | * Finds all Attachables in QuickBooks, optionally matching the specified criteria 1220 | * 1221 | * @param {object} criteria - (Optional) String or single-valued map converted to a where clause of the form "where key = 'value'" 1222 | * @param {function} callback - Callback function which is called with any error and the list of Attachable 1223 | */ 1224 | QuickBooks.prototype.findAttachables = function(criteria, callback) { 1225 | module.query(this, 'attachable', criteria, callback) 1226 | } 1227 | 1228 | /** 1229 | * Finds all Bills in QuickBooks, optionally matching the specified criteria 1230 | * 1231 | * @param {object} criteria - (Optional) String or single-valued map converted to a where clause of the form "where key = 'value'" 1232 | * @param {function} callback - Callback function which is called with any error and the list of Bill 1233 | */ 1234 | QuickBooks.prototype.findBills = function(criteria, callback) { 1235 | module.query(this, 'bill', criteria, callback) 1236 | } 1237 | 1238 | /** 1239 | * Finds all BillPayments in QuickBooks, optionally matching the specified criteria 1240 | * 1241 | * @param {object} criteria - (Optional) String or single-valued map converted to a where clause of the form "where key = 'value'" 1242 | * @param {function} callback - Callback function which is called with any error and the list of BillPayment 1243 | */ 1244 | QuickBooks.prototype.findBillPayments = function(criteria, callback) { 1245 | module.query(this, 'billPayment', criteria, callback) 1246 | } 1247 | 1248 | /** 1249 | * Finds all Budgets in QuickBooks, optionally matching the specified criteria 1250 | * 1251 | * @param {object} criteria - (Optional) String or single-valued map converted to a where clause of the form "where key = 'value'" 1252 | * @param {function} callback - Callback function which is called with any error and the list of Budget 1253 | */ 1254 | QuickBooks.prototype.findBudgets = function(criteria, callback) { 1255 | module.query(this, 'budget', criteria, callback) 1256 | } 1257 | 1258 | /** 1259 | * Finds all Classs in QuickBooks, optionally matching the specified criteria 1260 | * 1261 | * @param {object} criteria - (Optional) String or single-valued map converted to a where clause of the form "where key = 'value'" 1262 | * @param {function} callback - Callback function which is called with any error and the list of Class 1263 | */ 1264 | QuickBooks.prototype.findClasses = function(criteria, callback) { 1265 | module.query(this, 'class', criteria, callback) 1266 | } 1267 | 1268 | /** 1269 | * Finds all CompanyInfos in QuickBooks, optionally matching the specified criteria 1270 | * 1271 | * @param {object} criteria - (Optional) String or single-valued map converted to a where clause of the form "where key = 'value'" 1272 | * @param {function} callback - Callback function which is called with any error and the list of CompanyInfo 1273 | */ 1274 | QuickBooks.prototype.findCompanyInfos = function(criteria, callback) { 1275 | module.query(this, 'companyInfo', criteria, callback) 1276 | } 1277 | 1278 | /** 1279 | * Finds all CreditMemos in QuickBooks, optionally matching the specified criteria 1280 | * 1281 | * @param {object} criteria - (Optional) String or single-valued map converted to a where clause of the form "where key = 'value'" 1282 | * @param {function} callback - Callback function which is called with any error and the list of CreditMemo 1283 | */ 1284 | QuickBooks.prototype.findCreditMemos = function(criteria, callback) { 1285 | module.query(this, 'creditMemo', criteria, callback) 1286 | } 1287 | 1288 | /** 1289 | * Finds all Customers in QuickBooks, optionally matching the specified criteria 1290 | * 1291 | * @param {object} criteria - (Optional) String or single-valued map converted to a where clause of the form "where key = 'value'" 1292 | * @param {function} callback - Callback function which is called with any error and the list of Customer 1293 | */ 1294 | QuickBooks.prototype.findCustomers = function(criteria, callback) { 1295 | module.query(this, 'customer', criteria, callback) 1296 | } 1297 | 1298 | /** 1299 | * Finds all Departments in QuickBooks, optionally matching the specified criteria 1300 | * 1301 | * @param {object} criteria - (Optional) String or single-valued map converted to a where clause of the form "where key = 'value'" 1302 | * @param {function} callback - Callback function which is called with any error and the list of Department 1303 | */ 1304 | QuickBooks.prototype.findDepartments = function(criteria, callback) { 1305 | module.query(this, 'department', criteria, callback) 1306 | } 1307 | 1308 | /** 1309 | * Finds all Employees in QuickBooks, optionally matching the specified criteria 1310 | * 1311 | * @param {object} criteria - (Optional) String or single-valued map converted to a where clause of the form "where key = 'value'" 1312 | * @param {function} callback - Callback function which is called with any error and the list of Employee 1313 | */ 1314 | QuickBooks.prototype.findEmployees = function(criteria, callback) { 1315 | module.query(this, 'employee', criteria, callback) 1316 | } 1317 | 1318 | /** 1319 | * Finds all Estimates in QuickBooks, optionally matching the specified criteria 1320 | * 1321 | * @param {object} criteria - (Optional) String or single-valued map converted to a where clause of the form "where key = 'value'" 1322 | * @param {function} callback - Callback function which is called with any error and the list of Estimate 1323 | */ 1324 | QuickBooks.prototype.findEstimates = function(criteria, callback) { 1325 | module.query(this, 'estimate', criteria, callback) 1326 | } 1327 | 1328 | /** 1329 | * Finds all Invoices in QuickBooks, optionally matching the specified criteria 1330 | * 1331 | * @param {object} criteria - (Optional) String or single-valued map converted to a where clause of the form "where key = 'value'" 1332 | * @param {function} callback - Callback function which is called with any error and the list of Invoice 1333 | */ 1334 | QuickBooks.prototype.findInvoices = function(criteria, callback) { 1335 | module.query(this, 'invoice', criteria, callback) 1336 | } 1337 | 1338 | /** 1339 | * Finds all Items in QuickBooks, optionally matching the specified criteria 1340 | * 1341 | * @param {object} criteria - (Optional) String or single-valued map converted to a where clause of the form "where key = 'value'" 1342 | * @param {function} callback - Callback function which is called with any error and the list of Item 1343 | */ 1344 | QuickBooks.prototype.findItems = function(criteria, callback) { 1345 | module.query(this, 'item', criteria, callback) 1346 | } 1347 | 1348 | /** 1349 | * Finds all JournalEntrys in QuickBooks, optionally matching the specified criteria 1350 | * 1351 | * @param {object} criteria - (Optional) String or single-valued map converted to a where clause of the form "where key = 'value'" 1352 | * @param {function} callback - Callback function which is called with any error and the list of JournalEntry 1353 | */ 1354 | QuickBooks.prototype.findJournalEntries = function(criteria, callback) { 1355 | module.query(this, 'journalEntry', criteria, callback) 1356 | } 1357 | 1358 | /** 1359 | * Finds all Payments in QuickBooks, optionally matching the specified criteria 1360 | * 1361 | * @param {object} criteria - (Optional) String or single-valued map converted to a where clause of the form "where key = 'value'" 1362 | * @param {function} callback - Callback function which is called with any error and the list of Payment 1363 | */ 1364 | QuickBooks.prototype.findPayments = function(criteria, callback) { 1365 | module.query(this, 'payment', criteria, callback) 1366 | } 1367 | 1368 | /** 1369 | * Finds all PaymentMethods in QuickBooks, optionally matching the specified criteria 1370 | * 1371 | * @param {object} criteria - (Optional) String or single-valued map converted to a where clause of the form "where key = 'value'" 1372 | * @param {function} callback - Callback function which is called with any error and the list of PaymentMethod 1373 | */ 1374 | QuickBooks.prototype.findPaymentMethods = function(criteria, callback) { 1375 | module.query(this, 'paymentMethod', criteria, callback) 1376 | } 1377 | 1378 | /** 1379 | * Finds all Preferencess in QuickBooks, optionally matching the specified criteria 1380 | * 1381 | * @param {object} criteria - (Optional) String or single-valued map converted to a where clause of the form "where key = 'value'" 1382 | * @param {function} callback - Callback function which is called with any error and the list of Preferences 1383 | */ 1384 | QuickBooks.prototype.findPreferenceses = function(criteria, callback) { 1385 | module.query(this, 'preferences', criteria, callback) 1386 | } 1387 | 1388 | /** 1389 | * Finds all Purchases in QuickBooks, optionally matching the specified criteria 1390 | * 1391 | * @param {object} criteria - (Optional) String or single-valued map converted to a where clause of the form "where key = 'value'" 1392 | * @param {function} callback - Callback function which is called with any error and the list of Purchase 1393 | */ 1394 | QuickBooks.prototype.findPurchases = function(criteria, callback) { 1395 | module.query(this, 'purchase', criteria, callback) 1396 | } 1397 | 1398 | /** 1399 | * Finds all PurchaseOrders in QuickBooks, optionally matching the specified criteria 1400 | * 1401 | * @param {object} criteria - (Optional) String or single-valued map converted to a where clause of the form "where key = 'value'" 1402 | * @param {function} callback - Callback function which is called with any error and the list of PurchaseOrder 1403 | */ 1404 | QuickBooks.prototype.findPurchaseOrders = function(criteria, callback) { 1405 | module.query(this, 'purchaseOrder', criteria, callback) 1406 | } 1407 | 1408 | /** 1409 | * Finds all RefundReceipts in QuickBooks, optionally matching the specified criteria 1410 | * 1411 | * @param {object} criteria - (Optional) String or single-valued map converted to a where clause of the form "where key = 'value'" 1412 | * @param {function} callback - Callback function which is called with any error and the list of RefundReceipt 1413 | */ 1414 | QuickBooks.prototype.findRefundReceipts = function(criteria, callback) { 1415 | module.query(this, 'refundReceipt', criteria, callback) 1416 | } 1417 | 1418 | /** 1419 | * Finds all SalesReceipts in QuickBooks, optionally matching the specified criteria 1420 | * 1421 | * @param {object} criteria - (Optional) String or single-valued map converted to a where clause of the form "where key = 'value'" 1422 | * @param {function} callback - Callback function which is called with any error and the list of SalesReceipt 1423 | */ 1424 | QuickBooks.prototype.findSalesReceipts = function(criteria, callback) { 1425 | module.query(this, 'salesReceipt', criteria, callback) 1426 | } 1427 | 1428 | /** 1429 | * Finds all TaxAgencys in QuickBooks, optionally matching the specified criteria 1430 | * 1431 | * @param {object} criteria - (Optional) String or single-valued map converted to a where clause of the form "where key = 'value'" 1432 | * @param {function} callback - Callback function which is called with any error and the list of TaxAgency 1433 | */ 1434 | QuickBooks.prototype.findTaxAgencies = function(criteria, callback) { 1435 | module.query(this, 'taxAgency', criteria, callback) 1436 | } 1437 | 1438 | /** 1439 | * Finds all TaxCodes in QuickBooks, optionally matching the specified criteria 1440 | * 1441 | * @param {object} criteria - (Optional) String or single-valued map converted to a where clause of the form "where key = 'value'" 1442 | * @param {function} callback - Callback function which is called with any error and the list of TaxCode 1443 | */ 1444 | QuickBooks.prototype.findTaxCodes = function(criteria, callback) { 1445 | module.query(this, 'taxCode', criteria, callback) 1446 | } 1447 | 1448 | /** 1449 | * Finds all TaxRates in QuickBooks, optionally matching the specified criteria 1450 | * 1451 | * @param {object} criteria - (Optional) String or single-valued map converted to a where clause of the form "where key = 'value'" 1452 | * @param {function} callback - Callback function which is called with any error and the list of TaxRate 1453 | */ 1454 | QuickBooks.prototype.findTaxRates = function(criteria, callback) { 1455 | module.query(this, 'taxRate', criteria, callback) 1456 | } 1457 | 1458 | /** 1459 | * Finds all Terms in QuickBooks, optionally matching the specified criteria 1460 | * 1461 | * @param {object} criteria - (Optional) String or single-valued map converted to a where clause of the form "where key = 'value'" 1462 | * @param {function} callback - Callback function which is called with any error and the list of Term 1463 | */ 1464 | QuickBooks.prototype.findTerms = function(criteria, callback) { 1465 | module.query(this, 'term', criteria, callback) 1466 | } 1467 | 1468 | /** 1469 | * Finds all TimeActivitys in QuickBooks, optionally matching the specified criteria 1470 | * 1471 | * @param {object} criteria - (Optional) String or single-valued map converted to a where clause of the form "where key = 'value'" 1472 | * @param {function} callback - Callback function which is called with any error and the list of TimeActivity 1473 | */ 1474 | QuickBooks.prototype.findTimeActivities = function(criteria, callback) { 1475 | module.query(this, 'timeActivity', criteria, callback) 1476 | } 1477 | 1478 | /** 1479 | * Finds all Vendors in QuickBooks, optionally matching the specified criteria 1480 | * 1481 | * @param {object} criteria - (Optional) String or single-valued map converted to a where clause of the form "where key = 'value'" 1482 | * @param {function} callback - Callback function which is called with any error and the list of Vendor 1483 | */ 1484 | QuickBooks.prototype.findVendors = function(criteria, callback) { 1485 | module.query(this, 'vendor', criteria, callback) 1486 | } 1487 | 1488 | /** 1489 | * Finds all VendorCredits in QuickBooks, optionally matching the specified criteria 1490 | * 1491 | * @param {object} criteria - (Optional) String or single-valued map converted to a where clause of the form "where key = 'value'" 1492 | * @param {function} callback - Callback function which is called with any error and the list of VendorCredit 1493 | */ 1494 | QuickBooks.prototype.findVendorCredits = function(criteria, callback) { 1495 | module.query(this, 'vendorCredit', criteria, callback) 1496 | } 1497 | 1498 | 1499 | 1500 | /** 1501 | * Retrieves the BalanceSheet Report from QuickBooks 1502 | * 1503 | * @param {object} options - (Optional) Map of key-value pairs passed as options to the Report 1504 | * @param {function} callback - Callback function which is called with any error and the BalanceSheet Report 1505 | */ 1506 | QuickBooks.prototype.reportBalanceSheet = function(options, callback) { 1507 | module.report(this, 'BalanceSheet', options, callback) 1508 | } 1509 | 1510 | /** 1511 | * Retrieves the ProfitAndLoss Report from QuickBooks 1512 | * 1513 | * @param {object} options - (Optional) Map of key-value pairs passed as options to the Report 1514 | * @param {function} callback - Callback function which is called with any error and the ProfitAndLoss Report 1515 | */ 1516 | QuickBooks.prototype.reportProfitAndLoss = function(options, callback) { 1517 | module.report(this, 'ProfitAndLoss', options, callback) 1518 | } 1519 | 1520 | /** 1521 | * Retrieves the ProfitAndLossDetail Report from QuickBooks 1522 | * 1523 | * @param {object} options - (Optional) Map of key-value pairs passed as options to the Report 1524 | * @param {function} callback - Callback function which is called with any error and the ProfitAndLossDetail Report 1525 | */ 1526 | QuickBooks.prototype.reportProfitAndLossDetail = function(options, callback) { 1527 | module.report(this, 'ProfitAndLossDetail', options, callback) 1528 | } 1529 | 1530 | /** 1531 | * Retrieves the TrialBalance Report from QuickBooks 1532 | * 1533 | * @param {object} options - (Optional) Map of key-value pairs passed as options to the Report 1534 | * @param {function} callback - Callback function which is called with any error and the TrialBalance Report 1535 | */ 1536 | QuickBooks.prototype.reportTrialBalance = function(options, callback) { 1537 | module.report(this, 'TrialBalance', options, callback) 1538 | } 1539 | 1540 | /** 1541 | * Retrieves the CashFlow Report from QuickBooks 1542 | * 1543 | * @param {object} options - (Optional) Map of key-value pairs passed as options to the Report 1544 | * @param {function} callback - Callback function which is called with any error and the CashFlow Report 1545 | */ 1546 | QuickBooks.prototype.reportCashFlow = function(options, callback) { 1547 | module.report(this, 'CashFlow', options, callback) 1548 | } 1549 | 1550 | /** 1551 | * Retrieves the InventoryValuationSummary Report from QuickBooks 1552 | * 1553 | * @param {object} options - (Optional) Map of key-value pairs passed as options to the Report 1554 | * @param {function} callback - Callback function which is called with any error and the InventoryValuationSummary Report 1555 | */ 1556 | QuickBooks.prototype.reportInventoryValuationSummary = function(options, callback) { 1557 | module.report(this, 'InventoryValuationSummary', options, callback) 1558 | } 1559 | 1560 | /** 1561 | * Retrieves the CustomerSales Report from QuickBooks 1562 | * 1563 | * @param {object} options - (Optional) Map of key-value pairs passed as options to the Report 1564 | * @param {function} callback - Callback function which is called with any error and the CustomerSales Report 1565 | */ 1566 | QuickBooks.prototype.reportCustomerSales = function(options, callback) { 1567 | module.report(this, 'CustomerSales', options, callback) 1568 | } 1569 | 1570 | /** 1571 | * Retrieves the ItemSales Report from QuickBooks 1572 | * 1573 | * @param {object} options - (Optional) Map of key-value pairs passed as options to the Report 1574 | * @param {function} callback - Callback function which is called with any error and the ItemSales Report 1575 | */ 1576 | QuickBooks.prototype.reportItemSales = function(options, callback) { 1577 | module.report(this, 'ItemSales', options, callback) 1578 | } 1579 | 1580 | /** 1581 | * Retrieves the CustomerIncome Report from QuickBooks 1582 | * 1583 | * @param {object} options - (Optional) Map of key-value pairs passed as options to the Report 1584 | * @param {function} callback - Callback function which is called with any error and the CustomerIncome Report 1585 | */ 1586 | QuickBooks.prototype.reportCustomerIncome = function(options, callback) { 1587 | module.report(this, 'CustomerIncome', options, callback) 1588 | } 1589 | 1590 | /** 1591 | * Retrieves the CustomerBalance Report from QuickBooks 1592 | * 1593 | * @param {object} options - (Optional) Map of key-value pairs passed as options to the Report 1594 | * @param {function} callback - Callback function which is called with any error and the CustomerBalance Report 1595 | */ 1596 | QuickBooks.prototype.reportCustomerBalance = function(options, callback) { 1597 | module.report(this, 'CustomerBalance', options, callback) 1598 | } 1599 | 1600 | /** 1601 | * Retrieves the CustomerBalanceDetail Report from QuickBooks 1602 | * 1603 | * @param {object} options - (Optional) Map of key-value pairs passed as options to the Report 1604 | * @param {function} callback - Callback function which is called with any error and the CustomerBalanceDetail Report 1605 | */ 1606 | QuickBooks.prototype.reportCustomerBalanceDetail = function(options, callback) { 1607 | module.report(this, 'CustomerBalanceDetail', options, callback) 1608 | } 1609 | 1610 | /** 1611 | * Retrieves the AgedReceivables Report from QuickBooks 1612 | * 1613 | * @param {object} options - (Optional) Map of key-value pairs passed as options to the Report 1614 | * @param {function} callback - Callback function which is called with any error and the AgedReceivables Report 1615 | */ 1616 | QuickBooks.prototype.reportAgedReceivables = function(options, callback) { 1617 | module.report(this, 'AgedReceivables', options, callback) 1618 | } 1619 | 1620 | /** 1621 | * Retrieves the AgedReceivableDetail Report from QuickBooks 1622 | * 1623 | * @param {object} options - (Optional) Map of key-value pairs passed as options to the Report 1624 | * @param {function} callback - Callback function which is called with any error and the AgedReceivableDetail Report 1625 | */ 1626 | QuickBooks.prototype.reportAgedReceivableDetail = function(options, callback) { 1627 | module.report(this, 'AgedReceivableDetail', options, callback) 1628 | } 1629 | 1630 | /** 1631 | * Retrieves the VendorBalance Report from QuickBooks 1632 | * 1633 | * @param {object} options - (Optional) Map of key-value pairs passed as options to the Report 1634 | * @param {function} callback - Callback function which is called with any error and the VendorBalance Report 1635 | */ 1636 | QuickBooks.prototype.reportVendorBalance = function(options, callback) { 1637 | module.report(this, 'VendorBalance', options, callback) 1638 | } 1639 | 1640 | /** 1641 | * Retrieves the VendorBalanceDetail Report from QuickBooks 1642 | * 1643 | * @param {object} options - (Optional) Map of key-value pairs passed as options to the Report 1644 | * @param {function} callback - Callback function which is called with any error and the VendorBalanceDetail Report 1645 | */ 1646 | QuickBooks.prototype.reportVendorBalanceDetail = function(options, callback) { 1647 | module.report(this, 'VendorBalanceDetail', options, callback) 1648 | } 1649 | 1650 | /** 1651 | * Retrieves the AgedPayables Report from QuickBooks 1652 | * 1653 | * @param {object} options - (Optional) Map of key-value pairs passed as options to the Report 1654 | * @param {function} callback - Callback function which is called with any error and the AgedPayables Report 1655 | */ 1656 | QuickBooks.prototype.reportAgedPayables = function(options, callback) { 1657 | module.report(this, 'AgedPayables', options, callback) 1658 | } 1659 | 1660 | /** 1661 | * Retrieves the AgedPayableDetail Report from QuickBooks 1662 | * 1663 | * @param {object} options - (Optional) Map of key-value pairs passed as options to the Report 1664 | * @param {function} callback - Callback function which is called with any error and the AgedPayableDetail Report 1665 | */ 1666 | QuickBooks.prototype.reportAgedPayableDetail = function(options, callback) { 1667 | module.report(this, 'AgedPayableDetail', options, callback) 1668 | } 1669 | 1670 | /** 1671 | * Retrieves the VendorExpenses Report from QuickBooks 1672 | * 1673 | * @param {object} options - (Optional) Map of key-value pairs passed as options to the Report 1674 | * @param {function} callback - Callback function which is called with any error and the VendorExpenses Report 1675 | */ 1676 | QuickBooks.prototype.reportVendorExpenses = function(options, callback) { 1677 | module.report(this, 'VendorExpenses', options, callback) 1678 | } 1679 | 1680 | /** 1681 | * Retrieves the GeneralLedgerDetail Report from QuickBooks 1682 | * 1683 | * @param {object} options - (Optional) Map of key-value pairs passed as options to the Report 1684 | * @param {function} callback - Callback function which is called with any error and the GeneralLedgerDetail Report 1685 | */ 1686 | QuickBooks.prototype.reportGeneralLedgerDetail = function(options, callback) { 1687 | module.report(this, 'GeneralLedger', options, callback) 1688 | } 1689 | 1690 | /** 1691 | * Retrieves the DepartmentSales Report from QuickBooks 1692 | * 1693 | * @param {object} options - (Optional) Map of key-value pairs passed as options to the Report 1694 | * @param {function} callback - Callback function which is called with any error and the DepartmentSales Report 1695 | */ 1696 | QuickBooks.prototype.reportDepartmentSales = function(options, callback) { 1697 | module.report(this, 'DepartmentSales', options, callback) 1698 | } 1699 | 1700 | /** 1701 | * Retrieves the ClassSales Report from QuickBooks 1702 | * 1703 | * @param {object} options - (Optional) Map of key-value pairs passed as options to the Report 1704 | * @param {function} callback - Callback function which is called with any error and the ClassSales Report 1705 | */ 1706 | QuickBooks.prototype.reportClassSales = function(options, callback) { 1707 | module.report(this, 'ClassSales', options, callback) 1708 | } 1709 | 1710 | /** 1711 | * Retrieves the AccountListDetail Report from QuickBooks 1712 | * 1713 | * @param {object} options - (Optional) Map of key-value pairs passed as options to the Report 1714 | * @param {function} callback - Callback function which is called with any error and the AccountListDetail Report 1715 | */ 1716 | QuickBooks.prototype.reportAccountListDetail = function(options, callback) { 1717 | module.report(this, 'AccountList', options, callback) 1718 | } 1719 | 1720 | module.request = function(context, verb, options, entity, callback) { 1721 | var isPayment = options.url.match(/^\/(charge|tokens)/), 1722 | url = isPayment ? context.paymentEndpoint + options.url : 1723 | context.endpoint + context.realmId + options.url, 1724 | opts = { 1725 | url: url, 1726 | qs: options.qs || {}, 1727 | headers: options.headers || {}, 1728 | oauth: module.oauth(context), 1729 | json: true 1730 | } 1731 | opts.headers['User-Agent'] = 'node-quickbooks: version ' + version 1732 | if (isPayment) { 1733 | opts.headers['Request-Id'] = uuid.v1() 1734 | } 1735 | if (options.url.match(/pdf$/)) { 1736 | opts.headers['accept'] = 'application/pdf' 1737 | } 1738 | if (entity !== null) { 1739 | opts.body = entity 1740 | } 1741 | if ('production' !== process.env.NODE_ENV && context.debug) { 1742 | debug(request) 1743 | } 1744 | request[verb].call(context, opts, function (err, res, body) { 1745 | if ('production' !== process.env.NODE_ENV && context.debug) { 1746 | console.log('invoking endpoint: ' + url) 1747 | console.log(entity || '') 1748 | console.log(util.inspect(body, {showHidden: false, depth: null})); 1749 | } 1750 | if (callback) { 1751 | callback(err, body) 1752 | } else { 1753 | return 1754 | } 1755 | }) 1756 | } 1757 | 1758 | // ********************** CRUD Api ********************** 1759 | module.create = function(context, entityName, entity, callback) { 1760 | var url = '/' + entityName.toLowerCase() 1761 | module.request(context, 'post', {url: url}, entity, module.unwrap(callback, entityName)) 1762 | } 1763 | 1764 | module.read = function(context, entityName, id, callback) { 1765 | var url = '/' + entityName.toLowerCase() + '/' + id 1766 | module.request(context, 'get', {url: url}, null, module.unwrap(callback, entityName)) 1767 | } 1768 | 1769 | module.update = function(context, entityName, entity, callback) { 1770 | if (! entity.Id || ! entity.SyncToken) { 1771 | throw new Error(entityName + ' must contain Id and SyncToken fields: ' + 1772 | util.inspect(entity, {showHidden: false, depth: null})) 1773 | } 1774 | var url = '/' + entityName.toLowerCase() + '?operation=update' 1775 | module.request(context, 'post', {url: url}, entity, module.unwrap(callback, entityName)) 1776 | } 1777 | 1778 | module.delete = function(context, entityName, idOrEntity, callback) { 1779 | var url = '/' + entityName.toLowerCase() + '?operation=delete' 1780 | callback = callback || function(e, r) {} 1781 | if (_.isObject(idOrEntity)) { 1782 | module.request(context, 'post', {url: url}, idOrEntity, callback) 1783 | } else { 1784 | module.read(context, entityName, idOrEntity, function(err, entity) { 1785 | if (err) { 1786 | callback(err) 1787 | } else { 1788 | module.request(context, 'post', {url: url}, entity, callback) 1789 | } 1790 | }) 1791 | } 1792 | } 1793 | 1794 | // ********************** Query Api ********************** 1795 | module.query = function(context, entity, criteria, callback) { 1796 | var url = '/query?query@@select * from ' + entity 1797 | for (var p in criteria) { 1798 | if (p.toLowerCase() === 'count' && criteria[p]) { 1799 | url = url.replace('select \* from', 'select count(*) from') 1800 | delete criteria[p] 1801 | continue 1802 | } 1803 | } 1804 | if (criteria && typeof criteria !== 'function') { 1805 | url += module.criteriaToString(criteria) || '' 1806 | url = url.replace(/%/, '%25') 1807 | .replace(/'/g, '%27') 1808 | .replace(/=/, '%3D') 1809 | .replace(//, '%3E') 1811 | .replace(/\&/g, '%26') 1812 | .replace(/\#/g, '%23'); 1813 | } 1814 | url = url.replace('@@', '=') 1815 | module.request(context, 'get', {url: url}, null, typeof criteria === 'function' ? criteria : callback) 1816 | } 1817 | 1818 | 1819 | // ********************** Report Api ********************** 1820 | module.report = function(context, reportType, criteria, callback) { 1821 | var url = '/reports/' + reportType 1822 | if (criteria && typeof criteria !== 'function') { 1823 | url += module.reportCriteria(criteria) || '' 1824 | } 1825 | module.request(context, 'get', {url: url}, null, typeof criteria === 'function' ? criteria : callback) 1826 | } 1827 | 1828 | 1829 | module.oauth = function(context) { 1830 | return { 1831 | consumer_key: context.consumerKey, 1832 | consumer_secret: context.consumerSecret, 1833 | token: context.token, 1834 | token_secret: context.tokenSecret 1835 | } 1836 | } 1837 | 1838 | module.isNumeric = function(n) { 1839 | return ! isNaN(parseFloat(n)) && isFinite(n); 1840 | } 1841 | 1842 | module.checkProperty = function(field, name) { 1843 | return (field.toLowerCase() === name) 1844 | } 1845 | 1846 | module.criteriaToString = function(criteria) { 1847 | if (_.isString(criteria)) return criteria 1848 | var flattened = []; 1849 | if (_.isArray(criteria)) { 1850 | if (criteria.length === 0) return '' 1851 | for (var i=0, l=criteria.length; i') 127 | 128 | }); 129 | 130 | 131 | module.exports = router; 132 | -------------------------------------------------------------------------------- /test/test.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by sram on 7/15/15. 3 | */ 4 | 5 | var assert = require('assert'); 6 | var request = require('superagent'); 7 | var console = require ('console'); 8 | var qbosetup = require ('../helpers/qbo_setup'); 9 | //var qboauth; 10 | 11 | 12 | describe('Array', function() { 13 | describe('#indexOf()', function () { 14 | it('should return -1 when the value is not present', function () { 15 | assert.equal(-1, [1,2,3].indexOf(5)); 16 | assert.equal(-1, [1,2,3].indexOf(0)); 17 | }); 18 | }); 19 | }); 20 | 21 | var baseURL = "http://localhost:3000/"; 22 | var user1 = request.agent(); 23 | 24 | 25 | describe ('QuickBooks Setup', function() { 26 | it('should have the qboauth object available after login ', function (done) { 27 | user1 28 | .get(baseURL + "importdata/qboauth") 29 | //.send({email: "", password: ""}) 30 | //.get("http://localhost:3000/quickbooks/start") 31 | // .send({ name: 'Manny', species: 'cat' }) 32 | // .set('X-API-Key', 'foobar') 33 | // .set('Accept', 'application/json') 34 | .end(function (err, res) { 35 | if (res.ok) { 36 | console.log('yay got ' + JSON.stringify(res.text)); 37 | //qboauth = new JSONObject(res.text); 38 | done(); 39 | } else { 40 | console.log('Oh no! error ' + res.text); 41 | } 42 | 43 | }); 44 | }); 45 | 46 | 47 | describe('Get Accounts', function () { 48 | it('should get a list of QUickBooks Accounts', function (done) { 49 | this.timeout(10000); 50 | user1 51 | .get(baseURL + 'importdata/accounts') 52 | .end(function (err, res) { 53 | if (res.ok) { 54 | console.log('yay got' + JSON.stringify(res.text)); 55 | done(); 56 | } else { 57 | console.log('got an error' + res.text); 58 | } 59 | }); 60 | }); 61 | }); 62 | }); 63 | 64 | -------------------------------------------------------------------------------- /views/error.jade: -------------------------------------------------------------------------------- 1 | extends layout 2 | 3 | block content 4 | h1= message 5 | h2= error.status 6 | pre #{error.stack} 7 | -------------------------------------------------------------------------------- /views/failedlogin.jade: -------------------------------------------------------------------------------- 1 | //Created by sram on 7/15/15. 2 | 3 | 4 | 5 | extends layout 6 | 7 | block content 8 | h1= failed login 9 | h2= placeholder 10 | -------------------------------------------------------------------------------- /views/importdata.jade: -------------------------------------------------------------------------------- 1 | 2 | extends layout 3 | block content 4 | head 5 | title 'QBO Data' 6 | body 7 | a(href="/importdata/accounts") Import customer data 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /views/index.jade: -------------------------------------------------------------------------------- 1 | extends layout 2 | 3 | block content 4 | head 5 | title 'Sign in' 6 | 7 | script(type='text/javascript', src='https://ajax.googleapis.com/ajax/libs/jquery/1.6.3/jquery.min.js') 8 | script(type='text/javascript', src='https://js.appcenter.intuit.com/Content/IA/intuit.ipp.anywhere.js') 9 | body 10 | p Welcome to CanCan 11 | if user == undefined 12 | a(href="/intuit") Sign On with Intuit 13 | else 14 | p hello #{user.emails[0]} 15 | a(href="/quickbooks") load QuickBooks Data 16 | // ipp:login(href="http://localhost:3000/intuit/return", type="vertical") 17 | 18 | -------------------------------------------------------------------------------- /views/intuit.jade: -------------------------------------------------------------------------------- 1 | 2 | extends layout 3 | 4 | block content 5 | head 6 | title 'Sign in' 7 | p Welcome to #{Catmandu} 8 | body 9 | p #{data} 10 | 11 | -------------------------------------------------------------------------------- /views/layout.jade: -------------------------------------------------------------------------------- 1 | doctype html 2 | html 3 | head 4 | title= title 5 | link(rel='stylesheet', href='/stylesheets/style.css') 6 | body 7 | block content -------------------------------------------------------------------------------- /views/qboauth.jade: -------------------------------------------------------------------------------- 1 | doctype html 2 | html(lang="en") 3 | head 4 | title #{pageTitle} 5 | script(type='text/javascript', src='https://appcenter.intuit.com/Content/IA/intuit.ipp.anywhere.js') 6 | body 7 | p #{port} #{appCenter} 8 | a(href='/quickbase') connect to quickbase 9 | p 10 | script(type='text/javascript'). 11 | intuit.ipp.anywhere.setup({ 12 | menuProxy: '', 13 | grantUrl: 'http://localhost:' + #{port} + '/quickbooks/requestToken' 14 | }); 15 | ipp:connectToIntuit 16 | 17 | -------------------------------------------------------------------------------- /views/qbodatadisplay.jade: -------------------------------------------------------------------------------- 1 | 2 | extends layout 3 | block content 4 | head 5 | title 'QBO data' 6 | body 7 | ul 8 | for account in accounts.QueryResponse.Account 9 | li= JSON.stringify(account.Name) 10 | 11 | 12 | -------------------------------------------------------------------------------- /views/quickbase.jade: -------------------------------------------------------------------------------- 1 | //Created by sram on 7/6/15. 2 | 3 | extends layout 4 | block content 5 | h1= title 6 | p Welcome to #{title} 7 | 8 | -------------------------------------------------------------------------------- /views/quickbooks.jade: -------------------------------------------------------------------------------- 1 | // Created by sram on 7/6/15. 2 | 3 | extends layout 4 | block content 5 | h1= title 6 | p Welcome to #{title} 7 | 8 | --------------------------------------------------------------------------------