prFunctionLevel(30); $this->prEnter(compact('id', 'query')); $this->queryInit($query); $A = new Account(); if (!isset($query['link']['Lease'])) $query['link']['Lease'] = array(); if (!isset($query['link']['Lease']['fields'])) $query['link']['Lease']['fields'] = array(); $query['conditions'][] = array('Lease.id' => $id); $query['conditions'][] = array('StatementEntry.account_id' => $A->securityDepositAccountID()); $set = $this->StatementEntry->reconciledSet('CHARGE', $query); $set['summary'] = array('total' => $set['summary']['Charge']['total'], 'balance' => $set['summary']['Charge']['reconciled'], ); return $this->prReturn($set); } /************************************************************************** ************************************************************************** ************************************************************************** * 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) { $this->prEnter(compact('id')); $rent_account_id = $this->StatementEntry->Account->rentAccountID(); $entries = $this->find ('all', array('link' => array(// Models 'StatementEntry', 'SEx' => array('class' => 'StatementEntry', 'fields' => array(), 'conditions' => array ('SEx.effective_date = DATE_ADD(StatementEntry.through_date, INTERVAL 1 day)', 'SEx.lease_id = StatementEntry.lease_id', ), ), ), //'fields' => array('id', 'amount', 'effective_date', 'through_date'), 'fields' => array(), 'conditions' => array(array('Lease.id' => $id), array('StatementEntry.type' => 'CHARGE'), array('StatementEntry.account_id' => $rent_account_id), array('SEx.id' => null), ), ) ); return $this->prReturn($entries); } /************************************************************************** ************************************************************************** ************************************************************************** * function: rentChargeGaps * - Checks for gaps in rent charges */ function rentChargeGaps($id) { $this->prEnter(compact('id')); $entries = $this->rentLastCharges($id); if ($entries && count($entries) > 1) return $this->prReturn(true); return $this->prReturn(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) { $this->prEnter(compact('id')); $entries = $this->rentLastCharges($id); if (!$entries) return $this->prReturn(false); if (count($entries) != 1) return $this->prReturn(null); return $this->prReturn($entries[0]['StatementEntry']['through_date']); } /************************************************************************** ************************************************************************** ************************************************************************** * function: rentPaidThrough * - Determines the date of the first unpaid rent */ function rentPaidThrough($id) { $this->prEnter(compact('id')); $rent_account_id = $this->StatementEntry->Account->rentAccountID(); // First, see if we can find any unpaid entries. Of course, // the first unpaid entry gives us a very direct indication // of when the customer is paid up through, which is 1 day // prior to the effective date of that first unpaid charge. $rent = $this->StatementEntry->reconciledSet ('CHARGE', array('fields' => array('StatementEntry.*', 'DATE_SUB(StatementEntry.effective_date, INTERVAL 1 DAY) AS paid_through', ), 'conditions' => array(array('StatementEntry.lease_id' => $id), array('StatementEntry.account_id' => $rent_account_id)), 'order' => array('StatementEntry.effective_date'), ), true); $this->pr(20, $rent, "Unpaid rent"); if ($rent['entries']) return $this->prReturn($rent['entries'][0]['StatementEntry']['paid_through']); // If we don't have any unpaid charges (great!), then the // customer is paid up through the last day of the last // charge. So, search for paid charges, which already // have the paid through date saved as part of the entry. $rent = $this->StatementEntry->reconciledSet ('CHARGE', array('conditions' => array(array('StatementEntry.lease_id' => $id), array('StatementEntry.account_id' => $rent_account_id)), 'order' => array('StatementEntry.through_date DESC'), ), false); $this->pr(20, $rent, "Paid rent"); if ($rent['entries']) return $this->prReturn($rent['entries'][0]['StatementEntry']['through_date']); // After all that, having found that there are no unpaid // charges, and in fact, no paid charges either, we cannot // possibly say when the customer is paid through. return $this->prReturn(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) { $this->prEnter(compact('customer_id', 'unit_id', 'deposit', 'rent', 'stamp', 'comment')); $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 $this->prReturn(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 : 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->prReturn($this->id); } /************************************************************************** ************************************************************************** ************************************************************************** * function: moveOut * - Moves the customer out of the specified lease */ function moveOut($id, $status = 'VACANT', $stamp = null, $close = false) { $this->prEnter(compact('id', 'status', 'stamp', 'close')); // 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) { $this->prEnter(compact('id', 'stamp')); if (!$this->closeable($id)) return $this->prReturn(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 $this->prReturn(true); } /************************************************************************** ************************************************************************** ************************************************************************** * function: closeable * - Indicates whether or not the lease can be closed */ function closeable($id) { $this->prEnter(compact('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 $this->prReturn(false); // We can't close a lease that's already closed if (isset($this->data['Lease']['close_date'])) return $this->prReturn(false); $deposits = $this->securityDeposits($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 $this->prReturn(false); // Apparently this lease meets all the criteria! return $this->prReturn(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) { $this->prEnter(compact('id', 'query')); if (!$id) return $this->prReturn(null); $this->queryInit($query); //$query['link'] = array('Lease' => $query['link']); /* if (!isset($query['link']['StatementEntry'])) */ /* $query['link']['StatementEntry'] = array(); */ /* if (!isset($query['link']['StatementEntry']['ChargeEntry'])) */ /* $query['link']['StatementEntry']['ChargeEntry'] = array(); */ /* $query['link']['StatementEntry']['fields'] = array(); */ /* $query['link']['ChargeEntry']['fields'] = array(); */ /* $query['link']['ChargeEntry']['Account']['fields'] = array(); */ /* $query['link']['ChargeEntry']['StatementEntry']['fields'] = array(); */ /* $query['link']['ChargeEntry']['StatementEntry']['Invoice']['fields'] = array(); */ if (!isset($query['fields'])) $query['fields'] = array(); $query['fields'] = array_merge($query['fields'], $this->StatementEntry->chargePaymentFields(true)); $query['conditions'][] = array('StatementEntry.lease_id' => $id); $query['group'] = null; $stats = $this->StatementEntry->find('first', $query); //$this->pr(20, 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 $this->prReturn($stats); } } ?>