Preliminary work on NSF. It's far from working, but we're headed in the right direction.

git-svn-id: file:///svn-source/pmgr/branches/yafr_20090716@426 97e9348a-65ac-dc4b-aefc-98561f571b83
This commit is contained in:
abijah
2009-07-30 06:29:41 +00:00
parent 6e759e8589
commit 56e6aa1f34
3 changed files with 226 additions and 16 deletions

View File

@@ -132,21 +132,18 @@ class TendersController extends AppController {
('contain' => array('TenderType', 'Customer', 'LedgerEntry' => array('Transaction')),
));
// REVISIT <AP>: 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);
if (!empty($tender['Tender']['deposit_transaction_id']) &&
empty($tender['Tender']['nsf_transaction_id'])) {
// Set up dynamic menu items
$this->sidemenu_links[] =
array('name' => 'Operations', 'header' => true);
$this->sidemenu_links[] =
array('name' => 'NSF',
'url' => array('action' => 'nsf',
$id));
$this->sidemenu_links[] =
array('name' => 'NSF',
'url' => array('action' => 'nsf',
$id));
}
// Prepare to render.
$title = "Tender #{$tender['Tender']['id']}";

View File

@@ -87,8 +87,8 @@ class Tender extends AppModel {
*
* Steps:
* - Get information from Check (C1); for amount $A
* - New Transaction (T1)
* - Find Bank Deposit matching to Tender
* - New Transaction (T1)
* - New Bank Deposit (D1)
* - New Tender (N1); NSF; D1,
* - Add new LedgerEntry (L1a); T1; debit:bank; -$A
@@ -121,7 +121,68 @@ class Tender extends AppModel {
));
//'conditions' => array(array('Tender.id' => $id)),
pr($tender);
return;
if (!empty($tender['NsfTransaction']['id']))
die("Item has already been set as NSF");
if (empty($tender['DepositTransaction']['id']))
die("Item has not been deposited yet");
/* $payments = $this->LedgerEntry->Transaction->StatementEntry->find */
/* ('all', array */
/* ('contain' => array('Transaction' => */
/* array('fields' => array(), */
/* 'LedgerEntry */
/* 'conditions' => array('StatementEntry.transaction_id' => xx, */
/* array('LedgerEntry', */
/* 'DepositTransaction', */
/* 'NsfTransaction'), */
/* )); */
$nsf_ledger_entry = $this->LedgerEntry->find
('first', array
('contain' => array('Transaction' =>
array(//'fields' => array(),
'StatementEntry' =>
array(//'fields' => array(),
),
),
),
'conditions' => array('LedgerEntry.id' => $tender['LedgerEntry']['id']),
));
pr(compact('nsf_ledger_entry'));
$bounce = array('Transaction' => array(),
'Entry' => array());
$bounce['Transaction']['account_id'] = $tender['DepositTransaction']['account_id'];
$bounce['Transaction']['customer_id'] = $tender['Tender']['customer_id'];
$bounce['Transaction']['amount'] = -1 * $tender['LedgerEntry']['amount'];
foreach ($nsf_ledger_entry['Transaction']['StatementEntry'] AS $payment) {
$bounce['Entry'][] =
array('type' => 'PAYMENT',
'amount' => -1 * $payment['amount'],
'account_id' => $payment['account_id'],
'customer_id' => $payment['customer_id'],
'lease_id' => $payment['lease_id'],
'charge_entry_id' => $payment['charge_entry_id'],
//'effective_date' => $tender[ stamp ],
);
}
pr(compact('bounce'));
$result = $this->NsfTransaction->addNsf($bounce);
if ($result['error'])
die("Unable to save NSF transaction");
$this->id = $id;
$this->saveField('nsf_transaction_id', $result['transaction_id']);
die();
$nsf_account_id = $A->nsfAccountID();
$nsf_fee_account_id = $A->nsfChargeAccountID();

View File

