From ea1ad4764f1be1c4e9d2da9802a709f4250a0ca0 Mon Sep 17 00:00:00 2001 From: abijah Date: Wed, 1 Jul 2009 11:10:57 +0000 Subject: [PATCH] Implemented a bank deposit routine, to transfer funds out of the till and into the bank. git-svn-id: file:///svn-source/pmgr/branches/invoice_receipt_20090629/site@196 97e9348a-65ac-dc4b-aefc-98561f571b83 --- controllers/accounts_controller.php | 45 +++++++ models/account.php | 179 ++++++++++++++++++++++++++++ views/accounts/deposit.ctp | 58 +++++++++ views/elements/accounts.ctp | 9 +- views/elements/ledger_entries.ctp | 8 +- 5 files changed, 297 insertions(+), 2 deletions(-) create mode 100644 views/accounts/deposit.ctp diff --git a/controllers/accounts_controller.php b/controllers/accounts_controller.php index d957f10..f1674b4 100644 --- a/controllers/accounts_controller.php +++ b/controllers/accounts_controller.php @@ -12,6 +12,7 @@ class AccountsController extends AppController { array('name' => 'Equity', 'url' => array('controller' => 'accounts', 'action' => 'equity')), array('name' => 'Income', 'url' => array('controller' => 'accounts', 'action' => 'income')), array('name' => 'Expense', 'url' => array('controller' => 'accounts', 'action' => 'expense')), + array('name' => 'Bank Deposit', 'url' => array('controller' => 'accounts', 'action' => 'deposit')), ); @@ -189,4 +190,48 @@ class AccountsController extends AppController { $this->set(compact('account', 'title', 'stats')); } + + /************************************************************************** + ************************************************************************** + ************************************************************************** + * action: deposit + * - Prepares the books for a bank deposit + */ + function deposit() { + if ($this->data) { + pr($this->data); +/* $this->autoRender = false; */ +/* return; */ + + $transaction = array(); + foreach ($this->data['Tillable']['Ledger']['id'] AS $acct_id) { + if ($this->data['Tillable']['Ledger'][$acct_id]['amount'] == 0) + continue; + + $ids = $this->Account->postLedgerEntry + ($transaction, + null, + array('debit_account_id' => $this->data['Deposit']['Account']['id'], + 'credit_account_id' => $acct_id, + 'amount' => $this->data['Tillable']['Ledger'][$acct_id]['amount'])); + $transaction = array_intersect_key($ids, array('transaction_id'=>1)); + + $this->Account->closeCurrentLedger($acct_id); + } + + + $this->autoRender = false; + return; + } + + $tillable_account = $this->Account->relatedAccounts('tillable'); + $depositable_account = $this->Account->relatedAccounts('depositable'); + + foreach ($tillable_account AS &$acct) { + $acct['Account']['stats'] = $this->Account->stats($acct['Account']['id']); + } + + $this->set(compact('tillable_account', 'depositable_account')); + } + } diff --git a/models/account.php b/models/account.php index 792eda7..3465590 100644 --- a/models/account.php +++ b/models/account.php @@ -92,6 +92,26 @@ class Account extends AppModel { function invoiceAccountID() { return $this->nameToID('Invoice'); } function receiptAccountID() { return $this->nameToID('Receipt'); } + /************************************************************************** + ************************************************************************** + ************************************************************************** + * function: relatedAccounts + * - Returns an array of accounts related by similar attributes + */ + + function relatedAccounts($attribute) { + $this->cacheQueries = true; + $account = $this->find('all', array + ('contain' => array('CurrentLedger'), + 'fields' => array('Account.id', 'Account.type', 'Account.name', 'CurrentLedger.id'), + 'conditions' => array('Account.'.$attribute => true) + )); + $this->cacheQueries = false; + + return $account; + } + + /************************************************************************** ************************************************************************** ************************************************************************** @@ -346,6 +366,165 @@ class Account extends AppModel { return $unreconciled; } + + /************************************************************************** + ************************************************************************** + ************************************************************************** + * function: postLedgerEntry + * - + * transaction_data + * - transaction_id (optional... if set all else is ignored) + * - Transaction + * - stamp (optional... otherwise NOW is used) + * - comment + * + * monetary_source_data + * - monetary_source_id (optional... if set all else is ignored) + * - monetary_type_name + * - MonetarySource + * - name + * - monetary_type_id + */ + + function postLedgerEntry($transaction_data, + $monetary_data, + $entry_data) { + +/* if (!isset($entry_data) || */ +/* !isset($entry_data['amount']) || */ +/* !$entry_data['amount']) */ +/* return false; */ + + $A = new Account(); + +/* // Create a transaction if necessary */ +/* if (!isset($transaction_data['id'])) { */ +/* $transaction = new Transaction(); */ +/* $transaction->create(); */ +/* if (!$transaction->save($transaction_data, false)) { */ +/* return false; */ +/* } */ +/* $transaction_data['id'] = $transaction->id; */ +/* } */ + + // Get the Transaction squared away + if (isset($transaction_data['transaction_id'])) { + $transaction_data + = array_intersect_key($transaction_data, + array('transaction_id'=>1)); + } + elseif (isset($transaction_data['Transaction'])) { + $transaction_data + = array_intersect_key($transaction_data, + array('Transaction'=>1)); + } + else { + $transaction_data = array('Transaction'=>array('stamp' => null)); + } + + + // Get the Monetary Source squared away + if (isset($monetary_data['monetary_source_id'])) { + $monetary_data + = array_intersect_key($monetary_data, + array('monetary_source_id'=>1)); + } + elseif (isset($monetary_data['monetary_type_name'])) { + if ($monetary_data['monetary_type_name'] === 'Cash') { + // No distinguishing features of Cash, just + // use the shared monetary source + $monetary_data['monetary_source_id'] = + $this->Ledger->LedgerEntry->MonetarySource->nameToID('Cash'); + $monetary_data + = array_intersect_key($monetary_data, + array('monetary_source_id'=>1)); + } + else { + // The monetary source needs to be unique + // Create a new one dedicated to this entry + $monetary_data['MonetarySource']['monetary_type_id'] = + $this->Ledger->LedgerEntry->MonetarySource->MonetaryType + ->nameToID($monetary_data['monetary_type_name']); + + $monetary_data['MonetarySource']['name'] = + $this->Ledger->LedgerEntry->MonetarySource->MonetaryType + ->nameToID($monetary_data['monetary_type_name']); + + // Give it a fancy name based on the check number + $monetary_data['MonetarySource']['name'] = $monetary_data['monetary_type_name']; + if ($monetary_data['monetary_type_name'] === 'Check' || + $monetary_data['monetary_type_name'] === 'Money Order') { + $monetary_data['MonetarySource']['name'] .= + ' #' . $monetary_data['MonetarySource']['data1']; + } + + $monetary_data + = array_intersect_key($monetary_data, + array('MonetarySource'=>1)); + } + } + elseif (isset($monetary_data)) { + $monetary_data + = array_intersect_key($monetary_data, + array('MonetarySource'=>1)); + } + else { + $monetary_data = array(); + } + + // Make sure to clean out any unwanted data from the entry + $entry_data + = array_diff_key($entry_data, + array('transaction_id'=>1, 'Transaction'=>1, + 'monetary_source_id'=>1, 'MonetarySource'=>1)); + + // Then add in the transaction and monetary source data + //pr(compact('transaction_data', 'monetary_data', 'entry_data')); + if (isset($transaction_data)) + $entry_data += $transaction_data; + if (isset($monetary_data)) + $entry_data += $monetary_data; + + // Set up the debit ledger id + if (!isset($entry_data['debit_ledger_id'])) { + $entry_data['debit_ledger_id'] = + ($entry_data['debit_account_id'] + ? $A->currentLedgerID($entry_data['debit_account_id']) + : ($entry_data['debit_account_name'] + ? $A->currentLedgerID($A->nameToID($entry_data['debit_account_name'])) + : null + ) + ); + } + + // Set up the credit ledger id + if (!isset($entry_data['credit_ledger_id'])) { + $entry_data['credit_ledger_id'] = + ($entry_data['credit_account_id'] + ? $A->currentLedgerID($entry_data['credit_account_id']) + : ($entry_data['credit_account_name'] + ? $A->currentLedgerID($A->nameToID($entry_data['credit_account_name'])) + : null + ) + ); + } + + //pr(array('pre-save', compact('entry_data'))); + // Create it! + $entry = new LedgerEntry(); + $entry->create(); + if (!$entry->saveAll($entry_data, array('validate'=>false))) { + return false; + } + $entry->read(); + //pr(array('post-save', $entry->data)); + + return array('transaction_id' => $entry->data['LedgerEntry']['transaction_id'], + 'monetary_source_id' => $entry->data['LedgerEntry']['monetary_source_id'], + 'id' => $entry->data['LedgerEntry']['id']); + } + + /************************************************************************** ************************************************************************** ************************************************************************** diff --git a/views/accounts/deposit.ctp b/views/accounts/deposit.ctp new file mode 100644 index 0000000..8ae2f4b --- /dev/null +++ b/views/accounts/deposit.ctp @@ -0,0 +1,58 @@ +' . "\n"; +echo '

