Changed the app controller jqGrid virtual functions for getting the tables for both count and the full query. The ExtraTables bit was too confusing, and was only intended to allow the user to specify a subset for count and augment it for full query. This is easily accomplished by having DataTables just call DataCountTables first... one line solution ends the confusion.
Modified linkable behavior to support a %{MODEL_ALIAS} tag, which is replaced in the relationship conditions at runtime with the actual model alias. This is experimental at best, and certainly will create a problem for any model that ends up using the conditions in 'contain' instead of 'link'.
Broke the LedgerEntry->findInLedgerContext function out into multiple pieces, so those same pieces could be used in the LedgerEntries controller to populate jqGrid.
Changed the ledger_entries element, as a special case, to also allow listing control from ledger_id and account_type, instead of idlist as a mechanism for populating the grid.
Changed the infobox summary css, which will break several pages until I rework them.
Some next steps include fixing the broken infoboxes, and changing the transactions view to use the ledger_entries element. This also means the ledger_entries element will need to add support for idlist, or if we have any credit/debit issues, perhaps another custom transaction_id instead.
git-svn-id: file:///svn-source/pmgr/branches/ledger_transactions_20090605/site@134 97e9348a-65ac-dc4b-aefc-98561f571b83
155 lines
5.5 KiB
PHP
155 lines
5.5 KiB
PHP
<?php
|
|
class Ledger extends AppModel {
|
|
|
|
var $name = 'Ledger';
|
|
var $validate = array(
|
|
'id' => array('numeric'),
|
|
'name' => array('notempty'),
|
|
);
|
|
|
|
var $belongsTo = array(
|
|
'Account',
|
|
);
|
|
|
|
var $hasMany = array(
|
|
'LedgerEntry' => array(
|
|
'className' => 'LedgerEntry',
|
|
'foreignKey' => false,
|
|
|
|
// conditions will be used when JOINing tables
|
|
// (such as find with LinkableBehavior)
|
|
'conditions' => array('OR' =>
|
|
array('LedgerEntry.debit_ledger_id = %{MODEL_ALIAS}.id',
|
|
'LedgerEntry.credit_ledger_id = %{MODEL_ALIAS}.id')),
|
|
|
|
// finderQuery will be used when tables are put
|
|
// together across several querys, not with JOIN.
|
|
// (such as find with ContainableBehavior)
|
|
'finderQuery' => 'SELECT `LedgerEntry`.*
|
|
FROM pmgr_ledger_entries AS `LedgerEntry`
|
|
WHERE LedgerEntry.debit_ledger_id = ({$__cakeID__$})
|
|
OR LedgerEntry.credit_ledger_id = ({$__cakeID__$})',
|
|
|
|
'counterQuery' => ''
|
|
),
|
|
'DebitLedgerEntry' => array(
|
|
'className' => 'LedgerEntry',
|
|
'foreignKey' => 'debit_ledger_id',
|
|
'dependent' => false,
|
|
),
|
|
'CreditLedgerEntry' => array(
|
|
'className' => 'LedgerEntry',
|
|
'foreignKey' => 'credit_ledger_id',
|
|
'dependent' => false,
|
|
),
|
|
);
|
|
|
|
|
|
/**************************************************************************
|
|
**************************************************************************
|
|
**************************************************************************
|
|
* function: findLedgerEntries
|
|
* - Returns an array of ledger entries that belong to a given
|
|
* ledger. There is extra work done... see the LedgerEntry model.
|
|
*/
|
|
function findLedgerEntries($id, $account_type = null, $cond = null, $link = null) {
|
|
/* pr(array('function' => 'Ledger::findLedgerEntries', */
|
|
/* 'args' => compact('id', 'account_type', 'cond', 'link'), */
|
|
/* )); */
|
|
|
|
if (!isset($account_type)) {
|
|
$this->Behaviors->attach('Containable');
|
|
$ledger = $this->find('first', array
|
|
('contain' => array
|
|
('Account' => array
|
|
('fields' => array('type'),
|
|
),
|
|
),
|
|
'fields' => array(),
|
|
'conditions' => array(array('Ledger.id' => $id)),
|
|
));
|
|
$this->Behaviors->detach('Containable');
|
|
$account_type = $ledger['Account']['type'];
|
|
}
|
|
|
|
// If the requested entries are limited by date, we must calculate
|
|
// a balance forward, or the resulting balance will be thrown off.
|
|
//
|
|
// REVISIT <AP>: This obviously is more general than date.
|
|
// As such, it will not work (or, only work if the
|
|
// condition only manages to exclude the first parts
|
|
// of the ledger, nothing in the middle or at the
|
|
// end. For now, I'll just create an 'other' entry,
|
|
// not necessarily a balance forward.
|
|
|
|
$bf = array();
|
|
if (0 && isset($cond)) {
|
|
//$date = '<NOT IMPLEMENTED>';
|
|
$stats = $this->stats($id, array('NOT' => array($cond)));
|
|
$bf = array(array(array('debit' => $stats['debits'],
|
|
'credit' => $stats['credits'],
|
|
'balance' => $stats['balance']),
|
|
|
|
'LedgerEntry' => array('id' => null,
|
|
//'comment' => "Balance Forward from $date"),
|
|
'comment' => "-- SUMMARY OF EXCLUDED ENTRIES --"),
|
|
|
|
'Transaction' => array('id' => null,
|
|
//'stamp' => $date,
|
|
'stamp' => null,
|
|
'comment' => null),
|
|
));
|
|
}
|
|
|
|
$entries = $this->LedgerEntry->findInLedgerContext($id, $account_type, $cond, $link);
|
|
/* pr(array('function' => 'Ledger::findLedgerEntries', */
|
|
/* 'args' => compact('id', 'account_type', 'cond', 'link'), */
|
|
/* 'vars' => compact('ledger'), */
|
|
/* 'return' => compact('entries'), */
|
|
/* )); */
|
|
return $entries;
|
|
}
|
|
|
|
|
|
/**************************************************************************
|
|
**************************************************************************
|
|
**************************************************************************
|
|
* function: stats
|
|
* - Returns summary data from the requested ledger.
|
|
*/
|
|
function stats($id, $cond = null) {
|
|
|
|
$stats = $this->find
|
|
('first', array
|
|
('link' =>
|
|
array(// Models
|
|
'Account' => array('fields' => array()),
|
|
//'LedgerEntry' => array('fields' => array()),
|
|
'LedgerEntry' =>
|
|
array('fields' => array(),
|
|
'Transaction' => array('fields' => array('stamp')),
|
|
),
|
|
),
|
|
'fields' =>
|
|
array("SUM(IF(LedgerEntry.debit_ledger_id = Ledger.id,
|
|
LedgerEntry.amount, NULL)) AS debits",
|
|
"SUM(IF(LedgerEntry.credit_ledger_id = Ledger.id,
|
|
LedgerEntry.amount, NULL)) AS credits",
|
|
"SUM(IF(Account.type IN ('ASSET', 'EXPENSE'),
|
|
IF(LedgerEntry.debit_ledger_id = Ledger.id, 1, -1),
|
|
IF(LedgerEntry.credit_ledger_id = Ledger.id, 1, -1)
|
|
) * IF(LedgerEntry.amount, LedgerEntry.amount, 0)
|
|
) AS balance",
|
|
"COUNT(LedgerEntry.id) AS entries"),
|
|
'conditions' => array(isset($cond) ? $cond : array(),
|
|
array('Ledger.id' => $id)),
|
|
'group' => 'Ledger.id',
|
|
));
|
|
|
|
// The fields are all tucked into the [0] index,
|
|
// and the rest of the array is useless (empty).
|
|
return $stats[0];
|
|
}
|
|
|
|
}
|
|
?>
|