Combined the addNsf and addTransaction functions, which was always intended. There is more that could be done, but not all bugs are flushed out yet. Its close enough though, that I want to capture it as is to help work through the subtle issues.
git-svn-id: file:///svn-source/pmgr/branches/yafr_20090716@464 97e9348a-65ac-dc4b-aefc-98561f571b83
This commit is contained in:
@@ -103,7 +103,7 @@ class Tender extends AppModel {
|
||||
*/
|
||||
|
||||
function nsf($id, $stamp = null) {
|
||||
//$this->prFunctionLevel(30);
|
||||
$this->prFunctionLevel(30);
|
||||
$this->prEnter(compact('id'));
|
||||
|
||||
// Get information about this NSF item.
|
||||
@@ -115,7 +115,6 @@ class Tender extends AppModel {
|
||||
'DepositTransaction',
|
||||
'NsfTransaction'),
|
||||
));
|
||||
//'conditions' => array(array('Tender.id' => $id)),
|
||||
$this->pr(20, compact('tender'));
|
||||
|
||||
if (!empty($tender['NsfTransaction']['id']))
|
||||
@@ -124,108 +123,19 @@ class Tender extends AppModel {
|
||||
if (empty($tender['DepositTransaction']['id']))
|
||||
die("Item has not been deposited yet");
|
||||
|
||||
// Enter the NSF
|
||||
// This is the transaction pulling money from the bank account
|
||||
// and recording it in the NSF account. It has nothing to do
|
||||
// with the customer statement (charges, payments, credits, etc).
|
||||
$nsf_result = $this->DepositTransaction->addDeposit
|
||||
(array('Transaction' => array(),
|
||||
'Entry' => array(array('tender_id' => null,
|
||||
'account_id' => $this->LedgerEntry->Account->nsfAccountID(),
|
||||
'amount' => -1 * $tender['LedgerEntry']['amount'],
|
||||
))),
|
||||
$tender['DepositTransaction']['account_id']);
|
||||
$this->pr(20, compact('result'));
|
||||
$tender['Transaction'] = $tender['DepositTransaction'];
|
||||
unset($tender['DepositTransaction']);
|
||||
unset($tender['NsfTransaction']);
|
||||
|
||||
if ($nsf_result['error'])
|
||||
die("Unable to save NSF transaction");
|
||||
$T = new Transaction();
|
||||
$result = $T->addNsf($tender, $stamp);
|
||||
if ($result['error'])
|
||||
return $this->prReturn(false);
|
||||
|
||||
// Since we may have saved the nsf transaction with a null
|
||||
// timestamp, query it back out of the database to find out
|
||||
// what timestamp was _really_ specified, for later use.
|
||||
$nsf_deposit = $this->DepositTransaction->find
|
||||
('first', array('contain' => false, 'id' => $nsf_result['transaction_id']));
|
||||
$nsf_deposit = $nsf_deposit['DepositTransaction'];
|
||||
|
||||
// OK, now move into customer realm, finding all statement
|
||||
// entries that were affected by the bad payment (tender).
|
||||
$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']),
|
||||
));
|
||||
|
||||
$this->pr(20, compact('nsf_ledger_entry'));
|
||||
|
||||
// Build a transaction to adjust all of the statement entries
|
||||
$bounce = array('Transaction' => array(), 'Entry' => array());
|
||||
|
||||
$bounce['Transaction']['stamp'] = $nsf_deposit['stamp'];
|
||||
$bounce['Transaction']['account_id'] = $this->LedgerEntry->Account->nsfAccountID();
|
||||
$bounce['Transaction']['customer_id'] = $tender['Tender']['customer_id'];
|
||||
$bounce['Transaction']['amount'] = -1 * $tender['LedgerEntry']['amount'];
|
||||
|
||||
foreach ($nsf_ledger_entry['Transaction']['StatementEntry'] AS $payment) {
|
||||
if ($payment['type'] === 'SURPLUS') {
|
||||
$payment['type'] = 'VOID';
|
||||
$this->NsfTransaction->StatementEntry->id = $payment['id'];
|
||||
$this->NsfTransaction->StatementEntry->saveField('type', $payment['type']);
|
||||
}
|
||||
else {
|
||||
$bounce['Entry'][] =
|
||||
array('type' => $payment['type'],
|
||||
'amount' => -1 * $payment['amount'],
|
||||
'account_id' => $this->LedgerEntry->Account->nsfAccountID(),
|
||||
'customer_id' => $payment['customer_id'],
|
||||
'lease_id' => $payment['lease_id'],
|
||||
'charge_entry_id' => $payment['charge_entry_id'],
|
||||
'effective_date' => $nsf_deposit['stamp'],
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// Record the transaction, which will un-pay previously paid
|
||||
// charges, void any credits, and other similar work.
|
||||
$this->pr(20, compact('bounce'));
|
||||
$bounce_result = $this->NsfTransaction->addNsf($bounce);
|
||||
$this->pr(20, compact('bounce_result'));
|
||||
|
||||
if ($bounce_result['error'])
|
||||
die("Unable to save Bounce transaction");
|
||||
|
||||
|
||||
// Flag the tender as NSF, using the items created above.
|
||||
// Flag the tender as NSF, using the items created from addNsf
|
||||
$this->id = $id;
|
||||
$this->saveField('nsf_transaction_id', $nsf_result['transaction_id']);
|
||||
$this->saveField('nsf_ledger_entry_id', $bounce_result['entries'][0]['DoubleEntry']['Entry1']['ledger_entry_id']);
|
||||
|
||||
|
||||
// Add NSF Charge
|
||||
$result = $this->NsfTransaction->addInvoice
|
||||
(array('Transaction' =>
|
||||
array('stamp' => $nsf_deposit['stamp'],
|
||||
),
|
||||
|
||||
'Entry' =>
|
||||
array
|
||||
(array('account_id' => $this->LedgerEntry->Account->nsfChargeAccountID(),
|
||||
'effective_date' => $nsf_deposit['stamp'],
|
||||
// REVISIT <AP>: 20090730
|
||||
// BAD, BAD, BAD... who would actually
|
||||
// hardcode a value like this???? ;-)
|
||||
'amount' => 35,
|
||||
'comment' => "NSF: " . $tender['Tender']['name'],
|
||||
),
|
||||
),
|
||||
),
|
||||
$tender['Tender']['customer_id']);
|
||||
$this->pr(20, compact('result'));
|
||||
$this->saveField('nsf_transaction_id', $result['nsf_transaction_id']);
|
||||
$this->saveField('nsf_ledger_entry_id', $result['nsf_ledger_entry_id']);
|
||||
|
||||
return $this->prReturn(true);
|
||||
}
|
||||
|
||||
@@ -37,7 +37,7 @@ class Transaction extends AppModel {
|
||||
);
|
||||
|
||||
|
||||
//var $default_log_level = 30;
|
||||
var $default_log_level = 30;
|
||||
|
||||
/**************************************************************************
|
||||
**************************************************************************
|
||||
@@ -63,7 +63,7 @@ class Transaction extends AppModel {
|
||||
$entry['crdr'] = 'CREDIT';
|
||||
}
|
||||
|
||||
$ids = $this->addTransaction($data);
|
||||
$ids = $this->addTransaction($data['Transaction'], $data['Entry']);
|
||||
if (isset($ids['transaction_id']))
|
||||
$ids['invoice_id'] = $ids['transaction_id'];
|
||||
|
||||
@@ -98,7 +98,7 @@ class Transaction extends AppModel {
|
||||
}
|
||||
}
|
||||
|
||||
$ids = $this->addTransaction($data);
|
||||
$ids = $this->addTransaction($data['Transaction'], $data['Entry']);
|
||||
if (isset($ids['transaction_id']))
|
||||
$ids['receipt_id'] = $ids['transaction_id'];
|
||||
|
||||
@@ -141,7 +141,7 @@ class Transaction extends AppModel {
|
||||
}
|
||||
$data['Entry'] = $group;
|
||||
|
||||
$ids = $this->addTransaction($data);
|
||||
$ids = $this->addTransaction($data['Transaction'], $data['Entry']);
|
||||
if (isset($ids['transaction_id']))
|
||||
$ids['deposit_id'] = $ids['transaction_id'];
|
||||
|
||||
@@ -197,7 +197,7 @@ class Transaction extends AppModel {
|
||||
unset($data['Ledger']);
|
||||
|
||||
// Add the transaction and carry forward balances
|
||||
$ids = $this->addTransaction($data);
|
||||
$ids = $this->addTransaction($data['Transaction'], $data['Entry']);
|
||||
if (isset($ids['transaction_id']))
|
||||
$ids['close_id'] = $ids['transaction_id'];
|
||||
|
||||
@@ -221,7 +221,7 @@ class Transaction extends AppModel {
|
||||
* (not in a pre-existing transaction)
|
||||
*/
|
||||
function verifyTransaction($transaction, $entries) {
|
||||
$this->prFunctionLevel(10);
|
||||
//$this->prFunctionLevel(10);
|
||||
$this->prEnter(compact('transaction', 'entries'));
|
||||
|
||||
// Verify required Transaction data is present
|
||||
@@ -237,11 +237,15 @@ class Transaction extends AppModel {
|
||||
|
||||
// Verify all entries
|
||||
foreach ($entries AS $entry) {
|
||||
// Ensure these items are null'ed out so we don't
|
||||
// accidentally pick up stale data.
|
||||
$le1 = $le1_tender = $le2 = $se = null;
|
||||
extract($entry);
|
||||
if (!$this->LedgerEntry->DoubleEntry->verifyDoubleEntry($le1, $le2, $le1_tender)) {
|
||||
if (!empty($le1) && !empty($le2) &&
|
||||
!$this->LedgerEntry->DoubleEntry->verifyDoubleEntry($le1, $le2, $le1_tender)) {
|
||||
return $this->prReturn(false);
|
||||
}
|
||||
if ($transaction['type'] == 'INVOICE' &&
|
||||
if (!empty($se) &&
|
||||
!$this->StatementEntry->verifyStatementEntry($se)) {
|
||||
return $this->prReturn(false);
|
||||
}
|
||||
@@ -309,20 +313,18 @@ class Transaction extends AppModel {
|
||||
*
|
||||
*/
|
||||
|
||||
function addTransaction($data) {
|
||||
$this->prEnter(compact('data'));
|
||||
function addTransaction($transaction, $entries, $subtype = null) {
|
||||
$this->prEnter(compact('transaction', 'entries', 'subtype'));
|
||||
|
||||
// Verify that we have a transaction and entries
|
||||
if (empty($data['Transaction']) ||
|
||||
($data['Transaction']['type'] !== 'CLOSE' && empty($data['Entry'])))
|
||||
if (empty($transaction) ||
|
||||
($transaction['type'] !== 'CLOSE' && empty($entries)))
|
||||
return $this->prReturn(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']);
|
||||
if (empty($transaction['ledger_id']))
|
||||
$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'])) {
|
||||
@@ -336,15 +338,14 @@ class Transaction extends AppModel {
|
||||
// and into individual entries appropriate for saving. While
|
||||
// we're at it, calculate the transaction total as well.
|
||||
$transaction['amount'] = 0;
|
||||
foreach ($data['Entry'] AS &$entry) {
|
||||
foreach ($entries AS &$entry) {
|
||||
// Ensure these items are null'ed out so we don't
|
||||
// accidentally pick up stale data.
|
||||
$le1 = $le1_tender = $le2 = $se = null;
|
||||
|
||||
// Add entry amount into the transaction total
|
||||
$transaction['amount'] += $entry['amount'];
|
||||
|
||||
$entry['customer_id'] = $transaction['customer_id'];
|
||||
$entry['lease_id'] = $transaction['lease_id'];
|
||||
$entry['ledger_id'] =
|
||||
$this->Account->currentLedgerID($entry['account_id']);
|
||||
|
||||
// Set up our comments, possibly using the default 'comment' field
|
||||
if (empty($entry['ledger_entry_comment'])) {
|
||||
if ($transaction['type'] != 'INVOICE' && !empty($entry['comment']))
|
||||
@@ -377,173 +378,60 @@ class Transaction extends AppModel {
|
||||
}
|
||||
else {
|
||||
$le2 =
|
||||
array_intersect_key($transaction,
|
||||
array_flip(array('ledger_id', 'account_id', 'crdr'))) +
|
||||
array_intersect_key($entry,
|
||||
array_flip(array('amount')));
|
||||
}
|
||||
|
||||
if ($transaction['type'] == 'INVOICE') {
|
||||
// Create a statement entry
|
||||
// (PAYMENTS will have statement entries created below, when
|
||||
// assigning credits, and DEPOSITS don't have statement entries)
|
||||
$se =
|
||||
array_flip(array('amount'))) +
|
||||
array_intersect_key($transaction,
|
||||
array_flip(array('customer_id', 'lease_id'))) +
|
||||
array_intersect_key($entry,
|
||||
array_flip(array('type', 'account_id', 'amount',
|
||||
'effective_date', 'through_date', 'due_date')));
|
||||
$se['comment'] = $entry['statement_entry_comment'];
|
||||
array_flip(array('ledger_id', 'account_id', 'crdr')));
|
||||
}
|
||||
|
||||
// Replace combined entry with our new individual entries
|
||||
$entry = compact('le1', 'le1_tender', 'le2', 'se');
|
||||
}
|
||||
|
||||
// Move forward, verifying and saving everything.
|
||||
$ret = array();
|
||||
if (!$this->verifyTransaction($transaction, $data['Entry']))
|
||||
return $this->prReturn(array('error' => true) + $ret);
|
||||
|
||||
$this->pr(20, compact('transaction', 'data'),
|
||||
'Pre Transaction Save');
|
||||
|
||||
// Save transaction to the database
|
||||
$this->create();
|
||||
if (!$this->save($transaction))
|
||||
return $this->prReturn(array('error' => true) + $ret);
|
||||
|
||||
// Set up our return ids array
|
||||
$ret['transaction_id'] = $this->id;
|
||||
$ret['entries'] = array();
|
||||
$ret['error'] = false;
|
||||
|
||||
// Go through the entered charges
|
||||
foreach ($data['Entry'] AS $e_index => &$entry) {
|
||||
extract($entry);
|
||||
$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 (isset($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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
return $this->prReturn($ret);
|
||||
}
|
||||
|
||||
|
||||
/**************************************************************************
|
||||
**************************************************************************
|
||||
**************************************************************************
|
||||
* function: addNsf
|
||||
* - Adds NSF transaction
|
||||
*/
|
||||
|
||||
function addNsf($data) {
|
||||
$this->prEnter(compact('data'));
|
||||
|
||||
// Verify that we have a transaction and entries
|
||||
if (empty($data['Transaction']) || empty($data['Entry']))
|
||||
return $this->prReturn(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
|
||||
// Create the statement entry
|
||||
$se =
|
||||
array_intersect_key($entry,
|
||||
array_flip(array('type', 'account_id', 'amount',
|
||||
'effective_date', 'through_date', 'due_date',
|
||||
'customer_id', 'lease_id',
|
||||
'charge_entry_id')));
|
||||
'charge_entry_id'))) +
|
||||
array_intersect_key($transaction,
|
||||
array_flip(array('customer_id', 'lease_id')));
|
||||
$se['comment'] = $entry['statement_entry_comment'];
|
||||
|
||||
$se['ledger_id'] =
|
||||
$this->Account->currentLedgerID($se['account_id']);
|
||||
// (PAYMENTS will have statement entries created below, when
|
||||
// assigning credits, and DEPOSITS don't have statement entries)
|
||||
if ($transaction['type'] != 'INVOICE' && $subtype !== 'NSF')
|
||||
$se = null;
|
||||
|
||||
// NSF transactions don't use LedgerEntries
|
||||
// REVISIT <AP>: 20090731
|
||||
// Doesn't seem right... probably doing this because of the
|
||||
// single A/R entry we add below for NSF
|
||||
if ($subtype === 'NSF')
|
||||
$le1 = $le1_tender = $le2 = null;
|
||||
|
||||
// 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'])
|
||||
));
|
||||
if ($subtype === 'NSF') {
|
||||
// REVISIT <AP>: 20090731
|
||||
// Should we be doing this, or just doing individual ledger entries
|
||||
// that were created above before we nulled them out
|
||||
array_unshift($entries,
|
||||
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'])
|
||||
));
|
||||
}
|
||||
|
||||
$this->pr(20, compact('transaction', 'entries'));
|
||||
|
||||
// Move forward, verifying and saving everything.
|
||||
// REVISIT <AP>: 20090731 NSF was not verifying... let's find out why
|
||||
$ret = array();
|
||||
/* if (!$this->verifyTransaction($transaction, $data['Entry'])) */
|
||||
/* return array('error' => true) + $ret; */
|
||||
|
||||
$this->pr(20, compact('transaction'),
|
||||
'Pre Transaction Save');
|
||||
if (!$this->verifyTransaction($transaction, $entries))
|
||||
return $this->prReturn(array('error' => true) + $ret);
|
||||
|
||||
// Save transaction to the database
|
||||
$this->create();
|
||||
@@ -556,11 +444,10 @@ class Transaction extends AppModel {
|
||||
$ret['error'] = false;
|
||||
|
||||
// Go through the entries
|
||||
foreach ($data['Entry'] AS $e_index => &$entry) {
|
||||
$le1 = null;
|
||||
$le1_tender = null;
|
||||
$le2 = null;
|
||||
$se = null;
|
||||
foreach ($entries AS $e_index => &$entry) {
|
||||
// Ensure these items are null'ed out so we don't
|
||||
// accidentally pick up stale data.
|
||||
$le1 = $le1_tender = $le2 = $se = null;
|
||||
extract($entry);
|
||||
|
||||
if (!empty($le1) && !empty($le2)) {
|
||||
@@ -586,14 +473,146 @@ class Transaction extends AppModel {
|
||||
}
|
||||
}
|
||||
|
||||
// assigning credits could happen now, but the caller
|
||||
// will be adding an NSF fee, and credit assignment will
|
||||
// just happen again anyway. Return without assignment.
|
||||
if (($transaction['type'] == 'INVOICE' ||
|
||||
$transaction['type'] == 'RECEIPT') &&
|
||||
$subtype !== 'NSF' && !$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;
|
||||
}
|
||||
|
||||
return $this->prReturn($ret);
|
||||
}
|
||||
|
||||
|
||||
/**************************************************************************
|
||||
**************************************************************************
|
||||
**************************************************************************
|
||||
* function: addNsf
|
||||
* - Adds NSF transaction
|
||||
*/
|
||||
|
||||
function addNsf($tender, $stamp) {
|
||||
$this->prEnter(compact('tender', 'stamp'));
|
||||
|
||||
$ret = array();
|
||||
|
||||
// Enter the NSF
|
||||
// This is the transaction pulling money from the bank account
|
||||
// and recording it in the NSF account. It has nothing to do
|
||||
// with the customer statement (charges, payments, credits, etc).
|
||||
$bounce_result = $this->addDeposit
|
||||
(array('Transaction' => array(),
|
||||
'Entry' => array(array('tender_id' => null,
|
||||
'account_id' => $this->Account->nsfAccountID(),
|
||||
'amount' => -1 * $tender['LedgerEntry']['amount'],
|
||||
))),
|
||||
$tender['Transaction']['account_id']);
|
||||
|
||||
$this->pr(20, compact('bounce_result'));
|
||||
$ret['bounce'] = $bounce_result;
|
||||
if ($bounce_result['error'])
|
||||
return $this->prReturn(array('error' => true) + $ret);
|
||||
|
||||
// Since we may have saved the nsf transaction with a null
|
||||
// timestamp, query it back out of the database to find out
|
||||
// what timestamp was _really_ specified, for later use.
|
||||
$bounce = $this->find
|
||||
('first', array('contain' => false, 'id' => $bounce_result['transaction_id']));
|
||||
$this->pr(20, compact('bounce'));
|
||||
$stamp = $bounce['Transaction']['stamp'];
|
||||
|
||||
// OK, now move into customer realm, finding all statement
|
||||
// entries that were affected by the bad payment (tender).
|
||||
$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']),
|
||||
));
|
||||
|
||||
$this->pr(20, compact('nsf_ledger_entry'));
|
||||
if (!$nsf_ledger_entry)
|
||||
return $this->prReturn(array('error' => true) + $ret);
|
||||
|
||||
// Build a transaction to adjust all of the statement entries
|
||||
$rollback = array('Transaction' => array(), 'Entry' => array());
|
||||
|
||||
$rollback['Transaction']['stamp'] = $stamp;
|
||||
$rollback['Transaction']['type'] = 'RECEIPT';
|
||||
$rollback['Transaction']['crdr'] = 'DEBIT'; // Unused... keeps verifyTx happy
|
||||
$rollback['Transaction']['account_id'] = $this->Account->nsfAccountID();
|
||||
$rollback['Transaction']['customer_id'] = $tender['Tender']['customer_id'];
|
||||
$rollback['Transaction']['amount'] = -1 * $tender['LedgerEntry']['amount'];
|
||||
|
||||
foreach ($nsf_ledger_entry['Transaction']['StatementEntry'] AS $payment) {
|
||||
if ($payment['type'] === 'SURPLUS') {
|
||||
$payment['type'] = 'VOID';
|
||||
$this->StatementEntry->id = $payment['id'];
|
||||
$this->StatementEntry->saveField('type', $payment['type']);
|
||||
}
|
||||
else {
|
||||
$rollback['Entry'][] =
|
||||
array('type' => $payment['type'],
|
||||
'amount' => -1 * $payment['amount'],
|
||||
'account_id' => $this->Account->nsfAccountID(),
|
||||
'customer_id' => $payment['customer_id'],
|
||||
'lease_id' => $payment['lease_id'],
|
||||
'charge_entry_id' => $payment['charge_entry_id'],
|
||||
'effective_date' => $stamp,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// Record the transaction, which will un-pay previously paid
|
||||
// charges, void any credits, and other similar work.
|
||||
$rollback_result = $this->addTransaction($rollback['Transaction'], $rollback['Entry'], 'NSF');
|
||||
$this->pr(20, compact('rollback', 'rollback_result'));
|
||||
$ret['rollback'] = $rollback_result;
|
||||
if ($rollback_result['error'])
|
||||
return $this->prReturn(array('error' => true) + $ret);
|
||||
|
||||
// Add NSF Charge
|
||||
$charge_result = $this->addInvoice
|
||||
(array('Transaction' => compact('stamp'),
|
||||
|
||||
'Entry' =>
|
||||
array
|
||||
(array('account_id' => $this->Account->nsfChargeAccountID(),
|
||||
'effective_date' => $stamp,
|
||||
// REVISIT <AP>: 20090730
|
||||
// BAD, BAD, BAD... who would actually
|
||||
// hardcode a value like this???? ;-)
|
||||
'amount' => 35,
|
||||
'comment' => "NSF: " . $tender['Tender']['name'],
|
||||
),
|
||||
),
|
||||
),
|
||||
$tender['Tender']['customer_id']);
|
||||
|
||||
$this->pr(20, compact('charge_result'));
|
||||
$ret['charge'] = $charge_result;
|
||||
if ($charge_result['error'])
|
||||
return $this->prReturn(array('error' => true) + $ret);
|
||||
|
||||
$ret['nsf_transaction_id'] = $ret['bounce']['transaction_id'];
|
||||
$ret['nsf_ledger_entry_id'] = $ret['rollback']['entries'][0]['DoubleEntry']['Entry1']['ledger_entry_id'];
|
||||
return $this->prReturn($ret + array('error' => false));
|
||||
}
|
||||
|
||||
|
||||
/**************************************************************************
|
||||
**************************************************************************
|
||||
**************************************************************************
|
||||
|
||||
Reference in New Issue
Block a user