diff --git a/app_controller.php b/app_controller.php index 93e5135..f203193 100644 --- a/app_controller.php +++ b/app_controller.php @@ -248,7 +248,10 @@ class AppController extends Controller { } if (isset($params['action']) && $params['action'] === 'idlist') { - $conditions[] = array($model->alias.'.'.$model->primaryKey => $params['idlist']); + if (count($params['idlist'])) + $conditions[] = array($model->alias.'.'.$model->primaryKey => $params['idlist']); + else + $conditions[] = '0=1'; } return $conditions; diff --git a/controllers/ledger_entries_controller.php b/controllers/ledger_entries_controller.php index 3ca7f71..c4c9c59 100644 --- a/controllers/ledger_entries_controller.php +++ b/controllers/ledger_entries_controller.php @@ -32,31 +32,56 @@ class LedgerEntriesController extends AppController { array('fields' => array('id', 'stamp'), ), - 'DebitLedger' => - array('fields' => array('id', 'sequence'), - // Models - 'DebitAccount' => array('class' => 'Account', - 'fields' => array('id', 'name'), - ), - ), - - 'CreditLedger' => - array('fields' => array('id', 'sequence'), - // Models - 'CreditAccount' => array('class' => 'Account', - 'fields' => array('id', 'name'), - ), - ), - 'MonetarySource' => array('fields' => array('id', 'name'), ), ); - if ($params['action'] === 'reconcile') { - $type = $params['custom']['reconcile']; - $link[$type.'ReconciliationLedgerEntry'] = + if (isset($params['custom']['account_ftype'])) { + $ftype = $params['custom']['account_ftype']; + $ftype = ucfirst($ftype); + //$ftype = $this->LedgerEntry->DebitLedger->Account->fundamentalOpposite($ftype); + $link[$ftype . 'Ledger'] = + array('fields' => array('id', 'sequence'), + 'Account' => array('class' => 'Account', + 'fields' => array('id', 'name'), + ), + ); + } + elseif (isset($params['custom']['ledger_id'])) { + $ledger_id = $params['custom']['ledger_id']; + $link['Ledger'] = + array('fields' => array('id', 'sequence'), + 'conditions' => ("Ledger.id = IF(LedgerEntry.debit_ledger_id = $ledger_id," . + " LedgerEntry.credit_ledger_id," . + " LedgerEntry.debit_ledger_id)"), + 'Account' => array( + 'fields' => array('id', 'name'), + ), + ); + } + else { + $link['DebitLedger'] = + array('fields' => array('id', 'sequence'), + 'DebitAccount' => array('class' => 'Account', + 'fields' => array('id', 'name'), + ), + ); + + $link['CreditLedger'] = + array('fields' => array('id', 'sequence'), + 'CreditAccount' => array('class' => 'Account', + 'fields' => array('id', 'name'), + ), + ); + } + + if (isset($params['custom']['reconcile_id'])) { + $ftype = $params['custom']['account_ftype']; + $ftype = $this->LedgerEntry->DebitLedger->Account->fundamentalOpposite($ftype); + $ftype = ucfirst($ftype); + $link[$ftype.'ReconciliationLedgerEntry'] = array('fields' => array('Reconciliation.amount')); } @@ -64,21 +89,33 @@ class LedgerEntriesController extends AppController { } function jqGridDataFields(&$params, &$model) { - return $model->ledgerContextFields($params['custom']['ledger_id'], - $params['custom']['account_type']); + $ledger_id = (isset($params['custom']['ledger_id']) + ? $params['custom']['ledger_id'] + : null); + $account_type = (isset($params['custom']['account_type']) + ? $params['custom']['account_type'] + : null); + + return $model->ledgerContextFields($ledger_id, $account_type); } function jqGridDataConditions(&$params, &$model) { + $ledger_id = (isset($params['custom']['ledger_id']) + ? $params['custom']['ledger_id'] + : null); + $account_type = (isset($params['custom']['account_type']) + ? $params['custom']['account_type'] + : null); + $conditions = parent::jqGridDataConditions($params, $model); if ($params['action'] === 'ledger') { - $conditions[] = $model->ledgerContextConditions($params['custom']['ledger_id'], - $params['custom']['account_type']); + $conditions[] = $model->ledgerContextConditions($ledger_id, $account_type); } - if ($params['action'] === 'reconcile') { - $type = $params['custom']['reconcile']; - $other = ($type === 'Credit' ? 'debit' : 'credit'); - $conditions[] = array('Reconciliation.'.$other.'_ledger_entry_id' => $params['custom']['reconcile_id']); + if (isset($params['custom']['reconcile_id'])) { + $ftype = $params['custom']['account_ftype']; + //$ftype = $this->LedgerEntry->DebitLedger->Account->fundamentalOpposite($ftype); + $conditions[] = array('Reconciliation.'.$ftype.'_ledger_entry_id' => $params['custom']['reconcile_id']); } return $conditions; @@ -87,8 +124,13 @@ class LedgerEntriesController extends AppController { function jqGridRecordLinks(&$params, &$model, &$records, $links) { $links['Transaction'] = array('id'); $links['LedgerEntry'] = array('id'); - $links['DebitAccount'] = array('controller' => 'accounts', 'name'); - $links['CreditAccount'] = array('controller' => 'accounts', 'name'); + if (isset($params['custom']['account_ftype']) || isset($params['custom']['ledger_id'])) { + $links['Account'] = array('controller' => 'accounts', 'name'); + } + else { + $links['DebitAccount'] = array('controller' => 'accounts', 'name'); + $links['CreditAccount'] = array('controller' => 'accounts', 'name'); + } $links['MonetarySource'] = array('name'); return parent::jqGridRecordLinks($params, $model, $records, $links); } @@ -157,8 +199,11 @@ class LedgerEntriesController extends AppController { $stats['credit_amount_remaining'] = $entry['LedgerEntry']['amount'] - $stats['credit_amount_reconciled']; //pr($stats); + $reconciled = $this->LedgerEntry->findReconciledLedgerEntries($id); + //pr($reconciled); + // Prepare to render. $title = "Ledger Entry #{$entry['LedgerEntry']['id']}"; - $this->set(compact('entry', 'title', 'stats')); + $this->set(compact('entry', 'title', 'reconciled', 'stats')); } } diff --git a/models/ledger_entry.php b/models/ledger_entry.php index 9e16194..ad88596 100644 --- a/models/ledger_entry.php +++ b/models/ledger_entry.php @@ -61,29 +61,39 @@ class LedgerEntry extends AppModel { * as an argument for each function to avoid having to * query the ledger/account to find it out. */ - function ledgerContextFields($ledger_id, $account_type) { - if (in_array($account_type, array('ASSET', 'EXPENSE'))) - $ledger_type = 'debit'; - else - $ledger_type = 'credit'; + function ledgerContextFields($ledger_id = null, $account_type = null) { + $fields = array('id', 'name', 'comment', 'amount'); - return array - ('id', 'name', 'comment', - "IF(LedgerEntry.debit_ledger_id = $ledger_id," . - " LedgerEntry.amount, NULL) AS debit", - "IF(LedgerEntry.credit_ledger_id = $ledger_id," . - " LedgerEntry.amount, NULL) AS credit", - "(IF(LedgerEntry.{$ledger_type}_ledger_id = $ledger_id, 1, -1)" . - " * LedgerEntry.amount) AS balance", - ); + if (isset($ledger_id)) { + $fields[] = ("IF(LedgerEntry.debit_ledger_id = $ledger_id," . + " LedgerEntry.amount, NULL) AS debit"); + $fields[] = ("IF(LedgerEntry.credit_ledger_id = $ledger_id," . + " LedgerEntry.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(LedgerEntry.{$ledger_type}_ledger_id = $ledger_id," . + " 1, -1) * LedgerEntry.amount) AS balance"); + } + } + + return $fields; } function ledgerContextConditions($ledger_id, $account_type) { - return array - ('OR' => - array(array('LedgerEntry.debit_ledger_id' => $ledger_id), - array('LedgerEntry.credit_ledger_id' => $ledger_id)), - ); + if (isset($ledger_id)) { + return array + ('OR' => + array(array('LedgerEntry.debit_ledger_id' => $ledger_id), + array('LedgerEntry.credit_ledger_id' => $ledger_id)), + ); + } + + return array(); } /************************************************************************** @@ -120,6 +130,48 @@ class LedgerEntry extends AppModel { } + /************************************************************************** + ************************************************************************** + ************************************************************************** + * function: findReconciledLedgerEntries + * - Returns ledger entries that are reconciled to the given entry. + * (such as payments towards a charge). + */ + + function findReconciledLedgerEntries($id = null, $fundamental_type = null) { + foreach (($fundamental_type + ? array($fundamental_type) + : array('debit', 'credit')) AS $fund) { + $ucfund = ucfirst($fund); + $reconciled[$fund]['entry'] = $this->find + ('all', array + ('link' => array + ("ReconciliationLedgerEntry" => array + ('class' => "{$ucfund}ReconciliationLedgerEntry", + 'fields' => array + ('id', + "COALESCE(SUM(Reconciliation.amount),0) AS 'reconciled'", + "LedgerEntry.amount - COALESCE(SUM(Reconciliation.amount),0) AS 'balance'", + ), + ), + ), + 'group' => ("ReconciliationLedgerEntry.id"), + 'conditions' => array('LedgerEntry.id' => $id), + 'fields' => array(), + )); + //pr($reconciled); + $balance = 0; + foreach ($reconciled[$fund]['entry'] AS &$entry) { + $entry = array_merge($entry["ReconciliationLedgerEntry"], $entry[0]); + $balance += $entry['balance']; + } + $reconciled[$fund]['balance'] = $balance; + } + + return $reconciled; + } + + /************************************************************************** ************************************************************************** ************************************************************************** diff --git a/views/customers/payment.ctp b/views/customers/payment.ctp index 2ec59e5..1c633e1 100644 --- a/views/customers/payment.ctp +++ b/views/customers/payment.ctp @@ -357,20 +357,15 @@ echo $this->element('customers', array('grid_div_id' => 'customers-list', 'caption' => ('Select Customer'), - 'limit' => 7, 'grid_setup' => $grid_setup, )); echo $this->element('ledger_entries', array('grid_div_id' => 'charge-entries', 'caption' => 'Outstanding Charges', -/* (isset($customer['name']) */ -/* ? " for {$customer['name']}: ".FormatHelper::currency($charges['balance']) */ -/* : '')), */ - 'limit' => 8, - 'ledger_id' => 6, - 'account_type' => 'credit', + 'account_ftype' => 'credit', 'ledger_entries' => $charges['entry'], + 'limit' => 8, )); echo ('

' . diff --git a/views/elements/ledger_entries.ctp b/views/elements/ledger_entries.ctp index 09cbbea..2fee5c3 100644 --- a/views/elements/ledger_entries.ctp +++ b/views/elements/ledger_entries.ctp @@ -5,17 +5,27 @@ $cols = array(); $cols['Transaction'] = array('index' => 'Transaction.id', 'formatter' => 'id'); $cols['Entry'] = array('index' => 'LedgerEntry.id', 'formatter' => 'id'); $cols['Date'] = array('index' => 'Transaction.stamp', 'formatter' => 'date'); -$cols['Debit Account'] = array('index' => 'DebitAccount.name', 'formatter' => 'longname'); -$cols['Credit Account'] = array('index' => 'CreditAccount.name', 'formatter' => 'longname'); +if (isset($account_ftype) || isset($ledger_id)) { + $cols['Account'] = array('index' => 'Account.name', 'formatter' => 'longname'); +} +else { + $cols['Debit Account'] = array('index' => 'DebitAccount.name', 'formatter' => 'longname'); + $cols['Credit Account'] = array('index' => 'CreditAccount.name', 'formatter' => 'longname'); +} $cols['Source'] = array('index' => 'MonetarySource.name', 'formatter' => 'name'); $cols['Comment'] = array('index' => 'LedgerEntry.comment', 'formatter' => 'comment', 'width'=>150); -$cols['Debit'] = array('index' => 'debit', 'formatter' => 'currency'); -$cols['Credit'] = array('index' => 'credit', 'formatter' => 'currency'); -if (isset($reconcile)) +if (isset($account_ftype)) { + $cols['Amount'] = array('index' => 'LedgerEntry.amount', 'formatter' => 'currency'); +} +else { + $cols['Debit'] = array('index' => 'debit', 'formatter' => 'currency'); + $cols['Credit'] = array('index' => 'credit', 'formatter' => 'currency'); +} +if (isset($reconcile_id)) { $cols['Applied'] = array('index' => "Reconciliation.amount", 'formatter' => 'currency'); +} -$custom_post_data = array('ledger_id' => $ledger_id, - 'account_type' => $account_type); +$custom_post_data = compact('ledger_id', 'account_type', 'account_ftype'); $jqGrid_options = array('jqGridColumns' => $cols, 'controller' => 'ledger_entries', @@ -23,6 +33,11 @@ $jqGrid_options = array('jqGridColumns' => $cols, $jqGrid_options += compact('grid_div_id', 'grid_id', 'caption', 'grid_setup', 'limit'); +if (isset($ledger_id)) { + $jqGrid_options += array('action' => 'ledger', + 'limit' => 50); +} + if (isset($ledger_entries)) { $jqGrid_options += array('custom_ids' => array_map(create_function('$data', @@ -30,14 +45,10 @@ if (isset($ledger_entries)) { $ledger_entries), 'limit' => 10); } -elseif (isset($reconcile)) { - $custom_post_data += compact('reconcile', 'reconcile_id'); - $jqGrid_options += array('action' => 'reconcile', - 'limit' => 5); -} -else { - $jqGrid_options += array('action' => 'ledger', - 'limit' => 50); + +if (isset($reconcile_id)) { + $custom_post_data += compact('reconcile_id'); + $jqGrid_options += array('limit' => 5); } $jqGrid_options += compact('custom_post_data'); diff --git a/views/ledger_entries/view.ctp b/views/ledger_entries/view.ctp index fc49c57..51a6cec 100644 --- a/views/ledger_entries/view.ctp +++ b/views/ledger_entries/view.ctp @@ -99,20 +99,23 @@ echo '
' . "\n"; echo $this->element('ledger_entries', array('caption' => "Debit Applications", - 'grid_id' => 'debit_reconciliation_ledger_entries', - 'ledger_id' => $debit_ledger['id'], - 'account_type' => $debit_ledger['Account']['type'], - 'reconcile' => 'Credit', // Looking for credits to match this debit + 'grid_div_id' => 'debit_reconciliation_ledger_entries', + //'ledger_id' => $debit_ledger['id'], + //'account_type' => $debit_ledger['Account']['type'], + 'account_ftype' => 'debit', 'reconcile_id' => $entry['id'], + 'ledger_entries' => $reconciled['debit']['entry'], )); echo $this->element('ledger_entries', array('caption' => "Credit Applications", - 'grid_id' => 'credit_reconciliation_ledger_entries', - 'ledger_id' => $credit_ledger['id'], - 'account_type' => $credit_ledger['Account']['type'], - 'reconcile' => 'Debit', // Looking for debits to match this credit + 'grid_div_id' => 'credit_reconciliation_ledger_entries', + //'ledger_id' => $credit_ledger['id'], + //'account_type' => $credit_ledger['Account']['type'], + //'account_ftype' => 'debit', // Looking for debits to match this credit + 'account_ftype' => 'credit', 'reconcile_id' => $entry['id'], + 'ledger_entries' => $reconciled['credit']['entry'], ));