From 50c4ee225f9b58d2cc25faba70c1807febdd21a7 Mon Sep 17 00:00:00 2001 From: abijah Date: Wed, 15 Jul 2009 03:06:59 +0000 Subject: [PATCH] Finally, a working NSF implementation. Ledger Entry tracking stops at the Bank account, since we switch from positive to negative ledger entries. However, we're not going to reconcile debits to credits in the bank account anyway, so I just disabled tracking on the account. git-svn-id: file:///svn-source/pmgr/branches/invoice_receipt_20090629@334 97e9348a-65ac-dc4b-aefc-98561f571b83 --- db/schema.sql | 11 ++- site/controllers/accounts_controller.php | 2 + .../controllers/ledger_entries_controller.php | 7 +- site/models/monetary_source.php | 99 ++++++++++++------- site/views/accounts/collected.ctp | 5 + site/views/elements/ledger_entries.ctp | 8 +- 6 files changed, 85 insertions(+), 47 deletions(-) diff --git a/db/schema.sql b/db/schema.sql index e11693b..a895ec1 100644 --- a/db/schema.sql +++ b/db/schema.sql @@ -883,10 +883,11 @@ INSERT INTO `pmgr_accounts` (`type`, `name`, `tillable`, `payable`, `refundable` ('ASSET', 'Money Order', 1, 1, 0), ('ASSET', 'ACH', 0, 1, 0), ('EXPENSE', 'Concession', 0, 1, 0); -INSERT INTO `pmgr_accounts` (`type`, `name`, `tillable`, `payable`, `refundable`, `depositable`) +INSERT INTO `pmgr_accounts` (`type`, `name`, `refundable`, `depositable`) VALUES --- REVISIT : 20090710 : We probably don't really want petty cash depositable - ('ASSET', 'Petty Cash', 0, 0, 1, 1); +-- REVISIT : 20090710 : We probably don't really want petty cash depositable. +-- This is just for testing our deposit code + ('ASSET', 'Petty Cash', 1, 1); INSERT INTO `pmgr_accounts` (`type`, `name`, `chargeable`, `trackable`) VALUES ('LIABILITY', 'Tax', 1, 1), @@ -895,9 +896,9 @@ INSERT INTO `pmgr_accounts` (`type`, `name`, `chargeable`, `trackable`) ('INCOME', 'Late Charge', 1, 0), ('INCOME', 'NSF Charge', 1, 0), ('INCOME', 'Damage', 1, 0); -INSERT INTO `pmgr_accounts` (`type`, `name`, `depositable`) +INSERT INTO `pmgr_accounts` (`type`, `name`, `depositable`, `trackable`) VALUES - ('ASSET', 'Bank', 1); + ('ASSET', 'Bank', 1, 0); INSERT INTO `pmgr_accounts` (`type`, `name`, `trackable`) VALUES ('EXPENSE', 'Bad Debt', 0), diff --git a/site/controllers/accounts_controller.php b/site/controllers/accounts_controller.php index 52e3a88..450631e 100644 --- a/site/controllers/accounts_controller.php +++ b/site/controllers/accounts_controller.php @@ -153,6 +153,8 @@ class AccountsController extends AppController { } $payment_accounts = $this->Account->paymentAccounts(); + $payment_accounts[$this->Account->nsfAccountID()] = + $this->Account->name($this->Account->nsfAccountID()); $default_accounts = array_diff_key($payment_accounts, array($this->Account->concessionAccountID() => 1)); $this->set(compact('payment_accounts', 'default_accounts')); diff --git a/site/controllers/ledger_entries_controller.php b/site/controllers/ledger_entries_controller.php index d5165bc..3879f8f 100644 --- a/site/controllers/ledger_entries_controller.php +++ b/site/controllers/ledger_entries_controller.php @@ -184,6 +184,9 @@ class LedgerEntriesController extends AppController { if (count(array_intersect($params['fields'], array('applied'))) == 1) $fields[] = 'SUM(Reconciliation.amount) AS applied'; + if ($params['action'] === 'collected') + $fields[] = 'MAX(ReceiptTransaction.stamp) AS last_paid'; + return $fields; } @@ -205,12 +208,12 @@ class LedgerEntriesController extends AppController { else die("INTERNAL ERROR: COLLECTED ACCOUNT ID NOT SET"); - if (isset($collected_from_date)) + if (!empty($collected_from_date)) $conditions[] = array('ReceiptTransaction.stamp >=' => $this->LedgerEntry->Transaction->dateFormatBeforeSave($collected_from_date)); - if (isset($collected_through_date)) + if (!empty($collected_through_date)) $conditions[] = array('ReceiptTransaction.stamp <=' => $this->LedgerEntry->Transaction->dateFormatBeforeSave($collected_through_date . ' 23:59:59')); diff --git a/site/models/monetary_source.php b/site/models/monetary_source.php index 7c6c814..0fe33a2 100644 --- a/site/models/monetary_source.php +++ b/site/models/monetary_source.php @@ -30,18 +30,20 @@ class MonetarySource extends AppModel { * * FEE RENT A/R RECEIPT CHECK NSF BANK * ------- ------- ------- ------- ------- ------- ------- - * | |30 30| | | | | t1 e1a : R e2/e6a : - * | |20 20| | | | | t1 e1b : R e2/e6b : + * | |30 30| | | | | t1 e1a : R e2/e7a : + * | |20 20| | | | | t1 e1b : R e2/e7b : * | | | | | | | - * | | |50 50| | | | t2 e2 : R e3 : R e1a/e1b + * | | |30 30| | | | t2 e2a : R e3 : R e1a + * | | |20 20| | | | t2 e2b : R e3 : R e1b * | | | |50 50| | | t2 e3 : R e4 : R e2 * | | | | | | | - * | | | | |50 | 50| t3 e4 : R e5 : R e3 + * | | | | |50 | 50| t3 e4 : : R e3 * | | | | | | | - * | | | | | |-50 -50| t4 e5 : R e4 (?) : R e6a/e6b - * | | |-30 | | -30| | t5 e6a : R e1a : R e5 - * | | |-20 | | -20| | t5 e6b : R e1b : R e5 - * |35 | 35| | | | | t5 e7 + * | | | | | |-50 -50| t4 e5 : : R e6 + * | | | |-50 | -50| | t5 e6 : R e5 : R e7a/e7b + * | | |-30 -30| | | | t6 e7a : R e6 : R e1a + * | | |-20 -20| | | | t6 e7b : R e6 : R e1b + * |35 | 35| | | | | t6 e8 * */ @@ -125,8 +127,10 @@ class MonetarySource extends AppModel { $nsf_account_id = $A->nsfAccountID(); $nsf_fee_account_id = $A->nsfChargeAccountID(); $ar_account_id = $A->accountReceivableAccountID(); + $receipt_account_id = $A->receiptAccountID(); $t4_id = null; + $t5_id = null; foreach ($source['LedgerEntry'] AS $e3) { // We expect only a single e4 entry $e4 = $e3['CreditReconciliationLedgerEntry']; @@ -139,7 +143,7 @@ class MonetarySource extends AppModel { $e4 = $e4[0]; // e3 amount - $amount = -1 * $e3['amount']; + $amount = -$e3['amount']; // e4 account $bank_account_id = $e4['DebitLedger']['account_id']; @@ -147,21 +151,16 @@ class MonetarySource extends AppModel { // post new e5 $e5_ids = $A->postLedgerEntry (array('transaction_id' => $t4_id), - array('monetary_source_id' => $e3['monetary_source_id']), + null, array('debit_ledger_id' => $A->currentLedgerID($bank_account_id), 'credit_ledger_id' => $A->currentLedgerID($nsf_account_id), 'effective_date' => $stamp, 'amount' => $amount, 'lease_id' => $e3['lease_id'], 'customer_id' => $e3['customer_id'], - 'comment' => "NSF of Monetary Source #{$id}", - ), - array('debit' => array - (array('LedgerEntry' => array - ('id' => $e4['id'], - 'amount' => $amount, - ))), - )); + 'comment' => "NSF Bank Reversal; Monetary Source #{$id}", + ) + ); if ($e5_ids['error']) return null; @@ -170,26 +169,54 @@ class MonetarySource extends AppModel { pr(array('checkpoint' => 'Posted Ledger Entry e5', compact('e5_ids', 'amount'))); - $t5_id = null; + // 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->postLedgerEntry + (array('transaction_id' => $t5_id), + array('monetary_source_id' => $e3['monetary_source_id']), + array('debit_ledger_id' => $A->currentLedgerID($nsf_account_id), + 'credit_ledger_id' => $A->currentLedgerID($receipt_account_id), + 'effective_date' => $stamp, + 'amount' => $amount, + 'lease_id' => $e3['lease_id'], + 'customer_id' => $e3['customer_id'], + 'comment' => "NSF tracker; Monetary Source #{$id}", + ), + array('debit' => array + (array('LedgerEntry' => + array('id' => $e5_ids['id'], + 'amount' => $amount))), + ) + ); + + if ($e6_ids['error']) + return null; + $t5_id = $e6_ids['transaction_id']; + + pr(array('checkpoint' => 'Posted Ledger Entry e6', + compact('e6_ids', 'amount'))); + + $t6_id = null; foreach ($e3['DebitReconciliationLedgerEntry'] AS $e2) { foreach ($e2['DebitReconciliationLedgerEntry2'] AS $e1) { $amount = -1*$e1['Reconciliation']['amount']; - // post new e6 - $e6_ids = $A->postLedgerEntry - (array('transaction_id' => $t5_id), + // post new e7 + $e7_ids = $A->postLedgerEntry + (array('transaction_id' => $t6_id), null, - array('debit_ledger_id' => $A->currentLedgerID($nsf_account_id), + array('debit_ledger_id' => $A->currentLedgerID($receipt_account_id), 'credit_ledger_id' => $A->currentLedgerID($ar_account_id), 'effective_date' => $stamp, 'amount' => $amount, 'lease_id' => $e1['lease_id'], 'customer_id' => $e1['customer_id'], - 'comment' => "NSF back to A/R from Monetary Source #{$id}", + 'comment' => "NSF Receipt; Monetary Source #{$id}", ), array('debit' => array (array('LedgerEntry' => - array('id' => $e5_ids['id'], + array('id' => $e6_ids['id'], 'amount' => $amount))), 'credit' => array @@ -199,12 +226,12 @@ class MonetarySource extends AppModel { ) ); - if ($e6_ids['error']) + if ($e7_ids['error']) return null; - $t5_id = $e6_ids['transaction_id']; + $t6_id = $e7_ids['transaction_id']; - pr(array('checkpoint' => 'Posted Ledger Entry e6', - compact('e6_ids', 'amount'))); + pr(array('checkpoint' => 'Posted Ledger Entry e7', + compact('e7_ids', 'amount'))); } } } @@ -213,9 +240,9 @@ class MonetarySource extends AppModel { $customer_id = $source['LedgerEntry'][0]['customer_id']; $lease_id = null; - // post new e7 - $e7_ids = $A->postLedgerEntry - (array('transaction_id' => $t5_id), + // post new e8 + $e8_ids = $A->postLedgerEntry + (array('transaction_id' => $t6_id), null, array('debit_ledger_id' => $A->currentLedgerID($ar_account_id), 'credit_ledger_id' => $A->currentLedgerID($nsf_fee_account_id), @@ -223,15 +250,15 @@ class MonetarySource extends AppModel { 'amount' => 35, 'lease_id' => $lease_id, 'customer_id' => $customer_id, - 'comment' => "NSF Fee for Monetary Source #{$id}", + 'comment' => "NSF Fee; Monetary Source #{$id}", ) ); - if ($e7_ids['error']) + if ($e8_ids['error']) return null; - pr(array('checkpoint' => 'Posted Ledger Entry e7', - compact('e7_ids'))); + pr(array('checkpoint' => 'Posted Ledger Entry e8', + compact('e8_ids'))); return true; } diff --git a/site/views/accounts/collected.ctp b/site/views/accounts/collected.ctp index 92b50e9..6e43190 100644 --- a/site/views/accounts/collected.ctp +++ b/site/views/accounts/collected.ctp @@ -26,6 +26,11 @@ function resetForm() { /* datepickerBOM(null, 'TxFromDate'); */ /* datepickerNow('TxThroughDate', false); */ + // REVISIT : 20090714 + // Figure out how to just prevent jqGrid + // from loading in the first place + +/* $('#collected-entries-jqGrid').clearGridData(); */ /* updateEntriesGrid(); */ } diff --git a/site/views/elements/ledger_entries.ctp b/site/views/elements/ledger_entries.ctp index 293f266..890079e 100644 --- a/site/views/elements/ledger_entries.ctp +++ b/site/views/elements/ledger_entries.ctp @@ -24,7 +24,7 @@ $cols['Amount'] = array('index' => 'LedgerEntry.amount', 'formatter' => $cols['Debit'] = array('index' => 'debit', 'formatter' => 'currency'); $cols['Credit'] = array('index' => 'credit', 'formatter' => 'currency'); -$cols['Paid'] = array('index' => 'ReceiptTransaction.stamp', 'formatter' => 'date'); +$cols['Last Payment'] = array('index' => 'last_paid', 'formatter' => 'date'); $cols['Applied'] = array('index' => "applied", 'formatter' => 'currency'); $cols['Sub-Total'] = array('index' => 'subtotal-LedgerEntry.amount', 'formatter' => 'currency', 'sortable' => false); @@ -55,7 +55,7 @@ if ($group_by_tx) $grid->invalidFields(array('Effective', 'Through')); if (!isset($collected_account_id)) - $grid->invalidFields('Paid'); + $grid->invalidFields('Last Payment'); if (isset($account_ftype) || isset($ledger_id) || isset($account_id) || isset($ar_account)) $grid->invalidFields(array('Debit Account', 'Credit Account')); @@ -109,7 +109,7 @@ if (isset($reconcile_id)) { if (isset($collected_account_id)) { $config['action'] = 'collected'; $grid->customData(compact('collected_account_id'))->limit(500); - $grid->sortField('Paid'); + $grid->sortField('Last Payment'); } // Set up search fields if requested by caller @@ -124,7 +124,7 @@ $grid->customData(compact('ledger_id', 'account_id', 'ar_account', // Render the grid $grid ->render($this, isset($config) ? $config : null, - array('Transaction', 'Entry', 'Date', 'Effective', 'Paid', + array('Transaction', 'Entry', 'Date', 'Effective', 'Last Payment', 'Account', 'Debit Account', 'Credit Account', 'Customer', 'Unit', 'Comment',