Perform Bank Deposit

' . "\n"; + +//pr(compact('tillableAccount', 'depositableAccount')); + +echo $form->create(null, array('id' => 'deposit-form', + 'url' => array('controller' => 'accounts', + 'action' => 'deposit'))); + +$grid_setup = array(); +$grid_setup['hiddengrid'] = true; + +foreach ($tillableAccount AS $acct) { + //$acct = $acct['Account']; + + echo (' '); + echo ("I have exactly " . + FormatHelper::currency($acct['Account']['stats']['Ledger']['balance']) . + " in " . ($acct['Account']['name'] === 'Cash' + ? 'Cash' + : Inflector::pluralize($acct['Account']['name'])) . + " and will be depositing it all." . + "" . "\n"); + echo (' '); + + $grid_div_id = 'ledger_entries'.$acct['CurrentLedger']['id'].'-list'; + echo $this->element('ledger_entries', + array('grid_div_id' => $grid_div_id, + 'caption' => ('Items in '.$acct['Account']['name'].' Ledger'), + 'ledger_id' => $acct['CurrentLedger']['id'], + 'no_account' => true, + 'grid_setup' => $grid_setup, + //'account_id' => $acct['Account']['id'], + //'account_type' => $acct['Account']['type'], + //'account_ftype' => 'debit', + )); +} + +$options = array(); +foreach ($depositableAccount AS $acct) { + $options[$acct['Account']['id']] = $acct['Account']['name']; +} + +echo $form->input('Deposit.Account.id', array('label' => 'Deposit Account ', + 'options' => $options)); +echo $form->end('Perform Deposit'); + +/* End page div */ +echo '' . "\n"; diff --git a/views/elements/accounts.ctp b/views/elements/accounts.ctp index 70ae3ec..4c6cc0e 100644 --- a/views/elements/accounts.ctp +++ b/views/elements/accounts.ctp @@ -11,9 +11,14 @@ $cols['Credits'] = array('index' => 'credits', 'formatter' => 'currenc $cols['Balance'] = array('index' => 'balance', 'formatter' => 'currency'); $cols['Comment'] = array('index' => 'Account.comment', 'formatter' => 'comment'); +$custom_post_data = compact('nothing'); + $jqGrid_options = array('jqGridColumns' => $cols, 'controller' => 'accounts', - 'caption' => isset($caption) ? $caption : null); + ); + +$jqGrid_options += compact('grid_div_id', 'grid_id', 'caption', 'grid_setup', 'limit'); + if (isset($accounts)) { $jqGrid_options += array('custom_ids' => @@ -26,4 +31,6 @@ else { $jqGrid_options += array('search_fields' => array('Name')); } +$jqGrid_options += compact('custom_post_data'); +$jqGrid_options['sort_column'] = 'Name'; echo $this->element('jqGrid', $jqGrid_options); diff --git a/views/elements/ledger_entries.ctp b/views/elements/ledger_entries.ctp index 2fd4e8c..8ca5e3d 100644 --- a/views/elements/ledger_entries.ctp +++ b/views/elements/ledger_entries.ctp @@ -2,10 +2,15 @@ if (isset($account_ftype) || isset($ledger_id) || isset($account_id) || isset($ar_account)) { $single_account = true; + $double_account = false; } else { $single_account = false; + $double_account = true; } +if (isset($no_account)) + $single_account = $double_account = false; + if (isset($ledger_id) || isset($account_id) || isset($ar_account)) { $single_amount = false; } else { @@ -49,7 +54,8 @@ $cols['Date'] = array('index' => 'Transaction.stamp', 'formatter' => if ($single_account) { $cols['Account'] = array('index' => 'Account.name', 'formatter' => 'name'); } -else { + +if ($double_account) { $cols['Debit Account'] = array('index' => 'DebitAccount.name', 'formatter' => 'name'); $cols['Credit Account'] = array('index' => 'CreditAccount.name', 'formatter' => 'name'); }