Files
pmgr/models/customer.php
abijah 65acd0e181 Added routines to reconcile a new ledger entry against unreconciled entries. I haven't tested it robustly, but it seems to work on the surface at least.
git-svn-id: file:///svn-source/pmgr/branches/ledger_transactions_20090605/site@161 97e9348a-65ac-dc4b-aefc-98561f571b83
2009-06-17 18:40:39 +00:00

286 lines
9.1 KiB
PHP

<?php
class Customer extends AppModel {
var $name = 'Customer';
var $validate = array(
'id' => 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 <AP> 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;
}
}
?>