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

@@ -81,7 +81,28 @@ class AppModel extends Model {
} //end getEnumValues
/**************************************************************************
**************************************************************************
**************************************************************************
* function: queryInit
* - Initializes the query fields
*/
function queryInit(&$query, $link = true) {
if (!isset($query))
$query = array();
if (!isset($query['conditions']))
$query['conditions'] = array();
if (!isset($query['group']))
$query['group'] = null;
if (!isset($query['fields']))
$query['fields'] = null;
if ($link && !isset($query['link']))
$query['link'] = array();
if (!$link && !isset($query['contain']))
$query['contain'] = array();
}
/**************************************************************************
**************************************************************************
**************************************************************************

View File

@@ -76,7 +76,7 @@ class AccountsController extends AppController {
function jqGridDataFields(&$params, &$model) {
return array_merge(array('Account.*'),
$this->Account->Ledger->DoubleEntry->debitCreditFields('DoubleEntry', 'CurrentLedger'));
$this->Account->Ledger->DoubleEntry->debitCreditFields(true, 'DoubleEntry', 'CurrentLedger'));
}
function jqGridDataConditions(&$params, &$model) {
@@ -245,8 +245,9 @@ class AccountsController extends AppController {
);
// Get all ledger entries of the CURRENT ledger
$entries = $this->Account->findLedgerEntries($id);
$account['CurrentLedger']['DoubleEntry'] = $entries['Entries'];
$entries = $this->Account->ledgerEntries($id);
//pr(compact('entries'));
$account['CurrentLedger']['DoubleEntry'] = $entries;
// Summarize each ledger
foreach($account['Ledger'] AS &$ledger)
@@ -270,7 +271,7 @@ class AccountsController extends AppController {
}
function tst($id) {
$entries = $this->Account->unreconciledEntries($id);
//$entries = $this->Account->($id);
pr($entries);
}
}

View File

@@ -63,9 +63,9 @@ class CustomersController extends AppController {
function jqGridDataTables(&$params, &$model) {
$link = $this->jqGridDataCountTables($params, $model);
$link['link']['LedgerEntry'] = array('fields' => array());
$link['link']['LedgerEntry']['Ledger'] = array('fields' => array());
$link['link']['LedgerEntry']['Ledger']['Account'] = array('fields' => array());
$link['link']['DoubleEntry'] = array('fields' => array());
$link['link']['DoubleEntry']['Ledger'] = array('fields' => array());
$link['link']['DoubleEntry']['Ledger']['Account'] = array('fields' => array());
// INNER JOIN would be great, as it would ensure we're only looking
// at the ledger entries that we truly want. However, this also
// removes from the query any units that do not yet have a ledger
@@ -73,10 +73,10 @@ class CustomersController extends AppController {
// and LEFT JOIN it to the rest. Grouping of JOINs, however, is
// implemented with the 'joins' tag, and is not available through
// the Linkable behavior interface.
//$link['link']['LedgerEntry']['Ledger']['Account']['type'] = 'INNER';
$link['link']['LedgerEntry']['Ledger']['Account']['conditions']
//$link['link']['DoubleEntry']['Ledger']['Account']['type'] = 'INNER';
$link['link']['DoubleEntry']['Ledger']['Account']['conditions']
= array('Account.id' =>
$this->Customer->LedgerEntry->Ledger->Account->accountReceivableAccountID());
$this->Customer->DoubleEntry->Ledger->Account->accountReceivableAccountID());
return $link;
}
@@ -85,9 +85,9 @@ class CustomersController extends AppController {
$fields = $db->fields($model, $model->alias);
$fields[] = ('COUNT(DISTINCT CurrentLease.id) AS lease_count');
$fields[] = ("SUM(IF(Account.id IS NULL, 0," .
" IF(LedgerEntry.debit_ledger_id = Account.id," .
" IF(DoubleEntry.debit_ledger_id = Account.id," .
" 1, -1))" .
" * IF(LedgerEntry.amount IS NULL, 0, LedgerEntry.amount))" .
" * IF(DoubleEntry.amount IS NULL, 0, DoubleEntry.amount))" .
" AS 'balance'");
return $fields;
}
@@ -247,10 +247,18 @@ class CustomersController extends AppController {
$this->redirect(array('action'=>'index'));
}
$customer = $this->Customer->details($id);
/* //$result = $this->Customer->securityDeposits($id); */
/* $result = $this->Customer->excessPayments($id); */
/* //$result = $this->Customer->unreconciledCharges($id); */
/* echo('<HR>'); */
/* pr($result); */
/* $this->autoRender = false; */
/* return; */
$customer = $this->Customer->details($id);
//pr($customer);
$outstanding_balance = $customer['stats']['balance'];
$outstanding_deposit = $customer['deposits']['summary']['balance'];
$outstanding_deposit = $customer['deposits']['summary']['Payment']['reconciled'];
// Figure out if this customer has any non-closed leases
$show_moveout = false;
@@ -429,17 +437,17 @@ class CustomersController extends AppController {
*/
function refund() {
$entries = $this->Customer->LedgerEntry->find
$entries = $this->Customer->DoubleEntry->find
('all', array
('contain' => false,
'conditions' => array('LedgerEntry.id' =>
'conditions' => array('DoubleEntry.id' =>
//array(199,200,201)
61
),
));
pr(compact('entries'));
$this->Customer->LedgerEntry->reverse($entries);
$this->Customer->DoubleEntry->reverse($entries);
}
@@ -473,8 +481,8 @@ class CustomersController extends AppController {
if (!count($unreconciled['entries']['entry']))
unset($unreconciled['entries']['entry']);
pr($unreconciled);
//$reconciled = $cust->reconcileNewLedgerEntry($cust_id, 'credit', $amount);
//pr($unreconciled);
//$reconciled = $cust->reconcileNewDoubleEntry($cust_id, 'credit', $amount);
$opts = array();
//$opts['format'] = 'tags';

View File

@@ -35,7 +35,11 @@ class EntriesController extends AppController {
$link =
array(// Models
'Account' =>
array('fields' => array('id', 'name'),
array('fields' => array('id', 'name', 'type'),
),
'Ledger' =>
array('fields' => array('id', 'sequence'),
),
'DoubleEntry' => array
@@ -43,6 +47,20 @@ class EntriesController extends AppController {
array('fields' => array('id', 'stamp'),
),
'DebitLedger' =>
array('fields' => array('id'),
'Account' => array('alias' => 'DebitAccount',
'fields' => array('id', 'name'),
),
),
'CreditLedger' =>
array('fields' => array('id'),
'Account' => array('alias' => 'CreditAccount',
'fields' => array('id', 'name'),
),
),
'Customer' =>
array('fields' => array('id', 'name'),
),
@@ -56,23 +74,24 @@ class EntriesController extends AppController {
),
);
if ($params['action'] === 'collected' ||
isset($params['custom']['reconcile_id'])) {
$link['Payment'] = array(//'linkalias' => 'MatchingPayment',
if (count(array_intersect($params['fields'], array('applied'))) == 1) {
$link['Payment'] = array('DoubleEntry' =>
array('alias' => 'PaymentDoubleEntry',
'Receipt'),
'Account' => array('alias' => 'PaymentAccount'),
'Receipt');
$link['Charge'] = array(//'linkalias' => 'MatchingCharge',
);
$link['Charge'] = array('DoubleEntry' =>
array('alias' => 'ChargeDoubleEntry',
'Invoice'),
'Account' => array('alias' => 'ChargeAccount'),
'Invoice');
);
}
if (isset($params['custom']['ledger_id'])) {
$link['Ledger'] =
array('fields' => array('id', 'sequence'),
'Account' =>
array('fields' => array('id', 'name'),
),
);
elseif (isset($params['custom']['customer_id']) || isset($params['custom']['lease_id'])) {
$link['Charge'] = array('DoubleEntry' =>
array('alias' => 'ChargeDoubleEntry',
'Invoice'),
'Account' => array('alias' => 'ChargeAccount'),
);
}
return array('link' => $link);
@@ -81,20 +100,40 @@ class EntriesController extends AppController {
function jqGridDataFields(&$params, &$model) {
$fields = parent::jqGridDataFields($params, $model);
if (count(array_intersect($params['fields'], array('applied'))) == 1)
$fields[] = ('SUM(COALESCE(AppliedPayment.amount,0)' .
' + COALESCE(AppliedCharge.amount,0)) AS applied');
if (!isset($fields))
$fields = array('Entry.*');
if (isset($params['custom']['reconcile_id'])) {
$fields[] = array("IF(Entry.type = 'CHARGE',",
" COALESCE(AppliedCharge.amount,0),",
" COALESCE(AppliedPayment.amount,0))",
" AS 'applied'");
$fields[] = array("Entry.amount - (",
"IF(Entry.type = 'CHARGE',",
" COALESCE(AppliedCharge.amount,0),",
" COALESCE(AppliedPayment.amount,0))",
") AS 'balance'");
/* if (isset($params['custom']['reconcile_id'])) { */
/* $fields[] = array("IF(Entry.type = 'CHARGE',", */
/* " COALESCE(AppliedCharge.amount,0),", */
/* " COALESCE(AppliedPayment.amount,0))", */
/* " AS 'applied'"); */
/* $fields[] = array("Entry.amount - (", */
/* "IF(Entry.type = 'CHARGE',", */
/* " COALESCE(AppliedCharge.amount,0),", */
/* " COALESCE(AppliedPayment.amount,0))", */
/* ") AS 'balance'"); */
/* } */
if (isset($params['custom']['customer_id']) || isset($params['custom']['lease_id'])) {
$fields[] = "IF(Entry.type = 'CHARGE', DoubleEntry.amount, NULL) AS debit";
$fields[] = "IF(Entry.type = 'PAYMENT', DoubleEntry.amount, NULL) AS credit";
$fields[] = "IF(Entry.type = 'CHARGE', 1, -1) * DoubleEntry.amount AS balance";
}
else {
if (count(array_intersect($params['fields'], array('applied'))) == 1)
$fields[] = ('SUM(COALESCE(AppliedPayment.amount,0)' .
' + COALESCE(AppliedCharge.amount,0)) AS applied');
if (count(array_intersect($params['fields'], array('debit', 'credit'))) >= 1) {
$fields = array_merge($fields,
$this->Entry->DoubleEntry->debitCreditFields());
/* $fields = array_merge($fields, */
/* $this->Entry->Account->debitCreditFields()); */
/* $fields[] = "IF(Entry.crdr = 'CREDIT', DoubleEntry.amount, NULL) AS credit"; */
/* $fields[] = "IF(Entry.crdr = 'DEBIT', DoubleEntry.amount, NULL) AS debit"; */
/* $fields[] = "IF(Account.type IN Entry.crdr = 'DEBIT', DoubleEntry.amount, NULL) AS debit"; */
}
}
if ($params['action'] === 'collected')
@@ -145,13 +184,37 @@ class EntriesController extends AppController {
}
if (isset($params['custom']['customer_id'])) {
$customer_id = $params['custom']['customer_id'];
$conditions[] =
array('Customer.id' => $params['custom']['customer_id']);
array('OR' =>
array(array(array('Entry.type' => 'CHARGE'),
array('DoubleEntry.customer_id' => $customer_id)),
array(array('Entry.type' => 'PAYMENT'),
array('ChargeDoubleEntry.customer_id' => $customer_id)),
),
);
}
if (isset($params['custom']['lease_id'])) {
$lease_id = $params['custom']['lease_id'];
$conditions[] =
array('Lease.id' => $params['custom']['lease_id']);
array('OR' =>
array(array(array('Entry.type' => 'CHARGE'),
array('DoubleEntry.lease_id' => $lease_id)),
array(array('Entry.type' => 'PAYMENT'),
array('ChargeDoubleEntry.lease_id' => $lease_id)),
),
);
/* array('OR' => */
/* array('AND' => */
/* array(array('Entry.type' => 'CHARGE'), */
/* array('DoubleEntry.lease_id' => $lease_id)) */
/* ), */
/* array('AND' => */
/* array(array('Entry.type' => 'PAYMENT'), */
/* array('ChargeDoubleEntry.lease_id' => $lease_id)), */
/* ), */
/* ); */
}
if (isset($params['custom']['transaction_id'])) {

View File

@@ -57,9 +57,9 @@ class LeasesController extends AppController {
function jqGridDataTables(&$params, &$model) {
$link = $this->jqGridDataCountTables($params, $model);
$link['link']['LedgerEntry'] = array('fields' => array());
$link['link']['LedgerEntry']['Ledger'] = array('fields' => array());
$link['link']['LedgerEntry']['Ledger']['Account'] = array('fields' => array());
$link['link']['DoubleEntry'] = array('fields' => array());
$link['link']['DoubleEntry']['Ledger'] = array('fields' => array());
$link['link']['DoubleEntry']['Ledger']['Account'] = array('fields' => array());
// INNER JOIN would be great, as it would ensure we're only looking
// at the ledger entries that we truly want. However, this also
// removes from the query any leases that do not yet have a ledger
@@ -67,10 +67,10 @@ class LeasesController extends AppController {
// and LEFT JOIN it to the rest. Grouping of JOINs, however, is
// implemented with the 'joins' tag, and is not available through
// the Linkable behavior interface.
//$link['link']['LedgerEntry']['Ledger']['Account']['type'] = 'INNER';
$link['link']['LedgerEntry']['Ledger']['Account']['conditions']
//$link['link']['DoubleEntry']['Ledger']['Account']['type'] = 'INNER';
$link['link']['DoubleEntry']['Ledger']['Account']['conditions']
= array('Account.id' =>
$this->Lease->LedgerEntry->Ledger->Account->accountReceivableAccountID());
$this->Lease->DoubleEntry->Ledger->Account->accountReceivableAccountID());
return $link;
}
@@ -78,9 +78,9 @@ class LeasesController extends AppController {
$db = &$model->getDataSource();
$fields = $db->fields($model, $model->alias);
$fields[] = ("SUM(IF(Account.id IS NULL, 0," .
" IF(LedgerEntry.debit_ledger_id = Account.id," .
" IF(DoubleEntry.debit_ledger_id = Account.id," .
" 1, -1))" .
" * IF(LedgerEntry.amount IS NULL, 0, LedgerEntry.amount))" .
" * IF(DoubleEntry.amount IS NULL, 0, DoubleEntry.amount))" .
" AS 'balance'");
return $fields;
}
@@ -252,10 +252,10 @@ class LeasesController extends AppController {
$receipt_transaction = array_intersect_key($this->data,
array('Transaction'=>1,
'transaction_id'=>1));
foreach ($data['LedgerEntry'] AS $entry) {
foreach ($data['DoubleEntry'] AS $entry) {
// Create the receipt entry, and reconcile the credit side
// of the double-entry (which should be A/R) as a payment.
$ids = $this->LedgerEntry->Ledger->Account->postLedgerEntry
$ids = $this->DoubleEntry->Ledger->Account->postDoubleEntry
($receipt_transaction,
array_intersect_key($entry, array('MonetarySource'=>1))
+ array_intersect_key($entry, array('account_id'=>1)),
@@ -269,6 +269,14 @@ class LeasesController extends AppController {
if ($ids['error'])
$ret = false;
$db = &$model->getDataSource();
$fields = $db->fields($model, $model->alias);
$fields[] = ("SUM(IF(Account.id IS NULL, 0," .
" IF(LedgerEntry.debit_ledger_id = Account.id," .
" 1, -1))" .
" * IF(LedgerEntry.amount IS NULL, 0, LedgerEntry.amount))" .
" AS 'balance'");
return $fields;
$receipt_transaction = array_intersect_key($ids,
array('transaction_id'=>1,
'split_transaction_id'=>1));
@@ -315,7 +323,7 @@ class LeasesController extends AppController {
array('stats' => $this->Lease->stats($id)));
// Determine the lease security deposit
$deposit = $this->Lease->findSecurityDeposits($lease['Lease']['id']);
$deposit = $this->Lease->securityDeposits($lease['Lease']['id']);
$this->set(compact('deposit'));
$this->set('customer', $lease['Customer']);
$this->set('unit', $lease['Unit']);
@@ -371,7 +379,7 @@ class LeasesController extends AppController {
array('stats' => $this->Lease->stats($id)));
// Determine the lease security deposit
$deposit = $this->Lease->findSecurityDeposits($lease['Lease']['id']);
$deposit = $this->Lease->securityDeposits($lease['Lease']['id']);
if ($deposit['summary']['balance'] > 0)
die("Still have un-utilized security deposit");
@@ -406,7 +414,7 @@ class LeasesController extends AppController {
/* $outstanding_balance = $stats['balance']; */
/* // Determine the lease security deposit */
/* $deposits = $this->Lease->findSecurityDeposits($id); */
/* $deposits = $this->Lease->securityDeposits($id); */
/* $outstanding_deposit = $deposits['summary']['balance']; */
@@ -515,8 +523,8 @@ class LeasesController extends AppController {
$outstanding_balance = $lease['Lease']['stats']['balance'];
// Determine the lease security deposit
$deposits = $this->Lease->findSecurityDeposits($lease['Lease']['id']);
$outstanding_deposit = $deposits['summary']['balance'];
$deposits = $this->Lease->securityDeposits($lease['Lease']['id']);
$outstanding_deposit = $deposits['summary']['Payment']['reconciled'];
// Set up dynamic menu items
if (!isset($lease['Lease']['close_date'])) {

View File

@@ -67,7 +67,7 @@ class LedgersController extends AppController {
function jqGridDataFields(&$params, &$model) {
return array_merge(array('Ledger.*',
'CONCAT(Account.id, "-", Ledger.sequence) AS id_sequence'),
$this->Ledger->DoubleEntry->debitCreditFields());
$this->Ledger->DoubleEntry->debitCreditFields(true));
}
function jqGridDataConditions(&$params, &$model) {

View File

@@ -97,6 +97,41 @@ class Account extends AppModel {
}
/**************************************************************************
**************************************************************************
**************************************************************************
* 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.
*/
function debitCreditFields($id, $sum = false,
$entry_name = 'Entry', $double_name = 'DoubleEntry') {
$ftype = strtoupper($this->fundamentalType($id));
$fields = array
(
($sum ? 'SUM(' : '') .
"IF({$entry_name}.crdr = 'DEBIT', {$double_name}.amount, NULL)" .
($sum ? ')' : '') . ' AS debit' . ($sum ? 's' : ''),
($sum ? 'SUM(' : '') .
"IF({$entry_name}.crdr = 'CREDIT', {$double_name}.amount, NULL)" .
($sum ? ')' : '') . ' AS credit' . ($sum ? 's' : ''),
($sum ? 'SUM(' : '') .
"IF({$entry_name}.crdr = '$ftype', 1, -1) * {$double_name}.amount" .
// IF({$double_name}.amount, {$double_name}.amount, 0)" .
($sum ? ')' : '') . ' AS balance',
);
if ($sum)
$fields[] = "COUNT({$entry_name}.id) AS entries";
return $fields;
}
/**************************************************************************
**************************************************************************
**************************************************************************
@@ -346,7 +381,7 @@ class Account extends AppModel {
$link['Account'] = array('fields' => array());
$cond[] = array('Account.id' => $id);
$set = $this->Ledger->Entry->reconciledSet($set, $cond, $link, true);
pr(compact('set'));
//pr(compact('set'));
return $set;
}
@@ -416,7 +451,7 @@ class Account extends AppModel {
function reconcileLedgerEntries($id, $cond = null) {
$unreconciled = $this->findUnreconciledLedgerEntries($id, null, $cond);
pr(compact('unreconciled'));
//pr(compact('unreconciled'));
$entry = array();
foreach (array('debit', 'credit') AS $dc)
@@ -465,7 +500,7 @@ class Account extends AppModel {
$unreconciled['debit'] ['unapplied'] = $unreconciled['credit']['balance'];
$unreconciled['credit']['unapplied'] = $unreconciled['debit'] ['balance'];
pr(compact('unreconciled'));
//pr(compact('unreconciled'));
return $unreconciled;
}
@@ -787,37 +822,47 @@ class Account extends AppModel {
* - Returns summary data from the requested account.
*/
function stats($id = null, $all = false, $cond = null) {
function stats($id = null, $all = false, $query = null) {
if (!$id)
return null;
// All old, closed ledgers MUST balance to 0.
// However, the user may want the ENTIRE running totals,
// (not just the balance), so we may have to query all
// ledgers, as dictated by the $all parameter.
$this->queryInit($query);
$account = $this->find('first',
array('contain' =>
($all
? array('Ledger' => array
('fields' => array('id')))
: array('CurrentLedger' => array
('fields' => array('id')))
),
'conditions' => array
(array('Account.id' => $id))
));
/* if ($all) { */
/* if (!isset($query['link']['Ledger'])) */
/* $query['link']['Ledger'] = array(); */
/* if (!isset($query['link']['Ledger']['fields'])) */
/* $query['link']['Ledger']['fields'] = array(); */
/* $query['link']['Ledger']['fields'][] = 'id'; */
/* } */
/* else { */
/* if (!isset($query['link']['CurrentLedger'])) */
/* $query['link']['CurrentLedger'] = array(); */
/* if (!isset($query['link']['CurrentLedger']['fields'])) */
/* $query['link']['CurrentLedger']['fields'] = array(); */
/* $query['link']['CurrentLedger']['fields'][] = 'id'; */
/* } */
$stats = array();
if ($all) {
foreach ($account['Ledger'] AS $ledger)
$this->statsMerge($stats['Ledger'],
$this->Ledger->stats($ledger['id'], $cond));
}
else {
$stats['Ledger'] =
$this->Ledger->stats($account['CurrentLedger']['id'], $cond);
}
/* $query['conditions'][] = array('Account.id' => $id); */
/* $account = $this->find('first', $query); */
$query['link'] = array('Account' => $query['link']);
foreach ($this->ledgers($id, $all) AS $ledger)
$this->statsMerge($stats['Ledger'],
$this->Ledger->stats($ledger, $query));
/* $stats = array(); */
/* if ($all) { */
/* foreach ($account['Ledger'] AS $ledger) */
/* $this->statsMerge($stats['Ledger'], */
/* $this->Ledger->stats($ledger['id'], $query)); */
/* } */
/* else { */
/* $stats['Ledger'] = */
/* $this->Ledger->stats($account['CurrentLedger']['id'], $query); */
/* } */
return $stats;
}

View File

@@ -73,26 +73,27 @@ class Customer extends AppModel {
/**************************************************************************
**************************************************************************
**************************************************************************
* function: findSecurityDeposits
* function: securityDeposits
* - Returns an array of security deposit entries
*/
function findSecurityDeposits($id, $link = null) {
/* pr(array('function' => 'Customer::findSecurityDeposits', */
/* 'args' => compact('id', 'link'), */
/* )); */
function securityDeposits($id, $query = null) {
$this->queryInit($query);
$A = new Account();
$entries = $A->ledgerEntries
($A->securityDepositAccountID(),
true, array('DoubleEntry.customer_id' => $id), $link);
/* pr(array('function' => 'Customer::findSecurityDeposits', */
/* 'args' => compact('id', 'link'), */
/* 'vars' => compact('customer'), */
/* 'return' => compact('entries'), */
/* )); */
if (!isset($query['link']['DoubleEntry']))
$query['link']['DoubleEntry'] = array();
if (!isset($query['link']['DoubleEntry']['Customer']))
$query['link']['DoubleEntry']['Customer'] = array();
if (!isset($query['link']['DoubleEntry']['Customer']['fields']))
$query['link']['DoubleEntry']['Customer']['fields'] = array();
return $entries;
$query['conditions'][] = array('Customer.id' => $id);
$query['conditions'][] = array('Entry.account_id' => $A->securityDepositAccountID());
$set = $this->DoubleEntry->Entry->reconciledSet('CHARGE', $query);
//pr(compact('set'));
return $set;
}
@@ -103,20 +104,45 @@ class Customer extends AppModel {
* - Returns charges have not yet been fully paid
*/
function unreconciledCharges($id, $cond = null, $link = null) {
if (!isset($cond))
$cond = array();
if (!isset($link))
$link = array();
if (!isset($link['DoubleEntry']))
$link['DoubleEntry'] = array();
if (!isset($link['DoubleEntry']['Customer']))
$link['DoubleEntry']['Customer'] = array();
if (!isset($link['DoubleEntry']['Customer']['fields']))
$link['DoubleEntry']['Customer']['fields'] = array();
$cond[] = array('Customer.id' => $id);
$set = $this->DoubleEntry->Entry->reconciledSet('CHARGE', $cond, $link, true);
pr(compact('set'));
function unreconciledCharges($id, $query = null) {
$this->queryInit($query);
if (!isset($query['link']['DoubleEntry']))
$query['link']['DoubleEntry'] = array();
if (!isset($query['link']['DoubleEntry']['Customer']))
$query['link']['DoubleEntry']['Customer'] = array();
if (!isset($query['link']['DoubleEntry']['Customer']['fields']))
$query['link']['DoubleEntry']['Customer']['fields'] = array();
$query['conditions'][] = array('Customer.id' => $id);
$set = $this->DoubleEntry->Entry->reconciledSet('CHARGE', $query, true);
//pr(compact('set'));
return $set;
}
/**************************************************************************
**************************************************************************
**************************************************************************
* function: excessPayments
* - Returns payments which have not yet been fully utilized
*/
function excessPayments($id, $query = null) {
$this->queryInit($query);
if (!isset($query['link']['DoubleEntry']))
$query['link']['DoubleEntry'] = array();
if (!isset($query['link']['DoubleEntry']['Customer']))
$query['link']['DoubleEntry']['Customer'] = array();
if (!isset($query['link']['DoubleEntry']['Customer']['fields']))
$query['link']['DoubleEntry']['Customer']['fields'] = array();
$query['conditions'][] = array('Customer.id' => $id);
$set = $this->DoubleEntry->Entry->reconciledSet('PAYMENT', $query, true);
//pr(compact('set'));
return $set;
}
@@ -125,8 +151,7 @@ class Customer extends AppModel {
**************************************************************************
**************************************************************************
* function: paymentWouldReconcile
* - Returns which ledger entries a new credit/debit would
* reconcile, and how much.
* - Returns which charges a new payment would reconcile
*
* - REVISIT <AP> 20090617
* This should be subject to different algorithms, such
@@ -135,16 +160,17 @@ class Customer extends AppModel {
* whatever algorithm is simplest.
*/
function paymentWouldReconcile($id, $amount, $cond = null, $link = null) {
function paymentWouldReconcile($id, $amount, $query = null) {
$unreconciled = array($ofund => array('entry'=>array(), 'balance'=>0));
$applied = 0;
if ($amount <= 0)
return;
$unreconciled = $this->unreconciledEntries($id, 'CHARGE', $cond, $link);
$unreconciled = array();
$unreconciled['entries'] = $this->unreconciledCharges($id, $query);
foreach ($unreconciled AS $i => &$item) {
foreach ($unreconciled['entries'] AS $i => &$item) {
$entry =& $item['DoubleEntry'];
// Determine if amount is sufficient to cover the entry
if ($amount > $entry['balance'])
@@ -170,51 +196,6 @@ class Customer extends AppModel {
}
/**************************************************************************
**************************************************************************
**************************************************************************
* function: findUnreconciledLedgerEntries
* - Returns ledger entries that are not yet reconciled
* (such as charges not paid).
*/
function findUnreconciledLedgerEntries($id = null, $fundamental_type = null) {
$A = new Account();
$unreconciled = $A->findUnreconciledLedgerEntries
($A->accountReceivableAccountID(),
$fundamental_type,
array('DoubleEntry.customer_id' => $id));
return $unreconciled;
}
/**************************************************************************
**************************************************************************
**************************************************************************
* function: amountWouldReconcile
* - Returns which ledger entries a new credit/debit would
* reconcile, and how much.
*
* - REVISIT <AP> 20090617
* This should be subject to different algorithms, such
* as apply to oldest charges first, newest first, to fees
* before rent, etc. Until we get there, I'll hardcode
* whatever algorithm is simplest.
*/
function amountWouldReconcile($id, $fundamental_type, $amount) {
$A = new Account();
$reconciled = $A->amountWouldReconcile
($A->accountReceivableAccountID(),
$fundamental_type,
$amount,
array('DoubleEntry.customer_id' => $id));
return $reconciled;
}
/**************************************************************************
**************************************************************************
**************************************************************************
@@ -273,7 +254,7 @@ class Customer extends AppModel {
$customer['stats'] = $this->stats($id);
// Figure out the total security deposit for the current lease.
$customer['deposits'] = $this->findSecurityDeposits($id);
$customer['deposits'] = $this->securityDeposits($id);
return $customer;
}

View File

@@ -29,10 +29,12 @@ class DoubleEntry extends AppModel {
'Invoice' => array(
'className' => 'Transaction',
'conditions' => array('Invoice.type' => 'INVOICE'),
'foreignKey' => 'transaction_id',
),
'Receipt' => array(
'className' => 'Transaction',
'conditions' => array('Invoice.type' => 'RECEIPT'),
'foreignKey' => 'transaction_id',
),
@@ -81,7 +83,7 @@ class DoubleEntry extends AppModel {
}
function debitCreditFields($double_name = 'DoubleEntry', $ledger_name = 'Ledger', $sum = true) {
function debitCreditFields($sum = false, $double_name = 'DoubleEntry', $ledger_name = 'Ledger', $account_name = 'Account') {
$fields = array
(
($sum ? 'SUM(' : '') .
@@ -95,7 +97,7 @@ class DoubleEntry extends AppModel {
($sum ? ')' : '') . ' AS credit' . ($sum ? 's' : ''),
($sum ? 'SUM(' : '') .
"IF(Account.type IN ('ASSET', 'EXPENSE'),
"IF({$account_name}.type IN ('ASSET', 'EXPENSE'),
IF({$double_name}.debit_ledger_id = {$ledger_name}.id, 1, -1),
IF({$double_name}.credit_ledger_id = {$ledger_name}.id, 1, -1)
) * IF({$double_name}.amount, {$double_name}.amount, 0)" .

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;
}

View File

@@ -16,66 +16,27 @@ class Lease extends AppModel {
/**************************************************************************
**************************************************************************
**************************************************************************
* function: accountId
* - Returns the accountId of the given lease
*/
function accountId($id) {
$A = new Account();
return $A->invoiceAccountID();
}
/**************************************************************************
**************************************************************************
**************************************************************************
* function: findAccountEntries
* - Returns an array of ledger entries from the account of the given
* lease.
*/
function findAccountEntries($id, $all = false, $cond = null, $link = null) {
/* pr(array('function' => 'Lease::findAccountEntries', */
/* 'args' => compact('id', 'all', 'cond', 'link'), */
/* )); */
if (!isset($cond))
$cond = array();
$cond[] = array('DoubleEntry.lease_id' => $id);
$A = new Account();
$entries = $A->findLedgerEntries($this->accountId($id),
$all, $cond, $link);
/* pr(array('function' => 'Lease::findAccountEntries', */
/* 'args' => compact('id', 'all', 'cond', 'link'), */
/* 'vars' => compact('lease'), */
/* 'return' => compact('entries'), */
/* )); */
return $entries;
}
/**************************************************************************
**************************************************************************
**************************************************************************
* function: findSecurityDeposits
* function: securityDeposits
* - Returns an array of security deposit entries
*/
function findSecurityDeposits($id, $link = null) {
/* pr(array('function' => 'Lease::findSecurityDeposits', */
/* 'args' => compact('id', 'link'), */
/* )); */
function securityDeposits($id, $query = null) {
$this->queryInit($query);
$A = new Account();
$entries = $A->findLedgerEntries
($A->securityDepositAccountID(),
true, array('DoubleEntry.lease_id' => $id), $link);
$this->id = $id;
$this->recursive = -1;
$this->read();
/* pr(array('function' => 'Lease::findSecurityDeposits', */
/* 'args' => compact('id', 'link'), */
/* 'vars' => compact('lease'), */
/* 'return' => compact('entries'), */
/* )); */
return $entries;
if (!isset($query['link']['DoubleEntry']))
$query['link']['DoubleEntry'] = array();
if (!isset($query['link']['DoubleEntry']['Lease']))
$query['link']['DoubleEntry']['Lease'] = array();
if (!isset($query['link']['DoubleEntry']['Lease']['fields']))
$query['link']['DoubleEntry']['Lease']['fields'] = array();
$query['conditions'][] = array('Lease.id' => $id);
return $this->Customer->securityDeposits
($this->data['Lease']['customer_id'], $query);
}
@@ -91,38 +52,40 @@ class Lease extends AppModel {
*/
function rentLastCharges($id) {
$A = new Account();
$rent_account_id = $this->DoubleEntry->Entry->Account->rentAccountID();
$entries = $this->find
('all',
array('link' =>
array(// Models
'DoubleEntry' => array
('Ledger' => array
('fields' => array(),
'Account' => array
('fields' => array(),
'Ledger' => array
('alias' => 'Lx',
'fields' => array(),
'DoubleEntry' => array
('alias' => 'LEx',
'fields' => array(),
'conditions' => array
('LEx.effective_date = DATE_ADD(DoubleEntry.through_date, INTERVAL 1 day)',
'LEx.lease_id = DoubleEntry.lease_id',
)
),
),
),
),
),
'DoubleEntry' =>
array('Entry'// =>
//array('fields'),
),
'DEx' =>
array('class' => 'DoubleEntry',
'conditions' => array
('DEx.effective_date = DATE_ADD(Entry.through_date, INTERVAL 1 day)',
'DEx.lease_id = DoubleEntry.lease_id',
),
'Ex' =>
array('class' => 'Entry',
'type' => 'INNER',
'conditions' => array
('Ex.account_id = Entry.account_id',
'Ex.type = Entry.type',
'Ex.crdr = Entry.crdr'),
),
),
),
//'fields' => array('id', 'amount', 'effective_date', 'through_date'),
'fields' => array(),
'conditions' => array(array('Lease.id' => $id),
array('Account.id' => $A->rentAccountID()),
array('LEx.id' => null),
array('Entry.type' => 'CHARGE'),
array('Entry.account_id' => $rent_account_id),
array('DEx.id' => null),
),
)
);
@@ -174,62 +137,76 @@ class Lease extends AppModel {
*/
function rentPaidThrough($id) {
$rent_account_id = $this->DoubleEntry->Entry->Account->rentAccountID();
// Income / Receipt / Money
// debit: A/R credit: Income <-- this entry
// debit: Receipt credit: A/R <-- ReceiptDoubleEntry, below
// debit: Money credit: Receipt <-- MoneyDoubleEntry, below
$rent = $this->DoubleEntry->Entry->reconciledSet
('CHARGE',
array('fields' =>
array('DATE_SUB(DoubleEntry.effective_date, INTERVAL 1 DAY) AS paid_through',
),
'conditions' =>
array(array('DoubleEntry.lease_id' => $id),
array('Entry.account_id' => $rent_account_id)),
'order' => array('DoubleEntry.effective_date'),
),
true);
$query = array
('link' => array
(
'CreditLedger' =>
array('fields' => array(),
'Account' =>
array('fields' => array(),
),
),
/* $query = array */
/* ('link' => */
/* array(// Models */
/* 'DoubleEntry' => */
/* array('Entry' => */
/* array(), */
/* 'fields' => array('SUM(COALESCE(MoneyDoubleEntryR.amount,0)) AS paid'), */
/* ), */
/* ), */
// We're searching for the Receipt<->A/R entries,
// which are debits on the A/R account. Find the
// reconciling entries to that A/R debit.
'DebitReconciliationDoubleEntry' =>
array('alias' => 'ReceiptDoubleEntry',
'fields' => array(),
/* // Finally, the Money (Cash/Check/etc) Entry is the one */
/* // which reconciles our ReceiptDoubleEntry debit */
/* 'DebitReconciliationDoubleEntry' => */
/* array('alias' => 'MoneyDoubleEntry', */
/* 'linkalias' => 'MoneyDoubleEntryR', */
/* ), */
/* ), */
/* ), */
// Finally, the Money (Cash/Check/etc) Entry is the one
// which reconciles our ReceiptDoubleEntry debit
'DebitReconciliationDoubleEntry' =>
array('alias' => 'MoneyDoubleEntry',
'linkalias' => 'MoneyDoubleEntryR',
'fields' => array('SUM(COALESCE(MoneyDoubleEntryR.amount,0)) AS paid'),
),
),
),
/* 'fields' => array('DoubleEntry.amount', */
/* 'DATE_SUB(DoubleEntry.effective_date, INTERVAL 1 DAY) AS paid_through', */
/* ), */
'fields' => array('DoubleEntry.amount',
'DATE_SUB(DoubleEntry.effective_date, INTERVAL 1 DAY) AS paid_through',
),
/* 'group' => 'DoubleEntry.id HAVING paid <> DoubleEntry.amount', */
'group' => 'DoubleEntry.id HAVING paid <> DoubleEntry.amount',
/* 'conditions' => array(array('DoubleEntry.lease_id' => $id), */
/* array('Account.id' => $this->DoubleEntry->Ledger->Account->rentAccountID()), */
/* ), */
/* 'order' => array('DoubleEntry.effective_date', */
/* ), */
/* ); */
'conditions' => array(array('DoubleEntry.lease_id' => $id),
array('Account.id' => $this->DoubleEntry->Ledger->Account->rentAccountID()),
),
'order' => array('DoubleEntry.effective_date',
),
);
/* $rent = $this->DoubleEntry->find('first', $query); */
//pr($rent);
if ($rent['entries'])
return $rent['entries'][0]['DoubleEntry']['paid_through'];
$rent = $this->DoubleEntry->find('first', $query);
$rent = $this->DoubleEntry->Entry->reconciledSet
('CHARGE',
array('conditions' =>
array(array('DoubleEntry.lease_id' => $id),
array('Entry.account_id' => $rent_account_id)),
'order' => array('Entry.through_date DESC'),
),
false);
if ($rent)
return $rent[0]['paid_through'];
return $rent[0]['Entry']['through_date'];
$query['fields'] = 'DoubleEntry.through_date';
$query['order'] = 'DoubleEntry.through_date DESC';
$query['group'] = 'DoubleEntry.id';
$rent = $this->DoubleEntry->find('first', $query);
if ($rent)
return $rent['DoubleEntry']['through_date'];
/* $query['fields'] = 'Entry.through_date'; */
/* $query['order'] = 'Entry.through_date DESC'; */
/* $query['group'] = 'DoubleEntry.id'; */
/* $rent = $this->DoubleEntry->find('first', $query); */
/* if ($rent) */
/* return $rent['DoubleEntry']['through_date']; */
return null;
}
@@ -432,16 +409,60 @@ class Lease extends AppModel {
* - Returns summary data from the requested lease.
*/
function stats($id = null) {
function stats($id = null, $query = null) {
if (!$id)
return null;
$A = new Account();
$stats = $A->stats($A->accountReceivableAccountID(), true,
array('DoubleEntry.lease_id' => $id));
$this->queryInit($query);
//$query['link'] = array('Lease' => $query['link']);
if (!isset($query['link']['DoubleEntry']))
$query['link']['DoubleEntry'] = array();
if (!isset($query['link']['Charge']))
$query['link']['Charge'] = array();
if (!isset($query['link']['Charge']['DoubleEntry']))
$query['link']['Charge']['DoubleEntry'] = array();
if (!isset($query['link']['Charge']['DoubleEntry']['Invoice']))
$query['link']['Charge']['DoubleEntry']['Invoice'] = array();
if (!isset($query['link']['Charge']['Account']))
$query['link']['Charge']['Account'] = array();
/* $query['link']['DoubleEntry']['fields'] = array(); */
/* $query['link']['Charge']['fields'] = array(); */
/* $query['link']['Charge']['Account']['fields'] = array(); */
/* $query['link']['Charge']['DoubleEntry']['fields'] = array(); */
/* $query['link']['Charge']['DoubleEntry']['Invoice']['fields'] = array(); */
$query['link']['Charge']['Account']['alias'] = 'ChargeAccount';
$query['link']['Charge']['DoubleEntry']['alias'] = 'ChargeDoubleEntry';
if (!isset($query['fields']))
$query['fields'] = array();
$query['fields'] = array_merge($query['fields'],
$this->DoubleEntry->Entry->chargePaymentFields(false));
$query['conditions'][] = array('OR' =>
array(array(array('Entry.type' => 'CHARGE'),
array('DoubleEntry.lease_id' => $id)),
array(array('Entry.type' => 'PAYMENT'),
array('ChargeDoubleEntry.lease_id' => $id)),
),
);
$query['group'] = null;
$stats = $this->DoubleEntry->Entry->find('all', $query);
pr(compact('query', 'stats'));
// The fields are all tucked into the [0] index,
// and the rest of the array is useless (empty).
$stats = $stats[0];
// Make sure we have a non-null balance
if (!isset($stats['balance']))
$stats['balance'] = 0;
// Pull to the top level and return
$stats = $stats['Ledger'];
return $stats;
}

View File

@@ -41,10 +41,11 @@ class Ledger extends AppModel {
function accountID($id) {
$this->cacheQueries = true;
$item = $this->find('first', array
('contain' => 'Account.id',
('link' => array('Account'),
'conditions' => array('Ledger.id' => $id),
));
$this->cacheQueries = false;
//pr(compact('id', 'item'));
return $item['Account']['id'];
}
@@ -120,29 +121,18 @@ class Ledger extends AppModel {
}
function debitCreditFields($id, $sum = false, $entry_name = 'Entry', $double_name = 'DoubleEntry') {
$ftype = strtoupper($this->Account->fundamentalType($this->accountID($id)));
$fields = array
(
($sum ? 'SUM(' : '') .
"IF({$entry_name}.crdr = 'DEBIT', {$double_name}.amount, NULL)" .
($sum ? ')' : '') . ' AS debit' . ($sum ? 's' : ''),
($sum ? 'SUM(' : '') .
"IF({$entry_name}.crdr = 'CREDIT', {$double_name}.amount, NULL)" .
($sum ? ')' : '') . ' AS credit' . ($sum ? 's' : ''),
($sum ? 'SUM(' : '') .
"IF({$entry_name}.crdr = '$ftype', 1, -1) * {$double_name}.amount" .
// IF({$double_name}.amount, {$double_name}.amount, 0)" .
($sum ? ')' : '') . ' AS balance',
);
if ($sum)
$fields[] = "COUNT({$entry_name}.id) AS entries";
return $fields;
/**************************************************************************
**************************************************************************
**************************************************************************
* 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 ledger.
*/
function debitCreditFields($id, $sum = false,
$entry_name = 'Entry', $double_name = 'DoubleEntry') {
return $this->Account->debitCreditFields
($this->accountID($id), $sum, $entry_name, $double_name);
}
/**************************************************************************
@@ -171,7 +161,7 @@ class Ledger extends AppModel {
'conditions' => array('Entry.ledger_id' => $ids),
));
pr(compact('entries'));
//pr(compact('entries'));
return $entries;
}
@@ -182,27 +172,43 @@ class Ledger extends AppModel {
* function: stats
* - Returns summary data from the requested ledger.
*/
function stats($id, $cond = null) {
if (!isset($cond))
$cond = array();
$cond[] = array('Ledger.id' => $id);
function stats($id, $query = null) {
if (!$id)
return null;
$stats = $this->find
('first', array
('link' =>
array(// Models
'Account' => array('fields' => array()),
'Entry' => array
('DoubleEntry' =>
array('fields' => array(),
'Transaction' => array('fields' => array('stamp')),
),
),
),
'fields' => $this->debitCreditFields($id, true),
'conditions' => $cond,
'group' => 'Ledger.id',
));
$this->queryInit($query);
if (!isset($query['link']['Account']))
$query['link']['Account'] = array();
if (!isset($query['link']['Account']['fields']))
$query['link']['Account']['fields'] = array();
if (!isset($query['link']['Entry']))
$query['link']['Entry'] = array();
if (!isset($query['link']['Entry']['DoubleEntry']))
$query['link']['Entry']['DoubleEntry'] = array();
if (!isset($query['link']['Entry']['DoubleEntry']['fields']))
$query['link']['Entry']['DoubleEntry']['fields'] = array();
if (!isset($query['link']['Entry']['DoubleEntry']['Transaction']))
$query['link']['Entry']['DoubleEntry']['Transaction'] = array();
if (!isset($query['link']['Entry']['DoubleEntry']['Transaction']['fields']))
$query['link']['Entry']['DoubleEntry']['Transaction']['fields'] = array();
$query['link']['Entry']['DoubleEntry']['Transaction']['fields'][] = 'stamp';
if (!isset($query['fields']))
$query['fields'] = array();
$query['fields'] = array_merge($query['fields'],
$this->debitCreditFields($id, true));
$query['conditions'][] = array('Ledger.id' => $id);
$query['group'][] = 'Ledger.id';
$stats = $this->find('first', $query);
unset($query['group']);
$query['fields'] = $this->debitCreditFields($id, false);
$stats = $this->find('all', $query);
pr(compact('query', 'stats'));
// The fields are all tucked into the [0] index,
// and the rest of the array is useless (empty).

View File

@@ -66,11 +66,10 @@ echo $this->element('ledgers', array
* Current Ledger
*/
echo $this->element('ledger_entries', array
echo $this->element('entries', array
(// Element configuration
'ledger_id' => $account['CurrentLedger']['id'],
'account_type' => $account['Account']['type'],
'group_by_tx' => true,
// Grid configuration
'config' => array

View File

@@ -62,7 +62,9 @@ echo $this->element('contacts', array
*/
echo $this->element('leases', array
('config' => array
('no_customer' => true,
'config' => array
('caption' => 'Lease History',
'rows' => $customer['Lease'],
)));
@@ -72,10 +74,10 @@ echo $this->element('leases', array
* Customer Account History
*/
echo $this->element('ledger_entries', array
echo $this->element('entries', array
(// Element configuration
'customer_id' => $customer['Customer']['id'],
'ar_account' => true,
'entry_type' => array('CHARGE', 'PAYMENT'),
// Grid configuration
'config' => array

View File

@@ -63,7 +63,7 @@ if ($group_by_tx)
if (!isset($collected_account_id))
$grid->invalidFields('Last Payment');
if (isset($account_ftype) || isset($ledger_id) || isset($account_id) || isset($ar_account))
if (isset($account_ftype) || isset($ledger_id) || isset($account_id) || isset($ar_account) || isset($customer_id))
$grid->invalidFields(array('Debit Account', 'Credit Account'));
else
$grid->invalidFields('Account');
@@ -71,7 +71,7 @@ else
if (isset($no_account) || $group_by_tx || isset($collected_account_id))
$grid->invalidFields(array('Account', 'Debit Account', 'Credit Account'));
if (isset($ledger_id) || isset($account_id) || isset($ar_account)) {
if (isset($ledger_id) || isset($account_id) || isset($ar_account) || isset($customer_id)) {
$grid->invalidFields('Amount');
$cols['Sub-Total']['index'] = 'subtotal-balance';
} else {

View File

@@ -9,6 +9,8 @@ $cols['Date'] = array('index' => 'Transaction.stamp', 'formatter' =>
$cols['Effective'] = array('index' => 'DoubleEntry.effective_date', 'formatter' => 'date');
$cols['Through'] = array('index' => 'Entry.through_date', 'formatter' => 'date');
$cols['Debit Account'] = array('index' => 'DebitAccount.name', 'formatter' => 'name');
$cols['Credit Account'] = array('index' => 'CreditAccount.name', 'formatter' => 'name');
$cols['Account'] = array('index' => 'Account.name', 'formatter' => 'name');
$cols['Cr/Dr'] = array('index' => 'Entry.crdr', 'formatter' => 'name');
@@ -19,6 +21,8 @@ $cols['Unit'] = array('index' => 'Unit.name', 'formatter' =>
$cols['Source'] = array('index' => 'Entry.name', 'formatter' => 'name');
$cols['Comment'] = array('index' => 'Entry.comment', 'formatter' => 'comment', 'width'=>150);
$cols['Debit'] = array('index' => 'debit', 'formatter' => 'currency');
$cols['Credit'] = array('index' => 'credit', 'formatter' => 'currency');
$cols['Amount'] = array('index' => 'DoubleEntry.amount', 'formatter' => 'currency');
$cols['Last Payment'] = array('index' => 'last_paid', 'formatter' => 'date');
@@ -26,49 +30,24 @@ $cols['Applied'] = array('index' => "applied", 'formatter' =>
$cols['Sub-Total'] = array('index' => 'subtotal-DoubleEntry.amount', 'formatter' => 'currency', 'sortable' => false);
// Since group_by_tx is a boolean, let's just get it
// defined, regardless of whether the caller did so.
// group_by_tx will cause all entry fields to be
// invalidated, and will leave only the transaction
// fields. Yes... the caller should just use the
// transactions element instead, in theory. However,
// it hasn't yet been implemented to the level of
// this element, and additionally, the transactions
// element will not allow for customer information
// (rightly so, since it's a ledger_entry field).
// However, at the current implementation, all ledger
// entries of a transaction are for the same customer.
// So... we allow it for now.
if (!isset($group_by_tx))
$group_by_tx = false;
// REVISIT <AP>: 20090715
// If we really want to group by transaction, we need
// a transaction listing, not a ledger_entry listing.
// switch controllers... don't overload this one.
$group_by_tx = false;
if (isset($transaction_id) || isset($reconcile_id))
$grid->invalidFields('Transaction');
if ($group_by_tx)
$grid->invalidFields('Entry');
if ($group_by_tx)
$grid->invalidFields(array('Effective', 'Through'));
if (!isset($collected_account_id))
$grid->invalidFields('Last Payment');
if (isset($account_ftype) || isset($ledger_id) || isset($account_id) || isset($ar_account))
if (isset($account_ftype) || isset($ar_account) || isset($customer_id) || isset($lease_id))
$grid->invalidFields(array('Debit Account', 'Credit Account'));
else
$grid->invalidFields('Account');
$grid->invalidFields(array('Account', 'Cr/Dr'));
if (isset($no_account) || $group_by_tx || isset($collected_account_id))
$grid->invalidFields(array('Account', 'Debit Account', 'Credit Account'));
if (isset($customer_id) || isset($lease_id))
$grid->invalidFields(array('Cr/Dr'));
if (isset($ledger_id) || isset($account_id) || isset($ar_account)) {
if (isset($no_account) || isset($ledger_id) || isset($account_id) || isset($collected_account_id))
$grid->invalidFields(array('Account', 'Cr/Dr', 'Debit Account', 'Credit Account'));
if (isset($ledger_id) || isset($account_id) || isset($ar_account) || isset($customer_id) || isset($lease_id)) {
$grid->invalidFields('Amount');
$cols['Sub-Total']['index'] = 'subtotal-balance';
} else {
@@ -76,12 +55,10 @@ if (isset($ledger_id) || isset($account_id) || isset($ar_account)) {
$cols['Sub-Total']['index'] = 'subtotal-DoubleEntry.amount';
}
// group_by_tx SHOULD wipe out Customer, but the reality
// is that it works good at the present, so we'll leave it.
if (isset($lease_id) || isset($customer_id))
$grid->invalidFields(array('Customer'));
if (isset($lease_id) || $group_by_tx)
if (isset($lease_id))
$grid->invalidFields(array('Lease', 'Unit'));
if (!isset($reconcile_id) && !isset($collected_account_id))
@@ -127,17 +104,18 @@ if (isset($searchfields))
$grid->searchFields(array('Customer', 'Unit'));
// Include custom data
$grid->customData(compact('ledger_id', 'account_id', 'ar_account',
$grid->customData(compact('ledger_id', 'account_id', 'ar_account', 'entry_type',
'account_type', 'account_ftype', 'monetary_source_id',
'customer_id', 'lease_id', 'transaction_id', 'group_by_tx'));
'customer_id', 'lease_id', 'transaction_id'));
// Render the grid
$grid
->render($this, isset($config) ? $config : null,
array('Transaction', 'Entry', 'Date', 'Effective', 'Last Payment',
'Account', 'Cr/Dr',
'Debit Account', 'Credit Account', 'Account', 'Cr/Dr',
'Customer', 'Unit',
'Comment',
'Amount',
'Debit', 'Credit', 'Amount',
'Applied', 'Sub-Total')
);

View File

@@ -18,6 +18,9 @@ $cols['Comment'] = array('index' => 'Lease.comment', 'formatter' => 'com
if (isset($searchfields))
$grid->searchFields(array('Customer', 'Unit'));
if (isset($no_customer))
$grid->invalidFields('Customer');
// Render the grid
$grid
->columns($cols)

View File

@@ -52,6 +52,7 @@ $rows[] = array('Transaction', $html->link('#'.$transaction['id'],
$rows[] = array('Timestamp', FormatHelper::datetime($transaction['stamp']));
$rows[] = array('Effective', FormatHelper::date($double['effective_date']));
$rows[] = array('Through', FormatHelper::date($entry['through_date']));
$rows[] = array('Amount', FormatHelper::currency($double['amount']));
$rows[] = array('Account', $html->link($account['name'],
array('controller' => 'accounts',
'action' => 'view',
@@ -94,25 +95,24 @@ echo $this->element('table',
echo '<div class="infobox">' . "\n";
$applied_caption = "Transfers applied";
$remaining_caption = "Unapplied amount";
foreach ($reconciled['stats'] AS $Rtype => $stats) {
//pr($reconciled);
foreach ($reconciled['summary'] AS $Rtype => $stats) {
$rtype = strtolower($Rtype);
$applied_caption = "Transfers applied";
$remaining_caption = "Unapplied amount";
$applied_caption = "Applied";
$remaining_caption = "Balance";
/* $applied_caption = $Rtype . 's Applied'; */
/* $remaining_caption = 'Remaining for ' . $Rtype . 's'; */
$rows = array();
$rows[] = array($applied_caption,
'<SPAN id="'.$rtype.'-applied">' .
FormatHelper::currency($stats['applied']) .
FormatHelper::currency($stats['reconciled']) .
'</SPAN>');
$rows[] = array($remaining_caption,
'<SPAN id="'.$rtype.'-unapplied">' .
FormatHelper::currency($stats['unapplied']) .
FormatHelper::currency($stats['balance']) .
'</SPAN>');
echo $this->element('table',
@@ -148,6 +148,10 @@ foreach ($reconciled['entries'] AS $Rtype => $entries) {
echo $this->element('entries', array
(// Element configuration
'entry_ids' => $entries,
/* 'action' => 'reconcile', */
/* 'entry_id' => $entry['id'], */
/* 'reconcile_types' => array($rtype), */
// 'reconcile_id' => $entry['id'],
// Grid configuration
'config' => array

View File

@@ -79,10 +79,11 @@ echo '<div CLASS="detail supporting">' . "\n";
* Lease Account History
*/
echo $this->element('ledger_entries', array
echo $this->element('entries', array
(// Element configuration
'lease_id' => $lease['id'],
'ar_account' => true,
//'charge_payment' => true,
//'entry_type' => array('CHARGE', 'PAYMENT'),
// Grid configuration
'config' => array

View File

@@ -63,11 +63,10 @@ echo '<div CLASS="detail supporting">' . "\n";
* Ledger Entries
*/
echo $this->element('ledger_entries', array
echo $this->element('entries', array
(// Element configuration
'ledger_id' => $ledger['id'],
'account_type' => $account['type'],
'group_by_tx' => true,
// Grid configuration
'config' => array