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

@@ -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'),
// Models
'ChargeType',
'Receipt' => array(// Models
'Payment'
),
)
//'Contact' => array('alias' => 'PrimaryContact'),
// 'PrimaryContact',
'Customer' => array('fields' => array('id', 'name'),
// Models
'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'];
}
}
}