From 69b3cf3ed3c746625cba79e0955e17be97e29c2b Mon Sep 17 00:00:00 2001 From: abijah Date: Mon, 13 Jul 2009 10:14:38 +0000 Subject: [PATCH] Implementing NSF in MonetarySourcesController. It's nowhere near done, but it seems we're headed in the right direction. git-svn-id: file:///svn-source/pmgr/branches/invoice_receipt_20090629/site@328 97e9348a-65ac-dc4b-aefc-98561f571b83 --- controllers/monetary_sources_controller.php | 32 ++++ models/ledger_entry.php | 148 ++++++++++++++++++ models/monetary_source.php | 159 ++++++++++++++++++++ 3 files changed, 339 insertions(+) diff --git a/controllers/monetary_sources_controller.php b/controllers/monetary_sources_controller.php index cef0f05..9cc46a9 100644 --- a/controllers/monetary_sources_controller.php +++ b/controllers/monetary_sources_controller.php @@ -48,6 +48,22 @@ class MonetarySourcesController extends AppController { } + /************************************************************************** + ************************************************************************** + ************************************************************************** + * action: nsf + * - Marks a monetary source as having insufficient funds. + */ + + function nsf($id = null) { + if (!$id) { + $this->Session->setFlash(__('Invalid Item.', true)); + $this->redirect(array('action'=>'index')); + } + + $this->MonetarySource->nsf($id); + } + /************************************************************************** ************************************************************************** ************************************************************************** @@ -67,6 +83,22 @@ class MonetarySourcesController extends AppController { ('contain' => false, )); + // REVISIT : 20090713 + // Consider allowing the NSF operation only if the source is used on + // a ledger entry that is debited on a "payable" account (perhaps + // even restricted to "payable" ASSET accounts), credited on Receipt + // (or A/R), and reconciles the credit to an entry that debits on a + // "depositable" account. + + // Set up dynamic menu items + $this->sidemenu_links[] = + array('name' => 'Operations', 'header' => true); + + $this->sidemenu_links[] = + array('name' => 'NSF', + 'url' => array('action' => 'nsf', + $id)); + // Prepare to render. $title = "Monetary Source #{$monetary_source['MonetarySource']['id']}"; $this->set(compact('monetary_source', 'title')); diff --git a/models/ledger_entry.php b/models/ledger_entry.php index e40a90f..f947902 100644 --- a/models/ledger_entry.php +++ b/models/ledger_entry.php @@ -318,6 +318,154 @@ class LedgerEntry extends AppModel { $tid = $ids['transaction_id']; + pr(compact('entry')); + + foreach (array('Debit', 'Credit') AS $dc_type) { + foreach ($entry[$dc_type . 'ReconciliationLedgerEntry'] AS $RLE) { + pr(array('checkpoint' => "Reverse $dc_type LE", + compact('id', 'rec_id', 'RLE'))); + if ($RLE['id'] == $rec_id) { + pr(array('checkpoint' => "Skipping Reverse $dc_type LE, due to rec_id", + compact('id', 'RLE'))); + continue; + } + + if (!$this->reverse($RLE['id'], $RLE['Reconciliation']['amount'], $tid, $id)) + $ids['error'] = true; + +/* $rids = $this->Ledger->Account->postLedgerEntry */ +/* (array('transaction_id' => $tid), */ +/* null, */ +/* array('debit_ledger_id' => $A->currentLedgerID($RLE['CreditLedger']['account_id']), */ +/* 'credit_ledger_id' => $A->currentLedgerID($RLE['DebitLedger']['account_id']), */ +/* 'effective_date' => $RLE['effective_date'], */ +/* //'effective_date' => $RLE['effective_date'], */ +/* 'amount' => $RLE['Reconciliation']['amount'], */ +/* 'lease_id' => $entry['Lease']['id'], */ +/* 'customer_id' => $entry['Customer']['id'], */ +/* 'comment' => "Reversal of Ledger Entry #{$RLE['id']}", */ +/* ), */ +/* array('debit' => array(array('LedgerEntry' => array('id' => $RLE['id'], */ +/* 'amount' => $RLE['Reconciliation']['amount'], */ +/* ))), */ +/* 'credit' => array(array('LedgerEntry' => array('id' => $RLE['id'], */ +/* 'amount' => $RLE['Reconciliation']['amount'], */ +/* ))), */ +/* )); */ + +/* if ($rids['error']) */ +/* $ids['error'] = true; */ + } + } + + if ($ids['error']) + return null; + + return $ids['id']; + } + + + /************************************************************************** + ************************************************************************** + ************************************************************************** + * function: nsf + * - Flags the ledger entry as having insufficient funds + * - NOTE: nsf only works if given transaction t2b, below + * + * FEE RENT A/R RECEIPT CHECK NSF BANK + * ------- ------- ------- ------- ------- ------- ------- + * | |50 50| | | | | t1 + * | | | | | | | + * | | |50 50| | | | t2a + * | | | |50 50| | | t2b + * | | | | | | | + * | | | | |50 | 50| t3 + * | | | | | | | + * | | | | | 50| |50 t4a + * | | 50| | | |50 | t4b + * |35 | 35| | | | | t4b + * + */ + + function nsf($id, $amount = null, $transaction_id = null, $rec_id = null) { + pr(array('LedgerEntry::nsf', + compact('id', 'amount', 'transaction_id', 'rec_id'))); + + // Get the LedgerEntry and related fields + $entry = $this->find + ('first', + array('contain' => array(/* t2b */ + 'Transaction.id', + 'MonetarySource.id', + 'Customer.id', + 'Lease.id', + + /* e.g. CHECK */ +/* 'DebitLedger.account_id', */ + 'DebitLedger' => + array('fields' => array(), + 'Account' => + array('fields' => array('id', 'name'), + 'conditions' => + array(array('Account.payable' => 1), + array('Account.type' => 'ASSET')), + ), + ), + + /* e.g. RECEIPT */ +/* 'CreditLedger.account_id', */ + array('fields' => array(), + 'Account' => + array('fields' => array('id', 'name'), + 'conditions' => + array('Account.depositable' => 1), + ), + ), + + /* t3 */ + 'DebitReconciliationLedgerEntry' => + array(/* e.g. BANK */ + 'DebitLedger.account_id', + ), + ), + +/* 'fields' => array('LedgerEntry.*'), */ + + 'conditions' => array(array('LedgerEntry.id' => $id), + ), + )); + pr($entry); + + if (!isset($amount)) + $amount = $entry['LedgerEntry']['amount']; + + $A = new Account(); + + $ids = $this->Ledger->Account->postLedgerEntry + (array('transaction_id' => $transaction_id), + null, + array('debit_ledger_id' => $A->currentLedgerID($entry['CreditLedger']['account_id']), + 'credit_ledger_id' => $A->currentLedgerID($entry['DebitLedger']['account_id']), + 'effective_date' => $entry['LedgerEntry']['effective_date'], + //'effective_date' => $entry['LedgerEntry']['effective_date'], + 'amount' => $amount, + 'lease_id' => $entry['Lease']['id'], + 'customer_id' => $entry['Customer']['id'], + 'comment' => "Reversal of Ledger Entry #{$id}", + ), + array('debit' => array(array('LedgerEntry' => array('id' => $entry['LedgerEntry']['id'], + 'amount' => $amount, + ))), + 'credit' => array(array('LedgerEntry' => array('id' => $entry['LedgerEntry']['id'], + 'amount' => $amount, + ))), + )); + + if ($ids['error']) + return null; + + $tid = $ids['transaction_id']; + /* pr(compact('entry')); */ foreach (array('Debit', 'Credit') AS $dc_type) { diff --git a/models/monetary_source.php b/models/monetary_source.php index 32b99fb..dc30bec 100644 --- a/models/monetary_source.php +++ b/models/monetary_source.php @@ -15,5 +15,164 @@ class MonetarySource extends AppModel { 'LedgerEntry', ); + + /************************************************************************** + ************************************************************************** + ************************************************************************** + * function: nsf + * - Flags the ledger entry as having insufficient funds + * - NOTE: nsf only works if given the monetary source id + * to transaction t2b, below + * + * FEE RENT A/R RECEIPT CHECK NSF BANK + * ------- ------- ------- ------- ------- ------- ------- + * | |50 50| | | | | t1 + * | | | | | | | + * | | |50 50| | | | t2a + * | | | |50 50| | | t2b + * | | | | | | | + * | | | | |50 | 50| t3 + * | | | | | | | + * | | | | | 50| |50 t4a + * | | 50| | | |50 | t4b + * |35 | 35| | | | | t4b + * + */ + + function nsf($id) { + pr(array('MonetarySource::nsf', + compact('id'))); + + $A = new Account(); + + // Get the LedgerEntries that use this monetary source + $entries = $this->find + ('all', + array('contain' => + array(/* t2b */ + 'LedgerEntry' => + array('Transaction.id', + 'MonetarySource.id', + 'Customer.id', + 'Lease.id', + + /* e.g. CHECK */ + 'DebitLedger' => + array('fields' => array(), + 'Account' => + array('fields' => array('id', 'name'), + 'conditions' => +/* array(array('Account.payable' => 1), */ +/* array('Account.type' => 'ASSET')), */ + array('Account.payable' => 1, + 'Account.type' => 'ASSET'), + ), + ), + + /* e.g. RECEIPT */ + 'CreditLedger' => + array('fields' => array(), + 'Account' => + array('fields' => array('id', 'name'), + 'conditions' => + array('Account.id' => $A->receiptAccountID()), + ), + ), + + /* t3 */ + 'CreditReconciliationLedgerEntry' => + array(/* e.g. BANK */ + 'DebitLedger' => + array('fields' => array(), + 'Account' => + array('fields' => array('id', 'name'), + 'conditions' => + array('Account.depositable' => 1), + ), + ), + ), + ), + ), + +/* 'fields' => array('LedgerEntry.*'), */ + + 'conditions' => array(array('MonetarySource.id' => $id), + ), + )); + pr($entries); + die(); + + if (!isset($amount)) + $amount = $entry['LedgerEntry']['amount']; + + $ids = $this->Ledger->Account->postLedgerEntry + (array('transaction_id' => $transaction_id), + null, + array('debit_ledger_id' => $A->currentLedgerID($entry['CreditLedger']['account_id']), + 'credit_ledger_id' => $A->currentLedgerID($entry['DebitLedger']['account_id']), + 'effective_date' => $entry['LedgerEntry']['effective_date'], + //'effective_date' => $entry['LedgerEntry']['effective_date'], + 'amount' => $amount, + 'lease_id' => $entry['Lease']['id'], + 'customer_id' => $entry['Customer']['id'], + 'comment' => "Reversal of Ledger Entry #{$id}", + ), + array('debit' => array(array('LedgerEntry' => array('id' => $entry['LedgerEntry']['id'], + 'amount' => $amount, + ))), + 'credit' => array(array('LedgerEntry' => array('id' => $entry['LedgerEntry']['id'], + 'amount' => $amount, + ))), + )); + + if ($ids['error']) + return null; + + $tid = $ids['transaction_id']; + +/* pr(compact('entry')); */ + + foreach (array('Debit', 'Credit') AS $dc_type) { + foreach ($entry[$dc_type . 'ReconciliationLedgerEntry'] AS $RLE) { +/* pr(array('checkpoint' => "Reverse $dc_type LE", */ +/* compact('id', 'RLE'))); */ + if ($RLE['id'] == $rec_id) + continue; + + if (!$this->reverse($RLE['id'], $RLE['Reconciliation']['amount'], $tid, $id)) + $ids['error'] = true; + +/* $rids = $this->Ledger->Account->postLedgerEntry */ +/* (array('transaction_id' => $tid), */ +/* null, */ +/* array('debit_ledger_id' => $A->currentLedgerID($RLE['CreditLedger']['account_id']), */ +/* 'credit_ledger_id' => $A->currentLedgerID($RLE['DebitLedger']['account_id']), */ +/* 'effective_date' => $RLE['effective_date'], */ +/* //'effective_date' => $RLE['effective_date'], */ +/* 'amount' => $RLE['Reconciliation']['amount'], */ +/* 'lease_id' => $entry['Lease']['id'], */ +/* 'customer_id' => $entry['Customer']['id'], */ +/* 'comment' => "Reversal of Ledger Entry #{$RLE['id']}", */ +/* ), */ +/* array('debit' => array(array('LedgerEntry' => array('id' => $RLE['id'], */ +/* 'amount' => $RLE['Reconciliation']['amount'], */ +/* ))), */ +/* 'credit' => array(array('LedgerEntry' => array('id' => $RLE['id'], */ +/* 'amount' => $RLE['Reconciliation']['amount'], */ +/* ))), */ +/* )); */ + +/* if ($rids['error']) */ +/* $ids['error'] = true; */ + } + } + + if ($ids['error']) + return null; + + return $ids['id']; + } + + } ?> \ No newline at end of file