More tweaks to the addTransaction algorithm, working on a solid plan for customer surplus
git-svn-id: file:///svn-source/pmgr/branches/surplus_account_20090815@574 97e9348a-65ac-dc4b-aefc-98561f571b83
This commit is contained in:
@@ -258,7 +258,7 @@ class StatementEntry extends AppModel {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function reconciledSet($set, $query = null, $unrec = false, $if_rec_include_partial = false) {
|
function reconciledSet($set, $query = null, $unrec = false, $if_rec_include_partial = false) {
|
||||||
//$this->prFunctionLevel(array('log' => 16, 'show' => 10));
|
$this->prFunctionLevel(array('log' => 16, 'show' => 10));
|
||||||
$this->prEnter(compact('set', 'query', 'unrec', 'if_rec_include_partial'));
|
$this->prEnter(compact('set', 'query', 'unrec', 'if_rec_include_partial'));
|
||||||
$lquery = $this->reconciledSetQuery($set, $query);
|
$lquery = $this->reconciledSetQuery($set, $query);
|
||||||
$result = $this->find('all', $lquery);
|
$result = $this->find('all', $lquery);
|
||||||
@@ -395,7 +395,7 @@ class StatementEntry extends AppModel {
|
|||||||
"Credits Established");
|
"Credits Established");
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// Next, establish credit from the newly added receipt
|
// Establish credit from the (newly added) receipt
|
||||||
$lquery =
|
$lquery =
|
||||||
array('link' =>
|
array('link' =>
|
||||||
array('StatementEntry',
|
array('StatementEntry',
|
||||||
@@ -455,21 +455,8 @@ class StatementEntry extends AppModel {
|
|||||||
if ($charge['balance'] < 0)
|
if ($charge['balance'] < 0)
|
||||||
$this->INTERNAL_ERROR("Negative Charge Balance");
|
$this->INTERNAL_ERROR("Negative Charge Balance");
|
||||||
|
|
||||||
if (empty($credit['receipt'])) {
|
if (!isset($credit['balance']))
|
||||||
// Explicit Credit
|
$credit['balance'] = $credit['StatementEntry']['amount'];
|
||||||
$disbursement_date = $credit['StatementEntry']['effective_date'];
|
|
||||||
$disbursement_transaction_id = $credit['StatementEntry']['transaction_id'];
|
|
||||||
$disbursement_account_id = $credit['StatementEntry']['account_id'];
|
|
||||||
|
|
||||||
if (!isset($credit['balance']))
|
|
||||||
$credit['balance'] = $credit['StatementEntry']['amount'];
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
// Receipt Credit
|
|
||||||
$disbursement_date = $credit['Transaction']['stamp'];
|
|
||||||
$disbursement_transaction_id = $credit['Transaction']['id'];
|
|
||||||
$disbursement_account_id = $credit['LedgerEntry']['account_id'];
|
|
||||||
}
|
|
||||||
|
|
||||||
if (empty($credit['balance']))
|
if (empty($credit['balance']))
|
||||||
continue;
|
continue;
|
||||||
@@ -479,6 +466,11 @@ class StatementEntry extends AppModel {
|
|||||||
$this->pr(20, compact('charge'),
|
$this->pr(20, compact('charge'),
|
||||||
'Attempt Charge Reconciliation');
|
'Attempt Charge Reconciliation');
|
||||||
|
|
||||||
|
if (empty($credit['receipt']))
|
||||||
|
$disbursement_account_id = $credit['StatementEntry']['account_id'];
|
||||||
|
else
|
||||||
|
$disbursement_account_id = $credit['LedgerEntry']['account_id'];
|
||||||
|
|
||||||
// REVISIT <AP>: 20090811
|
// REVISIT <AP>: 20090811
|
||||||
// Need to come up with a better strategy for handling
|
// Need to come up with a better strategy for handling
|
||||||
// concessions. For now, just restricting concessions
|
// concessions. For now, just restricting concessions
|
||||||
@@ -501,25 +493,71 @@ class StatementEntry extends AppModel {
|
|||||||
($credit['balance'] > 0 ? 'Utilized' : 'Exhausted') .
|
($credit['balance'] > 0 ? 'Utilized' : 'Exhausted') .
|
||||||
(empty($credit['receipt']) ? ' Credit' : ' Receipt'));
|
(empty($credit['receipt']) ? ' Credit' : ' Receipt'));
|
||||||
|
|
||||||
// Add a disbursement that uses the available credit to pay the charge
|
if (empty($credit['receipt'])) {
|
||||||
$disbursement = array('type' => $disbursement_type,
|
// Explicit Credit
|
||||||
'account_id' => $disbursement_account_id,
|
$result = $this->Transaction->addTransactionEntries
|
||||||
'amount' => $disbursement_amount,
|
(array('include_ledger_entry' => true,
|
||||||
'effective_date' => $disbursement_date,
|
'include_statement_entry' => true),
|
||||||
'transaction_id' => $disbursement_transaction_id,
|
array('type' => 'INVOICE',
|
||||||
'customer_id' => $charge['StatementEntry']['customer_id'],
|
'id' => $credit['StatementEntry']['transaction_id'],
|
||||||
'lease_id' => $charge['StatementEntry']['lease_id'],
|
'account_id' => $this->Account->accountReceivableAccountID(),
|
||||||
'charge_entry_id' => $charge['StatementEntry']['id'],
|
'crdr' => 'CREDIT',
|
||||||
'comment' => null,
|
'customer_id' => $charge['StatementEntry']['customer_id'],
|
||||||
);
|
'lease_id' => $charge['StatementEntry']['lease_id'],
|
||||||
|
),
|
||||||
|
array
|
||||||
|
(array('type' => $disbursement_type,
|
||||||
|
//$credit['StatementEntry']['effective_date'];
|
||||||
|
'effective_date' => $credit['StatementEntry']['effective_date'],
|
||||||
|
'account_id' => $credit['StatementEntry']['account_id'],
|
||||||
|
'amount' => $disbursement_amount,
|
||||||
|
/* 'customer_id' => $charge['StatementEntry']['customer_id'], */
|
||||||
|
/* 'lease_id' => $charge['StatementEntry']['lease_id'], */
|
||||||
|
'charge_entry_id' => $charge['StatementEntry']['id'],
|
||||||
|
),
|
||||||
|
));
|
||||||
|
/* $result = $this->Transaction->addReceipt */
|
||||||
|
/* (array('control' => */
|
||||||
|
/* array('include_ledger_entry' => true, */
|
||||||
|
/* 'include_statement_entry' => false), */
|
||||||
|
|
||||||
$this->pr(20, compact('disbursement'),
|
/* 'Transaction' => */
|
||||||
'New Disbursement Entry');
|
/* array('id' => $credit['StatementEntry']['transaction_id'], */
|
||||||
|
/* 'account_id' => $credit['StatementEntry']['account_id'], */
|
||||||
|
/* 'crdr' => 'DEBIT'), */
|
||||||
|
/* array(array('type' => $disbursement_type, */
|
||||||
|
/* //$credit['StatementEntry']['effective_date']; */
|
||||||
|
/* 'effective_date' => $charge['StatementEntry']['effective_date'], */
|
||||||
|
/* 'account_id' => $charge['StatementEntry']['account_id'], */
|
||||||
|
/* 'amount' => $disbursement_amount, */
|
||||||
|
/* ), */
|
||||||
|
/* )); */
|
||||||
|
|
||||||
$result = $this->addStatementEntry($disbursement);
|
$ret['Disbursement'][] = $result;
|
||||||
$ret['Disbursement'][] = $result;
|
if ($result['error'])
|
||||||
if ($result['error'])
|
$ret['error'] = true;
|
||||||
$ret['error'] = true;
|
}
|
||||||
|
else {
|
||||||
|
// Receipt Credit
|
||||||
|
// Add a disbursement that uses the available credit to pay the charge
|
||||||
|
$disbursement =
|
||||||
|
array('type' => $disbursement_type,
|
||||||
|
'amount' => $disbursement_amount,
|
||||||
|
'account_id' => $credit['LedgerEntry']['account_id'],
|
||||||
|
'effective_date' => $credit['Transaction']['stamp'],
|
||||||
|
'transaction_id' => $credit['Transaction']['id'],
|
||||||
|
'customer_id' => $charge['StatementEntry']['customer_id'],
|
||||||
|
'lease_id' => $charge['StatementEntry']['lease_id'],
|
||||||
|
'charge_entry_id' => $charge['StatementEntry']['id'],
|
||||||
|
'comment' => null,
|
||||||
|
);
|
||||||
|
|
||||||
|
$this->pr(20, compact('disbursement'), 'New Disbursement Entry');
|
||||||
|
$result = $this->addStatementEntry($disbursement);
|
||||||
|
$ret['Disbursement'][] = $result;
|
||||||
|
if ($result['error'])
|
||||||
|
$ret['error'] = true;
|
||||||
|
}
|
||||||
|
|
||||||
// Adjust the charge balance to reflect the new disbursement
|
// Adjust the charge balance to reflect the new disbursement
|
||||||
$charge['balance'] -= $disbursement_amount;
|
$charge['balance'] -= $disbursement_amount;
|
||||||
@@ -594,7 +632,7 @@ class StatementEntry extends AppModel {
|
|||||||
* - Returns summary data from the requested statement entry
|
* - Returns summary data from the requested statement entry
|
||||||
*/
|
*/
|
||||||
function stats($id = null, $query = null) {
|
function stats($id = null, $query = null) {
|
||||||
//$this->prFunctionLevel(array('log' => 19, 'show' => 10));
|
$this->prFunctionLevel(array('log' => 16, 'show' => 10));
|
||||||
$this->prEnter(compact('id', 'query'));
|
$this->prEnter(compact('id', 'query'));
|
||||||
|
|
||||||
$this->queryInit($query);
|
$this->queryInit($query);
|
||||||
|
|||||||
@@ -454,33 +454,14 @@ class Transaction extends AppModel {
|
|||||||
function addTransaction($control, $transaction, $entries) {
|
function addTransaction($control, $transaction, $entries) {
|
||||||
$this->prEnter(compact('control', 'transaction', 'entries'));
|
$this->prEnter(compact('control', 'transaction', 'entries'));
|
||||||
|
|
||||||
// Verify that we have a transaction and entries
|
|
||||||
if (empty($transaction) ||
|
|
||||||
($transaction['type'] !== 'CLOSE' && empty($entries)))
|
|
||||||
return $this->prReturn(array('error' => true));
|
|
||||||
|
|
||||||
// set ledger ID as the current ledger of the specified account
|
|
||||||
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'])) {
|
|
||||||
$L = new Lease();
|
|
||||||
$L->id = $transaction['lease_id'];
|
|
||||||
$transaction['customer_id'] = $L->field('customer_id');
|
|
||||||
}
|
|
||||||
|
|
||||||
$result = $this->_splitEntries($control, $transaction, $entries);
|
$result = $this->_splitEntries($control, $transaction, $entries);
|
||||||
if (!empty($result['error']))
|
if (!empty($result['error']))
|
||||||
return $this->prReturn(array('error' => true));
|
return $this->prReturn(array('error' => true));
|
||||||
|
|
||||||
// Extract each item from result and make local variables
|
// Make use of the work done by splitEntries
|
||||||
extract($result);
|
$transaction = array_filter($transaction) + $result['transaction'];
|
||||||
|
$entries = $result['entries'];
|
||||||
// If transaction amount is not already set, use the
|
extract($result['vars']);
|
||||||
// sum of the entry amounts.
|
|
||||||
$transaction += array('amount' => $transaction_amount);
|
|
||||||
|
|
||||||
$this->pr(20, compact('transaction', 'entries'));
|
$this->pr(20, compact('transaction', 'entries'));
|
||||||
|
|
||||||
@@ -525,6 +506,34 @@ class Transaction extends AppModel {
|
|||||||
'amount' => $result['receipt_balance'],
|
'amount' => $result['receipt_balance'],
|
||||||
),
|
),
|
||||||
));
|
));
|
||||||
|
|
||||||
|
/* $result = $this->addInvoice */
|
||||||
|
/* (array('control' => array('assign' => false), */
|
||||||
|
/* 'Transaction' => */
|
||||||
|
/* array_intersect_key($transaction, array('stamp'=>1)) */
|
||||||
|
/* + array('type' => 'CREDIT_NOTE'), */
|
||||||
|
/* 'Entry' => array */
|
||||||
|
/* (array('type' => 'SURPLUS', */
|
||||||
|
/* 'account_id' => $this->Account->accountPayableAccountID(), */
|
||||||
|
/* 'amount' => $result['receipt_balance'], */
|
||||||
|
/* ), */
|
||||||
|
/* ), */
|
||||||
|
/* ), */
|
||||||
|
/* $transaction['customer_id'], */
|
||||||
|
/* $transaction['lease_id'] */
|
||||||
|
/* ); */
|
||||||
|
|
||||||
|
/* $result2 = $this->StatementEntry->assignCredits */
|
||||||
|
/* (null, */
|
||||||
|
/* $ret['transaction_id'], */
|
||||||
|
/* null, */
|
||||||
|
/* null, */
|
||||||
|
/* $transaction['customer_id'], */
|
||||||
|
/* $transaction['lease_id'] */
|
||||||
|
/* ); */
|
||||||
|
|
||||||
|
/* if (!empty($result2['receipt_balance'])) */
|
||||||
|
/* $this->INTERNAL_ERROR('Surplus invoice did not resolve receipt balance'); */
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -549,9 +558,8 @@ class Transaction extends AppModel {
|
|||||||
function addTransactionEntries($control, $transaction, $entries, $split = true) {
|
function addTransactionEntries($control, $transaction, $entries, $split = true) {
|
||||||
$this->prEnter(compact('control', 'transaction', 'entries', 'split'));
|
$this->prEnter(compact('control', 'transaction', 'entries', 'split'));
|
||||||
|
|
||||||
// Verify that we have a transaction and entries
|
// Verify that we have a transaction
|
||||||
if (empty($transaction['id']) ||
|
if (empty($transaction['id']))
|
||||||
($transaction['type'] !== 'CLOSE' && empty($entries)))
|
|
||||||
return $this->prReturn(array('error' => true));
|
return $this->prReturn(array('error' => true));
|
||||||
|
|
||||||
// If the entries are not already split, do so now.
|
// If the entries are not already split, do so now.
|
||||||
@@ -559,13 +567,17 @@ class Transaction extends AppModel {
|
|||||||
$result = $this->_splitEntries($control, $transaction, $entries);
|
$result = $this->_splitEntries($control, $transaction, $entries);
|
||||||
if (!empty($result['error']))
|
if (!empty($result['error']))
|
||||||
return $this->prReturn(array('error' => true));
|
return $this->prReturn(array('error' => true));
|
||||||
$entries = $result['entries'];
|
|
||||||
}
|
|
||||||
|
|
||||||
/* // Verify the entries */
|
// Make use of the work done by splitEntries
|
||||||
/* $ret = array(); */
|
$transaction = array_filter($transaction) + $result['transaction'];
|
||||||
/* if (!$this->verifyTransaction($transaction, $entries)) */
|
$entries = $result['entries'];
|
||||||
/* return $this->prReturn(array('error' => true) + $ret); */
|
extract($result['vars']);
|
||||||
|
|
||||||
|
/* // Verify the entries */
|
||||||
|
/* $ret = array(); */
|
||||||
|
/* if (!$this->verifyTransaction($transaction, $entries)) */
|
||||||
|
/* return $this->prReturn(array('error' => true) + $ret); */
|
||||||
|
}
|
||||||
|
|
||||||
$this->id = $transaction['id'];
|
$this->id = $transaction['id'];
|
||||||
$transaction['stamp'] = $this->field('stamp');
|
$transaction['stamp'] = $this->field('stamp');
|
||||||
@@ -632,6 +644,28 @@ class Transaction extends AppModel {
|
|||||||
($transaction['type'] !== 'CLOSE' && empty($entries)))
|
($transaction['type'] !== 'CLOSE' && empty($entries)))
|
||||||
return $this->prReturn(array('error' => true));
|
return $this->prReturn(array('error' => true));
|
||||||
|
|
||||||
|
// set ledger ID as the current ledger of the specified account
|
||||||
|
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'])) {
|
||||||
|
$L = new Lease();
|
||||||
|
$L->id = $transaction['lease_id'];
|
||||||
|
$transaction['customer_id'] = $L->field('customer_id');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!empty($transaction['account_id'])) {
|
||||||
|
if (empty($transaction['ledger_id']))
|
||||||
|
$transaction['ledger_id'] =
|
||||||
|
$this->Account->currentLedgerID($transaction['account_id']);
|
||||||
|
|
||||||
|
if (empty($transaction['crdr']))
|
||||||
|
$transaction['crdr'] = strtoupper($this->Account->fundamentalType
|
||||||
|
($transaction['account_id']));
|
||||||
|
}
|
||||||
|
|
||||||
// Some transactions do not have their statement entries
|
// Some transactions do not have their statement entries
|
||||||
// generated directly as part of the transaction, but are
|
// generated directly as part of the transaction, but are
|
||||||
// created in the final steps during the reconciliation
|
// created in the final steps during the reconciliation
|
||||||
@@ -643,7 +677,7 @@ class Transaction extends AppModel {
|
|||||||
// Break each entry out of the combined statement/ledger entry
|
// Break each entry out of the combined statement/ledger entry
|
||||||
// and into individual entries appropriate for saving. While
|
// and into individual entries appropriate for saving. While
|
||||||
// we're at it, calculate the transaction total as well.
|
// we're at it, calculate the transaction total as well.
|
||||||
$transaction_amount = 0;
|
$transaction['amount'] = 0;
|
||||||
foreach ($entries AS &$entry) {
|
foreach ($entries AS &$entry) {
|
||||||
// Ensure these items are null'ed out so we don't
|
// Ensure these items are null'ed out so we don't
|
||||||
// accidentally pick up stale data.
|
// accidentally pick up stale data.
|
||||||
@@ -667,10 +701,6 @@ class Transaction extends AppModel {
|
|||||||
$entry['statement_entry_comment'] = null;
|
$entry['statement_entry_comment'] = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (empty($transaction['crdr']) && !empty($transaction['account_id']))
|
|
||||||
$transaction['crdr'] = strtoupper($this->Account->fundamentalType
|
|
||||||
($transaction['account_id']));
|
|
||||||
|
|
||||||
if (empty($entry['crdr']) && !empty($transaction['crdr']))
|
if (empty($entry['crdr']) && !empty($transaction['crdr']))
|
||||||
$entry['crdr'] = strtoupper($this->Account->fundamentalOpposite
|
$entry['crdr'] = strtoupper($this->Account->fundamentalOpposite
|
||||||
($transaction['crdr']));
|
($transaction['crdr']));
|
||||||
@@ -737,15 +767,15 @@ class Transaction extends AppModel {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Add entry amount into the transaction total
|
// Add entry amount into the transaction total
|
||||||
$transaction_amount += $entry['amount'];
|
$transaction['amount'] += $entry['amount'];
|
||||||
|
|
||||||
// Replace combined entry with our new individual entries
|
// Replace combined entry with our new individual entries
|
||||||
$entry = compact('le1', 'le1_tender', 'le2', 'se');
|
$entry = compact('le1', 'le1_tender', 'le2', 'se');
|
||||||
}
|
}
|
||||||
|
|
||||||
return $this->prReturn(compact('transaction_amount',
|
return $this->prReturn(compact('transaction', 'entries')
|
||||||
'assign_disbursement_type',
|
+ array('vars' => compact('assign_disbursement_type'))
|
||||||
'entries') + array('error' => false));
|
+ array('error' => false));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user