diff --git a/controllers/customers_controller.php b/controllers/customers_controller.php
index b2dbada..56ad22f 100644
--- a/controllers/customers_controller.php
+++ b/controllers/customers_controller.php
@@ -178,17 +178,33 @@ class CustomersController extends AppController {
$this->redirect(array('action'=>'index'));
}
-/* //$result = $this->Customer->securityDeposits($id); */
-/* $result = $this->Customer->excessPayments($id); */
-/* //$result = $this->Customer->unreconciledCharges($id); */
-/* echo('
'); */
-/* pr($result); */
-/* $this->autoRender = false; */
-/* return; */
+ // Get details on this customer, its contacts and leases
+ $customer = $this->Customer->find
+ ('first', array
+ ('contain' => array
+ (// Models
+ 'Contact' =>
+ array('order' => array('Contact.display_name'),
+ // Models
+ 'ContactPhone',
+ 'ContactEmail',
+ 'ContactAddress',
+ ),
+ 'Lease' =>
+ array('Unit' =>
+ array('order' => array('sort_order'),
+ 'fields' => array('id', 'name'),
+ ),
+ ),
+ ),
- $customer = $this->Customer->details($id);
+ 'conditions' => array('Customer.id' => $id),
+ ));
//pr($customer);
- $outstanding_balance = $customer['stats']['balance'];
+
+ // Figure out the outstanding balances for this customer
+ $stats = $this->Customer->stats($id);
+ $outstanding_balance = $stats['balance'];
$outstanding_deposit = $this->Customer->securityDepositBalance($id);
// Figure out if this customer has any non-closed leases
@@ -229,6 +245,11 @@ class CustomersController extends AppController {
$id));
}
+ if ($outstanding_balance < 0)
+ $this->sidemenu_links[] =
+ array('name' => 'Issue Refund',
+ 'url' => array('action' => 'refund', $id));
+
// Prepare to render.
$title = 'Customer: ' . $customer['Customer']['name'];
$this->set(compact('customer', 'title',
diff --git a/controllers/leases_controller.php b/controllers/leases_controller.php
index 24e4012..9189556 100644
--- a/controllers/leases_controller.php
+++ b/controllers/leases_controller.php
@@ -213,22 +213,38 @@ class LeasesController extends AppController {
}
+/* /\************************************************************************** */
+/* ************************************************************************** */
+/* ************************************************************************** */
+/* * action: promote_credit */
+/* * - Moves any lease credit up to the customer level, so that */
+/* * it may be used for charges other than those on this lease. */
+/* *\/ */
+
+/* function promote_surplus($id) { */
+/* $this->Lease->promoteSurplus($id); */
+/* pr("PREVENTING REDIRECT"); */
+/* $this->render('fake'); */
+/* $this->redirect(array('controller' => 'leases', */
+/* 'action' => 'view', */
+/* $id)); */
+/* } */
+
+
/**************************************************************************
**************************************************************************
**************************************************************************
- * action: apply_deposit
- * - Applies the security deposit to charges. This is much
- * like a receipt, but it's separated to keep it simple and
- * to prevent feature overload on the receipt page.
+ * action: refund
+ * - Provides lease customer with a refund
*/
- function apply_deposit($id) {
- $this->Lease->releaseSecurityDeposits($id);
- pr("PREVENTING REDIRECT");
- $this->render('fake');
- $this->redirect(array('controller' => 'leases',
- 'action' => 'view',
- $id));
+ function refund($id) {
+ // Obtain the overall lease balance
+ $stats = $this->Lease->stats($id);
+ $outstanding_balance = $stats['balance'];
+
+ $this->set(compact('lease', 'title',
+ 'outstanding_balance'));
}
@@ -290,31 +306,6 @@ class LeasesController extends AppController {
}
- /**************************************************************************
- **************************************************************************
- **************************************************************************
- * action: refund
- * - Provides user with a refund
- * REVISIT : 20090710
- * Should this be a customer function?
- */
-
- function refund($id) {
-/* // Obtain the overall lease balance */
-/* $stats = $this->Lease->stats($id); */
-/* $outstanding_balance = $stats['balance']; */
-
-/* // Determine the lease security deposit */
-/* $deposits = $this->Lease->securityDeposits($id); */
-/* $outstanding_deposit = $deposits['summary']['balance']; */
-
-
-/* $this->set(compact('lease', 'title', */
-/* 'outstanding_deposit', */
-/* 'outstanding_balance')); */
- }
-
-
/**************************************************************************
**************************************************************************
**************************************************************************
@@ -435,19 +426,17 @@ class LeasesController extends AppController {
'action' => 'receipt',
$lease['Customer']['id']));
- if (isset($lease['Lease']['moveout_date']) && $outstanding_deposit > 0 && $outstanding_balance > 0)
- $this->sidemenu_links[] =
- array('name' => 'Apply Deposit', 'url' => array('action' => 'apply_deposit',
- $id));
+/* if ($outstanding_balance < 0) */
+/* $this->sidemenu_links[] = */
+/* array('name' => 'Transfer Credit to Customer', */
+/* 'url' => array('action' => 'promote_surplus', $id)); */
- if (isset($lease['Lease']['moveout_date']) &&
- $outstanding_balance <= 0 &&
- ($outstanding_deposit - $outstanding_balance) > 0)
+ if ($outstanding_balance < 0)
$this->sidemenu_links[] =
- array('name' => 'Issue Refund', 'url' => array('action' => 'refund',
- $id));
+ array('name' => 'Issue Refund',
+ 'url' => array('action' => 'refund', $id));
- if (isset($lease['Lease']['moveout_date']) && $outstanding_deposit == 0 && $outstanding_balance > 0)
+ if (isset($lease['Lease']['moveout_date']) && $outstanding_balance > 0)
$this->sidemenu_links[] =
array('name' => 'Write-Off', 'url' => array('action' => 'bad_debt',
$id));
diff --git a/models/lease.php b/models/lease.php
index 4ab7624..30965ca 100644
--- a/models/lease.php
+++ b/models/lease.php
@@ -48,6 +48,20 @@ class Lease extends AppModel {
$query['conditions'][] = array('StatementEntry.account_id' =>
$this->StatementEntry->Account->securityDepositAccountID());
+ // REVISIT : 20090804
+ // Dilemma... how to handle security deposits used to pay
+ // charges on the lease, yet are not part of the lease
+ // security deposit(s)? For example, Lease A & Lease B,
+ // each with $25 Sec. Dep. Move out of Lease A, and
+ // promote the lease surplus to the customer. A new
+ // charge on Lease B for $15, which is assigned $15/$25
+ // from the promoted Lease A surplus. They way this
+ // function works at present, it will presume the $15 is
+ // part of the security deposit balance, and will end up
+ // calculating it as only $10, which is wrong. Perhaps
+ // the fix is to release security deposits into some sort
+ // of income account.
+
$stats = $this->StatementEntry->stats(null, $query);
return $this->prReturn($stats['account_balance']);
}
@@ -450,18 +464,6 @@ class Lease extends AppModel {
}
- /**************************************************************************
- **************************************************************************
- **************************************************************************
- * function: addCharge
- * - Adds an additional charge to the lease
- */
-
- function addCharge($id, $charge) {
-
- }
-
-
/**************************************************************************
**************************************************************************
**************************************************************************
diff --git a/models/statement_entry.php b/models/statement_entry.php
index f55f03a..885e243 100644
--- a/models/statement_entry.php
+++ b/models/statement_entry.php
@@ -22,7 +22,7 @@ class StatementEntry extends AppModel {
);
- //var $default_log_level = array('log' => 30, 'show' => 15);
+ var $default_log_level = array('log' => 30, 'show' => 15);
/**************************************************************************
**************************************************************************
@@ -380,12 +380,15 @@ OPTION 2
$charge_ids = null, $payment_type = null,
$customer_id = null, $lease_id = null)
{
- //$this->prFunctionLevel(25);
+ $this->prFunctionLevel(25);
$this->prEnter(compact('query', 'receipt_id',
'charge_ids', 'payment_type',
'customer_id', 'lease_id'));
$this->queryInit($query);
+ if (!empty($customer_id))
+ $query['conditions'][] = array('StatementEntry.customer_id' => $customer_id);
+
if (empty($payment_type))
$payment_type = 'PAYMENT';
@@ -394,6 +397,22 @@ OPTION 2
// First, find all known credits
$lquery = $query;
$lquery['conditions'][] = array('StatementEntry.type' => 'SURPLUS');
+ // REVISIT : 20090804
+ // We need to ensure that we're using surplus credits ONLY from either
+ // the given lease, or those that do not apply to any specific lease.
+ // However, by doing this, it forces any lease surplus amounts to
+ // remain frozen with that lease until either there is a lease charge,
+ // we refund the money, or we "promote" that surplus to the customer
+ // level and out of the leases direct control.
+ // That seems like a pain. Perhaps we should allow any customer
+ // surplus to be used on any customer charge.
+ $lquery['conditions'][] =
+ array('OR' =>
+ array(array('StatementEntry.lease_id' => null),
+ (!empty($lease_id)
+ ? array('StatementEntry.lease_id' => $lease_id)
+ : array()),
+ ));
$lquery['order'][] = 'StatementEntry.effective_date ASC';
$credits = $this->find('all', $lquery);
$this->pr(18, compact('credits'),
@@ -403,6 +422,7 @@ OPTION 2
$receipt_credit = null;
if (!empty($receipt_id)) {
$lquery = $query;
+ $lquery['link'] = array('StatementEntry' => $lquery['link']);
$lquery['link'] += array('LedgerEntry' =>
array('conditions' =>
//array(LedgerEntry.'crdr'=>'DEBIT'),
@@ -429,6 +449,9 @@ OPTION 2
'conditions' => array('StatementEntry.id' => $charge_ids));
} else {
$lquery = $query;
+ // If we're working with a specific lease, then limit charges to it
+ if (!empty($lease_id))
+ $lquery['conditions'][] = array('StatementEntry.lease_id' => $lease_id);
}
$lquery['order'] = 'StatementEntry.effective_date ASC';
$charges = $this->reconciledSet('CHARGE', $lquery, true);
diff --git a/models/transaction.php b/models/transaction.php
index f257080..7f4a8a1 100644
--- a/models/transaction.php
+++ b/models/transaction.php
@@ -246,6 +246,44 @@ class Transaction extends AppModel {
}
+ /**************************************************************************
+ **************************************************************************
+ **************************************************************************
+ * function: addRefund
+ * - Adds a new refund transaction
+ */
+
+ function addRefund($data, $customer_id, $lease_id = null) {
+ $this->prEnter(compact('data', 'customer_id', 'lease_id'));
+
+ // REVISIT : 20090804
+ // NOT IMPLEMENTED AT ALL. Just cut and paste so far
+ return array('error' => true);
+
+ // Establish the transaction as an refund
+ $refund =& $data['Transaction'];
+ $refund +=
+ array('type' => 'VOUCHER',
+ 'crdr' => 'DEBIT',
+ 'account_id' => $this->Account->accountReceivableAccountID(),
+ 'customer_id' => $customer_id,
+ 'lease_id' => $lease_id,
+ );
+
+ // Go through the statement entries and flag as charges
+ foreach ($data['Entry'] AS &$entry)
+ $entry += array('type' => 'CHARGE',
+ 'crdr' => 'CREDIT',
+ );
+
+ $ids = $this->addTransaction($data['Transaction'], $data['Entry']);
+ if (isset($ids['transaction_id']))
+ $ids['refund_id'] = $ids['transaction_id'];
+
+ return $this->prReturn($ids);
+ }
+
+
/**************************************************************************
**************************************************************************
**************************************************************************
@@ -511,8 +549,7 @@ class Transaction extends AppModel {
$transaction['type'] == 'RECEIPT') &&
$subtype !== 'NSF' && !$ret['error']) {
$result = $this->StatementEntry->assignCredits
- (array('link' => array('Customer'),
- 'conditions' => array('Customer.id' => $transaction['customer_id'])),
+ (null,
($transaction['type'] == 'RECEIPT'
? $ret['transaction_id']
: null),
@@ -621,11 +658,13 @@ class Transaction extends AppModel {
// 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);
+ if (count($rollback['Entry'])) {
+ $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
@@ -651,7 +690,8 @@ class Transaction extends AppModel {
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'];
+ if (!empty($ret['rollback']))
+ $ret['nsf_ledger_entry_id'] = $ret['rollback']['entries'][0]['DoubleEntry']['Entry1']['ledger_entry_id'];
return $this->prReturn($ret + array('error' => false));
}