I'm still in the middle of moving onto a ledger based system. However, I'm am now changing how transactions and entries relate back to the customer. I'll be using a ledger for each lease (for rent, late charges, security deposits, etc), and a ledger for each customer (for POS, non-specific deposits such as reservations or covering mulitple units, bad debt writeoff, and possibly customer credits, when not obviously lease specific). This coming change might not be in the right direction, so I want to capture the work as is right now. This change set is not fully functional. Many operations do work, but there are obviously transaction problems with units and customers.

git-svn-id: file:///svn-source/pmgr/branches/ledger_transactions_20090605/site@71 97e9348a-65ac-dc4b-aefc-98561f571b83
This commit is contained in:
abijah
2009-06-06 20:18:56 +00:00
parent ce24abc812
commit 677458e942
52 changed files with 2367 additions and 1469 deletions

View File

@@ -83,27 +83,51 @@ class AppModel extends Model {
// a really large number of rows. However, trying to untagle this
// without changing a bunch of core code is near impossible.
var $paginate_rows_save;
function paginate($conditions, $fields, $order, $limit, $page = 1, $recursive = null, $extra = null) {
//var $paginate_rows_save;
function paginate($conditions, $fields, $order, $limit, $page = 1, $recursive = null, &$extra = null) {
/* pr("paginate"); */
/* pr(array_merge(compact('conditions', 'fields', 'order', 'limit', 'page', 'recursive', 'extra'))); */
if ($page > 1 && isset($limit))
$offset = ($page - 1) * $limit;
else
$offset = 0;
return array_slice($this->paginate_rows_save, $offset, $limit);
}
function paginateCount($conditions = null, $recursive = null, $extra = null) {
/* pr("paginateCount"); */
/* pr(array_merge(compact('conditions', 'recursive', 'extra'))); */
if (!isset($extra['results']))
die("Why isn't results set!?!");
$results = $extra['results'];
unset($extra['results']);
return array_slice($results, $offset, $limit);
}
function paginateCount($conditions = null, $recursive = null, &$extra = null) {
/* pr("paginateCount"); */
/* pr(compact('conditions', 'recursive', 'extra')); */
if (isset($extra['results'])) {
// Beauty! The results are already in!
// This happens if the user sets up a complex query
// and passes us the result to paginate.
$results = $extra['results'];
}
elseif (isset($extra['query'])) {
// Perform the query directly... forget all the find B.S.
$results = $this->query($extra['query']);
}
else {
if (!isset($recursive))
$recursive = $this->recursive;
$parameters = array_merge(compact('conditions', 'recursive'), $extra);
$results = $this->find('all', $parameters);
}
$this->paginate_rows_save = $results;
return count($this->paginate_rows_save);
//$this->paginate_rows_save = $results;
//return count($this->paginate_rows_save);
if (!isset($extra['results']))
$extra['results'] = $results;
return count($results);
}
}

View File

@@ -0,0 +1,265 @@
<?php
class AccountsController extends AppController {
var $paginate = array
('limit' => 100,
'link' =>
array(// Models
'CurrentLedger' => array
(// Models
'LedgerEntry' =>
array('fields' =>
array('SUM(IF(LedgerEntry.debit_ledger_id = CurrentLedger.id, LedgerEntry.amount, 0)) AS debits',
'SUM(IF(LedgerEntry.credit_ledger_id = CurrentLedger.id, LedgerEntry.amount, 0)) AS credits',
"SUM(IF(Account.type IN ('ASSET', 'EXPENSE'),
IF(LedgerEntry.debit_ledger_id = CurrentLedger.id, 1, -1),
IF(LedgerEntry.credit_ledger_id = CurrentLedger.id, 1, -1)
)* LedgerEntry.amount) AS balance",
'COUNT(LedgerEntry.id) AS entries'),
'conditions' =>
array('OR' =>
array('LedgerEntry.debit_ledger_id = CurrentLedger.id',
'LedgerEntry.credit_ledger_id = CurrentLedger.id'),
),
),
),
),
'group' => 'Account.id',
'order' => array('Account.name' => 'ASC'));
var $uses = array('Account', 'LedgerEntry');
var $sidemenu_links =
array(array('name' => 'Accounts', 'header' => true),
array('name' => 'All', 'url' => array('controller' => 'accounts', 'action' => 'all')),
array('name' => 'Asset', 'url' => array('controller' => 'accounts', 'action' => 'asset')),
array('name' => 'Liability', 'url' => array('controller' => 'accounts', 'action' => 'liability')),
array('name' => 'Equity', 'url' => array('controller' => 'accounts', 'action' => 'equity')),
array('name' => 'Income', 'url' => array('controller' => 'accounts', 'action' => 'income')),
array('name' => 'Expense', 'url' => array('controller' => 'accounts', 'action' => 'expense')),
);
/**************************************************************************
**************************************************************************
**************************************************************************
* override: sideMenuLinks
* - Generates controller specific links for the side menu
*/
function sideMenuLinks() {
return array_merge(parent::sideMenuLinks(), $this->sidemenu_links);
}
/**************************************************************************
**************************************************************************
**************************************************************************
* action: index
* - Lists all accounts
*/
function index() {
$this->all();
}
/**************************************************************************
**************************************************************************
**************************************************************************
* action: asset
* - Lists all asset accounts
*/
function asset() {
$title = 'Asset Accounts';
$this->set('title', $title); $this->set('heading', $title);
$this->set('accounts', $this->paginate(array('Account.type' => 'ASSET')));
$this->render('index');
}
/**************************************************************************
**************************************************************************
**************************************************************************
* action: liability
* - Lists all liability accounts
*/
function liability() {
$title = 'Liability Accounts';
$this->set('title', $title); $this->set('heading', $title);
$this->set('accounts', $this->paginate(array('Account.type' => 'LIABILITY')));
$this->render('index');
}
/**************************************************************************
**************************************************************************
**************************************************************************
* action: equity
* - Lists all equity accounts
*/
function equity() {
$title = 'Equity Accounts';
$this->set('title', $title); $this->set('heading', $title);
$this->set('accounts', $this->paginate(array('Account.type' => 'EQUITY')));
$this->render('index');
}
/**************************************************************************
**************************************************************************
**************************************************************************
* action: income
* - Lists all income accounts
*/
function income() {
$title = 'Income Accounts';
$this->set('title', $title); $this->set('heading', $title);
$this->set('accounts', $this->paginate(array('Account.type' => 'INCOME')));
$this->render('index');
}
/**************************************************************************
**************************************************************************
**************************************************************************
* action: expense
* - Lists all expense accounts
*/
function expense() {
$title = 'Expense Accounts';
$this->set('title', $title); $this->set('heading', $title);
$this->set('accounts', $this->paginate(array('Account.type' => 'EXPENSE')));
$this->render('index');
}
/**************************************************************************
**************************************************************************
**************************************************************************
* action: all
* - Lists all accounts
*/
function all() {
$title = 'All Accounts';
$this->set('title', $title); $this->set('heading', $title);
$this->set('accounts', $this->paginate());
$this->render('index');
}
/**************************************************************************
**************************************************************************
**************************************************************************
* action: view
* - Displays information about a specific account
*/
function view($id = null) {
if (!$id) {
$this->Session->setFlash(__('Invalid Item.', true));
$this->redirect(array('action'=>'index'));
}
/* $this->Account->bindModel(array('hasMany' => array */
/* ('LedgerEntry' => array */
/* ('className' => 'LedgerEntry', */
/* 'foreignKey' => false, */
/* 'finderQuery' => 'SELECT `LedgerEntry`.* */
/* FROM pmgr_entries AS `LedgerEntry` */
/* LEFT JOIN pmgr_transactions AS `Transaction` */
/* ON `Transaction`.id = `LedgerEntry`.transaction_id */
/* WHERE LedgerEntry.debit_ledger_id = ({$__cakeID__$}) */
/* OR LedgerEntry.credit_ledger_id = ({$__cakeID__$}) */
/* ORDER BY Transaction.stamp', */
/* )))); */
/* $this->Account->Behaviors->attach('Containable'); */
/* $this->Account->Contain(array('LedgerEntry' => array */
/* ( */
/* // Models */
/* 'Transaction' => array */
/* ( */
/* // Models */
/* 'Customer', */
/* )), */
/* )); */
/* } */
/* $account = $this->Account->read(null, $id); */
$this->Account->recursive = -1;
$account = $this->Account->read(null, $id);
$account['Ledger'] = $this->Account->find
('all', array
('link' => array
(// Models
'Ledger' => array
(// Models
'LedgerEntry' =>
array('fields' =>
array('SUM(IF(LedgerEntry.debit_ledger_id = Ledger.id, LedgerEntry.amount, 0)) AS debits',
'SUM(IF(LedgerEntry.credit_ledger_id = Ledger.id, LedgerEntry.amount, 0)) AS credits',
"SUM(IF(Account.type IN ('ASSET', 'EXPENSE'),
IF(LedgerEntry.debit_ledger_id = Ledger.id, 1, -1),
IF(LedgerEntry.credit_ledger_id = Ledger.id, 1, -1)
) * LedgerEntry.amount) AS balance",
'COUNT(LedgerEntry.id) AS entries'),
'conditions' =>
array('OR' =>
array('LedgerEntry.debit_ledger_id = Ledger.id',
'LedgerEntry.credit_ledger_id = Ledger.id'),
),
),
),
),
'fields' => array(),
'conditions' => array('Account.id' => $id),
'order' => 'Ledger.name',
'group' => 'Ledger.id',
'limit' => 4,
));
$account['CurrentLedger'] = array_shift($this->Account->Ledger->find
('first', array
('link' => array
(// Models
'Account' => array('fields' => array()),
'LedgerEntry' =>
array('fields' =>
array("SUM(IF(LedgerEntry.debit_ledger_id = Ledger.id, LedgerEntry.amount, 0)) AS debits",
"SUM(IF(LedgerEntry.credit_ledger_id = Ledger.id, LedgerEntry.amount, 0)) AS credits",
"SUM(IF(Account.type IN ('ASSET', 'EXPENSE'),
IF(LedgerEntry.debit_ledger_id = Ledger.id, 1, -1),
IF(LedgerEntry.credit_ledger_id = Ledger.id, 1, -1)
) * LedgerEntry.amount) AS balance",
'COUNT(LedgerEntry.id) AS entries'),
'conditions' =>
array('OR' =>
array("LedgerEntry.debit_ledger_id = Ledger.id",
"LedgerEntry.credit_ledger_id = Ledger.id"),
),
),
),
'fields' => array(),
'conditions' => array(array('Ledger.account_id' => $id),
'NOT' => array('Ledger.closed')),
//'order' => 'Ledger.name',
'group' => 'Ledger.id',
//'limit' => 4,
)));
//pr($account);
$balance = $account['CurrentLedger']['balance'];
$title = 'Account: ' . $account['Account']['name'];
$this->set(compact('account', 'title', 'balance'));
}
}

View File

@@ -0,0 +1,244 @@
<?php
class AccountsController extends AppController {
var $paginate = array
('limit' => 100,
'link' =>
array(// Models
'CurrentLedger' => array
(// Models
'LedgerEntry' =>
array('fields' =>
array('SUM(IF(LedgerEntry.debit_account_id = Account.id, LedgerEntry.amount, 0)) AS debits',
'SUM(IF(LedgerEntry.credit_account_id = Account.id, LedgerEntry.amount, 0)) AS credits',
"SUM(IF(Account.type IN ('ASSET', 'EXPENSE'),
IF(LedgerEntry.debit_account_id = Account.id, 1, -1),
IF(LedgerEntry.credit_account_id = Account.id, 1, -1)
)* LedgerEntry.amount) AS balance",
'COUNT(LedgerEntry.id) AS entries'),
'conditions' =>
array('OR' =>
array('LedgerEntry.debit_account_id = Account.id',
'LedgerEntry.credit_account_id = Account.id'),
),
),
),
'group' => 'Account.id',
'order' => array('Account.name' => 'ASC'));
var $sidemenu_links =
array(array('name' => 'Accounts', 'header' => true),
array('name' => 'All', 'url' => array('controller' => 'accounts', 'action' => 'all')),
array('name' => 'Asset', 'url' => array('controller' => 'accounts', 'action' => 'asset')),
array('name' => 'Liability', 'url' => array('controller' => 'accounts', 'action' => 'liability')),
array('name' => 'Equity', 'url' => array('controller' => 'accounts', 'action' => 'equity')),
array('name' => 'Income', 'url' => array('controller' => 'accounts', 'action' => 'income')),
array('name' => 'Expense', 'url' => array('controller' => 'accounts', 'action' => 'expense')),
);
/**************************************************************************
**************************************************************************
**************************************************************************
* override: sideMenuLinks
* - Generates controller specific links for the side menu
*/
function sideMenuLinks() {
return array_merge(parent::sideMenuLinks(), $this->sidemenu_links);
}
/**************************************************************************
**************************************************************************
**************************************************************************
* action: index
* - Lists all accounts
*/
function index() {
$this->all();
}
/**************************************************************************
**************************************************************************
**************************************************************************
* action: asset
* - Lists all asset accounts
*/
function asset() {
$title = 'Asset Accounts';
$this->set('title', $title); $this->set('heading', $title);
$this->set('accounts', $this->paginate(array('Account.type' => 'ASSET')));
$this->render('index');
}
/**************************************************************************
**************************************************************************
**************************************************************************
* action: liability
* - Lists all liability accounts
*/
function liability() {
$title = 'Liability Accounts';
$this->set('title', $title); $this->set('heading', $title);
$this->set('accounts', $this->paginate(array('Account.type' => 'LIABILITY')));
$this->render('index');
}
/**************************************************************************
**************************************************************************
**************************************************************************
* action: equity
* - Lists all equity accounts
*/
function equity() {
$title = 'Equity Accounts';
$this->set('title', $title); $this->set('heading', $title);
$this->set('accounts', $this->paginate(array('Account.type' => 'EQUITY')));
$this->render('index');
}
/**************************************************************************
**************************************************************************
**************************************************************************
* action: income
* - Lists all income accounts
*/
function income() {
$title = 'Income Accounts';
$this->set('title', $title); $this->set('heading', $title);
$this->set('accounts', $this->paginate(array('Account.type' => 'INCOME')));
$this->render('index');
}
/**************************************************************************
**************************************************************************
**************************************************************************
* action: expense
* - Lists all expense accounts
*/
function expense() {
$title = 'Expense Accounts';
$this->set('title', $title); $this->set('heading', $title);
$this->set('accounts', $this->paginate(array('Account.type' => 'EXPENSE')));
$this->render('index');
}
/**************************************************************************
**************************************************************************
**************************************************************************
* action: all
* - Lists all accounts
*/
function all() {
$title = 'All Accounts';
$this->set('title', $title); $this->set('heading', $title);
$this->set('accounts', $this->paginate());
$this->render('index');
}
/**************************************************************************
**************************************************************************
**************************************************************************
* action: view
* - Displays information about a specific account
*/
function view($id = null) {
if (!$id) {
$this->Session->setFlash(__('Invalid Item.', true));
$this->redirect(array('action'=>'index'));
}
/* $this->Account->bindModel(array('hasMany' => array */
/* ('LedgerEntry' => array */
/* ('className' => 'LedgerEntry', */
/* 'foreignKey' => false, */
/* 'finderQuery' => 'SELECT `LedgerEntry`.* */
/* FROM pmgr_entries AS `LedgerEntry` */
/* LEFT JOIN pmgr_transactions AS `Transaction` */
/* ON `Transaction`.id = `LedgerEntry`.transaction_id */
/* WHERE LedgerEntry.debit_account_id = ({$__cakeID__$}) */
/* OR LedgerEntry.credit_account_id = ({$__cakeID__$}) */
/* ORDER BY Transaction.stamp', */
/* )))); */
/* $this->Account->Behaviors->attach('Containable'); */
/* $this->Account->Contain(array('LedgerEntry' => array */
/* ( */
/* // Models */
/* 'Transaction' => array */
/* ( */
/* // Models */
/* 'Customer', */
/* )), */
/* )); */
/* } */
/* $account = $this->Account->read(null, $id); */
$this->Account->recursive = -1;
$account = $this->Account->read(null, $id);
if (in_array($account['Account']['type'], array('ASSET', 'EXPENSE')))
$account_type = 'debit';
else
$account_type = 'credit';
$ledger_id = $account['current_ledger_id'];
$account['CurrentLedger']['LedgerEntry'] =
$this->Account->Ledger->LedgerEntry->find
('all',
array('link' => array
(// Models
'fields' =>
array('id', 'name', 'comment',
"IF(LedgerEntry.debit_ledger_id = $id, LedgerEntry.amount, NULL) AS debit",
"IF(LedgerEntry.credit_ledger_id = $id, LedgerEntry.amount, NULL) AS credit",
"(IF(LedgerEntry.{$account_type}_ledger_id = $id, 1, -1)
* LedgerEntry.amount) AS balance"),
'conditions' =>
array('OR' =>
array('LedgerEntry.debit_ledger_id = Account.id',
'LedgerEntry.credit_ledger_id = Account.id'),
'Transaction' =>
array(// Models
'Customer',
)),
'conditions' => array('OR' =>
array("LedgerEntry.debit_account_id = $id",
"LedgerEntry.credit_account_id = $id")),
'order' => array('Transaction.stamp'),
//'limit' => 15,
//'limit' => 2,
));
//pr($account);
$balance = 0;
foreach($account['LedgerEntry'] AS &$entry) {
if (isset($entry[0]))
$entry = array_merge($entry[0], array_diff_key($entry, array(0)));
$balance += $entry['balance'];
}
$title = 'Account: ' . $account['Account']['name'];
$this->set(compact('account', 'title', 'balance'));
}
}

