Further tweaked the code to add new transactions, primarily by creating separate verification and addition functions in each underlying model. There are logic changes as well, such as adding in the other half of the missing double entry (as well as the double entry itself). This checkin also introduces the creation of CREDIT statement entries, when the customer has overpayed. It's working fairly well, although undoubtedly will need more tweaking.

git-svn-id: file:///svn-source/pmgr/branches/yafr_20090716@394 97e9348a-65ac-dc4b-aefc-98561f571b83
This commit is contained in:
abijah
2009-07-28 01:16:42 +00:00
parent ba62eed027
commit b3389652fd
6 changed files with 447 additions and 374 deletions

View File

@@ -56,6 +56,58 @@ class StatementEntry extends AppModel {
}
/**************************************************************************
**************************************************************************
**************************************************************************
* function: verifyStatementEntry
* - Verifies consistenty of new statement entry data
* (not in a pre-existing statement entry)
*/
function verifyStatementEntry($entry) {
pr(array("StatementEntry::verifyStatementEntry()"
=> compact('entry')));
if (empty($entry['type']) ||
//empty($entry['effective_date']) ||
empty($entry['account_id']) ||
empty($entry['amount'])
) {
pr(array("StatementEntry::verifyStatementEntry()"
=> "Entry verification failed"));
return false;
}
return true;
}
/**************************************************************************
**************************************************************************
**************************************************************************
* function: addStatementEntry
* - Inserts new Statement Entry into the database
*/
function addStatementEntry($entry) {
pr(array('StatementEntry::addStatementEntry' =>
compact('entry')));
$ret = array();
if (!$this->verifyStatementEntry($entry))
return array('error' => true, 'verify_data' => $entry) + $ret;
pr(array('StatementEntry::addStatementEntry' =>
array('checkpoint' => 'Pre-Save')
+ compact('entry')));
$this->create();
if (!$this->save($entry))
return array('error' => true, 'save_data' => $entry) + $ret;
$ret['statement_entry_id'] = $this->id;
return $ret + array('error' => false);
}
/**************************************************************************
**************************************************************************
**************************************************************************
@@ -354,12 +406,15 @@ OPTION 2
* - Assigns all credits to existing charges
*/
function assignCredits($query = null, $receipt_id = null) {
pr(array('StatementEntry::assignCredits' => compact('query')));
pr(array('StatementEntry::assignCredits' => compact('query', 'receipt_id')));
$this->queryInit($query);
$ret = array();
// First, find all known credits
$lquery = $query;
$lquery['conditions'][] = array('StatementEntry.type' => 'CREDIT');
$lquery['order'][] = 'StatementEntry.effective_date ASC';
$credits = $this->find('all', $lquery);
pr(compact('lquery', 'credits'));
@@ -377,8 +432,7 @@ OPTION 2
$lquery['link'] = array('StatementEntry' => array('fields' => array()) + $lquery['link']);
$lquery['conditions'][] = array('Transaction.type' => 'RECEIPT');
$lquery['fields'] = array('Transaction.id', 'Transaction.stamp', 'Transaction.amount',
//'SUM(StatementEntry.amount) AS applied_amount',
'Transaction.amount - SUM(StatementEntry.amount) AS balance');
'Transaction.amount - SUM(COALESCE(StatementEntry.amount,0)) AS balance');
$lquery['group'] = 'Transaction.id HAVING balance > 0';
$anon_credits = $this->Transaction->find('all', $lquery);
foreach ($anon_credits AS &$ac) {
@@ -387,6 +441,20 @@ OPTION 2
}
pr(compact('lquery', 'anon_credits'));
// Next, add in the credits from the newly added receipt
if (!empty($receipt_id)) {
$lquery = $query;
$lquery['conditions'][] = array('Transaction.type' => 'RECEIPT');
$lquery['conditions'][] = array('Transaction.id' => $receipt_id);
$lquery['fields'] = array('Transaction.id', 'Transaction.stamp', 'Transaction.amount',
'Transaction.amount AS balance');
$receipt_credit = $this->Transaction->find('first', $lquery);
if ($receipt_credit)
$anon_credits[] = $receipt_credit;
pr(compact('lquery', 'anon_credits'));
}
// REVISIT <AP>: 20090726
// This algorithm shouldn't be hardcoded. We need to allow
// the user to specify how payments should be applied.
@@ -495,10 +563,10 @@ OPTION 2
array('checkpoint' => 'New Payment Entry')
+ compact('payment')));
$SE = new StatementEntry();
$SE->create();
if (!$SE->save($payment))
die("UNABLE TO SAVE NEW PAYMENT ENTRY");
$result = $this->addStatementEntry($payment);
$ret['Payment'][] = $result;
if ($result['error'])
$ret['error'] = true;
// Adjust the charge balance to reflect the new payment
$charge['balance'] -= $payment_amount;
@@ -512,17 +580,15 @@ OPTION 2
}
// Make partially used credits are added to the used list
// Partially used credits must be added to the used list
if (isset($credits[0]['applied']))
$used_credits[] = array_shift($credits);
if (isset($anon_credits[0]['applied']))
$used_anon_credits[] = array_shift($anon_credits);
pr(array('StatementEntry::assignCredits' =>
array('checkpoint' => 'Payments added')
+ compact('credits', 'used_credits', 'anon_credits', 'used_anon_credits')));
// Finally, clean up any credits that have been used
// Clean up any explicit credits that have been used
foreach ($used_credits AS $credit) {
if ($credit['balance'] > 0) {
pr(array('StatementEntry::assignCredits' =>
@@ -541,6 +607,29 @@ OPTION 2
}
}
// Convert non-exhausted implicit credits to explicit ones
foreach ($anon_credits AS $credit) {
if ($credit['balance'] <= 0)
die("HOW DID EXHAUSTED ANON CREDITS GET LEFT?");
pr(array('StatementEntry::assignCredits' =>
array('checkpoint' => 'Create Explicit Credit')
+ compact('credit')));
$result = $this->addStatementEntry
(array('type' => 'CREDIT',
'account_id' => $this->Account->accountReceivableAccountID(),
'amount' => $credit['balance'],
'effective_date' => $credit['Transaction']['stamp'],
'transaction_id' => $credit['Transaction']['id'],
'customer_id' => $credit['Customer']['id'],
));
$ret['Credit'][] = $result;
if ($result['error'])
$ret['error'] = true;
}
return $ret + array('error' => false);
}
@@ -565,16 +654,21 @@ OPTION 2
$rquery['link']['PaymentEntry'] = array('fields' => array());
$rquery['fields'] = array();
$rquery['fields'][] = "SUM(StatementEntry.amount) AS total";
$rquery['fields'][] = "StatementEntry.amount";
$rquery['fields'][] = "SUM(PaymentEntry.amount) AS reconciled";
$rquery['fields'][] = "SUM(StatementEntry.amount - COALESCE(PaymentEntry.amount,0)) AS balance";
$rquery['conditions'][] = array('StatementEntry.type' => 'CHARGE');
$result = $this->find('first', $rquery);
if (!isset($result[0]['balance']))
$result[0]['balance'] = 0;
$stats['Charge'] = $result[0];
$rquery['group'] = 'StatementEntry.id';
$result = $this->find('all', $rquery);
$stats['Charge'] = array('total' => 0, 'reconciled' => 0);
foreach($result AS $charge) {
$stats['Charge']['total'] += $charge['StatementEntry']['amount'];
$stats['Charge']['reconciled'] += $charge[0]['reconciled'];
}
$stats['Charge']['balance'] =
$stats['Charge']['total'] - $stats['Charge']['reconciled'];
/* pr(array('StatementEntry::stats' => */
/* array('checkpoint' => 'Charges') */
/* + compact('query', 'result'))); */