From d5388e7767bc7aa69f1bf03d6d26b43f7ebde9a0 Mon Sep 17 00:00:00 2001 From: abijah Date: Thu, 18 Jun 2009 03:57:43 +0000 Subject: [PATCH] Although I'm not too happy with the modifications, I do have a working version that minimizes the columns need to display ledger entries. The logic feels screwy to me, but I've beat my head on it long enough. I'll move on to something else and come back to it when my head clears. git-svn-id: file:///svn-source/pmgr/branches/ledger_transactions_20090605/site@166 97e9348a-65ac-dc4b-aefc-98561f571b83 --- app_controller.php | 5 +- controllers/ledger_entries_controller.php | 105 +++++++++++++++------- models/ledger_entry.php | 90 +++++++++++++++---- views/customers/payment.ctp | 9 +- views/elements/ledger_entries.ctp | 41 +++++---- views/ledger_entries/view.ctp | 19 ++-- 6 files changed, 189 insertions(+), 80 deletions(-) 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'], ));