View File

@@ -7,10 +7,10 @@ class ContactsController extends AppController {
'Contact.first_name' => 'ASC'));
var $sidemenu_links =
array(array('name' => 'Tenants', 'header' => true),
array('name' => 'Current', 'url' => array('controller' => 'contacts', 'action' => 'current')),
array('name' => 'Past', 'url' => array('controller' => 'contacts', 'action' => 'past')),
array('name' => 'All Tenants', 'url' => array('controller' => 'contacts', 'action' => 'tenants')),
array(array('name' => 'Contacts', 'header' => true),
//array('name' => 'Current', 'url' => array('controller' => 'contacts', 'action' => 'current')),
//array('name' => 'Past', 'url' => array('controller' => 'contacts', 'action' => 'past')),
//array('name' => 'All Tenants', 'url' => array('controller' => 'contacts', 'action' => 'tenants')),
array('name' => 'All Contacts', 'url' => array('controller' => 'contacts', 'action' => 'all')),
);
@@ -154,50 +154,12 @@ class ContactsController extends AppController {
'ContactPhone',
'ContactEmail',
'ContactAddress',
'Lease' =>
array('order' => 'movein_date',
'conditions' => array('Lease.lease_date IS NOT NULL',
'ContactsLease.type !=' => 'ALTERNATE'),
// Models
'Unit' =>
array('order' => array('sort_order'),
'fields' => array('id', 'name'),
),
'Charge' =>
array('order' => array('charge_date'),
// Models
'ChargeType',
'Receipt',
)
)
)
'Customer')
);
$contact = $this->Contact->read(null, $id);
$outstanding_deposit = 0;
$outstanding_balance = 0;
foreach($contact['Lease'] AS $lease) {
foreach($lease['Charge'] AS $charge) {
$outstanding_balance += $charge['total'];
foreach ($charge['Receipt'] AS $receipt) {
$outstanding_balance -= $receipt['ChargesReceipt']['amount'];
// REVISIT <AP> 20090530:
// Using hardcoded value for security deposit...
// That can't be good!
if ($charge['charge_type_id'] == 1)
$outstanding_deposit += $receipt['ChargesReceipt']['amount'];
}
}
}
$this->sidemenu_links[] =
array('name' => 'Operations', 'header' => true);
$this->sidemenu_links[] =
array('name' => 'Move-Out', 'url' => array('controller' => 'units', 'action' => 'move-out'));
//pr($contact);
$title = $contact['Contact']['display_name'];
$this->set(compact('contact', 'title',
'outstanding_balance',
'outstanding_deposit'));
$this->set(compact('contact', 'title'));
}
}

View File

@@ -0,0 +1,177 @@
<?php
class CustomersController extends AppController {
var $paginate = array('limit' => 100,
'group' => 'Customer.id',
'order' => array('Customer.name' => 'ASC'));
var $sidemenu_links =
array(array('name' => 'Tenants', 'header' => true),
array('name' => 'Current', 'url' => array('controller' => 'customers', 'action' => 'current')),
array('name' => 'Past', 'url' => array('controller' => 'customers', 'action' => 'past')),
array('name' => 'All', 'url' => array('controller' => 'customers', 'action' => 'all')),
);
/**************************************************************************
**************************************************************************
**************************************************************************
* override: sideMenuLinks
* - Generates controller specific links for the side menu
*/
function sideMenuLinks() {
return array_merge(parent::sideMenuLinks(), $this->sidemenu_links);
}
/**************************************************************************
**************************************************************************
**************************************************************************
* action: index
* - Lists all current tenants
*/
function index() {
$this->current();
}
/**************************************************************************
**************************************************************************
**************************************************************************
* action: current
* - Lists all current tenants
*/
function current() {
$this->paginate = array_merge
($this->paginate,
array('link' =>
array(// Models
'Lease' =>
array('fields' => array(),
'type' => 'INNER',
),
),
'conditions' => array('Lease.close_date IS NULL')
));
$title = 'Current Tenants';
$this->set('title', $title); $this->set('heading', $title);
$this->set('customers', $this->paginate());
$this->render('index');
}
/**************************************************************************
**************************************************************************
**************************************************************************
* action: past
* - Lists all past tenants
*/
function past() {
$this->paginate = array_merge
($this->paginate,
array('link' =>
array(// Models
'Lease' =>
array('fields' => array(),
'type' => 'INNER',
),
),
'conditions' => array('Lease.close_date IS NOT NULL')
));
$title = 'Past Tenants';
$this->set('title', $title); $this->set('heading', $title);
$this->set('customers', $this->paginate());
$this->render('index');
}
/**************************************************************************
**************************************************************************
**************************************************************************
* action: all
* - Lists all customers, including non-tenants
*/
function all() {
$title = 'All Customers';
$this->set('title', $title); $this->set('heading', $title);
$this->set('customers', $this->paginate());
$this->render('index');
}
/**************************************************************************
**************************************************************************
**************************************************************************
* action: view
* - Displays information about a specific customer
*/
function view($id = null) {
if (!$id) {
$this->Session->setFlash(__('Invalid Item.', true));
$this->redirect(array('action'=>'index'));
}
$this->Customer->Behaviors->attach('Containable');
$this->Customer->contain
(array(// Models
'Contact' =>
array(// Models
'ContactPhone',
'ContactEmail',
'ContactAddress',
),
'Transaction' =>
array('order' => array('stamp'),
// Models
'Entry' =>
array(// Models
'DebitAccount',
'CreditAccount'),
),
'Lease' =>
array('order' => 'movein_date',
'conditions' => array('Lease.lease_date IS NOT NULL'),
// Models
'Unit' =>
array('order' => array('sort_order'),
'fields' => array('id', 'name'),
),
),
)
);
$customer = $this->Customer->read(null, $id);
//pr($customer);
$outstanding_deposit = 0;
$outstanding_balance = 0;
foreach($customer['Transaction'] AS $transaction) {
foreach($transaction['Entry'] AS $entry) {
if ($entry['DebitAccount']['name'] === 'A/R')
$outstanding_balance += $entry['amount'];
if ($entry['CreditAccount']['name'] === 'A/R')
$outstanding_balance -= $entry['amount'];
if ($entry['DebitAccount']['name'] === 'Security Deposit')
$outstanding_deposit -= $entry['amount'];
if ($entry['CreditAccount']['name'] === 'Security Deposit')
$outstanding_deposit += $entry['amount'];
}
}
$this->sidemenu_links[] =
array('name' => 'Operations', 'header' => true);
$this->sidemenu_links[] =
array('name' => 'Move-Out', 'url' => array('controller' => 'units', 'action' => 'move-out'));
$title = $customer['Customer']['name'];
$this->set(compact('customer', 'title',
'outstanding_balance',
'outstanding_deposit'));
}
}

View File

@@ -0,0 +1,55 @@
<?php
class LedgerEntriesController extends AppController {
var $paginate = array('limit' => 100,
'group' => 'Entry.id',
'order' => array('Entry.stamp' => 'ASC'));
var $sidemenu_links =
array(array('name' => 'Entries', 'header' => true),
array('name' => 'Cleared', 'url' => array('controller' => 'ledger_entries', 'action' => 'cleared')),
array('name' => 'Unresolved', 'url' => array('controller' => 'ledger_entries', 'action' => 'unresolved')),
);
/**************************************************************************
**************************************************************************
**************************************************************************
* override: sideMenuLinks
* - Generates controller specific links for the side menu
*/
function sideMenuLinks() {
return array_merge(parent::sideMenuLinks(), $this->sidemenu_links);
}
/**************************************************************************
**************************************************************************
**************************************************************************
* action: view
* - Displays information about a specific entry
*/
function view($id = null) {
if (!$id) {
$this->Session->setFlash(__('Invalid Item.', true));
$this->redirect(array('controller' => 'accounts', 'action'=>'index'));
}
$this->LedgerEntry->Behaviors->attach('Containable');
$this->LedgerEntry->contain
(array(// Models
'MonetarySource' => array('MonetaryType'),
'Transaction',
'DebitLedger',
'CreditLedger',
)
);
$entry = $this->LedgerEntry->read(null, $id);
pr($entry);
$title = "Entry #{$entry['LedgerEntry']['id']} ({$entry['LedgerEntry']['name']})";
$this->set(compact('entry', 'title'));
//$this->autoRender = false;
}
}

View File

@@ -0,0 +1,188 @@
<?php
class LedgersController extends AppController {
var $paginate = array
('limit' => 100,
'link' =>
array(// Models
'Account',
'LedgerEntry' =>
array('fields' =>
array('SUM(IF(LedgerEntry.debit_ledger_id = Ledger.id, LedgerEntry.amount, 0)) AS debits',
'SUM(IF(LedgerEntry.credit_ledger_id = Ledger.id, LedgerEntry.amount, 0)) AS credits',
"SUM(IF(Account.type IN ('ASSET', 'EXPENSE'),
IF(LedgerEntry.debit_ledger_id = Ledger.id, 1, -1),
IF(LedgerEntry.credit_ledger_id = Ledger.id, 1, -1)) * LedgerEntry.amount) AS balance",
'COUNT(LedgerEntry.id) AS entries'),
'conditions' =>
array('OR' =>
array('LedgerEntry.debit_ledger_id = Ledger.id',
'LedgerEntry.credit_ledger_id = Ledger.id'),
),
),
),
'group' => 'Ledger.id',
'order' => array('Ledger.name' => 'ASC'));
var $uses = array('Ledger', 'LedgerEntry');
var $sidemenu_links =
array(array('name' => 'Ledgers', 'header' => true),
array('name' => 'Current', 'url' => array('controller' => 'ledgers', 'action' => 'current')),
array('name' => 'Closed', 'url' => array('controller' => 'ledgers', 'action' => 'closed')),
array('name' => 'All', 'url' => array('controller' => 'ledgers', 'action' => 'all')),
);
/**************************************************************************
**************************************************************************
**************************************************************************
* override: sideMenuLinks
* - Generates controller specific links for the side menu
*/
function sideMenuLinks() {
return array_merge(parent::sideMenuLinks(), $this->sidemenu_links);
}
/**************************************************************************
**************************************************************************
**************************************************************************
* action: index
*/
function index() {
$this->current();
}
/**************************************************************************
**************************************************************************
**************************************************************************
* action: current
* - Lists all current ledgers
*/
function current() {
$title = 'Current Ledgers';
$this->set('title', $title); $this->set('heading', $title);
$this->set('ledgers', $this->paginate(null, array('NOT' => array('Ledger.closed'))));
$this->render('index');
}
/**************************************************************************
**************************************************************************
**************************************************************************
* action: closed
* - Lists all closed ledgers
*/
function closed() {
$title = 'Closed Ledgers';
$this->set('title', $title); $this->set('heading', $title);
$this->set('ledgers', $this->paginate(null, array('Ledger.closed')));
$this->render('index');
}
/**************************************************************************
**************************************************************************
**************************************************************************
* action: all
* - Lists all ledgers
*/
function all() {
$title = 'All Ledgers';
$this->set('title', $title); $this->set('heading', $title);
$this->set('ledgers', $this->paginate());
$this->render('index');
}
/**************************************************************************
**************************************************************************
**************************************************************************
* action: view
* - Displays information about a specific ledger
*/
function view($id = null) {
if (!$id) {
$this->Session->setFlash(__('Invalid Item.', true));
$this->redirect(array('action'=>'index'));
}
/* $this->Ledger->bindModel(array('hasMany' => array */
/* ('LedgerEntry' => array */
/* ('className' => 'LedgerEntry', */
/* 'foreignKey' => false, */
/* 'finderQuery' => 'SELECT `LedgerEntry`.* */
/* FROM pmgr_entries AS `LedgerEntry` */
/* LEFT JOIN pmgr_transactions AS `Transaction` */
/* ON `Transaction`.id = `LedgerEntry`.transaction_id */
/* WHERE LedgerEntry.debit_ledger_id = ({$__cakeID__$}) */
/* OR LedgerEntry.credit_ledger_id = ({$__cakeID__$}) */
/* ORDER BY Transaction.stamp', */
/* )))); */
/* $this->Ledger->Behaviors->attach('Containable'); */
/* $this->Ledger->Contain(array('LedgerEntry' => array */
/* ( */
/* // Models */
/* 'Transaction' => array */
/* ( */
/* // Models */
/* 'Customer', */
/* )), */
/* )); */
/* } */
/* $ledger = $this->Ledger->read(null, $id); */
$this->Ledger->Behaviors->attach('Containable');
$this->Ledger->Contain(array('Account'));
$ledger = $this->Ledger->read(null, $id);
//pr($ledger);
if (in_array($ledger['Account']['type'], array('ASSET', 'EXPENSE')))
$ledger_type = 'debit';
else
$ledger_type = 'credit';
$ledger['LedgerEntry'] = $this->LedgerEntry->find
('all',
array('link' => array
(// Models
'Transaction' =>
array(// Models
'Customer',
)),
'fields' =>
array('id', 'name', 'comment',
"IF(LedgerEntry.debit_ledger_id = $id, LedgerEntry.amount, NULL) AS debit",
"IF(LedgerEntry.credit_ledger_id = $id, LedgerEntry.amount, NULL) AS credit",
"(IF(LedgerEntry.{$ledger_type}_ledger_id = $id, 1, -1) * LedgerEntry.amount) AS balance"),
'conditions' => array('OR' =>
array("LedgerEntry.debit_ledger_id = $id",
"LedgerEntry.credit_ledger_id = $id")),
'order' => array('Transaction.stamp'),
//'limit' => 15,
//'limit' => 2,
));
//pr($ledger);
$balance = 0;
foreach($ledger['LedgerEntry'] AS &$entry) {
if (isset($entry[0]))
$entry = array_merge($entry[0], array_diff_key($entry, array(0)));
$balance += $entry['balance'];
}
$title = 'Ledger: ' . $ledger['Ledger']['name'];
$this->set(compact('ledger', 'title', 'balance'));
}
}

