Skip to content

Commit

Permalink
perf(Trial Balance): rewrite PostToGeneralLedger
Browse files Browse the repository at this point in the history
This commit rewrites the PostToGeneralLedger function for speed.  It now
shares common functions with the Trial Balance to stage transactions.

Closes #1928.
  • Loading branch information
jniles committed Sep 22, 2017
1 parent 646672e commit abb38b7
Show file tree
Hide file tree
Showing 5 changed files with 81 additions and 51 deletions.
3 changes: 2 additions & 1 deletion client/src/i18n/en/posting_journal.json
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,8 @@
"EXPORT" : "Export the Trial Balance",
"SHOW_ERRORS" : "Switch to Error View",
"RETURN_TO_OVERVIEW" : "Return to Summary View",
"IS_BALANCED" : "Balanced"
"IS_BALANCED" : "Balanced",
"POSTED_TRANSACTIONS" : "Success! Posted {{ numRecords }} Transactions to the General Ledger."
},
"TITLE":"Posting Journal",
"EDIT_MODE":"Edit Mode"
Expand Down
17 changes: 15 additions & 2 deletions client/src/modules/journal/trial-balance/trial-balance.ctrl.js
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
angular.module('bhima.controllers')
.controller('TrialBalanceController', TrialBalanceController);

TrialBalanceController.$inject = ['TrialBalanceService'];
TrialBalanceController.$inject = ['TrialBalanceService', '$state', 'NotifyService'];

