git-svn-id: file:///svn-source/pmgr/branches/surplus_account_20090815@591 97e9348a-65ac-dc4b-aefc-98561f571b83
218 lines
6.7 KiB
PHP
218 lines
6.7 KiB
PHP
<?php
|
|
class LedgerEntry extends AppModel {
|
|
|
|
var $belongsTo = array(
|
|
'Transaction',
|
|
'Account',
|
|
'Ledger',
|
|
);
|
|
|
|
var $hasOne = array(
|
|
'Tender' => array(
|
|
'dependent' => true,
|
|
),
|
|
'DebitDoubleEntry' => array(
|
|
'className' => 'DoubleEntry',
|
|
'foreignKey' => 'debit_entry_id',
|
|
'dependent' => true,
|
|
),
|
|
'CreditDoubleEntry' => array(
|
|
'className' => 'DoubleEntry',
|
|
'foreignKey' => 'credit_entry_id',
|
|
'dependent' => true,
|
|
),
|
|
'DoubleEntry' => array(
|
|
'foreignKey' => false,
|
|
),
|
|
);
|
|
|
|
var $hasMany = array(
|
|
);
|
|
|
|
var $hasAndBelongsToMany = array(
|
|
// The Debit half of the double entry matching THIS Credit (if it is one)
|
|
'DebitEntry' => array(
|
|
'className' => 'LedgerEntry',
|
|
'joinTable' => 'double_entries',
|
|
'linkalias' => 'DDE',
|
|
'foreignKey' => 'credit_entry_id',
|
|
'associationForeignKey' => 'debit_entry_id',
|
|
),
|
|
|
|
// The Credit half of the double entry matching THIS Debit (if it is one)
|
|
'CreditEntry' => array(
|
|
'className' => 'LedgerEntry',
|
|
'joinTable' => 'double_entries',
|
|
'linkalias' => 'CDE',
|
|
'foreignKey' => 'debit_entry_id',
|
|
'associationForeignKey' => 'credit_entry_id',
|
|
),
|
|
);
|
|
|
|
|
|
/**************************************************************************
|
|
**************************************************************************
|
|
**************************************************************************
|
|
* function: debitCreditFields
|
|
* - Returns the fields necessary to determine whether the queried
|
|
* entries are a debit, or a credit, and also the effect each have
|
|
* on the overall balance of the account/ledger.
|
|
*/
|
|
|
|
function debitCreditFields($sum = false, $balance = true,
|
|
$entry_name = 'LedgerEntry', $account_name = 'Account') {
|
|
$fields = array
|
|
(
|
|
($sum ? 'SUM(' : '') .
|
|
"IF({$entry_name}.crdr = 'DEBIT'," .
|
|
" {$entry_name}.amount, NULL)" .
|
|
($sum ? ')' : '') . ' AS debit' . ($sum ? 's' : ''),
|
|
|
|
($sum ? 'SUM(' : '') .
|
|
"IF({$entry_name}.crdr = 'CREDIT'," .
|
|
" {$entry_name}.amount, NULL)" .
|
|
($sum ? ')' : '') . ' AS credit' . ($sum ? 's' : ''),
|
|
);
|
|
|
|
if ($balance)
|
|
$fields[] =
|
|
($sum ? 'SUM(' : '') .
|
|
"IF(${account_name}.type IN ('ASSET', 'EXPENSE')," .
|
|
" IF({$entry_name}.crdr = 'DEBIT', 1, -1)," .
|
|
" IF({$entry_name}.crdr = 'CREDIT', 1, -1))" .
|
|
" * IF({$entry_name}.amount, {$entry_name}.amount, 0)" .
|
|
($sum ? ')' : '') . ' AS balance';
|
|
|
|
if ($sum)
|
|
$fields[] = "COUNT({$entry_name}.id) AS entries";
|
|
|
|
return $fields;
|
|
}
|
|
|
|
|
|
/**************************************************************************
|
|
**************************************************************************
|
|
**************************************************************************
|
|
* function: verifyLedgerEntry
|
|
* - Verifies consistenty of new ledger entry data
|
|
* (not in a pre-existing ledger entry)
|
|
*/
|
|
function verifyLedgerEntry($entry, $tender = null) {
|
|
/* pr(array("LedgerEntry::verifyLedgerEntry()" */
|
|
/* => compact('entry', 'tender'))); */
|
|
|
|
if (empty($entry['account_id']) ||
|
|
empty($entry['crdr']) ||
|
|
empty($entry['amount'])
|
|
) {
|
|
/* pr(array("LedgerEntry::verifyLedgerEntry()" */
|
|
/* => "Entry verification failed")); */
|
|
return false;
|
|
}
|
|
|
|
if (isset($tender) && !$this->Tender->verifyTender($tender)) {
|
|
/* pr(array("LedgerEntry::verifyLedgerEntry()" */
|
|
/* => "Tender verification failed")); */
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
|
|
/**************************************************************************
|
|
**************************************************************************
|
|
**************************************************************************
|
|
* function: addLedgerEntry
|
|
* - Inserts new Ledger Entry into the database
|
|
*/
|
|
function addLedgerEntry($entry, $tender = null) {
|
|
$this->prFunctionLevel(16);
|
|
$this->prEnter(compact('entry', 'tender'));
|
|
|
|
$ret = array('data' => $entry);
|
|
if (!$this->verifyLedgerEntry($entry, $tender))
|
|
return $this->prReturn(array('error' => true) + $ret);
|
|
|
|
if (empty($entry['ledger_id']))
|
|
$entry['ledger_id'] =
|
|
$this->Account->currentLedgerID($entry['account_id']);
|
|
|
|
$this->create();
|
|
if (!$this->save($entry))
|
|
return $this->prReturn(array('error' => true) + $ret);
|
|
|
|
$ret['ledger_entry_id'] = $this->id;
|
|
|
|
if (isset($tender)) {
|
|
$tender['account_id'] = $entry['account_id'];
|
|
$tender['ledger_entry_id'] = $ret['ledger_entry_id'];
|
|
$result = $this->Tender->addTender($tender);
|
|
$ret['Tender'] = $result;
|
|
if ($result['error'])
|
|
return $this->prReturn(array('error' => true) + $ret);
|
|
}
|
|
|
|
return $this->prReturn($ret + array('error' => false));
|
|
}
|
|
|
|
|
|
/**************************************************************************
|
|
**************************************************************************
|
|
**************************************************************************
|
|
* function: stats
|
|
* - Returns summary data from the requested ledger entry
|
|
*/
|
|
function stats($id = null, $query = null, $set = null) {
|
|
$this->queryInit($query);
|
|
unset($query['group']);
|
|
|
|
if (!isset($query['link']['DoubleEntry']))
|
|
$query['link']['DoubleEntry'] = array();
|
|
/* if (!isset($query['link']['DoubleEntry']['fields'])) */
|
|
/* $query['link']['DoubleEntry']['fields'] = array(); */
|
|
|
|
if (isset($id))
|
|
$query['conditions'][] = array('Entry.id' => $id);
|
|
|
|
if (isset($set))
|
|
$set = strtoupper($set);
|
|
|
|
//pr(array('stats()', compact('id', 'query', 'set')));
|
|
|
|
$rtypes = array('charge', 'disbursement',
|
|
// 'debit', 'credit',
|
|
);
|
|
|
|
$stats = array();
|
|
foreach($rtypes AS $rtype) {
|
|
$Rtype = ucfirst($rtype);
|
|
|
|
if (($rtype == 'charge' && (!isset($set) || $set == 'DISBURSEMENT')) ||
|
|
($rtype == 'disbursement' && (!isset($set) || $set == 'CHARGE'))
|
|
) {
|
|
|
|
$rquery = $query;
|
|
$rquery['link'][$Rtype] =
|
|
array('fields' => array("SUM(COALESCE(Applied{$Rtype}.amount,0)) AS reconciled"));
|
|
|
|
$rquery['fields'] = array();
|
|
//$rquery['fields'][] = "SUM(DoubleEntry.amount) AS total";
|
|
$rquery['fields'][] = "SUM(DoubleEntry.amount) - SUM(COALESCE(Applied{$Rtype}.amount,0)) AS balance";
|
|
$rquery['conditions'][] = array("Applied{$Rtype}.id !=" => null);
|
|
|
|
$result = $this->find('first', $rquery);
|
|
//pr(compact('Rtype', 'rquery', 'result'));
|
|
|
|
$sumfld = $Rtype;
|
|
$stats[$sumfld] = $result[0];
|
|
/* if (!isset($stats[$sumfld]['applied'])) */
|
|
/* $stats[$sumfld]['applied'] = 0; */
|
|
}
|
|
}
|
|
|
|
return $stats;
|
|
}
|
|
|
|
}
|