View File

@@ -1,118 +0,0 @@
<?php
class PaymentsController extends AppController {
var $paginate = array('limit' => 100,
'group' => 'Payment.id',
'order' => array('Payment.id' => 'ASC'));
var $sidemenu_links =
array(array('name' => 'Payments', 'header' => true),
array('name' => 'Cleared', 'url' => array('controller' => 'payments', 'action' => 'cleared')),
array('name' => 'Unresolved', 'url' => array('controller' => 'payments', 'action' => 'unresolved')),
);
/**************************************************************************
**************************************************************************
**************************************************************************
* override: sideMenuLinks
* - Generates controller specific links for the side menu
*/
function sideMenuLinks() {
return array_merge(parent::sideMenuLinks(), $this->sidemenu_links);
}
/**************************************************************************
**************************************************************************
**************************************************************************
* action: index
* - Lists all payments
*/
function index() {
$this->all();
}
/**************************************************************************
**************************************************************************
**************************************************************************
* action: cleared
* - Lists cleared payments
*/
function cleared() {
$this->all();
}
/**************************************************************************
**************************************************************************
**************************************************************************
* action: unresolved
* - Lists unresolved payments
*/
function unresolved() {
$this->all();
}
/**************************************************************************
**************************************************************************
**************************************************************************
* action: all
* - Lists all payments
*/
function all() {
$this->paginate = array_merge
($this->paginate,
array('link' =>
array(// Models
'PaymentType',
'Receipt',
),
));
$title = 'All Payments';
$this->set('title', $title); $this->set('heading', $title);
$this->set('payments', $this->paginate());
$this->render('index');
}
/**************************************************************************
**************************************************************************
**************************************************************************
* action: view
* - Displays information about a specific payment
*/
function view($id = null) {
if (!$id) {
$this->Session->setFlash(__('Invalid Item.', true));
$this->redirect(array('action'=>'index'));
}
$this->Payment->Behaviors->attach('Containable');
$this->Payment->contain
(array(// Models
'PaymentType',
'Receipt',
)
);
$payment = $this->Payment->read(null, $id);
//pr($payment);
/* $this->sidemenu_links[] = */
/* array('name' => 'Operations', 'header' => true); */
/* $this->sidemenu_links[] = */
/* array('name' => 'Move-Out', 'url' => array('controller' => 'payments', 'action' => 'move-out')); */
$title = 'Payment #' . $payment['Payment']['id'];
$this->set(compact('payment', 'title'));
}
}

View File

@@ -1,131 +0,0 @@
<?php
class ReceiptsController extends AppController {
var $paginate = array('limit' => 100,
'group' => 'Receipt.id',
'order' => array('Receipt.stamp' => 'ASC'));
var $sidemenu_links =
array(array('name' => 'Receipts', 'header' => true),
array('name' => 'Cleared', 'url' => array('controller' => 'receipts', 'action' => 'cleared')),
array('name' => 'Unresolved', 'url' => array('controller' => 'receipts', 'action' => 'unresolved')),
);
/**************************************************************************
**************************************************************************
**************************************************************************
* override: sideMenuLinks
* - Generates controller specific links for the side menu
*/
function sideMenuLinks() {
return array_merge(parent::sideMenuLinks(), $this->sidemenu_links);
}
/**************************************************************************
**************************************************************************
**************************************************************************
* action: index
* - Lists all receipts
*/
function index() {
$this->all();
}
/**************************************************************************
**************************************************************************
**************************************************************************
* action: cleared
* - Lists cleared receipts
*/
function cleared() {
$this->all();
}
/**************************************************************************
**************************************************************************
**************************************************************************
* action: unresolved
* - Lists unresolved receipts
*/
function unresolved() {
$this->all();
}
/**************************************************************************
**************************************************************************
**************************************************************************
* action: all
* - Lists all receipts
*/
function all() {
$this->paginate = array_merge
($this->paginate,
array('link' =>
array(// Models
'Charge',
'Payment'
),
));
$title = 'All Receipts';
$this->set('title', $title); $this->set('heading', $title);
$this->set('receipts', $this->paginate());
$this->render('index');
}
/**************************************************************************
**************************************************************************
**************************************************************************
* action: view
* - Displays information about a specific receipt
*/
function view($id = null) {
if (!$id) {
$this->Session->setFlash(__('Invalid Item.', true));
$this->redirect(array('action'=>'index'));
}
$this->Receipt->Behaviors->attach('Containable');
$this->Receipt->contain
(array(// Models
'Charge' => array(// Models
'Lease' => array('fields' => array('number')),
'ChargesReceipt',
'ChargeType'),
'Payment' => array(// Models
'PaymentType'),
)
);
$receipt = $this->Receipt->read(null, $id);
//pr($receipt);
$charge_amount = 0;
$payment_amount = 0;
foreach($receipt['Charge'] AS $charge)
$charge_amount += $charge['ChargesReceipt']['amount'];
foreach($receipt['Payment'] AS $payment)
$payment_amount += $payment['amount'];
/* $this->sidemenu_links[] = */
/* array('name' => 'Operations', 'header' => true); */
/* $this->sidemenu_links[] = */
/* array('name' => 'Move-Out', 'url' => array('controller' => 'receipts', 'action' => 'move-out')); */
$title = 'Receipt #' . $receipt['Receipt']['id'];
$this->set(compact('receipt', 'title',
'charge_amount',
'payment_amount'));
}
}

View File

