Added ability to move an existing customer into a vacant unit. Changed out all of the 'amount' fields with 'rent', since it's much more self-explanatory. We still need the ability to add customers and contacts. I'll consider doing this by using the insert row ability of jqGrid.

git-svn-id: file:///svn-source/pmgr/branches/invoice_receipt_20090629/site@204 97e9348a-65ac-dc4b-aefc-98561f571b83
This commit is contained in:
abijah
2009-07-03 06:53:41 +00:00
parent 6adf7e2358
commit 3a1fb00527
14 changed files with 448 additions and 63 deletions

View File

@@ -315,6 +315,10 @@ class AppController extends Controller {
}
function jqGridRecordLinks(&$params, &$model, &$records, $links) {
// Don't create any links if ordered not to.
if (isset($params['nolinks']))
return;
foreach ($links AS $table => $fields) {
$special = array('controller', 'id');
$controller = Inflector::pluralize(Inflector::underscore($table));

View File

@@ -140,6 +140,28 @@ class CustomersController extends AppController {
}
/**************************************************************************
**************************************************************************
**************************************************************************
* action: move_in
* - Sets up the move-in page for the given customer.
*/
function move_in($id = null) {
$customer = array();
$unit = array();
if (isset($id)) {
$this->Customer->recursive = -1;
$customer = current($this->Customer->read(null, $id));
}
$title = 'Customer Move-In';
$this->set(compact('customer', 'unit', 'title'));
$this->render('/leases/move_in');
}
/**************************************************************************
**************************************************************************
**************************************************************************
@@ -205,18 +227,25 @@ class CustomersController extends AppController {
}
// Set up dynamic menu items
if ($show_moveout || $show_payment) {
$this->sidemenu_links[] =
array('name' => 'Operations', 'header' => true);
$this->sidemenu_links[] =
array('name' => 'Move-In',
'url' => array('action' => 'move_in',
$id));
if ($show_moveout) {
$this->sidemenu_links[] =
array('name' => 'Move-Out', 'url' => array('action' => 'move_out',
array('name' => 'Move-Out',
'url' => array('action' => 'move_out',
$id));
}
if ($show_payment) {
$this->sidemenu_links[] =
array('name' => 'Payment', 'url' => array('action' => 'payment',
array('name' => 'Payment',
'url' => array('action' => 'payment',
$id));
}

View File

@@ -88,6 +88,33 @@ class LeasesController extends AppController {
}
/**************************************************************************
**************************************************************************
**************************************************************************
* action: move_in
* - execute a move in on a new lease
*/
function move_in() {
if (!$this->data)
die("Should have some data");
// Handle the move in based on the data given
//pr(array('Move-in data', $this->data));
$lid = $this->Lease->moveIn($this->data['Lease']['customer_id'],
$this->data['Lease']['unit_id'],
null, null,
$this->data['Lease']['movein_date'],
$this->data['Lease']['comment']
);
if (isset($this->data['redirect']))
$this->redirect($this->data['redirect']);
else
$this->redirect(array('action' => 'view', $lid));
}
/**************************************************************************
**************************************************************************
**************************************************************************

View File

@@ -55,7 +55,7 @@ class UnitsController extends AppController {
$link = array
('link' =>
array(// Models
'UnitSize' => array('fields' => array('name')),
'UnitSize' => array('fields' => array('id', 'name')),
),
);
@@ -82,6 +82,9 @@ class UnitsController extends AppController {
elseif ($params['action'] === 'occupied') {
$conditions[] = $this->Unit->conditionOccupied();
}
elseif ($params['action'] === 'unoccupied') {
$conditions[] = array('NOT' => array($this->Unit->conditionOccupied()));
}
return $conditions;
}
@@ -93,6 +96,34 @@ class UnitsController extends AppController {
return parent::jqGridDataOrder($params, $model, $index, $direction);
}
function jqGridRecordLinks(&$params, &$model, &$records, $links) {
$links['Unit'] = array('name');
$links['UnitSize'] = array('name');
return parent::jqGridRecordLinks($params, $model, $records, $links);
}
/**************************************************************************
**************************************************************************
**************************************************************************
* action: move_in
* - Sets up the move-in page for the given unit.
*/
function move_in($id = null) {
$customer = array();
$unit = array();
if (isset($id)) {
$this->Unit->recursive = -1;
$unit = current($this->Unit->read(null, $id));
}
$title = 'Unit Move-In';
$this->set(compact('customer', 'unit', 'title'));
$this->render('/leases/move_in');
}
/**************************************************************************
**************************************************************************
@@ -174,17 +205,22 @@ class UnitsController extends AppController {
}
// Set up dynamic menu items
if (isset($unit['CurrentLease']['id']) &&
!isset($unit['CurrentLease']['close_date'])) {
$this->sidemenu_links[] =
array('name' => 'Operations', 'header' => true);
if (!isset($unit['CurrentLease']['moveout_date'])) {
if (isset($unit['CurrentLease']['id']) &&
!isset($unit['CurrentLease']['moveout_date'])) {
$this->sidemenu_links[] =
array('name' => 'Move-Out', 'url' => array('action' => 'move_out',
$id));
} else {
$this->sidemenu_links[] =
array('name' => 'Move-In', 'url' => array('action' => 'move_in',
$id));
}
if (isset($unit['CurrentLease']['id']) &&
!isset($unit['CurrentLease']['close_date'])) {
$this->sidemenu_links[] =
array('name' => 'Payment', 'url' => array('action' => 'payment',
$id));

View File

@@ -20,9 +20,6 @@ class Customer extends AppModel {
),
'Lease',
'LedgerEntry',
// Cheat to get Account set as part of this class
'Account',
);
var $hasAndBelongsToMany = array(
@@ -86,9 +83,10 @@ class Customer extends AppModel {
/* 'args' => compact('id', 'link'), */
/* )); */
$entries = $this->Account->findLedgerEntriesRelatedToAccount
($this->Account->invoiceAccountID(),
$this->Account->securityDepositAccountID(),
$A = new Account();
$entries = $A->findLedgerEntriesRelatedToAccount
($A->invoiceAccountID(),
$A->securityDepositAccountID(),
true, array('LedgerEntry.customer_id' => $id), $link);
/* pr(array('function' => 'Customer::findSecurityDeposits', */
@@ -110,8 +108,9 @@ class Customer extends AppModel {
*/
function findUnreconciledLedgerEntries($id = null, $fundamental_type = null) {
$unreconciled = $this->Account->findUnreconciledLedgerEntries
($this->Account->accountReceivableAccountID(),
$A = new Account();
$unreconciled = $A->findUnreconciledLedgerEntries
($A->accountReceivableAccountID(),
$fundamental_type,
array('LedgerEntry.customer_id' => $id));
@@ -134,8 +133,9 @@ class Customer extends AppModel {
*/
function reconcileNewLedgerEntry($id, $fundamental_type, $amount) {
$reconciled = $this->Account->reconcileNewLedgerEntry
($this->Account->accountReceivableAccountID(),
$A = new Account();
$reconciled = $A->reconcileNewLedgerEntry
($A->accountReceivableAccountID(),
$fundamental_type,
$amount,
array('LedgerEntry.customer_id' => $id));
@@ -195,7 +195,8 @@ class Customer extends AppModel {
if (!$id)
return null;
$stats = $this->Account->stats($this->Account->accountReceivableAccountID(), true,
$A = new Account();
$stats = $A->stats($A->accountReceivableAccountID(), true,
array('LedgerEntry.customer_id' => $id));
// Pull to the top level and return

View File

@@ -17,9 +17,9 @@ class Lease extends AppModel {
'notice_received_date' => array('date'),
'close_date' => array('date'),
'deposit' => array('money'),
'amount' => array('money'),
'next_amount' => array('money'),
'next_amount_date' => array('date')
'rent' => array('money'),
'next_rent' => array('money'),
'next_rent_date' => array('date')
);
var $belongsTo = array(
@@ -34,6 +34,21 @@ class Lease extends AppModel {
);
function beforeSave() {
foreach (array('lease',
'movein', 'movein_planned',
'moveout', 'moveout_planned',
'notice_givein', 'notice_received',
'close', 'next_rent') AS $dtfield) {
$dtfield .= '_date';
if(isset($this->data['Lease'][$dtfield]))
$this->data['Lease'][$dtfield] =
$this->dateFormatBeforeSave($this->data['Lease'][$dtfield]);
}
return true;
}
/**************************************************************************
**************************************************************************
**************************************************************************
@@ -137,6 +152,90 @@ class Lease extends AppModel {
}
/**************************************************************************
**************************************************************************
**************************************************************************
* function: moveIn
* - Moves the specified customer into the specified lease
*/
function moveIn($customer_id, $unit_id,
$deposit = null, $rent = null,
$stamp = null, $comment = null) {
$lt = $this->LeaseType->find('first',
array('conditions' =>
array('code' => 'SL')));
// Use NOW if not given a movein date
if (!isset($stamp))
$stamp = date('Y-m-d G:i:s');
if (!$comment)
$comment = null;
if (!isset($deposit) || !isset($rent)) {
$rates = $this->Unit->find
('first',
array('contain' =>
array('UnitSize' =>
array('deposit', 'rent'),
),
'fields' => array('deposit', 'rent'),
'conditions' => array('Unit.id' => $unit_id),
));
$deposit =
(isset($deposit)
? $deposit
: (isset($rates['Unit']['deposit'])
? $rates['Unit']['deposit']
: (isset($rates['UnitSize']['deposit'])
? $rates['UnitSize']['deposit']
: 0)));
$rent =
(isset($rent)
? $rent
: (isset($rates['Unit']['rent'])
? $rates['Unit']['rent']
: (isset($rates['UnitSize']['rent'])
? $rates['UnitSize']['rent']
: 0)));
}
// Save this new lease.
$this->create();
if (!$this->save(array('lease_type_id' => $lt['LeaseType']['id'],
'unit_id' => $unit_id,
'customer_id' => $customer_id,
'lease_date' => $stamp,
'movein_date' => $stamp,
'deposit' => $deposit,
'rent' => $rent,
'comment' => $comment), false)) {
return null;
}
// Set the lease number to be the same as the lease ID
$this->id;
$this->saveField('number', $this->id);
// Update the unit status
$this->Unit->updateStatus($unit_id, 'OCCUPIED');
// REVISIT <AP>: 20090702
// We need to assess the security deposit charge,
// and probably rent as well. Rent, however, will
// require user parameters to indicate whether it
// was waived, pro-rated, etc.
// Return the new lease ID
return $this->id;
}
/**************************************************************************
**************************************************************************
**************************************************************************

View File

@@ -209,7 +209,13 @@ class Ledger extends AppModel {
// The fields are all tucked into the [0] index,
// and the rest of the array is useless (empty).
return $stats[0];
$stats = $stats[0];
// Make sure we have a non-null balance
if (!isset($stats['balance']))
$stats['balance'] = 0;
return $stats;
}
}

View File

@@ -72,7 +72,7 @@ class Unit extends AppModel {
*/
function updateStatus($id, $status) {
$this->id = $id;
pr(compact('id', 'status'));
//pr(compact('id', 'status'));
$this->saveField('status', $status);
}

View File

@@ -12,11 +12,12 @@ $cols['Leases'] = array('index' => 'lease_count', 'width' =>
$cols['Balance'] = array('index' => 'balance', 'formatter' => 'currency', 'sortable' => false);
$cols['Comment'] = array('index' => 'Customer.comment', 'formatter' => 'comment');
$custom_post_data = compact('nothing');
$jqGrid_options = array('jqGridColumns' => $cols,
'controller' => 'customers');
// User requested options have priority
$jqGrid_options += compact('grid_div_id', 'grid_id', 'caption', 'grid_setup', 'limit');
$jqGrid_options += compact('action', 'caption',
'grid_div_id', 'grid_id', 'grid_setup',
'nolinks', 'limit');
if (isset($customers)) {
$jqGrid_options += array('custom_ids' =>

View File

@@ -93,6 +93,9 @@ if (isset($custom_post_data)) {
// correct subset of data
$postData['action'] = $action;
if (isset($nolinks)) {
$postData['nolinks'] = true;
}
// Perform column customizations.
// This will largely be based off of the 'formatter' parameter,

View File

@@ -2,15 +2,22 @@
// Define the table columns
$cols = array();
$cols['Sort'] = array('index' => 'Unit.sort_order', 'hidden' => true);
//$cols['Sort'] = array('index' => 'Unit.sort_order');
//$cols['Walk'] = array('index' => 'Unit.walk_order');
$cols['ID'] = array('index' => 'Unit.id', 'formatter' => 'id');
$cols['Unit'] = array('index' => 'Unit.name', 'width' => '50');
$cols['Size'] = array('index' => 'UnitSize.name', 'width' => '75');
$cols['Status'] = array('index' => 'Unit.status', 'width' => '75');
$cols['Comment'] = array('index' => 'Unit.comment', 'formatter' => 'comment');
$custom_post_data = compact('nothing');
$jqGrid_options = array('jqGridColumns' => $cols,
'controller' => 'units',
'caption' => isset($caption) ? $caption : null);
'controller' => 'units');
$jqGrid_options += compact('action', 'caption',
'grid_div_id', 'grid_id', 'grid_setup',
'nolinks', 'limit');
if (isset($units)) {
$jqGrid_options += array('custom_ids' =>
@@ -19,9 +26,12 @@ if (isset($units)) {
$units),
'limit' => 5);
}
else {
if (isset($searchfields)) {
$jqGrid_options += array('search_fields' => array('Unit', 'Size', 'Status'));
}
$jqGrid_options += compact('custom_post_data');
$jqGrid_options['sort_column'] = 'Sort';
echo $this->element('jqGrid', $jqGrid_options);

159
views/leases/move_in.ctp Normal file
View File

@@ -0,0 +1,159 @@
<?php /* -*- mode:PHP -*- */ ?>
<div class="move-in input">
<?php
; // Editor alignment
/**********************************************************************
**********************************************************************
**********************************************************************
**********************************************************************
*
*/
$customer_grid_setup = array();
if (isset($customer['id']))
$customer_grid_setup['hiddengrid'] = true;
$customer_grid_setup['onSelectRow'] = array
('--special' =>
'function(ids) { if (ids != null) { onCustomerRowSelect("#"+$(this).attr("id"), ids); } }'
);
$unit_grid_setup = array();
if (isset($unit['id']))
$unit_grid_setup['hiddengrid'] = true;
$unit_grid_setup['onSelectRow'] = array
('--special' =>
'function(ids) { if (ids != null) { onUnitRowSelect("#"+$(this).attr("id"), ids); } }'
);
?>
<script type="text/javascript"><!--
function datepickerNow() {
now = new Date();
$("#datepicker").val($.datepicker.formatDate('mm/dd/yy', now)
+ ' '
+ (now.getHours() < 10 ? '0' : '')
+ now.getHours() + ':'
+ (now.getMinutes() < 10 ? '0' : '')
+ now.getMinutes());
}
function onCustomerRowSelect(grid_id, cust_id) {
// Set the customer id that will be returned with the form
$("#customer-id").val(cust_id);
// Get the customer name from the grid
$("#movein_customer").html($(grid_id).getCell(cust_id, "Customer-name"));
// Hide the "no customer" message and show the current customer
$("#no_customer").hide();
$("#current_customer").show();
$("#customers-list .HeaderButton").click();
}
function onUnitRowSelect(grid_id, unit_id) {
// Set the unit id that will be returned with the form
$("#unit-id").val(unit_id);
// Get the unit name from the grid
$("#movein_unit").html($(grid_id).getCell(unit_id, "Unit-name"));
// Hide the "no unit" message and show the current unit
$("#no_unit").hide();
$("#current_unit").show();
$("#units-list .HeaderButton").click();
}
--></script>
<?php
; // align
echo $this->element('customers',
array('grid_div_id' => 'customers-list',
'caption' => ('<A HREF="#" ONCLICK="$(\'#customers-list .HeaderButton\').click();'.
' return false;">Select Customer</A>'),
'grid_setup' => $customer_grid_setup,
'nolinks' => true,
'limit' => 10,
));
echo $this->element('units',
array('grid_div_id' => 'units-list',
'caption' => ('<A HREF="#" ONCLICK="$(\'#units-list .HeaderButton\').click();'.
' return false;">Select Unit</A>'),
'grid_setup' => $unit_grid_setup,
'action' => 'unoccupied',
'nolinks' => true,
'limit' => 10,
));
echo ('<H2>' .
'<SPAN id="current_customer" style="display:'.(isset($customer['id'])?"inline":"none").'">' .
'Customer: ' .
'<SPAN id="movein_customer">' . (isset($customer['name']) ? $customer['name'] : "") . '</SPAN>' .
'</SPAN>' .
'<SPAN id="no_customer" style="display:'.(isset($customer['id'])?"none":"inline").'">' .
'Please select customer' .
'</SPAN>' .
'</H2>' . "\n");
echo ('<H2>' .
'<SPAN id="current_unit" style="display:'.(isset($unit['id'])?"inline":"none").'">' .
'Unit: ' .
'<SPAN id="movein_unit">' . (isset($unit['name']) ? $unit['name'] : "") . '</SPAN>' .
'</SPAN>' .
'<SPAN id="no_unit" style="display:'.(isset($unit['id'])?"none":"inline").'">' .
'Please select unit' .
'</SPAN>' .
'</H2>' . "\n");
echo $form->create(null, array('id' => 'move-in-form',
'url' => array('controller' => 'leases',
'action' => 'move_in')));
echo $form->input("Lease.customer_id",
array('id' => 'customer-id',
'type' => 'hidden',
'value' => isset($customer['id']) ? $customer['id'] : 0));
echo $form->input("Lease.unit_id",
array('id' => 'unit-id',
'type' => 'hidden',
'value' => isset($unit['id']) ? $unit['id'] : 0));
echo 'Date: <input id="datepicker" name="data[Lease][movein_date]" type="text" /><BR>' . "\n";
echo 'Comment: <input id="comment" name="data[Lease][comment]" type="text" SIZE=80 /><BR>' . "\n";
echo $form->end('Move In Customer');
?>
<script type="text/javascript"><!--
$(document).ready(function(){
$("#datepicker").datepicker({ constrainInput: true,
numberOfMonths: [1, 1],
showCurrentAtPos: 0,
dateFormat: 'mm/dd/yy' })
.datepicker('setDate', '+0');
<?php if (isset($customer['id'])): ?>
$("#customer-id").val(<?php echo $customer['id']; ?>);
<?php endif; ?>
<?php if (isset($unit['id'])): ?>
$("#unit-id").val(<?php echo $unit['id']; ?>);
<?php endif; ?>
});
--></script>
</div>

View File

@@ -36,7 +36,7 @@ $rows = array(array('ID', $lease['id']),
array('Notice Received', FormatHelper::date($lease['notice_received_date'], true)),
array('Closed', FormatHelper::date($lease['close_date'], true)),
array('Deposit', FormatHelper::currency($lease['deposit'])),
array('Rent', FormatHelper::currency($lease['amount'])),
array('Rent', FormatHelper::currency($lease['rent'])),
array('Comment', $lease['comment']));

View File

@@ -9,9 +9,19 @@ echo '<div class="unit view">' . "\n";
* Unit Detail Main Section
*/
$rows = array(array('Name', $unit['Unit']['name']),
array('Status', $unit['Unit']['status']),
array('Comment', $unit['Unit']['comment']));
$leases = $unit['Lease'];
$current_lease = $unit['CurrentLease'];
$unit_size = $unit['UnitSize'];
if (isset($unit['Unit']))
$unit = $unit['Unit'];
$rows = array(array('Name', $unit['name']),
array('Status', $unit['status']),
array('Size', $unit_size['name']),
array('Deposit', FormatHelper::currency($unit['deposit'])),
array('Rent', FormatHelper::currency($unit['rent'])),
array('Comment', $unit['comment']));
echo $this->element('table',
array('class' => 'item unit detail',
@@ -53,20 +63,20 @@ echo '<div CLASS="detail supporting">' . "\n";
echo $this->element('leases',
array('caption' => 'Lease History',
'leases' => $unit['Lease']));
'leases' => $leases));
/**********************************************************************
* Current Tenant Lease Account History
*/
if (isset($unit['CurrentLease']['id'])) {
if (isset($current_lease['id'])) {
echo $this->element('ledger_entries',
array('caption' =>
('Current Lease Account ('
. $unit['CurrentLease']['Customer']['name']
. $current_lease['Customer']['name']
. ')'),
'ar_account' => true,
'lease_id' => $unit['CurrentLease']['id'],
'lease_id' => $current_lease['id'],
));
}