/**
* @class TrialBalanceController
*
* @description
* This applies to the structure.html file
*/
function TrialBalanceController(TrialBalance) {
function TrialBalanceController(TrialBalance, $state, Notify) {
var vm = this;

function startup() {
Expand All @@ -33,5 +33,18 @@ function TrialBalanceController(TrialBalance) {
TrialBalance.exportGrid();
};

vm.submit = function submit() {
// compute the number of transactions
var numTransactions = TrialBalance.transactions().length;

TrialBalance.postToGeneralLedger()
.then(function () {
Notify.success('JOURNAL.TRIAL_BALANCE.POSTED_TRANSACTIONS', { numRecords : numTransactions });

$state.go('journal', null, { reload : true });
})
.catch(Notify.handleError);
};

startup();
}
28 changes: 18 additions & 10 deletions client/src/modules/journal/trial-balance/trial-balance.service.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,11 @@ function TrialBalanceService(util, $http, Accounts) {
service.summary = summary;
service.errors = errors;

function uninitialise() {
initialised = false;
transactions = [];
}

/**
* @method initialise
*
Expand Down Expand Up @@ -95,16 +100,17 @@ function TrialBalanceService(util, $http, Accounts) {

/**
* @function postToGeneralLedger
* @description
* This function takes a parsed record list (grid rows processed by the parseSelectedGridRecord function)
* and extract their transaction IDS uniquely through the getTransactionList method
* and post these transaction to the server
*
* This function is called only when every test are passed without a fatal error
* @description
* This function attempts to post to the General Ledger by
*/
function postToGeneralLedger(records) {
return $http.post(url.concat('/transactions'), { transactions : records })
.then(util.unwrapHttpResponse);
function postToGeneralLedger() {
return $http.post(url.concat('/transactions'), { transactions : transactions })
.then(util.unwrapHttpResponse)
.then(function (data) {
uninitialise();
return data;
});
}

/**
Expand Down Expand Up @@ -133,6 +139,8 @@ function TrialBalanceService(util, $http, Accounts) {
*
* @description
* This function fetches the records associated with the account.
*
* @TODO
*/
function fetchSubGridRecords(account) {
$http.post(url.concat('/trialbalance/subgrid'));
Expand All @@ -144,10 +152,10 @@ function TrialBalanceService(util, $http, Accounts) {
* @description
* Returns the transactions that were used to initialize the trial balance.
*/
function transactions() {
this.transactions = function txns() {
ensureTrialBalanceInitialised('transactions()');
return transactions;
}
};

return service;
}
43 changes: 28 additions & 15 deletions server/controllers/finance/trialBalance/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,15 +21,23 @@ function stageTrialBalanceTransactions(txn, transactions) {
});
}

exports.runTrialBalance = function runTrialBalance(req, res, next) {
const transactions = req.body.transactions;
function validateTransactions(transactions) {
const hasInvalidTransactions = !(transactions && Array.isArray(transactions) && transactions.length);

if (hasInvalidTransactions) {
return next(new BadRequest(
throw new BadRequest(
'No transactions were submitted. Please ensure that some are selected.',
'POSTING_JOURNAL.ERRORS.MISSING_TRANSACTIONS'
));
);
}
}

exports.runTrialBalance = function runTrialBalance(req, res, next) {
const transactions = req.body.transactions;

try {
validateTransactions(transactions);
} catch (e) {
return next(e);
}

const txn = db.transaction();
Expand All @@ -43,9 +51,6 @@ exports.runTrialBalance = function runTrialBalance(req, res, next) {
// compute the trial balance summary
txn.addQuery('CALL TrialBalanceSummary()');

// compute the aggregate results for the trial balance
// txn.addQuery('CALL TrialBalanceAggregates()');

return txn.execute()
.then((results) => {
// because we do not know the number of stageTrialBalance() calls, we must index back by two
Expand All @@ -66,21 +71,29 @@ exports.runTrialBalance = function runTrialBalance(req, res, next) {

/**
* @function postToGeneralLedger
*
* @description
* This function can be called only when there is no fatal error
* It posts data to the general ledger.
*/
exports.postToGeneralLedger = function postToGeneralLedger(req, res, next) {
const transactions = req.body.transactions;

if (!transactions || !Array.isArray(transactions)) {
return next(new BadRequest('The transaction list is null or undefined otherwise The query is bad formatted'));
try {
validateTransactions(transactions);
} catch (e) {
return next(e);
}

// Just a workaround because mysql does not have a type for array
const transactionString = transactions.map(transId => `"${transId}"`).join(',');
const txn = db.transaction();

return db.exec('CALL PostToGeneralLedger(?)', [transactionString])
.then(() => res.status(201).json({}))
.catch(next);
// stage all trial balance transactions
stageTrialBalanceTransactions(txn, transactions);

txn.addQuery('CALL PostToGeneralLedger();');

return txn.execute()
.then(() => res.sendStatus(201))
.catch(next)
.done();
};
41 changes: 18 additions & 23 deletions server/models/procedures.sql
Original file line number Diff line number Diff line change
Expand Up @@ -488,46 +488,41 @@ BEGIN
END
$$

CREATE PROCEDURE PostToGeneralLedger(
IN transactions TEXT
) BEGIN

CREATE TEMPORARY TABLE IF NOT EXISTS stage_journal_transaction (record_uuid BINARY(16));

SET @sql = CONCAT(
"INSERT INTO stage_journal_transaction SELECT DISTINCT record_uuid FROM posting_journal WHERE trans_id IN (", transactions, ");"
);

PREPARE stmt FROM @sql;
EXECUTE stmt;
/*
PostToGeneralLedger()
DEALLOCATE PREPARE stmt;
This procedure uses the same staging code as the Trial Balance to stage and then post transactions
from the posting_journal table to the General Ledger table.
*/
CREATE PROCEDURE PostToGeneralLedger()
BEGIN
-- write into the posting journal
INSERT INTO general_ledger (
project_id, uuid, fiscal_year_id, period_id, trans_id, trans_date, record_uuid,
description, account_id, debit, credit, debit_equiv, credit_equiv, currency_id,
entity_uuid, reference_uuid, comment, origin_id, user_id, cc_id, pc_id
) SELECT project_id, uuid, fiscal_year_id, period_id, trans_id, trans_date, record_uuid,
project_id, uuid, fiscal_year_id, period_id, trans_id, trans_date,
record_uuid, description, account_id, debit, credit, debit_equiv,
credit_equiv, currency_id, entity_uuid, reference_uuid, comment, origin_id, user_id,
cc_id, pc_id
) SELECT project_id, uuid, fiscal_year_id, period_id, trans_id, trans_date, posting_journal.record_uuid,
description, account_id, debit, credit, debit_equiv, credit_equiv, currency_id,
entity_uuid, reference_uuid, comment, origin_id, user_id, cc_id, pc_id
FROM posting_journal
WHERE posting_journal.record_uuid IN (SELECT record_uuid FROM stage_journal_transaction);
FROM posting_journal JOIN stage_trial_balance_transaction AS staged
ON posting_journal.record_uuid = staged.record_uuid;

-- write into period_total
INSERT INTO period_total (
account_id, credit, debit, fiscal_year_id, enterprise_id, period_id
)
SELECT account_id, SUM(credit_equiv) AS credit, SUM(debit_equiv) as debit,
fiscal_year_id, project.enterprise_id, period_id
FROM posting_journal JOIN project
ON posting_journal.project_id = project.id
WHERE posting_journal.record_uuid IN (SELECT record_uuid FROM stage_journal_transaction)
FROM posting_journal JOIN stage_trial_balance_transaction JOIN project
ON posting_journal.record_uuid = stage_trial_balance_transaction.record_uuid
AND project_id = project.id
GROUP BY period_id, account_id
ON DUPLICATE KEY UPDATE credit = credit + VALUES(credit), debit = debit + VALUES(debit);

-- remove from posting journal
DELETE FROM posting_journal WHERE record_uuid IN (SELECT record_uuid FROM stage_journal_transaction);
DELETE FROM posting_journal WHERE record_uuid IN (SELECT record_uuid FROM stage_trial_balance_transaction);
END $$

-- Handles the Cash Table's Rounding
Expand Down

0 comments on commit abb38b7

Please sign in to comment.