array('numeric'), 'name' => array('notempty'), ); var $belongsTo = array( 'Account', 'PrimaryContact' => array( 'className' => 'Contact', ), ); var $hasMany = array( 'CurrentLease' => array( 'className' => 'Lease', 'conditions' => 'CurrentLease.close_date IS NULL', ), 'Lease', 'Transaction', ); var $hasAndBelongsToMany = array( 'Contact', ); /************************************************************************** ************************************************************************** ************************************************************************** * function: findSecurityDeposits * - Returns an array of security deposit entries */ function findSecurityDeposits($id, $link = null) { /* pr(array('function' => 'Customer::findSecurityDeposits', */ /* 'args' => compact('id', 'link'), */ /* )); */ $customer = $this->find('first', array('contain' => array('Lease' => array('fields' => array('id'))), 'fields' => array('account_id'), 'conditions' => array(array('Customer.id' => $id)))); $entries = $this->Account->findLedgerEntriesRelatedToAccount ($customer['Customer']['account_id'], $this->Account->securityDepositAccountID(), true, null, $link); foreach ($customer['Lease'] AS $lease) { $ledger_entries = $this->Lease->findSecurityDeposits($lease['id'], $link); $this->statsMerge($entries['summary'], $ledger_entries['summary']); $entries['Entries'] = array_merge($entries['Entries'], $ledger_entries['Entries']); } /* pr(array('function' => 'Customer::findSecurityDeposits', */ /* 'args' => compact('id', 'link'), */ /* 'vars' => compact('customer'), */ /* 'return' => compact('entries'), */ /* )); */ return $entries; } /************************************************************************** ************************************************************************** ************************************************************************** * function: findUnreconciledLedgerEntries * - Returns ledger entries that are not yet reconciled * (such as charges not paid). */ function findUnreconciledLedgerEntries($id = null, $fundamental_type = null) { $customer = $this->find('first', array('contain' => array('Lease' => array('fields' => array('id'))), 'fields' => array('account_id'), 'conditions' => array(array('Customer.id' => $id)))); $unreconciled = $this->Account->findUnreconciledLedgerEntries ($customer['Customer']['account_id'], $fundamental_type); foreach ($customer['Lease'] AS $lease) { $unrec = $this->Lease->findUnreconciledLedgerEntries($lease['id'], $fundamental_type); foreach (array('debit', 'credit', 'entries') AS $type) { if (!isset($unreconciled[$type])) continue; if ($type == 'entries') { $left = &$unreconciled; $right = &$unrec; } else { $left = &$unreconciled[$type]; $right = &$unrec[$type]; } $left['entries'] = array_merge($left['entries'], $right['entries']); $left['balance'] += $right['balance']; } /* if ($fundamental_type) { */ /* $unreconciled['entries'] */ /* = array_merge($unreconciled['entries'], $unrec['entries']); */ /* } */ /* else { */ /* foreach (array_keys($unreconciled) AS $type) { */ /* $unreconciled[$type]['entries'] */ /* = array_merge($unreconciled[$type]['entries'], */ /* $unrec[$type]['entries']); */ /* $unreconciled['balance'] += $unrec['balance']; */ /* } */ /* } */ /* $balance = $unreconciled['balance']; */ /* $unreconciled = array_merge_recursive */ /* (array_diff_key($unreconciled, array('balance'=>1)), */ /* $this->Lease->findUnreconciledLedgerEntries($lease['id'])); */ /* $unreconciled['balance'] += $balance; */ } return $unreconciled; } /************************************************************************** ************************************************************************** ************************************************************************** * function: reconcileNewLedgerEntry * - Returns which ledger entries a new credit/debit would * reconcile, and how much. * * - REVISIT 20090617 * This should be subject to different algorithms, such * as apply to oldest charges first, newest first, to fees * before rent, etc. Until we get there, I'll hardcode * whatever algorithm is simplest. */ function reconcileNewLedgerEntry($id, $fund, $amount) { $customer = $this->find('first', array('contain' => array('Lease' => array('fields' => array('id'))), 'fields' => array('account_id'), 'conditions' => array(array('Customer.id' => $id)))); $reconciled = $this->Account->reconcileNewLedgerEntry ($customer['Customer']['account_id'], $fund, $amount); foreach ($customer['Lease'] AS $lease) { $rec = $this->Lease->reconcileNewLedgerEntry($lease['id'], $fund, $reconciled['unapplied']); //pr(compact('reconciled', 'rec')); foreach (array('debit', 'credit', 'entries') AS $type) { if (!isset($reconciled[$type])) continue; if ($type == 'entries') { $left = &$reconciled; $right = &$rec; } else { $left = &$reconciled[$type]; $right = &$rec[$type]; } //pr(compact('type', 'left', 'right')); $left['entries'] = array_merge($left['entries'], $right['entries']); $left['balance'] += $right['balance']; $left['applied'] += $right['applied']; $left['unapplied'] = $right['unapplied']; } } /* foreach ($customer['Lease'] AS $lease) { */ /* $unapplied = $unreconciled['unapplied']; */ /* $balance = $unreconciled['balance']; */ /* $unreconciled = array_merge_recursive */ /* (array_diff_key($unreconciled, array('unapplied'=>1, 'balance'=>1)), */ /* $this->Lease->reconcileNewLedgerEntry($lease['id'], */ /* $fund, */ /* $unreconciled['unapplied'])); */ /* $unreconciled['balance'] += $balance; */ /* } */ return $reconciled; } /************************************************************************** ************************************************************************** ************************************************************************** * function: details * - Returns detail information for the customer */ function details($id = null) { // Query the DB for need information. $customer = $this->find ('first', array ('contain' => array (// Models 'Contact' => array(// Models 'ContactPhone', 'ContactEmail', 'ContactAddress', ), 'Account', 'Lease' => array('Unit' => array('order' => array('sort_order'), 'fields' => array('id', 'name'), ), ), ), 'conditions' => array('Customer.id' => $id), )); // Add the lease balance to each lease. foreach ($customer['Lease'] AS &$lease) { $stats = $this->Lease->stats($lease['id']); $lease['balance'] = $stats['Account']['Ledger']['balance']; } // Figure out the outstanding balance of the current lease. $customer['stats'] = $this->stats($id); // Figure out the total security deposit for the current lease. $customer['deposits'] = $this->findSecurityDeposits($id); // Add statistics into the customer account. $customer['Account'] = array_merge($customer['Account'], $customer['stats']['Account']['Ledger']); return $customer; } /************************************************************************** ************************************************************************** ************************************************************************** * function: stats * - Returns summary data from the requested customer. */ function stats($id = null) { if (!$id) return null; // Get the basic information necessary $customer = $this->find('first', array('contain' => array('Account' => array ('fields' => array('Account.id')), 'Lease' => array ('fields' => array('Lease.id')) ), 'conditions' => array (array('Customer.id' => $id)))); // Get stats from the customer account, and each lease $stats['Account'] = $this->Account->stats($customer['Account']['id']); foreach ($customer['Lease'] AS $lease) { $this->statsMerge($stats['Lease'], $this->Lease->stats($lease['id'])); } // Merge the stats from both the customer specific account, as // well as the leases. This will provide current customer standing. $this->statsMerge($stats, $stats['Account']['Ledger']); $this->statsMerge($stats, $stats['Lease']['Account']['Ledger']); return $stats; } } ?>