git-svn-id: file:///svn-source/pmgr/branches/yafr_20090716@356 97e9348a-65ac-dc4b-aefc-98561f571b83
470 lines
15 KiB
PHP
470 lines
15 KiB
PHP
<?php
|
|
class Lease extends AppModel {
|
|
|
|
var $belongsTo = array(
|
|
'LeaseType',
|
|
'Unit',
|
|
'Customer',
|
|
'LateSchedule',
|
|
);
|
|
|
|
var $hasMany = array(
|
|
'DoubleEntry',
|
|
);
|
|
|
|
|
|
/**************************************************************************
|
|
**************************************************************************
|
|
**************************************************************************
|
|
* function: securityDeposits
|
|
* - Returns an array of security deposit entries
|
|
*/
|
|
function securityDeposits($id, $query = null) {
|
|
$this->queryInit($query);
|
|
|
|
$this->id = $id;
|
|
$this->recursive = -1;
|
|
$this->read();
|
|
|
|
if (!isset($query['link']['DoubleEntry']))
|
|
$query['link']['DoubleEntry'] = array();
|
|
if (!isset($query['link']['DoubleEntry']['Lease']))
|
|
$query['link']['DoubleEntry']['Lease'] = array();
|
|
if (!isset($query['link']['DoubleEntry']['Lease']['fields']))
|
|
$query['link']['DoubleEntry']['Lease']['fields'] = array();
|
|
|
|
$query['conditions'][] = array('Lease.id' => $id);
|
|
|
|
return $this->Customer->securityDeposits
|
|
($this->data['Lease']['customer_id'], $query);
|
|
}
|
|
|
|
|
|
/**************************************************************************
|
|
**************************************************************************
|
|
**************************************************************************
|
|
* function: rentLastCharges
|
|
* - Returns a list of rent charges from this lease that
|
|
* do not have sequential followup charges. Under normal
|
|
* circumstances, there would only be one entry, which is
|
|
* the most recent rent charge. However, it's possible
|
|
* that there are several, indicating a problem with lease.
|
|
*/
|
|
|
|
function rentLastCharges($id) {
|
|
$rent_account_id = $this->DoubleEntry->Entry->Account->rentAccountID();
|
|
$entries = $this->find
|
|
('all',
|
|
array('link' =>
|
|
array(// Models
|
|
'DoubleEntry' =>
|
|
array('Entry'// =>
|
|
//array('fields'),
|
|
),
|
|
|
|
'DEx' =>
|
|
array('class' => 'DoubleEntry',
|
|
'conditions' => array
|
|
('DEx.effective_date = DATE_ADD(Entry.through_date, INTERVAL 1 day)',
|
|
'DEx.lease_id = DoubleEntry.lease_id',
|
|
),
|
|
|
|
'Ex' =>
|
|
array('class' => 'Entry',
|
|
'type' => 'INNER',
|
|
'conditions' => array
|
|
('Ex.account_id = Entry.account_id',
|
|
'Ex.type = Entry.type',
|
|
'Ex.crdr = Entry.crdr'),
|
|
),
|
|
),
|
|
),
|
|
|
|
//'fields' => array('id', 'amount', 'effective_date', 'through_date'),
|
|
'fields' => array(),
|
|
'conditions' => array(array('Lease.id' => $id),
|
|
array('Entry.type' => 'CHARGE'),
|
|
array('Entry.account_id' => $rent_account_id),
|
|
array('DEx.id' => null),
|
|
),
|
|
)
|
|
);
|
|
return $entries;
|
|
}
|
|
|
|
|
|
/**************************************************************************
|
|
**************************************************************************
|
|
**************************************************************************
|
|
* function: rentChargeGaps
|
|
* - Checks for gaps in rent charges
|
|
*/
|
|
|
|
function rentChargeGaps($id) {
|
|
$entries = $this->rentLastCharges($id);
|
|
if ($entries && count($entries) > 1)
|
|
return true;
|
|
return false;
|
|
}
|
|
|
|
|
|
/**************************************************************************
|
|
**************************************************************************
|
|
**************************************************************************
|
|
* function: rentChargeThrough
|
|
* - Determines the date that rent has been charged through
|
|
* Returns one of:
|
|
* null: There are gaps in the charges
|
|
* false: There are not yet any charges
|
|
* date: The date rent has been charged through
|
|
*/
|
|
|
|
function rentChargeThrough($id) {
|
|
$entries = $this->rentLastCharges($id);
|
|
if (!$entries)
|
|
return false;
|
|
if (count($entries) != 1)
|
|
return null;
|
|
return $entries[0]['DoubleEntry']['through_date'];
|
|
}
|
|
|
|
|
|
/**************************************************************************
|
|
**************************************************************************
|
|
**************************************************************************
|
|
* function: rentPaidThrough
|
|
* - Determines the date of the first unpaid rent
|
|
*/
|
|
|
|
function rentPaidThrough($id) {
|
|
$rent_account_id = $this->DoubleEntry->Entry->Account->rentAccountID();
|
|
|
|
$rent = $this->DoubleEntry->Entry->reconciledSet
|
|
('CHARGE',
|
|
array('fields' =>
|
|
array('DATE_SUB(DoubleEntry.effective_date, INTERVAL 1 DAY) AS paid_through',
|
|
),
|
|
'conditions' =>
|
|
array(array('DoubleEntry.lease_id' => $id),
|
|
array('Entry.account_id' => $rent_account_id)),
|
|
|
|
'order' => array('DoubleEntry.effective_date'),
|
|
),
|
|
true);
|
|
|
|
/* $query = array */
|
|
/* ('link' => */
|
|
/* array(// Models */
|
|
/* 'DoubleEntry' => */
|
|
/* array('Entry' => */
|
|
/* array(), */
|
|
/* 'fields' => array('SUM(COALESCE(MoneyDoubleEntryR.amount,0)) AS paid'), */
|
|
/* ), */
|
|
/* ), */
|
|
|
|
/* // Finally, the Money (Cash/Check/etc) Entry is the one */
|
|
/* // which reconciles our ReceiptDoubleEntry debit */
|
|
/* 'DebitReconciliationDoubleEntry' => */
|
|
/* array('alias' => 'MoneyDoubleEntry', */
|
|
/* 'linkalias' => 'MoneyDoubleEntryR', */
|
|
/* ), */
|
|
/* ), */
|
|
/* ), */
|
|
|
|
/* 'fields' => array('DoubleEntry.amount', */
|
|
/* 'DATE_SUB(DoubleEntry.effective_date, INTERVAL 1 DAY) AS paid_through', */
|
|
/* ), */
|
|
|
|
/* 'group' => 'DoubleEntry.id HAVING paid <> DoubleEntry.amount', */
|
|
|
|
/* 'conditions' => array(array('DoubleEntry.lease_id' => $id), */
|
|
/* array('Account.id' => $this->DoubleEntry->Ledger->Account->rentAccountID()), */
|
|
/* ), */
|
|
/* 'order' => array('DoubleEntry.effective_date', */
|
|
/* ), */
|
|
/* ); */
|
|
|
|
/* $rent = $this->DoubleEntry->find('first', $query); */
|
|
//pr($rent);
|
|
if ($rent['entries'])
|
|
return $rent['entries'][0]['DoubleEntry']['paid_through'];
|
|
|
|
$rent = $this->DoubleEntry->Entry->reconciledSet
|
|
('CHARGE',
|
|
array('conditions' =>
|
|
array(array('DoubleEntry.lease_id' => $id),
|
|
array('Entry.account_id' => $rent_account_id)),
|
|
|
|
'order' => array('Entry.through_date DESC'),
|
|
),
|
|
false);
|
|
if ($rent)
|
|
return $rent[0]['Entry']['through_date'];
|
|
|
|
/* $query['fields'] = 'Entry.through_date'; */
|
|
/* $query['order'] = 'Entry.through_date DESC'; */
|
|
/* $query['group'] = 'DoubleEntry.id'; */
|
|
/* $rent = $this->DoubleEntry->find('first', $query); */
|
|
/* if ($rent) */
|
|
/* return $rent['DoubleEntry']['through_date']; */
|
|
|
|
return null;
|
|
}
|
|
|
|
|
|
/**************************************************************************
|
|
**************************************************************************
|
|
**************************************************************************
|
|
* 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;
|
|
}
|
|
|
|
|
|
/**************************************************************************
|
|
**************************************************************************
|
|
**************************************************************************
|
|
* function: moveOut
|
|
* - Moves the customer out of the specified lease
|
|
*/
|
|
|
|
function moveOut($id, $status = 'VACANT',
|
|
$stamp = null, $close = false) {
|
|
// Use NOW if not given a moveout date
|
|
if (!isset($stamp))
|
|
$stamp = date('Y-m-d G:i:s');
|
|
|
|
// Reset the data
|
|
$this->create();
|
|
$this->id = $id;
|
|
|
|
// Set the customer move-out date
|
|
$this->data['Lease']['moveout_date'] = $stamp;
|
|
|
|
// Save it!
|
|
$this->save($this->data, false);
|
|
|
|
// Close the lease, if so requested
|
|
if ($close)
|
|
$this->close($id, $stamp);
|
|
|
|
// Finally, update the unit status
|
|
$this->recursive = -1;
|
|
$this->read();
|
|
$this->Unit->updateStatus($this->data['Lease']['unit_id'], $status);
|
|
}
|
|
|
|
|
|
/**************************************************************************
|
|
**************************************************************************
|
|
**************************************************************************
|
|
* function: close
|
|
* - Closes the lease to further action
|
|
*/
|
|
|
|
function close($id, $stamp = null) {
|
|
if (!$this->closeable($id))
|
|
return false;
|
|
|
|
// Reset the data
|
|
$this->create();
|
|
$this->id = $id;
|
|
|
|
// Use NOW if not given a moveout date
|
|
if (!isset($stamp))
|
|
$stamp = date('Y-m-d G:i:s');
|
|
|
|
// Set the close date
|
|
$this->data['Lease']['close_date'] = $stamp;
|
|
|
|
// Save it!
|
|
$this->save($this->data, false);
|
|
return true;
|
|
}
|
|
|
|
|
|
/**************************************************************************
|
|
**************************************************************************
|
|
**************************************************************************
|
|
* function: closeable
|
|
* - Indicates whether or not the lease can be closed
|
|
*/
|
|
|
|
function closeable($id) {
|
|
$this->recursive = -1;
|
|
$this->read(null, $id);
|
|
|
|
// We can't close a lease that's still in use
|
|
if (!isset($this->data['Lease']['moveout_date']))
|
|
return false;
|
|
|
|
// We can't close a lease that's already closed
|
|
if (isset($this->data['Lease']['close_date']))
|
|
return false;
|
|
|
|
$deposits = $this->findSecurityDeposits($id);
|
|
$stats = $this->stats($id);
|
|
|
|
// A lease can only be closed if there are no outstanding
|
|
// security deposits, and if the account balance is zero.
|
|
if ($deposits['summary']['balance'] != 0 || $stats['balance'] != 0)
|
|
return false;
|
|
|
|
// Apparently this lease meets all the criteria!
|
|
return true;
|
|
}
|
|
|
|
|
|
/**************************************************************************
|
|
**************************************************************************
|
|
**************************************************************************
|
|
* function: addCharge
|
|
* - Adds an additional charge to the lease
|
|
*/
|
|
|
|
function addCharge($id, $charge) {
|
|
|
|
}
|
|
|
|
|
|
/**************************************************************************
|
|
**************************************************************************
|
|
**************************************************************************
|
|
* function: stats
|
|
* - Returns summary data from the requested lease.
|
|
*/
|
|
|
|
function stats($id = null, $query = null) {
|
|
if (!$id)
|
|
return null;
|
|
|
|
$this->queryInit($query);
|
|
|
|
//$query['link'] = array('Lease' => $query['link']);
|
|
if (!isset($query['link']['DoubleEntry']))
|
|
$query['link']['DoubleEntry'] = array();
|
|
if (!isset($query['link']['Charge']))
|
|
$query['link']['Charge'] = array();
|
|
if (!isset($query['link']['Charge']['DoubleEntry']))
|
|
$query['link']['Charge']['DoubleEntry'] = array();
|
|
if (!isset($query['link']['Charge']['DoubleEntry']['Invoice']))
|
|
$query['link']['Charge']['DoubleEntry']['Invoice'] = array();
|
|
if (!isset($query['link']['Charge']['Account']))
|
|
$query['link']['Charge']['Account'] = array();
|
|
|
|
/* $query['link']['DoubleEntry']['fields'] = array(); */
|
|
/* $query['link']['Charge']['fields'] = array(); */
|
|
/* $query['link']['Charge']['Account']['fields'] = array(); */
|
|
/* $query['link']['Charge']['DoubleEntry']['fields'] = array(); */
|
|
/* $query['link']['Charge']['DoubleEntry']['Invoice']['fields'] = array(); */
|
|
|
|
$query['link']['Charge']['Account']['alias'] = 'ChargeAccount';
|
|
$query['link']['Charge']['DoubleEntry']['alias'] = 'ChargeDoubleEntry';
|
|
|
|
if (!isset($query['fields']))
|
|
$query['fields'] = array();
|
|
|
|
$query['fields'] = array_merge($query['fields'],
|
|
$this->DoubleEntry->Entry->chargePaymentFields(false));
|
|
|
|
$query['conditions'][] = array('OR' =>
|
|
array(array(array('Entry.type' => 'CHARGE'),
|
|
array('DoubleEntry.lease_id' => $id)),
|
|
array(array('Entry.type' => 'PAYMENT'),
|
|
array('ChargeDoubleEntry.lease_id' => $id)),
|
|
),
|
|
);
|
|
|
|
$query['group'] = null;
|
|
|
|
$stats = $this->DoubleEntry->Entry->find('all', $query);
|
|
pr(compact('query', 'stats'));
|
|
|
|
// The fields are all tucked into the [0] index,
|
|
// and the rest of the array is useless (empty).
|
|
$stats = $stats[0];
|
|
|
|
// Make sure we have a non-null balance
|
|
if (!isset($stats['balance']))
|
|
$stats['balance'] = 0;
|
|
|
|
return $stats;
|
|
}
|
|
|
|
}
|
|
?>
|