@@ -86,7 +86,7 @@ class Transaction extends AppModel {
// Go through the statement entries and flag as payments
foreach ($data['Entry'] AS &$entry) {
$entry['crdr'] = 'DEBIT';
if (isset($entry['Tender']['tender_type_id'])) {
if (empty($entry['account_id']) && isset($entry['Tender']['tender_type_id'])) {
$entry['account_id'] = $this->LedgerEntry->Tender->TenderType->
accountID($entry['Tender']['tender_type_id']);
}
@@ -464,6 +464,158 @@ class Transaction extends AppModel {
}
/**************************************************************************
**************************************************************************
**************************************************************************
* function: addNsf
* - Adds NSF transaction
*/
function addNsf($data) {
pr(array("Transaction::addNsf()"
=> compact('data')));
// Verify that we have a transaction and entries
if (empty($data['Transaction']) || empty($data['Entry']))
return array('error' => true);
// Extract the transaction to a local variable
$transaction = $data['Transaction'];
// set ledger ID as the current ledger of the specified account
$transaction['ledger_id'] =
$this->Account->currentLedgerID($transaction['account_id']);
// Automatically figure out the customer if we have the lease
if (!empty($transaction['lease_id']) && empty($transaction['customer_id'])) {
$L = new Lease();
$L->recursive = -1;
$lease = $L->read(null, $transaction['lease_id']);
$transaction['customer_id'] = $lease['Lease']['customer_id'];
}
// Account.id
// - Bank account that NSF occurred on
// amount
// - Amount of NSF
// StatementEntry list
// - payments to reverse
// Break each entry out of the combined statement/ledger entry
// and into individual entries appropriate for saving. While
// we're at it, calculate the transaction total as well.
$entry_total = 0;
foreach ($data['Entry'] AS &$entry) {
// Add entry amount into the transaction total
$entry_total += $entry['amount'];
// We won't be using ledger entries
$le1 = null;
$le1_tender = null;
$le2 = null;
// Create a statement entry
$se =
array_intersect_key($entry,
array_flip(array('type', 'account_id', 'amount',
'customer_id', 'lease_id',
'charge_entry_id')));
$se['ledger_id'] =
$this->Account->currentLedgerID($se['account_id']);
// Replace combined entry with our new individual entries
$entry = compact('le1', 'le1_tender', 'le2', 'se');
}
array_unshift($data['Entry'],
array('le1' => array('account_id' => $transaction['account_id'],
'crdr' => 'DEBIT',
'amount' => $transaction['amount']),
'le2' => array('account_id' => $this->Account->accountReceivableAccountID(),
'crdr' => 'CREDIT',
'amount' => $transaction['amount'])
));
// Move forward, verifying and saving everything.
$ret = array();
/* if (!$this->verifyTransaction($transaction, $data['Entry'])) */
/* return array('error' => true) + $ret; */
pr(array('Transaction::addNsf' =>
array('checkpoint' => 'Pre Transaction Save')
+ compact('transaction')));
pr(compact('data'));
// Save transaction to the database
$this->create();
if (!$this->save($transaction))
return array('error' => true) + $ret;
// Set up our return ids array
$ret['transaction_id'] = $this->id;
$ret['entries'] = array();
$ret['error'] = false;
// Go through the entries
foreach ($data['Entry'] AS $e_index => &$entry) {
$le1 = null;
$le1_tender = null;
$le2 = null;
$se = null;
pr(compact('entry'));
extract($entry);
if (!empty($le1) && !empty($le2)) {
$le1['transaction_id'] = $le2['transaction_id'] = $ret['transaction_id'];
if (isset($le1_tender))
$le1_tender['customer_id'] = $transaction['customer_id'];
$result = $this->LedgerEntry->DoubleEntry->addDoubleEntry($le1, $le2, $le1_tender);
$ret['entries'][$e_index]['DoubleEntry'] = $result;
if ($result['error']) {
$ret['error'] = true;
continue;
}
}
if (!empty($se)) {
$se['transaction_id'] = $ret['transaction_id'];
$result = $this->StatementEntry->addStatementEntry($se);
$ret['entries'][$e_index]['StatementEntry'] = $result;
if ($result['error']) {
$ret['error'] = true;
continue;
}
}
pr(compact('ret'));
}
/* if (($transaction['type'] == 'INVOICE' || */
/* $transaction['type'] == 'RECEIPT') && */
/* !$ret['error']) { */
/* $result = $this->StatementEntry->assignCredits */
/* (array('link' => array('Customer'), */
/* 'conditions' => array('Customer.id' => $transaction['customer_id'])), */
/* ($transaction['type'] == 'RECEIPT' */
/* ? $ret['transaction_id'] */
/* : null)); */
/* $ret['assigned'] = $result; */
/* if ($result['error']) */
/* $ret['error'] = true; */
/* } */
pr(array('Transaction::addNsf' =>
array('return' => $ret)));
return $ret;
}
/**************************************************************************
**************************************************************************
**************************************************************************