Making progress. Much still to do, but there are hints of functionality finally returning so I'm snapshotting.
git-svn-id: file:///svn-source/pmgr/branches/yafr_20090716/site@360 97e9348a-65ac-dc4b-aefc-98561f571b83
This commit is contained in:
@@ -219,6 +219,9 @@ class AppController extends Controller {
|
||||
if (isset($params['idlist']))
|
||||
$params['idlist'] = unserialize($params['idlist']);
|
||||
|
||||
// Make sure the action parameter at least exists
|
||||
if (!isset($params['action']))
|
||||
$params['action'] = null;
|
||||
}
|
||||
|
||||
function jqGridDataModel(&$params) {
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
class AccountsController extends AppController {
|
||||
|
||||
var $uses = array('Account', 'DoubleEntry');
|
||||
var $uses = array('Account', 'LedgerEntry');
|
||||
|
||||
var $sidemenu_links =
|
||||
array(array('name' => 'Accounts', 'header' => true),
|
||||
@@ -68,7 +68,7 @@ class AccountsController extends AppController {
|
||||
array(// Models
|
||||
'CurrentLedger' => array
|
||||
(// Models
|
||||
'DoubleEntry'
|
||||
'LedgerEntry'
|
||||
),
|
||||
),
|
||||
);
|
||||
@@ -76,7 +76,7 @@ class AccountsController extends AppController {
|
||||
|
||||
function jqGridDataFields(&$params, &$model) {
|
||||
return array_merge(array('Account.*'),
|
||||
$this->Account->Ledger->DoubleEntry->debitCreditFields(true, 'DoubleEntry', 'CurrentLedger'));
|
||||
$this->Account->Ledger->LedgerEntry->debitCreditFields(true, 'LedgerEntry', 'CurrentLedger'));
|
||||
}
|
||||
|
||||
function jqGridDataConditions(&$params, &$model) {
|
||||
@@ -166,7 +166,7 @@ class AccountsController extends AppController {
|
||||
('Account' =>
|
||||
array('fields' => array('name')),
|
||||
|
||||
'DoubleEntry' =>
|
||||
'LedgerEntry' =>
|
||||
array('fields' => array('id', 'amount'),
|
||||
|
||||
'MonetarySource' =>
|
||||
@@ -181,7 +181,7 @@ class AccountsController extends AppController {
|
||||
),
|
||||
'fields' => false,
|
||||
'conditions' => array(array('Ledger.id' => $ledger_id),
|
||||
array('DoubleEntry.id IS NOT NULL'),
|
||||
array('LedgerEntry.id IS NOT NULL'),
|
||||
),
|
||||
));
|
||||
|
||||
@@ -247,7 +247,7 @@ class AccountsController extends AppController {
|
||||
// Get all ledger entries of the CURRENT ledger
|
||||
$entries = $this->Account->ledgerEntries($id);
|
||||
//pr(compact('entries'));
|
||||
$account['CurrentLedger']['DoubleEntry'] = $entries;
|
||||
$account['CurrentLedger']['LedgerEntry'] = $entries;
|
||||
|
||||
// Summarize each ledger
|
||||
foreach($account['Ledger'] AS &$ledger)
|
||||
|
||||
@@ -16,203 +16,6 @@ class DoubleEntriesController extends AppController {
|
||||
}
|
||||
|
||||
|
||||
/**************************************************************************
|
||||
**************************************************************************
|
||||
**************************************************************************
|
||||
* virtuals: jqGridData
|
||||
* - With the application controller handling the jqGridData action,
|
||||
* these virtual functions ensure that the correct data is passed
|
||||
* to jqGrid.
|
||||
*/
|
||||
|
||||
function jqGridDataSetup(&$params) {
|
||||
parent::jqGridDataSetup($params);
|
||||
if (isset($params['custom']['collected_account_id']))
|
||||
$params['custom']['account_id'] = $params['custom']['collected_account_id'];
|
||||
}
|
||||
|
||||
function jqGridDataTables(&$params, &$model) {
|
||||
$link =
|
||||
array(// Models
|
||||
'Transaction' =>
|
||||
array('fields' => array('id', 'stamp'),
|
||||
),
|
||||
|
||||
'Customer' =>
|
||||
array('fields' => array('id', 'name'),
|
||||
),
|
||||
|
||||
'Lease' =>
|
||||
array('fields' => array('id', 'number'),
|
||||
'Unit' =>
|
||||
array('fields' => array('id', 'name'),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
if ($params['action'] == 'collected' || $params['action'] == 'reconcile') {
|
||||
$link['Payment'] = array('Account' => array('alias' => 'PaymentAccount'),
|
||||
'Receipt');
|
||||
$link['Charge'] = array('Account' => array('alias' => 'ChargeAccount'),
|
||||
'Invoice');
|
||||
}
|
||||
|
||||
if (isset($params['custom']['ledger_id'])) {
|
||||
$link['Ledger'] =
|
||||
array('fields' => array('id', 'sequence'),
|
||||
'Account' =>
|
||||
array('fields' => array('id', 'name'),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
return array('link' => $link);
|
||||
}
|
||||
|
||||
function jqGridDataFields(&$params, &$model) {
|
||||
if ($params['action'] == 'collected') {
|
||||
$fields[] = ('SUM(COALESCE(AppliedPayment.amount,0)' .
|
||||
' + COALESCE(AppliedCharge.amount,0)) AS applied');
|
||||
$fields[] = 'MAX(Receipt.stamp) AS last_paid';
|
||||
}
|
||||
elseif ($params['action'] == 'reconcile') {
|
||||
$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'");
|
||||
}
|
||||
|
||||
return $fields;
|
||||
}
|
||||
|
||||
function jqGridDataConditions(&$params, &$model) {
|
||||
if ($params['action'] === 'collected') {
|
||||
if (!isset($params['custom']['account_id']))
|
||||
die("INTERNAL ERROR: ACCOUNT ID NOT SET");
|
||||
|
||||
extract($params['custom']);
|
||||
|
||||
if (!empty($collected_from_date))
|
||||
$conditions[]
|
||||
= array('Receipt.stamp >=' =>
|
||||
$this->DoubleEntry->Transaction->dateFormatBeforeSave($collected_from_date));
|
||||
|
||||
if (!empty($collected_through_date))
|
||||
$conditions[]
|
||||
= array('Receipt.stamp <=' =>
|
||||
$this->DoubleEntry->Transaction->dateFormatBeforeSave($collected_through_date . ' 23:59:59'));
|
||||
|
||||
if (isset($collected_payment_accounts))
|
||||
$conditions[] = array('PaymentAccount.id' => $collected_payment_accounts);
|
||||
else
|
||||
$conditions[] = array('NOT' => array(array('PaymentAccount.id' => null)));
|
||||
}
|
||||
|
||||
if ($params['action'] === 'ledger') {
|
||||
$ledger_id = $params['custom']['ledger_id'];
|
||||
$conditions[] = array('Ledger.id' => $ledger_id);
|
||||
}
|
||||
|
||||
if (isset($params['custom']['reconcile_id'])) {
|
||||
$conditions[] = array('OR' =>
|
||||
array('AppliedCharge.id' => $reconcile_id),
|
||||
array('AppliedPayment.id' => $reconcile_id));
|
||||
}
|
||||
|
||||
if (isset($params['custom']['account_id'])) {
|
||||
$account_id = $params['custom']['account_id'];
|
||||
$conditions[] = array('Account.id' => $account_id);
|
||||
}
|
||||
|
||||
if (isset($params['custom']['customer_id'])) {
|
||||
$conditions[] =
|
||||
array('Customer.id' => $params['custom']['customer_id']);
|
||||
}
|
||||
|
||||
if (isset($params['custom']['lease_id'])) {
|
||||
$conditions[] =
|
||||
array('Lease.id' => $params['custom']['lease_id']);
|
||||
}
|
||||
|
||||
if (isset($params['custom']['transaction_id'])) {
|
||||
$conditions[] =
|
||||
array('Transaction.id' => $params['custom']['transaction_id']);
|
||||
}
|
||||
|
||||
return $conditions;
|
||||
}
|
||||
|
||||
function jqGridRecordLinks(&$params, &$model, &$records, $links) {
|
||||
$links['Transaction'] = array('id');
|
||||
$links['Entry'] = array('id');
|
||||
$links['Account'] = array('controller' => 'accounts', 'name');
|
||||
$links['DebitAccount'] = array('controller' => 'accounts', 'name');
|
||||
$links['CreditAccount'] = array('controller' => 'accounts', 'name');
|
||||
$links['MonetarySource'] = array('name');
|
||||
$links['Customer'] = array('name');
|
||||
$links['Lease'] = array('number');
|
||||
$links['Unit'] = array('name');
|
||||
return parent::jqGridRecordLinks($params, $model, $records, $links);
|
||||
}
|
||||
|
||||
function jqGridDataGroup(&$params, &$model) {
|
||||
return parent::jqGridDataGroup($params, $model);
|
||||
}
|
||||
|
||||
function jqGridDataOrder(&$params, &$model, $index, $direction) {
|
||||
/* if ($index === 'balance') */
|
||||
/* return ($index .' '. $direction); */
|
||||
$order = parent::jqGridDataOrder($params, $model, $index, $direction);
|
||||
|
||||
if ($index === 'Transaction.stamp') {
|
||||
$order[] = 'Entry.id ' . $direction;
|
||||
}
|
||||
|
||||
return $order;
|
||||
}
|
||||
|
||||
function jqGridDataRecords(&$params, &$model, $query) {
|
||||
if ($params['action'] === 'collected') {
|
||||
$tquery = array_diff_key($query, array(/*'fields'=>1,*/'group'=>1,'limit'=>1,'order'=>1));
|
||||
$tquery['group'] = array('AppliedPayment.id');
|
||||
$tquery['fields'] = array("IF(Entry.type = 'CHARGE',",
|
||||
" SUM(COALESCE(AppliedCharge.amount,0)),",
|
||||
" SUM(COALESCE(AppliedPayment.amount,0)))",
|
||||
" AS 'applied'",
|
||||
|
||||
"Charge.amount - (",
|
||||
"IF(Entry.type = 'CHARGE',",
|
||||
" SUM(COALESCE(AppliedCharge.amount,0)),",
|
||||
" SUM(COALESCE(AppliedPayment.amount,0)))",
|
||||
") AS 'balance'",
|
||||
);
|
||||
|
||||
$total = $model->find('first', $tquery);
|
||||
$params['userdata']['total'] = $total[0]['applied'];
|
||||
$params['userdata']['balance'] = $total[0]['balance'];
|
||||
}
|
||||
|
||||
return parent::jqGridDataRecords($params, $model, $query);
|
||||
}
|
||||
|
||||
|
||||
/**************************************************************************
|
||||
**************************************************************************
|
||||
**************************************************************************
|
||||
* action: reverse the ledger entry
|
||||
*/
|
||||
|
||||
function reverse($id) {
|
||||
$this->DoubleEntry->reverse($id);
|
||||
$this->redirect(array('action'=>'view', $id));
|
||||
}
|
||||
|
||||
|
||||
/**************************************************************************
|
||||
**************************************************************************
|
||||
**************************************************************************
|
||||
@@ -229,107 +32,13 @@ class DoubleEntriesController extends AppController {
|
||||
// Get the Entry and related fields
|
||||
$entry = $this->DoubleEntry->find
|
||||
('first',
|
||||
array('contain' => array
|
||||
('Transaction' => array('fields' => array('id', 'stamp')),
|
||||
'Customer' => array('fields' => array('id', 'name')),
|
||||
'Lease' => array('fields' => array('id')),
|
||||
'DebitLedger' => array('fields' => array('id', 'sequence'),
|
||||
'Account' => array('id', 'name', 'type', 'trackable')),
|
||||
'CreditLedger' => array('fields' => array('id', 'sequence'),
|
||||
'Account' => array('id', 'name', 'type', 'trackable')),
|
||||
'DebitEntry'/* => array('fields' => array('id'))*/,
|
||||
'CreditEntry'/* => array('fields' => array('id'))*/,
|
||||
'Entry' => array('fields' => array('id')),
|
||||
),
|
||||
|
||||
//'fields' => array('DoubleEntry.*'),
|
||||
|
||||
array('contain' => array('DebitEntry', 'CreditEntry'),
|
||||
'conditions' => array('DoubleEntry.id' => $id),
|
||||
));
|
||||
pr($entry);
|
||||
|
||||
$stats = $this->DoubleEntry->stats($id);
|
||||
|
||||
foreach (array('debit', 'credit') AS $crdr) {
|
||||
$CrDr = ucfirst($crdr);
|
||||
$entry[$CrDr.'Ledger']['Account']['ftype'] =
|
||||
$this->DoubleEntry->Ledger->Account->fundamentalType
|
||||
($entry[$CrDr.'Ledger']['Account']['type']);
|
||||
|
||||
$stats[$crdr]['amount_reconciled'] = null;
|
||||
$stats[$crdr]['amount_remaining'] = null;
|
||||
}
|
||||
|
||||
/* // Get the reconciliation balances for this ledger entry */
|
||||
/* $stats['debit']['amount_reconciled'] = $stats['debit_amount_reconciled']; */
|
||||
/* $stats['credit']['amount_reconciled'] = $stats['credit_amount_reconciled']; */
|
||||
/* if ($entry['DebitLedger']['Account']['trackable']) */
|
||||
/* $stats['debit']['amount_remaining'] = $entry['Entry']['amount'] - $stats['debit']['amount_reconciled']; */
|
||||
/* if ($entry['CreditLedger']['Account']['trackable']) */
|
||||
/* $stats['credit']['amount_remaining'] = $entry['Entry']['amount'] - $stats['credit']['amount_reconciled']; */
|
||||
/* //pr($stats); */
|
||||
|
||||
/* $reconciled = $this->DoubleEntry->findReconciledDoubleEntries($id); */
|
||||
/* //pr($reconciled); */
|
||||
|
||||
|
||||
// REVISIT <AP>: 20090711
|
||||
// It's not clear whether we should be able to reverse charges that have
|
||||
// already been paid/cleared/reconciled. Certainly, that will be the
|
||||
// case when someone has pre-paid and then moves out early. However, this
|
||||
// will work well for items accidentally charged but not yet paid for.
|
||||
if ((!$entry['DebitLedger']['Account']['trackable'] ||
|
||||
$stats['debit']['amount_reconciled'] == 0) &&
|
||||
(!$entry['CreditLedger']['Account']['trackable'] ||
|
||||
$stats['credit']['amount_reconciled'] == 0)
|
||||
|
||||
&& 0
|
||||
|
||||
)
|
||||
{
|
||||
// Set up dynamic menu items
|
||||
$this->sidemenu_links[] =
|
||||
array('name' => 'Operations', 'header' => true);
|
||||
|
||||
$this->sidemenu_links[] =
|
||||
array('name' => 'Undo',
|
||||
'url' => array('action' => 'reverse',
|
||||
$id));
|
||||
}
|
||||
|
||||
if ($this->DoubleEntry->Ledger->Account->type
|
||||
($entry['CreditLedger']['Account']['id']) == 'INCOME')
|
||||
{
|
||||
// Set up dynamic menu items
|
||||
$this->sidemenu_links[] =
|
||||
array('name' => 'Operations', 'header' => true);
|
||||
|
||||
$this->sidemenu_links[] =
|
||||
array('name' => 'Reverse',
|
||||
'url' => array('action' => 'reverse',
|
||||
$id));
|
||||
}
|
||||
|
||||
// Prepare to render.
|
||||
$title = "Double Ledger Entry #{$entry['DoubleEntry']['id']}";
|
||||
$this->set(compact('entry', 'title', 'reconciled', 'stats'));
|
||||
}
|
||||
|
||||
function tst($id = null) {
|
||||
$entry = $this->DoubleEntry->find
|
||||
('first',
|
||||
array('contain' => array('Account',
|
||||
|
||||
'DoubleEntry',
|
||||
|
||||
'Payment' => array('fields' => array('Payment.*'/*, 'AppliedPayment.*'*/),
|
||||
'DoubleEntry'/* => array('alias' => 'PaymentDoubleEntry')*/),
|
||||
'Charge' => array('fields' => array('Charge.*'/*, 'AppliedCharge.*'*/),
|
||||
'DoubleEntry'/* => array('alias' => 'ChargeDoubleEntry')*/),
|
||||
),
|
||||
'conditions' => array('Entry.id' => $id),
|
||||
));
|
||||
pr($entry);
|
||||
$this->set(compact('entry', 'title'));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -57,31 +57,15 @@ class LeasesController extends AppController {
|
||||
|
||||
function jqGridDataTables(&$params, &$model) {
|
||||
$link = $this->jqGridDataCountTables($params, $model);
|
||||
$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
|
||||
// entry in A/R. A solution would be to INNER JOIN these tables,
|
||||
// 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']['DoubleEntry']['Ledger']['Account']['type'] = 'INNER';
|
||||
$link['link']['DoubleEntry']['Ledger']['Account']['conditions']
|
||||
= array('Account.id' =>
|
||||
$this->Lease->DoubleEntry->Ledger->Account->accountReceivableAccountID());
|
||||
$link['link']['StatementEntry'] = array('fields' => array());
|
||||
return $link;
|
||||
}
|
||||
|
||||
function jqGridDataFields(&$params, &$model) {
|
||||
$db = &$model->getDataSource();
|
||||
$fields = $db->fields($model, $model->alias);
|
||||
$fields[] = ("SUM(IF(Account.id IS NULL, 0," .
|
||||
" IF(DoubleEntry.debit_ledger_id = Account.id," .
|
||||
" 1, -1))" .
|
||||
" * IF(DoubleEntry.amount IS NULL, 0, DoubleEntry.amount))" .
|
||||
" AS 'balance'");
|
||||
$fields = array_merge($fields,
|
||||
$this->Lease->StatementEntry->chargePaymentFields(true));
|
||||
return $fields;
|
||||
}
|
||||
|
||||
@@ -95,6 +79,9 @@ class LeasesController extends AppController {
|
||||
$conditions[] = 'Lease.close_date IS NOT NULL';
|
||||
}
|
||||
|
||||
if (isset($params['custom']['customer_id']))
|
||||
$conditions[] = array('Lease.customer_id' => $params['custom']['customer_id']);
|
||||
|
||||
return $conditions;
|
||||
}
|
||||
|
||||
@@ -252,10 +239,10 @@ class LeasesController extends AppController {
|
||||
$receipt_transaction = array_intersect_key($this->data,
|
||||
array('Transaction'=>1,
|
||||
'transaction_id'=>1));
|
||||
foreach ($data['DoubleEntry'] AS $entry) {
|
||||
foreach ($data['StatementEntry'] 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->DoubleEntry->Ledger->Account->postDoubleEntry
|
||||
$ids = $this->StatementEntry->Ledger->Account->postLedgerEntry
|
||||
($receipt_transaction,
|
||||
array_intersect_key($entry, array('MonetarySource'=>1))
|
||||
+ array_intersect_key($entry, array('account_id'=>1)),
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?php
|
||||
|
||||
class EntriesController extends AppController {
|
||||
class LedgerEntriesController extends AppController {
|
||||
|
||||
var $sidemenu_links = array();
|
||||
|
||||
@@ -58,7 +58,7 @@ class LedgersController extends AppController {
|
||||
('link' =>
|
||||
array(// Models
|
||||
'Account',
|
||||
'DoubleEntry',
|
||||
'LedgerEntry',
|
||||
'Close',
|
||||
),
|
||||
);
|
||||
@@ -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(true));
|
||||
$this->Ledger->LedgerEntry->debitCreditFields(true));
|
||||
}
|
||||
|
||||
function jqGridDataConditions(&$params, &$model) {
|
||||
|
||||
292
controllers/statement_entries_controller.php
Normal file
292
controllers/statement_entries_controller.php
Normal file
@@ -0,0 +1,292 @@
|
||||
<?php
|
||||
|
||||
class StatementEntriesController extends AppController {
|
||||
|
||||
var $sidemenu_links = array();
|
||||
|
||||
|
||||
/**************************************************************************
|
||||
**************************************************************************
|
||||
**************************************************************************
|
||||
* override: sideMenuLinks
|
||||
* - Generates controller specific links for the side menu
|
||||
*/
|
||||
function sideMenuLinks() {
|
||||
return array_merge(parent::sideMenuLinks(), $this->sidemenu_links);
|
||||
}
|
||||
|
||||
|
||||
/**************************************************************************
|
||||
**************************************************************************
|
||||
**************************************************************************
|
||||
* virtuals: jqGridData
|
||||
* - With the application controller handling the jqGridData action,
|
||||
* these virtual functions ensure that the correct data is passed
|
||||
* to jqGrid.
|
||||
*/
|
||||
|
||||
function jqGridDataSetup(&$params) {
|
||||
parent::jqGridDataSetup($params);
|
||||
}
|
||||
|
||||
function jqGridDataTables(&$params, &$model) {
|
||||
$link =
|
||||
array(// Models
|
||||
'Transaction' =>
|
||||
array('fields' => array('id', 'stamp'),
|
||||
),
|
||||
|
||||
'Customer' =>
|
||||
array('fields' => array('id', 'name'),
|
||||
),
|
||||
|
||||
'Lease' =>
|
||||
array('fields' => array('id', 'number'),
|
||||
'Unit' =>
|
||||
array('fields' => array('id', 'name'),
|
||||
),
|
||||
),
|
||||
|
||||
'Account' =>
|
||||
array('fields' => array('id', 'name', 'type'),
|
||||
),
|
||||
);
|
||||
|
||||
if (isset($params['custom']['statement_entry_id'])) {
|
||||
$link['PaymentEntry'] = array();
|
||||
$link['ChargeEntry'] = array();
|
||||
}
|
||||
/* if (count(array_intersect($params['fields'], array('applied'))) == 1) { */
|
||||
/* $link['PaymentEntry'] = array(); */
|
||||
/* $link['ChargeEntry'] = array(); */
|
||||
/* } */
|
||||
/* elseif (isset($params['custom']['customer_id']) || isset($params['custom']['lease_id'])) { */
|
||||
/* $link['PaymentEntry'] = array(); */
|
||||
/* } */
|
||||
|
||||
return array('link' => $link);
|
||||
}
|
||||
|
||||
function jqGridDataFields(&$params, &$model) {
|
||||
$fields = parent::jqGridDataFields($params, $model);
|
||||
|
||||
if (!isset($fields))
|
||||
$fields = array('StatementEntry.*');
|
||||
|
||||
/* if (isset($params['custom']['reconcile_id'])) { */
|
||||
/* $fields[] = array("IF(StatementEntry.type = 'CHARGE',", */
|
||||
/* " COALESCE(AppliedCharge.amount,0),", */
|
||||
/* " COALESCE(AppliedPayment.amount,0))", */
|
||||
/* " AS 'applied'"); */
|
||||
/* $fields[] = array("StatementEntry.amount - (", */
|
||||
/* "IF(StatementEntry.type = 'CHARGE',", */
|
||||
/* " COALESCE(AppliedCharge.amount,0),", */
|
||||
/* " COALESCE(AppliedPayment.amount,0))", */
|
||||
/* ") AS 'balance'"); */
|
||||
/* } */
|
||||
|
||||
if (isset($params['custom']['customer_id']) || isset($params['custom']['lease_id'])
|
||||
|| isset($params['custom']['statement_entry_id'])) {
|
||||
$fields = array_merge($fields,
|
||||
$this->StatementEntry->chargePaymentFields());
|
||||
}
|
||||
|
||||
if ($params['action'] === 'collected')
|
||||
$fields[] = 'MAX(Receipt.stamp) AS last_paid';
|
||||
|
||||
return $fields;
|
||||
}
|
||||
|
||||
function jqGridDataConditions(&$params, &$model) {
|
||||
$conditions = parent::jqGridDataConditions($params, $model);
|
||||
extract($params['custom']);
|
||||
|
||||
if (isset($transaction_id))
|
||||
$conditions[] = array('Transaction.id' => $transaction_id);
|
||||
|
||||
if (isset($account_id))
|
||||
$conditions[] = array('Account.id' => $account_id);
|
||||
|
||||
if (isset($customer_id))
|
||||
$conditions[] = array('Customer.id' => $customer_id);
|
||||
|
||||
if (isset($lease_id))
|
||||
$conditions[] = array('Lease.id' => $lease_id);
|
||||
|
||||
if (!empty($from_date))
|
||||
$conditions[]
|
||||
= array('Transaction.stamp >=' =>
|
||||
$this->StatementEntry->Transaction->dateFormatBeforeSave($from_date));
|
||||
|
||||
if (!empty($through_date))
|
||||
$conditions[]
|
||||
= array('Transaction.stamp <=' =>
|
||||
$this->StatementEntry->Transaction->dateFormatBeforeSave($through_date . ' 23:59:59'));
|
||||
|
||||
if (isset($payment_accounts))
|
||||
$conditions[] = array('PaymentEntry.account_id' => $payment_accounts);
|
||||
|
||||
if (isset($charge_accounts))
|
||||
$conditions[] = array('ChargeEntry.account_id' => $charge_accounts);
|
||||
|
||||
if (isset($statement_entry_id)) {
|
||||
$conditions[] = array('OR' =>
|
||||
array(array('ChargeEntry.id' => $statement_entry_id),
|
||||
array('PaymentEntry.id' => $statement_entry_id)));
|
||||
}
|
||||
|
||||
return $conditions;
|
||||
}
|
||||
|
||||
function jqGridRecordLinks(&$params, &$model, &$records, $links) {
|
||||
$links['StatementEntry'] = array('id');
|
||||
$links['Transaction'] = array('id');
|
||||
$links['Account'] = array('name');
|
||||
$links['Customer'] = array('name');
|
||||
$links['Lease'] = array('number');
|
||||
$links['Unit'] = array('name');
|
||||
return parent::jqGridRecordLinks($params, $model, $records, $links);
|
||||
}
|
||||
|
||||
function jqGridDataGroup(&$params, &$model) {
|
||||
return parent::jqGridDataGroup($params, $model);
|
||||
}
|
||||
|
||||
function jqGridDataOrder(&$params, &$model, $index, $direction) {
|
||||
$order = parent::jqGridDataOrder($params, $model, $index, $direction);
|
||||
|
||||
if ($index === 'Transaction.stamp')
|
||||
$order[] = 'StatementEntry.id ' . $direction;
|
||||
|
||||
return $order;
|
||||
}
|
||||
|
||||
function jqGridDataRecords(&$params, &$model, $query) {
|
||||
if ($params['action'] === 'collected') {
|
||||
$tquery = array_diff_key($query, array(/*'fields'=>1,*/'group'=>1,'limit'=>1,'order'=>1));
|
||||
$tquery['group'] = array('AppliedPayment.id');
|
||||
$tquery['fields'] = array("IF(StatementEntry.type = 'CHARGE',",
|
||||
" SUM(COALESCE(PaymentEntry.amount,0)),",
|
||||
" SUM(COALESCE(ChargeEntry.amount,0)))",
|
||||
" AS 'applied'",
|
||||
|
||||
"StatementEntry.amount - (",
|
||||
"IF(StatementEntry.type = 'CHARGE',",
|
||||
" SUM(COALESCE(PaymentEntry.amount,0)),",
|
||||
" SUM(COALESCE(ChargeEntry.amount,0)))",
|
||||
") AS 'balance'",
|
||||
);
|
||||
|
||||
$total = $model->find('first', $tquery);
|
||||
$params['userdata']['total'] = $total[0]['applied'];
|
||||
$params['userdata']['balance'] = $total[0]['balance'];
|
||||
}
|
||||
|
||||
return parent::jqGridDataRecords($params, $model, $query);
|
||||
}
|
||||
|
||||
|
||||
/**************************************************************************
|
||||
**************************************************************************
|
||||
**************************************************************************
|
||||
* action: reverse the ledger entry
|
||||
*/
|
||||
|
||||
function reverse($id) {
|
||||
$this->StatementEntry->reverse($id);
|
||||
$this->redirect(array('action'=>'view', $id));
|
||||
}
|
||||
|
||||
|
||||
/**************************************************************************
|
||||
**************************************************************************
|
||||
**************************************************************************
|
||||
* action: view
|
||||
* - Displays information about a specific entry
|
||||
*/
|
||||
|
||||
function view($id = null) {
|
||||
if (!$id) {
|
||||
$this->Session->setFlash(__('Invalid Item.', true));
|
||||
$this->redirect(array('controller' => 'accounts', 'action'=>'index'));
|
||||
}
|
||||
|
||||
// Get the StatementEntry and related fields
|
||||
$entry = $this->StatementEntry->find
|
||||
('first',
|
||||
array('contain' => array
|
||||
('Transaction' => array('fields' => array('id', 'stamp')),
|
||||
'Account' => array('id', 'name', 'type', 'trackable'),
|
||||
'Customer' => array('fields' => array('id', 'name')),
|
||||
'Lease' => array('fields' => array('id')),
|
||||
),
|
||||
|
||||
'conditions' => array('StatementEntry.id' => $id),
|
||||
));
|
||||
|
||||
$reconciled = $this->StatementEntry->reconciledEntries($id);
|
||||
|
||||
|
||||
/* // REVISIT <AP>: 20090711 */
|
||||
/* // It's not clear whether we should be able to reverse charges that have */
|
||||
/* // already been paid/cleared/reconciled. Certainly, that will be the */
|
||||
/* // case when someone has pre-paid and then moves out early. However, this */
|
||||
/* // will work well for items accidentally charged but not yet paid for. */
|
||||
/* if ((!$entry['DebitLedger']['Account']['trackable'] || */
|
||||
/* $stats['debit']['amount_reconciled'] == 0) && */
|
||||
/* (!$entry['CreditLedger']['Account']['trackable'] || */
|
||||
/* $stats['credit']['amount_reconciled'] == 0) */
|
||||
|
||||
/* && 0 */
|
||||
|
||||
/* ) */
|
||||
/* { */
|
||||
/* // Set up dynamic menu items */
|
||||
/* $this->sidemenu_links[] = */
|
||||
/* array('name' => 'Operations', 'header' => true); */
|
||||
|
||||
/* $this->sidemenu_links[] = */
|
||||
/* array('name' => 'Undo', */
|
||||
/* 'url' => array('action' => 'reverse', */
|
||||
/* $id)); */
|
||||
/* } */
|
||||
|
||||
/* if ($this->StatementEntry->Ledger->Account->type */
|
||||
/* ($entry['CreditLedger']['Account']['id']) == 'INCOME') */
|
||||
/* { */
|
||||
/* // Set up dynamic menu items */
|
||||
/* $this->sidemenu_links[] = */
|
||||
/* array('name' => 'Operations', 'header' => true); */
|
||||
|
||||
/* $this->sidemenu_links[] = */
|
||||
/* array('name' => 'Reverse', */
|
||||
/* 'url' => array('action' => 'reverse', */
|
||||
/* $id)); */
|
||||
/* } */
|
||||
|
||||
$stats = $this->StatementEntry->stats($id);
|
||||
pr($stats);
|
||||
|
||||
// Prepare to render.
|
||||
$title = "Statement Entry #{$entry['StatementEntry']['id']}";
|
||||
$this->set(compact('entry', 'title', 'reconciled', 'stats'));
|
||||
}
|
||||
|
||||
function tst($id = null) {
|
||||
$entry = $this->StatementEntry->find
|
||||
('first',
|
||||
array('contain' => array('Account',
|
||||
|
||||
'DoubleStatementEntry',
|
||||
|
||||
'Payment' => array('fields' => array('Payment.*'/*, 'AppliedPayment.*'*/),
|
||||
'DoubleStatementEntry'/* => array('alias' => 'PaymentDoubleStatementEntry')*/),
|
||||
'Charge' => array('fields' => array('Charge.*'/*, 'AppliedCharge.*'*/),
|
||||
'DoubleStatementEntry'/* => array('alias' => 'ChargeDoubleStatementEntry')*/),
|
||||
),
|
||||
'conditions' => array('StatementEntry.id' => $id),
|
||||
));
|
||||
pr($entry);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -64,31 +64,19 @@ class TransactionsController extends AppController {
|
||||
('first',
|
||||
array('contain' =>
|
||||
array(// Models
|
||||
'LedgerEntry' => array('fields' => array('LedgerEntry.id',
|
||||
'LedgerEntry.amount',
|
||||
'LedgerEntry.comment'),
|
||||
//Models
|
||||
|
||||
'DebitLedger' => array
|
||||
('fields' => array('DebitLedger.id', 'DebitLedger.sequence'),
|
||||
'Account' => array
|
||||
('fields' => array('Account.id', 'Account.name')),
|
||||
),
|
||||
|
||||
'CreditLedger' => array
|
||||
('fields' => array('CreditLedger.id', 'CreditLedger.sequence'),
|
||||
'Account' => array
|
||||
('fields' => array('Account.id', 'Account.name')),
|
||||
),
|
||||
),
|
||||
'LedgerEntry' =>
|
||||
array('fields' => array('LedgerEntry.id',
|
||||
'LedgerEntry.amount',
|
||||
'LedgerEntry.comment'),
|
||||
),
|
||||
),
|
||||
'conditions' => array('Transaction.id' => $id),
|
||||
));
|
||||
|
||||
// Figure out the transaction total
|
||||
$total = 0;
|
||||
foreach($transaction['LedgerEntry'] AS $entry)
|
||||
$total += $entry['amount'];
|
||||
/* // Figure out the transaction total */
|
||||
/* $total = 0; */
|
||||
/* foreach($transaction['LedgerEntry'] AS $entry) */
|
||||
/* $total += $entry['amount']; */
|
||||
|
||||
// OK, prepare to render.
|
||||
$title = 'Transaction #' . $transaction['Transaction']['id'];
|
||||
@@ -145,6 +133,7 @@ class TransactionsController extends AppController {
|
||||
}
|
||||
|
||||
pr($this->data);
|
||||
|
||||
if (!$this->Transaction->addReceipt($this->data,
|
||||
$this->data['Customer']['id'],
|
||||
(isset($this->data['Lease']['id'])
|
||||
|
||||
@@ -16,6 +16,7 @@ class Account extends AppModel {
|
||||
|
||||
var $hasMany = array(
|
||||
'Ledger',
|
||||
'LedgerEntry',
|
||||
);
|
||||
|
||||
|
||||
@@ -105,30 +106,10 @@ class Account extends AppModel {
|
||||
* 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;
|
||||
function debitCreditFields($sum = false, $entry_name = 'Entry', $account_name = 'Account') {
|
||||
return $this->LedgerEntry->debitCreditFields
|
||||
($sum, $entry_name, $account_name);
|
||||
}
|
||||
|
||||
|
||||
@@ -410,7 +391,7 @@ class Account extends AppModel {
|
||||
$unreconciled = $this->unreconciledEntries($id, 'CHARGE', $cond, $link);
|
||||
|
||||
foreach ($unreconciled AS $i => &$item) {
|
||||
$entry =& $item['DoubleEntry'];
|
||||
$entry =& $item['LedgerEntry'];
|
||||
// Determine if amount is sufficient to cover the entry
|
||||
if ($amount > $entry['balance'])
|
||||
$apply = $entry['balance'];
|
||||
@@ -509,7 +490,7 @@ class Account extends AppModel {
|
||||
/**************************************************************************
|
||||
**************************************************************************
|
||||
**************************************************************************
|
||||
* function: postDoubleEntry
|
||||
* function: postLedgerEntry
|
||||
* -
|
||||
* transaction_data
|
||||
* - transaction_id (optional... if set all else is ignored)
|
||||
@@ -524,7 +505,7 @@ class Account extends AppModel {
|
||||
* - name
|
||||
*/
|
||||
|
||||
function postDoubleEntry($transaction_data,
|
||||
function postLedgerEntry($transaction_data,
|
||||
$monetary_data,
|
||||
$entry_data,
|
||||
$reconcile = null) {
|
||||
@@ -577,7 +558,7 @@ class Account extends AppModel {
|
||||
// No distinguishing features of Cash, just
|
||||
// use the shared monetary source
|
||||
$monetary_data['monetary_source_id'] =
|
||||
$this->Ledger->DoubleEntry->MonetarySource->nameToID('Cash');
|
||||
$this->Ledger->LedgerEntry->MonetarySource->nameToID('Cash');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -645,7 +626,7 @@ class Account extends AppModel {
|
||||
|
||||
//pr(array('pre-save', compact('entry_data')));
|
||||
// Create it!
|
||||
$new_entry = new DoubleEntry();
|
||||
$new_entry = new LedgerEntry();
|
||||
$new_entry->create();
|
||||
if (!$new_entry->saveAll($entry_data, array('validate'=>false))) {
|
||||
return array('error' => true);
|
||||
@@ -700,7 +681,7 @@ class Account extends AppModel {
|
||||
|
||||
// Payment must debit the Receipt ledger, and credit the A/R ledger
|
||||
// debit: Receipt credit: A/R
|
||||
$ids = $this->postDoubleEntry
|
||||
$ids = $this->postLedgerEntry
|
||||
($split_transaction,
|
||||
null,
|
||||
array('debit_ledger_id' => $this->currentLedgerID($this->receiptAccountID()),
|
||||
@@ -709,9 +690,9 @@ class Account extends AppModel {
|
||||
'lease_id' => $rec['lease_id'],
|
||||
'customer_id' => $rec['customer_id'],
|
||||
),
|
||||
array('debit' => array(array('DoubleEntry' => array('id' => $new_entry->id,
|
||||
array('debit' => array(array('LedgerEntry' => array('id' => $new_entry->id,
|
||||
'amount' => $rec['applied']))),
|
||||
'credit' => array(array('DoubleEntry' => array('id' => $rec['id'],
|
||||
'credit' => array(array('LedgerEntry' => array('id' => $rec['id'],
|
||||
'amount' => $rec['applied']))))
|
||||
);
|
||||
// Keep using the same split transaction for all reconciled entries
|
||||
@@ -728,19 +709,19 @@ class Account extends AppModel {
|
||||
if (is_array($reconcile_set)) {
|
||||
//pr("reconcile_set is array");
|
||||
foreach ($reconcile_set AS $reconcile_entry) {
|
||||
if (!isset($reconcile_entry['DoubleEntry']['id']))
|
||||
if (!isset($reconcile_entry['LedgerEntry']['id']))
|
||||
continue;
|
||||
|
||||
$amount = $reconcile_entry['DoubleEntry']['amount'];
|
||||
$amount = $reconcile_entry['LedgerEntry']['amount'];
|
||||
if (!$amount)
|
||||
continue;
|
||||
|
||||
if ($dc_type == 'debit') {
|
||||
$debit_ledger_entry_id = $new_entry->id;
|
||||
$credit_ledger_entry_id = $reconcile_entry['DoubleEntry']['id'];
|
||||
$credit_ledger_entry_id = $reconcile_entry['LedgerEntry']['id'];
|
||||
}
|
||||
else {
|
||||
$debit_ledger_entry_id = $reconcile_entry['DoubleEntry']['id'];
|
||||
$debit_ledger_entry_id = $reconcile_entry['LedgerEntry']['id'];
|
||||
$credit_ledger_entry_id = $new_entry->id;
|
||||
}
|
||||
|
||||
@@ -760,9 +741,9 @@ class Account extends AppModel {
|
||||
|
||||
$ret = array
|
||||
('error' => $err,
|
||||
'id' => $new_entry->data['DoubleEntry']['id'],
|
||||
'transaction_id' => $new_entry->data['DoubleEntry']['transaction_id'],
|
||||
'monetary_source_id' => $new_entry->data['DoubleEntry']['monetary_source_id']);
|
||||
'id' => $new_entry->data['LedgerEntry']['id'],
|
||||
'transaction_id' => $new_entry->data['LedgerEntry']['transaction_id'],
|
||||
'monetary_source_id' => $new_entry->data['LedgerEntry']['monetary_source_id']);
|
||||
|
||||
if (isset($split_transaction['transaction_id']))
|
||||
$ret['split_transaction_id'] = $split_transaction['transaction_id'];
|
||||
@@ -794,7 +775,7 @@ class Account extends AppModel {
|
||||
if ($ledger['total'] == 0)
|
||||
continue;
|
||||
|
||||
$ids = $this->postDoubleEntry
|
||||
$ids = $this->postLedgerEntry
|
||||
($transaction,
|
||||
null,
|
||||
array('debit_account_id' => $deposit_account_id,
|
||||
@@ -806,7 +787,7 @@ class Account extends AppModel {
|
||||
//pr(compact('ids'));
|
||||
|
||||
if ($ids['error'])
|
||||
die("closeAndDeposit : postDoubleEntry returned error!");
|
||||
die("closeAndDeposit : postLedgerEntry returned error!");
|
||||
|
||||
$transaction = array_intersect_key($ids, array('transaction_id'=>1));
|
||||
|
||||
|
||||
@@ -1,261 +1,13 @@
|
||||
<?php
|
||||
class DoubleEntry extends AppModel {
|
||||
|
||||
var $name = 'DoubleEntry';
|
||||
var $validate = array(
|
||||
'id' => array('numeric'),
|
||||
'transaction_id' => array('numeric'),
|
||||
'amount' => array('money')
|
||||
);
|
||||
|
||||
var $hasOne = array(
|
||||
var $belongsTo = array(
|
||||
'DebitEntry' => array(
|
||||
'className' => 'Entry',
|
||||
'conditions' => array('DebitEntry.crdr' => 'DEBIT'),
|
||||
'className' => 'LedgerEntry',
|
||||
),
|
||||
'CreditEntry' => array(
|
||||
'className' => 'Entry',
|
||||
'conditions' => array('CreditEntry.crdr' => 'CREDIT'),
|
||||
'className' => 'LedgerEntry',
|
||||
),
|
||||
);
|
||||
|
||||
var $hasMany = array(
|
||||
'Entry',
|
||||
);
|
||||
|
||||
|
||||
var $belongsTo = array(
|
||||
'Transaction',
|
||||
'Invoice' => array(
|
||||
'className' => 'Transaction',
|
||||
'conditions' => array('Invoice.type' => 'INVOICE'),
|
||||
'foreignKey' => 'transaction_id',
|
||||
),
|
||||
'Receipt' => array(
|
||||
'className' => 'Transaction',
|
||||
'conditions' => array('Invoice.type' => 'RECEIPT'),
|
||||
'foreignKey' => 'transaction_id',
|
||||
),
|
||||
|
||||
|
||||
'Customer',
|
||||
'Lease',
|
||||
|
||||
'DebitLedger' => array(
|
||||
'className' => 'Ledger',
|
||||
'foreignKey' => 'debit_ledger_id',
|
||||
),
|
||||
'CreditLedger' => array(
|
||||
'className' => 'Ledger',
|
||||
'foreignKey' => 'credit_ledger_id',
|
||||
),
|
||||
|
||||
'Ledger' => array(
|
||||
'foreignKey' => false,
|
||||
// conditions will be used when JOINing tables
|
||||
// (such as find with LinkableBehavior)
|
||||
'conditions' => array('OR' =>
|
||||
array('%{MODEL_ALIAS}.debit_ledger_id = Ledger.id',
|
||||
'%{MODEL_ALIAS}.credit_ledger_id = Ledger.id')),
|
||||
|
||||
// finderQuery will be used when tables are put
|
||||
// together across several querys, not with JOIN.
|
||||
// (such as find with ContainableBehavior)
|
||||
'finderQuery' => 'NOT-IMPLEMENTED',
|
||||
|
||||
'counterQuery' => ''
|
||||
),
|
||||
|
||||
);
|
||||
|
||||
|
||||
/**************************************************************************
|
||||
**************************************************************************
|
||||
**************************************************************************
|
||||
* function: conditionEntryAsCreditOrDebit
|
||||
* - returns the condition necessary to match a set of
|
||||
* Ledgers to all related LedgerEntries
|
||||
*/
|
||||
function conditionEntryAsCreditOrDebit($ledger_ids) {
|
||||
return array('OR' =>
|
||||
array(array('debit_ledger_id' => $ledger_ids),
|
||||
array('credit_ledger_id' => $ledger_ids)));
|
||||
}
|
||||
|
||||
|
||||
function debitCreditFields($sum = false, $double_name = 'DoubleEntry', $ledger_name = 'Ledger', $account_name = 'Account') {
|
||||
$fields = array
|
||||
(
|
||||
($sum ? 'SUM(' : '') .
|
||||
"IF({$double_name}.debit_ledger_id = {$ledger_name}.id,
|
||||
{$double_name}.amount, NULL)" .
|
||||
($sum ? ')' : '') . ' AS debit' . ($sum ? 's' : ''),
|
||||
|
||||
($sum ? 'SUM(' : '') .
|
||||
"IF({$double_name}.credit_ledger_id = {$ledger_name}.id,
|
||||
{$double_name}.amount, NULL)" .
|
||||
($sum ? ')' : '') . ' AS credit' . ($sum ? 's' : ''),
|
||||
|
||||
($sum ? 'SUM(' : '') .
|
||||
"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)" .
|
||||
($sum ? ')' : '') . ' AS balance',
|
||||
);
|
||||
|
||||
if ($sum)
|
||||
$fields[] = "COUNT({$double_name}.id) AS entries";
|
||||
|
||||
return $fields;
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
**************************************************************************
|
||||
**************************************************************************
|
||||
* function: ledgerContext query helpers
|
||||
* - Returns parameters necessary to generate a query which
|
||||
* puts ledger entries into the context of a ledger. Since
|
||||
* debit/credit depends on the account type, it is required
|
||||
* as an argument for each function to avoid having to
|
||||
* query the ledger/account to find it out.
|
||||
*/
|
||||
function ledgerContextFields($ledger_id = null, $account_type = null) {
|
||||
$fields = array('id', 'effective_date',
|
||||
'lease_id', 'customer_id', 'comment', 'amount');
|
||||
|
||||
if (isset($ledger_id)) {
|
||||
$fields[] = ("IF(DoubleEntry.debit_ledger_id = $ledger_id," .
|
||||
" DoubleEntry.amount, NULL) AS debit");
|
||||
$fields[] = ("IF(DoubleEntry.credit_ledger_id = $ledger_id," .
|
||||
" DoubleEntry.amount, NULL) AS credit");
|
||||
|
||||
if (isset($account_type)) {
|
||||
if (in_array($account_type, array('ASSET', 'EXPENSE')))
|
||||
$ledger_type = 'debit';
|
||||
else
|
||||
$ledger_type = 'credit';
|
||||
|
||||
$fields[] = ("(IF(DoubleEntry.{$ledger_type}_ledger_id = $ledger_id," .
|
||||
" 1, -1) * DoubleEntry.amount) AS balance");
|
||||
}
|
||||
}
|
||||
|
||||
return $fields;
|
||||
}
|
||||
|
||||
function ledgerContextFields2($ledger_id = null, $account_id = null, $account_type = null) {
|
||||
$fields = array('id', 'effective_date', 'comment', 'amount');
|
||||
|
||||
if (isset($ledger_id)) {
|
||||
$fields[] = ("IF(DoubleEntry.debit_ledger_id = $ledger_id," .
|
||||
" SUM(DoubleEntry.amount), NULL) AS debit");
|
||||
$fields[] = ("IF(DoubleEntry.credit_ledger_id = $ledger_id," .
|
||||
" SUM(DoubleEntry.amount), NULL) AS credit");
|
||||
|
||||
if (isset($account_id) || isset($account_type)) {
|
||||
$Account = new Account();
|
||||
$account_ftype = $Account->fundamentalType($account_id ? $account_id : $account_type);
|
||||
$fields[] = ("(IF(DoubleEntry.{$account_ftype}_ledger_id = $ledger_id," .
|
||||
" 1, -1) * SUM(DoubleEntry.amount)) AS balance");
|
||||
}
|
||||
}
|
||||
elseif (isset($account_id)) {
|
||||
$fields[] = ("IF(DebitLedger.account_id = $account_id," .
|
||||
" SUM(DoubleEntry.amount), NULL) AS debit");
|
||||
$fields[] = ("IF(CreditLedger.account_id = $account_id," .
|
||||
" SUM(DoubleEntry.amount), NULL) AS credit");
|
||||
|
||||
$Account = new Account();
|
||||
$account_ftype = ucfirst($Account->fundamentalType($account_id));
|
||||
$fields[] = ("(IF({$account_ftype}Ledger.account_id = $account_id," .
|
||||
" 1, -1) * SUM(DoubleEntry.amount)) AS balance");
|
||||
}
|
||||
|
||||
return $fields;
|
||||
}
|
||||
|
||||
|
||||
function ledgerContextConditions($ledger_id, $account_type) {
|
||||
if (isset($ledger_id)) {
|
||||
return array
|
||||
('OR' =>
|
||||
array(array('DoubleEntry.debit_ledger_id' => $ledger_id),
|
||||
array('DoubleEntry.credit_ledger_id' => $ledger_id)),
|
||||
);
|
||||
}
|
||||
|
||||
return array();
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
**************************************************************************
|
||||
**************************************************************************
|
||||
* function: findInLedgerContext
|
||||
* - Returns an array of ledger entries that belong to a given ledger.
|
||||
* There is extra logic to also figure out whether the double_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;
|
||||
}
|
||||
|
||||
|
||||
/**************************************************************************
|
||||
**************************************************************************
|
||||
**************************************************************************
|
||||
* function: stats
|
||||
* - Returns summary data from the requested double entry
|
||||
*/
|
||||
function stats($id) {
|
||||
|
||||
/* $query = array */
|
||||
/* ( */
|
||||
/* 'fields' => array("SUM(Reconciliation.amount) AS 'reconciled'"), */
|
||||
|
||||
/* 'conditions' => array(isset($cond) ? $cond : array(), */
|
||||
/* array('DoubleEntry.id' => $id)), */
|
||||
|
||||
/* 'group' => 'DoubleEntry.id', */
|
||||
/* ); */
|
||||
|
||||
/* // Get the applied amounts on the debit side */
|
||||
/* $query['link'] = */
|
||||
/* array('DebitReconciliationDoubleEntry' => array('alias' => 'DRLE', 'DRLETransaction' => array('class' => 'Transaction'))); */
|
||||
/* $tmpstats = $this->find('first', $query); */
|
||||
/* $stats['debit_amount_reconciled'] = $tmpstats[0]['reconciled']; */
|
||||
|
||||
/* // Get the applied amounts on the credit side */
|
||||
/* $query['link'] = */
|
||||
/* array('CreditReconciliationDoubleEntry' => array('alias' => 'CRLE', 'CRLETransaction' => array('class' => 'Transaction'))); */
|
||||
/* $tmpstats = $this->find('first', $query); */
|
||||
/* $stats['credit_amount_reconciled'] = $tmpstats[0]['reconciled']; */
|
||||
|
||||
$stats['debit']['amount_reconciled'] = 0;
|
||||
$stats['credit']['amount_reconciled'] = 0;
|
||||
|
||||
return $stats;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
148
models/lease.php
148
models/lease.php
@@ -9,7 +9,7 @@ class Lease extends AppModel {
|
||||
);
|
||||
|
||||
var $hasMany = array(
|
||||
'DoubleEntry',
|
||||
'StatementEntry',
|
||||
);
|
||||
|
||||
|
||||
@@ -22,21 +22,19 @@ class Lease extends AppModel {
|
||||
function securityDeposits($id, $query = null) {
|
||||
$this->queryInit($query);
|
||||
|
||||
$this->id = $id;
|
||||
$this->recursive = -1;
|
||||
$this->read();
|
||||
$A = new Account();
|
||||
|
||||
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();
|
||||
if (!isset($query['link']['Lease']))
|
||||
$query['link']['Lease'] = array();
|
||||
if (!isset($query['link']['Lease']['fields']))
|
||||
$query['link']['Lease']['fields'] = array();
|
||||
|
||||
$query['conditions'][] = array('Lease.id' => $id);
|
||||
$query['conditions'][] = array('StatementEntry.account_id' => $A->securityDepositAccountID());
|
||||
|
||||
return $this->Customer->securityDeposits
|
||||
($this->data['Lease']['customer_id'], $query);
|
||||
$set = $this->StatementEntry->reconciledSet('CHARGE', $query);
|
||||
//pr(compact('set'));
|
||||
return $set;
|
||||
}
|
||||
|
||||
|
||||
@@ -52,40 +50,28 @@ class Lease extends AppModel {
|
||||
*/
|
||||
|
||||
function rentLastCharges($id) {
|
||||
$rent_account_id = $this->DoubleEntry->Entry->Account->rentAccountID();
|
||||
$rent_account_id = $this->StatementEntry->Account->rentAccountID();
|
||||
$entries = $this->find
|
||||
('all',
|
||||
array('link' =>
|
||||
array(// Models
|
||||
'DoubleEntry' =>
|
||||
array('Entry'// =>
|
||||
//array('fields'),
|
||||
),
|
||||
'StatementEntry' => array(),
|
||||
|
||||
'DEx' =>
|
||||
array('class' => 'DoubleEntry',
|
||||
'SEx' =>
|
||||
array('class' => 'StatementEntry',
|
||||
'conditions' => array
|
||||
('DEx.effective_date = DATE_ADD(Entry.through_date, INTERVAL 1 day)',
|
||||
'DEx.lease_id = DoubleEntry.lease_id',
|
||||
('SEx.effective_date = DATE_ADD(StatementEntry.through_date, INTERVAL 1 day)',
|
||||
'SEx.lease_id = StatementEntry.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('Entry.type' => 'CHARGE'),
|
||||
array('Entry.account_id' => $rent_account_id),
|
||||
array('DEx.id' => null),
|
||||
array('StatementEntry.type' => 'CHARGE'),
|
||||
array('StatementEntry.account_id' => $rent_account_id),
|
||||
array('SEx.id' => null),
|
||||
),
|
||||
)
|
||||
);
|
||||
@@ -125,7 +111,7 @@ class Lease extends AppModel {
|
||||
return false;
|
||||
if (count($entries) != 1)
|
||||
return null;
|
||||
return $entries[0]['DoubleEntry']['through_date'];
|
||||
return $entries[0]['StatementEntry']['through_date'];
|
||||
}
|
||||
|
||||
|
||||
@@ -137,76 +123,77 @@ class Lease extends AppModel {
|
||||
*/
|
||||
|
||||
function rentPaidThrough($id) {
|
||||
$rent_account_id = $this->DoubleEntry->Entry->Account->rentAccountID();
|
||||
$rent_account_id = $this->StatementEntry->Account->rentAccountID();
|
||||
|
||||
$rent = $this->DoubleEntry->Entry->reconciledSet
|
||||
$rent = $this->StatementEntry->reconciledSet
|
||||
('CHARGE',
|
||||
array('fields' =>
|
||||
array('DATE_SUB(DoubleEntry.effective_date, INTERVAL 1 DAY) AS paid_through',
|
||||
array('StatementEntry.*',
|
||||
'DATE_SUB(StatementEntry.effective_date, INTERVAL 1 DAY) AS paid_through',
|
||||
),
|
||||
'conditions' =>
|
||||
array(array('DoubleEntry.lease_id' => $id),
|
||||
array('Entry.account_id' => $rent_account_id)),
|
||||
array(array('StatementEntry.lease_id' => $id),
|
||||
array('StatementEntry.account_id' => $rent_account_id)),
|
||||
|
||||
'order' => array('DoubleEntry.effective_date'),
|
||||
'order' => array('StatementEntry.effective_date'),
|
||||
),
|
||||
true);
|
||||
|
||||
/* $query = array */
|
||||
/* ('link' => */
|
||||
/* array(// Models */
|
||||
/* 'DoubleEntry' => */
|
||||
/* 'StatementEntry' => */
|
||||
/* array('Entry' => */
|
||||
/* array(), */
|
||||
/* 'fields' => array('SUM(COALESCE(MoneyDoubleEntryR.amount,0)) AS paid'), */
|
||||
/* 'fields' => array('SUM(COALESCE(MoneyStatementEntryR.amount,0)) AS paid'), */
|
||||
/* ), */
|
||||
/* ), */
|
||||
|
||||
/* // Finally, the Money (Cash/Check/etc) Entry is the one */
|
||||
/* // which reconciles our ReceiptDoubleEntry debit */
|
||||
/* 'DebitReconciliationDoubleEntry' => */
|
||||
/* array('alias' => 'MoneyDoubleEntry', */
|
||||
/* 'linkalias' => 'MoneyDoubleEntryR', */
|
||||
/* // which reconciles our ReceiptStatementEntry debit */
|
||||
/* 'DebitReconciliationStatementEntry' => */
|
||||
/* array('alias' => 'MoneyStatementEntry', */
|
||||
/* 'linkalias' => 'MoneyStatementEntryR', */
|
||||
/* ), */
|
||||
/* ), */
|
||||
/* ), */
|
||||
|
||||
/* 'fields' => array('DoubleEntry.amount', */
|
||||
/* 'DATE_SUB(DoubleEntry.effective_date, INTERVAL 1 DAY) AS paid_through', */
|
||||
/* 'fields' => array('StatementEntry.amount', */
|
||||
/* 'DATE_SUB(StatementEntry.effective_date, INTERVAL 1 DAY) AS paid_through', */
|
||||
/* ), */
|
||||
|
||||
/* 'group' => 'DoubleEntry.id HAVING paid <> DoubleEntry.amount', */
|
||||
/* 'group' => 'StatementEntry.id HAVING paid <> StatementEntry.amount', */
|
||||
|
||||
/* 'conditions' => array(array('DoubleEntry.lease_id' => $id), */
|
||||
/* array('Account.id' => $this->DoubleEntry->Ledger->Account->rentAccountID()), */
|
||||
/* 'conditions' => array(array('StatementEntry.lease_id' => $id), */
|
||||
/* array('Account.id' => $this->StatementEntry->Ledger->Account->rentAccountID()), */
|
||||
/* ), */
|
||||
/* 'order' => array('DoubleEntry.effective_date', */
|
||||
/* 'order' => array('StatementEntry.effective_date', */
|
||||
/* ), */
|
||||
/* ); */
|
||||
|
||||
/* $rent = $this->DoubleEntry->find('first', $query); */
|
||||
/* $rent = $this->StatementEntry->find('first', $query); */
|
||||
//pr($rent);
|
||||
if ($rent['entries'])
|
||||
return $rent['entries'][0]['DoubleEntry']['paid_through'];
|
||||
return $rent['entries'][0]['StatementEntry']['paid_through'];
|
||||
|
||||
$rent = $this->DoubleEntry->Entry->reconciledSet
|
||||
$rent = $this->StatementEntry->reconciledSet
|
||||
('CHARGE',
|
||||
array('conditions' =>
|
||||
array(array('DoubleEntry.lease_id' => $id),
|
||||
array('Entry.account_id' => $rent_account_id)),
|
||||
array(array('StatementEntry.lease_id' => $id),
|
||||
array('StatementEntry.account_id' => $rent_account_id)),
|
||||
|
||||
'order' => array('Entry.through_date DESC'),
|
||||
),
|
||||
false);
|
||||
if ($rent)
|
||||
return $rent[0]['Entry']['through_date'];
|
||||
return $rent[0]['StatementEntry']['through_date'];
|
||||
|
||||
/* $query['fields'] = 'Entry.through_date'; */
|
||||
/* $query['order'] = 'Entry.through_date DESC'; */
|
||||
/* $query['group'] = 'DoubleEntry.id'; */
|
||||
/* $rent = $this->DoubleEntry->find('first', $query); */
|
||||
/* $query['group'] = 'StatementEntry.id'; */
|
||||
/* $rent = $this->StatementEntry->find('first', $query); */
|
||||
/* if ($rent) */
|
||||
/* return $rent['DoubleEntry']['through_date']; */
|
||||
/* return $rent['StatementEntry']['through_date']; */
|
||||
|
||||
return null;
|
||||
}
|
||||
@@ -416,43 +403,28 @@ class Lease extends AppModel {
|
||||
$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();
|
||||
/* if (!isset($query['link']['StatementEntry'])) */
|
||||
/* $query['link']['StatementEntry'] = array(); */
|
||||
/* if (!isset($query['link']['StatementEntry']['ChargeEntry'])) */
|
||||
/* $query['link']['StatementEntry']['ChargeEntry'] = 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';
|
||||
/* $query['link']['StatementEntry']['fields'] = array(); */
|
||||
/* $query['link']['ChargeEntry']['fields'] = array(); */
|
||||
/* $query['link']['ChargeEntry']['Account']['fields'] = array(); */
|
||||
/* $query['link']['ChargeEntry']['StatementEntry']['fields'] = array(); */
|
||||
/* $query['link']['ChargeEntry']['StatementEntry']['Invoice']['fields'] = array(); */
|
||||
|
||||
if (!isset($query['fields']))
|
||||
$query['fields'] = array();
|
||||
|
||||
$query['fields'] = array_merge($query['fields'],
|
||||
$this->DoubleEntry->Entry->chargePaymentFields(false));
|
||||
$this->StatementEntry->chargePaymentFields(true));
|
||||
|
||||
$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['conditions'][] = array('StatementEntry.lease_id' => $id);
|
||||
|
||||
$query['group'] = null;
|
||||
|
||||
$stats = $this->DoubleEntry->Entry->find('all', $query);
|
||||
$stats = $this->StatementEntry->find('first', $query);
|
||||
pr(compact('query', 'stats'));
|
||||
|
||||
// The fields are all tucked into the [0] index,
|
||||
|
||||
@@ -8,27 +8,8 @@ class Ledger extends AppModel {
|
||||
);
|
||||
|
||||
var $hasMany = array(
|
||||
'Entry',
|
||||
|
||||
'DoubleEntry' => array(
|
||||
'foreignKey' => false,
|
||||
|
||||
// conditions will be used when JOINing tables
|
||||
// (such as find with LinkableBehavior)
|
||||
'conditions' => array('OR' =>
|
||||
array('DoubleEntry.debit_ledger_id = %{MODEL_ALIAS}.id',
|
||||
'DoubleEntry.credit_ledger_id = %{MODEL_ALIAS}.id')),
|
||||
|
||||
// finderQuery will be used when tables are put
|
||||
// together across several querys, not with JOIN.
|
||||
// (such as find with ContainableBehavior)
|
||||
'finderQuery' => 'SELECT `DoubleEntry`.*
|
||||
FROM pmgr_double_entries AS `DoubleEntry`
|
||||
WHERE DoubleEntry.debit_ledger_id = ({$__cakeID__$})
|
||||
OR DoubleEntry.credit_ledger_id = ({$__cakeID__$})',
|
||||
|
||||
'counterQuery' => ''
|
||||
),
|
||||
'Transaction',
|
||||
'LedgerEntry',
|
||||
);
|
||||
|
||||
|
||||
@@ -111,7 +92,7 @@ class Ledger extends AppModel {
|
||||
'comment' => "Ledger Balance Forward",
|
||||
);
|
||||
|
||||
$carry_entry = new DoubleEntry();
|
||||
$carry_entry = new LedgerEntry();
|
||||
$carry_entry->create();
|
||||
if (!$carry_entry->save($carry_entry_data, false)) {
|
||||
return null;
|
||||
@@ -129,10 +110,9 @@ class Ledger extends AppModel {
|
||||
* 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);
|
||||
function debitCreditFields($sum = false, $entry_name = 'Entry', $account_name = 'Account') {
|
||||
return $this->LedgerEntry->debitCreditFields
|
||||
($sum, $entry_name, $account_name);
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
@@ -142,23 +122,16 @@ class Ledger extends AppModel {
|
||||
* - Returns an array of ledger entries that belong to a given
|
||||
* ledger. There is extra work done to establish debit/credit
|
||||
*/
|
||||
function ledgerEntries($ids, $cond = null, $link = null) {
|
||||
function ledgerEntries($ids, $query = null) {
|
||||
if (empty($ids))
|
||||
return null;
|
||||
|
||||
/* $id = (is_array($ids) ? $ids[0] : $ids); */
|
||||
/* $ftype = strtoupper($this->Account->fundamentalType($this->accountID($id))); */
|
||||
|
||||
$entries = $this->Entry->find
|
||||
$entries = $this->LedgerEntry->find
|
||||
('all', array
|
||||
('contain' => array('DoubleEntry' => array('fields' => array('amount'))),
|
||||
'fields' => array_merge(array("Entry.*"),
|
||||
$this->debitCreditFields(is_array($ids) ? $ids[0] : $ids)),
|
||||
/* "IF(Entry.crdr = 'CREDIT', DoubleEntry.amount, NULL) AS credit", */
|
||||
/* "IF(Entry.crdr = 'DEBIT', DoubleEntry.amount, NULL) AS debit", */
|
||||
/* "IF(Entry.crdr = '$ftype', 1, -1) * DoubleEntry.amount AS balance", */
|
||||
|
||||
'conditions' => array('Entry.ledger_id' => $ids),
|
||||
('contain' => array('Ledger' => array('Account')),
|
||||
'fields' => array_merge(array("LedgerEntry.*"),
|
||||
$this->LedgerEntry->debitCreditFields()),
|
||||
'conditions' => array('LedgerEntry.ledger_id' => $ids),
|
||||
));
|
||||
|
||||
//pr(compact('entries'));
|
||||
@@ -178,37 +151,37 @@ class Ledger extends AppModel {
|
||||
|
||||
$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['link']['Ledger']))
|
||||
$query['link']['Ledger'] = array();
|
||||
if (!isset($query['link']['Ledger']['fields']))
|
||||
$query['link']['Ledger']['fields'] = array();
|
||||
if (!isset($query['link']['Ledger']['Account']))
|
||||
$query['link']['Ledger']['Account'] = array();
|
||||
if (!isset($query['link']['Ledger']['Account']['fields']))
|
||||
$query['link']['Ledger']['Account']['fields'] = array();
|
||||
/* if (!isset($query['link']['Transaction'])) */
|
||||
/* $query['link']['Transaction'] = array(); */
|
||||
/* if (!isset($query['link']['Transaction']['fields'])) */
|
||||
/* $query['link']['Transaction']['fields'] = array(); */
|
||||
/* $query['link']['Transaction']['fields'][] = 'stamp'; */
|
||||
|
||||
if (!isset($query['fields']))
|
||||
$query['fields'] = array();
|
||||
|
||||
$query['fields'] = array_merge($query['fields'],
|
||||
$this->debitCreditFields($id, true));
|
||||
$this->debitCreditFields(true));
|
||||
|
||||
$query['conditions'][] = array('Ledger.id' => $id);
|
||||
$query['group'][] = 'Ledger.id';
|
||||
$query['conditions'][] = array('LedgerEntry.ledger_id' => $id);
|
||||
$query['group'][] = 'LedgerEntry.ledger_id';
|
||||
|
||||
$stats = $this->find('first', $query);
|
||||
$stats = $this->LedgerEntry->find('first', $query);
|
||||
pr(compact('stats'));
|
||||
|
||||
unset($query['group']);
|
||||
$query['fields'] = $this->debitCreditFields($id, false);
|
||||
$stats = $this->find('all', $query);
|
||||
pr(compact('query', 'stats'));
|
||||
|
||||
/* 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).
|
||||
|
||||
320
models/ledger_entry.php
Normal file
320
models/ledger_entry.php
Normal file
@@ -0,0 +1,320 @@
|
||||
<?php
|
||||
class LedgerEntry extends AppModel {
|
||||
|
||||
var $belongsTo = array(
|
||||
'Transaction',
|
||||
'Account',
|
||||
'Ledger',
|
||||
);
|
||||
|
||||
var $hasOne = array(
|
||||
'Payment',
|
||||
);
|
||||
|
||||
var $hasMany = array(
|
||||
);
|
||||
|
||||
var $hasAndBelongsToMany = array(
|
||||
// The Debit half of the double entry matching THIS Credit (if it is one)
|
||||
'DebitEntry' => array(
|
||||
'className' => 'LedgerEntry',
|
||||
'joinTable' => 'double_entries',
|
||||
'linkalias' => 'DDE',
|
||||
'foreignKey' => 'credit_entry_id',
|
||||
'associationForeignKey' => 'debit_entry_id',
|
||||
),
|
||||
|
||||
// The Credit half of the double entry matching THIS Debit (if it is one)
|
||||
'CreditEntry' => array(
|
||||
'className' => 'LedgerEntry',
|
||||
'joinTable' => 'double_entries',
|
||||
'linkalias' => 'CDE',
|
||||
'foreignKey' => 'debit_entry_id',
|
||||
'associationForeignKey' => 'credit_entry_id',
|
||||
),
|
||||
);
|
||||
|
||||
|
||||
/**************************************************************************
|
||||
**************************************************************************
|
||||
**************************************************************************
|
||||
* function: debitCreditFields
|
||||
* - Returns the fields necessary to determine whether the queried
|
||||
* entries are a debit, or a credit, and also the effect each have
|
||||
* on the overall balance of the account/ledger.
|
||||
*/
|
||||
|
||||
function debitCreditFields($sum = false, $entry_name = 'Entry', $account_name = 'Account') {
|
||||
$fields = array
|
||||
(
|
||||
($sum ? 'SUM(' : '') .
|
||||
"IF({$entry_name}.type = 'DEBIT'," .
|
||||
" {$entry_name}.amount, NULL)" .
|
||||
($sum ? ')' : '') . ' AS debit' . ($sum ? 's' : ''),
|
||||
|
||||
($sum ? 'SUM(' : '') .
|
||||
"IF({$entry_name}.type = 'CREDIT'," .
|
||||
" {$entry_name}.amount, NULL)" .
|
||||
($sum ? ')' : '') . ' AS credit' . ($sum ? 's' : ''),
|
||||
|
||||
($sum ? 'SUM(' : '') .
|
||||
"IF(${account_name}.type IN ('ASSET', 'EXPENSE')," .
|
||||
" IF({$entry_name}.type = 'DEBIT', 1, -1)," .
|
||||
" IF({$entry_name}.type = '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: addCharge
|
||||
* - Adds a new charge
|
||||
*/
|
||||
|
||||
function addCharge($data, $transaction, $customer_id, $lease_id = null) {
|
||||
// Create some models for convenience
|
||||
$A = new Account();
|
||||
|
||||
// Assume this will succeed
|
||||
$ret = true;
|
||||
|
||||
// Establish the key charge parameters
|
||||
$charge = array_intersect_key($data, array('stamp'=>1, 'amount'=>1, 'account_id'=>1));
|
||||
|
||||
$charge['customer_id'] = $customer_id;
|
||||
$charge['lease_id'] = $lease_id;
|
||||
$charge['type'] = 'CHARGE';
|
||||
|
||||
$ids = $this->Entry->Ledger->Account->postLedgerEntry
|
||||
($transaction,
|
||||
$charge,
|
||||
array('debit_ledger_id' => $A->currentLedgerID($data['account_id']),
|
||||
'credit_ledger_id' => $A->currentLedgerID($A->accountReceivableAccountID())
|
||||
) + $data
|
||||
);
|
||||
|
||||
if ($ids['error'])
|
||||
$ret = false;
|
||||
|
||||
return $ids['charge_id'];
|
||||
}
|
||||
|
||||
|
||||
/**************************************************************************
|
||||
**************************************************************************
|
||||
**************************************************************************
|
||||
* function: addPayment
|
||||
* - Adds a new payment
|
||||
*/
|
||||
|
||||
function addPayment($data, $transaction, $customer_id, $lease_id = null) {
|
||||
// Create some models for convenience
|
||||
$A = new Account();
|
||||
|
||||
// Assume this will succeed
|
||||
$ret = true;
|
||||
|
||||
// Establish the key payment parameters
|
||||
$payment = array_intersect_key($data, array('stamp'=>1, 'name'=>1, 'monetary_type'=>1,
|
||||
'data1'=>1, 'data2'=>1, 'data3'=>1, 'data4'=>1,
|
||||
'amount'=>1, 'account_id'=>1));
|
||||
$payment['customer_id'] = $customer_id;
|
||||
$payment['type'] = 'PAYMENT';
|
||||
|
||||
$ids = $this->Entry->Ledger->Account->postLedgerEntry
|
||||
($transaction,
|
||||
$payment,
|
||||
array('debit_ledger_id' => $A->currentLedgerID($data['account_id']),
|
||||
'credit_ledger_id' => $A->currentLedgerID($A->accountReceivableAccountID())
|
||||
) + $data
|
||||
);
|
||||
|
||||
if ($ids['error'])
|
||||
$ret = false;
|
||||
|
||||
return $ids['payment_id'];
|
||||
}
|
||||
|
||||
|
||||
/**************************************************************************
|
||||
**************************************************************************
|
||||
**************************************************************************
|
||||
* function: reverse
|
||||
* - Reverses the charges
|
||||
*
|
||||
* SAMPLE MOVE IN w/ PRE PAYMENT
|
||||
* DEPOSIT RENT A/R RECEIPT CHECK PETTY BANK
|
||||
* ------- ------- ------- ------- ------- ------- -------
|
||||
* |25 | 25| | | | |
|
||||
* | |20 20| | | | |
|
||||
* | |20 20| | | | |
|
||||
* | |20 20| | | | |
|
||||
* | | |25 25| | | |
|
||||
* | | |20 20| | | |
|
||||
* | | |20 20| | | |
|
||||
* | | |20 20| | | |
|
||||
* | | | |85 85| | |
|
||||
* | | | | |85 | 85|
|
||||
|
||||
* MOVE OUT and REFUND FINAL MONTH
|
||||
* DEPOSIT RENT C/P RECEIPT CHECK PETTY BANK
|
||||
* ------- ------- ------- ------- ------- ------- -------
|
||||
* 25| | |25 | | | | t20 e20a
|
||||
* | 20| |20 | | | | t20 e20b
|
||||
|
||||
* -ONE REFUND CHECK-
|
||||
* | | 25| |25 | | | t30 e30a
|
||||
* | | 20| |20 | | | t30 e30b
|
||||
* | | | 45| | | |45 t40 e40
|
||||
* -OR MULTIPLE-
|
||||
* | | 15| |15 | | | t50a e50a
|
||||
* | | | 15| | |15 | t60a e60a
|
||||
* | | 30| |30 | | | t50b e50b
|
||||
* | | | 30| | | |30 t60b e60b
|
||||
* | | | | | | |
|
||||
|
||||
|
||||
OPTION 1
|
||||
* |-25 | -25| | | | |
|
||||
* | |-20 -20| | | | |
|
||||
* | | |-25 -25| | | |
|
||||
* | | |-20 -20| | | |
|
||||
|
||||
OPTION 2
|
||||
* |-25 | | -25| | | |
|
||||
* | |-20 | -20| | | |
|
||||
* | | | |-15 | -15| |
|
||||
* | | | |-30 | | -30|
|
||||
* | | | | | | |
|
||||
*
|
||||
*/
|
||||
function reverse($ledger_entries, $stamp = null) {
|
||||
pr(array('Entry::reverse',
|
||||
compact('ledger_entries', 'stamp')));
|
||||
|
||||
// If the user only wants to reverse one ID, we'll allow it
|
||||
if (!is_array($ledger_entries))
|
||||
$ledger_entries = $this->find
|
||||
('all', array
|
||||
('contain' => false,
|
||||
'conditions' => array('Entry.id' => $ledger_entries)));
|
||||
|
||||
$A = new Account();
|
||||
|
||||
$ar_account_id = $A->accountReceivableAccountID();
|
||||
$receipt_account_id = $A->receiptAccountID();
|
||||
|
||||
$transaction_id = null;
|
||||
foreach ($ledger_entries AS $entry) {
|
||||
$entry = $entry['Entry'];
|
||||
$amount = -1*$entry['amount'];
|
||||
|
||||
if (isset($entry['credit_account_id']))
|
||||
$refund_account_id = $entry['credit_account_id'];
|
||||
elseif (isset($entry['CreditLedger']['Account']['id']))
|
||||
$refund_account_id = $entry['CreditLedger']['Account']['id'];
|
||||
elseif (isset($entry['credit_ledger_id']))
|
||||
$refund_account_id = $this->Ledger->accountID($entry['credit_ledger_id']);
|
||||
else
|
||||
return null;
|
||||
|
||||
// post new refund in the income account
|
||||
$ids = $A->postEntry
|
||||
(array('transaction_id' => $transaction_id),
|
||||
null,
|
||||
array('debit_ledger_id' => $A->currentLedgerID($ar_account_id),
|
||||
'credit_ledger_id' => $A->currentLedgerID($refund_account_id),
|
||||
'effective_date' => $entry['effective_date'],
|
||||
'through_date' => $entry['through_date'],
|
||||
'amount' => $amount,
|
||||
'lease_id' => $entry['lease_id'],
|
||||
'customer_id' => $entry['customer_id'],
|
||||
'comment' => "Refund; Entry #{$entry['id']}",
|
||||
),
|
||||
array('debit' => array
|
||||
(array('Entry' =>
|
||||
array('id' => $entry['id'],
|
||||
'amount' => $amount))),
|
||||
)
|
||||
);
|
||||
|
||||
if ($ids['error'])
|
||||
return null;
|
||||
$transaction_id = $ids['transaction_id'];
|
||||
|
||||
pr(array('checkpoint' => 'Posted Refund Ledger Entry',
|
||||
compact('ids', 'amount', 'refund_account_id', 'ar_account_id')));
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/**************************************************************************
|
||||
**************************************************************************
|
||||
**************************************************************************
|
||||
* 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;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -2,16 +2,13 @@
|
||||
class Payment extends AppModel {
|
||||
|
||||
var $belongsTo = array(
|
||||
'Customer',
|
||||
'Lease',
|
||||
);
|
||||
|
||||
var $hasMany = array(
|
||||
'DoubleEntry',
|
||||
);
|
||||
|
||||
var $hasAndBelongsToMany = array(
|
||||
'DoubleEntry',
|
||||
'LedgerEntry',
|
||||
'DepositTransaction' => array(
|
||||
'className' => 'Transaction',
|
||||
),
|
||||
'NsfTransaction' => array(
|
||||
'className' => 'Transaction',
|
||||
),
|
||||
);
|
||||
|
||||
|
||||
@@ -36,7 +33,7 @@ class Payment extends AppModel {
|
||||
|
||||
// Create the payment entry, and reconcile the credit side
|
||||
// of the double-entry (which should be A/R) as a payment.
|
||||
$ids = $this->DoubleEntry->Ledger->Account->postDoubleEntry
|
||||
$ids = $this->LedgerEntry->Ledger->Account->postLedgerEntry
|
||||
($payment,
|
||||
array('debit_ledger_id' => $A->currentLedgerID($entry['account_id']),
|
||||
'credit_ledger_id' => $A->currentLedgerID($A->paymentAccountID())
|
||||
@@ -97,7 +94,7 @@ class Payment extends AppModel {
|
||||
('first',
|
||||
array('contain' =>
|
||||
array(/* e3 */
|
||||
'DoubleEntry' =>
|
||||
'LedgerEntry' =>
|
||||
array('Transaction.id',
|
||||
'Payment.id',
|
||||
'Customer.id',
|
||||
@@ -126,7 +123,7 @@ class Payment extends AppModel {
|
||||
),
|
||||
|
||||
/* e2 */
|
||||
'DebitReconciliationDoubleEntry' =>
|
||||
'DebitReconciliationLedgerEntry' =>
|
||||
array(/* e2 credit */
|
||||
'CreditLedger' => /* i.e. A/R Ledger */
|
||||
array('fields' => array(),
|
||||
@@ -141,11 +138,11 @@ class Payment extends AppModel {
|
||||
/* e1 */
|
||||
// STUPID CakePHP bug screws up CLASS contains CLASS.
|
||||
// Use the same class, but with different name.
|
||||
'DebitReconciliationDoubleEntry2',
|
||||
'DebitReconciliationLedgerEntry2',
|
||||
),
|
||||
|
||||
/* e4 */
|
||||
'CreditReconciliationDoubleEntry' =>
|
||||
'CreditReconciliationLedgerEntry' =>
|
||||
array(/* e4 debit */
|
||||
'DebitLedger' => /* e.g. BANK Ledger */
|
||||
array('fields' => array('id'),
|
||||
@@ -170,9 +167,9 @@ class Payment extends AppModel {
|
||||
|
||||
$t4_id = null;
|
||||
$t5_id = null;
|
||||
foreach ($source['DoubleEntry'] AS $e3) {
|
||||
foreach ($source['LedgerEntry'] AS $e3) {
|
||||
// We expect only a single e4 entry
|
||||
$e4 = $e3['CreditReconciliationDoubleEntry'];
|
||||
$e4 = $e3['CreditReconciliationLedgerEntry'];
|
||||
if (count($e4) < 1)
|
||||
continue;
|
||||
if (count($e4) > 1)
|
||||
@@ -188,7 +185,7 @@ class Payment extends AppModel {
|
||||
$bank_account_id = $e4['DebitLedger']['account_id'];
|
||||
|
||||
// post new e5
|
||||
$e5_ids = $A->postDoubleEntry
|
||||
$e5_ids = $A->postLedgerEntry
|
||||
(array('transaction_id' => $t4_id),
|
||||
null,
|
||||
array('debit_ledger_id' => $A->currentLedgerID($bank_account_id),
|
||||
@@ -211,7 +208,7 @@ class Payment extends AppModel {
|
||||
// post new e6... this will be our crossover point
|
||||
// from typical positive entries to negative entries.
|
||||
// Therefore, no reconciliation on this account.
|
||||
$e6_ids = $A->postDoubleEntry
|
||||
$e6_ids = $A->postLedgerEntry
|
||||
(array('transaction_id' => $t5_id),
|
||||
array('monetary_source_id' => $e3['monetary_source_id']),
|
||||
array('debit_ledger_id' => $A->currentLedgerID($nsf_account_id),
|
||||
@@ -223,7 +220,7 @@ class Payment extends AppModel {
|
||||
'comment' => "NSF tracker; Monetary Source #{$id}",
|
||||
),
|
||||
array('debit' => array
|
||||
(array('DoubleEntry' =>
|
||||
(array('LedgerEntry' =>
|
||||
array('id' => $e5_ids['id'],
|
||||
'amount' => $amount))),
|
||||
)
|
||||
@@ -237,12 +234,12 @@ class Payment extends AppModel {
|
||||
compact('e6_ids', 'amount')));
|
||||
|
||||
$t6_id = null;
|
||||
foreach ($e3['DebitReconciliationDoubleEntry'] AS $e2) {
|
||||
foreach ($e2['DebitReconciliationDoubleEntry2'] AS $e1) {
|
||||
foreach ($e3['DebitReconciliationLedgerEntry'] AS $e2) {
|
||||
foreach ($e2['DebitReconciliationLedgerEntry2'] AS $e1) {
|
||||
$amount = -1*$e1['Reconciliation']['amount'];
|
||||
|
||||
// post new e7
|
||||
$e7_ids = $A->postDoubleEntry
|
||||
$e7_ids = $A->postLedgerEntry
|
||||
(array('transaction_id' => $t6_id),
|
||||
null,
|
||||
array('debit_ledger_id' => $A->currentLedgerID($receipt_account_id),
|
||||
@@ -254,12 +251,12 @@ class Payment extends AppModel {
|
||||
'comment' => "NSF Receipt; Monetary Source #{$id}",
|
||||
),
|
||||
array('debit' => array
|
||||
(array('DoubleEntry' =>
|
||||
(array('LedgerEntry' =>
|
||||
array('id' => $e6_ids['id'],
|
||||
'amount' => $amount))),
|
||||
|
||||
'credit' => array
|
||||
(array('DoubleEntry' =>
|
||||
(array('LedgerEntry' =>
|
||||
array('id' => $e1['id'],
|
||||
'amount' => $amount))),
|
||||
)
|
||||
@@ -276,11 +273,11 @@ class Payment extends AppModel {
|
||||
}
|
||||
|
||||
// Cheat for now
|
||||
$customer_id = $source['DoubleEntry'][0]['customer_id'];
|
||||
$customer_id = $source['LedgerEntry'][0]['customer_id'];
|
||||
$lease_id = null;
|
||||
|
||||
// post new e8
|
||||
$e8_ids = $A->postDoubleEntry
|
||||
$e8_ids = $A->postLedgerEntry
|
||||
(array('transaction_id' => $t6_id),
|
||||
null,
|
||||
array('debit_ledger_id' => $A->currentLedgerID($ar_account_id),
|
||||
|
||||
@@ -1,13 +0,0 @@
|
||||
<?php
|
||||
class Reconciliation extends AppModel {
|
||||
|
||||
var $belongsTo = array(
|
||||
'DebitEntry' => array(
|
||||
'className' => 'Entry',
|
||||
),
|
||||
'CreditEntry' => array(
|
||||
'className' => 'Entry',
|
||||
),
|
||||
);
|
||||
|
||||
}
|
||||
@@ -1,72 +1,25 @@
|
||||
<?php
|
||||
class Entry extends AppModel {
|
||||
class StatementEntry extends AppModel {
|
||||
|
||||
var $belongsTo = array(
|
||||
'Transaction',
|
||||
'Customer',
|
||||
'Lease',
|
||||
'Account',
|
||||
'DoubleEntry',
|
||||
|
||||
// The charge to which this payment applies (if it is one)
|
||||
'ChargeEntry' => array(
|
||||
'className' => 'StatementEntry',
|
||||
),
|
||||
);
|
||||
|
||||
var $hasAndBelongsToMany = array(
|
||||
|
||||
// The Charges that match THIS Payment (if it is one)
|
||||
'Charge' => array(
|
||||
'className' => 'Entry',
|
||||
'joinTable' => 'charges_payments',
|
||||
'linkalias' => 'AppliedCharge',
|
||||
'foreignKey' => 'payment_entry_id',
|
||||
'associationForeignKey' => 'charge_entry_id',
|
||||
),
|
||||
|
||||
// The Payments that match THIS Charge (if it is one)
|
||||
'Payment' => array(
|
||||
'className' => 'Entry',
|
||||
'joinTable' => 'charges_payments',
|
||||
'linkalias' => 'AppliedPayment',
|
||||
var $hasMany = array(
|
||||
// The payments that apply to this charge (if it is one)
|
||||
'PaymentEntry' => array(
|
||||
'className' => 'StatementEntry',
|
||||
'foreignKey' => 'charge_entry_id',
|
||||
'associationForeignKey' => 'payment_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( */
|
||||
/* 'className' => 'Entry', */
|
||||
/* 'joinTable' => 'reconciliations', */
|
||||
/* //'linkalias' => 'AppliedCredit', */
|
||||
/* 'foreignKey' => false, */
|
||||
/* 'associationForeignKey' => false, */
|
||||
/* 'conditions' => array( */
|
||||
/* "Reconciliation.credit_entry_id */
|
||||
/* = IF(Entry.crdr = 'CREDIT', Entry.id, REntry.id)", */
|
||||
/* "Reconciliation.debit_entry_id */
|
||||
/* = IF(Entry.crdr = 'DEBIT', Entry.id, REntry.id)" */
|
||||
/* ), */
|
||||
/* ), */
|
||||
);
|
||||
|
||||
|
||||
@@ -77,22 +30,22 @@ class Entry extends AppModel {
|
||||
*/
|
||||
|
||||
|
||||
function chargePaymentFields($sum = false, $entry_name = 'Entry', $double_name = 'DoubleEntry') {
|
||||
function chargePaymentFields($sum = false, $entry_name = 'StatementEntry') {
|
||||
$fields = array
|
||||
(
|
||||
($sum ? 'SUM(' : '') .
|
||||
"IF({$entry_name}.type = 'CHARGE'," .
|
||||
" {$double_name}.amount, NULL)" .
|
||||
" {$entry_name}.amount, NULL)" .
|
||||
($sum ? ')' : '') . ' AS charge' . ($sum ? 's' : ''),
|
||||
|
||||
($sum ? 'SUM(' : '') .
|
||||
"IF({$entry_name}.type = 'PAYMENT'," .
|
||||
" {$double_name}.amount, NULL)" .
|
||||
" {$entry_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)" .
|
||||
" * IF({$entry_name}.amount, {$entry_name}.amount, 0)" .
|
||||
($sum ? ')' : '') . ' AS balance',
|
||||
);
|
||||
|
||||
@@ -124,7 +77,7 @@ class Entry extends AppModel {
|
||||
$charge['lease_id'] = $lease_id;
|
||||
$charge['type'] = 'CHARGE';
|
||||
|
||||
$ids = $this->Entry->Ledger->Account->postDoubleEntry
|
||||
$ids = $this->Entry->Ledger->Account->postLedgerEntry
|
||||
($transaction,
|
||||
$charge,
|
||||
array('debit_ledger_id' => $A->currentLedgerID($data['account_id']),
|
||||
@@ -160,7 +113,7 @@ class Entry extends AppModel {
|
||||
$payment['customer_id'] = $customer_id;
|
||||
$payment['type'] = 'PAYMENT';
|
||||
|
||||
$ids = $this->Entry->Ledger->Account->postDoubleEntry
|
||||
$ids = $this->Entry->Ledger->Account->postLedgerEntry
|
||||
($transaction,
|
||||
$payment,
|
||||
array('debit_ledger_id' => $A->currentLedgerID($data['account_id']),
|
||||
@@ -300,24 +253,16 @@ OPTION 2
|
||||
$this->queryInit($query);
|
||||
|
||||
if ($set == 'CHARGE' || $set == 'PAYMENT')
|
||||
$query['conditions'][] = array('Entry.type' => $set);
|
||||
elseif ($set == 'DEBIT' || $set == 'CREDIT')
|
||||
$query['conditions'][] = array('Entry.crdr' => $set);
|
||||
$query['conditions'][] = array('StatementEntry.type' => $set);
|
||||
else
|
||||
die("INVALID RECONCILE SET");
|
||||
|
||||
if (!isset($query['link']['DoubleEntry']))
|
||||
$query['link']['DoubleEntry'] = array();
|
||||
if ($set == 'CHARGE')
|
||||
$query['link']['Payment'] = array('fields' => array("SUM(AppliedPayment.amount) AS reconciled"));
|
||||
$query['link']['PaymentEntry'] = array('fields' => array("SUM(PaymentEntry.amount) AS reconciled"));
|
||||
if ($set == 'PAYMENT')
|
||||
$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")); */
|
||||
$query['link']['ChargeEntry'] = array('fields' => array("SUM(ChargeEntry.amount) AS reconciled"));
|
||||
|
||||
$query['group'] = 'Entry.id';
|
||||
$query['group'] = 'StatementEntry.id';
|
||||
return $query;
|
||||
}
|
||||
|
||||
@@ -329,15 +274,16 @@ OPTION 2
|
||||
|
||||
$resultset = array();
|
||||
foreach ($result AS $i => $entry) {
|
||||
$entry['DoubleEntry'] += $entry[0];
|
||||
pr(compact('entry'));
|
||||
$entry['StatementEntry'] += $entry[0];
|
||||
unset($entry[0]);
|
||||
|
||||
$entry['DoubleEntry']['balance'] =
|
||||
$entry['DoubleEntry']['amount'] - $entry['DoubleEntry']['reconciled'];
|
||||
$entry['StatementEntry']['balance'] =
|
||||
$entry['StatementEntry']['amount'] - $entry['StatementEntry']['reconciled'];
|
||||
|
||||
// Since HAVING isn't a builtin feature of CakePHP,
|
||||
// we'll have to post-process to get the desired entries
|
||||
if ($entry['DoubleEntry']['balance'] == 0) {
|
||||
if ($entry['StatementEntry']['balance'] == 0) {
|
||||
if (!$unrec)
|
||||
$resultset[] = $entry;
|
||||
}
|
||||
@@ -347,10 +293,12 @@ OPTION 2
|
||||
}
|
||||
}
|
||||
|
||||
//pr(array('StatementEntry::reconciledSet()' => compact('resultset')));
|
||||
|
||||
//$resultset['stats'] = $this->stats(null, $query);
|
||||
//pr($this->stats(null, $query));
|
||||
return array('entries' => $resultset,
|
||||
'summary' => $this->stats(null, $query, $set));
|
||||
'summary' => $this->stats(null, $query));
|
||||
}
|
||||
|
||||
|
||||
@@ -364,20 +312,16 @@ OPTION 2
|
||||
function reconciledEntriesQuery($id, $query = null) {
|
||||
$this->queryInit($query, false);
|
||||
|
||||
$entry = $this->find('first', array('conditions' => array('Entry.id' => $id),
|
||||
'recursive' => -1));
|
||||
$entry = $entry['Entry'];
|
||||
$this->id = $id;
|
||||
$this->recursive = -1;
|
||||
$this->read();
|
||||
|
||||
$query['conditions'][] = array('Entry.id' => $id);
|
||||
$query['conditions'][] = array('StatementEntry.id' => $id);
|
||||
|
||||
if ($entry['type'] == 'CHARGE')
|
||||
$query['contain']['Payment'] = array('fields' => array('Payment.*', 'ChargesPayment.amount'));
|
||||
if ($entry['type'] == 'PAYMENT')
|
||||
$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')); */
|
||||
if ($this->data['StatementEntry']['type'] == 'CHARGE')
|
||||
$query['link']['PaymentEntry'] = array();
|
||||
if ($this->data['StatementEntry']['type'] == 'PAYMENT')
|
||||
$query['link']['ChargeEntry'] = array();
|
||||
|
||||
return $query;
|
||||
}
|
||||
@@ -386,11 +330,13 @@ OPTION 2
|
||||
$lquery = $this->reconciledEntriesQuery($id, $query);
|
||||
|
||||
//pr(array('reconciledEntries', compact('entry', 'contain')));
|
||||
$result = $this->find('first', $lquery);
|
||||
unset($result['Entry']);
|
||||
$result = $this->find('all', $lquery);
|
||||
foreach (array_keys($result) AS $i)
|
||||
unset($result[$i]['StatementEntry']);
|
||||
|
||||
return array('entries' => $result,
|
||||
'summary' => $this->stats($id, $query));
|
||||
//pr(array('StatementEntry::reconciledEntries()' => compact('result')));
|
||||
return array('entries' => $result);
|
||||
//'summary' => $this->stats($id, $query));
|
||||
}
|
||||
|
||||
|
||||
@@ -398,59 +344,138 @@ OPTION 2
|
||||
**************************************************************************
|
||||
**************************************************************************
|
||||
* function: stats
|
||||
* - Returns summary data from the requested ledger entry
|
||||
* - Returns summary data from the requested statement entry
|
||||
*/
|
||||
function stats($id = null, $query = null, $set = null) {
|
||||
function stats($id = null, $query = 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($id)) {
|
||||
$this->id = $id;
|
||||
$this->recursive = -1;
|
||||
$this->read();
|
||||
|
||||
if (isset($set))
|
||||
$set = strtoupper($set);
|
||||
if ($this->data['StatementEntry']['type'] == 'PAYMENT') {
|
||||
// Payment has only a _single_ charge, and by definition
|
||||
// 100% of the payment is used to reconcile that charge.
|
||||
return array('total' => $this->data['StatementEntry']['amount'],
|
||||
'reconciled' => $this->data['StatementEntry']['amount'],
|
||||
'balance' => 0);
|
||||
}
|
||||
|
||||
$query['link']['PaymentEntry'] =
|
||||
array('fields' => array("SUM(COALESCE(PaymentEntry.amount,0)) AS reconciled"),
|
||||
//'type' => 'INNER',
|
||||
);
|
||||
|
||||
$query['fields'] = array();
|
||||
$query['fields'][] = "StatementEntry.amount AS total";
|
||||
//$query['conditions'][] = array("{$Set}Entry.id !=" => null);
|
||||
|
||||
$query['conditions'][] = array('StatementEntry.id' => $id);
|
||||
|
||||
$query['group'] = 'StatementEntry.id';
|
||||
|
||||
$result = $this->find('first', $query);
|
||||
$result[0]['balance'] = $result[0]['total'] - $result[0]['reconciled'];
|
||||
//pr(compact('query', 'result'));
|
||||
|
||||
return $result['StatementEntry'] + $result[0];
|
||||
}
|
||||
|
||||
$stats = array();
|
||||
|
||||
$rquery = $query;
|
||||
$rquery['link']['PaymentEntry'] =
|
||||
array('fields' => array("SUM(COALESCE(PaymentEntry.amount,0)) AS reconciled"),
|
||||
//'type' => 'INNER',
|
||||
);
|
||||
|
||||
$rquery['fields'] = array();
|
||||
$rquery['fields'][] = "SUM(StatementEntry.amount) AS total";
|
||||
|
||||
$rquery['conditions'][] = array("PaymentEntry.id !=" => null);
|
||||
|
||||
$result = $this->find('first', $rquery);
|
||||
$result[0]['balance'] = $result[0]['total'] - $result[0]['reconciled'];
|
||||
$stats['Payment'] = $result[0];
|
||||
//pr(array('stats Payment', compact('rquery', 'stats')));
|
||||
|
||||
$rquery = $query;
|
||||
$rquery['fields'] = array();
|
||||
$rquery['fields'][] = "SUM(StatementEntry.amount) AS total";
|
||||
$rquery['fields'][] = "SUM(StatementEntry.amount) AS reconciled";
|
||||
|
||||
$result = $this->find('first', $rquery);
|
||||
$result[0]['balance'] = $result[0]['total'] - $result[0]['reconciled'];
|
||||
$stats['Charge'] = $result[0];
|
||||
//pr(array('stats Charge', compact('rquery', 'stats')));
|
||||
|
||||
|
||||
return $stats;
|
||||
|
||||
|
||||
$this->id = $id;
|
||||
$this->recursive = -1;
|
||||
$this->read();
|
||||
|
||||
//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')) */
|
||||
) {
|
||||
/* if ($this->data['StatementEntry']['type'] == 'CHARGE') */
|
||||
/* $set = 'PAYMENT'; */
|
||||
/* else */
|
||||
/* $set = 'CHARGE'; */
|
||||
|
||||
$rquery = $query;
|
||||
$rquery['link'][$Rtype] =
|
||||
array('fields' => array("SUM(COALESCE(Applied{$Rtype}.amount,0)) AS reconciled"));
|
||||
/* $Set = ucfirst(strtolower($set)); */
|
||||
|
||||
$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);
|
||||
/* $query['link'][$Set.'Entry'] = */
|
||||
/* array('fields' => array("SUM(COALESCE({$Set}Entry.amount,0)) AS reconciled"), */
|
||||
/* //'type' => 'INNER', */
|
||||
/* ); */
|
||||
|
||||
$result = $this->find('first', $rquery);
|
||||
//pr(compact('Rtype', 'rquery', 'result'));
|
||||
/* $query['fields'] = array(); */
|
||||
/* $query['fields'][] = "StatementEntry.amount AS total"; */
|
||||
/* $query['fields'][] = "StatementEntry.amount - SUM(COALESCE({$Set}Entry.amount,0)) AS balance"; */
|
||||
/* //$query['conditions'][] = array("{$Set}Entry.id !=" => null); */
|
||||
|
||||
$sumfld = $Rtype;
|
||||
$stats[$sumfld] = $result[0];
|
||||
/* if (!isset($stats[$sumfld]['applied'])) */
|
||||
/* $stats[$sumfld]['applied'] = 0; */
|
||||
}
|
||||
/* $query['conditions'][] = array('StatementEntry.id' => $id); */
|
||||
|
||||
/* $query['group'] = 'StatementEntry.id'; */
|
||||
|
||||
/* $result = $this->find('first', $query); */
|
||||
/* pr(compact('Rtype', 'query', 'result')); */
|
||||
|
||||
/* return $result['StatementEntry'] + $result[0]; */
|
||||
|
||||
if ($this->data['StatementEntry']['type'] == 'PAYMENT') {
|
||||
// Payment has only a _single_ charge, and by definition
|
||||
// 100% of the payment is used to reconcile that charge.
|
||||
return array('total' => $this->data['StatementEntry']['amount'],
|
||||
'reconciled' => $this->data['StatementEntry']['amount'],
|
||||
'balance' => 0);
|
||||
}
|
||||
|
||||
return $stats;
|
||||
$query['link']['PaymentEntry'] =
|
||||
array('fields' => array("SUM(COALESCE(PaymentEntry.amount,0)) AS reconciled"),
|
||||
//'type' => 'INNER',
|
||||
);
|
||||
|
||||
$query['fields'] = array();
|
||||
$query['fields'][] = "StatementEntry.amount AS total";
|
||||
$query['fields'][] = "StatementEntry.amount - SUM(COALESCE(PaymentEntry.amount,0)) AS balance";
|
||||
//$query['conditions'][] = array("{$Set}Entry.id !=" => null);
|
||||
|
||||
$query['conditions'][] = array('StatementEntry.id' => $id);
|
||||
|
||||
$query['group'] = 'StatementEntry.id';
|
||||
|
||||
$result = $this->find('first', $query);
|
||||
//pr(compact('Rtype', 'query', 'result'));
|
||||
|
||||
return $result['StatementEntry'] + $result[0];
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,17 +1,14 @@
|
||||
<?php
|
||||
class Transaction extends AppModel {
|
||||
|
||||
var $validate = array(
|
||||
'stamp' => array('date')
|
||||
);
|
||||
|
||||
var $belongsTo = array(
|
||||
'Customer',
|
||||
'Lease',
|
||||
'Account',
|
||||
'Ledger',
|
||||
);
|
||||
|
||||
var $hasMany = array(
|
||||
'DoubleEntry',
|
||||
'LedgerEntry',
|
||||
'StatementEntry',
|
||||
);
|
||||
|
||||
|
||||
@@ -37,15 +34,15 @@ class Transaction extends AppModel {
|
||||
|
||||
// Determine the total charges on the invoice
|
||||
$invoice['amount'] = 0;
|
||||
foreach ($data['DoubleEntry'] AS $entry)
|
||||
foreach ($data['LedgerEntry'] AS $entry)
|
||||
$invoice['amount'] += $entry['amount'];
|
||||
|
||||
// Go through the entered charges
|
||||
foreach ($data['DoubleEntry'] AS $entry) {
|
||||
foreach ($data['LedgerEntry'] AS $entry) {
|
||||
//pr(compact('entry'));
|
||||
// Create the receipt entry, and reconcile the credit side
|
||||
// of the double-entry (which should be A/R) as a payment.
|
||||
$ids = $this->DoubleEntry->Ledger->Account->postDoubleEntry
|
||||
$ids = $this->LedgerEntry->Ledger->Account->postLedgerEntry
|
||||
($invoice,
|
||||
array('debit_ledger_id' => $A->currentLedgerID($A->accountReceivableAccountID()),
|
||||
'credit_ledger_id' => $A->currentLedgerID($entry['account_id'])
|
||||
@@ -83,14 +80,14 @@ class Transaction extends AppModel {
|
||||
|
||||
// Determine the total charges on the receipt
|
||||
$receipt['amount'] = 0;
|
||||
foreach ($data['DoubleEntry'] AS $entry)
|
||||
foreach ($data['LedgerEntry'] AS $entry)
|
||||
$receipt['amount'] += $entry['amount'];
|
||||
|
||||
// Go through the entered charges
|
||||
foreach ($data['DoubleEntry'] AS $entry) {
|
||||
foreach ($data['LedgerEntry'] AS $entry) {
|
||||
// Create the receipt entry, and reconcile the credit side
|
||||
// of the double-entry (which should be A/R) as a receipt.
|
||||
$ids = $this->DoubleEntry->Ledger->Account->postDoubleEntry
|
||||
$ids = $this->LedgerEntry->Ledger->Account->postLedgerEntry
|
||||
($receipt,
|
||||
array('debit_ledger_id' => $A->currentLedgerID($entry['account_id']),
|
||||
'credit_ledger_id' => $A->currentLedgerID($A->receiptAccountID())
|
||||
|
||||
@@ -1,2 +0,0 @@
|
||||
1243395559
|
||||
a:36:{i:0;s:12:"pmgr_actions";i:1;s:27:"pmgr_actions_late_schedules";i:2;s:17:"pmgr_charge_types";i:3;s:19:"pmgr_config_options";i:4;s:18:"pmgr_config_system";i:5;s:20:"pmgr_config_versions";i:6;s:22:"pmgr_contact_addresses";i:7;s:19:"pmgr_contact_emails";i:8;s:20:"pmgr_contact_methods";i:9;s:19:"pmgr_contact_phones";i:10;s:13:"pmgr_contacts";i:11;s:18:"pmgr_group_options";i:12;s:22:"pmgr_group_permissions";i:13;s:11:"pmgr_groups";i:14;s:19:"pmgr_late_schedules";i:15;s:19:"pmgr_lease_contacts";i:16;s:16:"pmgr_lease_types";i:17;s:11:"pmgr_leases";i:18;s:14:"pmgr_map_units";i:19;s:9:"pmgr_maps";i:20;s:10:"pmgr_notes";i:21;s:18:"pmgr_payment_types";i:22;s:15:"pmgr_site_areas";i:23;s:21:"pmgr_site_memberships";i:24;s:17:"pmgr_site_options";i:25;s:10:"pmgr_sites";i:26;s:24:"pmgr_transaction_charges";i:27;s:25:"pmgr_transaction_payments";i:28;s:25:"pmgr_transaction_receipts";i:29;s:32:"pmgr_transaction_reconciliations";i:30;s:15:"pmgr_unit_sizes";i:31;s:15:"pmgr_unit_types";i:32;s:10:"pmgr_units";i:33;s:17:"pmgr_user_options";i:34;s:10:"pmgr_users";i:35;s:5:"posts";}
|
||||
@@ -62,7 +62,7 @@ echo $this->element('contacts', array
|
||||
*/
|
||||
|
||||
echo $this->element('leases', array
|
||||
('customer_id' => $customer['id'],
|
||||
('customer_id' => $customer['Customer']['id'],
|
||||
|
||||
'config' => array
|
||||
('caption' => 'Lease History',
|
||||
|
||||
@@ -16,6 +16,9 @@ $cols['Comment'] = array('index' => 'Customer.comment', 'formatter
|
||||
if (isset($searchfields))
|
||||
$grid->searchFields(array('Last Name', 'First Name'));
|
||||
|
||||
// Include custom data
|
||||
//$grid->customData(compact('lease_id'));
|
||||
|
||||
// Render the grid
|
||||
$grid
|
||||
->columns($cols)
|
||||
|
||||
@@ -18,9 +18,12 @@ $cols['Comment'] = array('index' => 'Lease.comment', 'formatter' => 'com
|
||||
if (isset($searchfields))
|
||||
$grid->searchFields(array('Customer', 'Unit'));
|
||||
|
||||
if (isset($no_customer))
|
||||
if (isset($customer_id))
|
||||
$grid->invalidFields('Customer');
|
||||
|
||||
// Include custom data
|
||||
$grid->customData(compact('customer_id'));
|
||||
|
||||
// Render the grid
|
||||
$grid
|
||||
->columns($cols)
|
||||
|
||||
79
views/elements/statement_entries.ctp
Normal file
79
views/elements/statement_entries.ctp
Normal file
@@ -0,0 +1,79 @@
|
||||
<?php /* -*- mode:PHP -*- */
|
||||
|
||||
// Define the table columns
|
||||
$cols = array();
|
||||
$cols['Transaction'] = array('index' => 'Transaction.id', 'formatter' => 'id');
|
||||
$cols['StatementEntry'] = array('index' => 'StatementEntry.id', 'formatter' => 'id');
|
||||
|
||||
$cols['Date'] = array('index' => 'Transaction.stamp', 'formatter' => 'date');
|
||||
$cols['Effective'] = array('index' => 'StatementEntry.effective_date', 'formatter' => 'date');
|
||||
$cols['Through'] = array('index' => 'StatementEntry.through_date', 'formatter' => 'date');
|
||||
|
||||
$cols['Account'] = array('index' => 'Account.name', 'formatter' => 'name');
|
||||
|
||||
$cols['Customer'] = array('index' => 'Customer.name', 'formatter' => 'longname');
|
||||
$cols['Lease'] = array('index' => 'Lease.number', 'formatter' => 'id');
|
||||
$cols['Unit'] = array('index' => 'Unit.name', 'formatter' => 'name');
|
||||
|
||||
$cols['Comment'] = array('index' => 'StatementEntry.comment', 'formatter' => 'comment', 'width'=>150);
|
||||
|
||||
$cols['Charge'] = array('index' => 'charge', 'formatter' => 'currency');
|
||||
$cols['Payment'] = array('index' => 'payment', 'formatter' => 'currency');
|
||||
|
||||
$cols['Last Payment'] = array('index' => 'last_paid', 'formatter' => 'date');
|
||||
$cols['Applied'] = array('index' => "applied", 'formatter' => 'currency');
|
||||
$cols['Sub-Total'] = array('index' => 'subtotal-StatementEntry.amount', 'formatter' => 'currency', 'sortable' => false);
|
||||
|
||||
|
||||
if (isset($transaction_id))
|
||||
$grid->invalidFields('Transaction');
|
||||
|
||||
if (!isset($collected_account_id))
|
||||
$grid->invalidFields('Last Payment');
|
||||
|
||||
if (isset($ledger_id) || isset($account_id))
|
||||
$grid->invalidFields(array('Account'));
|
||||
|
||||
if (isset($lease_id) || isset($customer_id))
|
||||
$grid->invalidFields(array('Customer'));
|
||||
|
||||
if (isset($lease_id))
|
||||
$grid->invalidFields(array('Lease', 'Unit'));
|
||||
|
||||
if (!isset($statement_entry_id))
|
||||
$grid->invalidFields('Applied');
|
||||
else
|
||||
$cols['Sub-Total']['index'] = 'subtotal-applied';
|
||||
|
||||
$grid->invalidFields('Sub-Total');
|
||||
$grid->invalidFields('Applied');
|
||||
|
||||
|
||||
// Now that columns are defined, establish basic grid parameters
|
||||
$grid
|
||||
->columns($cols)
|
||||
->sortField('Date')
|
||||
->defaultFields(array('Entry', 'Date', 'Amount', 'Credit', 'Debit'));
|
||||
|
||||
|
||||
/* // Set up search fields if requested by caller */
|
||||
/* if (isset($searchfields)) */
|
||||
/* $grid->searchFields(array('Customer', 'Unit')); */
|
||||
|
||||
|
||||
// Include custom data
|
||||
$grid->customData(compact('transaction_id', 'account_id', 'customer_id', 'lease_id',
|
||||
'statement_entry_id', 'from_date', 'through_date',
|
||||
'payment_accounts', 'charge_accounts'));
|
||||
|
||||
// Render the grid
|
||||
$grid
|
||||
->render($this, isset($config) ? $config : null,
|
||||
array('Transaction', 'StatementEntry', 'Date', 'Effective', 'Last Payment',
|
||||
'Account',
|
||||
'Customer', 'Unit',
|
||||
'Comment',
|
||||
'Charge', 'Payment', 'Amount',
|
||||
'Applied', 'Sub-Total')
|
||||
);
|
||||
|
||||
@@ -79,11 +79,9 @@ echo '<div CLASS="detail supporting">' . "\n";
|
||||
* Lease Account History
|
||||
*/
|
||||
|
||||
echo $this->element('entries', array
|
||||
echo $this->element('ledger_entries', array
|
||||
(// Element configuration
|
||||
'lease_id' => $lease['id'],
|
||||
//'charge_payment' => true,
|
||||
//'entry_type' => array('CHARGE', 'PAYMENT'),
|
||||
|
||||
// Grid configuration
|
||||
'config' => array
|
||||
|
||||
114
views/statement_entries/view.ctp
Normal file
114
views/statement_entries/view.ctp
Normal file
@@ -0,0 +1,114 @@
|
||||
<?php /* -*- mode:PHP -*- */
|
||||
|
||||
echo '<div class="statement-entry view">' . "\n";
|
||||
|
||||
/**********************************************************************
|
||||
**********************************************************************
|
||||
**********************************************************************
|
||||
**********************************************************************
|
||||
* Entry Detail Main Section
|
||||
*/
|
||||
|
||||
$transaction = $entry['Transaction'];
|
||||
$account = $entry['Account'];
|
||||
$customer = $entry['Customer'];
|
||||
$lease = $entry['Lease'];
|
||||
$entry = $entry['StatementEntry'];
|
||||
|
||||
$rows = array();
|
||||
$rows[] = array('ID', $entry['id']);
|
||||
$rows[] = array('Transaction', $html->link('#'.$transaction['id'],
|
||||
array('controller' => 'transactions',
|
||||
'action' => 'view',
|
||||
$transaction['id'])));
|
||||
$rows[] = array('Timestamp', FormatHelper::datetime($transaction['stamp']));
|
||||
$rows[] = array('Effective', FormatHelper::date($entry['effective_date']));
|
||||
$rows[] = array('Through', FormatHelper::date($entry['through_date']));
|
||||
$rows[] = array('Type', $entry['type']);
|
||||
$rows[] = array('Amount', FormatHelper::currency($entry['amount']));
|
||||
$rows[] = array('Account', $html->link($account['name'],
|
||||
array('controller' => 'accounts',
|
||||
'action' => 'view',
|
||||
$account['id'])));
|
||||
$rows[] = array('Customer', (isset($customer['name'])
|
||||
? $html->link($customer['name'],
|
||||
array('controller' => 'customers',
|
||||
'action' => 'view',
|
||||
$customer['id']))
|
||||
: null));
|
||||
$rows[] = array('Lease', (isset($lease['id'])
|
||||
? $html->link('#'.$lease['id'],
|
||||
array('controller' => 'leases',
|
||||
'action' => 'view',
|
||||
$lease['id']))
|
||||
: null));
|
||||
$rows[] = array('Comment', $entry['comment']);
|
||||
|
||||
echo $this->element('table',
|
||||
array('class' => 'item statement-entry detail',
|
||||
'caption' => 'Statement Entry Detail',
|
||||
'rows' => $rows,
|
||||
'column_class' => array('field', 'value')));
|
||||
|
||||
|
||||
/**********************************************************************
|
||||
* Entry Info Box
|
||||
*/
|
||||
|
||||
echo '<div class="infobox">' . "\n";
|
||||
|
||||
$applied_caption = "Applied";
|
||||
$remaining_caption = "Balance";
|
||||
|
||||
$rows = array();
|
||||
$rows[] = array($applied_caption,
|
||||
'<SPAN id="statement-entry-applied">' .
|
||||
FormatHelper::currency($stats['reconciled']) .
|
||||
'</SPAN>');
|
||||
$rows[] = array($remaining_caption,
|
||||
'<SPAN id="statement-entry-balance">' .
|
||||
FormatHelper::currency($stats['balance']) .
|
||||
'</SPAN>');
|
||||
|
||||
echo $this->element('table',
|
||||
array('class' => 'item summary',
|
||||
'caption' => null,
|
||||
'rows' => $rows,
|
||||
'column_class' => array('field', 'value'),
|
||||
//'suppress_alternate_rows' => true,
|
||||
));
|
||||
|
||||
echo '</div>' . "\n";
|
||||
|
||||
|
||||
/**********************************************************************
|
||||
**********************************************************************
|
||||
**********************************************************************
|
||||
**********************************************************************
|
||||
* Supporting Elements Section
|
||||
*/
|
||||
|
||||
echo '<div CLASS="detail supporting">' . "\n";
|
||||
|
||||
|
||||
/**********************************************************************
|
||||
* Reconciliation Ledger Entries
|
||||
*/
|
||||
|
||||
echo $this->element('statement_entries', array
|
||||
(// Element configuration
|
||||
'statement_entry_id' => $entry['id'],
|
||||
/* 'action' => 'reconcile', */
|
||||
|
||||
// Grid configuration
|
||||
'config' => array
|
||||
('caption' => 'Entries Applied',
|
||||
),
|
||||
));
|
||||
|
||||
|
||||
/* End "detail supporting" div */
|
||||
echo '</div>' . "\n";
|
||||
|
||||
/* End page div */
|
||||
echo '</div>' . "\n";
|
||||
Reference in New Issue
Block a user