Another snapshot

git-svn-id: file:///svn-source/pmgr/branches/yafr_20090716/site@356 97e9348a-65ac-dc4b-aefc-98561f571b83
This commit is contained in:
abijah
2009-07-20 23:35:11 +00:00
parent bfbf119aca
commit d5bcd9a496
20 changed files with 696 additions and 759 deletions

View File

@@ -8,15 +8,6 @@ class Entry extends AppModel {
var $hasAndBelongsToMany = array(
// The Payments that match THIS Charge (if it is one)
'Payment' => array(
'className' => 'Entry',
'joinTable' => 'charges_payments',
'linkalias' => 'AppliedPayment',
'foreignKey' => 'charge_entry_id',
'associationForeignKey' => 'payment_entry_id',
),
// The Charges that match THIS Payment (if it is one)
'Charge' => array(
'className' => 'Entry',
@@ -26,23 +17,41 @@ class Entry extends AppModel {
'associationForeignKey' => 'charge_entry_id',
),
// The Debits of this same account matching THIS Credit (if it is one)
'Debit' => array(
// The Payments that match THIS Charge (if it is one)
'Payment' => array(
'className' => 'Entry',
'joinTable' => 'reconciliations',
'linkalias' => 'AppliedDebit',
'foreignKey' => 'credit_entry_id',
'associationForeignKey' => 'debit_entry_id',
'joinTable' => 'charges_payments',
'linkalias' => 'AppliedPayment',
'foreignKey' => 'charge_entry_id',
'associationForeignKey' => 'payment_entry_id',
),
// The Credits of this same account matching THIS Debit (if it is one)
'Credit' => array(
'className' => 'Entry',
'joinTable' => 'reconciliations',
'linkalias' => 'AppliedCredit',
'foreignKey' => 'debit_entry_id',
'associationForeignKey' => 'credit_entry_id',
),
/* // The Deposits that match THIS Payment (if it is one) */
/* 'Deposit' => array( */
/* 'className' => 'Entry', */
/* 'joinTable' => 'deposits_payments', */
/* 'linkalias' => 'AppliedDeposit', */
/* 'foreignKey' => 'payment_entry_id', */
/* 'associationForeignKey' => 'deposit_entry_id', */
/* ), */
/* // The Debits of this same account matching THIS Credit (if it is one) */
/* 'Debit' => array( */
/* 'className' => 'Entry', */
/* 'joinTable' => 'reconciliations', */
/* 'linkalias' => 'AppliedDebit', */
/* 'foreignKey' => 'credit_entry_id', */
/* 'associationForeignKey' => 'debit_entry_id', */
/* ), */
/* // The Credits of this same account matching THIS Debit (if it is one) */
/* 'Credit' => array( */
/* 'className' => 'Entry', */
/* 'joinTable' => 'reconciliations', */
/* 'linkalias' => 'AppliedCredit', */
/* 'foreignKey' => 'debit_entry_id', */
/* 'associationForeignKey' => 'credit_entry_id', */
/* ), */
/* // The Entries of this same account matching THIS Entry */
/* 'REntry' => array( */
@@ -61,6 +70,38 @@ class Entry extends AppModel {
);
/**************************************************************************
**************************************************************************
**************************************************************************
* function: chargePaymentFields
*/
function chargePaymentFields($sum = false, $entry_name = 'Entry', $double_name = 'DoubleEntry') {
$fields = array
(
($sum ? 'SUM(' : '') .
"IF({$entry_name}.type = 'CHARGE'," .
" {$double_name}.amount, NULL)" .
($sum ? ')' : '') . ' AS charge' . ($sum ? 's' : ''),
($sum ? 'SUM(' : '') .
"IF({$entry_name}.type = 'PAYMENT'," .
" {$double_name}.amount, NULL)" .
($sum ? ')' : '') . ' AS payment' . ($sum ? 's' : ''),
($sum ? 'SUM(' : '') .
"IF({$entry_name}.type = 'CHARGE', 1, -1)" .
" * IF({$double_name}.amount, {$double_name}.amount, 0)" .
($sum ? ')' : '') . ' AS balance',
);
if ($sum)
$fields[] = "COUNT({$entry_name}.id) AS entries";
return $fields;
}
/**************************************************************************
**************************************************************************
@@ -134,40 +175,6 @@ class Entry extends AppModel {
}
/**************************************************************************
**************************************************************************
**************************************************************************
* function: findInLedgerContext
* - Returns an array of ledger entries that belong to a given ledger.
* There is extra logic to also figure out whether the ledger_entry
* amount is either a credit, or a debit, depending on how it was
* written into the ledger, as well as whether the amount increases or
* decreases the balance depending on the particular account type of
* the ledger.
*/
function findInLedgerContext($ledger_id, $account_type, $cond = null, $link = null) {
if (!isset($link))
$link = array('Transaction');
if (!isset($cond))
$cond = array();
$fields = $this->ledgerContextFields($ledger_id, $account_type);
$cond[] = $this->ledgerContextConditions($ledger_id, $account_type);
$order = array('Transaction.stamp');
$entries = $this->find
('all',
array('link' => $link,
'fields' => $fields,
'conditions' => $cond,
'order' => $order,
));
return $entries;
}
/**************************************************************************
**************************************************************************
**************************************************************************
@@ -282,94 +289,6 @@ OPTION 2
}
/**************************************************************************
**************************************************************************
**************************************************************************
* function: reconcileConditions
* - Returns entries which reconcile, or match, the set of entries
* requested through the $cond argument.
*/
function reconcilingQuery($double_name = 'DoubleEntry', $sum = false) {
$applied = array();
foreach (array('Payment', 'Charge') AS $pc) {
$applied[$pc] = "COALESCE(Applied{$pc}.amount,0)";
if ($sum)
$applied[$pc] = "SUM({$applied[$pc]})";
}
return array
('fields' => array("IF(Entry.type = 'CHARGE'," .
" {$applied['Payment']}, {$applied['Charge']}) AS 'applied'",
"{$double_name}.amount - IF(Entry.type = 'CHARGE'," .
" {$applied['Payment']}, {$applied['Charge']}) AS 'balance'",
),
'conditions' => array(),
);
}
/**************************************************************************
**************************************************************************
**************************************************************************
* function: matchingEntries
* - Returns entries which reconcile, or match, the set of entries
* requested through the $cond argument.
*/
function matchingEntries($cond, $group, $strip_rec = false, $strip_unrec = false) {
$rquery = $this->reconcilingQuery('DoubleEntry', $group);
$fields = array_merge(array('Entry.*'), $rquery['fields']);
$cond = array_merge($cond, $rquery['conditions']);
$reconciled = $this->find
('all', array
('link' => array('DoubleEntry', 'Account',
'Charge' => array('fields' => array('Charge.*', 'AppliedCharge.*')),
'Payment' => array('fields' => array('Payment.*', 'AppliedPayment.*')),
),
'fields' => $fields,
'group' => $group,
'conditions' => $cond,
));
foreach ($reconciled AS $i => &$entry) {
$entry['Entry'] += $entry[0];
unset($entry[0]);
// Since HAVING isn't a builtin feature of CakePHP,
// we'll have to post-process to get the desired entries
if ($entry['Entry']['balance'] == 0) {
if ($strip_rec)
unset($reconciled[$i]);
}
else {
if ($strip_unrec)
unset($reconciled[$i]);
}
}
//pr(compact('reconciled'));
return $reconciled;
}
/**************************************************************************
**************************************************************************
**************************************************************************
* function: reconciledEntries
* - Returns the list of entries that have been reconciled (if $rec),
* or not fully reconciled (if $rec is false), along with the amount
* that has already been applied towards the entry as well as the
* remaining balance.
*/
function reconciledEntries1($id, $rec = true, $cond = null) {
$cond[] = array('Entry.id' => $id);
//return $this->matchingEntries($cond, array('Entry.id'), !$rec, $rec);
return $this->matchingEntries($cond, array('Entry.id'), false, false);
}
/**************************************************************************
**************************************************************************
**************************************************************************
@@ -377,46 +296,36 @@ OPTION 2
* - Returns the set of entries satisfying the given conditions,
* along with any entries that they reconcile
*/
function reconciledSet($set, $cond = null, $link = null, $unrec = false) {
if (!isset($cond))
$cond = array();
if (!isset($link))
$link = array();
function reconciledSetQuery($set, $query) {
$this->queryInit($query);
if ($set == 'CHARGE' || $set == 'PAYMENT')
$cond[] = array('Entry.type' => $set);
$query['conditions'][] = array('Entry.type' => $set);
elseif ($set == 'DEBIT' || $set == 'CREDIT')
$cond[] = array('Entry.crdr' => $set);
$query['conditions'][] = array('Entry.crdr' => $set);
else
die("INVALID RECONCILE SET");
$link['DoubleEntry'] += array();
/* if ($set == 'CHARGE') */
/* $link['Payment'] = array('fields' => array("SUM(ChargesPayment.amount) AS applied")); */
/* if ($set == 'PAYMENT') */
/* $link['Charge'] = array('fields' => array("SUM(ChargesPayment.amount) AS applied")); */
/* if ($set == 'DEBIT') */
/* $link['Credit'] = array('fields' => array("SUM(Reconciliation.amount) AS applied")); */
/* if ($set == 'CREDIT') */
/* $link['Debit'] = array('fields' => array("SUM(Reconciliation.amount) AS applied")); */
if (!isset($query['link']['DoubleEntry']))
$query['link']['DoubleEntry'] = array();
if ($set == 'CHARGE')
$link['Payment'] = array('fields' => array("SUM(AppliedPayment.amount) AS applied"));
$query['link']['Payment'] = array('fields' => array("SUM(AppliedPayment.amount) AS reconciled"));
if ($set == 'PAYMENT')
$link['Charge'] = array('fields' => array("SUM(AppliedCharge.amount) AS applied"));
if ($set == 'DEBIT')
$link['Credit'] = array('fields' => array("SUM(AppliedCredit.amount) AS applied"));
if ($set == 'CREDIT')
$link['Debit'] = array('fields' => array("SUM(AppliedDebit.amount) AS applied"));
$query['link']['Charge'] = array('fields' => array("SUM(AppliedCharge.amount) AS reconciled"));
/* if ($set == 'DEBIT') */
/* $query['link']['Credit'] = array('fields' => array("SUM(AppliedCredit.amount) AS reconciled")); */
/* if ($set == 'CREDIT') */
/* $query['link']['Debit'] = array('fields' => array("SUM(AppliedDebit.amount) AS reconciled")); */
$result = $this->find
('all', array
(
'link' => $link,
'conditions' => $cond,
'group' => 'Entry.id',
));
pr(array('reconciledSet', compact('set', 'cond', 'link', 'result')));
$query['group'] = 'Entry.id';
return $query;
}
function reconciledSet($set, $query = null, $unrec = false) {
$lquery = $this->reconciledSetQuery($set, $query);
$result = $this->find('all', $lquery);
//pr(array('reconciledSet', compact('set', 'lquery', 'result')));
$resultset = array();
foreach ($result AS $i => $entry) {
@@ -424,7 +333,7 @@ OPTION 2
unset($entry[0]);
$entry['DoubleEntry']['balance'] =
$entry['DoubleEntry']['amount'] - $entry['DoubleEntry']['applied'];
$entry['DoubleEntry']['amount'] - $entry['DoubleEntry']['reconciled'];
// Since HAVING isn't a builtin feature of CakePHP,
// we'll have to post-process to get the desired entries
@@ -438,9 +347,10 @@ OPTION 2
}
}
//$result['stats'] = $this->stats(null, $cond);
pr($this->stats(null, $cond, $link));
return $resultset;
//$resultset['stats'] = $this->stats(null, $query);
//pr($this->stats(null, $query));
return array('entries' => $resultset,
'summary' => $this->stats(null, $query, $set));
}
@@ -451,93 +361,36 @@ OPTION 2
* - Returns a list of entries that reconcile against the given entry.
* (such as payments towards a charge).
*/
function reconciledEntries($id, $cond = null, $link = null) {
if (!isset($cond))
$cond = array();
if (!isset($link))
$link = array();
$cond[] = array('Entry.id' => $id);
function reconciledEntriesQuery($id, $query = null) {
$this->queryInit($query, false);
$entry = $this->find('first', array('conditions' => array('Entry.id' => $id),
'recursive' => -1));
$entry = $entry['Entry'];
$contain = array();
$query['conditions'][] = array('Entry.id' => $id);
if ($entry['type'] == 'CHARGE')
$contain['Payment'] = array('fields' => array('Payment.*', 'ChargesPayment.amount'));
$query['contain']['Payment'] = array('fields' => array('Payment.*', 'ChargesPayment.amount'));
if ($entry['type'] == 'PAYMENT')
$contain['Charge'] = array('fields' => array('Charge.*', 'ChargesPayment.amount'));
if ($entry['crdr'] == 'DEBIT')
$contain['Credit'] = array('fields' => array('Credit.*', 'Reconciliation.amount'));
if ($entry['crdr'] == 'CREDIT')
$contain['Debit'] = array('fields' => array('Debit.*', 'Reconciliation.amount'));
$query['contain']['Charge'] = array('fields' => array('Charge.*', 'ChargesPayment.amount'));
/* if ($entry['crdr'] == 'DEBIT') */
/* $query['contain']['Credit'] = array('fields' => array('Credit.*', 'Reconciliation.amount')); */
/* if ($entry['crdr'] == 'CREDIT') */
/* $query['contain']['Debit'] = array('fields' => array('Debit.*', 'Reconciliation.amount')); */
return $query;
}
function reconciledEntries($id, $query = null) {
$lquery = $this->reconciledEntriesQuery($id, $query);
//pr(array('reconciledEntries', compact('entry', 'contain')));
$result = array();
$result['entries'] = $this->find
('first', array
(
'contain' => $contain,
$result = $this->find('first', $lquery);
unset($result['Entry']);
/* 'zcontain' => array(//'DoubleEntry' => array('fields' => array('amount')), */
/* 'REntry' => array('fields' => array('Reconciliation.amount'), */
/* 'DoubleEntry'), */
/* ), */
/* 'zlink' => array(//'DoubleEntry' => array('fields' => array('amount')), */
/* 'REntry' => array('fields' => array('REntry.*', 'Reconciliation.amount'), */
/* 'DoubleEntry'), */
/* ), */
/* 'zlink' => array(//'DoubleEntry' => array('fields' => array('amount')), */
/* 'Debit' => array('fields' => array('AppliedDebit.amount'), */
/* 'DoubleEntry' => array('alias' => 'DebitDoubleEntry')), */
/* 'Credit' => array('fields' => array('AppliedCredit.amount'), */
/* 'DoubleEntry' => array('alias' => 'CreditDoubleEntry')), */
/* ), */
'fields' => array('id'),
'conditions' => $cond,
));
unset($result['entries']['Entry']);
$result['stats'] = $this->stats($id);
return $result;
/* $balance = $this->find */
/* ('first', array */
/* ('link' => array */
/* ( */
/* "Charge" => array */
/* ('fields' => array("SUM(COALESCE(ChargesPayment.amount,0)) AS 'reconciling_charges'")), */
/* "Payment" => array */
/* ('fields' => array("SUM(COALESCE(ChargesPayment.amount,0)) AS 'reconciling_payments'")), */
/* ), */
/* 'fields' => array('Entry.amount'), */
/* 'group' => array('Entry.id'); */
/* 'conditions' => $cond, */
/* )); */
/* pr(compact('balance')); */
// pull up, since there should only be one
//$reconciling = $reconciling[0];
// Add the calculated fields to Entry
/* $reconciling['applied'] = 0; */
/* $reconciling['balance'] = $reconciling[0]['Entry']['amount']; */
/* foreach ($reconciling AS $i => $entry) { */
/* $reconciling['applied'] += $entry[0]['applied']; */
/* unset($reconciling[$i]['Entry']); */
/* } */
/* $reconciling['balance'] -= $reconciling['applied']; */
/* pr(compact('reconciling')); */
/* return $reconciling; */
return array('entries' => $result,
'summary' => $this->stats($id, $query));
}
@@ -547,44 +400,48 @@ OPTION 2
* function: stats
* - Returns summary data from the requested ledger entry
*/
function stats($id = null, $cond = null, $link = null) {
if (!isset($cond))
$cond = array();
if (!isset($link))
$link = array();
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))
$cond[] = array('Entry.id' => $id);
$query['conditions'][] = array('Entry.id' => $id);
/* $entry = $this->find('first', array('contain' => array('DoubleEntry.amount'), */
/* 'fields' => array('Entry.type', 'Entry.crdr'), */
/* 'conditions' => array('Entry.id' => $id))); */
/* pr(compact('entry')); */
/* $entry['Entry'] += $entry['DoubleEntry']; */
/* $entry = $entry['Entry']; */
if (isset($set))
$set = strtoupper($set);
//pr(array('stats()', compact('id', 'query', 'set')));
$rtypes = array('charge', 'payment',
// 'debit', 'credit',
);
$stats = array();
foreach(array('charge', 'payment', 'debit', 'credit') AS $rtype) {
foreach($rtypes AS $rtype) {
$Rtype = ucfirst($rtype);
$rlink = $link;
$rlink[$Rtype] = array('fields' => array("SUM(Applied{$Rtype}.amount) AS applied"));
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')) */
) {
pr(array('stats()', compact('id', 'cond', 'link', 'rlink')));
$rquery = $query;
$rquery['link'][$Rtype] =
array('fields' => array("SUM(COALESCE(Applied{$Rtype}.amount,0)) AS reconciled"));
if (1 || ($rtype == 'charge' && $entry['type'] == 'PAYMENT') ||
($rtype == 'payment' && $entry['type'] == 'CHARGE') ||
($rtype == 'debit' && $entry['crdr'] == 'CREDIT') ||
($rtype == 'credit' && $entry['crdr'] == 'DEBIT')) {
$result = $this->find
('first', array
('link' => $rlink,
'fields' => array("SUM(DoubleEntry.amount) AS total",
"SUM(DoubleEntry.amount) - SUM(Applied{$Rtype}.amount) AS unapplied"),
'conditions' => $cond,
//'group' => 'Entry.id',
));
pr(compact('Rtype', 'result'));
$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];
@@ -593,68 +450,6 @@ OPTION 2
}
}
return $stats;
/* $result = $this->find */
/* ('first', array */
/* ('link' => array('DoubleEntry' => array('fields' => array('amount')), */
/* 'Credit' => array('fields' => array()), */
/* 'Debit' => array('fields' => array())), */
/* 'fields' => array('Entry.crdr', */
/* "SUM(AppliedDebit.amount) AS 'applied_debits'", */
/* "SUM(AppliedCredit.amount) AS 'applied_credits'"), */
/* 'conditions' => $cond, */
/* 'group' => 'Entry.id', */
/* )); */
//pr(compact('result'));
$stats = array();
if ($result['Entry']['crdr'] == 'DEBIT') {
if ($result[0]['applied_debits'])
die('INCONSISTENT DATABASE ENTRIES');
$stats['applied'] = $result[0]['applied_credits'];
}
elseif ($result['Entry']['crdr'] == 'CREDIT') {
if ($result[0]['applied_credits'])
die('INCONSISTENT DATABASE ENTRIES');
$stats['applied'] = $result[0]['applied_debits'];
}
if (!isset($stats['applied']))
$stats['applied'] = 0;
$stats['unapplied'] = $result['DoubleEntry']['amount'] - $stats['applied'];
/* $reconciled = $this->find */
/* ('all', array */
/* ('link' => array */
/* ( */
/* "Charge" => array */
/* ('fields' => array */
/* ('id', */
/* "COALESCE(SUM(ChargesPayment.amount),0) AS 'reconciled'", */
/* "Entry.amount - COALESCE(SUM(ChargesPayment.amount),0) AS 'balance'", */
/* ), */
/* ), */
/* "Payment" => array */
/* ('fields' => array */
/* ('id', */
/* "COALESCE(SUM(ChargesPayment.amount),0) AS 'reconciled'", */
/* "Entry.amount - COALESCE(SUM(ChargesPayment.amount),0) AS 'balance'", */
/* ), */
/* ), */
/* ), */
/* 'conditions' => array(isset($cond) ? $cond : array(), */
/* array('Entry.id' => $id)), */
/* 'group' => 'Entry.id', */
/* )); */
return $stats;
}