@@ -1,14 +1,14 @@
<?php
class ChargesController extends AppController {
class TransactionsController extends AppController {
var $paginate = array('limit' => 100,
'group' => 'Charge.id',
'order' => array('Charge.charge_date' => 'ASC'));
'group' => 'Transaction.id',
'order' => array('Transaction.stamp' => 'ASC'));
var $sidemenu_links =
array(array('name' => 'Charges', 'header' => true),
array('name' => 'Cleared', 'url' => array('controller' => 'charges', 'action' => 'cleared')),
array('name' => 'Unresolved', 'url' => array('controller' => 'charges', 'action' => 'unresolved')),
array(array('name' => 'Transactions', 'header' => true),
array('name' => 'Cleared', 'url' => array('controller' => 'transactions', 'action' => 'cleared')),
array('name' => 'Unresolved', 'url' => array('controller' => 'transactions', 'action' => 'unresolved')),
);
@@ -27,7 +27,7 @@ class ChargesController extends AppController {
**************************************************************************
**************************************************************************
* action: index
* - Lists all charges
* - Lists all transactions
*/
function index() {
@@ -39,7 +39,7 @@ class ChargesController extends AppController {
**************************************************************************
**************************************************************************
* action: cleared
* - Lists cleared charges
* - Lists cleared transactions
*/
function cleared() {
@@ -51,7 +51,7 @@ class ChargesController extends AppController {
**************************************************************************
**************************************************************************
* action: unresolved
* - Lists unresolved charges
* - Lists unresolved transactions
*/
function unresolved() {
@@ -64,7 +64,7 @@ class ChargesController extends AppController {
**************************************************************************
**************************************************************************
* action: all
* - Lists all charges
* - Lists all transactions
*/
function all() {
@@ -72,15 +72,14 @@ class ChargesController extends AppController {
($this->paginate,
array('link' =>
array(// Models
'ChargeType',
'Receipt',
'Lease' => array('fields' => array('number'))
'Customer',
'LedgerEntry' => array('DebitLedger', 'CreditLedger')
),
));
$title = 'All Charges';
$title = 'All Transactions';
$this->set('title', $title); $this->set('heading', $title);
$this->set('charges', $this->paginate());
$this->set('transactions', $this->paginate());
$this->render('index');
}
@@ -89,7 +88,7 @@ class ChargesController extends AppController {
**************************************************************************
**************************************************************************
* action: view
* - Displays information about a specific charge
* - Displays information about a specific transaction
*/
function view($id = null) {
@@ -98,30 +97,33 @@ class ChargesController extends AppController {
$this->redirect(array('action'=>'index'));
}
$this->Charge->Behaviors->attach('Containable');
$this->Charge->contain
$this->Transaction->Behaviors->attach('Containable');
$this->Transaction->contain
(array(// Models
'ChargeType',
'Receipt',
'Lease' => array('fields' => array('number')),
'LedgerEntry' => array(//Models
'DebitLedger',
'CreditLedger',
),
)
);
$charge = $this->Charge->read(null, $id);
//pr($charge);
$transaction = $this->Transaction->read(null, $id);
pr($transaction);
$payment_amount = 0;
foreach($charge['Receipt'] AS $receipt)
$payment_amount += $receipt['ChargesReceipt']['amount'];
$balance_amount = $charge['Charge']['total'] - $payment_amount;
$debit_amount = 0;
$credit_amount = 0;
foreach($transaction['LedgerEntry'] AS $entry) {
$debit_amount += $entry['amount'];
$credit_amount += $entry['amount'];
}
/* $this->sidemenu_links[] = */
/* array('name' => 'Operations', 'header' => true); */
/* $this->sidemenu_links[] = */
/* array('name' => 'Move-Out', 'url' => array('controller' => 'charges', 'action' => 'move-out')); */
/* array('name' => 'Move-Out', 'url' => array('controller' => 'transactions', 'action' => 'move-out')); */
$title = 'Charge #' . $charge['Charge']['id'];
$this->set(compact('charge', 'title',
'payment_amount',
'balance_amount'));
$title = 'Transaction #' . $transaction['Transaction']['id'];
$this->set(compact('transaction', 'title',
'debit_amount',
'credit_amount'));
}
}

View File

@@ -156,45 +156,70 @@ class UnitsController extends AppController {
$this->Unit->contain
(array(// Models
'UnitSize',
//'CurrentLease' =>
'Lease' =>
array('order' => 'movein_date',
'conditions' => array('Lease.lease_date IS NOT NULL',
),
array(//'order' => 'movein_date',
//'conditions' => array('Lease.lease_date IS NOT NULL',
//),
// Models
'Contact' =>
array(//'order' => array('sort_order'),
'fields' => array('id', 'display_name'),
),
'Charge' =>
array('order' => array('charge_date'),
//'Contact' => array('alias' => 'PrimaryContact'),
// 'PrimaryContact',
'Customer' => array('fields' => array('id', 'name'),
// Models
'ChargeType',
'Receipt' => array(// Models
'Payment'
'Transaction' =>
array('order' => array('stamp'),
// Models
'LedgerEntry' => array('DebitLedger' => array('Account'),
'CreditLedger' => array('Account'),
),
)
),
),
/* array(//'order' => array('sort_order'), */
/* 'fields' => array('id', 'display_name'), */
/* ), */
)
)
);
$unit = $this->Unit->read(null, $id);
//$unit = $this->Unit->read(null, $id);
//pr($unit);
$this->Unit->Lease->Customer->Transaction->LedgerEntry->Behaviors->attach('Containable');
$entries = $this->Unit->Lease->Customer->Transaction->LedgerEntry->find
('all',
array
(
'contain' =>
array('Transaction' =>
array('Customer' =>
array('Lease' =>
array('Unit' =>
array('conditions' => array('Unit.id' => $id)),
),
),
),
),
//'conditions' => 'xyz',
'limit' => 2,
));
pr($entries);
$this->autoRender = false;
$outstanding_deposit = 0;
$outstanding_balance = 0;
foreach($unit['Lease'] AS $lease) {
foreach($lease['Charge'] AS $charge) {
$outstanding_balance += $charge['total'];
foreach ($charge['Receipt'] AS $receipt) {
$outstanding_balance -= $receipt['ChargesReceipt']['amount'];
foreach($lease['Customer']['Transaction'] AS $transaction) {
foreach($transaction['LedgerEntry'] AS $entry) {
if ($entry['DebitLedger']['Account']['name'] === 'A/R')
$outstanding_balance += $entry['amount'];
if ($entry['CreditLedger']['Account']['name'] === 'A/R')
$outstanding_balance -= $entry['amount'];
/* foreach($receipt['Payment'] AS $payment) */
/* $outstanding_balance -= $payment['amount']; */
// REVISIT <AP> 20090530:
// Using hardcoded value for security deposit...
// That can't be good!
if ($charge['charge_type_id'] == 1)
$outstanding_deposit += $receipt['ChargesReceipt']['amount'];
if ($entry['DebitLedger']['Account']['name'] === 'Security Deposit')
$outstanding_deposit -= $entry['amount'];
if ($entry['CreditLedger']['Account']['name'] === 'Security Deposit')
$outstanding_deposit += $entry['amount'];
}
}
}

View File

@@ -8,10 +8,25 @@ class Account extends AppModel {
'external_name' => array('notempty')
);
//The Associations below have been created with all possible keys, those that are not needed can be removed
var $hasOne = array(
'CurrentLedger' => array(
'className' => 'Ledger',
'foreignKey' => 'account_id',
'dependent' => false,
'conditions' => array(array('CurrentLedger.closed' => 0)),
'fields' => '',
'order' => '',
'limit' => '',
'offset' => '',
'exclusive' => '',
'finderQuery' => '',
'counterQuery' => ''
),
);
var $hasMany = array(
'ChargeType' => array(
'className' => 'ChargeType',
'Ledger' => array(
'className' => 'Ledger',
'foreignKey' => 'account_id',
'dependent' => false,
'conditions' => '',
@@ -22,7 +37,7 @@ class Account extends AppModel {
'exclusive' => '',
'finderQuery' => '',
'counterQuery' => ''
)
),
);
}

View File

@@ -82,23 +82,51 @@ class LinkableBehavior extends ModelBehavior {
/* pr("_Model: $options[class] : $_Model->name ($_Model->alias)"); */
/* pr("Reference: $options[reference] : $Reference->name ($Reference->alias)"); */
$db =& $_Model->getDataSource();
$associations = $_Model->getAssociated();
if (isset($associations[$Reference->alias])) {
$associatedThroughReference = 0;
$association = null;
// Figure out how these two models are related, creating
// a relationship if one doesn't otherwise already exists.
if (($associations = $Reference->getAssociated()) &&
isset($associations[$_Model->alias])) {
/* pr("Reference defines association to _Model"); */
$associatedThroughReference = 1;
$type = $associations[$_Model->alias];
$association = $Reference->{$type}[$_Model->alias];
}
elseif (($associations = $_Model->getAssociated()) &&
isset($associations[$Reference->alias])) {
/* pr("_Model defines association to Reference"); */
$type = $associations[$Reference->alias];
$association = $_Model->{$type}[$Reference->alias];
} else {
$_Model->bind($Reference->alias);
}
else {
// No relationship... make our best effort to create one.
/* pr("No assocation between _Model and Reference"); */
$type = 'belongsTo';
$_Model->bind($Reference->alias);
// Grab the association now, since we'll unbind in a moment.
$association = $_Model->{$type}[$Reference->alias];
$_Model->unbindModel(array('belongsTo' => array($Reference->alias)));
}
// Determine which model holds the foreign key
if (($type === 'hasMany' || $type === 'hasOne') ^ $associatedThroughReference) {
$primaryModel = $Reference;
$foreignModel = $_Model;
} else {
$primaryModel = $_Model;
$foreignModel = $Reference;
}
/* pr("primaryModel: $primaryModel->name ($primaryModel->alias)"); */
/* pr("foreignModel: $foreignModel->name ($foreignModel->alias)"); */
/* pr($type); */
/* pr($association); */
if (empty($options['conditions'])) {
if ($type === 'belongsTo') {
$modelKey = $_Model->escapeField($association['foreignKey']);
$referenceKey = $Reference->escapeField($Reference->primaryKey);
$options['conditions'] = "{$referenceKey} = {$modelKey}";
} elseif ($type === 'hasAndBelongsToMany') {
if ($type === 'hasAndBelongsToMany') {
if (isset($association['with']))
$Link =& $_Model->{$association['with']};
else
@@ -144,23 +172,34 @@ class LinkableBehavior extends ModelBehavior {
'conditions' => "{$modelKey} = {$modelLink}",
'table' => $db->fullTableName($_Model, true));
// The user may have specified conditions directly in the model
// for this join. Make sure to adhere to those conditions.
if (isset($association['conditions']) && is_array($association['conditions']))
$options['conditions'] = $association['conditions'];
elseif (!empty($association['conditions']))
$options['conditions'] = array($association['conditions']);
// Now for the top level join. This will be added into the list
// of joins down below, outside of the HABTM specific code.
$options['alias'] = $linkAlias;
$options['table'] = $Link->getDataSource()->fullTableName($Link);
$options['conditions'][] = "{$referenceLink} = {$referenceKey}";
} else {
$referenceKey = $Reference->escapeField($association['foreignKey']);
$modelKey = $_Model->escapeField($_Model->primaryKey);
$options['conditions'] = "{$modelKey} = {$referenceKey}";
$foreignKey = $primaryModel->escapeField($association['foreignKey']);
$primaryKey = $foreignModel->escapeField($foreignModel->primaryKey);
// Only differentiating to help show the logical flow.
// Either way works and this test can be tossed out
if (($type === 'hasMany' || $type === 'hasOne') ^ $associatedThroughReference)
$options['conditions'][] = "{$primaryKey} = {$foreignKey}";
else
$options['conditions'][] = "{$foreignKey} = {$primaryKey}";
}
// The user may have specified conditions directly in the model
// for this join. Make sure to adhere to those conditions.
if (isset($association['conditions']) && is_array($association['conditions']))
$options['conditions'] = array_merge($options['conditions'], $association['conditions']);
elseif (!empty($association['conditions']))
$options['conditions'][] = $association['conditions'];
/* pr(array("Link ", $options['conditions'])); */
//pr($modelKey);
//pr($referenceKey);
}
if (empty($options['table'])) {
$options['table'] = $db->fullTableName($_Model, true);

View File

@@ -1,53 +0,0 @@
<?php
class Charge extends AppModel {
var $name = 'Charge';
var $validate = array(
'id' => array('numeric'),
'charge_type_id' => array('numeric'),
'lease_id' => array('numeric'),
'charge_date' => array('date'),
'charge_to_date' => array('date'),
'due_date' => array('date'),
'amount' => array('money'),
'tax' => array('money'),
'total' => array('money')
);
var $belongsTo = array(
'ChargeType' => array(
'className' => 'ChargeType',
'foreignKey' => 'charge_type_id',
'conditions' => '',
'fields' => '',
'order' => ''
),
'Lease' => array(
'className' => 'Lease',
'foreignKey' => 'lease_id',
'conditions' => '',
'fields' => '',
'order' => ''
)
);
var $hasAndBelongsToMany = array(
'Receipt' => array(
'className' => 'Receipt',
'joinTable' => 'charges_receipts',
'foreignKey' => 'charge_id',
'associationForeignKey' => 'receipt_id',
'unique' => true,
'conditions' => '',
'fields' => '',
'order' => '',
'limit' => '',
'offset' => '',
'finderQuery' => '',
'deleteQuery' => '',
'insertQuery' => ''
)
);
}
?>

View File

@@ -1,39 +0,0 @@
<?php
class ChargeType extends AppModel {
var $name = 'ChargeType';
var $validate = array(
'id' => array('numeric'),
'name' => array('notempty'),
'account_id' => array('numeric')
);
//The Associations below have been created with all possible keys, those that are not needed can be removed
/* var $belongsTo = array( */
/* 'Account' => array( */
/* 'className' => 'Account', */
/* 'foreignKey' => 'account_id', */
/* 'conditions' => '', */
/* 'fields' => '', */
/* 'order' => '' */
/* ) */
/* ); */
var $hasMany = array(
'Charge' => array(
'className' => 'Charge',
'foreignKey' => 'charge_type_id',
'dependent' => false,
'conditions' => '',
'fields' => '',
'order' => '',
'limit' => '',
'offset' => '',
'exclusive' => '',
'finderQuery' => '',
'counterQuery' => ''
)
);
}
?>

View File

@@ -10,11 +10,11 @@ class Contact extends AppModel {
);
var $hasAndBelongsToMany = array(
'Lease' => array(
'className' => 'Lease',
'joinTable' => 'contacts_leases',
'Customer' => array(
'className' => 'Customer',
'joinTable' => 'contacts_customers',
'foreignKey' => 'contact_id',
'associationForeignKey' => 'lease_id',
'associationForeignKey' => 'customer_id',
'unique' => true,
'conditions' => '',
'fields' => '',

58
models/customer.php Normal file
View File

@@ -0,0 +1,58 @@
<?php
class Customer extends AppModel {
var $name = 'Customer';
var $validate = array(
'id' => array('numeric'),
'name' => array('notempty'),
);
var $hasMany = array(
'Lease' => array(
'className' => 'Lease',
'foreignKey' => 'customer_id',
'dependent' => false,
'conditions' => '',
'fields' => '',
'order' => '',
'limit' => '',
'offset' => '',
'exclusive' => '',
'finderQuery' => '',
'counterQuery' => ''
),
'Transaction' => array(
'className' => 'Transaction',
'foreignKey' => 'customer_id',
'dependent' => false,
'conditions' => '',
'fields' => '',
'order' => '',
'limit' => '',
'offset' => '',
'exclusive' => '',
'finderQuery' => '',
'counterQuery' => ''
)
);
var $hasAndBelongsToMany = array(
'Contact' => array(
'className' => 'Contact',
'joinTable' => 'contacts_customers',
'foreignKey' => 'customer_id',
'associationForeignKey' => 'contact_id',
'unique' => true,
'conditions' => '',
'fields' => '',
'order' => '',
'limit' => '',
'offset' => '',
'finderQuery' => '',
'deleteQuery' => '',
'insertQuery' => ''
),
);
}
?>

View File

@@ -22,7 +22,6 @@ class Lease extends AppModel {
'next_amount_date' => array('date')
);
//The Associations below have been created with all possible keys, those that are not needed can be removed
var $belongsTo = array(
'LeaseType' => array(
'className' => 'LeaseType',
@@ -44,41 +43,15 @@ class Lease extends AppModel {
'conditions' => '',
'fields' => '',
'order' => ''
)
);
var $hasMany = array(
'Charge' => array(
'className' => 'Charge',
'foreignKey' => 'lease_id',
),
'Customer' => array(
'className' => 'Customer',
'foreignKey' => 'customer_id',
'dependent' => false,
'conditions' => '',
'fields' => '',
'order' => '',
'limit' => '',
'offset' => '',
'exclusive' => '',
'finderQuery' => '',
'counterQuery' => ''
)
);
var $hasAndBelongsToMany = array(
'Contact' => array(
'className' => 'Contact',
'joinTable' => 'contacts_leases',
'foreignKey' => 'lease_id',
'associationForeignKey' => 'contact_id',
'unique' => true,
'conditions' => '',
'fields' => '',
'order' => '',
'limit' => '',
'offset' => '',
'finderQuery' => '',
'deleteQuery' => '',
'insertQuery' => ''
)
'order' => ''
),
);
}

65
models/ledger.php Normal file
View File

@@ -0,0 +1,65 @@
<?php
class Ledger extends AppModel {
var $name = 'Ledger';
var $validate = array(
'id' => array('numeric'),
'name' => array('notempty'),
);
var $belongsTo = array(
'Account' => array(
'className' => 'Account',
'foreignKey' => 'account_id',
'conditions' => '',
'fields' => '',
'order' => ''
),
);
var $hasMany = array(
/* 'LedgerEntry' => array( */
/* 'className' => 'LedgerEntry', */
/* 'foreignKey' => false, */
/* 'dependent' => false, */
/* 'conditions' => '', */
/* 'fields' => '', */
/* 'order' => '', */
/* 'limit' => '', */
/* 'offset' => '', */
/* 'exclusive' => '', */
/* 'finderQuery' => 'SELECT `Entry`.* FROM pmgr_entries AS `Entry` */
/* WHERE Entry.debit_ledger_id = ({$__cakeID__$}) */
/* OR Entry.credit_ledger_id = ({$__cakeID__$})', */
/* 'counterQuery' => '' */
/* ), */
'DebitLedgerEntry' => array(
'className' => 'LedgerEntry',
'foreignKey' => 'debit_ledger_id',
'dependent' => false,
'conditions' => '',
'fields' => '',
'order' => '',
'limit' => '',
'offset' => '',
'exclusive' => '',
'finderQuery' => '',
'counterQuery' => ''
),
'CreditLedgerEntry' => array(
'className' => 'LedgerEntry',
'foreignKey' => 'credit_ledger_id',
'dependent' => false,
'conditions' => '',
'fields' => '',
'order' => '',
'limit' => '',
'offset' => '',
'exclusive' => '',
'finderQuery' => '',
'counterQuery' => ''
),
);
}
?>

43
models/ledger_entry.php Normal file
View File

@@ -0,0 +1,43 @@
<?php
class LedgerEntry extends AppModel {
var $name = 'LedgerEntry';
var $validate = array(
'id' => array('numeric'),
'transaction_id' => array('numeric'),
'amount' => array('money')
);
var $belongsTo = array(
'MonetarySource' => array(
'className' => 'MonetarySource',
'foreignKey' => 'monetary_source_id',
'conditions' => '',
'fields' => '',
'order' => ''
),
'Transaction' => array(
'className' => 'Transaction',
'foreignKey' => 'transaction_id',
'conditions' => '',
'fields' => '',
'order' => ''
),
'DebitLedger' => array(
'className' => 'Ledger',
'foreignKey' => 'debit_ledger_id',
'conditions' => '',
'fields' => '',
'order' => ''
),
'CreditLedger' => array(
'className' => 'Ledger',
'foreignKey' => 'credit_ledger_id',
'conditions' => '',
'fields' => '',
'order' => ''
),
);
}
?>

View File

@@ -0,0 +1,28 @@
<?php
class MonetarySource extends AppModel {
var $name = 'MonetarySource';
var $validate = array(
'id' => array('numeric'),
'name' => array('notempty'),
'tillable' => array('boolean')
);
var $belongsTo = array(
'MonetaryType' => array(
'className' => 'MonetaryType',
'foreignKey' => 'monetary_type_id',
'dependent' => false,
'conditions' => '',
'fields' => '',
'order' => '',
'limit' => '',
'offset' => '',
'exclusive' => '',
'finderQuery' => '',
'counterQuery' => ''
)
);
}
?>

View File

@@ -1,18 +1,17 @@
<?php
class PaymentType extends AppModel {
class MonetaryType extends AppModel {
var $name = 'PaymentType';
var $name = 'MonetaryType';
var $validate = array(
'id' => array('numeric'),
'name' => array('notempty'),
'tillable' => array('boolean')
);
//The Associations below have been created with all possible keys, those that are not needed can be removed
var $hasMany = array(
'Payment' => array(
'className' => 'Payment',
'foreignKey' => 'payment_type_id',
'MonetarySource' => array(
'className' => 'MonetarySource',
'foreignKey' => 'monetary_type_id',
'dependent' => false,
'conditions' => '',
'fields' => '',

View File

@@ -1,31 +0,0 @@
<?php
class Payment extends AppModel {
var $name = 'Payment';
var $validate = array(
'id' => array('numeric'),
'receipt_id' => array('numeric'),
'payment_type_id' => array('numeric'),
'amount' => array('money')
);
//The Associations below have been created with all possible keys, those that are not needed can be removed
var $belongsTo = array(
'Receipt' => array(
'className' => 'Receipt',
'foreignKey' => 'receipt_id',
'conditions' => '',
'fields' => '',
'order' => ''
),
'PaymentType' => array(
'className' => 'PaymentType',
'foreignKey' => 'payment_type_id',
'conditions' => '',
'fields' => '',
'order' => ''
)
);
}
?>

View File

@@ -1,46 +0,0 @@
<?php
class Receipt extends AppModel {
var $name = 'Receipt';
var $validate = array(
'id' => array('numeric'),
'stamp' => array('time')
);
//The Associations below have been created with all possible keys, those that are not needed can be removed
var $hasMany = array(
'Payment' => array(
'className' => 'Payment',
'foreignKey' => 'receipt_id',
'dependent' => false,
'conditions' => '',
'fields' => '',
'order' => '',
'limit' => '',
'offset' => '',
'exclusive' => '',
'finderQuery' => '',
'counterQuery' => ''
)
);
var $hasAndBelongsToMany = array(
'Charge' => array(
'className' => 'Charge',
'joinTable' => 'charges_receipts',
'foreignKey' => 'receipt_id',
'associationForeignKey' => 'charge_id',
'unique' => true,
'conditions' => '',
'fields' => '',
'order' => '',
'limit' => '',
'offset' => '',
'finderQuery' => '',
'deleteQuery' => '',
'insertQuery' => ''
)
);
}
?>

37
models/transaction.php Normal file
View File

@@ -0,0 +1,37 @@
<?php
class Transaction extends AppModel {
var $name = 'Transaction';
var $validate = array(
'id' => array('numeric'),
'stamp' => array('time')
);
var $belongsTo = array(
'Customer' => array(
'className' => 'Customer',
'foreignKey' => 'customer_id',
'conditions' => '',
'fields' => '',
'order' => ''
),
);
var $hasMany = array(
'LedgerEntry' => array(
'className' => 'LedgerEntry',
'foreignKey' => 'transaction_id',
'dependent' => false,
'conditions' => '',
'fields' => '',
'order' => '',
'limit' => '',
'offset' => '',
'exclusive' => '',
'finderQuery' => '',
'counterQuery' => ''
)
);
}
?>

View File

@@ -20,6 +20,13 @@ class Unit extends AppModel {
'fields' => '',
'order' => ''
),
'CurrentLease' => array(
'className' => 'Lease',
'foreignKey' => 'current_lease_id',
'conditions' => '',
'fields' => '',
'order' => ''
),
/* 'Map' => array( */
/* 'className' => 'MapsUnit', */
/* 'foreignKey' => 'unit_id', */

3
views/accounts/index.ctp Normal file
View File

@@ -0,0 +1,3 @@
<div class="accounts index">
<?php echo $this->element('accounts', array('heading' => '<h2>'.$heading.'</h2>')) ?>
</div>

95
views/accounts/view.ctp Normal file
View File

@@ -0,0 +1,95 @@
<?php /* -*- mode:PHP -*- */ ?>
<div class="account view">
<?php
; // Editor alignment
function currency($number) {
if (!isset($number))
return null;
if ($number < 0)
return "($ " . number_format(-1*$number, 2) . ")";
else
return "$ " . number_format($number, 2);
}
function datefmt($date) {
$date_fmt = 'm/d/Y';
return ($date
? date_format(date_create($date), $date_fmt)
: null);
}
function comment($comment) {
if (isset($comment) && is_array($comment)) {
foreach (array_keys($comment) AS $k) {
if (!$comment[$k])
unset($comment[$k]);
}
return implode('; ', $comment);
}
return $comment;
}
/**********************************************************************
**********************************************************************
**********************************************************************
**********************************************************************
* Account Detail Main Section
*/
$rows = array(array('ID', $account['Account']['id']),
array('Name', $account['Account']['name']),
array('Type', $account['Account']['type']),
array('External Name', $account['Account']['external_name']),
array('External Account', $account['Account']['external_account']),
array('Comment', $account['Account']['comment']));
echo $this->element('table',
array('class' => 'item account detail',
'caption' => 'Account Detail',
'rows' => $rows,
'column_class' => array('field', 'value')));
/**********************************************************************
* Account Info Box
*/
?>
<DIV CLASS="infobox">
<DIV CLASS="summary balance">
Account Balance: <?php echo currency($balance); ?>
</DIV>
</DIV>
<DIV CLASS="detail supporting">
<?php
; // Editor alignment
/**********************************************************************
**********************************************************************
**********************************************************************
**********************************************************************
* Supporting Elements Section
*/
/**********************************************************************
* Ledger
*/
echo $this->element('ledgers',
array('caption' => $account['Account']['name'] . " Ledgers",
'ledgers' => $account['Ledger']));
/* End "detail supporting" DIV */ ?>
</DIV>
</div>

View File

@@ -1,3 +0,0 @@
<div class="charges index">
<?php echo $this->element('charges', array('heading' => '<h2>'.$heading.'</h2>')) ?>
</div>

View File

@@ -1,87 +0,0 @@
<?php /* -*- mode:PHP -*- */ ?>
<div class="charges view">
<?php
function currency($number) {
if ($number < 0)
return "($ " . number_format(-1*$number, 2) . ")";
else
return "$ " . number_format($number, 2);
}
function datefmt($date) {
$date_fmt = 'm/d/Y';
return ($date
? date_format(date_create($date), $date_fmt)
: null);
}
/**********************************************************************
* Charge Info
*/
$rows = array(array('ID', $charge['Charge']['id']),
array('Date', datefmt($charge['Charge']['charge_date'])),
array('Through', datefmt($charge['Charge']['charge_to_date'])),
array('Due', datefmt($charge['Charge']['due_date'])),
array('Type', $charge['ChargeType']['name']),
array('Lease', '#'.$charge['Lease']['number']),
array('Amount', currency($charge['Charge']['amount'])),
array('Tax', currency($charge['Charge']['tax'])),
array('Total', currency($charge['Charge']['total'])),
array('Comment', $charge['Charge']['comment']));
echo $this->element('table',
array('class' => 'item charge detail',
'caption' => 'Charge Info',
'rows' => $rows,
'column_class' => array('field', 'value')));
?>
<DIV CLASS="infobox charge">
<DIV CLASS="summary grand payment">
Amount Received: <?php echo currency($paymentAmount); ?>
</DIV>
<DIV CLASS="summary grand balance">
Amount Owing: <?php echo currency($balanceAmount); ?>
</DIV>
</DIV>
<?php
/**********************************************************************
* Receipts
*/
$headers = array('ID', 'Timestamp', 'Comment', 'Applied', 'Balance');
$rows = array();
$running_total = $charge['Charge']['total'];
foreach($charge['Receipt'] AS $receipt) {
$amount = $receipt['ChargesReceipt']['amount'];
$running_total -= $amount;
$rows[] = array($html->link('#'.$receipt['id'],
array('controller' => 'receipts',
'action' => 'view',
$receipt['id'])),
datefmt($receipt['stamp']),
$receipt['comment'],
currency($receipt['ChargesReceipt']['amount']),
currency($running_total)
);
}
echo $this->element('table',
array('class' => 'item receipt list',
'caption' => 'Receipts towards Charge',
'headers' => $headers,
'rows' => $rows,
'column_class' => $headers));
?>
</div>

View File

@@ -1,6 +1,6 @@
<?php /* -*- mode:PHP -*- */ ?>
<div class="contacts view">
<div class="contact view">
<?php
@@ -28,36 +28,48 @@ function datefmt($date) {
: null);
}
/**********************************************************************
* Tenant Info
**********************************************************************
**********************************************************************
**********************************************************************
* Contact Detail Main Section
*/
$rows = array(array('Name', $contact['Contact']['display_name']),
array('Company', $contact['Contact']['company_name']),
array('SSN', $contact['Contact']['id_federal']),
array('ID', ($contact['Contact']['id_num']
. ($contact['Contact']['id_state']
? " - ".$contact['Contact']['id_state']
array('ID', ($contact['Contact']['id_local']
. ($contact['Contact']['id_local']
? " - ".$contact['Contact']['id_local_state']
: ""))),
array('Comment', $contact['Contact']['comment']));
echo $this->element('table',
array('class' => 'item contact detail',
'caption' => 'Tenant Info',
'caption' => 'Contact Details',
'rows' => $rows,
'column_class' => array('field', 'value')));
/**********************************************************************
* Contact Info Box
*/
?>
<DIV CLASS="infobox contact">
<DIV CLASS="summary grand deposit">
Security Deposit: <?php echo currency($outstandingDeposit); ?>
</DIV>
<DIV CLASS="summary grand balance">
Balance: <?php echo currency($outstandingBalance); ?>
</DIV>
<DIV CLASS="infobox">
</DIV>
<DIV CLASS="detail supporting">
<?php
; // Editor alignment
/**********************************************************************
**********************************************************************
**********************************************************************
**********************************************************************
* Supporting Elements Section
*/
/**********************************************************************
@@ -127,77 +139,14 @@ echo $this->element('table',
/**********************************************************************
* Lease History
* Customers
*/
$headers = array('Lease', 'Unit', 'Signed', 'Move-In', 'Move-Out', 'Rent', 'Deposit', 'Comment');
$rows = array();
foreach($contact['Lease'] AS $lease) {
$rows[] = array('#'.$lease['number'],
$html->link($lease['Unit']['name'],
array('controller' => 'units',
'action' => 'view',
$lease['Unit']['id'])),
datefmt($lease['lease_date']),
datefmt($lease['movein_date']),
datefmt($lease['moveout_date']),
$lease['amount'],
$lease['deposit'],
$lease['comment']);
}
echo $this->element('table',
array('class' => 'item lease list',
'caption' => 'Lease History',
'headers' => $headers,
'rows' => $rows,
'column_class' => $headers));
echo $this->element('customers', array('heading' => '',
'caption' => 'Related Customers',
'customers' => $contact['Customer']));
/**********************************************************************
* Ledger History
*/
foreach($contact['Lease'] AS $lease) {
$headers = array(/*'Charge/Receipt'*/'Charge', 'Date', 'Through', 'Type', 'Comment', 'Amount', 'Balance', 'Total');
$rows = array();
$row_class = array();
$running_total = 0;
$odd = 0;
foreach($lease['Charge'] AS $charge) {
$amount = $charge['total'];
$balance = $amount;
foreach ($charge['Receipt'] AS $receipt)
$balance -= $receipt['ChargesReceipt']['amount'];
$running_total += $balance;
$rows[] = array($html->link('#'.$charge['id'],
array('controller' => 'charges',
'action' => 'view',
$charge['id'])),
datefmt($charge['charge_date']),
datefmt($charge['charge_to_date']),
$charge['ChargeType']['name'],
$charge['comment'],
currency($amount),
currency($balance),
//currency($amount - $paid));
currency($running_total));
$row_class[] = array('charge', (++$odd % 2) ? 'oddrow' : 'evnrow');
}
echo $this->element('table',
array('class' => 'item ledger list',
'caption' => 'Lease #'.$lease['number'].' (Unit: '.$lease['Unit']['name'].')',
'suppress_alternate_rows' => true,
'headers' => $headers,
'rows' => $rows,
'row_class' => $row_class,
'column_class' => $headers));
}
?>
/* End "detail supporting" DIV */ ?>
</DIV>
</div>

View File

@@ -0,0 +1,3 @@
<div class="customers index">
<?php echo $this->element('customers', array('heading' => '<h2>'.$heading.'</h2>')) ?>
</div>

189
views/customers/view.ctp Normal file
View File

@@ -0,0 +1,189 @@
<?php /* -*- mode:PHP -*- */ ?>
<div class="customer view">
<?php
function currency($number) {
if ($number < 0)
return "($ " . number_format(-1*$number, 2) . ")";
else
return "$ " . number_format($number, 2);
}
function phone($phone) {
$phone = preg_replace("/\D/", "", $phone);
if(strlen($phone) == 7)
return preg_replace("/(\d{3})(\d{4})/", "$1-$2", $phone);
elseif(strlen($phone) == 10)
return preg_replace("/(\d{3})(\d{3})(\d{4})/", "$1-$2-$3", $phone);
else
return $phone;
}
function datefmt($date) {
$date_fmt = 'm/d/Y';
return ($date
? date_format(date_create($date), $date_fmt)
: null);
}
/**********************************************************************
**********************************************************************
**********************************************************************
**********************************************************************
* Customer Detail Main Section
*/
$rows = array(array('Name', $customer['Customer']['name']),
array('Comment', $customer['Customer']['comment']));
echo $this->element('table',
array('class' => 'item customer detail',
'caption' => 'Tenant Info',
'rows' => $rows,
'column_class' => array('field', 'value')));
/**********************************************************************
* Customer Info Box
*/
?>
<DIV CLASS="infobox">
<DIV CLASS="summary grand deposit">
Security Deposit: <?php echo currency($outstandingDeposit); ?>
</DIV>
<DIV CLASS="summary grand balance">
Balance: <?php echo currency($outstandingBalance); ?>
</DIV>
</DIV>
<DIV CLASS="detail supporting">
<?php
; // Editor alignment
/**********************************************************************
**********************************************************************
**********************************************************************
**********************************************************************
* Supporting Elements Section
*/
/**********************************************************************
* Contacts
*/
echo $this->element('contacts',
array('caption' => 'Customer Contacts',
'contacts' => $customer['Contact']));
/* foreach ($customer['Contact'] AS $contact) { */
/* /\********************************************************************** */
/* * Phones */
/* *\/ */
/* $headers = array('Phone', 'Preference', 'Comment'); */
/* $rows = array(); */
/* foreach($contact['ContactPhone'] AS $phone) { */
/* $rows[] = array(phone($phone['phone']) . */
/* ($phone['ext'] ? " x".$phone['ext'] : ""), */
/* $phone['ContactsMethod']['preference'] . " / " . */
/* $phone['ContactsMethod']['type'] . " / " . */
/* $phone['type'], */
/* $phone['comment']); */
/* } */
/* echo $this->element('table', */
/* array('class' => 'item phone list', */
/* 'caption' => 'Phone', */
/* 'headers' => $headers, */
/* 'rows' => $rows, */
/* 'column_class' => $headers)); */
/* /\********************************************************************** */
/* * Emails */
/* *\/ */
/* $headers = array('Email', 'Preference', 'Comment'); */
/* $rows = array(); */
/* foreach($contact['ContactEmail'] AS $email) { */
/* $rows[] = array($email['email'], */
/* $email['ContactsMethod']['preference'] . " / " . */
/* $email['ContactsMethod']['type'], */
/* $email['comment']); */
/* } */
/* echo $this->element('table', */
/* array('class' => 'item email list', */
/* 'caption' => 'Email', */
/* 'headers' => $headers, */
/* 'rows' => $rows, */
/* 'column_class' => $headers)); */
/* /\********************************************************************** */
/* * Addresses */
/* *\/ */
/* $headers = array('Address', 'Preference', 'Comment'); */
/* $rows = array(); */
/* foreach($contact['ContactAddress'] AS $address) { */
/* $rows[] = array(preg_replace("/\n/", "<BR>\n", $address['address']) . "<BR>\n" . */
/* $address['city'] . ", " . */
/* $address['state'] . " " . */
/* $address['postcode'], */
/* //. ? "<BR>\n" . $address['country'], */
/* $address['ContactsMethod']['preference'] . " / " . */
/* $address['ContactsMethod']['type'], */
/* $address['comment']); */
/* } */
/* echo $this->element('table', */
/* array('class' => 'item address list', */
/* 'caption' => 'Address', */
/* 'headers' => $headers, */
/* 'rows' => $rows, */
/* 'column_class' => $headers)); */
/**********************************************************************
* Lease History
*/
$headers = array('Lease', 'Unit', 'Signed', 'Move-In', 'Move-Out', 'Rent', 'Deposit', 'Comment');
$rows = array();
foreach($customer['Lease'] AS $lease) {
$rows[] = array('#'.$lease['number'],
$html->link($lease['Unit']['name'],
array('controller' => 'units',
'action' => 'view',
$lease['Unit']['id'])),
datefmt($lease['lease_date']),
datefmt($lease['movein_date']),
datefmt($lease['moveout_date']),
$lease['amount'],
$lease['deposit'],
$lease['comment']);
}
echo $this->element('table',
array('class' => 'item lease list',
'caption' => 'Lease History',
'headers' => $headers,
'rows' => $rows,
'column_class' => $headers));
/**********************************************************************
* Ledger History
*/
echo $this->element('ledger',
array('caption' => 'Ledger History',
'transactions' => $customer['Transaction'],
'ledger' => array('mix'=>1)));
/* End "detail supporting" DIV */ ?>
</DIV>
</div>

View File

@@ -0,0 +1,85 @@
<?php /* -*- mode:PHP -*- */
if (isset($heading))
echo $heading;
else
echo '<h2>'.__('Accounts',true).'</h2>';
function currency($number) {
if ($number < 0)
return "($ " . number_format(-1*$number, 2) . ")";
else
return "$ " . number_format($number, 2);
}
function datefmt($date) {
$date_fmt = 'm/d/Y';
return ($date
? date_format(date_create($date), $date_fmt)
: null);
}
$headers = array('Name', 'Type', 'Ext. Name', 'Ext. Account', 'Entries', 'Debits', 'Credits', 'Balance', 'Comment');
$column_class = array();
foreach (array_intersect($column_class, array('Debits', 'Credits', 'Balance')) AS $k => $v) {
$column_class[$k] = 'currency';
}
if (isset($paginator)) {
echo $paginator->counter(array(
'format' => __('Page %page% of %pages%, showing %current% records (%start% - %end%) of %count% total', true)));
$headers = array($paginator->sort('name'),
$paginator->sort('type'),
$paginator->sort('Ext. Name', 'external_name'),
$paginator->sort('Ext. Account', 'external_account'),
$paginator->sort('entries'),
$paginator->sort('debits'),
$paginator->sort('credits'),
$paginator->sort('balance'),
$paginator->sort('comment'));
}
$rows = array();
foreach ($accounts as $account) {
$extra = null;
if (isset($account[0])) {
$extra = $account[0];
unset($account[0]);
}
if (isset($account['Account']))
$account = $account['Account'];
if (isset($extra))
$account = array_merge($account, $extra);
$rows[] = array($html->link($account['name'],
array('controller' => 'accounts',
'action' => 'view',
$account['id'])),
$account['type'],
$account['external_name'],
$account['external_account'],
$account['entries'],
currency($account['debits']),
currency($account['credits']),
currency($account['balance']),
$account['comment'],
);
}
echo $this->element('table',
array('class' => 'item account list',
'headers' => $headers,
'rows' => $rows,
'column_class' => $column_class));
if (isset($paginator)) {
echo('<div class="paging">' . "\n");
echo $paginator->prev('<< '.__('previous', true), array(), null, array('class'=>'disabled'));
echo(' | ');
echo $paginator->numbers();
echo(' | ');
echo $paginator->next(__('next', true).' >>', array(), null, array('class'=>'disabled'));
echo('</div>' . "\n");
}

View File

@@ -1,68 +0,0 @@
<?php /* -*- mode:PHP -*- */
if (isset($heading))
echo $heading;
else
echo '<h2>'.__('Charges',true).'</h2>';
function currency($number) {
if ($number < 0)
return "($ " . number_format(-1*$number, 2) . ")";
else
return "$ " . number_format($number, 2);
}
function datefmt($date) {
$date_fmt = 'm/d/Y';
return ($date
? date_format(date_create($date), $date_fmt)
: null);
}
$headers_manual = array('ID', 'Date', 'Due', 'Type', 'Lease', 'Amount', 'Comment');
if (isset($paginator)) {
echo $paginator->counter(array(
'format' => __('Page %page% of %pages%, showing %current% records (%start% - %end%) of %count% total', true)));
$headers = array($paginator->sort('id'),
$paginator->sort('Date', 'charge_date'),
$paginator->sort('Due', 'due_date'),
$paginator->sort('Type', 'charge_type'),
$paginator->sort('Lease', 'number'),
$paginator->sort('total'),
$paginator->sort('comment'));
} else {
$headers = $headers_manual;
}
$rows = array();
foreach ($charges as $charge) {
$rows[] = array($html->link($charge['Charge']['id'],
array('controller' => 'charges',
'action' => 'view',
$charge['Charge']['id'])),
datefmt($charge['Charge']['charge_date']),
datefmt($charge['Charge']['due_date']),
$charge['ChargeType']['name'],
'#'.$charge['Lease']['number'],
currency($charge['Charge']['total']),
$charge['Charge']['comment'],
);
}
echo $this->element('table',
array('class' => 'item charge list',
'headers' => $headers,
'rows' => $rows,
'column_class' => $headers_manual));
if (isset($paginator)) {
echo('<div class="paging">' . "\n");
echo $paginator->prev('<< '.__('previous', true), array(), null, array('class'=>'disabled'));
echo(' | ');
echo $paginator->numbers();
echo(' | ');
echo $paginator->next(__('next', true).' >>', array(), null, array('class'=>'disabled'));
echo('</div>' . "\n");
}

View File

@@ -2,44 +2,57 @@
if (isset($heading))
echo $heading;
else
elseif (!isset($caption))
echo '<h2>'.__('Contacts',true).'</h2>';
$headers_manual = array('Id', 'Last Name', 'First Name', 'Company', 'Comment');
$headers_manual = array_merge(array('Id', 'Last Name', 'First Name', 'Company'),
isset($contacts[0]['ContactsCustomer']) ? array('Type', 'Active') : array(),
array('Comment'));
if (isset($paginator)) {
echo $paginator->counter(array(
'format' => __('Page %page% of %pages%, showing %current% records (%start% - %end%) of %count% total', true)));
$headers = array($paginator->sort('id'),
$headers = array_merge(array($paginator->sort('id'),
$paginator->sort('last_name'),
$paginator->sort('first_name'),
$paginator->sort('company_name'),
//$paginator->sort('unit_id'),
$paginator->sort('comment'));
$paginator->sort('company_name')),
(isset($contacts[0]['ContactsCustomer'])
? array($paginator->sort('type'),
$paginator->sort('active'))
: array()),
array($paginator->sort('comment')));
} else {
$headers = $headers_manual;
}
$rows = array();
foreach ($contacts as $contact) {
$rows[] = array($html->link($contact['Contact']['id'],
if (isset($contact['Contact']))
$contact = $contact['Contact'];
$rows[] = array_merge(array($html->link($contact['id'],
array('controller' => 'contacts',
'action' => 'view',
$contact['Contact']['id'])),
$html->link($contact['Contact']['last_name'],
$contact['id'])),
$html->link($contact['last_name'],
array('controller' => 'contacts',
'action' => 'view',
$contact['Contact']['id'])),
$html->link($contact['Contact']['first_name'],
$contact['id'])),
$html->link($contact['first_name'],
array('controller' => 'contacts',
'action' => 'view',
$contact['Contact']['id'])),
$contact['Contact']['company_name'],
$contact['Contact']['comment']);
$contact['id'])),
$contact['company_name']),
(isset($contact['ContactsCustomer'])
? array($contact['ContactsCustomer']['type'],
$contact['ContactsCustomer']['active'],
$contact['ContactsCustomer']['comment'])
: array($contact['comment'])));
}
echo $this->element('table',
array('class' => 'item contact list',
'caption' => isset($caption) ? $caption : null,
'headers' => $headers,
'rows' => $rows,
'column_class' => $headers_manual));

View File

@@ -3,46 +3,39 @@
if (isset($heading))
echo $heading;
else
echo '<h2>'.__('Receipts',true).'</h2>';
echo '<h2>'.__('Customers',true).'</h2>';
function currency($number) {
if ($number < 0)
return "($ " . number_format(-1*$number, 2) . ")";
else
return "$ " . number_format($number, 2);
}
function datefmt($date) {
$date_fmt = 'm/d/Y';
return ($date
? date_format(date_create($date), $date_fmt)
: null);
}
$headers_manual = array('Id', 'Timestamp', 'Comment');
$headers_manual = array('Id', 'Name', 'Comment');
if (isset($paginator)) {
echo $paginator->counter(array(
'format' => __('Page %page% of %pages%, showing %current% records (%start% - %end%) of %count% total', true)));
$headers = array($paginator->sort('id'),
$paginator->sort('Timestamp', 'stamp'),
$paginator->sort('name'),
$paginator->sort('comment'));
} else {
$headers = $headers_manual;
}
$rows = array();
foreach ($receipts as $receipt) {
$rows[] = array($html->link($receipt['Receipt']['id'],
array('controller' => 'receipts',
foreach ($customers as $customer) {
if (isset($customer['Customer']))
$customer = $customer['Customer'];
$rows[] = array($html->link($customer['id'],
array('controller' => 'customers',
'action' => 'view',
$receipt['Receipt']['id'])),
datefmt($receipt['Receipt']['stamp']),
$receipt['Receipt']['comment']);
$customer['id'])),
$html->link($customer['name'],
array('controller' => 'customers',
'action' => 'view',
$customer['id'])),
$customer['comment']);
}
echo $this->element('table',
array('class' => 'item receipt list',
array('class' => 'item customer list',
'caption' => isset($caption) ? $caption : null,
'headers' => $headers,
'rows' => $rows,
'column_class' => $headers_manual));

View File

@@ -1,314 +1,80 @@
<?php /* -*- mode:PHP -*- */
/* if (isset($heading)) */
/* echo $heading; */
/* else */
/* echo '<h2>'.__('Payments',true).'</h2>'; */
?>
<div class="ledger collection">
<!-- <span class="title">$caption</span> -->
<?php
; // Alignment purposes only
// Charges Only
// Payments Only
// Mixture of both (by date)
// Match both (payments match charges)
/**********************************************************************
* Charges Only
*/
if (isset($ledger['charges'])) {
$headers = array('Charge', 'Date', 'Through', 'Type', 'Comment', 'Amount', 'Balance', 'Total');
$rows = array();
$row_class = array();
$running_total = 0;
foreach($lease['Charge'] AS $charge) {
$amount = $charge['total'];
$balance = $amount;
foreach ($charge['Receipt'] AS $receipt)
$balance -= $receipt['ChargesReceipt']['amount'];
$running_total += $balance;
$rows[] = array($html->link('#'.$charge['id'],
array('controller' => 'charges',
'action' => 'view',
$charge['id'])),
datefmt($charge['charge_date']),
datefmt($charge['charge_to_date']),
$charge['ChargeType']['name'],
$charge['comment'],
currency($amount),
currency($balance),
//currency($amount - $paid));
currency($running_total));
$row_class[] = 'charge';
}
echo ('<div class="ledger history charges">' . "\n");
echo $this->element('table',
array('class' => 'item ledger list',
'caption' => $caption,
'headers' => $headers,
'rows' => $rows,
'row_class' => $row_class,
'column_class' => $headers));
echo ('</div>' . "\n");
$headers = array('Transaction', 'Entry', 'Date', 'Customer', 'Comment', 'Debit', 'Credit', 'Total');
$column_class = $headers;
foreach (array_intersect($column_class, array('Transaction', 'Entry')) AS $k => $v) {
$column_class[$k] = array($column_class[$k], 'id');
}
/**********************************************************************
* Receipts Only
*/
if (isset($ledger['receipts'])) {
$headers = array('Receipt', 'Date', 'Comment', 'Amount', 'Balance', 'Total');
$receipts = array();
foreach ($lease['Charge'] AS $charge) {
foreach($charge['Receipt'] AS $receipt) {
if (!isset($receipts[$receipt['id']])) {
$receipts[$receipt['id']] = $receipt;
$receipts[$receipt['id']]['amount'] = 0;
$receipts[$receipt['id']]['charge'] = 0;
foreach($receipt['Payment'] AS $payment)
$receipts[$receipt['id']]['amount'] += $payment['amount'];
unset($receipts[$receipt['id']]['ChargesReceipt']);
unset($receipts[$receipt['id']]['Payment']);
}
$receipts[$receipt['id']]['charge'] += $receipt['ChargesReceipt']['amount'];
}
}
usort($receipts,
create_function('$a, $b',
'$adate = TimeHelper::toUnix(isset($a["charge_date"]) ? $a["charge_date"] : $a["stamp"]); ' .
'$bdate = TimeHelper::toUnix(isset($b["charge_date"]) ? $b["charge_date"] : $b["stamp"]); ' .
'return strcmp($adate, $bdate);')
);
$rows = array();
$row_class = array();
$running_total = 0;
foreach ($receipts AS $receipt) {
$amount = $receipt['amount'];
$balance = $amount - $receipt['charge'];
$running_total += $balance;
$rows[] = array($html->link('#'.$receipt['id'],
array('controller' => 'receipts',
'action' => 'view',
$receipt['id'])),
datefmt($receipt['stamp']),
$receipt['comment'],
currency($amount),
currency($balance),
currency($running_total));
$row_class[] = 'receipt';
}
echo ('<div class="ledger history receipts">' . "\n");
echo $this->element('table',
array('class' => 'item ledger list',
'caption' => $caption,
'headers' => $headers,
'rows' => $rows,
'row_class' => $row_class,
'column_class' => $headers));
echo ('</div>' . "\n");
foreach (array_intersect($column_class, array('Debits', 'Credits', 'Total')) AS $k => $v) {
$column_class[$k] = array($column_class[$k], 'currency');
}
/* if (isset($paginator)) { */
/* echo $paginator->counter(array( */
/* 'format' => __('Page %page% of %pages%, showing %current% records (%start% - %end%) of %count% total', true))); */
/* $headers = array('Receipt', 'Date', 'Comment', 'Amount', 'Balance', 'Total'); */
/* $rows = array(); */
/* $row_class = array(); */
/* $running_total = 0; */
/* $odd = 0; */
/* foreach($lease['Receipt'] AS $charge) { */
/* $amount = $charge['total']; */
/* $balance = $amount; */
/* foreach ($charge['Receipt'] AS $receipt) */
/* $balance -= $receipt['ChargesReceipt']['amount']; */
/* $running_total += $balance; */
/* $charge_amount = 0; */
/* $payment_amount = 0; */
/* foreach($receipt['Charge'] AS $charge) */
/* $charge_amount += $charge['ChargesReceipt']['amount']; */
/* foreach($receipt['Payment'] AS $payment) */
/* $payment_amount += $payment['amount']; */
/* foreach ($charge['Receipt'] AS $receipt) { */
/* $amount = -1 * $receipt['ChargesReceipt']['amount']; */
/* $running_total += $amount; */
/* $rows[] = array($html->link('#'.$receipt['id'], */
/* array('controller' => 'receipts', */
/* 'action' => 'view', */
/* $receipt['id'])), */
/* datefmt($receipt['stamp']), */
/* $receipt['comment'], */
/* currency($amount), */
/* currency($running_total)); */
/* $row_class[] = array('receipt', ($odd % 2) ? 'oddrow' : 'evnrow'); */
/* $headers = array($paginator->sort('Transaction', 'transaction_id'), */
/* $paginator->sort('entry_id'), */
/* $paginator->sort('Date', 'stamp'), */
/* $paginator->sort('customer_id'), */
/* $paginator->sort('comment'), */
/* $paginator->sort('debit'), */
/* $paginator->sort('credit'), */
/* $paginator->sort('total')); */
/* } */
/* $rows[] = array($html->link('#'.$charge['id'], */
/* array('controller' => 'charges', */
/* 'action' => 'view', */
/* $charge['id'])), */
/* datefmt($charge['charge_date']), */
/* datefmt($charge['charge_to_date']), */
/* $charge['ChargeType']['name'], */
/* $charge['comment'], */
/* currency($amount), */
/* currency($balance), */
/* //currency($amount - $paid)); */
/* currency($running_total)); */
$rows = array();
$running_total = 0;
foreach($entries AS $entry) {
$transaction = $entry['Transaction'];
$customer = $entry['Customer'];
/* $row_class[] = array('charge', (++$odd % 2) ? 'oddrow' : 'evnrow'); */
/* } */
$credit = $debit = null;
$running_total += $entry['balance'];
/* echo ('<div class="ledger history charges">' . "\n"); */
/* echo $this->element('table', */
/* array('class' => 'item ledger list', */
/* 'caption' => $caption */
/* 'suppress_alternate_rows' => true, */
/* 'headers' => $headers, */
/* 'rows' => $rows, */
/* 'row_class' => $row_class, */
/* 'column_class' => $headers)); */
/* echo ('</div>' . "\n"); */
if (isset($entry['debit']))
$debit = $entry['debit'];
if (isset($entry['credit']))
$credit = $entry['credit'];
// Now that we've extracted top level 'entry' data
// move our variable to the meat of 'LedgerEntry' for clarity
$entry = $entry['LedgerEntry'];
/**********************************************************************
* Mixture
*/
if (isset($ledger['mix'])) {
$headers = array(/*'Charge/Receipt'*/'ID', 'Date', /*'Through',*/ 'Type', 'Comment', 'Amount', 'Total');
/* $mix = array_merge($lease['Charge'], $receipts); */
/* usort($mix, */
/* create_function('$a, $b', */
/* '$adate = TimeHelper::toUnix(isset($a["charge_date"]) ? $a["charge_date"] : $a["stamp"]); ' . */
/* '$bdate = TimeHelper::toUnix(isset($b["charge_date"]) ? $b["charge_date"] : $b["stamp"]); ' . */
/* 'return strcmp($adate, $bdate);') */
/* ); */
$rows = array();
$row_class = array();
$running_total = 0;
foreach ($transactions AS $transaction) {
$transaction_date = datefmt($transaction['stamp']);
if (isset($transaction['through_date']))
$transaction_date .= ' - '. datefmt($transaction['through_date']);
$comment = $transaction['comment'];
foreach ($transaction['Entry'] AS $entry) {
if ($entry['DebitAccount']['name'] === 'A/R') {
$name = $entry['CreditAccount']['name'];
$amount = $entry['amount'];
$class = 'charge';
}
elseif ($entry['CreditAccount']['name'] === 'A/R') {
$name = 'Payment';
$amount = -1 * $entry['amount'];
$class = 'payment';
}
else
continue;
$running_total += $amount;
$rows[] = array($html->link('#'.$transaction['id'],
array('controller' => 'transactions',
'action' => 'view',
$transaction['id'])),
$transaction_date,
$name,
$comment,
currency($amount),
currency($running_total));
$row_class[] = $class;
}
}
echo ('<div class="ledger history mix">' . "\n");
echo $this->element('table',
array('class' => 'item ledger list',
'caption' => $caption,
//'suppress_alternate_rows' => true,
'headers' => $headers,
'rows' => $rows,
'row_class' => $row_class,
'column_class' => $headers));
echo ('</div>' . "\n");
$html->link('#'.$entry['id'],
array('controller' => 'ledger_entries',
'action' => 'view',
$entry['id'])),
datefmt($transaction['stamp']),
$html->link($customer['name'],
array('controller' => 'customers',
'action' => 'view',
$customer['id'])),
comment(array($transaction['comment'], $entry['comment'])),
currency($debit),
currency($credit),
currency($running_total)
);
}
/**********************************************************************
* Match
*/
if (isset($ledger['match'])) {
$headers = array(/*'Charge/Receipt'*/'ID', 'Date', /*'Through',*/ 'Type', 'Comment', 'Amount', 'Total');
$rows = array();
$row_class = array();
$running_total = 0;
$odd = 0;
foreach($lease['Charge'] AS $charge) {
$amount = $charge['total'];
$running_total += $amount;
$rows[] = array($html->link('#'.$charge['id'],
array('controller' => 'charges',
'action' => 'view',
$charge['id'])),
datefmt($charge['charge_date']) .' - '. datefmt($charge['charge_to_date']),
$charge['ChargeType']['name'],
$charge['comment'],
currency($amount),
currency($running_total));
$row_class[] = array('charge', (++$odd % 2) ? 'oddrow' : 'evnrow');
foreach ($charge['Receipt'] AS $receipt) {
$amount = -1 * $receipt['ChargesReceipt']['amount'];
$running_total += $amount;
$rows[] = array($html->link('#'.$receipt['id'],
array('controller' => 'receipts',
'action' => 'view',
$receipt['id'])),
' -- ' . datefmt($receipt['stamp']),
'Payment Applied',
$receipt['comment'],
currency($amount),
currency($running_total));
$row_class[] = array('receipt', ($odd % 2) ? 'oddrow' : 'evnrow');
}
}
echo ('<div class="ledger history match">' . "\n");
echo $this->element('table',
array('class' => 'item ledger list',
echo $this->element('table',
array('class' => 'item account ledger list',
'caption' => $caption,
'suppress_alternate_rows' => true,
'headers' => $headers,
'rows' => $rows,
'row_class' => $row_class,
'column_class' => $headers));
echo ('</div>' . "\n");
}
'column_class' => $column_class));
/* if (isset($paginator)) { */
/* echo('<div class="paging">' . "\n"); */
/* echo $paginator->prev('<< '.__('previous', true), array(), null, array('class'=>'disabled')); */
/* echo(' | '); */
/* echo $paginator->numbers(); */
/* echo(' | '); */
/* echo $paginator->next(__('next', true).' >>', array(), null, array('class'=>'disabled')); */
/* echo('</div>' . "\n"); */
/* } */
?>

View File

@@ -0,0 +1,77 @@
<?php /* -*- mode:PHP -*- */
if (isset($heading))
echo $heading;
elseif (!isset($caption))
echo '<h2>'.__('Ledgers',true).'</h2>';
$headers = array_merge(array('Name'),
(isset($ledgers[0]['Account'])
? array('Account')
: array()),
array('Entries', 'Debits', 'Credits', 'Balance', 'Closed', 'Comment'));
$column_class = array();
foreach (array_intersect($column_class, array('Comment')) AS $k => $v) {
$column_class[$k] = 'comment';
}
if (isset($paginator)) {
echo $paginator->counter(array(
'format' => __('Page %page% of %pages%, showing %current% records (%start% - %end%) of %count% total', true)));
$headers = array_merge(array($paginator->sort('name')),
(isset($ledgers[0]['Account'])
? array($paginator->sort('Account', 'Account.name'))
: array()),
array($paginator->sort('entries'),
$paginator->sort('debits'),
$paginator->sort('credits'),
$paginator->sort('balance'),
$paginator->sort('closed'),
$paginator->sort('comment')));
}
$rows = array();
foreach ($ledgers as $ledger) {
if (isset($ledger[0]))
$ledger = array_merge($ledger[0], array_diff_key($ledger, array(0=>1)));
if (isset($ledger['Ledger']))
$ledger = array_merge($ledger['Ledger'], array_diff_key($ledger, array('Ledger'=>1)));
if (isset($ledger['Account']))
$account = $ledger['Account'];
$rows[] = array_merge(array($html->link($ledger['name'],
array('controller' => 'ledgers',
'action' => 'view',
$ledger['id']))),
(isset($ledger['Account'])
? array($html->link($account['name'],
array('controller' => 'accounts',
'action' => 'view',
$account['id'])))
: array()),
array($ledger['entries'],
currency($ledger['debits']),
currency($ledger['credits']),
currency($ledger['balance']),
$ledger['closed'] ? 'Closed' : 'Open',
$ledger['comment']));
}
echo $this->element('table',
array('class' => 'item ledger list',
'caption' => isset($caption) ? $caption : null,
'headers' => $headers,
'rows' => $rows,
'column_class' => $column_class));
if (isset($paginator)) {
echo('<div class="paging">' . "\n");
echo $paginator->prev('<< '.__('previous', true), array(), null, array('class'=>'disabled'));
echo(' | ');
echo $paginator->numbers();
echo(' | ');
echo $paginator->next(__('next', true).' >>', array(), null, array('class'=>'disabled'));
echo('</div>' . "\n");
}

View File

@@ -1,67 +0,0 @@
<?php /* -*- mode:PHP -*- */
if (isset($heading))
echo $heading;
else
echo '<h2>'.__('Payments',true).'</h2>';
function currency($number) {
if ($number < 0)
return "($ " . number_format(-1*$number, 2) . ")";
else
return "$ " . number_format($number, 2);
}
function datefmt($date) {
$date_fmt = 'm/d/Y';
return ($date
? date_format(date_create($date), $date_fmt)
: null);
}
$headers_manual = array('ID', 'Type', 'Receipt', 'Amount', 'Comment');
if (isset($paginator)) {
echo $paginator->counter(array(
'format' => __('Page %page% of %pages%, showing %current% records (%start% - %end%) of %count% total', true)));
$headers = array($paginator->sort('id'),
$paginator->sort('Type', 'payment_type'),
$paginator->sort('Receipt', 'receipt_id'),
$paginator->sort('amount'),
$paginator->sort('comment'));
} else {
$headers = $headers_manual;
}
$rows = array();
foreach ($payments as $payment) {
$rows[] = array($html->link($payment['Payment']['id'],
array('controller' => 'payments',
'action' => 'view',
$payment['Payment']['id'])),
$payment['PaymentType']['name'],
$html->link('#'.$payment['Receipt']['id'],
array('controller' => 'receipts',
'action' => 'view',
$payment['Receipt']['id'])),
currency($payment['Payment']['amount']),
$payment['Payment']['comment'],
);
}
echo $this->element('table',
array('class' => 'item payment list',
'headers' => $headers,
'rows' => $rows,
'column_class' => $headers_manual));
if (isset($paginator)) {
echo('<div class="paging">' . "\n");
echo $paginator->prev('<< '.__('previous', true), array(), null, array('class'=>'disabled'));
echo(' | ');
echo $paginator->numbers();
echo(' | ');
echo $paginator->next(__('next', true).' >>', array(), null, array('class'=>'disabled'));
echo('</div>' . "\n");
}

View File

@@ -32,7 +32,7 @@ if (isset($rows) && is_array($rows) && count($rows)) {
if (!is_array($rca))
$rca = array($rca);
foreach ($rca AS &$rc)
$rc = preg_replace("/ /", "-", strtolower($rc));
$rc = preg_replace("/ /", "-", preg_replace('/\./', '', strtolower($rc)));
}
// Same prework for column_class
@@ -40,7 +40,7 @@ if (isset($rows) && is_array($rows) && count($rows)) {
if (!is_array($cca))
$cca = array($cca);
foreach ($cca AS &$cc)
$cc = preg_replace("/ /", "-", strtolower($cc));
$cc = preg_replace("/ /", "-", preg_replace('/\./', '', strtolower($cc)));
}
// Associate each cell with the appropriate class(es).

View File

@@ -0,0 +1,65 @@
<?php /* -*- mode:PHP -*- */
if (isset($heading))
echo $heading;
elseif (!isset($caption))
echo '<h2>'.__('Transactions',true).'</h2>';
$headers = array('Id', 'Timestamp', 'Comment');
$column_class = array();
foreach (array_intersect($headers, array('Comment')) AS $k => $v) {
$column_class[$k] = 'comment';
}
foreach (array_intersect($headers, array('Id')) AS $k => $v) {
$column_class[$k] = 'id';
}
if (isset($paginator)) {
echo $paginator->counter(array(
'format' => __('Page %page% of %pages%, showing %current% records (%start% - %end%) of %count% total', true)));
$headers = array($paginator->sort('id'),
$paginator->sort('customer_id'),
$paginator->sort('Timestamp', 'stamp'),
$paginator->sort('Through', 'through_date'),
$paginator->sort('Due', 'due_date'),
$paginator->sort('comment'));
}
$rows = array();
foreach ($transactions as $transaction) {
$customer = $transaction['Customer'];
if (isset($transaction['Transaction']))
$transaction = $transaction['Transaction'];
$rows[] = array($html->link('#'.$transaction['id'],
array('controller' => 'transactions',
'action' => 'view',
$transaction['id'])),
$html->link($customer['name'],
array('controller' => 'customers',
'action' => 'view',
$customer['id'])),
datefmt($transaction['stamp']),
datefmt($transaction['through_date']),
datefmt($transaction['due_date']),
$transaction['comment']);
}
echo $this->element('table',
array('class' => 'item transaction list',
'caption' => isset($caption) ? $caption : null,
'headers' => $headers,
'rows' => $rows,
'column_class' => $column_class));
if (isset($paginator)) {
echo('<div class="paging">' . "\n");
echo $paginator->prev('<< '.__('previous', true), array(), null, array('class'=>'disabled'));
echo(' | ');
echo $paginator->numbers();
echo(' | ');
echo $paginator->next(__('next', true).' >>', array(), null, array('class'=>'disabled'));
echo('</div>' . "\n");
}

14
views/ledgers/index.ctp Normal file
View File

@@ -0,0 +1,14 @@
<div class="ledgers index">
<?php
function currency($number) {
if (!isset($number))
return null;
if ($number < 0)
return "($ " . number_format(-1*$number, 2) . ")";
else
return "$ " . number_format($number, 2);
}
?>
<?php echo $this->element('ledgers', array('heading' => '<h2>'.$heading.'</h2>')) ?>
</div>

98
views/ledgers/view.ctp Normal file
View File

@@ -0,0 +1,98 @@
<?php /* -*- mode:PHP -*- */ ?>
<div class="ledger view">
<?php
; // Editor alignment
function currency($number) {
if (!isset($number))
return null;
if ($number < 0)
return "($ " . number_format(-1*$number, 2) . ")";
else
return "$ " . number_format($number, 2);
}
function datefmt($date) {
$date_fmt = 'm/d/Y';
return ($date
? date_format(date_create($date), $date_fmt)
: null);
}
function comment($comment) {
if (isset($comment) && is_array($comment)) {
foreach (array_keys($comment) AS $k) {
if (!$comment[$k])
unset($comment[$k]);
}
return implode('; ', $comment);
}
return $comment;
}
/**********************************************************************
**********************************************************************
**********************************************************************
**********************************************************************
* Ledger Detail Main Section
*/
$rows = array(array('ID', $ledger['Ledger']['id']),
array('Name', $ledger['Ledger']['name']),
array('Account', $html->link($ledger['Account']['name'],
array('controller' => 'accounts',
'action' => 'view',
$ledger['Account']['id']))),
array('Closed', $ledger['Ledger']['closed']),
array('Comment', $ledger['Ledger']['comment']));
echo $this->element('table',
array('class' => 'item ledger detail',
'caption' => 'Ledger Detail',
'rows' => $rows,
'column_class' => array('field', 'value')));
/**********************************************************************
* Ledger Info Box
*/
?>
<DIV CLASS="infobox">
<DIV CLASS="summary balance">
Ledger Balance: <?php echo currency($balance); ?>
</DIV>
</DIV>
<DIV CLASS="detail supporting">
<?php
; // Editor alignment
/**********************************************************************
**********************************************************************
**********************************************************************
**********************************************************************
* Supporting Elements Section
*/
/**********************************************************************
* Ledger
*/
echo $this->element('ledger',
array('caption' => $ledger['Ledger']['name'],
'ledger' => array('id' => $ledger['Ledger']['id'],
'type' => $ledger['Account']['type']),
'entries' => $ledger['LedgerEntry']));
/* End "detail supporting" DIV */ ?>
</DIV>
</div>

View File

@@ -1,3 +0,0 @@
<div class="payments index">
<?php echo $this->element('payments', array('heading' => '<h2>'.$heading.'</h2>')) ?>
</div>

View File

@@ -1,43 +0,0 @@
<?php /* -*- mode:PHP -*- */ ?>
<div class="payments view">
<?php
function currency($number) {
if ($number < 0)
return "($ " . number_format(-1*$number, 2) . ")";
else
return "$ " . number_format($number, 2);
}
function datefmt($date) {
$date_fmt = 'm/d/Y';
return ($date
? date_format(date_create($date), $date_fmt)
: null);
}
/**********************************************************************
* Payment Info
*/
$rows = array(array('ID', $payment['Payment']['id']),
array('Type', $payment['PaymentType']['name']),
array('Receipt', $html->link('#'.$payment['Receipt']['id'],
array('controller' => 'receipts',
'action' => 'view',
$payment['Receipt']['id']))),
array('Amount', currency($payment['Payment']['amount'])),
array('Comment', $payment['Payment']['comment']));
echo $this->element('table',
array('class' => 'item payment detail',
'caption' => 'Payment Info',
'rows' => $rows,
'column_class' => array('field', 'value')));
?>
</div>

View File

@@ -1,3 +0,0 @@
<div class="receipts index">
<?php echo $this->element('receipts', array('heading' => '<h2>'.$heading.'</h2>')) ?>
</div>

View File

@@ -1,116 +0,0 @@
<?php /* -*- mode:PHP -*- */ ?>
<div class="receipts view">
<?php
function currency($number) {
if ($number < 0)
return "($ " . number_format(-1*$number, 2) . ")";
else
return "$ " . number_format($number, 2);
}
function datefmt($date) {
$date_fmt = 'm/d/Y';
return ($date
? date_format(date_create($date), $date_fmt)
: null);
}
/**********************************************************************
* Receipt Info
*/
$rows = array(array('ID', $receipt['Receipt']['id']),
array('Timestamp', datefmt($receipt['Receipt']['stamp'])),
array('Comment', $receipt['Receipt']['comment']));
echo $this->element('table',
array('class' => 'item receipt detail',
'caption' => 'Receipt Info',
'rows' => $rows,
'column_class' => array('field', 'value')));
?>
<DIV CLASS="infobox receipt">
<DIV CLASS="summary grand payment">
Amount Received: <?php echo currency($paymentAmount); ?>
</DIV>
<DIV CLASS="summary grand charge">
Amount Applied: <?php echo currency($chargeAmount); ?>
</DIV>
</DIV>
<?php
/**********************************************************************
* Payments
*/
$headers = array('ID', 'Type', 'Comment', 'Amount', 'Total');
$rows = array();
$running_total = 0;
foreach($receipt['Payment'] AS $payment) {
$amount = $payment['amount'];
$running_total += $amount;
$rows[] = array($html->link('#'.$payment['id'],
array('controller' => 'payments',
'action' => 'view',
$payment['id'])),
$payment['PaymentType']['name'],
$payment['comment'],
currency($payment['amount']),
currency($running_total)
);
}
echo $this->element('table',
array('class' => 'item payment list',
'caption' => 'Payments in Receipt',
'headers' => $headers,
'rows' => $rows,
'column_class' => $headers));
/**********************************************************************
* Charges
*/
$headers = array('ID', 'Date', /*'Due',*/ 'Type', 'Lease', 'Comment', 'Amount' /*, 'Tax', 'Subtotal'*/, 'Applied', /*'Total'*/);
$rows = array();
$running_total = 0;
foreach($receipt['Charge'] AS $charge) {
$amount = $charge['total'];
$running_total += $amount;
$rows[] = array($html->link('#'.$charge['id'],
array('controller' => 'charges',
'action' => 'view',
$charge['id'])),
datefmt($charge['charge_date']) .' - '. datefmt($charge['charge_to_date']),
//datefmt($charge['due_date']),
$charge['ChargeType']['name'],
'#'.$charge['Lease']['number'],
$charge['comment'],
//currency($charge['amount']),
//currency($charge['tax']),
currency($charge['total']),
currency($charge['ChargesReceipt']['amount']),
//currency($running_total)
);
}
echo $this->element('table',
array('class' => 'item charge list',
'caption' => 'Charges Applied Towards',
'headers' => $headers,
'rows' => $rows,
'column_class' => $headers));
?>
</div>

View File

@@ -0,0 +1,13 @@
<div class="transactions index">
<?php
function datefmt($date) {
$date_fmt = 'm/d/Y';
return ($date
? date_format(date_create($date), $date_fmt)
: null);
}
?>
<?php echo $this->element('transactions', array('heading' => '<h2>'.$heading.'</h2>')) ?>
</div>

102
views/transactions/view.ctp Normal file
View File

@@ -0,0 +1,102 @@
<?php /* -*- mode:PHP -*- */ ?>
<div class="transaction view">
<?php
function currency($number) {
if ($number < 0)
return "($ " . number_format(-1*$number, 2) . ")";
else
return "$ " . number_format($number, 2);
}
function datefmt($date) {
$date_fmt = 'm/d/Y';
return ($date
? date_format(date_create($date), $date_fmt)
: null);
}
/**********************************************************************
**********************************************************************
**********************************************************************
**********************************************************************
* Transaction Detail Main Section
*/
$rows = array(array('ID', $transaction['Transaction']['id']),
array('Timestamp', datefmt($transaction['Transaction']['stamp'])),
array('Comment', $transaction['Transaction']['comment']));
echo $this->element('table',
array('class' => 'item transaction detail',
'caption' => 'Transaction Info',
'rows' => $rows,
'column_class' => array('field', 'value')));
/**********************************************************************
* Transaction Info Box
*/
?>
<DIV CLASS="infobox">
<DIV CLASS="summary grand debit">
Debits: <?php echo currency($debitAmount); ?>
</DIV>
<DIV CLASS="summary grand credit">
Credits: <?php echo currency($creditAmount); ?>
</DIV>
</DIV>
<DIV CLASS="detail supporting">
<?php
; // Editor alignment
/**********************************************************************
**********************************************************************
**********************************************************************
**********************************************************************
* Supporting Elements Section
*/
/**********************************************************************
* Entries
*/
$headers = array('Name', 'Debit', 'Credit', 'Comment', 'Amount', 'Total');
$rows = array();
$running_total = 0;
foreach($transaction['LedgerEntry'] AS $entry) {
$amount = $entry['amount'];
$running_total += $amount;
$rows[] = array($entry['name'],
$html->link($entry['DebitLedger']['name'],
array('controller' => 'ledgers',
'action' => 'view',
$entry['DebitLedger']['id'])),
$html->link($entry['CreditLedger']['name'],
array('controller' => 'ledgers',
'action' => 'view',
$entry['CreditLedger']['id'])),
$entry['comment'],
currency($entry['amount']),
currency($running_total)
);
}
echo $this->element('table',
array('class' => 'item entry list',
'caption' => 'Entries in Transaction',
'headers' => $headers,
'rows' => $rows,
'column_class' => $headers));
/* End "detail supporting" DIV */ ?>
</DIV>
</div>

View File

@@ -1,6 +1,6 @@
<?php /* -*- mode:PHP -*- */ ?>
<div class="units view">
<div class="unit view">
<?php
@@ -9,17 +9,22 @@ function currency($amount) {
}
function datefmt($date) {
if (!$date) return null;
$date_fmt = 'm/d/Y';
return TimeHelper::format($date_fmt, $date);
}
function datetimefmt($date) {
if (!$date) return null;
return TimeHelper::nice($date);
}
/**********************************************************************
* Unit Info
**********************************************************************
**********************************************************************
**********************************************************************
* Unit Detail Main Section
*/
$rows = array(array('Name', $unit['Unit']['name']),
@@ -33,8 +38,12 @@ echo $this->element('table',
'column_class' => array('field', 'value')));
/**********************************************************************
* Unit Info Box
*/
?>
<DIV CLASS="infobox unit">
<DIV CLASS="infobox">
<DIV CLASS="summary grand deposit">
Security Deposit: <?php echo currency($outstandingDeposit); ?>
</DIV>
@@ -42,7 +51,17 @@ echo $this->element('table',
Balance: <?php echo currency($outstandingBalance); ?>
</DIV>
</DIV>
<DIV CLASS="detail supporting">
<?php
; // Editor alignment
/**********************************************************************
**********************************************************************
**********************************************************************
**********************************************************************
* Supporting Elements Section
*/
/**********************************************************************
@@ -52,10 +71,10 @@ $headers = array('Lease', 'Tenant', 'Signed', 'Move-In', 'Move-Out', 'Rent', 'De
$rows = array();
foreach($unit['Lease'] AS $lease) {
$rows[] = array('#'.$lease['number'],
$html->link($lease['Contact'][0]['display_name'],
array('controller' => 'contacts',
$html->link($lease['Customer']['name'],
array('controller' => 'customers',
'action' => 'view',
$lease['Contact'][0]['id'])),
$lease['Customer']['id'])),
datefmt($lease['lease_date']),
datefmt($lease['movein_date']),
datefmt($lease['moveout_date']),
@@ -76,12 +95,15 @@ echo $this->element('table',
* Ledger History
*/
foreach($unit['Lease'] AS $lease) {
$caption = 'Lease #'.$lease['number'].' (Tenant: '.$lease['Contact'][0]['display_name'].')';
pr($lease);
$caption = 'Lease #'.$lease['number'].' (Tenant: '.$lease['Customer']['name'].')';
echo $this->element('ledger',
array('lease' => $lease,
'caption' => $caption,
'ledger' => array('charges'=>1, 'receipts'=>1, 'match'=>1, 'zmix'=>1)));
array('caption' => $caption,
'entries' => $lease['Customer']['Transaction'],
'ledger' => array('mix'=>1)));
}
?>
/* End "detail supporting" DIV */ ?>
</DIV>
</div>

View File

@@ -60,45 +60,16 @@ tr.evnrow { background: #f4f4f4; }
/************************************************************
************************************************************
* Item table formats
* Item detail formats
* (such as Tenant Info, Unit Info, etc)
*/
/* Item listing width and borders */
table.detail { width : 60%; }
table.list { width : 100%; }
/* Text alignment exceptions */
table.list td.id { text-align: center; }
/* White spacing exceptions */
td.comment { white-space: normal; }
/* Detail Tables (such as Tenant Info, Unit Info, etc) */
table.detail { float: left; }
table.detail { width : 60%;
float: left; }
table.detail td.field { width: 10em; }
/* List Tables (listing multiple items of one type) */
table.list { clear: both; }
div.detail.supporting { clear : both; }
/* Contact methods */
table.list.phone td.preference ,
table.list.email td.preference ,
table.list.address td.preference { width: 18em; }
table.list.phone td.phone ,
table.list.email td.email ,
table.list.address td.address { width: 15em; }
table.list.phone td.comment ,
table.list.email td.comment ,
table.list.address td.comment { width: auto; }
/* Leases */
table.list.lease td.comment { width : 99%; }
/* Ledger Entries */
table.list.ledger td { border-top : 1px dashed #ccc; }
table.list.ledger td.date.receipt { padding-left: 1em; }
table.list.ledger td.evnrow { background: #f4f4f4; }
table.list.ledger td.comment { width : 99%; }
/************************************************************
@@ -123,6 +94,48 @@ div.summary { color: #993;
}
/************************************************************
************************************************************
* Item table formats
* (listing multiple items of one type)
*/
/* Item listing width and borders */
table.list { width : 100%; }
/* Text alignment exceptions */
table.list td.id { text-align: center; }
table.list td.currency { text-align: right; }
/* White spacing exceptions */
td.comment { white-space: normal; }
/* Contacts */
table.list.contact td.comment { width : 66%; }
/* Contact methods */
table.list.phone td.preference ,
table.list.email td.preference ,
table.list.address td.preference { width: 18em; }
table.list.phone td.phone ,
table.list.email td.email ,
table.list.address td.address { width: 15em; }
table.list.phone td.comment ,
table.list.email td.comment ,
table.list.address td.comment { width: auto; }
/* Leases */
table.list.lease td.comment { width : 99%; }
/* Ledger Entries */
table.list.ledger td { border-top : 1px dashed #ccc; }
table.list.ledger td.date.receipt { padding-left: 1em; }
table.list.ledger td.evnrow { background: #f4f4f4; }
table.list.ledger td.comment { width : 99%; }
/* Account Ledger Entries */
/************************************************************
************************************************************
* General Style Info