From: Gil Moskowitz Date: Fri, 27 Jun 2014 19:21:12 +0000 (-0400) Subject: first pass bankrec test - not run yet X-Git-Tag: v4.6.0-beta~13^2~11 X-Git-Url: http://git.roojs.org/?a=commitdiff_plain;h=193a413f5195b3b2f24535f4e29a7f978d9d6007;p=xtuple first pass bankrec test - not run yet --- diff --git a/test/database/bankrec.js b/test/database/bankrec.js new file mode 100644 index 000000000..9e80904dc --- /dev/null +++ b/test/database/bankrec.js @@ -0,0 +1,384 @@ +/*jshint trailing:true, white:true, indent:2, strict:true, curly:true, + immed:true, eqeqeq:true, forin:true, latedef:true, + newcap:true, noarg:true, undef:true */ +/*global XT:true, describe:true, it:true, require:true, __dirname:true, before:true */ + +var _ = require("underscore"), + assert = require('chai').assert, + path = require('path'); + +(function () { + "use strict"; + + describe('test bank reconciliation functions', function () { + + var loginData = require("../lib/login_data.js").data, + datasource = require('../../../xtuple/node-datasource/lib/ext/datasource').dataSource, + config = require(path.join(__dirname, "../../node-datasource/config.js")), + creds = _.extend({}, config.databaseServer, {database: loginData.org}), + bankaccnt, + bankrec, + trans1 = { amount: 98.76 }, + trans2 = { amount: 54.32 }, + bankRecItemSql = 'SELECT * FROM bankrecitem ' + + ' WHERE bankrecitem_bankrec_id=:brid' + + ' AND bankrecitem_source_id=:srcid' + + ' AND bankrecitem_source=:src;', + toggleCheckSql = "SELECT toggleBankRecCleared(:bankrec_id,'A/R'" + + ", gltrans_id, checkhead_curr_rate, checkhead_amount)" + + " AS result" + + " FROM checkhead JOIN gltrans ON (gltrans_doctype='CK'" + + " AND gltrans_misc_id=checkhead_id)" + + " WHERE checkhead_id=:checkid;", + checkCheckSql = "SELECT *," + " bankrecitem_amount/bankrecitem_curr_rate AS base"+ + " JOIN bankrecitem ON (gltrans_id=bankrecitem_source_id)"+ + " JOIN bankrec ON (bankrecitem_bankrec_id=bankrec_id)"+ + " WHERE gltrans_doctype='CK'" + + " AND gltrans_misc_id=:checkid" + + " AND bankrec_id=:bankrec_id;", + bankAdjCheckSql = "SELECT *," + " ABS(bankadj_amount / bankadj_curr_rate) AS baseamt" + + " FROM bankadj LEFT OUTER" + + " JOIN bankaccnt ON (bankadj_bankaccnt_id=bankaccnt_id)" + + " LEFT OUTER" + + " JOIN gltrans ON (bankaccnt_accnt_id=gltrans_accnt_id" + + " AND gltrans_doctype='AD'" + + " AND gltrans_notes ~ bankadj_notes" + + " AND gltrans_docnumber=bankadj_docnumber)"+ + " LEFT OUTER" + + " JOIN bankrecitem ON (bankrec_source='G/L' " + + " AND bankrec_source_id=gltrans_id)" + + " WHERE bankadj_id=:bankadjid;" // TODO: precise enough? + ; + + it('looks for a bank account with no open reconciliations', function (done) { + var sql = 'SELECT * FROM bankaccnt WHERE bankaccnt_id IN (' + + ' SELECT bankrec_bankaccnt_id FROM bankrec' + + ' GROUP BY bankrec_bankaccnt_id' + + ' HAVING BOOL_AND(bankrec_posted)) LIMIT 1;' + ; + datasource.query(sql, creds, function (err, res) { + assert.equal(res.rowCount, 1); + bankaccnt = _.clone(res.rows[0]); + assert.isNotNull(bankaccnt, 'we found a bank account'); + done(); + }); + }); + + it('creates a new open bankrec to test with', function (done) { + var sql = 'INSERT INTO bankrec (bankrec_bankaccnt_id,' + + ' bankrec_opendate, bankrec_openbal' + + ') SELECT bankrec_bankaccnt_id,' + + ' bankrec_enddate + 1, bankrec_endbal' + + ' FROM bankrec' + + ' WHERE bankrec_bankaccnt_id=' + bankaccnt.bankaccnt_id + + ' AND bankrec_posted' + + ' ORDER BY bankrec_enddate DESC' + + ' LIMIT 1 RETURNING *;' + ; + datasource.query(sql, creds, function (err, res) { + assert.equal(res.rowCount, 1); + bankrec = _.clone(res.rows[0]); + assert.isNotNull(bankrec, 'we have a bank rec'); + assert.isFalse(bankrec.bankrec_posted, 'we have an open bank rec'); + done(); + }); + }); + + it('creates a check as the 1st transaction to reconcile', function (done) { + var sql = "SELECT createCheck(" + bankaccnt.bankaccnt_id + + "'V', (SELECT MIN(vend_id) FROM vendinfo), '" + + bankrec.bankrec_opendate + "' + 1, " + trans1.amount + ", " + + bankaccnt.bankaccnt_curr_id + ", NULL, NULL, 'Bearer'," + + ", 'bankrec test 1', TRUE, NULL) RETURNING checkid;" + ; + datasource.query(sql, cred, function (err, res) { + assert.equal(res.rowCount, 1); + assert(res.row[0].checkid > 0); + trans1.checkid = res.row[0].checkid; + done(); + }); + }); + + it('posts the check', function (done) { + var sql = 'SELECT postCheck(' + trans1.checkid + ', NULL) AS result;'; + datasource.query(sql, cred, function (err, res) { + assert.equal(res.rowCount, 1); + assert(res.row[0].result > 0); + trans1.journalNumber = res.row[0].result; + done(); + }); + }); + + it('marks the check as cleared', function (done) { + var sql = _.clone(toggleCheckSql) + .replace(':bankrec_id', bankrec.bankrec_id) + .replace(':checkid', trans1.checkid); + datasource.query(sql, cred, function (err, res) { + assert.equal(res.rowCount, 1); + assert.isTrue(res.row[0].result); + done(); + }); + }); + + it('confirms the check was marked as cleared', function (done) { + var sql = _.clone(bankRecItemSql) + .replace(':brid', bankrec.bankrec_id) + .replace(':src', 'A/R') + .replace('=:srcid', + " IN (SELECT gltrans_id FROM gltrans WHERE" + + " gltrans_doctype='CK' AND gltrans_misc_id=" + + trans1.checkid) + ; + datasource.query(sql, cred, function (err, res) { + assert.equal(res.rowCount, 1); + assert.isTrue(res.row[0].bankrecitem_cleared); + assert(res.row[0].bankrecitem_cleared); + done(); + }); + }); + + it('marks the check as /not/ cleared', function (done) { + var sql = _.clone(toggleCheckSql) + .replace(':bankrec_id', bankrec.bankrec_id) + .replace(':checkid', trans1.checkid); + datasource.query(sql, cred, function (err, res) { + assert.equal(res.rowCount, 1); + assert.isFalse(res.row[0].result); + done(); + }); + }); + + it('confirms the check is no longer marked as cleared', function (done) { + var sql = _.clone(bankRecItemSql) + .replace(':brid', bankrec.bankrec_id) + .replace(':src', 'A/R') + .replace('=:srcid', + " IN (SELECT gltrans_id FROM gltrans WHERE" + + " gltrans_doctype='CK' AND gltrans_misc_id=" + + trans1.checkid) + ; + datasource.query(sql, cred, function (err, res) { + assert.equal(res.rowCount, 0); + done(); + }); + }); + + it('marks the check as cleared again', function (done) { + var sql = _.clone(toggleCheckSql) + .replace(':bankrec_id', bankrec.bankrec_id) + .replace(':checkid', trans1.checkid) + ; + datasource.query(sql, cred, function (err, res) { + assert.equal(res.rowCount, 1); + assert.isTrue(res.row[0].result); + done(); + }); + }); + + it('confirms that the check is marked as cleared again', function (done) { + var sql = bankRecItemSql.replace(':brid', bankrec.bankrec_id) + .replace(':src', 'A/R') + .replace('=:srcid', + " IN (SELECT gltrans_id FROM gltrans" + + " WHERE gltrans_doctype='CK' AND " + " gltrans_misc_id=" + trans1.checkid) + ; + datasource.query(sql, cred, function (err, res) { + assert.equal(res.rowCount, 1); + assert.isTrue(res.row[0].bankrecitem_cleared); + assert(res.row[0].bankrecitem_cleared); + done(); + }); + }); + + it('creates a bank adjustment as a second transaction', function (done) { + var sql = "INSERT INTO bankadj (" + + " bankadj_bankaccnt_id, bankadj_bankadjtype_id," + + " bankadj_date, bankadj_docnumber," + + " bankadj_amount, bankadj_notes, bankadj_curr_id" + + ") SELECT " + bankaccnt.bankaccnt_id + ", bankadjtype_id, '" + + bankrec.bankrec_opendate + "' + 1, 'BankRecTest', " + + trans2.amount + ", 'Bank Rec Test Transaction 2', " + + bankaccnt.bankaccnt_curr_id + + " FROM bankadjtype RETURNING *;" + ; + datasource.query(sql, cred, function (err, res) { + assert.equal(res.rowCount, 1); + _.extend(trans2, res.rows[0]); + assert.isOk(trans2.bankadj_id, 'we have a bank adjustment'); + done(); + }); + }); + + it('posts the reconciliation', function (done) { + var sql = 'SELECT postBankReconciliation(' + bankrec.bankrec_id + + ') AS result;' + ; + datasource.query(sql, cred, function (err, res) { + assert.equal(res.rowCount, 1); + assert.equal(res.row[0].result, bankrec.bankrec_id); + done(); + }); + }); + + it('confirms the check was reconciled properly', function (done) { + var sql = _.clone(checkCheckSql) + .replace(':checkid', trans1.checkid) + .replace(':bankrecid', bankrec.bankrec_id) + ; + datasource.query(sql, cred, function (err, res) { + assert.equal(res.rowCount, 1); + assert.isTrue(res.row[0].gltrans_rec); + assert.isTrue(res.row[0].bankrec_posted); + done(); + }); + }); + + // TODO: confirm the CashBasedTax reconciliation code worked + + it('confirms the bank adjustment was /not/ posted', function (done) { + sql = _.clone(bankAdjCheckSql).replace(':bankadjid', trans2.bankadj_id); + datasource.query(sql, cred, function (err, res) { + assert.equal(res.rowCount, 1); + assert.isFalse(res.row[0].bankadj_posted); + assert.notOk(res.row[0].gltrans_id); + assert.notOk(res.row[0].bankrecitem_id); + done(); + }); + }); + + it('reopens the reconcilation', function (done) { + var sql = 'SELECT reopenBankReconciliation(' + bankrec.bankrec_id + + ') AS result;' + ; + datasource.query(sql, cred, function (err, res) { + assert.equal(res.rowCount, 1); + assert.equal(res.row[0].result, bankrec.bankrec_id); + done(); + }); + }); + + it('confirms the check was handled properly by the reopen', function (done) { + var sql = _.clone(checkCheckSql) + .replace(':checkid', trans1.checkid) + .replace(':bankrecid', bankrec.bankrec_id) + ; + datasource.query(sql, cred, function (err, res) { + assert.equal(res.rowCount, 1); + assert.isFalse(res.row[0].gltrans_rec); + assert.isFalse(res.row[0].bankrec_posted); + assert.closeTo(Math.abs(res.row[0].gltrans_amount), res.row[0].base, + 0.001); + done(); + }); + }); + + // TODO: confirm the CashBasedTax reconciliation code worked + + it('marks the bank adjustment as cleared', function (done) { + var sql = "SELECT toggleBankRecCleared(" + bankrec.bankrec_id + + ", 'G/L', gltrans_id, bankadj_curr_rate," + + " bankadj_amount) AS result" + + " FROM bankadj JOIN gltrans" + + " ON (gltrans_doctype='AD' AND gltrans_misc_id=bankadj_id)" + + " WHERE bankadj_id=" + trans2.bankadj_id + ";" + ; + datasource.query(sql, cred, function (err, res) { + assert.equal(res.rowCount, 1); + assert.isTrue(res.row[0].result); + done(); + }); + }); + + it('confirms the bank adjustment was /not/ posted but is cleared', function (done) { + sql = _.clone(bankAdjCheckSql).replace(':bankadjid', trans2.bankadj_id); + datasource.query(sql, cred, function (err, res) { + assert.equal(res.rowCount, 1); + assert.isFalse(res.row[0].bankadj_posted); + assert(res.row[0].bankrecitem_id >= 0); + done(); + }); + }); + + it('posts the reconciliation again', function (done) { + var sql = 'SELECT postBankReconciliation(' + bankrec.bankrec_id + + ') AS result;' + ; + datasource.query(sql, cred, function (err, res) { + assert.equal(res.rowCount, 1); + assert.equal(res.row[0].result, bankrec.bankrec_id); + done(); + }); + }); + + it('confirms the check was reconciled properly', function (done) { + var sql = _.clone(checkCheckSql) + .replace(':checkid', trans1.checkid) + .replace(':bankrecid', bankrec.bankrec_id) + ; + datasource.query(sql, cred, function (err, res) { + assert.equal(res.rowCount, 1); + assert.isTrue(res.row[0].gltrans_rec); + assert.isTrue(res.row[0].bankrec_posted); + done(); + }); + }); + + // TODO: confirm the CashBasedTax reconciliation code worked + + it('confirms the bank adjustment was cleared, posted, written to the GL', function (done) { + sql = _.clone(bankAdjCheckSql).replace(':bankadjid', trans2.bankadj_id); + datasource.query(sql, cred, function (err, res) { + assert.equal(res.rowCount, 1); + assert.isTrue(res.row[0].bankadj_posted); + assert(res.row[0].bankadj_sequence >= 0); + assert.isTrue(res.row[0].gltrans_rec); + assert.closeTo(Math.abs(res.row[0].gltrans_amount), res.row[0].baseamt, + 0.001); + done(); + }); + }); + + it('deletes the bankrec', function (done) { + var sql = 'SELECT deleteBankReconciliation(' + bankrec.bankrec_id + + ') AS result;'; + datasource.query(sql, cred, function (err, res) { + assert.equal(res.rowCount, 1); + assert(res.row[0].result >= 0); + done(); + }); + }); + + it('checks that the bankrec is really gone', function (done) { + var sql = 'SELECT COUNT(*) FROM bankrec WHERE bankrec_id = ' + + bankrec.bankrec_id; + datasource.query(sql, cred, function (err, res) { + assert.equal(res.rowCount, 1); + assert(res.row[0].result === 0); + done(); + }); + }); + + it('checks that the bankrecitems are gone', function (done) { + var sql = 'SELECT COUNT(*) FROM bankrecitem' + ' WHERE bankrecitem_bankrec_id = ' + bankrec.bankrec_id; + datasource.query(sql, cred, function (err, res) { + assert.equal(res.rowCount, 1); + assert(res.row[0].result === 0); + done(); + }); + }); + + it('tries to delete a non-existent bankrec', function (done) { + var sql = 'SELECT deleteBankReconciliation(-15) AS result;'; + datasource.query(sql, cred, function (err, res) { + assert.equal(res.rowCount, 1); + assert(res.row[0].result === 0); // no, it doesn't complain + done(); + }); + }); + + }); +}());