Files
pmgr/site/models/ledger_entry.php

216 lines
6.7 KiB
PHP

<?php
class LedgerEntry extends AppModel {
var $belongsTo = array(
'Transaction',
'Account',
'Ledger',
);
var $hasOne = array(
'Tender',
'DoubleEntry',
);
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',
),
//
'StatementEntry' => array(
'joinTable' => 'statement_fractions',
'fields' => 'StatementFraction.amount',
),
);
/**************************************************************************
**************************************************************************
**************************************************************************
* 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) {
/* pr(array('LedgerEntry::addLedgerEntry' => */
/* compact('entry', 'tender'))); */
$ret = array();
if (!$this->verifyLedgerEntry($entry, $tender))
return array('error' => true) + $ret;
if (empty($entry['ledger_id']))
$entry['ledger_id'] =
$this->Account->currentLedgerID($entry['account_id']);
/* pr(array('LedgerEntry::addLedgerEntry' => */
/* array('checkpoint' => 'Pre-Save') */
/* + compact('entry'))); */
$this->create();
if (!$this->save($entry))
return 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 array('error' => true) + $ret;
}
return $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', 'payment',
// 'debit', 'credit',
);
$stats = array();
foreach($rtypes AS $rtype) {
$Rtype = ucfirst($rtype);
if (($rtype == 'charge' && (!isset($set) || $set == 'PAYMENT')) ||
($rtype == 'payment' && (!isset($set) || $set == 'CHARGE'))
/* ($rtype == 'debit' && (!isset($set) || $set == 'CREDIT')) || */
/* ($rtype == 'credit' && (!isset($set) || $set == 'DEBIT')) */
) {
$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;
}
}