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 ('