Skip to content

Commit

Permalink
added reports to the sample app, not yet completed
Browse files Browse the repository at this point in the history
  • Loading branch information
Jordan Walsh committed Mar 15, 2017
1 parent 7e612c3 commit 673c805
Show file tree
Hide file tree
Showing 7 changed files with 264 additions and 52 deletions.
2 changes: 1 addition & 1 deletion lib/application.js
Expand Up @@ -267,7 +267,7 @@ Object.assign(Application.prototype, {
function getResource(offset) {
var endPointUrl = options.api === 'payroll' ? self.options.payrollAPIEndPointUrl : self.options.coreAPIEndPointUrl;
var url = self.options.baseUrl + endPointUrl + path;
var params = {};
var params = options.params || {};
if (offset) {
params[options.pager.paramName || 'page'] = offset;
if (options.other) {
Expand Down
50 changes: 18 additions & 32 deletions lib/entities/accounting/report.js
Expand Up @@ -42,46 +42,32 @@ var Report = Entity.extend(ReportSchema, {
var self = this;
Object.assign(self, _.omit(obj, 'Rows', 'Cells'));


if (hasMoreRows(obj)) {
logger.debug("Top Level");
obj.Rows.Row.forEach(function(thisRow) {

if (hasMoreRows(thisRow)) {
logger.debug("2nd Level");
thisRow.Rows.Row.forEach(function(anotherRow) {

if (hasMoreRows(anotherRow)) {
logger.debug("3rd Level");
anotherRow.Rows.Row.forEach(function(lastRow) {

if (hasMoreRows(lastRow)) {
logger.debug("You're kidding");
}

});
}

//Loop through the rows to find the next level down
obj.Rows.Row.forEach(function(level1Row) {

if (hasMoreRows(level1Row)) {
var level2RowsArray = [];
level1Row.Rows.Row.forEach(function(level2row) {
level2row.Cells ? level2row.Cells = extractCells(level2row) : false;
level2RowsArray.push(level2row);
});
level1Row.Rows = level2RowsArray;
}

level1Row.Cells ? level1Row.Cells = extractCells(level1Row) : false;
self.Rows.push(level1Row);
});
}


if (obj.Rows) {
obj.Rows.Row.forEach(function(row) {
row.Cells ? row.Cells = extractCells(row) : false;
self.Rows.push(row);
});
} else {
//No more rows, but we should check for cells in this row
if (obj.Rows && obj.Rows.Row && obj.Rows.Row.Cells && obj.Rows.Row.Cells.Cell && obj.Rows.Row.Cells.Cell.length > 0) {
obj.Rows.Row.Cells = extractCells(obj.Rows.Row);
self.Rows.push(obj.Rows.Row);
}
}

return this;

function extractRows(obj) {

}

function hasMoreRows(obj) {
return obj.Rows && obj.Rows.Row && obj.Rows.Row.length >= 0;
}
Expand All @@ -100,4 +86,4 @@ var Report = Entity.extend(ReportSchema, {
});

module.exports = Report;
module.exports.ItemSchema = ReportSchema;
module.exports.ReportSchema = ReportSchema;
51 changes: 51 additions & 0 deletions sample_app/index.js
Expand Up @@ -436,6 +436,57 @@ app.get('/items', function(req, res) {
})
});

app.get('/reports', function(req, res) {
authorizedOperation(req, res, '/reports', function(xeroClient) {

var reportkeys = {
'1': 'BalanceSheet',
'2': 'TrialBalance',
'3': 'ProfitAndLoss',
'4': 'BankStatement',
'5': 'BudgetSummary',
'6': 'ExecutiveSummary',
'7': 'BankSummary',
'8': 'AgedReceivablesByContact',
'9': 'AgedPayablesByContact'
};

var report = req.query ? req.query.r : null;

if (reportkeys[report]) {
var selectedReport = reportkeys[report];

var data = {
active: {}
};

data.active[selectedReport.toLowerCase()] = true;

xeroClient.core.reports.generateReport({
id: selectedReport
})
.then(function(report) {
data.report = report;
res.render('reports', data);
})
.catch(function(err) {
handleErr(err, req, res, 'reports');
})


} else {
res.render('index', {
error: {
message: "Report not found"
},
active: {
overview: true
}
});
}
})
});

app.use('/createinvoice', function(req, res) {
if (req.method == 'GET') {
return res.render('createinvoice');
Expand Down
6 changes: 6 additions & 0 deletions sample_app/views/index.handlebars
@@ -1,3 +1,9 @@
{{#if error}}
<div class="alert alert-danger">
<strong>Error:</strong> {{error.message}}
</div>
{{/if}}

<h2>Xero Node.js - Sample App</h2>
<p>An API wrapper for the Xero API (<a href="http://developer.xero.com">http://developer.xero.com</a>).</p>
<p>Supports all three applications types:</p>
Expand Down
12 changes: 12 additions & 0 deletions sample_app/views/partials/nav.handlebars
Expand Up @@ -15,6 +15,18 @@
<li class="{{#if active.trackingcategories}}active{{/if}}"><a href="/trackingcategories">List Tracking Categories</a></li>
<li class="{{#if active.users}}active{{/if}}"><a href="/users">List Users</a></li>
</ul>
<h5>Reports</h5>
<ul class="nav nav-sidebar">
<li class="{{#if active.balancesheet}}active{{/if}}"><a href="/reports?r=1">Balance Sheet Report</a></li>
<li class="{{#if active.trialbalance}}active{{/if}}"><a href="/reports?r=2">Trial Balance Report</a></li>
<li class="{{#if active.profitandloss}}active{{/if}}"><a href="/reports?r=3">Profit and Loss Report</a></li>
<li class="{{#if active.bankstatement}}active{{/if}}"><a href="/reports?r=4">Bank Statement Report</a></li>
<li class="{{#if active.budgetsummary}}active{{/if}}"><a href="/reports?r=5">Budget Summary Report</a></li>
<li class="{{#if active.executivesummary}}active{{/if}}"><a href="/reports?r=6">Executive Summary Report</a></li>
<li class="{{#if active.banksummary}}active{{/if}}"><a href="/reports?r=7">Bank Summary Report</a></li>
<li class="{{#if active.agedreceivablesbycontact}}active{{/if}}"><a href="/reports?r=8">Aged Receivables Report</a></li>
<li class="{{#if active.agedpayablesbycontact}}active{{/if}}"><a href="/reports?r=9">Aged Payables Report</a></li>
</ul>
<h5>Payroll API - AU</h5>
<ul class="nav nav-sidebar">
<li class="{{#if active.employees}}active{{/if}}"><a href="/employees">List employees</a></li>
Expand Down
1 change: 1 addition & 0 deletions sample_app/views/reports.handlebars
@@ -0,0 +1 @@
<h3>{{report.ReportName}}</h3>
194 changes: 175 additions & 19 deletions test/accountingtests.js
Expand Up @@ -217,33 +217,70 @@ describe('get access for public or partner application', function() {

describe('reporting tests', function() {
this.timeout(10000);
it('generates a Balance Sheet', function(done) {
it('Generates a Balance Sheet Report', function(done) {
currentApp.core.reports.generateReport({ id: 'BalanceSheet' })
.then(function(report) {
expect(report.ReportType).to.equal('BalanceSheet');
expect(report.ReportName).to.equal('Balance Sheet');
expect(report.Rows).to.have.length.greaterThan(0);
report.Rows.forEach(function(row) {
console.log(row);
expect(row.RowType).to.be.oneOf(['Header', 'Section', 'Row', 'SummaryRow']);

//Each row can have some cells, each cell should have some data.
if (row.Cells) {
expect(row.Cells).to.have.length.greaterThan(0);
row.Cells.forEach(function(cell) {
//each cell can either be a string or an object
expect(cell).to.not.equal(undefined);
expect(cell).to.satisfy(function(c) { return typeof c === "string" || typeof c === "object" });
});
}

validateRows(report.Rows);

if (row.Rows) {
//This row has nested rows
}
done();
})
.catch(function(err) {
console.log(err);
done(wrapError(err));
})

});
});

it('Generates a Bank Statement Report', function(done) {
currentApp.core.reports.generateReport({
id: 'BankStatement',
params: {
bankAccountID: '13918178-849a-4823-9a31-57b7eac713d7'
}
})
.then(function(report) {
expect(report.ReportType).to.equal('BankStatement');
expect(report.ReportName).to.equal('Bank Statement');

validateRows(report.Rows);

done();
})
.catch(function(err) {
console.log(err);
done(wrapError(err));
})

});

it('Generates a Trial Balance Report', function(done) {
currentApp.core.reports.generateReport({
id: 'TrialBalance'
})
.then(function(report) {
expect(report.ReportType).to.equal('TrialBalance');
expect(report.ReportName).to.equal('Trial Balance');
validateRows(report.Rows);
done();
})
.catch(function(err) {
console.log(err);
done(wrapError(err));
})

});

it('Generates a Profit and Loss Report', function(done) {
currentApp.core.reports.generateReport({
id: 'ProfitAndLoss'
})
.then(function(report) {
expect(report.ReportType).to.equal('ProfitAndLoss');
expect(report.ReportName).to.equal('Profit and Loss');
validateRows(report.Rows);
done();
})
.catch(function(err) {
Expand All @@ -253,6 +290,125 @@ describe('reporting tests', function() {

});

it('Generates a Budget Summary Report', function(done) {
currentApp.core.reports.generateReport({
id: 'BudgetSummary'
})
.then(function(report) {
expect(report.ReportType).to.equal('BudgetSummary');
expect(report.ReportName).to.equal('Budget Summary');
validateRows(report.Rows);
done();
})
.catch(function(err) {
console.log(err);
done(wrapError(err));
})

});

it('Generates an Executive Summary Report', function(done) {
currentApp.core.reports.generateReport({
id: 'ExecutiveSummary'
})
.then(function(report) {
expect(report.ReportType).to.equal('ExecutiveSummary');
expect(report.ReportName).to.equal('Executive Summary');
validateRows(report.Rows);
done();
})
.catch(function(err) {
console.log(err);
done(wrapError(err));
})

});

it('Generates a Bank Summary Report', function(done) {
currentApp.core.reports.generateReport({
id: 'BankSummary'
})
.then(function(report) {
expect(report.ReportType).to.equal('BankSummary');
expect(report.ReportName).to.equal('Bank Summary');
validateRows(report.Rows);
done();
})
.catch(function(err) {
console.log(err);
done(wrapError(err));
})

});

it('Generates an Aged Receivables Report', function(done) {
currentApp.core.reports.generateReport({
id: 'AgedReceivablesByContact',
params: {
contactId: '58697449-85ef-46ae-83fc-6a9446f037fb'
}
})
.then(function(report) {
expect(report.ReportType).to.equal('AgedReceivablesByContact');
expect(report.ReportName).to.equal('Aged Receivables By Contact');
validateRows(report.Rows);
done();
})
.catch(function(err) {
console.log(err);
done(wrapError(err));
})

});

it('Generates an Aged Payables Report', function(done) {
currentApp.core.reports.generateReport({
id: 'AgedPayablesByContact',
params: {
contactId: '58697449-85ef-46ae-83fc-6a9446f037fb'
}
})
.then(function(report) {
expect(report.ReportType).to.equal('AgedPayablesByContact');
expect(report.ReportName).to.equal('Aged Payables By Contact');
validateRows(report.Rows);
done();
})
.catch(function(err) {
console.log(err);
done(wrapError(err));
})

});

function validateRows(rows) {
expect(rows).to.have.length.greaterThan(0);
rows.forEach(function(row) {
expect(row.RowType).to.be.oneOf(['Header', 'Section', 'Row', 'SummaryRow']);

//Each row can have some cells, each cell should have some data.
if (row.Cells) {
validateCells(row);
}

if (row.Rows && row.Rows.length > 0) {
row.Rows.forEach(function(thisRow) {
validateCells(thisRow);
})
}

function validateCells(row) {
expect(row.Cells).to.have.length.greaterThan(0);
row.Cells.forEach(function(cell) {
//each cell can either be a string or an object
expect(cell).to.not.equal(undefined);
expect(cell).to.satisfy(function(c) { return typeof c === "string" || typeof c === "object" });
});
}

});
}

})

describe.skip('regression tests', function() {
Expand Down

0 comments on commit 673c805

Please sign in to comment.