xero icon indicating copy to clipboard operation
xero copied to clipboard

Added ability to GET, PUT and POST to the Xero Payroll API

Open gazzenger opened this issue 8 years ago • 20 comments

Thanks so much for this fantastic module.

I made a minor change so that a user can now also perform GET, POST and PUT commands to the Payroll API on Xero. This means users can now handle timesheets, payitems as well as many other features.

I've left support for the command xero.call, however I've added the following commands, xero.callAccounting() and xero.callPayroll()

These commands work the same way as xero.call, but allow distinguishing between Accounting API (which is what the current code does), and the Payroll API.

An example to get a list of timesheets would be, xero.callPayroll('GET', "/Timesheets", null, function (err, json) {...})

Let me know your thoughts on the additions,

Kind Regards, Gary

gazzenger avatar Oct 26 '16 08:10 gazzenger

Thanks for doing this! I am half way through writing something to achieve the same thing and thought i should look! lol I had a look at your update and am wondering if there is there a reason you don't just just switch the XERO_API_URL value based on the 'path' received? That would save having to specify which endpoint you want to call and would be seemless (?). What you think?

presolve avatar Nov 23 '16 06:11 presolve

Heya, The reason I haven't switched the XERO_API_URL on the value based on a path, was it simple when specifying either the Accounting or Payroll APIs. But I wanted to keep it backwards compatible with what you've written. I'm really happy for anything either way :)

gazzenger avatar Nov 23 '16 06:11 gazzenger

Yep I think that looks good.

On Wed, Nov 23, 2016 at 2:55 PM, presolve [email protected] wrote:

Something like...

`var paths = { "accounting": ["/Contacts"], "payroll": ["/Employees"] }

function contains(a, obj) { for (var i = 0; i < a.length; i++) { if (a[i] === obj) { return true; } } return false; }

function Xero(key, secret, rsa_key, showXmlAttributes, customHeaders, version) { this.key = key; this.secret = secret;

this.parser = new xml2js.Parser({explicitArray: false, ignoreAttrs: showXmlAttributes !== undefined ? (showXmlAttributes ? false : true) : true, async: true});

this.oa = new oauth.OAuth(null, null, key, secret, '1.0', null, "PLAINTEXT", null, customHeaders); this.oa._signatureMethod = "RSA-SHA1" this.oa._createSignature = function(signatureBase, tokenSecret) { return crypto.createSign("RSA-SHA1").update(signatureBase).sign(rsa_key, output_format = "base64"); }

}

Xero.prototype.call = function(method, path, body, callback) { var self = this;

XERO_API_URL = XERO_BASE_URL + ((contains(paths.payroll,path)) ? ('/payroll.xro/1.0') : ('/api.xro/2.0'));

var post_body = null;`

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/thallium205/xero/pull/23#issuecomment-262444989, or mute the thread https://github.com/notifications/unsubscribe-auth/AKDdNXIJ9TV6iVyJt2SCGhWmiplxDGgnks5rA-NMgaJpZM4Kg5E6 .

Gary T. Namestnik

Mobile: +61 (0) 4 1537 0736

gazzenger avatar Nov 23 '16 07:11 gazzenger

I'm a git n00b... sorry... I've made this patch which is working great for me now. It's dynamic and works for both US and AUS payroll paths. Any chance you could put this forward?

index.txt

.. just rename to index.js (not allowed to upload a .js file sorry)

presolve avatar Nov 23 '16 07:11 presolve

Same here, I'll have a look at adding a new commit to my branch so hopefully you'll see it in the pull request. I might do it later this afternoon if that's alright.

gazzenger avatar Nov 23 '16 07:11 gazzenger

Hey I've been looking over the code, and I noticed that you've got an array explicitly listing the URIs for using the payroll API,

