From 2949a4eb5e0d890cb9e937162385c507cf9cc0e6 Mon Sep 17 00:00:00 2001 From: Purujit Srinivasan Date: Thu, 29 Apr 2021 18:24:32 +0530 Subject: [PATCH 1/4] add get for commonly used items --- src/OAuthClient.js | 605 +++++++++++++++++++++++++++++++++++ src/response/AuthResponse.js | 1 + 2 files changed, 606 insertions(+) diff --git a/src/OAuthClient.js b/src/OAuthClient.js index 011c251b..68fa9341 100644 --- a/src/OAuthClient.js +++ b/src/OAuthClient.js @@ -36,6 +36,7 @@ const jwt = require('jsonwebtoken'); const AuthResponse = require('./response/AuthResponse'); const version = require('../package.json'); const Token = require('./access-token/Token'); +const https = require('https'); /** * @constructor @@ -49,6 +50,7 @@ function OAuthClient(config) { this.clientId = config.clientId; this.clientSecret = config.clientSecret; this.redirectUri = config.redirectUri; + this.realmId = config.realmId; this.token = new Token(config.token); this.logging = !!( Object.prototype.hasOwnProperty.call(config, 'logging') && config.logging === true @@ -158,6 +160,8 @@ OAuthClient.prototype.createToken = function createToken(uri) { if (!uri) throw new Error('Provide the Uri'); const params = queryString.parse(uri.split('?').reverse()[0]); this.getToken().realmId = params.realmId ? params.realmId : ''; + if (this.getToken().realmId) this.realmId = this.getToken().realmId; + else if (this.realmId && typeof(this.realmId)==="string") this.getToken().realmId = this.realmId; if ('state' in params) this.getToken().state = params.state; const body = {}; @@ -226,6 +230,9 @@ OAuthClient.prototype.refresh = function refresh() { const authResponse = res.json ? res : null; const json = (authResponse && authResponse.getJson()) || res; this.token.setToken(json); + if (!this.getToken().realmId && this.realmId && typeof(this.realmId)==="string") { + this.getToken().realmId = this.realmId; + } this.log('info', 'Refresh Token () response is : ', JSON.stringify(authResponse, null, 2)); return authResponse; }) @@ -268,6 +275,9 @@ OAuthClient.prototype.refreshUsingToken = function refreshUsingToken(refresh_tok const authResponse = res.json ? res : null; const json = (authResponse && authResponse.getJson()) || res; this.token.setToken(json); + if (!this.getToken().realmId && this.realmId && typeof(this.realmId)==="string") { + this.getToken().realmId = this.realmId; + } this.log( 'info', 'Refresh usingToken () response is : ', @@ -644,4 +654,599 @@ OAuthClient.prototype.log = function log(level, message, messageData) { } }; +/** + * Get details of a quickbooks Account + * @param {string|number} acc_id - Id reference of Account + * @returns {Promise} QuickBooks Account + */ + +OAuthClient.prototype.getAccount = function getAccount(acc_id) { + return new Promise((resolve) => { + if (!this.isAccessTokenValid()) throw new Error('OAuth authentication failed! Invalid Token!'); + const acc = parseInt(acc_id, 10); + if (Number.isNaN(acc)) throw new Error('Invalid Account Id! Must be a number or number as a string!'); + const companyID = this.getToken().realmId; + if (!companyID) throw new Error('Realm Id missing! Please create a new token using OAuth and try again.'); + const url0 = this.environment === 'sandbox' + ? OAuthClient.environment.sandbox + : OAuthClient.environment.production; + const headers0 = { + Authorization: `Bearer ${this.getToken().access_token}`, + Accept: AuthResponse._jsonContentType, + 'User-Agent': OAuthClient.user_agent, + }; + const request = { + method: 'GET', + url: `${url0}v3/company/${companyID}/account/${acc}`, + headers: headers0, + }; + resolve(this.getTokenRequest(request)); + }) + .then((authResponse) => { + this.log('info', 'The getAccount () response is : ', JSON.stringify(authResponse, null, 2)); + const myAccount = JSON.parse(authResponse.text()); + return myAccount.Account; + }) + .catch((e) => { + this.log('error', 'Get getAccount () threw an exception : ', JSON.stringify(e, null, 2)); + throw e; + }); +}; + +/** + * Get details of a quickbooks Bill + * @param {string|number} bill_id - Id reference of Bill + * @returns {Promise} QuickBooks Bill + */ + +OAuthClient.prototype.getBill = function getBill(bill_id) { + return new Promise((resolve) => { + if (!this.isAccessTokenValid()) throw new Error('OAuth authentication failed! Invalid Token!'); + const bill0 = parseInt(bill_id, 10); + if (Number.isNaN(bill0)) throw new Error('Invalid Bill Id! Must be a number or number as a string!'); + const companyID = this.getToken().realmId; + if (!companyID) throw new Error('Realm Id missing! Please create a new token using OAuth and try again.'); + const url0 = this.environment === 'sandbox' + ? OAuthClient.environment.sandbox + : OAuthClient.environment.production; + const headers0 = { + Authorization: `Bearer ${this.getToken().access_token}`, + Accept: AuthResponse._jsonContentType, + 'User-Agent': OAuthClient.user_agent, + }; + const request = { + method: 'GET', + url: `${url0}v3/company/${companyID}/bill/${bill0}`, + headers: headers0, + }; + resolve(this.getTokenRequest(request)); + }) + .then((authResponse) => { + this.log('info', 'The getBill () response is : ', JSON.stringify(authResponse, null, 2)); + const myBill = JSON.parse(authResponse.text()); + return myBill.Bill; + }) + .catch((e) => { + this.log('error', 'Get getBill () threw an exception : ', JSON.stringify(e, null, 2)); + throw e; + }); +}; + +/** + * Get details of a quickbooks companyInfo based on realmId + * @returns {Promise} QuickBooks CompanyInfo + */ + +OAuthClient.prototype.getCompanyInfo = function getCompanyInfo() { + return new Promise((resolve) => { + if (!this.isAccessTokenValid()) throw new Error('OAuth authentication failed! Invalid Token!'); + const companyID = this.getToken().realmId; + if (!companyID) throw new Error('Realm Id / CompanyInfo Id missing! Please create a new token using OAuth and try again.'); + const url0 = this.environment === 'sandbox' + ? OAuthClient.environment.sandbox + : OAuthClient.environment.production; + const headers0 = { + Authorization: `Bearer ${this.getToken().access_token}`, + Accept: AuthResponse._jsonContentType, + 'User-Agent': OAuthClient.user_agent, + }; + const request = { + method: 'GET', + url: `${url0}v3/company/${companyID}/companyinfo/${companyID}`, + headers: headers0, + }; + resolve(this.getTokenRequest(request)); + }) + .then((authResponse) => { + this.log('info', 'The getCompanyInfo () response is : ', JSON.stringify(authResponse, null, 2)); + const myCompanyInfo = JSON.parse(authResponse.text()); + return myCompanyInfo.CompanyInfo; + }) + .catch((e) => { + this.log('error', 'Get getCompanyInfo () threw an exception : ', JSON.stringify(e, null, 2)); + throw e; + }); +}; + +/** + * Get details of a quickbooks Customer + * @param {string|number} customer_id - Id reference of Customer + * @returns {Promise} QuickBooks Customer + */ + +OAuthClient.prototype.getCustomer = function getCustomer(customer_id) { + return new Promise((resolve) => { + if (!this.isAccessTokenValid()) throw new Error('OAuth authentication failed! Invalid Token!'); + const cus = parseInt(customer_id, 10); + if (Number.isNaN(cus)) throw new Error('Invalid Customer Id! Must be a number or number as a string!'); + const companyID = this.getToken().realmId; + if (!companyID) throw new Error('Realm Id missing! Please create a new token using OAuth and try again.'); + const url0 = this.environment === 'sandbox' + ? OAuthClient.environment.sandbox + : OAuthClient.environment.production; + const headers0 = { + Authorization: `Bearer ${this.getToken().access_token}`, + Accept: AuthResponse._jsonContentType, + 'User-Agent': OAuthClient.user_agent, + }; + const request = { + method: 'GET', + url: `${url0}v3/company/${companyID}/customer/${cus}`, + headers: headers0, + }; + resolve(this.getTokenRequest(request)); + }) + .then((authResponse) => { + this.log('info', 'The getCustomer () response is : ', JSON.stringify(authResponse, null, 2)); + const myCustomer = JSON.parse(authResponse.text()); + return myCustomer.Customer; + }) + .catch((e) => { + this.log('error', 'Get getCustomer () threw an exception : ', JSON.stringify(e, null, 2)); + throw e; + }); +}; + +/** + * Get details of a quickbooks Employee + * @param {string|number} employee_id - Id reference of Employee + * @returns {Promise} QuickBooks Employee + */ + +OAuthClient.prototype.getEmployee = function getEmployee(employee_id) { + return new Promise((resolve) => { + if (!this.isAccessTokenValid()) throw new Error('OAuth authentication failed! Invalid Token!'); + const employee0 = parseInt(employee_id, 10); + if (Number.isNaN(employee0)) throw new Error('Invalid Employee Id! Must be a number or number as a string!'); + const companyID = this.getToken().realmId; + if (!companyID) throw new Error('Realm Id missing! Please create a new token using OAuth and try again.'); + const url0 = this.environment === 'sandbox' + ? OAuthClient.environment.sandbox + : OAuthClient.environment.production; + const headers0 = { + Authorization: `Bearer ${this.getToken().access_token}`, + Accept: AuthResponse._jsonContentType, + 'User-Agent': OAuthClient.user_agent, + }; + const request = { + method: 'GET', + url: `${url0}v3/company/${companyID}/employee/${employee0}`, + headers: headers0, + }; + resolve(this.getTokenRequest(request)); + }) + .then((authResponse) => { + this.log('info', 'The getEmployee () response is : ', JSON.stringify(authResponse, null, 2)); + const myEmployee = JSON.parse(authResponse.text()); + return myEmployee.Employee; + }) + .catch((e) => { + this.log('error', 'Get getEmployee () threw an exception : ', JSON.stringify(e, null, 2)); + throw e; + }); +}; + +/** + * Get details of a quickbooks Estimate + * @param {string|number} estimate_id - Id reference of Estimate + * @returns {Promise} QuickBooks Estimate + */ + +OAuthClient.prototype.getEstimate = function getEstimate(estimate_id) { + return new Promise((resolve) => { + if (!this.isAccessTokenValid()) throw new Error('OAuth authentication failed! Invalid Token!'); + const estimate0 = parseInt(estimate_id, 10); + if (Number.isNaN(estimate0)) throw new Error('Invalid Estimate Id! Must be a number or number as a string!'); + const companyID = this.getToken().realmId; + if (!companyID) throw new Error('Realm Id missing! Please create a new token using OAuth and try again.'); + const url0 = this.environment === 'sandbox' + ? OAuthClient.environment.sandbox + : OAuthClient.environment.production; + const headers0 = { + Authorization: `Bearer ${this.getToken().access_token}`, + Accept: AuthResponse._jsonContentType, + 'User-Agent': OAuthClient.user_agent, + }; + const request = { + method: 'GET', + url: `${url0}v3/company/${companyID}/estimate/${estimate0}`, + headers: headers0, + }; + resolve(this.getTokenRequest(request)); + }) + .then((authResponse) => { + this.log('info', 'The getEstimate () response is : ', JSON.stringify(authResponse, null, 2)); + const myEstimate = JSON.parse(authResponse.text()); + return myEstimate.Estimate; + }) + .catch((e) => { + this.log('error', 'Get getEstimate () threw an exception : ', JSON.stringify(e, null, 2)); + throw e; + }); +}; + +/** + * Get PDF of a quickbooks Estimate + * @param {string|number} estimate_id - Id reference of EstimatePDF + * @returns {Promise} QuickBooks EstimatePDF + */ + + OAuthClient.prototype.getEstimatePDF = function getEstimatePDF(estimate_id) { + return new Promise((resolve) => { + if (!this.isAccessTokenValid()) throw new Error('OAuth authentication failed! Invalid Token!'); + const estimate0 = parseInt(estimate_id, 10); + if (Number.isNaN(estimate0)) throw new Error('Invalid Estimate Id! Must be a number or number as a string!'); + const companyID = this.getToken().realmId; + if (!companyID) throw new Error('Realm Id missing! Please create a new token using OAuth and try again.'); + const url0 = this.environment === 'sandbox' + ? OAuthClient.environment.sandbox + : OAuthClient.environment.production; + const headers0 = { + Authorization: `Bearer ${this.getToken().access_token}`, + Accept: AuthResponse._pdfContentType, + 'User-Agent': OAuthClient.user_agent, + }; + const req_options = { + method: 'GET', + headers: headers0, + }; + const get_url = `${url0}v3/company/${companyID}/estimate/${estimate0}/pdf`; + const request = https.get(get_url, req_options, (resp) => { + let myPDFBuffer = []; + resp.on('data', (chunk) => { + myPDFBuffer.push(chunk); + }); + resp.on('end', () => { + resolve(Buffer.concat(myPDFBuffer)); + }); + }); + request.on('error', (er) => { + throw er; + }); + request.end(); + }) + .then((authResponse) => { + this.log('info', 'The getEstimatePDF () response is : ', authResponse ? authResponse.toString() : "EMPTY"); + return authResponse; + }) + .catch((e) => { + this.log('error', 'Get getEstimatePDF () threw an exception : ', JSON.stringify(e, null, 2)); + throw e; + }); +}; + +/** + * Get details of a quickbooks Invoice + * @param {string|number} invoice_id - Id reference of Invoice + * @returns {Promise} QuickBooks Invoice + */ + +OAuthClient.prototype.getInvoice = function getInvoice(invoice_id) { + return new Promise((resolve) => { + if (!this.isAccessTokenValid()) throw new Error('OAuth authentication failed! Invalid Token!'); + const invoice0 = parseInt(invoice_id, 10); + if (Number.isNaN(invoice0)) throw new Error('Invalid Invoice Id! Must be a number or number as a string!'); + const companyID = this.getToken().realmId; + if (!companyID) throw new Error('Realm Id missing! Please create a new token using OAuth and try again.'); + const url0 = this.environment === 'sandbox' + ? OAuthClient.environment.sandbox + : OAuthClient.environment.production; + const headers0 = { + Authorization: `Bearer ${this.getToken().access_token}`, + Accept: AuthResponse._jsonContentType, + 'User-Agent': OAuthClient.user_agent, + }; + const request = { + method: 'GET', + url: `${url0}v3/company/${companyID}/invoice/${invoice0}`, + headers: headers0, + }; + resolve(this.getTokenRequest(request)); + }) + .then((authResponse) => { + this.log('info', 'The getInvoice () response is : ', JSON.stringify(authResponse, null, 2)); + const myInvoice = JSON.parse(authResponse.text()); + return myInvoice.Invoice; + }) + .catch((e) => { + this.log('error', 'Get getInvoice () threw an exception : ', JSON.stringify(e, null, 2)); + throw e; + }); +}; + +/** + * Get PDF of a quickbooks Invoice + * @param {string|number} invoice_id - Id reference of InvoicePDF + * @returns {Promise} QuickBooks InvoicePDF + */ + +OAuthClient.prototype.getInvoicePDF = function getInvoicePDF(invoice_id) { + return new Promise((resolve) => { + if (!this.isAccessTokenValid()) throw new Error('OAuth authentication failed! Invalid Token!'); + const invoice0 = parseInt(invoice_id, 10); + if (Number.isNaN(invoice0)) throw new Error('Invalid Invoice Id! Must be a number or number as a string!'); + const companyID = this.getToken().realmId; + if (!companyID) throw new Error('Realm Id missing! Please create a new token using OAuth and try again.'); + const url0 = this.environment === 'sandbox' + ? OAuthClient.environment.sandbox + : OAuthClient.environment.production; + const headers0 = { + Authorization: `Bearer ${this.getToken().access_token}`, + Accept: AuthResponse._pdfContentType, + 'User-Agent': OAuthClient.user_agent, + }; + const req_options = { + method: 'GET', + headers: headers0, + }; + const get_url = `${url0}v3/company/${companyID}/invoice/${invoice0}/pdf`; + const request = https.get(get_url, req_options, (resp) => { + let myPDFBuffer = []; + resp.on('data', (chunk) => { + myPDFBuffer.push(chunk); + }); + resp.on('end', () => { + resolve(Buffer.concat(myPDFBuffer)); + }); + }); + request.on('error', (er) => { + throw er; + }); + request.end(); + }) + .then((authResponse) => { + this.log('info', 'The getInvoicePDF () response is : ', authResponse ? authResponse.toString() : "EMPTY"); + return authResponse; + }) + .catch((e) => { + this.log('error', 'Get getInvoicePDF () threw an exception : ', JSON.stringify(e, null, 2)); + throw e; + }); +}; + +/** + * Get details of a quickbooks Item + * @param {string|number} item_id - Id reference of Item + * @returns {Promise} QuickBooks Item + */ + +OAuthClient.prototype.getItem = function getItem(item_id) { + return new Promise((resolve) => { + if (!this.isAccessTokenValid()) throw new Error('OAuth authentication failed! Invalid Token!'); + const item0 = parseInt(item_id, 10); + if (Number.isNaN(item0)) throw new Error('Invalid Item Id! Must be a number or number as a string!'); + const companyID = this.getToken().realmId; + if (!companyID) throw new Error('Realm Id missing! Please create a new token using OAuth and try again.'); + const url0 = this.environment === 'sandbox' + ? OAuthClient.environment.sandbox + : OAuthClient.environment.production; + const headers0 = { + Authorization: `Bearer ${this.getToken().access_token}`, + Accept: AuthResponse._jsonContentType, + 'User-Agent': OAuthClient.user_agent, + }; + const request = { + method: 'GET', + url: `${url0}v3/company/${companyID}/item/${item0}`, + headers: headers0, + }; + resolve(this.getTokenRequest(request)); + }) + .then((authResponse) => { + this.log('info', 'The getItem () response is : ', JSON.stringify(authResponse, null, 2)); + const myItem = JSON.parse(authResponse.text()); + return myItem.Item; + }) + .catch((e) => { + this.log('error', 'Get getItem () threw an exception : ', JSON.stringify(e, null, 2)); + throw e; + }); +}; + +/** + * Get details of a quickbooks Payment + * @param {string|number} payment_id - Id reference of Payment + * @returns {Promise} QuickBooks Payment + */ + +OAuthClient.prototype.getPayment = function getPayment(payment_id) { + return new Promise((resolve) => { + if (!this.isAccessTokenValid()) throw new Error('OAuth authentication failed! Invalid Token!'); + const payment0 = parseInt(payment_id, 10); + if (Number.isNaN(payment0)) throw new Error('Invalid Payment Id! Must be a number or number as a string!'); + const companyID = this.getToken().realmId; + if (!companyID) throw new Error('Realm Id missing! Please create a new token using OAuth and try again.'); + const url0 = this.environment === 'sandbox' + ? OAuthClient.environment.sandbox + : OAuthClient.environment.production; + const headers0 = { + Authorization: `Bearer ${this.getToken().access_token}`, + Accept: AuthResponse._jsonContentType, + 'User-Agent': OAuthClient.user_agent, + }; + const request = { + method: 'GET', + url: `${url0}v3/company/${companyID}/payment/${payment0}`, + headers: headers0, + }; + resolve(this.getTokenRequest(request)); + }) + .then((authResponse) => { + this.log('info', 'The getPayment () response is : ', JSON.stringify(authResponse, null, 2)); + const myPayment = JSON.parse(authResponse.text()); + return myPayment.Payment; + }) + .catch((e) => { + this.log('error', 'Get getPayment () threw an exception : ', JSON.stringify(e, null, 2)); + throw e; + }); +}; + +/** + * Get quickbooks Preferences for default company ID i.e. realmId + * @returns {Promise} QuickBooks Preferences + */ + +OAuthClient.prototype.getPreferences = function getPreferences() { + return new Promise((resolve) => { + if (!this.isAccessTokenValid()) throw new Error('OAuth authentication failed! Invalid Token!'); + const companyID = this.getToken().realmId; + if (!companyID) throw new Error('Realm Id missing! Please create a new token using OAuth and try again.'); + const url0 = this.environment === 'sandbox' + ? OAuthClient.environment.sandbox + : OAuthClient.environment.production; + const headers0 = { + Authorization: `Bearer ${this.getToken().access_token}`, + Accept: AuthResponse._jsonContentType, + 'User-Agent': OAuthClient.user_agent, + }; + const request = { + method: 'GET', + url: `${url0}v3/company/${companyID}/preferences`, + headers: headers0, + }; + resolve(this.getTokenRequest(request)); + }) + .then((authResponse) => { + this.log('info', 'The getPreferences () response is : ', JSON.stringify(authResponse, null, 2)); + const myPreferences = JSON.parse(authResponse.text()); + return myPreferences.Preferences; + }) + .catch((e) => { + this.log('error', 'Get getPreferences () threw an exception : ', JSON.stringify(e, null, 2)); + throw e; + }); +}; + +/** + * Get details of a quickbooks TaxAgency + * @param {string|number} tax_agency_id - Id reference of TaxAgency + * @returns {Promise} QuickBooks TaxAgency + */ + +OAuthClient.prototype.getTaxAgency = function getTaxAgency(tax_agency_id) { + return new Promise((resolve) => { + if (!this.isAccessTokenValid()) throw new Error('OAuth authentication failed! Invalid Token!'); + const taxagency0 = parseInt(tax_agency_id, 10); + if (Number.isNaN(taxagency0)) throw new Error('Invalid TaxAgency Id! Must be a number or number as a string!'); + const companyID = this.getToken().realmId; + if (!companyID) throw new Error('Realm Id missing! Please create a new token using OAuth and try again.'); + const url0 = this.environment === 'sandbox' + ? OAuthClient.environment.sandbox + : OAuthClient.environment.production; + const headers0 = { + Authorization: `Bearer ${this.getToken().access_token}`, + Accept: AuthResponse._jsonContentType, + 'User-Agent': OAuthClient.user_agent, + }; + const request = { + method: 'GET', + url: `${url0}v3/company/${companyID}/taxagency/${taxagency0}`, + headers: headers0, + }; + resolve(this.getTokenRequest(request)); + }) + .then((authResponse) => { + this.log('info', 'The getTaxAgency () response is : ', JSON.stringify(authResponse, null, 2)); + const myTaxAgency = JSON.parse(authResponse.text()); + return myTaxAgency.TaxAgency; + }) + .catch((e) => { + this.log('error', 'Get getTaxAgency () threw an exception : ', JSON.stringify(e, null, 2)); + throw e; + }); +}; + +/** + * Get details of a quickbooks Vendor + * @param {string|number} vendor_id - Id reference of Vendor + * @returns {Promise} QuickBooks Vendor + */ + + OAuthClient.prototype.getVendor = function getVendor(vendor_id) { + return new Promise((resolve) => { + if (!this.isAccessTokenValid()) throw new Error('OAuth authentication failed! Invalid Token!'); + const vendor0 = parseInt(vendor_id, 10); + if (Number.isNaN(vendor0)) throw new Error('Invalid Vendor Id! Must be a number or number as a string!'); + const companyID = this.getToken().realmId; + if (!companyID) throw new Error('Realm Id missing! Please create a new token using OAuth and try again.'); + const url0 = this.environment === 'sandbox' + ? OAuthClient.environment.sandbox + : OAuthClient.environment.production; + const headers0 = { + Authorization: `Bearer ${this.getToken().access_token}`, + Accept: AuthResponse._jsonContentType, + 'User-Agent': OAuthClient.user_agent, + }; + const request = { + method: 'GET', + url: `${url0}v3/company/${companyID}/vendor/${vendor0}`, + headers: headers0, + }; + resolve(this.getTokenRequest(request)); + }) + .then((authResponse) => { + this.log('info', 'The getVendor () response is : ', JSON.stringify(authResponse, null, 2)); + const myVendor = JSON.parse(authResponse.text()); + return myVendor.Vendor; + }) + .catch((e) => { + this.log('error', 'Get getVendor () threw an exception : ', JSON.stringify(e, null, 2)); + throw e; + }); +}; + +// OAuthClient.prototype.getCompanyInfo = function getCompanyInfo() { +// return new Promise((resolve) => { +// const request = { +// url: +// this.environment === 'sandbox' +// ? OAuthClient.userinfo_endpoint_sandbox +// : OAuthClient.userinfo_endpoint_production, +// method: 'GET', +// headers: { +// Authorization: `Bearer ${this.token.access_token}`, +// Accept: AuthResponse._jsonContentType, +// 'User-Agent': OAuthClient.user_agent, +// }, +// }; + +// resolve(this.getTokenRequest(request)); +// }) +// .then((res) => { +// const authResponse = res.json ? res : null; +// this.log( +// 'info', +// 'The Get User Info () response is : ', +// JSON.stringify(authResponse, null, 2), +// ); +// return authResponse; +// }) +// .catch((e) => { +// this.log('error', 'Get User Info () threw an exception : ', JSON.stringify(e, null, 2)); +// throw e; +// }); +// }; + + module.exports = OAuthClient; diff --git a/src/response/AuthResponse.js b/src/response/AuthResponse.js index 5a4abee5..4e1d16a0 100644 --- a/src/response/AuthResponse.js +++ b/src/response/AuthResponse.js @@ -150,6 +150,7 @@ AuthResponse.prototype.isJson = function isJson() { AuthResponse._contentType = 'Content-Type'; AuthResponse._jsonContentType = 'application/json'; +AuthResponse._pdfContentType = 'application/pdf'; AuthResponse._urlencodedContentType = 'application/x-www-form-urlencoded'; From 7d65a0f246e9cc25cf95a0fc1c8de01e732d6757 Mon Sep 17 00:00:00 2001 From: Purujit Srinivasan Date: Fri, 30 Apr 2021 12:32:28 +0530 Subject: [PATCH 2/4] minimize all get --- src/OAuthClient.js | 552 +++++++++------------------------------------ 1 file changed, 111 insertions(+), 441 deletions(-) diff --git a/src/OAuthClient.js b/src/OAuthClient.js index 68fa9341..6f5748a0 100644 --- a/src/OAuthClient.js +++ b/src/OAuthClient.js @@ -655,16 +655,23 @@ OAuthClient.prototype.log = function log(level, message, messageData) { }; /** - * Get details of a quickbooks Account - * @param {string|number} acc_id - Id reference of Account - * @returns {Promise} QuickBooks Account - */ - -OAuthClient.prototype.getAccount = function getAccount(acc_id) { + * This is a generic method for performing API call + * We also have makeAPICall() but here we are first checking whether token is valid, realm Id is there + * @param {object} options0 - Fetch API call options, defaults to GET method + * @param {string} entity0 - QuickBooks Entity name e.g. CompanyInfo (Important: Case sensitive) + * @param {string|number} [id0] - If GET method, specify Id of Entity (wherever required) + * @returns {Promise} - Quickbooks Entity Object or Response of API + */ + +OAuthClient.prototype.fetchAPI = function fetchAPI(options0, entity0, id0) { + if (!entity0 || typeof(entity0)!=='string' || !entity0.slice(0,50).trim()) throw new Error('Invalid Quickbooks Entity!'); + entity0 = entity0.slice(0,50).trim(); + const name0 = entity0[0].toUpperCase() + entity0.slice(1); + entity0 = entity0.toLowerCase(); return new Promise((resolve) => { if (!this.isAccessTokenValid()) throw new Error('OAuth authentication failed! Invalid Token!'); - const acc = parseInt(acc_id, 10); - if (Number.isNaN(acc)) throw new Error('Invalid Account Id! Must be a number or number as a string!'); + const entity_id = parseInt(id0, 10); + if (id0 && Number.isNaN(entity_id)) throw new Error(`Invalid ${name0} Id! Must be a number or number as a string!`); const companyID = this.getToken().realmId; if (!companyID) throw new Error('Realm Id missing! Please create a new token using OAuth and try again.'); const url0 = this.environment === 'sandbox' @@ -675,35 +682,59 @@ OAuthClient.prototype.getAccount = function getAccount(acc_id) { Accept: AuthResponse._jsonContentType, 'User-Agent': OAuthClient.user_agent, }; + let extendURL = entity0; + if (id0) { + extendURL += `/${entity_id}`; + } const request = { method: 'GET', - url: `${url0}v3/company/${companyID}/account/${acc}`, + url: `${url0}v3/company/${companyID}/${extendURL}`, headers: headers0, }; + if (options0 && typeof(options0)==='object' && typeof(options0.method)==='string') { + request.method = options0.method; + if (options0.method.toUpperCase()!=='GET') { + request.body = options0.body; + } + if (typeof(options0.headers)==='object') { + Object.assign(request.headers, options0.headers); + } + } resolve(this.getTokenRequest(request)); }) .then((authResponse) => { - this.log('info', 'The getAccount () response is : ', JSON.stringify(authResponse, null, 2)); - const myAccount = JSON.parse(authResponse.text()); - return myAccount.Account; + this.log('info', `The fetch on ${name0} () response is : `, JSON.stringify(authResponse, null, 2)); + let myEntity; + if (authResponse.headers()['content-type'].indexOf('json')>-1) { + myEntity = JSON.parse(authResponse.text())[name0]; + } + else { + myEntity = authResponse.text(); + } + return myEntity; }) .catch((e) => { - this.log('error', 'Get getAccount () threw an exception : ', JSON.stringify(e, null, 2)); + this.log('error', `The fetch on ${name0} () threw an exception : `, JSON.stringify(e, null, 2)); throw e; }); -}; +} /** - * Get details of a quickbooks Bill - * @param {string|number} bill_id - Id reference of Bill - * @returns {Promise} QuickBooks Bill + * This is a method for getting a PDF + * @param {string} entity0 - QuickBooks Entity name e.g. Invoice (Important: Case sensitive) + * @param {string|number} id0 - Specify Id of Entity (required) + * @returns {Promise} - PDF response (It is a buffer in the form of PDF) */ -OAuthClient.prototype.getBill = function getBill(bill_id) { + OAuthClient.prototype.fetchPDF = function fetchPDF(entity0, id0) { + if (!entity0 || typeof(entity0)!=='string' || !entity0.slice(0,50).trim()) throw new Error('Invalid Quickbooks Entity!'); + entity0 = entity0.slice(0,50).trim(); + const name0 = entity0[0].toUpperCase() + entity0.slice(1); + entity0 = entity0.toLowerCase(); return new Promise((resolve) => { if (!this.isAccessTokenValid()) throw new Error('OAuth authentication failed! Invalid Token!'); - const bill0 = parseInt(bill_id, 10); - if (Number.isNaN(bill0)) throw new Error('Invalid Bill Id! Must be a number or number as a string!'); + const entity_id = parseInt(id0, 10); + if (Number.isNaN(entity_id)) throw new Error(`Invalid ${name0} Id! Must be a number or number as a string!`); const companyID = this.getToken().realmId; if (!companyID) throw new Error('Realm Id missing! Please create a new token using OAuth and try again.'); const url0 = this.environment === 'sandbox' @@ -711,25 +742,63 @@ OAuthClient.prototype.getBill = function getBill(bill_id) { : OAuthClient.environment.production; const headers0 = { Authorization: `Bearer ${this.getToken().access_token}`, - Accept: AuthResponse._jsonContentType, + Accept: AuthResponse._pdfContentType, 'User-Agent': OAuthClient.user_agent, }; - const request = { + const extendURL = `${entity0}/${entity_id}/pdf`; + const req_options = { method: 'GET', - url: `${url0}v3/company/${companyID}/bill/${bill0}`, headers: headers0, }; - resolve(this.getTokenRequest(request)); + const get_url = `${url0}v3/company/${companyID}/${extendURL}`; + const request = https.get(get_url, req_options, (resp) => { + let myPDFBuffer = []; + resp.on('data', (chunk) => { + myPDFBuffer.push(chunk); + }); + resp.on('end', () => { + resolve(Buffer.concat(myPDFBuffer)); + }); + }); + request.on('error', (er) => { + throw er; + }); + request.end(); }) .then((authResponse) => { - this.log('info', 'The getBill () response is : ', JSON.stringify(authResponse, null, 2)); - const myBill = JSON.parse(authResponse.text()); - return myBill.Bill; + this.log('info', `The get${name0}PDF () response is : `, authResponse ? authResponse.toString() : "EMPTY"); + return authResponse; }) .catch((e) => { - this.log('error', 'Get getBill () threw an exception : ', JSON.stringify(e, null, 2)); + this.log('error', `Get get${name0}PDF () threw an exception : `, JSON.stringify(e, null, 2)); throw e; }); +} + +/* CREATE ENTITIES */ + +/* DELETE ENTITIES */ + +/* GET ENTITIES */ + +/** + * Get details of a quickbooks Account + * @param {string|number} acc_id - Id reference of Account + * @returns {Promise} QuickBooks Account + */ + +OAuthClient.prototype.getAccount = function getAccount(acc_id) { + return this.fetchAPI(null, 'Account', acc_id); +}; + +/** + * Get details of a quickbooks Bill + * @param {string|number} bill_id - Id reference of Bill + * @returns {Promise} QuickBooks Bill + */ + +OAuthClient.prototype.getBill = function getBill(bill_id) { + return this.fetchAPI(null, 'Bill', bill_id); }; /** @@ -737,35 +806,8 @@ OAuthClient.prototype.getBill = function getBill(bill_id) { * @returns {Promise} QuickBooks CompanyInfo */ -OAuthClient.prototype.getCompanyInfo = function getCompanyInfo() { - return new Promise((resolve) => { - if (!this.isAccessTokenValid()) throw new Error('OAuth authentication failed! Invalid Token!'); - const companyID = this.getToken().realmId; - if (!companyID) throw new Error('Realm Id / CompanyInfo Id missing! Please create a new token using OAuth and try again.'); - const url0 = this.environment === 'sandbox' - ? OAuthClient.environment.sandbox - : OAuthClient.environment.production; - const headers0 = { - Authorization: `Bearer ${this.getToken().access_token}`, - Accept: AuthResponse._jsonContentType, - 'User-Agent': OAuthClient.user_agent, - }; - const request = { - method: 'GET', - url: `${url0}v3/company/${companyID}/companyinfo/${companyID}`, - headers: headers0, - }; - resolve(this.getTokenRequest(request)); - }) - .then((authResponse) => { - this.log('info', 'The getCompanyInfo () response is : ', JSON.stringify(authResponse, null, 2)); - const myCompanyInfo = JSON.parse(authResponse.text()); - return myCompanyInfo.CompanyInfo; - }) - .catch((e) => { - this.log('error', 'Get getCompanyInfo () threw an exception : ', JSON.stringify(e, null, 2)); - throw e; - }); +OAuthClient.prototype.getCompanyInfo = function getCompanyInfo() { // check + return this.fetchAPI(null, 'CompanyInfo', this.getToken().realmId); }; /** @@ -775,36 +817,7 @@ OAuthClient.prototype.getCompanyInfo = function getCompanyInfo() { */ OAuthClient.prototype.getCustomer = function getCustomer(customer_id) { - return new Promise((resolve) => { - if (!this.isAccessTokenValid()) throw new Error('OAuth authentication failed! Invalid Token!'); - const cus = parseInt(customer_id, 10); - if (Number.isNaN(cus)) throw new Error('Invalid Customer Id! Must be a number or number as a string!'); - const companyID = this.getToken().realmId; - if (!companyID) throw new Error('Realm Id missing! Please create a new token using OAuth and try again.'); - const url0 = this.environment === 'sandbox' - ? OAuthClient.environment.sandbox - : OAuthClient.environment.production; - const headers0 = { - Authorization: `Bearer ${this.getToken().access_token}`, - Accept: AuthResponse._jsonContentType, - 'User-Agent': OAuthClient.user_agent, - }; - const request = { - method: 'GET', - url: `${url0}v3/company/${companyID}/customer/${cus}`, - headers: headers0, - }; - resolve(this.getTokenRequest(request)); - }) - .then((authResponse) => { - this.log('info', 'The getCustomer () response is : ', JSON.stringify(authResponse, null, 2)); - const myCustomer = JSON.parse(authResponse.text()); - return myCustomer.Customer; - }) - .catch((e) => { - this.log('error', 'Get getCustomer () threw an exception : ', JSON.stringify(e, null, 2)); - throw e; - }); + return this.fetchAPI(null, 'Customer', customer_id); }; /** @@ -814,36 +827,7 @@ OAuthClient.prototype.getCustomer = function getCustomer(customer_id) { */ OAuthClient.prototype.getEmployee = function getEmployee(employee_id) { - return new Promise((resolve) => { - if (!this.isAccessTokenValid()) throw new Error('OAuth authentication failed! Invalid Token!'); - const employee0 = parseInt(employee_id, 10); - if (Number.isNaN(employee0)) throw new Error('Invalid Employee Id! Must be a number or number as a string!'); - const companyID = this.getToken().realmId; - if (!companyID) throw new Error('Realm Id missing! Please create a new token using OAuth and try again.'); - const url0 = this.environment === 'sandbox' - ? OAuthClient.environment.sandbox - : OAuthClient.environment.production; - const headers0 = { - Authorization: `Bearer ${this.getToken().access_token}`, - Accept: AuthResponse._jsonContentType, - 'User-Agent': OAuthClient.user_agent, - }; - const request = { - method: 'GET', - url: `${url0}v3/company/${companyID}/employee/${employee0}`, - headers: headers0, - }; - resolve(this.getTokenRequest(request)); - }) - .then((authResponse) => { - this.log('info', 'The getEmployee () response is : ', JSON.stringify(authResponse, null, 2)); - const myEmployee = JSON.parse(authResponse.text()); - return myEmployee.Employee; - }) - .catch((e) => { - this.log('error', 'Get getEmployee () threw an exception : ', JSON.stringify(e, null, 2)); - throw e; - }); + return this.fetchAPI(null, 'Employee', employee_id); }; /** @@ -853,36 +837,7 @@ OAuthClient.prototype.getEmployee = function getEmployee(employee_id) { */ OAuthClient.prototype.getEstimate = function getEstimate(estimate_id) { - return new Promise((resolve) => { - if (!this.isAccessTokenValid()) throw new Error('OAuth authentication failed! Invalid Token!'); - const estimate0 = parseInt(estimate_id, 10); - if (Number.isNaN(estimate0)) throw new Error('Invalid Estimate Id! Must be a number or number as a string!'); - const companyID = this.getToken().realmId; - if (!companyID) throw new Error('Realm Id missing! Please create a new token using OAuth and try again.'); - const url0 = this.environment === 'sandbox' - ? OAuthClient.environment.sandbox - : OAuthClient.environment.production; - const headers0 = { - Authorization: `Bearer ${this.getToken().access_token}`, - Accept: AuthResponse._jsonContentType, - 'User-Agent': OAuthClient.user_agent, - }; - const request = { - method: 'GET', - url: `${url0}v3/company/${companyID}/estimate/${estimate0}`, - headers: headers0, - }; - resolve(this.getTokenRequest(request)); - }) - .then((authResponse) => { - this.log('info', 'The getEstimate () response is : ', JSON.stringify(authResponse, null, 2)); - const myEstimate = JSON.parse(authResponse.text()); - return myEstimate.Estimate; - }) - .catch((e) => { - this.log('error', 'Get getEstimate () threw an exception : ', JSON.stringify(e, null, 2)); - throw e; - }); + return this.fetchAPI(null, 'Estimate', estimate_id); }; /** @@ -892,47 +847,7 @@ OAuthClient.prototype.getEstimate = function getEstimate(estimate_id) { */ OAuthClient.prototype.getEstimatePDF = function getEstimatePDF(estimate_id) { - return new Promise((resolve) => { - if (!this.isAccessTokenValid()) throw new Error('OAuth authentication failed! Invalid Token!'); - const estimate0 = parseInt(estimate_id, 10); - if (Number.isNaN(estimate0)) throw new Error('Invalid Estimate Id! Must be a number or number as a string!'); - const companyID = this.getToken().realmId; - if (!companyID) throw new Error('Realm Id missing! Please create a new token using OAuth and try again.'); - const url0 = this.environment === 'sandbox' - ? OAuthClient.environment.sandbox - : OAuthClient.environment.production; - const headers0 = { - Authorization: `Bearer ${this.getToken().access_token}`, - Accept: AuthResponse._pdfContentType, - 'User-Agent': OAuthClient.user_agent, - }; - const req_options = { - method: 'GET', - headers: headers0, - }; - const get_url = `${url0}v3/company/${companyID}/estimate/${estimate0}/pdf`; - const request = https.get(get_url, req_options, (resp) => { - let myPDFBuffer = []; - resp.on('data', (chunk) => { - myPDFBuffer.push(chunk); - }); - resp.on('end', () => { - resolve(Buffer.concat(myPDFBuffer)); - }); - }); - request.on('error', (er) => { - throw er; - }); - request.end(); - }) - .then((authResponse) => { - this.log('info', 'The getEstimatePDF () response is : ', authResponse ? authResponse.toString() : "EMPTY"); - return authResponse; - }) - .catch((e) => { - this.log('error', 'Get getEstimatePDF () threw an exception : ', JSON.stringify(e, null, 2)); - throw e; - }); + return this.fetchPDF('Estimate', estimate_id); }; /** @@ -942,36 +857,7 @@ OAuthClient.prototype.getEstimate = function getEstimate(estimate_id) { */ OAuthClient.prototype.getInvoice = function getInvoice(invoice_id) { - return new Promise((resolve) => { - if (!this.isAccessTokenValid()) throw new Error('OAuth authentication failed! Invalid Token!'); - const invoice0 = parseInt(invoice_id, 10); - if (Number.isNaN(invoice0)) throw new Error('Invalid Invoice Id! Must be a number or number as a string!'); - const companyID = this.getToken().realmId; - if (!companyID) throw new Error('Realm Id missing! Please create a new token using OAuth and try again.'); - const url0 = this.environment === 'sandbox' - ? OAuthClient.environment.sandbox - : OAuthClient.environment.production; - const headers0 = { - Authorization: `Bearer ${this.getToken().access_token}`, - Accept: AuthResponse._jsonContentType, - 'User-Agent': OAuthClient.user_agent, - }; - const request = { - method: 'GET', - url: `${url0}v3/company/${companyID}/invoice/${invoice0}`, - headers: headers0, - }; - resolve(this.getTokenRequest(request)); - }) - .then((authResponse) => { - this.log('info', 'The getInvoice () response is : ', JSON.stringify(authResponse, null, 2)); - const myInvoice = JSON.parse(authResponse.text()); - return myInvoice.Invoice; - }) - .catch((e) => { - this.log('error', 'Get getInvoice () threw an exception : ', JSON.stringify(e, null, 2)); - throw e; - }); + return this.fetchAPI(null, 'Invoice', invoice_id); }; /** @@ -981,47 +867,7 @@ OAuthClient.prototype.getInvoice = function getInvoice(invoice_id) { */ OAuthClient.prototype.getInvoicePDF = function getInvoicePDF(invoice_id) { - return new Promise((resolve) => { - if (!this.isAccessTokenValid()) throw new Error('OAuth authentication failed! Invalid Token!'); - const invoice0 = parseInt(invoice_id, 10); - if (Number.isNaN(invoice0)) throw new Error('Invalid Invoice Id! Must be a number or number as a string!'); - const companyID = this.getToken().realmId; - if (!companyID) throw new Error('Realm Id missing! Please create a new token using OAuth and try again.'); - const url0 = this.environment === 'sandbox' - ? OAuthClient.environment.sandbox - : OAuthClient.environment.production; - const headers0 = { - Authorization: `Bearer ${this.getToken().access_token}`, - Accept: AuthResponse._pdfContentType, - 'User-Agent': OAuthClient.user_agent, - }; - const req_options = { - method: 'GET', - headers: headers0, - }; - const get_url = `${url0}v3/company/${companyID}/invoice/${invoice0}/pdf`; - const request = https.get(get_url, req_options, (resp) => { - let myPDFBuffer = []; - resp.on('data', (chunk) => { - myPDFBuffer.push(chunk); - }); - resp.on('end', () => { - resolve(Buffer.concat(myPDFBuffer)); - }); - }); - request.on('error', (er) => { - throw er; - }); - request.end(); - }) - .then((authResponse) => { - this.log('info', 'The getInvoicePDF () response is : ', authResponse ? authResponse.toString() : "EMPTY"); - return authResponse; - }) - .catch((e) => { - this.log('error', 'Get getInvoicePDF () threw an exception : ', JSON.stringify(e, null, 2)); - throw e; - }); + return this.fetchPDF('Invoice', invoice_id); }; /** @@ -1031,36 +877,7 @@ OAuthClient.prototype.getInvoicePDF = function getInvoicePDF(invoice_id) { */ OAuthClient.prototype.getItem = function getItem(item_id) { - return new Promise((resolve) => { - if (!this.isAccessTokenValid()) throw new Error('OAuth authentication failed! Invalid Token!'); - const item0 = parseInt(item_id, 10); - if (Number.isNaN(item0)) throw new Error('Invalid Item Id! Must be a number or number as a string!'); - const companyID = this.getToken().realmId; - if (!companyID) throw new Error('Realm Id missing! Please create a new token using OAuth and try again.'); - const url0 = this.environment === 'sandbox' - ? OAuthClient.environment.sandbox - : OAuthClient.environment.production; - const headers0 = { - Authorization: `Bearer ${this.getToken().access_token}`, - Accept: AuthResponse._jsonContentType, - 'User-Agent': OAuthClient.user_agent, - }; - const request = { - method: 'GET', - url: `${url0}v3/company/${companyID}/item/${item0}`, - headers: headers0, - }; - resolve(this.getTokenRequest(request)); - }) - .then((authResponse) => { - this.log('info', 'The getItem () response is : ', JSON.stringify(authResponse, null, 2)); - const myItem = JSON.parse(authResponse.text()); - return myItem.Item; - }) - .catch((e) => { - this.log('error', 'Get getItem () threw an exception : ', JSON.stringify(e, null, 2)); - throw e; - }); + return this.fetchAPI(null, 'Item', item_id); }; /** @@ -1070,36 +887,7 @@ OAuthClient.prototype.getItem = function getItem(item_id) { */ OAuthClient.prototype.getPayment = function getPayment(payment_id) { - return new Promise((resolve) => { - if (!this.isAccessTokenValid()) throw new Error('OAuth authentication failed! Invalid Token!'); - const payment0 = parseInt(payment_id, 10); - if (Number.isNaN(payment0)) throw new Error('Invalid Payment Id! Must be a number or number as a string!'); - const companyID = this.getToken().realmId; - if (!companyID) throw new Error('Realm Id missing! Please create a new token using OAuth and try again.'); - const url0 = this.environment === 'sandbox' - ? OAuthClient.environment.sandbox - : OAuthClient.environment.production; - const headers0 = { - Authorization: `Bearer ${this.getToken().access_token}`, - Accept: AuthResponse._jsonContentType, - 'User-Agent': OAuthClient.user_agent, - }; - const request = { - method: 'GET', - url: `${url0}v3/company/${companyID}/payment/${payment0}`, - headers: headers0, - }; - resolve(this.getTokenRequest(request)); - }) - .then((authResponse) => { - this.log('info', 'The getPayment () response is : ', JSON.stringify(authResponse, null, 2)); - const myPayment = JSON.parse(authResponse.text()); - return myPayment.Payment; - }) - .catch((e) => { - this.log('error', 'Get getPayment () threw an exception : ', JSON.stringify(e, null, 2)); - throw e; - }); + return this.fetchAPI(null, 'Payment', payment_id); }; /** @@ -1108,34 +896,7 @@ OAuthClient.prototype.getPayment = function getPayment(payment_id) { */ OAuthClient.prototype.getPreferences = function getPreferences() { - return new Promise((resolve) => { - if (!this.isAccessTokenValid()) throw new Error('OAuth authentication failed! Invalid Token!'); - const companyID = this.getToken().realmId; - if (!companyID) throw new Error('Realm Id missing! Please create a new token using OAuth and try again.'); - const url0 = this.environment === 'sandbox' - ? OAuthClient.environment.sandbox - : OAuthClient.environment.production; - const headers0 = { - Authorization: `Bearer ${this.getToken().access_token}`, - Accept: AuthResponse._jsonContentType, - 'User-Agent': OAuthClient.user_agent, - }; - const request = { - method: 'GET', - url: `${url0}v3/company/${companyID}/preferences`, - headers: headers0, - }; - resolve(this.getTokenRequest(request)); - }) - .then((authResponse) => { - this.log('info', 'The getPreferences () response is : ', JSON.stringify(authResponse, null, 2)); - const myPreferences = JSON.parse(authResponse.text()); - return myPreferences.Preferences; - }) - .catch((e) => { - this.log('error', 'Get getPreferences () threw an exception : ', JSON.stringify(e, null, 2)); - throw e; - }); + return this.fetchAPI(null, 'Preferences'); }; /** @@ -1144,37 +905,8 @@ OAuthClient.prototype.getPreferences = function getPreferences() { * @returns {Promise} QuickBooks TaxAgency */ -OAuthClient.prototype.getTaxAgency = function getTaxAgency(tax_agency_id) { - return new Promise((resolve) => { - if (!this.isAccessTokenValid()) throw new Error('OAuth authentication failed! Invalid Token!'); - const taxagency0 = parseInt(tax_agency_id, 10); - if (Number.isNaN(taxagency0)) throw new Error('Invalid TaxAgency Id! Must be a number or number as a string!'); - const companyID = this.getToken().realmId; - if (!companyID) throw new Error('Realm Id missing! Please create a new token using OAuth and try again.'); - const url0 = this.environment === 'sandbox' - ? OAuthClient.environment.sandbox - : OAuthClient.environment.production; - const headers0 = { - Authorization: `Bearer ${this.getToken().access_token}`, - Accept: AuthResponse._jsonContentType, - 'User-Agent': OAuthClient.user_agent, - }; - const request = { - method: 'GET', - url: `${url0}v3/company/${companyID}/taxagency/${taxagency0}`, - headers: headers0, - }; - resolve(this.getTokenRequest(request)); - }) - .then((authResponse) => { - this.log('info', 'The getTaxAgency () response is : ', JSON.stringify(authResponse, null, 2)); - const myTaxAgency = JSON.parse(authResponse.text()); - return myTaxAgency.TaxAgency; - }) - .catch((e) => { - this.log('error', 'Get getTaxAgency () threw an exception : ', JSON.stringify(e, null, 2)); - throw e; - }); +OAuthClient.prototype.getTaxAgency = function getTaxAgency(tax_agency_id) { // check + return this.fetchAPI(null, 'TaxAgency', tax_agency_id); }; /** @@ -1184,69 +916,7 @@ OAuthClient.prototype.getTaxAgency = function getTaxAgency(tax_agency_id) { */ OAuthClient.prototype.getVendor = function getVendor(vendor_id) { - return new Promise((resolve) => { - if (!this.isAccessTokenValid()) throw new Error('OAuth authentication failed! Invalid Token!'); - const vendor0 = parseInt(vendor_id, 10); - if (Number.isNaN(vendor0)) throw new Error('Invalid Vendor Id! Must be a number or number as a string!'); - const companyID = this.getToken().realmId; - if (!companyID) throw new Error('Realm Id missing! Please create a new token using OAuth and try again.'); - const url0 = this.environment === 'sandbox' - ? OAuthClient.environment.sandbox - : OAuthClient.environment.production; - const headers0 = { - Authorization: `Bearer ${this.getToken().access_token}`, - Accept: AuthResponse._jsonContentType, - 'User-Agent': OAuthClient.user_agent, - }; - const request = { - method: 'GET', - url: `${url0}v3/company/${companyID}/vendor/${vendor0}`, - headers: headers0, - }; - resolve(this.getTokenRequest(request)); - }) - .then((authResponse) => { - this.log('info', 'The getVendor () response is : ', JSON.stringify(authResponse, null, 2)); - const myVendor = JSON.parse(authResponse.text()); - return myVendor.Vendor; - }) - .catch((e) => { - this.log('error', 'Get getVendor () threw an exception : ', JSON.stringify(e, null, 2)); - throw e; - }); + return this.fetchAPI(null, 'Vendor', vendor_id); }; -// OAuthClient.prototype.getCompanyInfo = function getCompanyInfo() { -// return new Promise((resolve) => { -// const request = { -// url: -// this.environment === 'sandbox' -// ? OAuthClient.userinfo_endpoint_sandbox -// : OAuthClient.userinfo_endpoint_production, -// method: 'GET', -// headers: { -// Authorization: `Bearer ${this.token.access_token}`, -// Accept: AuthResponse._jsonContentType, -// 'User-Agent': OAuthClient.user_agent, -// }, -// }; - -// resolve(this.getTokenRequest(request)); -// }) -// .then((res) => { -// const authResponse = res.json ? res : null; -// this.log( -// 'info', -// 'The Get User Info () response is : ', -// JSON.stringify(authResponse, null, 2), -// ); -// return authResponse; -// }) -// .catch((e) => { -// this.log('error', 'Get User Info () threw an exception : ', JSON.stringify(e, null, 2)); -// throw e; -// }); -// }; - - module.exports = OAuthClient; From 455994d6b977b0585d6cc6c893fde433c26dde7b Mon Sep 17 00:00:00 2001 From: Purujit Srinivasan Date: Fri, 30 Apr 2021 14:16:16 +0530 Subject: [PATCH 3/4] create common entities --- src/OAuthClient.js | 244 ++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 242 insertions(+), 2 deletions(-) diff --git a/src/OAuthClient.js b/src/OAuthClient.js index 6f5748a0..82d3a4ff 100644 --- a/src/OAuthClient.js +++ b/src/OAuthClient.js @@ -696,7 +696,7 @@ OAuthClient.prototype.fetchAPI = function fetchAPI(options0, entity0, id0) { if (options0.method.toUpperCase()!=='GET') { request.body = options0.body; } - if (typeof(options0.headers)==='object') { + if (options0.headers && typeof(options0.headers)==='object') { Object.assign(request.headers, options0.headers); } } @@ -770,15 +770,253 @@ OAuthClient.prototype.fetchAPI = function fetchAPI(options0, entity0, id0) { return authResponse; }) .catch((e) => { - this.log('error', `Get get${name0}PDF () threw an exception : `, JSON.stringify(e, null, 2)); + this.log('error', `Get ${name0} PDF () threw an exception : `, JSON.stringify(e, null, 2)); throw e; }); } /* CREATE ENTITIES */ +/** + * Create quickbooks Account + * https://developer.intuit.com/app/developer/qbo/docs/api/accounting/most-commonly-used/account#create-an-account + * + * Refer to above link for exact fields and description + * @param {object} accountObj - Object to create: Account + * @param {string} accountObj.Name - Unique name for Account + * @param {string} accountObj.AccountType - Account Type Enum i.e. must be one of the Account types, default 'Accounts Receivable' + * @returns {Promise} QuickBooks Account created + */ + + OAuthClient.prototype.createAccount = function createAccount(accountObj) { + if (!accountObj || typeof(accountObj)!=='object') return new Error('Cannot create empty object!'); + return this.fetchAPI({ + method: 'POST', + headers: { + 'Content-Type': 'application/json', + }, + body: JSON.stringify(accountObj), + }, 'Account'); +}; + +/** + * Create quickbooks Bill + * https://developer.intuit.com/app/developer/qbo/docs/api/accounting/most-commonly-used/bill#create-a-bill + * + * Refer to above link for exact fields and description + * @param {object} billObj - Object to create: Bill + * @param {object} billObj.Line - Line must be a JSON for Bill + * @param {string} billObj.Line.DetailType - Set to 'AccountBasedExpenseLineDetail' + * @param {number} billObj.Line.Amount - Amount payable for this Bill + * @param {object} billObj.Line.AccountBasedExpenseLineDetail - Account details + * @param {object} billObj.Line.AccountBasedExpenseLineDetail.AccountRef - Account associated with this Bill + * @param {string} billObj.Line.AccountBasedExpenseLineDetail.AccountRef.value - String Id of Account + * @param {object} billObj.VendorRef - Vendor associated with this Bill + * @param {string} billObj.VendorRef.value - String Id of Vendor associated with this Bill + * @param {object} billObj.CurrencyRef - Currency Ref string + * @param {string} billObj.CurrencyRef.value - E.g. 'USD' + * @returns {Promise} QuickBooks Bill created + */ + +OAuthClient.prototype.createBill = function createBill(billObj) { + if (!billObj || typeof(billObj)!=='object') return new Error('Cannot create empty object!'); + return this.fetchAPI({ + method: 'POST', + headers: { + 'Content-Type': 'application/json', + }, + body: JSON.stringify(billObj), + }, 'Bill'); +}; + +/** + * Create quickbooks Customer + * https://developer.intuit.com/app/developer/qbo/docs/api/accounting/most-commonly-used/customer#create-a-customer + * + * DisplayName OR at least one of Title, GivenName, MiddleName, FamilyName, or Suffix must be present + * The equivalent Name must be UNIQUE + * Refer to above link for exact fields and description + * @param {object} customerObj - Object to create: Customer + * @returns {Promise} QuickBooks Customer created + */ + +OAuthClient.prototype.createCustomer = function createCustomer(customerObj) { + if (!customerObj || typeof(customerObj)!=='object') return new Error('Cannot create empty object!'); + return this.fetchAPI({ + method: 'POST', + headers: { + 'Content-Type': 'application/json', + }, + body: JSON.stringify(customerObj), + }, 'Customer'); +}; + +/** + * Create quickbooks Employee + * https://developer.intuit.com/app/developer/qbo/docs/api/accounting/most-commonly-used/employee#create-an-employee + * + * Refer to above link for exact fields and description + * @param {object} employeeObj - Object to create: Employee + * @returns {Promise} QuickBooks Employee created + */ + +OAuthClient.prototype.createEmployee = function createEmployee(employeeObj) { + if (!employeeObj || typeof(employeeObj)!=='object') return new Error('Cannot create empty object!'); + return this.fetchAPI({ + method: 'POST', + headers: { + 'Content-Type': 'application/json', + }, + body: JSON.stringify(employeeObj), + }, 'Employee'); +}; + +/** + * Create quickbooks Estimate + * https://developer.intuit.com/app/developer/qbo/docs/api/accounting/most-commonly-used/estimate#create-an-estimate + * + * Refer to above link for exact fields and description + * @param {object} estimateObj - Object to create: Estimate + * @param {object} estimateObj.Line - Line details + * @param {string} estimateObj.Line.DetailType - Type of Line + * @param {object} estimateObj.CustomerRef - Customer associated with this Estimate + * @param {string} estimateObj.CustomerRef.value - String Id of Customer associated with this Estimate + * @param {object} estimateObj.CurrencyRef - Currency Ref string + * @param {string} estimateObj.CurrencyRef.value - E.g. 'USD' + * @returns {Promise} QuickBooks Estimate created + */ + +OAuthClient.prototype.createEstimate = function createEstimate(estimateObj) { + if (!estimateObj || typeof(estimateObj)!=='object') return new Error('Cannot create empty object!'); + return this.fetchAPI({ + method: 'POST', + headers: { + 'Content-Type': 'application/json', + }, + body: JSON.stringify(estimateObj), + }, 'Estimate'); +}; + +/** + * Create quickbooks Invoice + * https://developer.intuit.com/app/developer/qbo/docs/api/accounting/most-commonly-used/invoice#create-an-invoice + * + * Refer to above link for exact fields and description + * @param {object} invoiceObj - Object to create: Invoice + * @param {object} invoiceObj.Line - Line details + * @param {string} invoiceObj.Line.DetailType - Type of Line + * @param {object} invoiceObj.CustomerRef - Customer associated with this Invoice + * @param {string} invoiceObj.CustomerRef.value - String Id of Customer associated with this Invoice + * @param {object} invoiceObj.CurrencyRef - Currency Ref string + * @param {string} invoiceObj.CurrencyRef.value - E.g. 'USD' + * @returns {Promise} QuickBooks Invoice created + */ + +OAuthClient.prototype.createInvoice = function createInvoice(invoiceObj) { + if (!invoiceObj || typeof(invoiceObj)!=='object') return new Error('Cannot create empty object!'); + return this.fetchAPI({ + method: 'POST', + headers: { + 'Content-Type': 'application/json', + }, + body: JSON.stringify(invoiceObj), + }, 'Invoice'); +}; + +/** + * Create quickbooks Item + * https://developer.intuit.com/app/developer/qbo/docs/api/accounting/most-commonly-used/item#create-an-item + * + * Refer to above link for exact fields and description + * @param {object} itemObj - Object to create: Item + * @returns {Promise} QuickBooks Item created + */ + +OAuthClient.prototype.createItem = function createItem(itemObj) { + if (!itemObj || typeof(itemObj)!=='object') return new Error('Cannot create empty object!'); + return this.fetchAPI({ + method: 'POST', + headers: { + 'Content-Type': 'application/json', + }, + body: JSON.stringify(itemObj), + }, 'Item'); +}; + +/** + * Create quickbooks Payment + * https://developer.intuit.com/app/developer/qbo/docs/api/accounting/most-commonly-used/payment#create-a-payment + * + * Refer to above link for exact fields and description + * @param {object} paymentObj - Object to create: Payment + * @param {number} paymentObj.TotalAmt - Total amount of Payment + * @param {object} paymentObj.CustomerRef - Customer associated with this Payment + * @param {string} paymentObj.CustomerRef.value - String Id of Customer associated with this Payment + * @param {object} paymentObj.CurrencyRef - Currency Ref string + * @param {string} paymentObj.CurrencyRef.value - E.g. 'USD' + * @returns {Promise} QuickBooks Payment created + */ + +OAuthClient.prototype.createPayment = function createPayment(paymentObj) { + if (!paymentObj || typeof(paymentObj)!=='object') return new Error('Cannot create empty object!'); + return this.fetchAPI({ + method: 'POST', + headers: { + 'Content-Type': 'application/json', + }, + body: JSON.stringify(paymentObj), + }, 'Payment'); +}; + +/** + * Create quickbooks TaxAgency + * https://developer.intuit.com/app/developer/qbo/docs/api/accounting/most-commonly-used/taxagency#create-a-taxagency + * + * Refer to above link for exact fields and description + * @param {object} tax_agencyObj - Object to create: TaxAgency + * @param {string} tax_agencyObj.DisplayName - Name of TaxAgency + * @returns {Promise} QuickBooks TaxAgency created + */ + +OAuthClient.prototype.createTaxAgency = function createTaxAgency(tax_agencyObj) { // check + if (!tax_agencyObj || typeof(tax_agencyObj)!=='object') return new Error('Cannot create empty object!'); + return this.fetchAPI({ + method: 'POST', + headers: { + 'Content-Type': 'application/json', + }, + body: JSON.stringify(tax_agencyObj), + }, 'TaxAgency'); +}; + +/** + * Create quickbooks Vendor + * https://developer.intuit.com/app/developer/qbo/docs/api/accounting/most-commonly-used/vendor#create-a-vendor + * + * DisplayName OR at least one of Title, GivenName, MiddleName, FamilyName, or Suffix must be present + * The equivalent Name must be UNIQUE + * Refer to above link for exact fields and description + * @param {object} vendorObj - Object to create: Vendor + * @returns {Promise} QuickBooks Vendor created + */ + + OAuthClient.prototype.createVendor = function createVendor(vendorObj) { + if (!vendorObj || typeof(vendorObj)!=='object') return new Error('Cannot create empty object!'); + return this.fetchAPI({ + method: 'POST', + headers: { + 'Content-Type': 'application/json', + }, + body: JSON.stringify(vendorObj), + }, 'Vendor'); +}; + +/* END CREATE ENTITIES */ + /* DELETE ENTITIES */ +/* END DELETE ENTITIES */ + /* GET ENTITIES */ /** @@ -919,4 +1157,6 @@ OAuthClient.prototype.getTaxAgency = function getTaxAgency(tax_agency_id) { // c return this.fetchAPI(null, 'Vendor', vendor_id); }; +/* END GET ENTITIES */ + module.exports = OAuthClient; From d5bc047c874e6a79eed17acb10cfc58e6cf487be Mon Sep 17 00:00:00 2001 From: Purujit Srinivasan Date: Fri, 30 Apr 2021 15:03:40 +0530 Subject: [PATCH 4/4] fix fetch throw error --- src/OAuthClient.js | 28 +++++++++++++++------------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/src/OAuthClient.js b/src/OAuthClient.js index 82d3a4ff..13c5f0ac 100644 --- a/src/OAuthClient.js +++ b/src/OAuthClient.js @@ -33,10 +33,10 @@ const winston = require('winston'); const path = require('path'); const fs = require('fs'); const jwt = require('jsonwebtoken'); +const https = require('https'); const AuthResponse = require('./response/AuthResponse'); const version = require('../package.json'); const Token = require('./access-token/Token'); -const https = require('https'); /** * @constructor @@ -664,11 +664,12 @@ OAuthClient.prototype.log = function log(level, message, messageData) { */ OAuthClient.prototype.fetchAPI = function fetchAPI(options0, entity0, id0) { - if (!entity0 || typeof(entity0)!=='string' || !entity0.slice(0,50).trim()) throw new Error('Invalid Quickbooks Entity!'); - entity0 = entity0.slice(0,50).trim(); - const name0 = entity0[0].toUpperCase() + entity0.slice(1); - entity0 = entity0.toLowerCase(); + let name0; return new Promise((resolve) => { + if (!entity0 || typeof(entity0)!=='string' || !entity0.slice(0,50).trim()) throw new Error('Invalid Quickbooks Entity!'); + entity0 = entity0.slice(0,50).trim(); + name0 = entity0[0].toUpperCase() + entity0.slice(1); + entity0 = entity0.toLowerCase(); if (!this.isAccessTokenValid()) throw new Error('OAuth authentication failed! Invalid Token!'); const entity_id = parseInt(id0, 10); if (id0 && Number.isNaN(entity_id)) throw new Error(`Invalid ${name0} Id! Must be a number or number as a string!`); @@ -703,7 +704,7 @@ OAuthClient.prototype.fetchAPI = function fetchAPI(options0, entity0, id0) { resolve(this.getTokenRequest(request)); }) .then((authResponse) => { - this.log('info', `The fetch on ${name0} () response is : `, JSON.stringify(authResponse, null, 2)); + this.log('info', `The fetch on ${entity0} () response is : `, JSON.stringify(authResponse, null, 2)); let myEntity; if (authResponse.headers()['content-type'].indexOf('json')>-1) { myEntity = JSON.parse(authResponse.text())[name0]; @@ -714,7 +715,7 @@ OAuthClient.prototype.fetchAPI = function fetchAPI(options0, entity0, id0) { return myEntity; }) .catch((e) => { - this.log('error', `The fetch on ${name0} () threw an exception : `, JSON.stringify(e, null, 2)); + this.log('error', `The fetch on ${entity0} () threw an exception : `, JSON.stringify(e, null, 2)); throw e; }); } @@ -727,11 +728,12 @@ OAuthClient.prototype.fetchAPI = function fetchAPI(options0, entity0, id0) { */ OAuthClient.prototype.fetchPDF = function fetchPDF(entity0, id0) { - if (!entity0 || typeof(entity0)!=='string' || !entity0.slice(0,50).trim()) throw new Error('Invalid Quickbooks Entity!'); - entity0 = entity0.slice(0,50).trim(); - const name0 = entity0[0].toUpperCase() + entity0.slice(1); - entity0 = entity0.toLowerCase(); + let name0; return new Promise((resolve) => { + if (!entity0 || typeof(entity0)!=='string' || !entity0.slice(0,50).trim()) throw new Error('Invalid Quickbooks Entity!'); + entity0 = entity0.slice(0,50).trim(); + name0 = entity0[0].toUpperCase() + entity0.slice(1); + entity0 = entity0.toLowerCase(); if (!this.isAccessTokenValid()) throw new Error('OAuth authentication failed! Invalid Token!'); const entity_id = parseInt(id0, 10); if (Number.isNaN(entity_id)) throw new Error(`Invalid ${name0} Id! Must be a number or number as a string!`); @@ -766,11 +768,11 @@ OAuthClient.prototype.fetchAPI = function fetchAPI(options0, entity0, id0) { request.end(); }) .then((authResponse) => { - this.log('info', `The get${name0}PDF () response is : `, authResponse ? authResponse.toString() : "EMPTY"); + this.log('info', `The get${entity0}PDF () response is : `, authResponse ? authResponse.toString() : "EMPTY"); return authResponse; }) .catch((e) => { - this.log('error', `Get ${name0} PDF () threw an exception : `, JSON.stringify(e, null, 2)); + this.log('error', `Get ${entity0} PDF () threw an exception : `, JSON.stringify(e, null, 2)); throw e; }); }