var paths = {
    'payroll': [
        '/Employees',
        '/Leaveapplications',
        '/Payitems',
        ...

And then to determine if the user intends to use the payroll or accounting API, you check if the path is contained in the array paths.payroll.

XERO_API_URL = XERO_BASE_URL + ((contains(paths.payroll,path)) ? ('/payroll.xro/1.0') : ('/api.xro/2.0'));

Although this seems like a good method, I can spot that at least one URI has the same name in both the accounting and payroll API.

So you can have endpoints such as these:

https://api.xero.com/payroll.xro/1.0/employees 
https://api.xero.com/api.xro/2.0/employees

I'm thinking the best way to avoid this issue, could be to add an extra parameter when calling the xero module, and specify which API to use, maybe set the default to be accounting.

xero.call(method, **apiType**, path, body, callback)

Let me know your thoughts

gazzenger avatar Nov 24 '16 01:11 gazzenger

Yep... I literally only 5 mins ago came across that! lol It's a bummer cos the Employees path is the ONLY one that exists in both endpoints and 99% of the time it's not even used (most people use the Employees Payroll endpoint). I originally started down the "mode" switch path so I'll just redo it with the switch instead. :) Thanks for reviewing!!

presolve avatar Nov 24 '16 02:11 presolve

i'll learn git so i can push a patch i swear... but here's the update... now it'll work for all endpoints and you just specify the 'endpoint'.

Xero.prototype.call = function(method, endpoint, path, body, callback) {
    var self = this;
    switch (endpoint) {
        case 'accounting':
            endpoint = '/api.xro/2.0';
            break;
        case 'payroll':
            endpoint = '/payroll.xro/1.0';
            break;
        case 'assets':
            endpoint = '/assets.xro/1.0';
            break;
        case 'files':
            endpoint = '/files.xro/1.0';
            break;
        default:
            endpoint = '/api.xro/2.0';
    }
    XERO_API_URL = XERO_BASE_URL + endpoint;

So when you call it now you just

xero.call('GET', 'payroll', '/Employees', null, function(err, xeroEmployees) {...

What do you think? (complete file attached... just rename to index.js... :) index.txt

presolve avatar Nov 24 '16 02:11 presolve

I love it, what're the assets and files endpoints used for?

gazzenger avatar Nov 24 '16 02:11 gazzenger

Uploading files and such! :P https://developer.xero.com/documentation/files-api/files/

I think i'll start using this feature now that it's working! :D

presolve avatar Nov 24 '16 02:11 presolve

Do you want me to do the updates in my branch?

gazzenger avatar Nov 24 '16 03:11 gazzenger

if you wouldn't mind... that would be great. :)

presolve avatar Nov 24 '16 03:11 presolve

Whenever we feel ready I can get this change published to npm.

On Wed, Nov 23, 2016 at 7:20 PM, presolve [email protected] wrote:

if you wouldn't mind... that would be great. :)

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/thallium205/xero/pull/23#issuecomment-262681507, or mute the thread https://github.com/notifications/unsubscribe-auth/AA1RgPkGgWZ3mGJxTCtom1tqaZTDSTaYks5rBQJ1gaJpZM4Kg5E6 .

thallium205 avatar Nov 24 '16 04:11 thallium205

Sooner the better! I'm using it now and it's working great. :) Thanks heaps!!!

presolve avatar Nov 24 '16 04:11 presolve

Sorry, I was out at lunch, let me update it in my branch (I think it'll automatically go through with the pull request)

gazzenger avatar Nov 24 '16 05:11 gazzenger

Alrighty, it should all be updated now. See what you think

gazzenger avatar Nov 24 '16 05:11 gazzenger

I've given the new module a whirl, and it works well

gazzenger avatar Nov 24 '16 05:11 gazzenger

Same! Thanks heaps for your help @gazzenger And thanks @thallium205 for the module!!

presolve avatar Nov 24 '16 06:11 presolve

@thallium205 The pull request is ready now

gazzenger avatar Nov 24 '16 06:11 gazzenger

The branch has got some conflicts and can't be merged. If you resolve I'll merge. Thanks!

thallium205 avatar Oct 03 '19 04:10 thallium205