Compare commits
50 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 0848ab5055 | |||
| 52c72b08b2 | |||
| fc71c058fb | |||
| dd5402d2f1 | |||
| f473a91870 | |||
| cdd274adf7 | |||
| 8ea0822ed1 | |||
| 492e70b2f6 | |||
| abff728a37 | |||
| b8c4257f95 | |||
| 5f715cc076 | |||
| f40dc205f9 | |||
| feaabd29d9 | |||
| f48e7d8907 | |||
| 991b5a3317 | |||
| 68585a0b30 | |||
| a9a570d666 | |||
| 15c4b96a2a | |||
| ce252f2e70 | |||
| 4b857ff11f | |||
| 6661d26c76 | |||
| b409bf09d1 | |||
| b488054106 | |||
| 59398cb3f0 | |||
| 1145d293b2 | |||
| 2feb7f60a4 | |||
| bd6cc37d4a | |||
| 8dae1ccf84 | |||
| 50449205b4 | |||
| 77c038e880 | |||
| 44bdb384f5 | |||
| 2b135b0e66 | |||
| 23ec1b6b20 | |||
| 8f4f3c054e | |||
| 1249854514 | |||
| 7805e4d229 | |||
| 54c7287ee4 | |||
| bcec2a9891 | |||
| e772ff8755 | |||
| 3288969b0d | |||
| d268b6fe7e | |||
| e9b31d964c | |||
| 47d362750e | |||
| 47af64aefe | |||
| 1ca704157b | |||
| 8a3be97d41 | |||
| 05a4ee38f0 | |||
| 0e68fea04b | |||
| a9f47d73ba | |||
| 5b5e478bd0 |
@@ -0,0 +1,54 @@
|
|||||||
|
<?php
|
||||||
|
/* SVN FILE: $Id: app_controller.php 7945 2008-12-19 02:16:01Z gwoo $ */
|
||||||
|
/**
|
||||||
|
* Short description for file.
|
||||||
|
*
|
||||||
|
* This file is application-wide controller file. You can put all
|
||||||
|
* application-wide controller-related methods here.
|
||||||
|
*
|
||||||
|
* PHP versions 4 and 5
|
||||||
|
*
|
||||||
|
* CakePHP(tm) : Rapid Development Framework (http://www.cakephp.org)
|
||||||
|
* Copyright 2005-2008, Cake Software Foundation, Inc. (http://www.cakefoundation.org)
|
||||||
|
*
|
||||||
|
* Licensed under The MIT License
|
||||||
|
* Redistributions of files must retain the above copyright notice.
|
||||||
|
*
|
||||||
|
* @filesource
|
||||||
|
* @copyright Copyright 2005-2008, Cake Software Foundation, Inc. (http://www.cakefoundation.org)
|
||||||
|
* @link http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
|
||||||
|
* @package cake
|
||||||
|
* @subpackage cake.app
|
||||||
|
* @since CakePHP(tm) v 0.2.9
|
||||||
|
* @version $Revision: 7945 $
|
||||||
|
* @modifiedby $LastChangedBy: gwoo $
|
||||||
|
* @lastmodified $Date: 2008-12-18 18:16:01 -0800 (Thu, 18 Dec 2008) $
|
||||||
|
* @license http://www.opensource.org/licenses/mit-license.php The MIT License
|
||||||
|
*/
|
||||||
|
/**
|
||||||
|
* Short description for class.
|
||||||
|
*
|
||||||
|
* Add your application-wide methods in the class below, your controllers
|
||||||
|
* will inherit them.
|
||||||
|
*
|
||||||
|
* @package cake
|
||||||
|
* @subpackage cake.app
|
||||||
|
*/
|
||||||
|
class AppController extends Controller {
|
||||||
|
var $helpers = array('Html', 'Number', 'Time');
|
||||||
|
|
||||||
|
function sideMenuLinks() {
|
||||||
|
return array(
|
||||||
|
array('name' => 'Common', 'header' => true),
|
||||||
|
array('name' => 'Site Map', 'url' => array('controller' => 'maps', 'action' => 'view', 1)),
|
||||||
|
array('name' => 'Tenants', 'url' => array('controller' => 'contacts', 'action' => 'index')),
|
||||||
|
array('name' => 'Units', 'url' => array('controller' => 'units', 'action' => 'index')),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function beforeRender() {
|
||||||
|
$this->set('sidemenu', $this->sideMenuLinks());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
?>
|
||||||
+109
@@ -0,0 +1,109 @@
|
|||||||
|
<?php
|
||||||
|
/* SVN FILE: $Id: app_model.php 7945 2008-12-19 02:16:01Z gwoo $ */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Application model for Cake.
|
||||||
|
*
|
||||||
|
* This file is application-wide model file. You can put all
|
||||||
|
* application-wide model-related methods here.
|
||||||
|
*
|
||||||
|
* PHP versions 4 and 5
|
||||||
|
*
|
||||||
|
* CakePHP(tm) : Rapid Development Framework (http://www.cakephp.org)
|
||||||
|
* Copyright 2005-2008, Cake Software Foundation, Inc. (http://www.cakefoundation.org)
|
||||||
|
*
|
||||||
|
* Licensed under The MIT License
|
||||||
|
* Redistributions of files must retain the above copyright notice.
|
||||||
|
*
|
||||||
|
* @filesource
|
||||||
|
* @copyright Copyright 2005-2008, Cake Software Foundation, Inc. (http://www.cakefoundation.org)
|
||||||
|
* @link http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
|
||||||
|
* @package cake
|
||||||
|
* @subpackage cake.app
|
||||||
|
* @since CakePHP(tm) v 0.2.9
|
||||||
|
* @version $Revision: 7945 $
|
||||||
|
* @modifiedby $LastChangedBy: gwoo $
|
||||||
|
* @lastmodified $Date: 2008-12-18 18:16:01 -0800 (Thu, 18 Dec 2008) $
|
||||||
|
* @license http://www.opensource.org/licenses/mit-license.php The MIT License
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Application model for Cake.
|
||||||
|
*
|
||||||
|
* Add your application-wide methods in the class below, your models
|
||||||
|
* will inherit them.
|
||||||
|
*
|
||||||
|
* @package cake
|
||||||
|
* @subpackage cake.app
|
||||||
|
*/
|
||||||
|
class AppModel extends Model {
|
||||||
|
|
||||||
|
//var $actsAs = array('Containable');
|
||||||
|
var $actsAs = array('Linkable');
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get Enum Values
|
||||||
|
* Snippet v0.1.3
|
||||||
|
* http://cakeforge.org/snippet/detail.php?type=snippet&id=112
|
||||||
|
*
|
||||||
|
* Gets the enum values for MySQL 4 and 5 to use in selectTag()
|
||||||
|
*/
|
||||||
|
function getEnumValues($columnName=null, $respectDefault=false)
|
||||||
|
{
|
||||||
|
if ($columnName==null) { return array(); } //no field specified
|
||||||
|
|
||||||
|
//Get the name of the table
|
||||||
|
$db =& ConnectionManager::getDataSource($this->useDbConfig);
|
||||||
|
$tableName = $db->fullTableName($this, false);
|
||||||
|
|
||||||
|
//Get the values for the specified column (database and version specific, needs testing)
|
||||||
|
$result = $this->query("SHOW COLUMNS FROM {$tableName} LIKE '{$columnName}'");
|
||||||
|
|
||||||
|
//figure out where in the result our Types are (this varies between mysql versions)
|
||||||
|
$types = null;
|
||||||
|
if ( isset( $result[0]['COLUMNS']['Type'] ) ) { //MySQL 5
|
||||||
|
$types = $result[0]['COLUMNS']['Type']; $default = $result[0]['COLUMNS']['Default'];
|
||||||
|
}
|
||||||
|
elseif ( isset( $result[0][0]['Type'] ) ) { //MySQL 4
|
||||||
|
$types = $result[0][0]['Type']; $default = $result[0][0]['Default'];
|
||||||
|
}
|
||||||
|
else { //types return not accounted for
|
||||||
|
return array();
|
||||||
|
}
|
||||||
|
|
||||||
|
//Get the values
|
||||||
|
return array_flip(array_merge(array(''), // MySQL sets 0 to be the empty string
|
||||||
|
explode("','", preg_replace("/(enum)\('(.+?)'\)/","\\2", $types))
|
||||||
|
));
|
||||||
|
} //end getEnumValues
|
||||||
|
|
||||||
|
|
||||||
|
// Overriding pagination, since the stupid count mechanism blows.
|
||||||
|
// This is also a crappy solution, especially if the query returns
|
||||||
|
// 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) {
|
||||||
|
/* 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($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);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
@echo off
|
|
||||||
%~dp0\scripts\sitelink2pmgr.pl %~dp0\db\schema.sql %~dp0db\vss.mdb %*
|
|
||||||
echo Done!
|
|
||||||
@@ -31,39 +31,6 @@
|
|||||||
* You can also use this to include or require any files in your application.
|
* You can also use this to include or require any files in your application.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
function INTERNAL_ERROR($message) {
|
|
||||||
echo '<DIV class="internal-error" style="color:#000; background:#c22; padding:0.5em 1.5em 0.5em 1.5em;">';
|
|
||||||
echo '<H1 style="margin-bottom:0.2em">INTERNAL ERROR:</H1>';
|
|
||||||
echo '<H2 style="margin-top:0; margin-left:1.5em">' . $message . '</H2>';
|
|
||||||
echo '<H4>This error was not caused by anything that you did wrong.';
|
|
||||||
echo '<BR>It is a problem within the application itself and should be reported to the administrator.</H4>';
|
|
||||||
|
|
||||||
// Print out the entire stack trace
|
|
||||||
echo "<HR>Stack Trace:<OL>";
|
|
||||||
$trace = debug_backtrace(false);
|
|
||||||
for ($i = 0; $i < count($trace); ++$i) {
|
|
||||||
$bline = $trace[$i]['line'];
|
|
||||||
$bfile = $trace[$i]['file'];
|
|
||||||
$bfile = str_replace(ROOT.DS, '', $bfile);
|
|
||||||
$bfile = str_replace(CAKE_CORE_INCLUDE_PATH.DS, '', $bfile);
|
|
||||||
|
|
||||||
if ($i < count($trace)-1) {
|
|
||||||
$bfunc = $trace[$i+1]['function'];
|
|
||||||
$bclas = $trace[$i+1]['class'];
|
|
||||||
} else {
|
|
||||||
$bfunc = null;
|
|
||||||
$bclas = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
echo("<LI>$bfile:$bline (" . ($bclas ? "$bclas::$bfunc" : "entry point") . ")</LI>\n");
|
|
||||||
}
|
|
||||||
echo '</OL>';
|
|
||||||
|
|
||||||
echo '</DIV>';
|
|
||||||
die();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The settings below can be used to set additional paths to models, views and controllers.
|
* The settings below can be used to set additional paths to models, views and controllers.
|
||||||
* This is related to Ticket #470 (https://trac.cakephp.org/ticket/470)
|
* This is related to Ticket #470 (https://trac.cakephp.org/ticket/470)
|
||||||
@@ -38,7 +38,7 @@
|
|||||||
*
|
*
|
||||||
* $uninflectedPlural = array('.*[nrlm]ese', '.*deer', '.*fish', '.*measles', '.*ois', '.*pox');
|
* $uninflectedPlural = array('.*[nrlm]ese', '.*deer', '.*fish', '.*measles', '.*ois', '.*pox');
|
||||||
*/
|
*/
|
||||||
$uninflectedPlural = array('.*cash');
|
$uninflectedPlural = array();
|
||||||
/**
|
/**
|
||||||
* This is a key => value array of plural irregular words.
|
* This is a key => value array of plural irregular words.
|
||||||
* If key matches then the value is returned.
|
* If key matches then the value is returned.
|
||||||
@@ -26,12 +26,14 @@
|
|||||||
* @lastmodified $Date: 2008-12-18 18:16:01 -0800 (Thu, 18 Dec 2008) $
|
* @lastmodified $Date: 2008-12-18 18:16:01 -0800 (Thu, 18 Dec 2008) $
|
||||||
* @license http://www.opensource.org/licenses/mit-license.php The MIT License
|
* @license http://www.opensource.org/licenses/mit-license.php The MIT License
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Here, we are connecting '/' (base path) to our site map.
|
* Here, we are connecting '/' (base path) to controller called 'Pages',
|
||||||
* It's hardcoded to map #1, but at some point we'll implement
|
* its action called 'display', and we pass a param to select the view file
|
||||||
* a login mechanism and the default path will be to log on instead.
|
* to use (in this case, /app/views/pages/home.ctp)...
|
||||||
*/
|
*/
|
||||||
Router::connect('/', array('controller' => 'maps', 'action' => 'view', '1'));
|
Router::connect('/', array('controller' => 'pages', 'action' => 'display', 'home'));
|
||||||
|
/**
|
||||||
|
* ...and connect the rest of 'Pages' controller's urls.
|
||||||
|
*/
|
||||||
|
Router::connect('/pages/*', array('controller' => 'pages', 'action' => 'display'));
|
||||||
?>
|
?>
|
||||||
@@ -0,0 +1,127 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
class ChargesController extends AppController {
|
||||||
|
var $paginate = array('limit' => 100,
|
||||||
|
'group' => 'Charge.id',
|
||||||
|
'order' => array('Charge.charge_date' => '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')),
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
/**************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
* override: sideMenuLinks
|
||||||
|
* - Generates controller specific links for the side menu
|
||||||
|
*/
|
||||||
|
function sideMenuLinks() {
|
||||||
|
return array_merge(parent::sideMenuLinks(), $this->sidemenu_links);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
* action: index
|
||||||
|
* - Lists all charges
|
||||||
|
*/
|
||||||
|
|
||||||
|
function index() {
|
||||||
|
$this->all();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
* action: cleared
|
||||||
|
* - Lists cleared charges
|
||||||
|
*/
|
||||||
|
|
||||||
|
function cleared() {
|
||||||
|
$this->all();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
* action: unresolved
|
||||||
|
* - Lists unresolved charges
|
||||||
|
*/
|
||||||
|
|
||||||
|
function unresolved() {
|
||||||
|
$this->all();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
* action: all
|
||||||
|
* - Lists all charges
|
||||||
|
*/
|
||||||
|
|
||||||
|
function all() {
|
||||||
|
$this->paginate = array_merge
|
||||||
|
($this->paginate,
|
||||||
|
array('link' =>
|
||||||
|
array(// Models
|
||||||
|
'ChargeType',
|
||||||
|
'Receipt',
|
||||||
|
'Lease' => array('fields' => array('number'))
|
||||||
|
),
|
||||||
|
));
|
||||||
|
|
||||||
|
$title = 'All Charges';
|
||||||
|
$this->set('title', $title); $this->set('heading', $title);
|
||||||
|
$this->set('charges', $this->paginate());
|
||||||
|
$this->render('index');
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
* action: view
|
||||||
|
* - Displays information about a specific charge
|
||||||
|
*/
|
||||||
|
|
||||||
|
function view($id = null) {
|
||||||
|
if (!$id) {
|
||||||
|
$this->Session->setFlash(__('Invalid Item.', true));
|
||||||
|
$this->redirect(array('action'=>'index'));
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->Charge->Behaviors->attach('Containable');
|
||||||
|
$this->Charge->contain
|
||||||
|
(array(// Models
|
||||||
|
'ChargeType',
|
||||||
|
'Receipt',
|
||||||
|
'Lease' => array('fields' => array('number')),
|
||||||
|
)
|
||||||
|
);
|
||||||
|
$charge = $this->Charge->read(null, $id);
|
||||||
|
//pr($charge);
|
||||||
|
|
||||||
|
$payment_amount = 0;
|
||||||
|
foreach($charge['Receipt'] AS $receipt)
|
||||||
|
$payment_amount += $receipt['ChargesReceipt']['amount'];
|
||||||
|
$balance_amount = $charge['Charge']['total'] - $payment_amount;
|
||||||
|
|
||||||
|
/* $this->sidemenu_links[] = */
|
||||||
|
/* array('name' => 'Operations', 'header' => true); */
|
||||||
|
/* $this->sidemenu_links[] = */
|
||||||
|
/* array('name' => 'Move-Out', 'url' => array('controller' => 'charges', 'action' => 'move-out')); */
|
||||||
|
|
||||||
|
$title = 'Charge #' . $charge['Charge']['id'];
|
||||||
|
$this->set(compact('charge', 'title',
|
||||||
|
'payment_amount',
|
||||||
|
'balance_amount'));
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,203 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
class ContactsController extends AppController {
|
||||||
|
var $paginate = array('limit' => 100,
|
||||||
|
'group' => 'Contact.id',
|
||||||
|
'order' => array('Contact.last_name' => 'ASC',
|
||||||
|
'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('name' => 'All Contacts', 'url' => array('controller' => 'contacts', '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: past
|
||||||
|
* - Lists all tenants, past and present
|
||||||
|
*/
|
||||||
|
|
||||||
|
function tenants() {
|
||||||
|
$this->paginate = array_merge
|
||||||
|
($this->paginate,
|
||||||
|
array('link' =>
|
||||||
|
array(// Models
|
||||||
|
'Lease' =>
|
||||||
|
array('fields' => array(),
|
||||||
|
'type' => 'INNER',
|
||||||
|
),
|
||||||
|
),
|
||||||
|
'conditions' => array('ContactsLease.type !=' => 'ALTERNATE')
|
||||||
|
));
|
||||||
|
|
||||||
|
$title = 'All Tenants';
|
||||||
|
$this->set('title', $title); $this->set('heading', $title);
|
||||||
|
$this->set('contacts', $this->paginate());
|
||||||
|
$this->render('index');
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
* 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('ContactsLease.type !=' => 'ALTERNATE',
|
||||||
|
'Lease.close_date IS NULL')
|
||||||
|
));
|
||||||
|
|
||||||
|
$title = 'Current Tenants';
|
||||||
|
$this->set('title', $title); $this->set('heading', $title);
|
||||||
|
$this->set('contacts', $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('ContactsLease.type !=' => 'ALTERNATE',
|
||||||
|
'Lease.close_date IS NOT NULL')
|
||||||
|
));
|
||||||
|
|
||||||
|
$title = 'Past Tenants';
|
||||||
|
$this->set('title', $title); $this->set('heading', $title);
|
||||||
|
$this->set('contacts', $this->paginate());
|
||||||
|
$this->render('index');
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
* action: all
|
||||||
|
* - Lists all contacts, including non-tenants
|
||||||
|
*/
|
||||||
|
|
||||||
|
function all() {
|
||||||
|
$title = 'All Contacts';
|
||||||
|
$this->set('title', $title); $this->set('heading', $title);
|
||||||
|
$this->set('contacts', $this->paginate());
|
||||||
|
$this->render('index');
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
* action: view
|
||||||
|
* - Displays information about a specific contact
|
||||||
|
*/
|
||||||
|
|
||||||
|
function view($id = null) {
|
||||||
|
if (!$id) {
|
||||||
|
$this->Session->setFlash(__('Invalid Item.', true));
|
||||||
|
$this->redirect(array('action'=>'index'));
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->Contact->Behaviors->attach('Containable');
|
||||||
|
$this->Contact->contain
|
||||||
|
(array(// Models
|
||||||
|
'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',
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
$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'));
|
||||||
|
|
||||||
|
$title = $contact['Contact']['display_name'];
|
||||||
|
$this->set(compact('contact', 'title',
|
||||||
|
'outstanding_balance',
|
||||||
|
'outstanding_deposit'));
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -2,44 +2,22 @@
|
|||||||
|
|
||||||
class MapsController extends AppController {
|
class MapsController extends AppController {
|
||||||
|
|
||||||
|
|
||||||
/**************************************************************************
|
/**************************************************************************
|
||||||
**************************************************************************
|
**************************************************************************
|
||||||
**************************************************************************
|
**************************************************************************
|
||||||
* action: index / all
|
* action: index
|
||||||
* - Generate a listing of maps
|
* - Generates a list of all site maps
|
||||||
*
|
*
|
||||||
* REVISIT <AP> 20090528:
|
* REVISIT <AP> 20090528:
|
||||||
* We'll need to present only those site area maps that correspond
|
* We'll need to present only those site area maps that correspond
|
||||||
* to the users particular site.
|
* to the users particular site.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
function index() { $this->all(); }
|
function index() {
|
||||||
function all() { $this->gridView('All Maps', 'all'); }
|
$this->Map->recursive = 0;
|
||||||
|
$this->set('maps', $this->paginate());
|
||||||
|
|
||||||
/**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
* virtuals: gridData
|
|
||||||
* - With the application controller handling the gridData action,
|
|
||||||
* these virtual functions ensure that the correct data is passed
|
|
||||||
* to jqGrid.
|
|
||||||
*/
|
|
||||||
|
|
||||||
function gridDataTables(&$params, &$model) {
|
|
||||||
return array
|
|
||||||
('link' => array('SiteArea' => array('fields' => array('SiteArea.id', 'SiteArea.name')),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function gridDataPostProcessLinks(&$params, &$model, &$records, $links) {
|
|
||||||
$links['Map'] = array('id');
|
|
||||||
return parent::gridDataPostProcessLinks($params, $model, $records, $links);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**************************************************************************
|
/**************************************************************************
|
||||||
**************************************************************************
|
**************************************************************************
|
||||||
**************************************************************************
|
**************************************************************************
|
||||||
@@ -53,7 +31,6 @@ class MapsController extends AppController {
|
|||||||
$this->redirect(array('action'=>'index'));
|
$this->redirect(array('action'=>'index'));
|
||||||
}
|
}
|
||||||
$this->set('info', $this->mapInfo($id, $requested_width));
|
$this->set('info', $this->mapInfo($id, $requested_width));
|
||||||
$this->set('title', "Site Map");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -151,6 +128,22 @@ class MapsController extends AppController {
|
|||||||
return $info;
|
return $info;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Temporary function
|
||||||
|
function unitStatusList() {
|
||||||
|
return
|
||||||
|
array('DELETED' => array(),
|
||||||
|
'DAMAGED' => array(),
|
||||||
|
'COMPANY' => array(),
|
||||||
|
'UNAVAILABLE' => array(),
|
||||||
|
'RESERVED' => array(),
|
||||||
|
'DIRTY' => array(),
|
||||||
|
'VACANT' => array(),
|
||||||
|
'OCCUPIED' => array(),
|
||||||
|
'LATE' => array(),
|
||||||
|
'LOCKED' => array(),
|
||||||
|
'LIENED' => array(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
/**************************************************************************
|
/**************************************************************************
|
||||||
**************************************************************************
|
**************************************************************************
|
||||||
@@ -160,10 +153,9 @@ class MapsController extends AppController {
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
function legend($id = null, $requested_width = 400) {
|
function legend($id = null, $requested_width = 400) {
|
||||||
$status = $this->Map->Unit->activeStatusEnums();
|
$status = $this->unitStatusList();
|
||||||
//pr($status);
|
$cols = 6;
|
||||||
$rows = 2;
|
$rows = (int)((count($status) + $cols - 1) / $cols);
|
||||||
$cols = (int)((count($status) + $rows - 1) / $rows);
|
|
||||||
|
|
||||||
$info = array('units' => array());
|
$info = array('units' => array());
|
||||||
|
|
||||||
@@ -191,7 +183,7 @@ class MapsController extends AppController {
|
|||||||
$item_width *= $screen_adjustment_factor;
|
$item_width *= $screen_adjustment_factor;
|
||||||
$item_depth *= $screen_adjustment_factor;
|
$item_depth *= $screen_adjustment_factor;
|
||||||
|
|
||||||
foreach ($status AS $code => $value) {
|
foreach ($status AS $code => $color) {
|
||||||
$info['units'][] = array('name' => $code,
|
$info['units'][] = array('name' => $code,
|
||||||
'status' => $code,
|
'status' => $code,
|
||||||
'width' => $item_width,
|
'width' => $item_width,
|
||||||
@@ -219,13 +211,9 @@ class MapsController extends AppController {
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
function image($info, $legend = false) {
|
function image($info, $legend = false) {
|
||||||
$debug = false;
|
$this->layout = null;
|
||||||
|
$this->autoLayout = false;
|
||||||
if (!$debug) {
|
Configure::write('debug', '0');
|
||||||
$this->layout = null;
|
|
||||||
$this->autoLayout = false;
|
|
||||||
Configure::write('debug', '0');
|
|
||||||
}
|
|
||||||
|
|
||||||
// Define our color palate
|
// Define our color palate
|
||||||
// REVISIT <AP>: 20090513
|
// REVISIT <AP>: 20090513
|
||||||
@@ -266,7 +254,9 @@ class MapsController extends AppController {
|
|||||||
$code['fg'] = $component;
|
$code['fg'] = $component;
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->set(compact('info', 'debug'));
|
//pr($info);
|
||||||
|
|
||||||
|
$this->set(compact('info'));
|
||||||
$this->render('image');
|
$this->render('image');
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,86 @@
|
|||||||
|
<?php
|
||||||
|
/* SVN FILE: $Id: pages_controller.php 7945 2008-12-19 02:16:01Z gwoo $ */
|
||||||
|
/**
|
||||||
|
* Static content controller.
|
||||||
|
*
|
||||||
|
* This file will render views from views/pages/
|
||||||
|
*
|
||||||
|
* PHP versions 4 and 5
|
||||||
|
*
|
||||||
|
* CakePHP(tm) : Rapid Development Framework (http://www.cakephp.org)
|
||||||
|
* Copyright 2005-2008, Cake Software Foundation, Inc. (http://www.cakefoundation.org)
|
||||||
|
*
|
||||||
|
* Licensed under The MIT License
|
||||||
|
* Redistributions of files must retain the above copyright notice.
|
||||||
|
*
|
||||||
|
* @filesource
|
||||||
|
* @copyright Copyright 2005-2008, Cake Software Foundation, Inc. (http://www.cakefoundation.org)
|
||||||
|
* @link http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
|
||||||
|
* @package cake
|
||||||
|
* @subpackage cake.cake.libs.controller
|
||||||
|
* @since CakePHP(tm) v 0.2.9
|
||||||
|
* @version $Revision: 7945 $
|
||||||
|
* @modifiedby $LastChangedBy: gwoo $
|
||||||
|
* @lastmodified $Date: 2008-12-18 18:16:01 -0800 (Thu, 18 Dec 2008) $
|
||||||
|
* @license http://www.opensource.org/licenses/mit-license.php The MIT License
|
||||||
|
*/
|
||||||
|
/**
|
||||||
|
* Static content controller
|
||||||
|
*
|
||||||
|
* Override this controller by placing a copy in controllers directory of an application
|
||||||
|
*
|
||||||
|
* @package cake
|
||||||
|
* @subpackage cake.cake.libs.controller
|
||||||
|
*/
|
||||||
|
class PagesController extends AppController {
|
||||||
|
/**
|
||||||
|
* Controller name
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
* @access public
|
||||||
|
*/
|
||||||
|
var $name = 'Pages';
|
||||||
|
/**
|
||||||
|
* Default helper
|
||||||
|
*
|
||||||
|
* @var array
|
||||||
|
* @access public
|
||||||
|
*/
|
||||||
|
var $helpers = array('Html');
|
||||||
|
/**
|
||||||
|
* This controller does not use a model
|
||||||
|
*
|
||||||
|
* @var array
|
||||||
|
* @access public
|
||||||
|
*/
|
||||||
|
var $uses = array();
|
||||||
|
/**
|
||||||
|
* Displays a view
|
||||||
|
*
|
||||||
|
* @param mixed What page to display
|
||||||
|
* @access public
|
||||||
|
*/
|
||||||
|
function display() {
|
||||||
|
$path = func_get_args();
|
||||||
|
|
||||||
|
$count = count($path);
|
||||||
|
if (!$count) {
|
||||||
|
$this->redirect('/');
|
||||||
|
}
|
||||||
|
$page = $subpage = $title = null;
|
||||||
|
|
||||||
|
if (!empty($path[0])) {
|
||||||
|
$page = $path[0];
|
||||||
|
}
|
||||||
|
if (!empty($path[1])) {
|
||||||
|
$subpage = $path[1];
|
||||||
|
}
|
||||||
|
if (!empty($path[$count - 1])) {
|
||||||
|
$title = Inflector::humanize($path[$count - 1]);
|
||||||
|
}
|
||||||
|
$this->set(compact('page', 'subpage', 'title'));
|
||||||
|
$this->render(join('/', $path));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
?>
|
||||||
@@ -0,0 +1,118 @@
|
|||||||
|
<?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'));
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,131 @@
|
|||||||
|
<?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'));
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,212 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
class UnitsController extends AppController {
|
||||||
|
var $paginate = array('limit' => 100,
|
||||||
|
'group' => 'Unit.id',
|
||||||
|
'order' => array('Unit.sort_order' => 'ASC'));
|
||||||
|
|
||||||
|
var $sidemenu_links =
|
||||||
|
array(array('name' => 'Units', 'header' => true),
|
||||||
|
array('name' => 'Occupied', 'url' => array('controller' => 'units', 'action' => 'occupied')),
|
||||||
|
array('name' => 'Vacant', 'url' => array('controller' => 'units', 'action' => 'vacant')),
|
||||||
|
array('name' => 'Unavailable', 'url' => array('controller' => 'units', 'action' => 'unavailable')),
|
||||||
|
array('name' => 'All', 'url' => array('controller' => 'units', '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 units
|
||||||
|
*/
|
||||||
|
|
||||||
|
function index() {
|
||||||
|
$this->all();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
* action: unavailable
|
||||||
|
* - Lists unavailable units
|
||||||
|
*/
|
||||||
|
|
||||||
|
function unavailable() {
|
||||||
|
$this->paginate = array_merge
|
||||||
|
($this->paginate,
|
||||||
|
array('link' =>
|
||||||
|
array(// Models
|
||||||
|
'UnitSize' => array('fields' => array('name')),
|
||||||
|
),
|
||||||
|
'conditions' => $this->Unit->conditionUnavailable()
|
||||||
|
));
|
||||||
|
|
||||||
|
$title = 'Unavailable Units';
|
||||||
|
$this->set('title', $title); $this->set('heading', $title);
|
||||||
|
$this->set('units', $this->paginate());
|
||||||
|
$this->render('index');
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
* action: vacant
|
||||||
|
* - Lists vacant units
|
||||||
|
*/
|
||||||
|
|
||||||
|
function vacant() {
|
||||||
|
$this->paginate = array_merge
|
||||||
|
($this->paginate,
|
||||||
|
array('link' =>
|
||||||
|
array(// Models
|
||||||
|
'UnitSize' => array('fields' => array('name')),
|
||||||
|
),
|
||||||
|
'conditions' => $this->Unit->conditionVacant()
|
||||||
|
));
|
||||||
|
|
||||||
|
$title = 'Vacant Units';
|
||||||
|
$this->set('title', $title); $this->set('heading', $title);
|
||||||
|
$this->set('units', $this->paginate());
|
||||||
|
$this->render('index');
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
* action: occupied
|
||||||
|
* - Lists occupied units
|
||||||
|
*/
|
||||||
|
|
||||||
|
function occupied() {
|
||||||
|
$this->paginate = array_merge
|
||||||
|
($this->paginate,
|
||||||
|
array('link' =>
|
||||||
|
array(// Models
|
||||||
|
'UnitSize' => array('fields' => array('name')),
|
||||||
|
'Lease' => array('fields' => array(),
|
||||||
|
|
||||||
|
// Models
|
||||||
|
'Contact' => array('fields' => array('display_name'),
|
||||||
|
//'type' => 'LEFT',
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
'conditions' => $this->Unit->conditionOccupied()
|
||||||
|
));
|
||||||
|
|
||||||
|
$title = 'Occupied Units';
|
||||||
|
$this->set('title', $title); $this->set('heading', $title);
|
||||||
|
$this->set('units', $this->paginate());
|
||||||
|
$this->render('index');
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
* action: all
|
||||||
|
* - Lists all units
|
||||||
|
*/
|
||||||
|
|
||||||
|
function all() {
|
||||||
|
$this->paginate = array_merge
|
||||||
|
($this->paginate,
|
||||||
|
array('link' =>
|
||||||
|
array(// Models
|
||||||
|
'UnitSize' => array('fields' => array('name')),
|
||||||
|
),
|
||||||
|
));
|
||||||
|
|
||||||
|
$title = 'All Units';
|
||||||
|
$this->set('title', $title); $this->set('heading', $title);
|
||||||
|
$this->set('units', $this->paginate());
|
||||||
|
$this->render('index');
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
* action: view
|
||||||
|
* - Displays information about a specific unit
|
||||||
|
*/
|
||||||
|
|
||||||
|
function view($id = null) {
|
||||||
|
if (!$id) {
|
||||||
|
$this->Session->setFlash(__('Invalid Item.', true));
|
||||||
|
$this->redirect(array('action'=>''));
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->Unit->Behaviors->attach('Containable');
|
||||||
|
$this->Unit->contain
|
||||||
|
(array(// Models
|
||||||
|
'UnitSize',
|
||||||
|
'Lease' =>
|
||||||
|
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'
|
||||||
|
),
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
$unit = $this->Unit->read(null, $id);
|
||||||
|
//pr($unit);
|
||||||
|
|
||||||
|
$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($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'];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->sidemenu_links[] =
|
||||||
|
array('name' => 'Operations', 'header' => true);
|
||||||
|
$this->sidemenu_links[] =
|
||||||
|
array('name' => 'Move-Out', 'url' => array('controller' => 'units', 'action' => 'move-out'));
|
||||||
|
|
||||||
|
$title = 'Unit ' . $unit['Unit']['name'];
|
||||||
|
$this->set(compact('unit', 'title',
|
||||||
|
'outstanding_balance',
|
||||||
|
'outstanding_deposit'));
|
||||||
|
}
|
||||||
|
}
|
||||||
-1359
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,29 @@
|
|||||||
|
<?php
|
||||||
|
class Account extends AppModel {
|
||||||
|
|
||||||
|
var $name = 'Account';
|
||||||
|
var $validate = array(
|
||||||
|
'id' => array('numeric'),
|
||||||
|
'name' => array('notempty'),
|
||||||
|
'external_name' => array('notempty')
|
||||||
|
);
|
||||||
|
|
||||||
|
//The Associations below have been created with all possible keys, those that are not needed can be removed
|
||||||
|
var $hasMany = array(
|
||||||
|
'ChargeType' => array(
|
||||||
|
'className' => 'ChargeType',
|
||||||
|
'foreignKey' => 'account_id',
|
||||||
|
'dependent' => false,
|
||||||
|
'conditions' => '',
|
||||||
|
'fields' => '',
|
||||||
|
'order' => '',
|
||||||
|
'limit' => '',
|
||||||
|
'offset' => '',
|
||||||
|
'exclusive' => '',
|
||||||
|
'finderQuery' => '',
|
||||||
|
'counterQuery' => ''
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
}
|
||||||
|
?>
|
||||||
@@ -0,0 +1,193 @@
|
|||||||
|
<?php
|
||||||
|
/*
|
||||||
|
* LinkableBehavior
|
||||||
|
* Light-weight approach for data mining on deep relations between models.
|
||||||
|
* Join tables based on model relations to easily enable right to left find operations.
|
||||||
|
*
|
||||||
|
* Can be used as a alternative to the ContainableBehavior:
|
||||||
|
* - On data fetching only in right to left operations,
|
||||||
|
* wich means that in "one to many" relations (hasMany, hasAndBelongsToMany)
|
||||||
|
* should only be used from the "many to one" tables. i.e:
|
||||||
|
* To fetch all Users assigneds to a Project with ProjectAssignment,
|
||||||
|
* $Project->find('all', array('link' => 'User', 'conditions' => 'project_id = 1'))
|
||||||
|
* - Won't produce the desired result as data came from users table will be lost.
|
||||||
|
* $User->find('all', array('link' => 'Project', 'conditions' => 'project_id = 1'))
|
||||||
|
* - Will fetch all users related to the specified project in one query
|
||||||
|
*
|
||||||
|
* - On data mining as a much lighter approach - can reduce 300+ query find operations
|
||||||
|
* in one single query with joins; "or your money back!" ;-)
|
||||||
|
*
|
||||||
|
* - Has the 'fields' param enabled to make it easy to replace Containable usage,
|
||||||
|
* only change the 'contain' param to 'link'.
|
||||||
|
*
|
||||||
|
* Linkable Behavior. Taking it easy in your DB.
|
||||||
|
* RafaelBandeira <rafaelbandeira3(at)gmail(dot)com>
|
||||||
|
*
|
||||||
|
* Licensed under The MIT License
|
||||||
|
* Redistributions of files must retain the above copyright notice.
|
||||||
|
*
|
||||||
|
* @version 1.0;
|
||||||
|
*/
|
||||||
|
|
||||||
|
class LinkableBehavior extends ModelBehavior {
|
||||||
|
|
||||||
|
protected $_key = 'link';
|
||||||
|
|
||||||
|
protected $_options = array(
|
||||||
|
'type' => true, 'table' => true, 'alias' => true, 'joins' => true,
|
||||||
|
'conditions' => true, 'fields' => true, 'reference' => true,
|
||||||
|
'class' => true, 'defaults' => true
|
||||||
|
);
|
||||||
|
|
||||||
|
protected $_defaults = array('type' => 'LEFT');
|
||||||
|
|
||||||
|
public function beforeFind(&$Model, $query) {
|
||||||
|
/* pr("Linkable::beforeFind() begin"); pr($query); */
|
||||||
|
if (isset($query[$this->_key])) {
|
||||||
|
$optionsDefaults = $this->_defaults + array('reference' => $Model->alias, $this->_key => array());
|
||||||
|
$optionsKeys = $this->_options + array($this->_key => true);
|
||||||
|
if (!isset($query['fields']) || $query['fields'] === true) {
|
||||||
|
//$query['fields'] = array_keys($Model->_schema);
|
||||||
|
$query['fields'] = $Model->getDataSource()->fields($Model);
|
||||||
|
} elseif (!is_array($query['fields'])) {
|
||||||
|
$query['fields'] = array($query['fields']);
|
||||||
|
}
|
||||||
|
$query = am(array('joins' => array()), $query, array('recursive' => -1));
|
||||||
|
$iterators[] = $query[$this->_key];
|
||||||
|
$cont = 0;
|
||||||
|
do {
|
||||||
|
$iterator = $iterators[$cont];
|
||||||
|
$defaults = $optionsDefaults;
|
||||||
|
if (isset($iterator['defaults'])) {
|
||||||
|
$defaults = array_merge($defaults, $iterator['defaults']);
|
||||||
|
unset($iterator['defaults']);
|
||||||
|
}
|
||||||
|
$iterations = Set::normalize($iterator);
|
||||||
|
foreach ($iterations as $alias => $options) {
|
||||||
|
if (is_null($options)) {
|
||||||
|
$options = array();
|
||||||
|
}
|
||||||
|
$options = am($defaults, compact('alias'), $options);
|
||||||
|
if (empty($options['alias'])) {
|
||||||
|
throw new InvalidArgumentException(sprintf('%s::%s must receive aliased links', get_class($this), __FUNCTION__));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (empty($options['table']) && empty($options['class'])) {
|
||||||
|
$options['class'] = $options['alias'];
|
||||||
|
} elseif (!empty($options['table']) && empty($options['class'])) {
|
||||||
|
$options['class'] = Inflector::classify($options['table']);
|
||||||
|
}
|
||||||
|
$_Model =& ClassRegistry::init($options['class']); // the incoming model to be linked in query
|
||||||
|
$Reference =& ClassRegistry::init($options['reference']); // the already in query model that links to $_Model
|
||||||
|
/* 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])) {
|
||||||
|
$type = $associations[$Reference->alias];
|
||||||
|
$association = $_Model->{$type}[$Reference->alias];
|
||||||
|
} else {
|
||||||
|
$_Model->bind($Reference->alias);
|
||||||
|
$type = 'belongsTo';
|
||||||
|
$association = $_Model->{$type}[$Reference->alias];
|
||||||
|
$_Model->unbindModel(array('belongsTo' => array($Reference->alias)));
|
||||||
|
}
|
||||||
|
|
||||||
|
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 (isset($association['with']))
|
||||||
|
$Link =& $_Model->{$association['with']};
|
||||||
|
else
|
||||||
|
$Link =& $_Model->{Inflector::classify($association['joinTable'])};
|
||||||
|
|
||||||
|
$linkAlias = $Link->alias;
|
||||||
|
//$linkAlias = $Link->alias . $options['alias'];
|
||||||
|
|
||||||
|
// Get the foreign key fields (for the link table) directly from
|
||||||
|
// the defined model associations, if they exists. This is the
|
||||||
|
// users direct specification, and therefore definitive if present.
|
||||||
|
$modelLink = $Link->escapeField($association['foreignKey'], $linkAlias);
|
||||||
|
$referenceLink = $Link->escapeField($association['associationForeignKey'], $linkAlias);
|
||||||
|
|
||||||
|
// If we haven't figured out the foreign keys, see if there is a
|
||||||
|
// model for the link table, and if it has the appropriate
|
||||||
|
// associations with the two tables we're trying to join.
|
||||||
|
if (empty($modelLink) && isset($Link->belongsTo[$_Model->alias]))
|
||||||
|
$modelLink = $Link->escapeField($Link->belongsTo[$_Model->alias]['foreignKey'], $linkAlias);
|
||||||
|
if (empty($referenceLink) && isset($Link->belongsTo[$Reference->alias]))
|
||||||
|
$referenceLink = $Link->escapeField($Link->belongsTo[$Reference->alias]['foreignKey'], $linkAlias);
|
||||||
|
|
||||||
|
// We're running quite thin here. None of the models spell
|
||||||
|
// out the appropriate linkages. We'll have to SWAG it.
|
||||||
|
if (empty($modelLink))
|
||||||
|
$modelLink = $Link->escapeField(Inflector::underscore($_Model->alias) . '_id', $linkAlias);
|
||||||
|
if (empty($referenceLink))
|
||||||
|
$referenceLink = $Link->escapeField(Inflector::underscore($Reference->alias) . '_id', $linkAlias);
|
||||||
|
|
||||||
|
// Get the primary key from the tables we're joining.
|
||||||
|
$referenceKey = $Reference->escapeField();
|
||||||
|
$modelKey = $_Model->escapeField();
|
||||||
|
|
||||||
|
// Join the linkage table to our model. We'll use an inner join,
|
||||||
|
// as the whole purpose of the linkage table is to make this
|
||||||
|
// connection. As we are embedding this join, the INNER will not
|
||||||
|
// cause any problem with the overall query, should the user not
|
||||||
|
// be concerned with whether or not the join has any results.
|
||||||
|
// They control that with the 'type' parameter which will be at
|
||||||
|
// the top level join.
|
||||||
|
$options['joins'][] = array('type' => 'INNER',
|
||||||
|
'alias' => $options['alias'],
|
||||||
|
'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}";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (empty($options['table'])) {
|
||||||
|
$options['table'] = $db->fullTableName($_Model, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!isset($options['fields']) || !is_array($options['fields']))
|
||||||
|
$options['fields'] = $db->fields($_Model);
|
||||||
|
elseif (!empty($options['fields']))
|
||||||
|
$options['fields'] = $db->fields($_Model, null, $options['fields']);
|
||||||
|
|
||||||
|
$query['fields'] = array_merge($query['fields'], $options['fields'],
|
||||||
|
(empty($association['fields'])
|
||||||
|
? array() : $db->fields($_Model, null, $association['fields'])));
|
||||||
|
|
||||||
|
|
||||||
|
$options[$this->_key] = am($options[$this->_key], array_diff_key($options, $optionsKeys));
|
||||||
|
$options = array_intersect_key($options, $optionsKeys);
|
||||||
|
if (!empty($options[$this->_key])) {
|
||||||
|
$iterators[] = $options[$this->_key] + array('defaults' => array_merge($defaults, array('reference' => $options['class'])));
|
||||||
|
}
|
||||||
|
$query['joins'][] = array_intersect_key($options, array('type' => true, 'alias' => true, 'table' => true, 'joins' => true, 'conditions' => true));
|
||||||
|
}
|
||||||
|
++$cont;
|
||||||
|
$notDone = isset($iterators[$cont]);
|
||||||
|
} while ($notDone);
|
||||||
|
}
|
||||||
|
/* pr("Linkable::beforeFind() end"); pr($query); */
|
||||||
|
return $query;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,53 @@
|
|||||||
|
<?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' => ''
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
}
|
||||||
|
?>
|
||||||
@@ -0,0 +1,39 @@
|
|||||||
|
<?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' => ''
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
}
|
||||||
|
?>
|
||||||
@@ -0,0 +1,76 @@
|
|||||||
|
<?php
|
||||||
|
class Contact extends AppModel {
|
||||||
|
|
||||||
|
var $name = 'Contact';
|
||||||
|
var $validate = array(
|
||||||
|
'id' => array('numeric'),
|
||||||
|
'display_name' => array('notempty'),
|
||||||
|
'id_federal' => array('ssn'),
|
||||||
|
'id_exp' => array('date')
|
||||||
|
);
|
||||||
|
|
||||||
|
var $hasAndBelongsToMany = array(
|
||||||
|
'Lease' => array(
|
||||||
|
'className' => 'Lease',
|
||||||
|
'joinTable' => 'contacts_leases',
|
||||||
|
'foreignKey' => 'contact_id',
|
||||||
|
'associationForeignKey' => 'lease_id',
|
||||||
|
'unique' => true,
|
||||||
|
'conditions' => '',
|
||||||
|
'fields' => '',
|
||||||
|
'order' => '',
|
||||||
|
'limit' => '',
|
||||||
|
'offset' => '',
|
||||||
|
'finderQuery' => '',
|
||||||
|
'deleteQuery' => '',
|
||||||
|
'insertQuery' => ''
|
||||||
|
),
|
||||||
|
'ContactAddress' => array(
|
||||||
|
'className' => 'ContactAddress',
|
||||||
|
'joinTable' => 'contacts_methods',
|
||||||
|
'foreignKey' => 'contact_id',
|
||||||
|
'associationForeignKey' => 'method_id',
|
||||||
|
'unique' => true,
|
||||||
|
'conditions' => "method = 'POST'",
|
||||||
|
'fields' => '',
|
||||||
|
'order' => '',
|
||||||
|
'limit' => '',
|
||||||
|
'offset' => '',
|
||||||
|
'finderQuery' => '',
|
||||||
|
'deleteQuery' => '',
|
||||||
|
'insertQuery' => ''
|
||||||
|
),
|
||||||
|
'ContactPhone' => array(
|
||||||
|
'className' => 'ContactPhone',
|
||||||
|
'joinTable' => 'contacts_methods',
|
||||||
|
'foreignKey' => 'contact_id',
|
||||||
|
'associationForeignKey' => 'method_id',
|
||||||
|
'unique' => true,
|
||||||
|
'conditions' => "method = 'PHONE'",
|
||||||
|
'fields' => '',
|
||||||
|
'order' => '',
|
||||||
|
'limit' => '',
|
||||||
|
'offset' => '',
|
||||||
|
'finderQuery' => '',
|
||||||
|
'deleteQuery' => '',
|
||||||
|
'insertQuery' => ''
|
||||||
|
),
|
||||||
|
'ContactEmail' => array(
|
||||||
|
'className' => 'ContactEmail',
|
||||||
|
'joinTable' => 'contacts_methods',
|
||||||
|
'foreignKey' => 'contact_id',
|
||||||
|
'associationForeignKey' => 'method_id',
|
||||||
|
'unique' => true,
|
||||||
|
'conditions' => "method = 'EMAIL'",
|
||||||
|
'fields' => '',
|
||||||
|
'order' => '',
|
||||||
|
'limit' => '',
|
||||||
|
'offset' => '',
|
||||||
|
'finderQuery' => '',
|
||||||
|
'deleteQuery' => '',
|
||||||
|
'insertQuery' => ''
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
}
|
||||||
|
?>
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
<?php
|
||||||
|
class ContactAddress extends AppModel {
|
||||||
|
|
||||||
|
var $name = 'ContactAddress';
|
||||||
|
var $validate = array(
|
||||||
|
'id' => array('numeric'),
|
||||||
|
'postcode' => array('postal')
|
||||||
|
);
|
||||||
|
|
||||||
|
var $hasAndBelongsToMany = array(
|
||||||
|
'Contact' => array(
|
||||||
|
'className' => 'Contact',
|
||||||
|
'joinTable' => 'contacts_methods',
|
||||||
|
'foreignKey' => 'method_id',
|
||||||
|
'associationForeignKey' => 'contact_id',
|
||||||
|
'unique' => true,
|
||||||
|
'conditions' => "method = 'POST'",
|
||||||
|
'fields' => '',
|
||||||
|
'order' => '',
|
||||||
|
'limit' => '',
|
||||||
|
'offset' => '',
|
||||||
|
'finderQuery' => '',
|
||||||
|
'deleteQuery' => '',
|
||||||
|
'insertQuery' => ''
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
?>
|
||||||
@@ -2,7 +2,6 @@
|
|||||||
class ContactEmail extends AppModel {
|
class ContactEmail extends AppModel {
|
||||||
|
|
||||||
var $name = 'ContactEmail';
|
var $name = 'ContactEmail';
|
||||||
var $displayField = 'email';
|
|
||||||
var $validate = array(
|
var $validate = array(
|
||||||
'id' => array('numeric'),
|
'id' => array('numeric'),
|
||||||
'email' => array('email')
|
'email' => array('email')
|
||||||
@@ -16,12 +15,15 @@ class ContactEmail extends AppModel {
|
|||||||
'associationForeignKey' => 'contact_id',
|
'associationForeignKey' => 'contact_id',
|
||||||
'unique' => true,
|
'unique' => true,
|
||||||
'conditions' => "method = 'EMAIL'",
|
'conditions' => "method = 'EMAIL'",
|
||||||
|
'fields' => '',
|
||||||
|
'order' => '',
|
||||||
|
'limit' => '',
|
||||||
|
'offset' => '',
|
||||||
|
'finderQuery' => '',
|
||||||
|
'deleteQuery' => '',
|
||||||
|
'insertQuery' => ''
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
function emailList() {
|
|
||||||
return $this->find('list');
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
?>
|
?>
|
||||||
@@ -0,0 +1,31 @@
|
|||||||
|
<?php
|
||||||
|
class ContactPhone extends AppModel {
|
||||||
|
|
||||||
|
var $name = 'ContactPhone';
|
||||||
|
var $validate = array(
|
||||||
|
'id' => array('numeric'),
|
||||||
|
//'type' => array('inlist'),
|
||||||
|
'phone' => array('phone'),
|
||||||
|
'ext' => array('numeric')
|
||||||
|
);
|
||||||
|
|
||||||
|
var $hasAndBelongsToMany = array(
|
||||||
|
'Contact' => array(
|
||||||
|
'className' => 'Contact',
|
||||||
|
'joinTable' => 'contacts_methods',
|
||||||
|
'foreignKey' => 'method_id',
|
||||||
|
'associationForeignKey' => 'contact_id',
|
||||||
|
'unique' => true,
|
||||||
|
'conditions' => "method = 'PHONE'",
|
||||||
|
'fields' => '',
|
||||||
|
'order' => '',
|
||||||
|
'limit' => '',
|
||||||
|
'offset' => '',
|
||||||
|
'finderQuery' => '',
|
||||||
|
'deleteQuery' => '',
|
||||||
|
'insertQuery' => ''
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
}
|
||||||
|
?>
|
||||||
@@ -0,0 +1,85 @@
|
|||||||
|
<?php
|
||||||
|
class Lease extends AppModel {
|
||||||
|
|
||||||
|
var $name = 'Lease';
|
||||||
|
var $validate = array(
|
||||||
|
'id' => array('numeric'),
|
||||||
|
'number' => array('alphanumeric'),
|
||||||
|
'lease_type_id' => array('numeric'),
|
||||||
|
'unit_id' => array('numeric'),
|
||||||
|
'late_schedule_id' => array('numeric'),
|
||||||
|
'lease_date' => array('date'),
|
||||||
|
'movein_planed_date' => array('date'),
|
||||||
|
'movein_date' => array('date'),
|
||||||
|
'moveout_date' => array('date'),
|
||||||
|
'moveout_planed_date' => array('date'),
|
||||||
|
'notice_given_date' => array('date'),
|
||||||
|
'notice_received_date' => array('date'),
|
||||||
|
'close_date' => array('date'),
|
||||||
|
'deposit' => array('money'),
|
||||||
|
'amount' => array('money'),
|
||||||
|
'next_amount' => array('money'),
|
||||||
|
'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',
|
||||||
|
'foreignKey' => 'lease_type_id',
|
||||||
|
'conditions' => '',
|
||||||
|
'fields' => '',
|
||||||
|
'order' => ''
|
||||||
|
),
|
||||||
|
'Unit' => array(
|
||||||
|
'className' => 'Unit',
|
||||||
|
'foreignKey' => 'unit_id',
|
||||||
|
'conditions' => '',
|
||||||
|
'fields' => '',
|
||||||
|
'order' => ''
|
||||||
|
),
|
||||||
|
'LateSchedule' => array(
|
||||||
|
'className' => 'LateSchedule',
|
||||||
|
'foreignKey' => 'late_schedule_id',
|
||||||
|
'conditions' => '',
|
||||||
|
'fields' => '',
|
||||||
|
'order' => ''
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
var $hasMany = array(
|
||||||
|
'Charge' => array(
|
||||||
|
'className' => 'Charge',
|
||||||
|
'foreignKey' => 'lease_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' => ''
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
}
|
||||||
|
?>
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
<?php
|
||||||
|
class LeaseType extends AppModel {
|
||||||
|
|
||||||
|
var $name = 'LeaseType';
|
||||||
|
var $validate = array(
|
||||||
|
'id' => array('numeric'),
|
||||||
|
'name' => array('notempty')
|
||||||
|
);
|
||||||
|
|
||||||
|
//The Associations below have been created with all possible keys, those that are not needed can be removed
|
||||||
|
var $hasMany = array(
|
||||||
|
'Lease' => array(
|
||||||
|
'className' => 'Lease',
|
||||||
|
'foreignKey' => 'lease_type_id',
|
||||||
|
'dependent' => false,
|
||||||
|
'conditions' => '',
|
||||||
|
'fields' => '',
|
||||||
|
'order' => '',
|
||||||
|
'limit' => '',
|
||||||
|
'offset' => '',
|
||||||
|
'exclusive' => '',
|
||||||
|
'finderQuery' => '',
|
||||||
|
'counterQuery' => ''
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
}
|
||||||
|
?>
|
||||||
@@ -0,0 +1,44 @@
|
|||||||
|
<?php
|
||||||
|
class Map extends AppModel {
|
||||||
|
|
||||||
|
var $name = 'Map';
|
||||||
|
var $validate = array(
|
||||||
|
'id' => array('numeric'),
|
||||||
|
'site_id' => array('numeric'),
|
||||||
|
'site_area_id' => array('numeric'),
|
||||||
|
'name' => array('notempty'),
|
||||||
|
'width' => array('numeric'),
|
||||||
|
'depth' => array('numeric')
|
||||||
|
);
|
||||||
|
|
||||||
|
//The Associations below have been created with all possible keys, those that are not needed can be removed
|
||||||
|
var $belongsTo = array(
|
||||||
|
'SiteArea' => array(
|
||||||
|
'className' => 'SiteArea',
|
||||||
|
'foreignKey' => 'site_area_id',
|
||||||
|
'conditions' => '',
|
||||||
|
'fields' => '',
|
||||||
|
'order' => ''
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
var $hasAndBelongsToMany = array(
|
||||||
|
'Unit' => array(
|
||||||
|
'className' => 'Unit',
|
||||||
|
'joinTable' => 'maps_units',
|
||||||
|
'foreignKey' => 'map_id',
|
||||||
|
'associationForeignKey' => 'unit_id',
|
||||||
|
'unique' => true,
|
||||||
|
'conditions' => '',
|
||||||
|
'fields' => '',
|
||||||
|
'order' => '',
|
||||||
|
'limit' => '',
|
||||||
|
'offset' => '',
|
||||||
|
'finderQuery' => '',
|
||||||
|
'deleteQuery' => '',
|
||||||
|
'insertQuery' => ''
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
}
|
||||||
|
?>
|
||||||
@@ -0,0 +1,31 @@
|
|||||||
|
<?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' => ''
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
}
|
||||||
|
?>
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
<?php
|
||||||
|
class PaymentType extends AppModel {
|
||||||
|
|
||||||
|
var $name = 'PaymentType';
|
||||||
|
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',
|
||||||
|
'dependent' => false,
|
||||||
|
'conditions' => '',
|
||||||
|
'fields' => '',
|
||||||
|
'order' => '',
|
||||||
|
'limit' => '',
|
||||||
|
'offset' => '',
|
||||||
|
'exclusive' => '',
|
||||||
|
'finderQuery' => '',
|
||||||
|
'counterQuery' => ''
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
}
|
||||||
|
?>
|
||||||
@@ -0,0 +1,46 @@
|
|||||||
|
<?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' => ''
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
}
|
||||||
|
?>
|
||||||
@@ -0,0 +1,41 @@
|
|||||||
|
<?php
|
||||||
|
class Site extends AppModel {
|
||||||
|
|
||||||
|
var $name = 'Site';
|
||||||
|
var $validate = array(
|
||||||
|
'id' => array('numeric'),
|
||||||
|
'name' => array('notempty')
|
||||||
|
);
|
||||||
|
|
||||||
|
//The Associations below have been created with all possible keys, those that are not needed can be removed
|
||||||
|
var $hasMany = array(
|
||||||
|
'SiteArea' => array(
|
||||||
|
'className' => 'SiteArea',
|
||||||
|
'foreignKey' => 'site_id',
|
||||||
|
'dependent' => false,
|
||||||
|
'conditions' => '',
|
||||||
|
'fields' => '',
|
||||||
|
'order' => '',
|
||||||
|
'limit' => '',
|
||||||
|
'offset' => '',
|
||||||
|
'exclusive' => '',
|
||||||
|
'finderQuery' => '',
|
||||||
|
'counterQuery' => ''
|
||||||
|
),
|
||||||
|
'SiteOption' => array(
|
||||||
|
'className' => 'SiteOption',
|
||||||
|
'foreignKey' => 'site_id',
|
||||||
|
'dependent' => false,
|
||||||
|
'conditions' => '',
|
||||||
|
'fields' => '',
|
||||||
|
'order' => '',
|
||||||
|
'limit' => '',
|
||||||
|
'offset' => '',
|
||||||
|
'exclusive' => '',
|
||||||
|
'finderQuery' => '',
|
||||||
|
'counterQuery' => ''
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
}
|
||||||
|
?>
|
||||||
@@ -0,0 +1,34 @@
|
|||||||
|
<?php
|
||||||
|
class SiteArea extends AppModel {
|
||||||
|
|
||||||
|
var $name = 'SiteArea';
|
||||||
|
var $validate = array(
|
||||||
|
'id' => array('numeric'),
|
||||||
|
'site_id' => array('numeric'),
|
||||||
|
'name' => array('notempty')
|
||||||
|
);
|
||||||
|
|
||||||
|
//The Associations below have been created with all possible keys, those that are not needed can be removed
|
||||||
|
var $belongsTo = array(
|
||||||
|
'Site' => array(
|
||||||
|
'className' => 'Site',
|
||||||
|
'foreignKey' => 'site_id',
|
||||||
|
'conditions' => '',
|
||||||
|
'fields' => '',
|
||||||
|
'order' => ''
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
var $hasOne = array(
|
||||||
|
'Map' => array(
|
||||||
|
'className' => 'Map',
|
||||||
|
'foreignKey' => 'site_area_id',
|
||||||
|
'dependent' => false,
|
||||||
|
'conditions' => '',
|
||||||
|
'fields' => '',
|
||||||
|
'order' => ''
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
}
|
||||||
|
?>
|
||||||
@@ -0,0 +1,79 @@
|
|||||||
|
<?php
|
||||||
|
class Unit extends AppModel {
|
||||||
|
|
||||||
|
var $name = 'Unit';
|
||||||
|
var $validate = array(
|
||||||
|
'id' => array('numeric'),
|
||||||
|
'unit_size_id' => array('numeric'),
|
||||||
|
'name' => array('notempty'),
|
||||||
|
'sort_order' => array('numeric'),
|
||||||
|
'walk_order' => array('numeric'),
|
||||||
|
'deposit' => array('money'),
|
||||||
|
'amount' => array('money')
|
||||||
|
);
|
||||||
|
|
||||||
|
var $belongsTo = array(
|
||||||
|
'UnitSize' => array(
|
||||||
|
'className' => 'UnitSize',
|
||||||
|
'foreignKey' => 'unit_size_id',
|
||||||
|
'conditions' => '',
|
||||||
|
'fields' => '',
|
||||||
|
'order' => ''
|
||||||
|
),
|
||||||
|
/* 'Map' => array( */
|
||||||
|
/* 'className' => 'MapsUnit', */
|
||||||
|
/* 'foreignKey' => 'unit_id', */
|
||||||
|
/* 'conditions' => '', */
|
||||||
|
/* 'fields' => '', */
|
||||||
|
/* 'order' => '' */
|
||||||
|
/* ) */
|
||||||
|
);
|
||||||
|
|
||||||
|
var $hasMany = array(
|
||||||
|
'Lease' => array(
|
||||||
|
'className' => 'Lease',
|
||||||
|
'foreignKey' => 'unit_id',
|
||||||
|
'dependent' => false,
|
||||||
|
'conditions' => '',
|
||||||
|
'fields' => '',
|
||||||
|
'order' => '',
|
||||||
|
'limit' => '',
|
||||||
|
'offset' => '',
|
||||||
|
'exclusive' => '',
|
||||||
|
'finderQuery' => '',
|
||||||
|
'counterQuery' => ''
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
function statusEnums() {
|
||||||
|
static $status_enums;
|
||||||
|
if (!isset($status_enums))
|
||||||
|
$status_enums = $this->getEnumValues('status');
|
||||||
|
return $status_enums;
|
||||||
|
}
|
||||||
|
|
||||||
|
function statusValue($enum) {
|
||||||
|
$enums = $this->statusEnums();
|
||||||
|
return $enums[$enum];
|
||||||
|
}
|
||||||
|
|
||||||
|
function occupiedEnumValue() {
|
||||||
|
return statusValue('OCCUPIED');
|
||||||
|
}
|
||||||
|
|
||||||
|
function conditionOccupied() {
|
||||||
|
return ('Unit.status >= ' . $this->statusValue('OCCUPIED'));
|
||||||
|
}
|
||||||
|
|
||||||
|
function conditionVacant() {
|
||||||
|
return ('Unit.status BETWEEN ' .
|
||||||
|
($this->statusValue('UNAVAILABLE')+1) .
|
||||||
|
' AND ' .
|
||||||
|
($this->statusValue('OCCUPIED')-1));
|
||||||
|
}
|
||||||
|
|
||||||
|
function conditionUnavailable() {
|
||||||
|
return ('Unit.status <= ' . $this->statusValue('UNAVAILABLE'));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,43 @@
|
|||||||
|
<?php
|
||||||
|
class UnitSize extends AppModel {
|
||||||
|
|
||||||
|
var $name = 'UnitSize';
|
||||||
|
var $validate = array(
|
||||||
|
'id' => array('numeric'),
|
||||||
|
'unit_type_id' => array('numeric'),
|
||||||
|
'code' => array('notempty'),
|
||||||
|
'name' => array('notempty'),
|
||||||
|
'width' => array('numeric'),
|
||||||
|
'depth' => array('numeric'),
|
||||||
|
'deposit' => array('money'),
|
||||||
|
'amount' => array('money')
|
||||||
|
);
|
||||||
|
|
||||||
|
var $belongsTo = array(
|
||||||
|
'UnitType' => array(
|
||||||
|
'className' => 'UnitType',
|
||||||
|
'foreignKey' => 'unit_type_id',
|
||||||
|
'conditions' => '',
|
||||||
|
'fields' => '',
|
||||||
|
'order' => ''
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
var $hasMany = array(
|
||||||
|
'Unit' => array(
|
||||||
|
'className' => 'Unit',
|
||||||
|
'foreignKey' => 'unit_size_id',
|
||||||
|
'dependent' => false,
|
||||||
|
'conditions' => '',
|
||||||
|
'fields' => '',
|
||||||
|
'order' => '',
|
||||||
|
'limit' => '',
|
||||||
|
'offset' => '',
|
||||||
|
'exclusive' => '',
|
||||||
|
'finderQuery' => '',
|
||||||
|
'counterQuery' => ''
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
}
|
||||||
|
?>
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
<?php
|
||||||
|
class UnitType extends AppModel {
|
||||||
|
|
||||||
|
var $name = 'UnitType';
|
||||||
|
var $validate = array(
|
||||||
|
'id' => array('numeric'),
|
||||||
|
'code' => array('notempty'),
|
||||||
|
'name' => array('notempty')
|
||||||
|
);
|
||||||
|
|
||||||
|
var $hasMany = array(
|
||||||
|
'UnitSize' => array(
|
||||||
|
'className' => 'UnitSize',
|
||||||
|
'foreignKey' => 'unit_type_id',
|
||||||
|
'dependent' => false,
|
||||||
|
'conditions' => '',
|
||||||
|
'fields' => '',
|
||||||
|
'order' => '',
|
||||||
|
'limit' => '',
|
||||||
|
'offset' => '',
|
||||||
|
'exclusive' => '',
|
||||||
|
'finderQuery' => '',
|
||||||
|
'counterQuery' => ''
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
}
|
||||||
|
?>
|
||||||
@@ -1,68 +0,0 @@
|
|||||||
N - GATE
|
|
||||||
N - ACH / CREDIT CARD PROCESSING
|
|
||||||
Y - CREDIT CARD ENTRY
|
|
||||||
Y - ACH ENTRY
|
|
||||||
P - INVENTORY TRACKING / POS
|
|
||||||
Y - UNIT TYPES
|
|
||||||
Y - UNIT SIZES
|
|
||||||
Y - UNITS
|
|
||||||
Y - MOVE IN / OUT
|
|
||||||
Y - UNIT TRANSFERS
|
|
||||||
Y - LEASE TRACKING (PDF Generation)
|
|
||||||
Y - LETTERS (PDF Generation)
|
|
||||||
Y - REMINDERS
|
|
||||||
Y - MULTIPLE LATE RENT SCHEDULES (Tenant A vs Tenant B)
|
|
||||||
Y - ACCOUNTING (assign charges to accounts)
|
|
||||||
Y - DETAILED REPORTING (HTML & PDF)
|
|
||||||
Y - SITE MAP; HOT CLICKABLE
|
|
||||||
P - PROSPECTIVE TENANTS
|
|
||||||
Y - MARKETING
|
|
||||||
P - RESERVATIONS
|
|
||||||
P - MOVE OUT NOTICES
|
|
||||||
P - MULTI-SITE (One database, multiple sites)
|
|
||||||
Y - GENERATE GEOGRAPHIC MAP OF CUSTOMERS USING GOOGLE!
|
|
||||||
- Major advantage here... MapPoint only choice with competitors
|
|
||||||
Y - WEB BASED
|
|
||||||
Y - CUSTOMER VIEW / MANAGER VIEW
|
|
||||||
Y - CUSTOMERS CAN CREATE ACCOUNTS, VIEW HISTORY
|
|
||||||
Y - CUSTOMERS CAN SIGN UP FOR AUTO PAY
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
----------------------------------------------------------------------
|
|
||||||
----------------------------------------------------------------------
|
|
||||||
Operations to be functional
|
|
||||||
'X' marks functionality sufficiently completed
|
|
||||||
|
|
||||||
X - Create Customer ID/Account
|
|
||||||
X - Add Contact information to Customer
|
|
||||||
X - Move Customer into Unit
|
|
||||||
? - Enter Rent Concessions given
|
|
||||||
X - Asses Rent Charges
|
|
||||||
X - Asses Late Charges
|
|
||||||
X - Asses Security Deposits
|
|
||||||
X - Receive and record Checks
|
|
||||||
X - Receive and record Money Orders
|
|
||||||
X - Receive and record Cash
|
|
||||||
X - Receive and record ACH Deposits
|
|
||||||
? - Reverse rent charges (early moveout on prepaid occupancy)
|
|
||||||
X - Handle NSF checks
|
|
||||||
X - Assess NSF Fees
|
|
||||||
X - Determine Lease Paid-Through status
|
|
||||||
- Report: List of customers overdue
|
|
||||||
X - Flag unit as overlocked
|
|
||||||
X - Flag unit as evicting
|
|
||||||
X - Flag unit as normal status
|
|
||||||
X - Flag unit as dirty
|
|
||||||
- Enter notes when communicating with Customer
|
|
||||||
X - Accept pre-payments
|
|
||||||
X - Record Customer Move-Out from Unit
|
|
||||||
X - Record utilization of Security Deposit
|
|
||||||
X - Record issuing of a refund
|
|
||||||
- Record Deposit into Petty Cash
|
|
||||||
- Record Payment from Petty Cash to expenses
|
|
||||||
X - Record Petty Cash to refund.
|
|
||||||
X - Write Off Bad Debt
|
|
||||||
X - Perform a Deposit
|
|
||||||
X - Close the Books (nightly / weekly, etc)
|
|
||||||
X - Determine Rents Collected for a given period.
|
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -1,807 +0,0 @@
|
|||||||
<?php
|
|
||||||
/* SVN FILE: $Id: app_controller.php 7945 2008-12-19 02:16:01Z gwoo $ */
|
|
||||||
/**
|
|
||||||
* Short description for file.
|
|
||||||
*
|
|
||||||
* This file is application-wide controller file. You can put all
|
|
||||||
* application-wide controller-related methods here.
|
|
||||||
*
|
|
||||||
* PHP versions 4 and 5
|
|
||||||
*
|
|
||||||
* CakePHP(tm) : Rapid Development Framework (http://www.cakephp.org)
|
|
||||||
* Copyright 2005-2008, Cake Software Foundation, Inc. (http://www.cakefoundation.org)
|
|
||||||
*
|
|
||||||
* Licensed under The MIT License
|
|
||||||
* Redistributions of files must retain the above copyright notice.
|
|
||||||
*
|
|
||||||
* @filesource
|
|
||||||
* @copyright Copyright 2005-2008, Cake Software Foundation, Inc. (http://www.cakefoundation.org)
|
|
||||||
* @link http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
|
|
||||||
* @package cake
|
|
||||||
* @subpackage cake.app
|
|
||||||
* @since CakePHP(tm) v 0.2.9
|
|
||||||
* @version $Revision: 7945 $
|
|
||||||
* @modifiedby $LastChangedBy: gwoo $
|
|
||||||
* @lastmodified $Date: 2008-12-18 18:16:01 -0800 (Thu, 18 Dec 2008) $
|
|
||||||
* @license http://www.opensource.org/licenses/mit-license.php The MIT License
|
|
||||||
*/
|
|
||||||
/**
|
|
||||||
* Short description for class.
|
|
||||||
*
|
|
||||||
* Add your application-wide methods in the class below, your controllers
|
|
||||||
* will inherit them.
|
|
||||||
*
|
|
||||||
* @package cake
|
|
||||||
* @subpackage cake.app
|
|
||||||
*/
|
|
||||||
class AppController extends Controller {
|
|
||||||
var $helpers = array('Html', 'Form', 'Javascript', 'Format', 'Time', 'Grid');
|
|
||||||
var $components = array('DebugKit.Toolbar');
|
|
||||||
|
|
||||||
function sideMenuLinks() {
|
|
||||||
return array(
|
|
||||||
array('name' => 'Common', 'header' => true),
|
|
||||||
array('name' => 'Site Map', 'url' => array('controller' => 'maps', 'action' => 'view', 1)),
|
|
||||||
array('name' => 'Units', 'url' => array('controller' => 'units', 'action' => 'index')),
|
|
||||||
array('name' => 'Leases', 'url' => array('controller' => 'leases', 'action' => 'index')),
|
|
||||||
array('name' => 'Customers', 'url' => array('controller' => 'customers', 'action' => 'index')),
|
|
||||||
array('name' => 'Accounts', 'url' => array('controller' => 'accounts', 'action' => 'index')),
|
|
||||||
array('name' => 'Debug', 'header' => true),
|
|
||||||
array('name' => 'Un-Nuke', 'url' => '#', 'htmlAttributes' =>
|
|
||||||
array('onclick' => '$(".pr-section").show(); return false;')),
|
|
||||||
array('name' => 'Contacts', 'url' => array('controller' => 'contacts', 'action' => 'index')),
|
|
||||||
array('name' => 'Ledgers', 'url' => array('controller' => 'ledgers', 'action' => 'index')),
|
|
||||||
array('name' => 'New Ledgers', 'url' => array('controller' => 'accounts', 'action' => 'newledger')),
|
|
||||||
array('name' => 'RESET DATA', 'url' => array('controller' => 'accounts', 'action' => 'reset_data')),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
function beforeRender() {
|
|
||||||
$this->set('sidemenu', $this->sideMenuLinks());
|
|
||||||
}
|
|
||||||
|
|
||||||
function reset_data() {
|
|
||||||
$this->layout = null;
|
|
||||||
$this->autoLayout = false;
|
|
||||||
$this->autoRender = false;
|
|
||||||
Configure::write('debug', '0');
|
|
||||||
$script = $_SERVER['DOCUMENT_ROOT'] . '/pmgr/build.cmd';
|
|
||||||
echo "<P>" . date('r') . "\n";
|
|
||||||
//echo "<P>Script: $script" . "\n";
|
|
||||||
$db = & $this->Account->getDataSource();
|
|
||||||
$script .= ' "' . $db->config['database'] . '"';
|
|
||||||
$script .= ' "' . $db->config['login'] . '"';
|
|
||||||
$script .= ' "' . $db->config['password'] . '"';
|
|
||||||
$handle = popen($script . ' 2>&1', 'r');
|
|
||||||
//echo "<P>Handle: $handle; " . gettype($handle) . "\n";
|
|
||||||
echo "<P><PRE>\n";
|
|
||||||
while (($read = fread($handle, 2096))) {
|
|
||||||
echo $read;
|
|
||||||
}
|
|
||||||
echo "</PRE>\n";
|
|
||||||
pclose($handle);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
* helper: gridView
|
|
||||||
* - called by derived controllers to create an index listing
|
|
||||||
*/
|
|
||||||
|
|
||||||
function gridView($title, $action = null, $element = null) {
|
|
||||||
$this->set('title', $title);
|
|
||||||
// The resulting page will contain a grid, which will
|
|
||||||
// use ajax to obtain the actual data for this action
|
|
||||||
$this->set('action', $action ? $action : $this->params['action']);
|
|
||||||
$this->render('/elements/' . ($element ? $element : $this->params['controller']));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
* action: gridData
|
|
||||||
* - Fetches the actual data requested by grid as XML
|
|
||||||
*/
|
|
||||||
|
|
||||||
function gridData() {
|
|
||||||
// Grab a copy of the parameters that control this request
|
|
||||||
$params = array();
|
|
||||||
if (isset($this->params['url']) && is_array($this->params['url']))
|
|
||||||
$params = $this->params['url'];
|
|
||||||
|
|
||||||
// Do any preliminary setup necessary
|
|
||||||
$this->gridDataSetup($params);
|
|
||||||
|
|
||||||
// Get the top level model for this grid
|
|
||||||
$model = $this->gridDataModel($params);
|
|
||||||
|
|
||||||
// Get the number of records prior to pagination
|
|
||||||
$count = $this->gridDataCount($params, $model);
|
|
||||||
|
|
||||||
// Determine pagination configuration (and save to $params)
|
|
||||||
$pagination = $this->gridDataPagination($params, $model, $count);
|
|
||||||
|
|
||||||
// Retreive the appropriate subset of data
|
|
||||||
$records = $this->gridDataRecords($params, $model, $pagination);
|
|
||||||
|
|
||||||
// Post process the records
|
|
||||||
$this->gridDataPostProcess($params, $model, $records);
|
|
||||||
|
|
||||||
// Output the resulting record set
|
|
||||||
$this->gridDataOutput($params, $model, $records, $pagination);
|
|
||||||
|
|
||||||
// Call out to finalize everything
|
|
||||||
$this->gridDataFinalize($params);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
* virtual: gridData* functions
|
|
||||||
* - These set up the context for the grid data, and will
|
|
||||||
* need to be overridden in the derived class for anything
|
|
||||||
* other than the most basic of grids.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
* gridData SETUP / CLEANUP
|
|
||||||
*/
|
|
||||||
|
|
||||||
function gridDataModel(&$params) {
|
|
||||||
return $this->{$this->modelClass};
|
|
||||||
}
|
|
||||||
|
|
||||||
function gridDataSetup(&$params) {
|
|
||||||
// Assume we're debugging.
|
|
||||||
// The actual grid request will set this to false
|
|
||||||
$debug = true;
|
|
||||||
|
|
||||||
if (isset($this->passedArgs['debug']))
|
|
||||||
$debug = $this->passedArgs['debug'];
|
|
||||||
|
|
||||||
$params['debug'] = $debug;
|
|
||||||
|
|
||||||
if ($debug) {
|
|
||||||
ob_start();
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
$this->layout = null;
|
|
||||||
$this->autoLayout = false;
|
|
||||||
$this->autoRender = false;
|
|
||||||
Configure::write('debug', '0');
|
|
||||||
}
|
|
||||||
|
|
||||||
// Establish some defaults (except for serialized items)
|
|
||||||
$params = array_merge(array('page' => 1,
|
|
||||||
'rows' => 20),
|
|
||||||
$params);
|
|
||||||
|
|
||||||
// Unserialize our complex structure of post data.
|
|
||||||
// This SHOULD always be set, except when debugging
|
|
||||||
if (isset($params['post']))
|
|
||||||
$params['post'] = unserialize($params['post']);
|
|
||||||
else
|
|
||||||
$params['post'] = array();
|
|
||||||
|
|
||||||
// Unserialize our complex structure of dynamic post data
|
|
||||||
if (isset($params['dynamic_post']))
|
|
||||||
$params['dynamic_post'] = unserialize($params['dynamic_post']);
|
|
||||||
else
|
|
||||||
$params['dynamic_post'] = null;
|
|
||||||
|
|
||||||
// Unserialize our complex structure of dynamic post data
|
|
||||||
if (isset($params['dynamic_post_replace']))
|
|
||||||
$params['dynamic_post_replace'] = unserialize($params['dynamic_post_replace']);
|
|
||||||
else
|
|
||||||
$params['dynamic_post_replace'] = null;
|
|
||||||
|
|
||||||
// Merge the static and dynamic post data
|
|
||||||
if (!empty($params['dynamic_post']))
|
|
||||||
$params['post'] = array_merge_recursive($params['post'], $params['dynamic_post']);
|
|
||||||
if (!empty($params['dynamic_post_replace']))
|
|
||||||
$params['post'] = array_merge($params['post'], $params['dynamic_post_replace']);
|
|
||||||
|
|
||||||
// This SHOULD always be set, except when debugging
|
|
||||||
if (!isset($params['post']['fields']))
|
|
||||||
$params['post']['fields'] = array($this->{$this->modelClass}->alias
|
|
||||||
.'.'.
|
|
||||||
$this->{$this->modelClass}->primaryKey);
|
|
||||||
|
|
||||||
// Make sure the action parameter at least exists, and
|
|
||||||
// promote it to the top level (since it drives the operation).
|
|
||||||
if (isset($params['post']['action']))
|
|
||||||
$params['action'] = $params['post']['action'];
|
|
||||||
else
|
|
||||||
$params['action'] = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
function gridDataFinalize(&$params) {
|
|
||||||
if ($params['debug']) {
|
|
||||||
$xml = ob_get_contents();
|
|
||||||
ob_end_clean();
|
|
||||||
|
|
||||||
$xml = preg_replace("/&/", "&", $xml);
|
|
||||||
$xml = preg_replace("/</", "<", $xml);
|
|
||||||
$xml = preg_replace("/>/", ">", $xml);
|
|
||||||
echo ("\n<PRE>\n$xml\n</PRE>\n");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
* gridData COUNTING
|
|
||||||
*/
|
|
||||||
|
|
||||||
function gridDataCount(&$params, &$model) {
|
|
||||||
// Establish the tables and conditions for counting
|
|
||||||
$query = array_intersect_key($this->gridDataCountTableSet($params, $model),
|
|
||||||
array('link'=>1, 'contain'=>1));
|
|
||||||
|
|
||||||
// Conditions for the count
|
|
||||||
$query['conditions'] = $this->gridDataCountConditionSet($params, $model);
|
|
||||||
|
|
||||||
// Grouping (which would not be typical)
|
|
||||||
$query['group'] = $this->gridDataCountGroup($params, $model);
|
|
||||||
|
|
||||||
// DEBUG PURPOSES ONLY!
|
|
||||||
$params['count_query'] = $query;
|
|
||||||
|
|
||||||
// Get the number of records prior to pagination
|
|
||||||
return $this->gridDataCountExecute($params, $model, $query);
|
|
||||||
}
|
|
||||||
|
|
||||||
function gridDataCountExecute(&$params, &$model, $query) {
|
|
||||||
return $model->find('count', $query);
|
|
||||||
}
|
|
||||||
|
|
||||||
function gridDataCountTables(&$params, &$model) {
|
|
||||||
// Same tables for counting as for retreiving
|
|
||||||
return $this->gridDataTables($params, $model);
|
|
||||||
}
|
|
||||||
|
|
||||||
function gridDataCountTableSet(&$params, &$model) {
|
|
||||||
// Preliminary set of tables
|
|
||||||
$query = array_intersect_key($this->gridDataCountTables($params, $model),
|
|
||||||
array('link'=>1, 'contain'=>1));
|
|
||||||
|
|
||||||
// Perform filtering based on user request: $params['post']['filter']
|
|
||||||
return array_intersect_key($this->gridDataFilterTables($params, $model, $query),
|
|
||||||
array('link'=>1, 'contain'=>1));
|
|
||||||
}
|
|
||||||
|
|
||||||
function gridDataCountConditions(&$params, &$model) {
|
|
||||||
// Same conditions for counting as for retreiving
|
|
||||||
return $this->gridDataConditions($params, $model);
|
|
||||||
}
|
|
||||||
|
|
||||||
function gridDataCountConditionSet(&$params, &$model) {
|
|
||||||
// Conditions for the count
|
|
||||||
$conditions = $this->gridDataCountConditions($params, $model);
|
|
||||||
|
|
||||||
// Perform filtering based on user request: $params['post']['filter']
|
|
||||||
return $this->gridDataFilterConditions($params, $model, $conditions);
|
|
||||||
}
|
|
||||||
|
|
||||||
function gridDataCountGroup(&$params, &$model) {
|
|
||||||
// Grouping will screw up the count, since it
|
|
||||||
// causes the results to be split into chunks
|
|
||||||
// based on the GROUP BY clause. We can't have
|
|
||||||
// more than one row of data in the count query,
|
|
||||||
// just a _single_ row with the actual count.
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
* gridData FILTERING
|
|
||||||
*/
|
|
||||||
|
|
||||||
function gridDataFilterTables(&$params, &$model, $query) {
|
|
||||||
if (isset($query['contain']))
|
|
||||||
$link = 'contain';
|
|
||||||
else
|
|
||||||
$link = 'link';
|
|
||||||
|
|
||||||
if (empty($params['post']['filter']))
|
|
||||||
return $query;
|
|
||||||
|
|
||||||
foreach ($params['post']['filter'] AS $filter => $filter_value) {
|
|
||||||
$split = $this->gridDataFilterSplit($params, $model, $filter, $filter_value);
|
|
||||||
|
|
||||||
/* pr(array('AppController::gridDataFilterTable' => */
|
|
||||||
/* array('checkpoint' => "Filter split") */
|
|
||||||
/* + compact('split'))); */
|
|
||||||
|
|
||||||
$table = $this->gridDataFilterTablesTable($params, $model, $split['table']);
|
|
||||||
if (!$table)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
$config = $this->gridDataFilterTablesConfig($params, $model, $split['table']);
|
|
||||||
|
|
||||||
/* pr(array('AppController::gridDataFilterTable' => */
|
|
||||||
/* array('checkpoint' => "Add filter config to query") */
|
|
||||||
/* + array('query[link]' => $query[$link]) */
|
|
||||||
/* + compact('config'))); */
|
|
||||||
|
|
||||||
// If the table is already part of the query, append to it
|
|
||||||
if ($table == $model->alias) {
|
|
||||||
$query[$link] =
|
|
||||||
array_merge_recursive(array_diff_key($config, array('fields'=>1)),
|
|
||||||
$query[$link]);
|
|
||||||
}
|
|
||||||
elseif (isset($query[$link][$table])) {
|
|
||||||
$query[$link][$table] =
|
|
||||||
array_merge_recursive($config, $query[$link][$table]);
|
|
||||||
}
|
|
||||||
elseif (in_array($table, $query[$link])) {
|
|
||||||
// REVISIT <AP>: 20090727
|
|
||||||
// This presents a dilema. $config may specify fields
|
|
||||||
// as array(), whereas the user has already indicated
|
|
||||||
// they desire ALL fields (by the fact that table is
|
|
||||||
// a member of the query['link'] array without anything
|
|
||||||
// specified). However, $config _could_ specify a
|
|
||||||
// non-standard field in the array, such as using SUM()
|
|
||||||
// or other equation. In that case, we'd have to add
|
|
||||||
// in all the fields of table to the array. That
|
|
||||||
// wouldn't be very hard, but I'll ignore it at the
|
|
||||||
// moment and wait until it's needed.
|
|
||||||
$key = array_search($table, $query[$link]);
|
|
||||||
$query[$link][$table] = array('fields' => null) + $config;
|
|
||||||
unset($query[$link][$key]);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
// Table is NOT already part of the query... set it now
|
|
||||||
$query[$link][$table] = $config;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* pr(array('post-filter-table-config' => */
|
|
||||||
/* array('query[link]' => $query[$link]))); */
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
return $query;
|
|
||||||
}
|
|
||||||
|
|
||||||
function gridDataFilterTablesTable(&$params, &$model, $table) {
|
|
||||||
// By default, don't add anything if the filter
|
|
||||||
// condition occurs on the actual model table
|
|
||||||
if ($table == $model->alias)
|
|
||||||
return null;
|
|
||||||
return $this->gridDataFilterTableName($params, $model, $table);
|
|
||||||
}
|
|
||||||
|
|
||||||
function gridDataFilterTablesConfig(&$params, &$model, $table) {
|
|
||||||
return array('fields' => array());
|
|
||||||
}
|
|
||||||
|
|
||||||
function gridDataFilterConditions(&$params, &$model, $conditions) {
|
|
||||||
if (empty($params['post']['filter']))
|
|
||||||
return $conditions;
|
|
||||||
|
|
||||||
foreach ($params['post']['filter'] AS $filter => $filter_value) {
|
|
||||||
$split = $this->gridDataFilterSplit($params, $model, $filter, $filter_value);
|
|
||||||
|
|
||||||
$table = $this->gridDataFilterConditionsTable($params, $model, $split['table']);
|
|
||||||
$key = $this->gridDataFilterConditionsKey($params, $model, $split['table'], $split['field']);
|
|
||||||
if (!$key)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
$conditions[]
|
|
||||||
= $this->gridDataFilterConditionsStatement($params, $model, $table, $key,
|
|
||||||
array_intersect_key
|
|
||||||
($split,
|
|
||||||
array('value'=>1,
|
|
||||||
'value_present'=>1)));
|
|
||||||
}
|
|
||||||
|
|
||||||
return $conditions;
|
|
||||||
}
|
|
||||||
|
|
||||||
function gridDataFilterConditionsTable(&$params, &$model, $table) {
|
|
||||||
return $this->gridDataFilterTableName($params, $model, $table);
|
|
||||||
}
|
|
||||||
|
|
||||||
function gridDataFilterConditionsKey(&$params, &$model, $table, $id) {
|
|
||||||
// REVISIT <AP>: 20090722
|
|
||||||
// When $id is null, we could instantiate the table,
|
|
||||||
// and use the _actual_ primary key. However, I don't
|
|
||||||
// expect that functionality to be used, and will just
|
|
||||||
// stick with 'id' for now.
|
|
||||||
return $id ? $id : 'id';
|
|
||||||
}
|
|
||||||
|
|
||||||
function gridDataFilterConditionsStatement(&$params, &$model, $table, $key, $value) {
|
|
||||||
$key = (empty($table)?"":"{$table}.") . $key;
|
|
||||||
if (isset($value['value_present']) && $value['value_present'])
|
|
||||||
return array($key => $value['value']);
|
|
||||||
else
|
|
||||||
return array($key);
|
|
||||||
}
|
|
||||||
|
|
||||||
function gridDataFilterSplit(&$params, &$model, $filter, $value) {
|
|
||||||
$value_present = true;
|
|
||||||
if (!is_string($filter)) {
|
|
||||||
// only a filter condition was set, not filter=>value
|
|
||||||
$filter = $value;
|
|
||||||
$value = null;
|
|
||||||
$value_present = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
$table = $field = null;
|
|
||||||
if (preg_match("/^\w+\.\w+(\s*[!<>=]+)?$/", $filter)) {
|
|
||||||
list($table, $field) = explode(".", $filter);
|
|
||||||
}
|
|
||||||
elseif (preg_match('/^[A-Z][A-Za-z]*$/', $filter)) {
|
|
||||||
$table = $filter;
|
|
||||||
$field = null;
|
|
||||||
}
|
|
||||||
elseif (preg_match('/^\w+(\s*[!<>=]+)?$/', $filter)) {
|
|
||||||
$table = $model->alias;
|
|
||||||
$field = $filter;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
// $filter must be a function or other complicated condition
|
|
||||||
$table = null;
|
|
||||||
$field = $filter;
|
|
||||||
}
|
|
||||||
|
|
||||||
return compact('table', 'field', 'value', 'value_present');
|
|
||||||
}
|
|
||||||
|
|
||||||
function gridDataFilterTableName(&$params, &$model, $table) {
|
|
||||||
return Inflector::camelize($table);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
* gridData PAGINATION
|
|
||||||
*/
|
|
||||||
|
|
||||||
function gridDataPagination(&$params, &$model, $record_count) {
|
|
||||||
// Retrieve, or calculate, all parameters necesssary for
|
|
||||||
// pagination. Verify the passed in parameters are valid.
|
|
||||||
|
|
||||||
$limit = $params['rows'] > 0 ? $params['rows'] : 10;
|
|
||||||
$total = ($record_count < 0) ? 0 : ceil($record_count/$limit);
|
|
||||||
$page = ($params['page'] <= 1) ? 1 : (($params['page'] > $total) ? $total : $params['page']);
|
|
||||||
$start = $limit * ($page - 1);
|
|
||||||
|
|
||||||
return compact('record_count', 'limit', 'page', 'start', 'total');
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
* gridData RETREIVAL
|
|
||||||
*/
|
|
||||||
|
|
||||||
function gridDataRecords(&$params, &$model, $pagination) {
|
|
||||||
// Establish the tables for this query
|
|
||||||
$query = array_intersect_key($this->gridDataTableSet($params, $model),
|
|
||||||
array('link'=>1, 'contain'=>1));
|
|
||||||
|
|
||||||
// Specify the fields for the query
|
|
||||||
$query['fields'] = $this->gridDataFields($params, $model);
|
|
||||||
|
|
||||||
// Conditions of the query
|
|
||||||
$query['conditions'] = $this->gridDataConditionSet($params, $model);
|
|
||||||
|
|
||||||
// Data record grouping
|
|
||||||
$query['group'] = $this->gridDataGroup($params, $model);
|
|
||||||
|
|
||||||
// The subset of data based on pagination
|
|
||||||
$query['limit'] = $this->gridDataLimit($params, $model, $pagination['start'], $pagination['limit']);
|
|
||||||
|
|
||||||
// Ordering based on user request
|
|
||||||
$query['order'] = $this->gridDataOrder($params, $model,
|
|
||||||
isset($params['sidx']) ? $params['sidx'] : null,
|
|
||||||
isset($params['sord']) ? $params['sord'] : null);
|
|
||||||
|
|
||||||
// DEBUG PURPOSES ONLY!
|
|
||||||
$params['query'] = $query;
|
|
||||||
|
|
||||||
return $this->gridDataRecordsExecute($params, $model, $query);
|
|
||||||
}
|
|
||||||
|
|
||||||
function gridDataRecordsExecute(&$params, &$model, $query) {
|
|
||||||
return $model->find('all', $query);
|
|
||||||
}
|
|
||||||
|
|
||||||
function gridDataTables(&$params, &$model) {
|
|
||||||
return array('link' => array());
|
|
||||||
}
|
|
||||||
|
|
||||||
function gridDataTableSet(&$params, &$model) {
|
|
||||||
// Preliminary set of tables
|
|
||||||
$query = array_intersect_key($this->gridDataTables($params, $model),
|
|
||||||
array('link'=>1, 'contain'=>1));
|
|
||||||
|
|
||||||
// Perform filtering based on user request: $params['post']['filter']
|
|
||||||
$query = array_intersect_key($this->gridDataFilterTables($params, $model, $query),
|
|
||||||
array('link'=>1, 'contain'=>1));
|
|
||||||
|
|
||||||
return $query;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
function gridDataConditions(&$params, &$model) {
|
|
||||||
$searches = array();
|
|
||||||
|
|
||||||
if (isset($params['_search']) && $params['_search'] === 'true') {
|
|
||||||
if (isset($params['searchOper'])) {
|
|
||||||
$searches[] = array('op' => $params['searchOper'],
|
|
||||||
'field' => $params['searchField'],
|
|
||||||
'value' => $params['searchString']);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
// DOH! Crappy mechanism puts toolbar search terms
|
|
||||||
// directly into params as name/value pairs. No
|
|
||||||
// way to know which elements of params are search
|
|
||||||
// terms, so skipping this at the moment.
|
|
||||||
}
|
|
||||||
}
|
|
||||||
elseif (isset($params['filt']) && $params['filt']) {
|
|
||||||
$searches[] = array('op' => 'bw',
|
|
||||||
'field' => $params['filtField'],
|
|
||||||
'value' => $params['filtValue']);
|
|
||||||
}
|
|
||||||
|
|
||||||
$ops = array('eq' => array('op' => null, 'pre' => '', 'post' => ''),
|
|
||||||
'ne' => array('op' => '<>', 'pre' => '', 'post' => ''),
|
|
||||||
'lt' => array('op' => '<', 'pre' => '', 'post' => ''),
|
|
||||||
'le' => array('op' => '<=', 'pre' => '', 'post' => ''),
|
|
||||||
'gt' => array('op' => '>', 'pre' => '', 'post' => ''),
|
|
||||||
'ge' => array('op' => '>=', 'pre' => '', 'post' => ''),
|
|
||||||
'bw' => array('op' => 'LIKE', 'pre' => '', 'post' => '%'),
|
|
||||||
'ew' => array('op' => 'LIKE', 'pre' => '%', 'post' => ''),
|
|
||||||
'cn' => array('op' => 'LIKE', 'pre' => '%', 'post' => '%'),
|
|
||||||
);
|
|
||||||
|
|
||||||
$conditions = array();
|
|
||||||
foreach ($searches AS $search) {
|
|
||||||
$op = $ops[$search['op']];
|
|
||||||
$field = $search['field'] . ($op['op'] ? ' '.$op['op'] : '');
|
|
||||||
$value = $op['pre'] . $search['value']. $op['post'];
|
|
||||||
$conditions[] = array($field => $value);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isset($params['action']) && $params['action'] === 'idlist') {
|
|
||||||
if (count($params['post']['idlist']))
|
|
||||||
$conditions[] = array($model->alias.'.'.$model->primaryKey => $params['post']['idlist']);
|
|
||||||
else
|
|
||||||
$conditions[] = '0=1';
|
|
||||||
}
|
|
||||||
|
|
||||||
return $conditions;
|
|
||||||
}
|
|
||||||
|
|
||||||
function gridDataConditionSet(&$params, &$model) {
|
|
||||||
// Conditions for record retrieval
|
|
||||||
$conditions = $this->gridDataConditions($params, $model);
|
|
||||||
|
|
||||||
// Perform filtering based on user request: $params['post']['filter']
|
|
||||||
return $this->gridDataFilterConditions($params, $model, $conditions);
|
|
||||||
}
|
|
||||||
|
|
||||||
function gridDataFields(&$params, &$model) {
|
|
||||||
$db = &$model->getDataSource();
|
|
||||||
$fields = $db->fields($model, $model->alias);
|
|
||||||
return $fields;
|
|
||||||
}
|
|
||||||
|
|
||||||
function gridDataGroup(&$params, &$model) {
|
|
||||||
return $model->alias.'.'.$model->primaryKey;
|
|
||||||
}
|
|
||||||
|
|
||||||
function gridDataOrder(&$params, &$model, $index, $direction) {
|
|
||||||
return $index ? array($index .' '. $direction) : null;
|
|
||||||
}
|
|
||||||
|
|
||||||
function gridDataLimit(&$params, &$model, $start, $limit) {
|
|
||||||
return $start . ', ' . $limit;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
* gridData POST PROCESSING
|
|
||||||
*/
|
|
||||||
|
|
||||||
function gridDataPostProcess(&$params, &$model, &$records) {
|
|
||||||
// Add grid IDs to each record
|
|
||||||
$this->gridDataPostProcessGridIDs($params, $model, $records);
|
|
||||||
|
|
||||||
// Add the calculated fields (if any), to the model fields
|
|
||||||
$this->gridDataPostProcessCalculatedFields($params, $model, $records);
|
|
||||||
|
|
||||||
// Perform any requested subtotaling of fields
|
|
||||||
$this->gridDataPostProcessSubtotal($params, $model, $records);
|
|
||||||
|
|
||||||
// Add in any needed hyperlinks
|
|
||||||
$this->gridDataPostProcessLinks($params, $model, $records, array());
|
|
||||||
|
|
||||||
// DEBUG PURPOSES ONLY!
|
|
||||||
//$params['records'] = $records;
|
|
||||||
}
|
|
||||||
|
|
||||||
function gridDataPostProcessGridIDs(&$params, &$model, &$records) {
|
|
||||||
$model_alias = $model->alias;
|
|
||||||
$id = $model->primaryKey;
|
|
||||||
|
|
||||||
foreach ($records AS &$record) {
|
|
||||||
$record['grid_id'] = $record[$model_alias][$id];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function gridDataPostProcessCalculatedFields(&$params, &$model, &$records) {
|
|
||||||
$model_alias = $model->alias;
|
|
||||||
|
|
||||||
foreach ($records AS &$record) {
|
|
||||||
// Add the calculated fields (if any), to the model fields
|
|
||||||
if (isset($record[0])) {
|
|
||||||
$record[$model_alias] += $record[0];
|
|
||||||
unset($record[0]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function gridDataPostProcessSubtotal(&$params, &$model, &$records) {
|
|
||||||
$model_alias = $model->alias;
|
|
||||||
|
|
||||||
// REVISIT <AP>: 20090722
|
|
||||||
// Horrible solution to something that should be done
|
|
||||||
// in SQL. But, it works for now, so what the heck...
|
|
||||||
|
|
||||||
$subtotals = array();
|
|
||||||
foreach ($params['post']['fields'] AS $field) {
|
|
||||||
if (preg_match('/subtotal-(.*)$/', $field, $matches))
|
|
||||||
$subtotals[] = array('field' => $matches[1],
|
|
||||||
'name' => $field,
|
|
||||||
'amount' => 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach ($records AS &$record) {
|
|
||||||
foreach ($subtotals AS &$subtotal) {
|
|
||||||
$field = $subtotal['field'];
|
|
||||||
if (preg_match("/\./", $field)) {
|
|
||||||
list($tbl, $col) = explode(".", $field);
|
|
||||||
$record['subtotal-'.$tbl][$col] =
|
|
||||||
($subtotal['amount'] += $record[$tbl][$col]);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
$record[$model->alias]['subtotal-'.$field] =
|
|
||||||
($subtotal['amount'] += $record[$model->alias][$field]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function gridDataPostProcessLinks(&$params, &$model, &$records, $links) {
|
|
||||||
// Don't create any links if ordered not to.
|
|
||||||
if (isset($params['post']['nolinks']))
|
|
||||||
return;
|
|
||||||
|
|
||||||
foreach ($links AS $table => $fields) {
|
|
||||||
$special = array('controller', 'id');
|
|
||||||
$controller = Inflector::pluralize(Inflector::underscore($table));
|
|
||||||
$id = 'id';
|
|
||||||
extract(array_intersect_key($fields, array_flip($special)));
|
|
||||||
foreach ($records AS &$record) {
|
|
||||||
if (!isset($record[$table]))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
foreach (array_diff_key($fields, array_flip($special)) AS $field) {
|
|
||||||
if (!isset($record[$table][$id]) || !isset($record[$table][$field]))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
// DEBUG PURPOSES ONLY!
|
|
||||||
//$params['linkrecord'][] = compact('table', 'field', 'id', 'controller', 'record');
|
|
||||||
$record[$table][$field] =
|
|
||||||
'<A HREF="' .
|
|
||||||
Router::url(array('controller' => $controller,
|
|
||||||
'action' => 'view',
|
|
||||||
$record[$table][$id])) .
|
|
||||||
'">' .
|
|
||||||
$record[$table][$field] .
|
|
||||||
'</A>';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
* gridData OUTPUT
|
|
||||||
*/
|
|
||||||
|
|
||||||
function gridDataOutput(&$params, &$model, &$records, $pagination) {
|
|
||||||
$this->gridDataOutputHeader($params, $model);
|
|
||||||
$this->gridDataOutputXMLHeader($params, $model);
|
|
||||||
$this->gridDataOutputRootNodeBegin($params, $model);
|
|
||||||
$this->gridDataOutputSummary($params, $model, $pagination);
|
|
||||||
$this->gridDataOutputRecords($params, $model, $records);
|
|
||||||
$this->gridDataOutputRootNodeEnd($params, $model);
|
|
||||||
}
|
|
||||||
|
|
||||||
function gridDataOutputHeader(&$params, &$model) {
|
|
||||||
if (!$params['debug']) {
|
|
||||||
header("Content-type: text/xml;charset=utf-8");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function gridDataOutputXMLHeader(&$params, &$model) {
|
|
||||||
echo "<?xml version='1.0' encoding='utf-8'?>\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
function gridDataOutputRootNodeBegin(&$params, &$model) {
|
|
||||||
echo "<rows>\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
function gridDataOutputRootNodeEnd(&$params, &$model) {
|
|
||||||
echo "</rows>\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
function gridDataOutputSummary(&$params, &$model, $pagination) {
|
|
||||||
echo " <params><![CDATA[\n" . print_r($params, true) . "\n]]></params>\n";
|
|
||||||
echo " <page>{$pagination['page']}</page>\n";
|
|
||||||
echo " <total>{$pagination['total']}</total>\n";
|
|
||||||
echo " <records>{$pagination['record_count']}</records>\n";
|
|
||||||
|
|
||||||
if (isset($params['userdata'])) {
|
|
||||||
foreach ($params['userdata'] AS $field => $value)
|
|
||||||
echo ' <userdata name="'.$field.'">' . "{$value}</userdata>\n";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function gridDataOutputRecords(&$params, &$model, &$records) {
|
|
||||||
$id_field = 'grid_id';
|
|
||||||
foreach ($records AS $record) {
|
|
||||||
$this->gridDataOutputRecord($params, $model, $record,
|
|
||||||
$record[$id_field], $params['post']['fields']);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function gridDataOutputRecord(&$params, &$model, &$record, $id, $fields) {
|
|
||||||
echo " <row id='$id'>\n";
|
|
||||||
foreach ($fields AS $field) {
|
|
||||||
$this->gridDataOutputRecordField($params, $model, $record, $field);
|
|
||||||
}
|
|
||||||
echo " </row>\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
function gridDataOutputRecordField(&$params, &$model, &$record, $field) {
|
|
||||||
if (preg_match("/\./", $field)) {
|
|
||||||
list($tbl, $col) = explode(".", $field);
|
|
||||||
//pr(compact('record', 'field', 'tbl', 'col'));
|
|
||||||
$data = $record[$tbl][$col];
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
$data = $record[$model->alias][$field];
|
|
||||||
}
|
|
||||||
$this->gridDataOutputRecordCell($params, $model, $record, $field, $data);
|
|
||||||
}
|
|
||||||
|
|
||||||
function gridDataOutputRecordCell(&$params, &$model, &$record, $field, $data) {
|
|
||||||
// be sure to put text data in CDATA
|
|
||||||
if (preg_match("/^\d*$/", $data))
|
|
||||||
echo " <cell>$data</cell>\n";
|
|
||||||
else
|
|
||||||
echo " <cell><![CDATA[$data]]></cell>\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
?>
|
|
||||||
@@ -1,479 +0,0 @@
|
|||||||
<?php
|
|
||||||
/* SVN FILE: $Id: app_model.php 7945 2008-12-19 02:16:01Z gwoo $ */
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Application model for Cake.
|
|
||||||
*
|
|
||||||
* This file is application-wide model file. You can put all
|
|
||||||
* application-wide model-related methods here.
|
|
||||||
*
|
|
||||||
* PHP versions 4 and 5
|
|
||||||
*
|
|
||||||
* CakePHP(tm) : Rapid Development Framework (http://www.cakephp.org)
|
|
||||||
* Copyright 2005-2008, Cake Software Foundation, Inc. (http://www.cakefoundation.org)
|
|
||||||
*
|
|
||||||
* Licensed under The MIT License
|
|
||||||
* Redistributions of files must retain the above copyright notice.
|
|
||||||
*
|
|
||||||
* @filesource
|
|
||||||
* @copyright Copyright 2005-2008, Cake Software Foundation, Inc. (http://www.cakefoundation.org)
|
|
||||||
* @link http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
|
|
||||||
* @package cake
|
|
||||||
* @subpackage cake.app
|
|
||||||
* @since CakePHP(tm) v 0.2.9
|
|
||||||
* @version $Revision: 7945 $
|
|
||||||
* @modifiedby $LastChangedBy: gwoo $
|
|
||||||
* @lastmodified $Date: 2008-12-18 18:16:01 -0800 (Thu, 18 Dec 2008) $
|
|
||||||
* @license http://www.opensource.org/licenses/mit-license.php The MIT License
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Application model for Cake.
|
|
||||||
*
|
|
||||||
* Add your application-wide methods in the class below, your models
|
|
||||||
* will inherit them.
|
|
||||||
*
|
|
||||||
* @package cake
|
|
||||||
* @subpackage cake.app
|
|
||||||
*/
|
|
||||||
class AppModel extends Model {
|
|
||||||
|
|
||||||
var $actsAs = array('Containable', 'Linkable');
|
|
||||||
var $useNullForEmpty = true;
|
|
||||||
var $formatDateFields = true;
|
|
||||||
|
|
||||||
// Default Log Level, if not specified at the function level
|
|
||||||
var $default_log_level = 5;
|
|
||||||
|
|
||||||
// Class specific log levels
|
|
||||||
var $class_log_level = array('Model' => 5);
|
|
||||||
|
|
||||||
// Function specific log levels
|
|
||||||
var $function_log_level = array();
|
|
||||||
|
|
||||||
// Force the module to log at LEAST at this level
|
|
||||||
var $min_log_level;
|
|
||||||
|
|
||||||
// Force logging of nothing higher than this level
|
|
||||||
var $max_log_level;
|
|
||||||
|
|
||||||
|
|
||||||
// REVISIT <AP>: 20090730
|
|
||||||
// Why is this constructor crashing?
|
|
||||||
// Clearly it's in some sort of infinite
|
|
||||||
// loop, but it seems the correct way
|
|
||||||
// to have a constructor call the parent...
|
|
||||||
|
|
||||||
/* function __construct() { */
|
|
||||||
/* parent::__construct(); */
|
|
||||||
/* $this->prClassLevel(5, 'Model'); */
|
|
||||||
/* } */
|
|
||||||
|
|
||||||
/**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
* function: pr
|
|
||||||
* - Prints out debug information, if the log level allows
|
|
||||||
*/
|
|
||||||
|
|
||||||
function prClassLevel($level, $class = null) {
|
|
||||||
$trace = debug_backtrace(false);
|
|
||||||
$caller = array_shift($trace);
|
|
||||||
$caller = array_shift($trace);
|
|
||||||
if (empty($class))
|
|
||||||
$class = $caller['class'];
|
|
||||||
$this->class_log_level[$class] = $level;
|
|
||||||
}
|
|
||||||
|
|
||||||
function prFunctionLevel($level, $function = null, $class = null) {
|
|
||||||
$trace = debug_backtrace(false);
|
|
||||||
$caller = array_shift($trace);
|
|
||||||
$caller = array_shift($trace);
|
|
||||||
if (empty($class))
|
|
||||||
$class = $caller['class'];
|
|
||||||
if (empty($function))
|
|
||||||
$function = $caller['function'];
|
|
||||||
$this->function_log_level["{$class}-{$function}"] = $level;
|
|
||||||
}
|
|
||||||
|
|
||||||
function _pr($level, $mixed, $checkpoint = null) {
|
|
||||||
if (Configure::read() <= 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
$log_level = $this->default_log_level;
|
|
||||||
|
|
||||||
$trace = debug_backtrace(false);
|
|
||||||
|
|
||||||
// Get rid of pr/prEnter/prReturn
|
|
||||||
$caller = array_shift($trace);
|
|
||||||
|
|
||||||
// The next entry shows where pr was called from, but it
|
|
||||||
// shows _what_ was called, which is pr/prEntry/prReturn.
|
|
||||||
$caller = array_shift($trace);
|
|
||||||
$file = $caller['file'];
|
|
||||||
$line = $caller['line'];
|
|
||||||
|
|
||||||
// So, this caller holds the calling function name
|
|
||||||
$caller = $trace[0];
|
|
||||||
$function = $caller['function'];
|
|
||||||
$class = $caller['class'];
|
|
||||||
//$class = $this->name;
|
|
||||||
|
|
||||||
// Use class or function specific log level if available
|
|
||||||
if (isset($this->class_log_level[$class]))
|
|
||||||
$log_level = $this->class_log_level[$class];
|
|
||||||
if (isset($this->function_log_level["{$class}-{$function}"]))
|
|
||||||
$log_level = $this->function_log_level["{$class}-{$function}"];
|
|
||||||
|
|
||||||
// Establish log level minimums
|
|
||||||
$min_log_level = $this->min_log_level;
|
|
||||||
if (is_array($this->min_log_level)) {
|
|
||||||
$min_show_level = $min_log_level['show'];
|
|
||||||
$min_log_level = $min_log_level['log'];
|
|
||||||
}
|
|
||||||
|
|
||||||
// Establish log level maximums
|
|
||||||
$max_log_level = $this->max_log_level;
|
|
||||||
if (is_array($this->max_log_level)) {
|
|
||||||
$max_show_level = $max_log_level['show'];
|
|
||||||
$max_log_level = $max_log_level['log'];
|
|
||||||
}
|
|
||||||
|
|
||||||
// Determine the applicable log and show levels
|
|
||||||
if (is_array($log_level)) {
|
|
||||||
$show_level = $log_level['show'];
|
|
||||||
$log_level = $log_level['log'];
|
|
||||||
}
|
|
||||||
|
|
||||||
// Adjust log level up/down to min/max
|
|
||||||
if (isset($min_log_level))
|
|
||||||
$log_level = max($log_level, $min_log_level);
|
|
||||||
if (isset($max_log_level))
|
|
||||||
$log_level = min($log_level, $max_log_level);
|
|
||||||
|
|
||||||
// Adjust show level up/down to min/max
|
|
||||||
if (isset($min_show_level))
|
|
||||||
$show_level = max($show_level, $min_show_level);
|
|
||||||
if (isset($max_show_level))
|
|
||||||
$show_level = min($show_level, $max_show_level);
|
|
||||||
|
|
||||||
// If the level is insufficient, bail out
|
|
||||||
if ($level > $log_level)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (!empty($checkpoint)) {
|
|
||||||
$chk = array("checkpoint" => $checkpoint);
|
|
||||||
if (is_array($mixed))
|
|
||||||
$mixed = $chk + $mixed;
|
|
||||||
else
|
|
||||||
$mixed = $chk + array($mixed);
|
|
||||||
}
|
|
||||||
|
|
||||||
static $pr_unique_number = 0;
|
|
||||||
$pr_id = 'pr-section-class-' . $class . '-print-' . (++$pr_unique_number);
|
|
||||||
$pr_trace_id = $pr_id . '-trace';
|
|
||||||
$pr_output_id = $pr_id . '-output';
|
|
||||||
|
|
||||||
$pr_entire_base_class = "pr-section";
|
|
||||||
$pr_entire_class_class = $pr_entire_base_class . '-class-' . $class;
|
|
||||||
$pr_entire_function_class = $pr_entire_class_class . '-function-' . $function;
|
|
||||||
$pr_entire_class = "$pr_entire_base_class $pr_entire_class_class $pr_entire_function_class";
|
|
||||||
$pr_header_class = "pr-caller";
|
|
||||||
$pr_trace_class = "pr-trace";
|
|
||||||
$pr_output_base_class = 'pr-output';
|
|
||||||
$pr_output_class_class = $pr_output_base_class . '-class-' . $class;
|
|
||||||
$pr_output_function_class = $pr_output_class_class . '-function-' . $function;
|
|
||||||
$pr_output_class = "$pr_output_base_class $pr_output_class_class $pr_output_function_class";
|
|
||||||
|
|
||||||
echo '<DIV class="'.$pr_entire_class.'" id="'.$pr_id.'">'."\n";
|
|
||||||
echo '<DIV class="'.$pr_header_class.'">'."\n";
|
|
||||||
echo '<DIV class="'.$pr_trace_class.'" id="'.$pr_trace_id.'" style="display:none;">'."\n";
|
|
||||||
echo '<HR />' . "\n";
|
|
||||||
|
|
||||||
// Flip trace around so the sequence flows from top to bottom
|
|
||||||
// Then print out the entire stack trace (in hidden div)
|
|
||||||
$trace = array_reverse($trace);
|
|
||||||
for ($i = 0; $i < count($trace); ++$i) {
|
|
||||||
$bline = $trace[$i]['line'];
|
|
||||||
$bfile = $trace[$i]['file'];
|
|
||||||
$bfile = str_replace(ROOT.DS, '', $bfile);
|
|
||||||
$bfile = str_replace(CAKE_CORE_INCLUDE_PATH.DS, '', $bfile);
|
|
||||||
|
|
||||||
if ($i > 0) {
|
|
||||||
$bfunc = $trace[$i-1]['function'];
|
|
||||||
$bclas = $trace[$i-1]['class'];
|
|
||||||
} else {
|
|
||||||
$bfunc = null;
|
|
||||||
$bclas = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
echo("$bfile:$bline (" . ($bclas ? "$bclas::$bfunc" : "entry point") . ")<BR>\n");
|
|
||||||
//echo(($bclas ? "$bclas::$bfunc" : "entry point") . "; $bfile : $bline<BR>\n");
|
|
||||||
}
|
|
||||||
echo '</DIV>' . "\n"; // End pr_trace_class
|
|
||||||
$file = str_replace(ROOT.DS, '', $file);
|
|
||||||
$file = str_replace(CAKE_CORE_INCLUDE_PATH.DS, '', $file);
|
|
||||||
|
|
||||||
echo "<strong>$file:$line ($class::$function)</strong>" . ";\n";
|
|
||||||
/* $log_show_level = isset($show_level) ? $show_level : '?'; */
|
|
||||||
/* echo ' L' . $level . "({$log_level}/{$log_show_level})" . ";\n"; */
|
|
||||||
echo ' L' . $level . ";\n";
|
|
||||||
echo ' <A HREF="#" onclick="$' . "('#{$pr_trace_id}').slideToggle(); return false;" . '">stack</A>'.";\n";
|
|
||||||
|
|
||||||
echo " this ";
|
|
||||||
echo '<A HREF="#" onclick="$' . "('#{$pr_output_id}').slideToggle(); return false;" . '">t</A>'."/";
|
|
||||||
echo '<A HREF="#" onclick="$' . "('#{$pr_id}').hide(); return false;" . '">n</A>'.";\n";
|
|
||||||
|
|
||||||
echo " $class ";
|
|
||||||
echo '<A HREF="#" onclick="$' . "('.{$pr_output_class_class}').slideDown(); return false;" . '">s</A>'."/";
|
|
||||||
echo '<A HREF="#" onclick="$' . "('.{$pr_output_class_class}').slideUp(); return false;" . '">h</A>'."/";
|
|
||||||
echo '<A HREF="#" onclick="$' . "('.{$pr_entire_class_class}').hide(); return false;" . '">n</A>'.";\n";
|
|
||||||
|
|
||||||
echo " $function ";
|
|
||||||
echo '<A HREF="#" onclick="$' . "('.{$pr_output_function_class}').slideDown(); return false;" . '">s</A>'."/";
|
|
||||||
echo '<A HREF="#" onclick="$' . "('.{$pr_output_function_class}').slideUp(); return false;" . '">h</A>'."/";
|
|
||||||
echo '<A HREF="#" onclick="$' . "('.{$pr_entire_function_class}').hide(); return false;" . '">n</A>'.";\n";
|
|
||||||
|
|
||||||
echo " all ";
|
|
||||||
echo '<A HREF="#" onclick="$' . "('.{$pr_output_base_class}').show(); return false;" . '">s</A>'."/";
|
|
||||||
echo '<A HREF="#" onclick="$' . "('.{$pr_output_base_class}').hide(); return false;" . '">h</A>'."/";
|
|
||||||
echo '<A HREF="#" onclick="$' . "('.{$pr_entire_base_class}').hide(); return false;" . '">n</A>'."\n";
|
|
||||||
|
|
||||||
echo '</DIV>' . "\n"; // End pr_header_class
|
|
||||||
|
|
||||||
if (isset($show_level) && $level > $show_level)
|
|
||||||
$display = 'none';
|
|
||||||
else
|
|
||||||
$display = 'block';
|
|
||||||
|
|
||||||
echo '<DIV class="'.$pr_output_class.'" id="'.$pr_output_id.'" style="display:'.$display.';">'."\n";
|
|
||||||
pr($mixed, false, false);
|
|
||||||
echo '</DIV>' . "\n"; // End pr_output_class
|
|
||||||
echo '</DIV>' . "\n"; // End pr_entire_class
|
|
||||||
}
|
|
||||||
|
|
||||||
function pr($level, $mixed, $checkpoint = null) {
|
|
||||||
$this->_pr($level, $mixed, $checkpoint);
|
|
||||||
}
|
|
||||||
|
|
||||||
function prEnter($args, $level = 15) {
|
|
||||||
$this->_pr($level, $args, 'Function Entry');
|
|
||||||
}
|
|
||||||
|
|
||||||
function prReturn($retval, $level = 16) {
|
|
||||||
$this->_pr($level, $retval, 'Function Return');
|
|
||||||
return $retval;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
* function: queryInit
|
|
||||||
* - Initializes the query fields
|
|
||||||
*/
|
|
||||||
function prDump($all = false) {
|
|
||||||
$vars = get_object_vars($this);
|
|
||||||
foreach (array_keys($vars) AS $name) {
|
|
||||||
if (preg_match("/^[A-Z]/", $name))
|
|
||||||
unset($vars[$name]);
|
|
||||||
if (preg_match("/^_/", $name) && !$all)
|
|
||||||
unset($vars[$name]);
|
|
||||||
}
|
|
||||||
pr($vars);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get Enum Values
|
|
||||||
* Snippet v0.1.3
|
|
||||||
* http://cakeforge.org/snippet/detail.php?type=snippet&id=112
|
|
||||||
*
|
|
||||||
* Gets the enum values for MySQL 4 and 5 to use in selectTag()
|
|
||||||
*/
|
|
||||||
function getEnumValues($columnName=null, $tableName=null)
|
|
||||||
{
|
|
||||||
if ($columnName==null) { return array(); } //no field specified
|
|
||||||
|
|
||||||
if (!isset($tableName)) {
|
|
||||||
//Get the name of the table
|
|
||||||
$db =& ConnectionManager::getDataSource($this->useDbConfig);
|
|
||||||
$tableName = $db->fullTableName($this, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
//Get the values for the specified column (database and version specific, needs testing)
|
|
||||||
$result = $this->query("SHOW COLUMNS FROM {$tableName} LIKE '{$columnName}'");
|
|
||||||
|
|
||||||
//figure out where in the result our Types are (this varies between mysql versions)
|
|
||||||
$types = null;
|
|
||||||
if ( isset( $result[0]['COLUMNS']['Type'] ) ) { //MySQL 5
|
|
||||||
$types = $result[0]['COLUMNS']['Type']; $default = $result[0]['COLUMNS']['Default'];
|
|
||||||
}
|
|
||||||
elseif ( isset( $result[0][0]['Type'] ) ) { //MySQL 4
|
|
||||||
$types = $result[0][0]['Type']; $default = $result[0][0]['Default'];
|
|
||||||
}
|
|
||||||
else { //types return not accounted for
|
|
||||||
return array();
|
|
||||||
}
|
|
||||||
|
|
||||||
//Get the values
|
|
||||||
return array_flip(array_merge(array(''), // MySQL sets 0 to be the empty string
|
|
||||||
explode("','", strtoupper(preg_replace("/(enum)\('(.+?)'\)/","\\2", $types)))
|
|
||||||
));
|
|
||||||
} //end getEnumValues
|
|
||||||
|
|
||||||
|
|
||||||
/**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
* function: queryInit
|
|
||||||
* - Initializes the query fields
|
|
||||||
*/
|
|
||||||
function queryInit(&$query, $link = true) {
|
|
||||||
if (!isset($query))
|
|
||||||
$query = array();
|
|
||||||
if (!isset($query['conditions']))
|
|
||||||
$query['conditions'] = array();
|
|
||||||
if (!isset($query['group']))
|
|
||||||
$query['group'] = null;
|
|
||||||
if (!isset($query['fields']))
|
|
||||||
$query['fields'] = null;
|
|
||||||
if ($link && !isset($query['link']))
|
|
||||||
$query['link'] = array();
|
|
||||||
if (!$link && !isset($query['contain']))
|
|
||||||
$query['contain'] = array();
|
|
||||||
|
|
||||||
// In case caller expects query to come back
|
|
||||||
return $query;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
* function: nameToID
|
|
||||||
* - Returns the ID of the named item
|
|
||||||
*/
|
|
||||||
function nameToID($name) {
|
|
||||||
$this->cacheQueries = true;
|
|
||||||
$item = $this->find('first', array
|
|
||||||
('recursive' => -1,
|
|
||||||
'conditions' => compact('name'),
|
|
||||||
));
|
|
||||||
$this->cacheQueries = false;
|
|
||||||
if ($item) {
|
|
||||||
$item = current($item);
|
|
||||||
return $item['id'];
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
* function: statMerge
|
|
||||||
* - Merges summary data from $b into $a
|
|
||||||
*/
|
|
||||||
|
|
||||||
function statsMerge (&$a, $b) {
|
|
||||||
if (!isset($b))
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (!isset($a)) {
|
|
||||||
$a = $b;
|
|
||||||
}
|
|
||||||
elseif (!is_array($a) && !is_array($b)) {
|
|
||||||
$a += $b;
|
|
||||||
}
|
|
||||||
elseif (is_array($a) && is_array($b)) {
|
|
||||||
foreach (array_intersect_key($a, $b) AS $k => $v)
|
|
||||||
{
|
|
||||||
if (preg_match("/^sp\./", $k))
|
|
||||||
$a[$k] .= '; ' . $b[$k];
|
|
||||||
else
|
|
||||||
$this->statsMerge($a[$k], $b[$k]);
|
|
||||||
}
|
|
||||||
$a = array_merge($a, array_diff_key($b, $a));
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
die ("Can't yet merge array and non-array stats");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
function recursive_array_replace($find, $replace, &$data) {
|
|
||||||
if (!isset($data))
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (is_array($data)) {
|
|
||||||
foreach ($data as $key => &$value) {
|
|
||||||
$this->recursive_array_replace($find, $replace, $value);
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isset($replace))
|
|
||||||
$data = preg_replace($find, $replace, $data);
|
|
||||||
elseif (preg_match($find, $data))
|
|
||||||
$data = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
function beforeSave() {
|
|
||||||
/* pr(array('class' => $this->name, */
|
|
||||||
/* 'alias' => $this->alias, */
|
|
||||||
/* 'function' => 'AppModel::beforeSave')); */
|
|
||||||
|
|
||||||
// Replace all empty strings with NULL.
|
|
||||||
// If a particular model doesn't like this, they'll have to
|
|
||||||
// override the behavior, or set useNullForEmpty to false.
|
|
||||||
if ($this->useNullForEmpty)
|
|
||||||
$this->recursive_array_replace("/^\s*$/", null, $this->data);
|
|
||||||
|
|
||||||
if ($this->formatDateFields) {
|
|
||||||
$alias = $this->alias;
|
|
||||||
|
|
||||||
foreach ($this->_schema AS $field => $info) {
|
|
||||||
if ($info['type'] == 'date' || $info['type'] == 'timestamp') {
|
|
||||||
if (isset($this->data[$alias][$field])) {
|
|
||||||
/* pr("Fix Date for '$alias'.'$field'; current value = " . */
|
|
||||||
/* "'{$this->data[$alias][$field]}'"); */
|
|
||||||
if ($this->data[$alias][$field] === 'CURRENT_TIMESTAMP')
|
|
||||||
// Seems CakePHP is broken for the default timestamp.
|
|
||||||
// It tries to automagically set the value to CURRENT_TIMESTAMP
|
|
||||||
// which is wholly rejected by MySQL. Just put it back to NULL
|
|
||||||
// and let the SQL engine deal with the defaults... it's not
|
|
||||||
// Cake's place to do this anyway :-/
|
|
||||||
$this->data[$alias][$field] = null;
|
|
||||||
else
|
|
||||||
$this->data[$alias][$field] =
|
|
||||||
$this->dateFormatBeforeSave($this->data[$alias][$field]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
* function: dateFormatBeforeSave
|
|
||||||
* - convert dates to database format
|
|
||||||
*/
|
|
||||||
|
|
||||||
function dateFormatBeforeSave($dateString) {
|
|
||||||
/* $time = ''; */
|
|
||||||
/* if (preg_match('/(\d+(:\d+))/', $dateString, $match)) */
|
|
||||||
/* $time = ' '.$match[1]; */
|
|
||||||
/* $dateString = preg_replace('/(\d+(:\d+))/', '', $dateString); */
|
|
||||||
/* return date('Y-m-d', strtotime($dateString)) . $time; */
|
|
||||||
|
|
||||||
if (preg_match('/:/', $dateString))
|
|
||||||
return date('Y-m-d H:i:s', strtotime($dateString));
|
|
||||||
else
|
|
||||||
return date('Y-m-d', strtotime($dateString));
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,212 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
class AccountsController extends AppController {
|
|
||||||
|
|
||||||
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')),
|
|
||||||
array('name' => 'Deposits', 'header' => true),
|
|
||||||
array('name' => 'Prior Deposits', 'url' => array('controller' => 'transactions', 'action' => 'deposit')),
|
|
||||||
array('name' => 'New Deposit', 'url' => array('controller' => 'tenders', 'action' => 'deposit')),
|
|
||||||
);
|
|
||||||
|
|
||||||
|
|
||||||
/**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
* override: sideMenuLinks
|
|
||||||
* - Generates controller specific links for the side menu
|
|
||||||
*/
|
|
||||||
function sideMenuLinks() {
|
|
||||||
return array_merge(parent::sideMenuLinks(), $this->sidemenu_links);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
* action: index / asset / liability / equity / income / expense / all
|
|
||||||
* - Generate a chart of accounts
|
|
||||||
*/
|
|
||||||
|
|
||||||
function index() { $this->all(); }
|
|
||||||
function asset() { $this->gridView('Asset Accounts'); }
|
|
||||||
function liability() { $this->gridView('Liability Accounts'); }
|
|
||||||
function equity() { $this->gridView('Equity Accounts'); }
|
|
||||||
function income() { $this->gridView('Income Accounts'); }
|
|
||||||
function expense() { $this->gridView('Expense Accounts'); }
|
|
||||||
function all() { $this->gridView('All Accounts', 'all'); }
|
|
||||||
|
|
||||||
|
|
||||||
/**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
* virtuals: gridData
|
|
||||||
* - With the application controller handling the gridData action,
|
|
||||||
* these virtual functions ensure that the correct data is passed
|
|
||||||
* to jqGrid.
|
|
||||||
*/
|
|
||||||
|
|
||||||
function gridDataSetup(&$params) {
|
|
||||||
parent::gridDataSetup($params);
|
|
||||||
if (!isset($params['action']))
|
|
||||||
$params['action'] = 'all';
|
|
||||||
}
|
|
||||||
|
|
||||||
function gridDataCountTables(&$params, &$model) {
|
|
||||||
// Our count should NOT include anything extra,
|
|
||||||
// so we need the virtual function to prevent
|
|
||||||
// the base class from just calling our
|
|
||||||
// gridDataTables function
|
|
||||||
return parent::gridDataTables($params, $model);
|
|
||||||
}
|
|
||||||
|
|
||||||
function gridDataTables(&$params, &$model) {
|
|
||||||
return array
|
|
||||||
('link' =>
|
|
||||||
array(// Models
|
|
||||||
'CurrentLedger' => array
|
|
||||||
(// Models
|
|
||||||
'LedgerEntry'
|
|
||||||
),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
function gridDataFields(&$params, &$model) {
|
|
||||||
$fields = parent::gridDataFields($params, $model);
|
|
||||||
return array_merge($fields,
|
|
||||||
$this->Account->Ledger->LedgerEntry->debitCreditFields(true));
|
|
||||||
}
|
|
||||||
|
|
||||||
function gridDataConditions(&$params, &$model) {
|
|
||||||
$conditions = parent::gridDataConditions($params, $model);
|
|
||||||
|
|
||||||
if (in_array($params['action'], array('asset', 'liability', 'equity', 'income', 'expense'))) {
|
|
||||||
$conditions[] = array('Account.type' => strtoupper($params['action']));
|
|
||||||
}
|
|
||||||
|
|
||||||
return $conditions;
|
|
||||||
}
|
|
||||||
|
|
||||||
function gridDataPostProcessLinks(&$params, &$model, &$records, $links) {
|
|
||||||
$links['Account'] = array('name');
|
|
||||||
return parent::gridDataPostProcessLinks($params, $model, $records, $links);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
* action: newledger
|
|
||||||
* - Close the current account ledger and create a new one,
|
|
||||||
* carrying forward any balance if necessary.
|
|
||||||
*/
|
|
||||||
|
|
||||||
function newledger($id = null) {
|
|
||||||
$result = $this->Account->closeCurrentLedgers($id);
|
|
||||||
|
|
||||||
if ($result['error']) {
|
|
||||||
pr(compact('result'));
|
|
||||||
die("Unable to create new ledger.");
|
|
||||||
$this->Session->setFlash(__('Unable to create new Ledger.', true));
|
|
||||||
}
|
|
||||||
if ($id)
|
|
||||||
$this->redirect(array('action'=>'view', $id));
|
|
||||||
else
|
|
||||||
$this->redirect(array('action'=>'index'));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
* action: collected
|
|
||||||
* - Displays the items actually collected for the period
|
|
||||||
* e.g. How much was collected in rent from 4/1/09 - 5/1/09
|
|
||||||
*/
|
|
||||||
function collected($id = null) {
|
|
||||||
if (!$id) {
|
|
||||||
$this->Session->setFlash(__('Invalid Item.', true));
|
|
||||||
$this->redirect(array('action'=>'index'));
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->Account->recursive = -1;
|
|
||||||
$account = $this->Account->read(null, $id);
|
|
||||||
$account = $account['Account'];
|
|
||||||
|
|
||||||
$payment_accounts = $this->Account->collectableAccounts();
|
|
||||||
//$payment_accounts[$this->Account->nameToID('Closing')] = 'Closing';
|
|
||||||
//$payment_accounts[$this->Account->nameToID('Equity')] = 'Equity';
|
|
||||||
//$payment_accounts[$id] = 'Reversals';
|
|
||||||
$default_accounts = array_diff_key($this->Account->receiptAccounts(),
|
|
||||||
array($this->Account->concessionAccountID() => 1));
|
|
||||||
$this->set(compact('payment_accounts', 'default_accounts'));
|
|
||||||
|
|
||||||
$title = ($account['name'] . ': Collected Report');
|
|
||||||
$this->set(compact('account', 'title'));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
* 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'));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get details about the account and its ledgers (no ledger entries yet)
|
|
||||||
$account = $this->Account->find
|
|
||||||
('first',
|
|
||||||
array('contain' =>
|
|
||||||
array(// Models
|
|
||||||
'CurrentLedger' =>
|
|
||||||
array('fields' => array('id', 'sequence', 'name')),
|
|
||||||
|
|
||||||
'Ledger' =>
|
|
||||||
array('CloseTransaction' => array
|
|
||||||
('order' => array('CloseTransaction.stamp' => 'DESC'))),
|
|
||||||
),
|
|
||||||
'conditions' => array(array('Account.id' => $id)),
|
|
||||||
)
|
|
||||||
);
|
|
||||||
|
|
||||||
// Get all ledger entries of the CURRENT ledger
|
|
||||||
$entries = $this->Account->ledgerEntries($id);
|
|
||||||
//pr(compact('entries'));
|
|
||||||
$account['CurrentLedger']['LedgerEntry'] = $entries;
|
|
||||||
|
|
||||||
// Obtain stats across ALL ledgers for the summary infobox
|
|
||||||
$stats = $this->Account->stats($id, true);
|
|
||||||
$stats = $stats['Ledger'];
|
|
||||||
|
|
||||||
$this->sidemenu_links[] =
|
|
||||||
array('name' => 'Operations', 'header' => true);
|
|
||||||
$this->sidemenu_links[] =
|
|
||||||
array('name' => 'New Ledger', 'url' => array('action' => 'newledger', $id));
|
|
||||||
$this->sidemenu_links[] =
|
|
||||||
array('name' => 'Collected', 'url' => array('action' => 'collected', $id));
|
|
||||||
|
|
||||||
// Prepare to render
|
|
||||||
$title = 'Account: ' . $account['Account']['name'];
|
|
||||||
$this->set(compact('account', 'title', 'stats'));
|
|
||||||
}
|
|
||||||
|
|
||||||
function tst($id) {
|
|
||||||
//$entries = $this->Account->($id);
|
|
||||||
pr($entries);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,204 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
class ContactsController extends AppController {
|
|
||||||
|
|
||||||
var $sidemenu_links = array();
|
|
||||||
|
|
||||||
/**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
* override: sideMenuLinks
|
|
||||||
* - Generates controller specific links for the side menu
|
|
||||||
*/
|
|
||||||
function sideMenuLinks() {
|
|
||||||
return array_merge(parent::sideMenuLinks(), $this->sidemenu_links);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
* action: index / all
|
|
||||||
* - Generate a listing of contacts
|
|
||||||
*/
|
|
||||||
|
|
||||||
function index() { $this->all(); }
|
|
||||||
function all() { $this->gridView('All Contacts', 'all'); }
|
|
||||||
|
|
||||||
|
|
||||||
/**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
* virtuals: gridData
|
|
||||||
* - With the application controller handling the gridData action,
|
|
||||||
* these virtual functions ensure that the correct data is passed
|
|
||||||
* to jqGrid.
|
|
||||||
*/
|
|
||||||
|
|
||||||
function gridDataOrder(&$params, &$model, $index, $direction) {
|
|
||||||
$order = parent::gridDataOrder($params, $model, $index, $direction);
|
|
||||||
if ($index === 'Contact.last_name') {
|
|
||||||
$order[] = 'Contact.first_name ' . $direction;
|
|
||||||
}
|
|
||||||
if ($index === 'Contact.first_name') {
|
|
||||||
$order[] = 'Contact.last_name ' . $direction;
|
|
||||||
}
|
|
||||||
return $order;
|
|
||||||
}
|
|
||||||
|
|
||||||
function gridDataPostProcessLinks(&$params, &$model, &$records, $links) {
|
|
||||||
$links['Contact'] = array('id');
|
|
||||||
return parent::gridDataPostProcessLinks($params, $model, $records, $links);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
* action: view
|
|
||||||
* - Displays information about a specific contact
|
|
||||||
*/
|
|
||||||
|
|
||||||
function view($id = null) {
|
|
||||||
if (!$id) {
|
|
||||||
$this->Session->setFlash(__('Invalid Item.', true));
|
|
||||||
$this->redirect(array('action'=>'index'));
|
|
||||||
}
|
|
||||||
|
|
||||||
$contact = $this->Contact->find
|
|
||||||
('first', array
|
|
||||||
('contain' => array
|
|
||||||
(// Models
|
|
||||||
'ContactPhone',
|
|
||||||
'ContactEmail',
|
|
||||||
'ContactAddress',
|
|
||||||
'Customer'),
|
|
||||||
|
|
||||||
'conditions' => array('Contact.id' => $id),
|
|
||||||
));
|
|
||||||
|
|
||||||
// Set up dynamic menu items
|
|
||||||
$this->sidemenu_links[] =
|
|
||||||
array('name' => 'Operations', 'header' => true);
|
|
||||||
|
|
||||||
$this->sidemenu_links[] =
|
|
||||||
array('name' => 'Edit',
|
|
||||||
'url' => array('action' => 'edit',
|
|
||||||
$id));
|
|
||||||
|
|
||||||
// Prepare to render.
|
|
||||||
$title = 'Contact: ' . $contact['Contact']['display_name'];
|
|
||||||
$this->set(compact('contact', 'title'));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
* action: edit
|
|
||||||
*/
|
|
||||||
|
|
||||||
function edit($id = null, $customer_id = null) {
|
|
||||||
if (isset($this->data)) {
|
|
||||||
|
|
||||||
if (isset($this->params['form']['cancel'])) {
|
|
||||||
if (isset($this->data['Contact']['id']))
|
|
||||||
$this->redirect(array('action'=>'view', $this->data['Contact']['id']));
|
|
||||||
/* else */
|
|
||||||
/* $this->redirect(array('controller' => 'customers', */
|
|
||||||
/* 'action'=>'add', $this->data['Customer']['id'])); */
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Go through each contact method and strip the bogus ID if new
|
|
||||||
foreach (array_intersect_key($this->data,
|
|
||||||
array('ContactPhone'=>1,
|
|
||||||
'ContactAddress'=>1,
|
|
||||||
'ContactEmail'=>1)) AS $type => $arr) {
|
|
||||||
foreach ($arr AS $idx => $item) {
|
|
||||||
if (isset($item['source']) && $item['source'] === 'new')
|
|
||||||
unset($this->data[$type][$idx]['id']);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Save the contact and all associated data
|
|
||||||
$this->Contact->saveContact($this->data['Contact']['id'], $this->data);
|
|
||||||
|
|
||||||
// Now that the work is done, let the user view the updated contact
|
|
||||||
$this->redirect(array('action'=>'view', $this->data['Contact']['id']));
|
|
||||||
//$this->render('/empty');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($id) {
|
|
||||||
$this->data = $this->Contact->find
|
|
||||||
('first', array
|
|
||||||
('contain' => array
|
|
||||||
(// Models
|
|
||||||
'ContactPhone',
|
|
||||||
'ContactEmail',
|
|
||||||
'ContactAddress',
|
|
||||||
'Customer'),
|
|
||||||
|
|
||||||
'conditions' => array('Contact.id' => $id),
|
|
||||||
));
|
|
||||||
|
|
||||||
$title = 'Contact: ' . $this->data['Contact']['display_name'] . " : Edit";
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
$title = "Enter New Contact";
|
|
||||||
$this->data = array('ContactPhone' => array(),
|
|
||||||
'ContactAddress' => array(),
|
|
||||||
'ContactEmail' => array());
|
|
||||||
}
|
|
||||||
|
|
||||||
$phone_types = array_flip($this->Contact->ContactPhone->getEnumValues('type'));
|
|
||||||
unset($phone_types[0]);
|
|
||||||
// REVISIT <AP> 20090705
|
|
||||||
// Use this to have a mixed case enum
|
|
||||||
// array_map('ucfirst', array_map('strtolower', $phone_types))
|
|
||||||
$phone_types = array_combine($phone_types, $phone_types);
|
|
||||||
$this->set(compact('phone_types'));
|
|
||||||
|
|
||||||
$method_types = array_flip($this->Contact->getEnumValues
|
|
||||||
('type',
|
|
||||||
$this->Contact->tablePrefix . 'contacts_methods'));
|
|
||||||
unset($method_types[0]);
|
|
||||||
$method_types = array_combine($method_types, $method_types);
|
|
||||||
$this->set(compact('method_types'));
|
|
||||||
|
|
||||||
$method_preferences = array_flip($this->Contact->getEnumValues
|
|
||||||
('preference',
|
|
||||||
$this->Contact->tablePrefix . 'contacts_methods'));
|
|
||||||
unset($method_preferences[0]);
|
|
||||||
$method_preferences = array_combine($method_preferences, $method_preferences);
|
|
||||||
$this->set(compact('method_preferences'));
|
|
||||||
|
|
||||||
$contact_phones = $this->Contact->ContactPhone->phoneList();
|
|
||||||
$this->set(compact('contact_phones'));
|
|
||||||
|
|
||||||
$contact_addresses = $this->Contact->ContactAddress->addressList();
|
|
||||||
$this->set(compact('contact_addresses'));
|
|
||||||
|
|
||||||
$contact_emails = $this->Contact->ContactEmail->emailList();
|
|
||||||
$this->set(compact('contact_emails'));
|
|
||||||
|
|
||||||
// Prepare to render.
|
|
||||||
//pr($this->data);
|
|
||||||
$this->set(compact('title'));
|
|
||||||
$this->render('edit');
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
* action: add
|
|
||||||
* - Adds a new contact
|
|
||||||
*/
|
|
||||||
|
|
||||||
function add($customer_id = null) {
|
|
||||||
$this->edit(null, $customer_id);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,458 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
class CustomersController extends AppController {
|
|
||||||
var $sidemenu_links =
|
|
||||||
array(array('name' => 'Customers', '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')),
|
|
||||||
array('name' => 'Add Customer', 'url' => array('controller' => 'customers', 'action' => 'add')),
|
|
||||||
);
|
|
||||||
|
|
||||||
//var $components = array('RequestHandler');
|
|
||||||
|
|
||||||
|
|
||||||
/**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
* override: sideMenuLinks
|
|
||||||
* - Generates controller specific links for the side menu
|
|
||||||
*/
|
|
||||||
function sideMenuLinks() {
|
|
||||||
return array_merge(parent::sideMenuLinks(), $this->sidemenu_links);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
* action: index / current / past / all
|
|
||||||
* - Creates a list of customers
|
|
||||||
*/
|
|
||||||
|
|
||||||
function index() { $this->current(); }
|
|
||||||
function current() { $this->gridView('Current Tenants', 'current'); }
|
|
||||||
function past() { $this->gridView('Past Tenants'); }
|
|
||||||
function all() { $this->gridView('All Customers'); }
|
|
||||||
|
|
||||||
|
|
||||||
/**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
* virtuals: gridData
|
|
||||||
* - With the application controller handling the gridData action,
|
|
||||||
* these virtual functions ensure that the correct data is passed
|
|
||||||
* to jqGrid.
|
|
||||||
*/
|
|
||||||
|
|
||||||
function gridDataCountTables(&$params, &$model) {
|
|
||||||
return array
|
|
||||||
('link' =>
|
|
||||||
array(// Models
|
|
||||||
'PrimaryContact',
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
function gridDataTables(&$params, &$model) {
|
|
||||||
$link = $this->gridDataCountTables($params, $model);
|
|
||||||
// StatementEntry is needed to determine customer balance
|
|
||||||
$link['link']['StatementEntry'] = array('fields' => array());
|
|
||||||
return $link;
|
|
||||||
}
|
|
||||||
|
|
||||||
function gridDataFields(&$params, &$model) {
|
|
||||||
$fields = parent::gridDataFields($params, $model);
|
|
||||||
return array_merge($fields,
|
|
||||||
$this->Customer->StatementEntry->chargeDisbursementFields(true));
|
|
||||||
}
|
|
||||||
|
|
||||||
function gridDataConditions(&$params, &$model) {
|
|
||||||
$conditions = parent::gridDataConditions($params, $model);
|
|
||||||
|
|
||||||
if ($params['action'] === 'current') {
|
|
||||||
$conditions[] = array('Customer.current_lease_count >' => 0);
|
|
||||||
}
|
|
||||||
elseif ($params['action'] === 'past') {
|
|
||||||
$conditions[] = array('Customer.current_lease_count' => 0);
|
|
||||||
$conditions[] = array('Customer.past_lease_count >' => 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
return $conditions;
|
|
||||||
}
|
|
||||||
|
|
||||||
function gridDataOrder(&$params, &$model, $index, $direction) {
|
|
||||||
$order = array();
|
|
||||||
$order[] = parent::gridDataOrder($params, $model, $index, $direction);
|
|
||||||
|
|
||||||
if ($index !== 'PrimaryContact.last_name')
|
|
||||||
$order[] = parent::gridDataOrder($params, $model,
|
|
||||||
'PrimaryContact.last_name', $direction);
|
|
||||||
if ($index !== 'PrimaryContact.first_name')
|
|
||||||
$order[] = parent::gridDataOrder($params, $model,
|
|
||||||
'PrimaryContact.first_name', $direction);
|
|
||||||
if ($index !== 'Customer.id')
|
|
||||||
$order[] = parent::gridDataOrder($params, $model,
|
|
||||||
'Customer.id', $direction);
|
|
||||||
|
|
||||||
return $order;
|
|
||||||
}
|
|
||||||
|
|
||||||
function gridDataPostProcessLinks(&$params, &$model, &$records, $links) {
|
|
||||||
$links['Customer'] = array('name');
|
|
||||||
return parent::gridDataPostProcessLinks($params, $model, $records, $links);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
* action: move_in
|
|
||||||
* - Sets up the move-in page for the given customer.
|
|
||||||
*/
|
|
||||||
|
|
||||||
function move_in($id = null) {
|
|
||||||
$customer = array();
|
|
||||||
$unit = array();
|
|
||||||
|
|
||||||
if (isset($id)) {
|
|
||||||
$this->Customer->recursive = -1;
|
|
||||||
$customer = current($this->Customer->read(null, $id));
|
|
||||||
}
|
|
||||||
$this->set(compact('customer', 'unit'));
|
|
||||||
|
|
||||||
$title = 'Customer Move-In';
|
|
||||||
$this->set(compact('title'));
|
|
||||||
$this->render('/leases/move');
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
* action: move_out
|
|
||||||
* - prepare to move a customer out of one of their units
|
|
||||||
*/
|
|
||||||
|
|
||||||
function move_out($id) {
|
|
||||||
|
|
||||||
$customer = $this->Customer->find
|
|
||||||
('first', array
|
|
||||||
('contain' => array
|
|
||||||
(// Models
|
|
||||||
'Lease' =>
|
|
||||||
array('conditions' => array('Lease.moveout_date' => null),
|
|
||||||
// Models
|
|
||||||
'Unit' =>
|
|
||||||
array('order' => array('sort_order'),
|
|
||||||
'fields' => array('id', 'name'),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
|
|
||||||
'conditions' => array('Customer.id' => $id),
|
|
||||||
));
|
|
||||||
$this->set('customer', $lease['Customer']);
|
|
||||||
$this->set('unit', array());
|
|
||||||
|
|
||||||
$redirect = array('controller' => 'customers',
|
|
||||||
'action' => 'view',
|
|
||||||
$id);
|
|
||||||
|
|
||||||
$title = $customer['Customer']['name'] . ': Prepare Move-Out';
|
|
||||||
$this->set(compact('title', 'customer', 'redirect'));
|
|
||||||
$this->render('/leases/move');
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
* 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'));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get details on this customer, its contacts and leases
|
|
||||||
$customer = $this->Customer->find
|
|
||||||
('first', array
|
|
||||||
('contain' => array
|
|
||||||
(// Models
|
|
||||||
'Contact' =>
|
|
||||||
array('order' => array('Contact.display_name'),
|
|
||||||
// Models
|
|
||||||
'ContactPhone',
|
|
||||||
'ContactEmail',
|
|
||||||
'ContactAddress',
|
|
||||||
),
|
|
||||||
'Lease' =>
|
|
||||||
array('Unit' =>
|
|
||||||
array('order' => array('sort_order'),
|
|
||||||
'fields' => array('id', 'name'),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
|
|
||||||
'conditions' => array('Customer.id' => $id),
|
|
||||||
));
|
|
||||||
//pr($customer);
|
|
||||||
|
|
||||||
// Figure out the outstanding balances for this customer
|
|
||||||
$outstanding_balance = $this->Customer->balance($id);
|
|
||||||
$outstanding_deposit = $this->Customer->securityDepositBalance($id);
|
|
||||||
|
|
||||||
// Figure out if this customer has any non-closed leases
|
|
||||||
$show_moveout = false;
|
|
||||||
$show_payment = false;
|
|
||||||
foreach ($customer['Lease'] AS $lease) {
|
|
||||||
if (!isset($lease['close_date']))
|
|
||||||
$show_payment = true;
|
|
||||||
if (!isset($lease['moveout_date']))
|
|
||||||
$show_moveout = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set up dynamic menu items
|
|
||||||
$this->sidemenu_links[] =
|
|
||||||
array('name' => 'Operations', 'header' => true);
|
|
||||||
|
|
||||||
$this->sidemenu_links[] =
|
|
||||||
array('name' => 'Edit',
|
|
||||||
'url' => array('action' => 'edit',
|
|
||||||
$id));
|
|
||||||
|
|
||||||
$this->sidemenu_links[] =
|
|
||||||
array('name' => 'Move-In',
|
|
||||||
'url' => array('action' => 'move_in',
|
|
||||||
$id));
|
|
||||||
|
|
||||||
/* if ($show_moveout) { */
|
|
||||||
/* $this->sidemenu_links[] = */
|
|
||||||
/* array('name' => 'Move-Out', */
|
|
||||||
/* 'url' => array('action' => 'move_out', */
|
|
||||||
/* $id)); */
|
|
||||||
/* } */
|
|
||||||
|
|
||||||
if ($show_payment) {
|
|
||||||
$this->sidemenu_links[] =
|
|
||||||
array('name' => 'Payment',
|
|
||||||
'url' => array('action' => 'receipt',
|
|
||||||
$id));
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($outstanding_balance < 0)
|
|
||||||
$this->sidemenu_links[] =
|
|
||||||
array('name' => 'Issue Refund',
|
|
||||||
'url' => array('action' => 'refund', $id));
|
|
||||||
|
|
||||||
// Prepare to render.
|
|
||||||
$title = 'Customer: ' . $customer['Customer']['name'];
|
|
||||||
$this->set(compact('customer', 'title',
|
|
||||||
'outstanding_balance',
|
|
||||||
'outstanding_deposit'));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
* action: edit
|
|
||||||
* - Edit customer information
|
|
||||||
*/
|
|
||||||
|
|
||||||
function edit($id = null) {
|
|
||||||
if (isset($this->data)) {
|
|
||||||
// Check to see if the operation was cancelled.
|
|
||||||
if (isset($this->params['form']['cancel'])) {
|
|
||||||
if (isset($this->data['Customer']['id']))
|
|
||||||
$this->redirect(array('action'=>'view', $this->data['Customer']['id']));
|
|
||||||
else
|
|
||||||
$this->redirect(array('action'=>'index'));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Make sure we have at least one contact
|
|
||||||
if (!isset($this->data['Contact']) || count($this->data['Contact']) == 0) {
|
|
||||||
$this->Session->setFlash("MUST SPECIFY AT LEAST ONE CONTACT", true);
|
|
||||||
$this->redirect(array('action'=>'view', $this->data['Customer']['id']));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Make sure there is a primary contact
|
|
||||||
if (!isset($this->data['Customer']['primary_contact_entry'])) {
|
|
||||||
$this->Session->setFlash("MUST SPECIFY A PRIMARY CONTACT", true);
|
|
||||||
$this->redirect(array('action'=>'view', $this->data['Customer']['id']));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Go through each customer and strip the bogus ID if new
|
|
||||||
foreach ($this->data['Contact'] AS &$contact) {
|
|
||||||
if (isset($contact['source']) && $contact['source'] === 'new')
|
|
||||||
unset($contact['id']);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Save the customer and all associated data
|
|
||||||
if (!$this->Customer->saveCustomer($this->data['Customer']['id'],
|
|
||||||
$this->data,
|
|
||||||
$this->data['Customer']['primary_contact_entry'])) {
|
|
||||||
$this->Session->setFlash("CUSTOMER SAVE FAILED", true);
|
|
||||||
pr("CUSTOMER SAVE FAILED");
|
|
||||||
}
|
|
||||||
|
|
||||||
// If existing customer, then view it. Otherwise, since
|
|
||||||
// this is a new customer, go to the move in screen.
|
|
||||||
if ($this->data['Customer']['id'])
|
|
||||||
$this->redirect(array('action'=>'view', $this->Customer->id));
|
|
||||||
else
|
|
||||||
$this->redirect(array('action'=>'move_in', $this->Customer->id));
|
|
||||||
|
|
||||||
// For debugging, only if the redirects above have been
|
|
||||||
// commented out, otherwise this section isn't reached.
|
|
||||||
$this->render('/empty');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($id) {
|
|
||||||
$this->data = $this->Customer->details($id);
|
|
||||||
$title = 'Customer: ' . $this->data['Customer']['name'] . " : Edit";
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
$title = "Enter New Customer";
|
|
||||||
$this->data = array('Contact' => array(), 'PrimaryContact' => null);
|
|
||||||
}
|
|
||||||
|
|
||||||
$contact_types = array_flip($this->Customer->ContactsCustomer->getEnumValues('type'));
|
|
||||||
unset($contact_types[0]);
|
|
||||||
$contact_types = array_combine($contact_types, $contact_types);
|
|
||||||
$this->set(compact('contact_types'));
|
|
||||||
|
|
||||||
$contacts = $this->Customer->Contact->contactList();
|
|
||||||
$this->set(compact('contacts'));
|
|
||||||
|
|
||||||
// Prepare to render.
|
|
||||||
//pr($this->data);
|
|
||||||
$this->set(compact('title'));
|
|
||||||
$this->render('edit');
|
|
||||||
}
|
|
||||||
|
|
||||||
/**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
* action: add
|
|
||||||
* - Add a new customer
|
|
||||||
*/
|
|
||||||
|
|
||||||
function add() {
|
|
||||||
$this->edit();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
* action: receipt
|
|
||||||
* - Sets up the receipt entry page for the given customer.
|
|
||||||
*/
|
|
||||||
|
|
||||||
function receipt($id = null) {
|
|
||||||
if (isset($id)) {
|
|
||||||
$this->Customer->recursive = -1;
|
|
||||||
$customer = $this->Customer->read(null, $id);
|
|
||||||
$customer = $customer['Customer'];
|
|
||||||
$unreconciled = $this->Customer->unreconciledCharges($id);
|
|
||||||
//pr($unreconciled);
|
|
||||||
$charges = $unreconciled['entries'];
|
|
||||||
$stats = $unreconciled['summary']['Charge'];
|
|
||||||
// Kludge until we update receipt to have the unpaid
|
|
||||||
// charges grid generated from a dynamic query instead
|
|
||||||
// of simply pre-providing the list of charge IDs
|
|
||||||
foreach ($charges AS &$charge)
|
|
||||||
$charge['id'] = $charge['StatementEntry']['id'];
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
$customer = null;
|
|
||||||
$charges = array();
|
|
||||||
$stats = array('balance' => 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
$TT = new TenderType();
|
|
||||||
$payment_types = $TT->paymentTypes();
|
|
||||||
$default_type = $TT->defaultPaymentType();
|
|
||||||
$this->set(compact('payment_types', 'default_type'));
|
|
||||||
|
|
||||||
$title = ($customer['name'] . ': Receipt Entry');
|
|
||||||
$this->set(compact('customer', 'charges', 'stats', 'title'));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
* action: refund
|
|
||||||
* - Refunds customer charges
|
|
||||||
*/
|
|
||||||
|
|
||||||
function refund() {
|
|
||||||
$entries = $this->Customer->StatementEntry->find
|
|
||||||
('all', array
|
|
||||||
('contain' => false,
|
|
||||||
'conditions' => array('StatementEntry.id' =>
|
|
||||||
//array(199,200,201)
|
|
||||||
61
|
|
||||||
),
|
|
||||||
));
|
|
||||||
pr(compact('entries'));
|
|
||||||
|
|
||||||
$this->Customer->refund($entries);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
* action: unreconciled
|
|
||||||
* - returns the list of unreconciled entries
|
|
||||||
*/
|
|
||||||
|
|
||||||
function unreconciled($id) {
|
|
||||||
|
|
||||||
//$this->layout = 'ajax';
|
|
||||||
$this->layout = null;
|
|
||||||
$this->autoLayout = false;
|
|
||||||
$this->autoRender = false;
|
|
||||||
Configure::write('debug', '0');
|
|
||||||
header("Content-type: text/xml;charset=utf-8");
|
|
||||||
|
|
||||||
App::import('Helper', 'Xml');
|
|
||||||
$xml = new XmlHelper();
|
|
||||||
|
|
||||||
// Find the unreconciled entries, then manipulate the structure
|
|
||||||
// slightly to accomodate the format necessary for XML Helper.
|
|
||||||
$unreconciled = $this->Customer->unreconciledCharges($id);
|
|
||||||
|
|
||||||
foreach ($unreconciled['entries'] AS &$entry)
|
|
||||||
$entry = array_intersect_key($entry['StatementEntry'],
|
|
||||||
array('id'=>1));
|
|
||||||
|
|
||||||
$unreconciled = array('entries' =>
|
|
||||||
array('entry' => $unreconciled['entries'],
|
|
||||||
'balance' => $unreconciled['summary']['balance']));
|
|
||||||
|
|
||||||
// XML Helper will dump an empty tag if the array is empty
|
|
||||||
if (empty($unreconciled['entries']['entry']))
|
|
||||||
unset($unreconciled['entries']['entry']);
|
|
||||||
|
|
||||||
/* pr(compact('unreconciled')); */
|
|
||||||
/* echo htmlspecialchars($xml->serialize($unreconciled)); */
|
|
||||||
/* $this->render('/fake'); */
|
|
||||||
|
|
||||||
$opts = array();
|
|
||||||
//$opts['format'] = 'tags';
|
|
||||||
echo $xml->header();
|
|
||||||
echo $xml->serialize($unreconciled, $opts);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,44 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
class DoubleEntriesController extends AppController {
|
|
||||||
|
|
||||||
var $sidemenu_links = array();
|
|
||||||
|
|
||||||
|
|
||||||
/**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
* 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'));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get the Entry and related fields
|
|
||||||
$entry = $this->DoubleEntry->find
|
|
||||||
('first',
|
|
||||||
array('contain' => array('DebitEntry', 'CreditEntry'),
|
|
||||||
'conditions' => array('DoubleEntry.id' => $id),
|
|
||||||
));
|
|
||||||
|
|
||||||
// Prepare to render.
|
|
||||||
$title = "Double Ledger Entry #{$entry['DoubleEntry']['id']}";
|
|
||||||
$this->set(compact('entry', 'title'));
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,462 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
class LeasesController extends AppController {
|
|
||||||
|
|
||||||
var $sidemenu_links =
|
|
||||||
array(array('name' => 'Leases', 'header' => true),
|
|
||||||
array('name' => 'Active', 'url' => array('controller' => 'leases', 'action' => 'active')),
|
|
||||||
array('name' => 'Closed', 'url' => array('controller' => 'leases', 'action' => 'closed')),
|
|
||||||
array('name' => 'All', 'url' => array('controller' => 'leases', 'action' => 'all')),
|
|
||||||
);
|
|
||||||
|
|
||||||
|
|
||||||
/**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
* override: sideMenuLinks
|
|
||||||
* - Generates controller specific links for the side menu
|
|
||||||
*/
|
|
||||||
function sideMenuLinks() {
|
|
||||||
return array_merge(parent::sideMenuLinks(), $this->sidemenu_links);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
* action: index / active / closed / all
|
|
||||||
* - Generate a listing of leases
|
|
||||||
*/
|
|
||||||
|
|
||||||
function index() { $this->all(); }
|
|
||||||
function active() { $this->gridView('Active Leases'); }
|
|
||||||
function closed() { $this->gridView('Closed Leases'); }
|
|
||||||
function all() { $this->gridView('All Leases', 'all'); }
|
|
||||||
|
|
||||||
|
|
||||||
/**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
* virtuals: gridData
|
|
||||||
* - With the application controller handling the gridData action,
|
|
||||||
* these virtual functions ensure that the correct data is passed
|
|
||||||
* to jqGrid.
|
|
||||||
*/
|
|
||||||
|
|
||||||
function gridDataSetup(&$params) {
|
|
||||||
parent::gridDataSetup($params);
|
|
||||||
if (!isset($params['action']))
|
|
||||||
$params['action'] = 'all';
|
|
||||||
}
|
|
||||||
|
|
||||||
function gridDataCountTables(&$params, &$model) {
|
|
||||||
return array
|
|
||||||
('link' => array('Unit' => array('fields' => array('id', 'name')),
|
|
||||||
'Customer' => array('fields' => array('id', 'name'))));
|
|
||||||
}
|
|
||||||
|
|
||||||
function gridDataTables(&$params, &$model) {
|
|
||||||
$link = $this->gridDataCountTables($params, $model);
|
|
||||||
$link['link']['StatementEntry'] = array('fields' => array());
|
|
||||||
return $link;
|
|
||||||
}
|
|
||||||
|
|
||||||
function gridDataFields(&$params, &$model) {
|
|
||||||
$fields = parent::gridDataFields($params, $model);
|
|
||||||
return array_merge($fields,
|
|
||||||
$this->Lease->StatementEntry->chargeDisbursementFields(true));
|
|
||||||
}
|
|
||||||
|
|
||||||
function gridDataConditions(&$params, &$model) {
|
|
||||||
$conditions = parent::gridDataConditions($params, $model);
|
|
||||||
|
|
||||||
if ($params['action'] === 'active') {
|
|
||||||
$conditions[] = 'Lease.close_date IS NULL';
|
|
||||||
}
|
|
||||||
elseif ($params['action'] === 'closed') {
|
|
||||||
$conditions[] = 'Lease.close_date IS NOT NULL';
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isset($customer_id))
|
|
||||||
$conditions[] = array('Lease.customer_id' => $customer_id);
|
|
||||||
|
|
||||||
return $conditions;
|
|
||||||
}
|
|
||||||
|
|
||||||
function gridDataOrder(&$params, &$model, $index, $direction) {
|
|
||||||
// Do not sort by number, which is type varchar and
|
|
||||||
// sorts on an ascii basis. Sort by ID instead.
|
|
||||||
if ($index === 'Lease.number')
|
|
||||||
$index = 'Lease.id';
|
|
||||||
|
|
||||||
// Instead of sorting by name, sort by defined order
|
|
||||||
if ($index === 'Unit.name')
|
|
||||||
$index = 'Unit.sort_order';
|
|
||||||
|
|
||||||
$order = array();
|
|
||||||
$order[] = parent::gridDataOrder($params, $model, $index, $direction);
|
|
||||||
|
|
||||||
// If sorting by anything other than id/number
|
|
||||||
// add sorting by id as a secondary condition.
|
|
||||||
if ($index !== 'Lease.id' && $index !== 'Lease.number')
|
|
||||||
$order[] = parent::gridDataOrder($params, $model,
|
|
||||||
'Lease.id', $direction);
|
|
||||||
|
|
||||||
return $order;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* function gridDataPostProcess(&$params, &$model, &$records) { */
|
|
||||||
/* foreach ($records AS &$record) { */
|
|
||||||
/* $record['Lease']['through_date'] */
|
|
||||||
/* = $this->Lease->rentChargeThrough($record['Lease']['id']); */
|
|
||||||
/* } */
|
|
||||||
|
|
||||||
/* parent::gridDataPostProcess($params, $model, $records); */
|
|
||||||
/* } */
|
|
||||||
|
|
||||||
function gridDataPostProcessLinks(&$params, &$model, &$records, $links) {
|
|
||||||
$links['Lease'] = array('number');
|
|
||||||
$links['Unit'] = array('name');
|
|
||||||
$links['Customer'] = array('name');
|
|
||||||
return parent::gridDataPostProcessLinks($params, $model, $records, $links);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
* action: move_in
|
|
||||||
* - execute a move in on a new lease
|
|
||||||
*/
|
|
||||||
|
|
||||||
function move_in() {
|
|
||||||
if (!$this->data)
|
|
||||||
die("Should have some data");
|
|
||||||
|
|
||||||
// Handle the move in based on the data given
|
|
||||||
//pr(array('Move-in data', $this->data));
|
|
||||||
|
|
||||||
$lid = $this->Lease->moveIn($this->data['Lease']['customer_id'],
|
|
||||||
$this->data['Lease']['unit_id'],
|
|
||||||
null, null,
|
|
||||||
$this->data['Lease']['movein_date'],
|
|
||||||
$this->data['Lease']['comment']
|
|
||||||
);
|
|
||||||
|
|
||||||
// Since this is a new lease, go to the invoice
|
|
||||||
// screen so we can start assessing charges.
|
|
||||||
$this->redirect(array('action'=>'invoice', $lid));
|
|
||||||
|
|
||||||
// For debugging, only if the redirect above have been
|
|
||||||
// commented out, otherwise this section isn't reached.
|
|
||||||
$this->render('/empty');
|
|
||||||
}
|
|
||||||
|
|
||||||
/**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
* action: move_out
|
|
||||||
* - prepare or execute a move out on a specific lease
|
|
||||||
*/
|
|
||||||
|
|
||||||
function move_out($id = null) {
|
|
||||||
if ($this->data) {
|
|
||||||
// Handle the move out based on the data given
|
|
||||||
//pr($this->data);
|
|
||||||
|
|
||||||
$this->Lease->moveOut($this->data['Lease']['id'],
|
|
||||||
'VACANT',
|
|
||||||
$this->data['Lease']['moveout_date'],
|
|
||||||
//true // Close this lease, if able
|
|
||||||
false
|
|
||||||
);
|
|
||||||
|
|
||||||
$this->redirect($this->data['redirect']);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!isset($id))
|
|
||||||
die("Oh Nooooo!!");
|
|
||||||
|
|
||||||
$lease = $this->Lease->find
|
|
||||||
('first', array
|
|
||||||
('contain' => array
|
|
||||||
(// Models
|
|
||||||
'Unit' =>
|
|
||||||
array('order' => array('sort_order'),
|
|
||||||
'fields' => array('id', 'name'),
|
|
||||||
),
|
|
||||||
|
|
||||||
'Customer' =>
|
|
||||||
array('fields' => array('id', 'name'),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
|
|
||||||
'conditions' => array(array('Lease.id' => $id),
|
|
||||||
array('Lease.close_date' => null),
|
|
||||||
),
|
|
||||||
));
|
|
||||||
$this->set('customer', $lease['Customer']);
|
|
||||||
$this->set('unit', $lease['Unit']);
|
|
||||||
$this->set('lease', $lease['Lease']);
|
|
||||||
|
|
||||||
$redirect = array('controller' => 'leases',
|
|
||||||
'action' => 'view',
|
|
||||||
$id);
|
|
||||||
|
|
||||||
$title = ('Lease #' . $lease['Lease']['number'] . ': ' .
|
|
||||||
$lease['Unit']['name'] . ': ' .
|
|
||||||
$lease['Customer']['name'] . ': Prepare Move-Out');
|
|
||||||
$this->set(compact('title', 'redirect'));
|
|
||||||
$this->render('/leases/move');
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* /\************************************************************************** */
|
|
||||||
/* ************************************************************************** */
|
|
||||||
/* ************************************************************************** */
|
|
||||||
/* * action: promote_credit */
|
|
||||||
/* * - Moves any lease credit up to the customer level, so that */
|
|
||||||
/* * it may be used for charges other than those on this lease. */
|
|
||||||
/* *\/ */
|
|
||||||
|
|
||||||
/* function promote_surplus($id) { */
|
|
||||||
/* $this->Lease->promoteSurplus($id); */
|
|
||||||
/* pr("PREVENTING REDIRECT"); */
|
|
||||||
/* $this->render('fake'); */
|
|
||||||
/* $this->redirect(array('controller' => 'leases', */
|
|
||||||
/* 'action' => 'view', */
|
|
||||||
/* $id)); */
|
|
||||||
/* } */
|
|
||||||
|
|
||||||
|
|
||||||
/**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
* action: refund
|
|
||||||
* - Provides lease customer with a refund
|
|
||||||
*/
|
|
||||||
|
|
||||||
function refund($id) {
|
|
||||||
$lease = $this->Lease->find
|
|
||||||
('first', array
|
|
||||||
('contain' => array
|
|
||||||
(// Models
|
|
||||||
'Unit' => array('fields' => array('id', 'name')),
|
|
||||||
'Customer' => array('fields' => array('id', 'name')),
|
|
||||||
),
|
|
||||||
|
|
||||||
'conditions' => array(array('Lease.id' => $id),
|
|
||||||
// Make sure lease is not closed...
|
|
||||||
array('Lease.close_date' => null),
|
|
||||||
),
|
|
||||||
));
|
|
||||||
if (empty($lease)) {
|
|
||||||
$this->redirect(array('action'=>'view', $id));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Determine the lease balance, bailing if the customer owes money
|
|
||||||
$balance = $this->Lease->balance($id);
|
|
||||||
if ($balance >= 0) {
|
|
||||||
$this->redirect(array('action'=>'view', $id));
|
|
||||||
}
|
|
||||||
|
|
||||||
// The refund will be for a positive amount
|
|
||||||
$balance *= -1;
|
|
||||||
|
|
||||||
// Get the accounts capable of paying the refund
|
|
||||||
$refundAccounts = $this->Lease->StatementEntry->Account->refundAccounts();
|
|
||||||
$defaultAccount = current($refundAccounts);
|
|
||||||
$this->set(compact('refundAccounts', 'defaultAccount'));
|
|
||||||
|
|
||||||
// Prepare to render
|
|
||||||
$title = ('Lease #' . $lease['Lease']['number'] . ': ' .
|
|
||||||
$lease['Unit']['name'] . ': ' .
|
|
||||||
$lease['Customer']['name'] . ': Refund');
|
|
||||||
$this->set(compact('title', 'lease', 'balance'));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
* action: bad_debt
|
|
||||||
* - Sets up the write-off entry page, so that the
|
|
||||||
* user can write off remaining charges on a lease.
|
|
||||||
*/
|
|
||||||
|
|
||||||
function bad_debt($id) {
|
|
||||||
$lease = $this->Lease->find
|
|
||||||
('first', array
|
|
||||||
('contain' => array
|
|
||||||
(// Models
|
|
||||||
'Unit' => array('fields' => array('id', 'name')),
|
|
||||||
'Customer' => array('fields' => array('id', 'name')),
|
|
||||||
),
|
|
||||||
|
|
||||||
'conditions' => array(array('Lease.id' => $id),
|
|
||||||
// Make sure lease is not closed...
|
|
||||||
array('Lease.close_date' => null),
|
|
||||||
),
|
|
||||||
));
|
|
||||||
|
|
||||||
// Make sure we have a valid lease to write off
|
|
||||||
if (empty($lease))
|
|
||||||
$this->redirect(array('action' => 'view', $id));
|
|
||||||
|
|
||||||
// Get the lease balance, part of lease stats
|
|
||||||
$stats = $this->Lease->stats($id);
|
|
||||||
$balance = $stats['balance'];
|
|
||||||
|
|
||||||
// Prepare to render
|
|
||||||
$title = ('Lease #' . $lease['Lease']['number'] . ': ' .
|
|
||||||
$lease['Unit']['name'] . ': ' .
|
|
||||||
$lease['Customer']['name'] . ': Write Off Bad Debt');
|
|
||||||
$this->set(compact('title', 'lease', 'balance'));
|
|
||||||
$this->render('/transactions/bad_debt');
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
* action: close
|
|
||||||
* - Closes a lease to any further action
|
|
||||||
*/
|
|
||||||
|
|
||||||
function close($id) {
|
|
||||||
// REVISIT <AP>: 20090708
|
|
||||||
// We should probably seek confirmation first...
|
|
||||||
$this->Lease->close($id);
|
|
||||||
$this->redirect(array('action'=>'view', $id));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
* action: invoice
|
|
||||||
* - Sets up the invoice entry page for the given customer.
|
|
||||||
*/
|
|
||||||
|
|
||||||
function invoice($id = null, $type = null) {
|
|
||||||
|
|
||||||
$lease = $this->Lease->find
|
|
||||||
('first', array
|
|
||||||
('contain' => array
|
|
||||||
(// Models
|
|
||||||
'Unit' =>
|
|
||||||
array('order' => array('sort_order'),
|
|
||||||
'fields' => array('id', 'name'),
|
|
||||||
),
|
|
||||||
|
|
||||||
'Customer' =>
|
|
||||||
array('fields' => array('id', 'name'),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
|
|
||||||
'conditions' => array(array('Lease.id' => $id),
|
|
||||||
array('Lease.close_date' => null),
|
|
||||||
),
|
|
||||||
));
|
|
||||||
|
|
||||||
$A = new Account();
|
|
||||||
$charge_accounts = $A->invoiceAccounts();
|
|
||||||
$default_account = $A->rentAccountID();
|
|
||||||
$this->set(compact('charge_accounts', 'default_account'));
|
|
||||||
|
|
||||||
// REVISIT <AP> 20090705:
|
|
||||||
// Of course, the late charge should come from the late_schedule
|
|
||||||
$default_rent = $lease['Lease']['rent'];
|
|
||||||
$default_late = 10;
|
|
||||||
$this->set(compact('default_rent', 'default_late'));
|
|
||||||
|
|
||||||
$title = ('Lease #' . $lease['Lease']['number'] . ': ' .
|
|
||||||
$lease['Unit']['name'] . ': ' .
|
|
||||||
$lease['Customer']['name'] . ': Charge Entry');
|
|
||||||
$this->set(compact('title', 'lease', 'charge'));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
* action: view
|
|
||||||
* - Displays information about a specific lease
|
|
||||||
*/
|
|
||||||
|
|
||||||
function view($id = null) {
|
|
||||||
if (!$id) {
|
|
||||||
$this->Session->setFlash(__('Invalid Item.', true));
|
|
||||||
$this->redirect(array('action'=>'index'));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get details about the lease and its ledgers (no ledger entries yet)
|
|
||||||
$lease = $this->Lease->find
|
|
||||||
('first',
|
|
||||||
array('contain' =>
|
|
||||||
array(// Models
|
|
||||||
'LeaseType',
|
|
||||||
'Unit',
|
|
||||||
'Customer',
|
|
||||||
),
|
|
||||||
'conditions' => array(array('Lease.id' => $id)),
|
|
||||||
)
|
|
||||||
);
|
|
||||||
|
|
||||||
$lease['Lease']['paid_through'] = $this->Lease->rentPaidThrough($id);
|
|
||||||
|
|
||||||
|
|
||||||
$this->set('charge_gaps', $this->Lease->rentChargeGaps($id));
|
|
||||||
$this->set('charge_through', $this->Lease->rentChargeThrough($id));
|
|
||||||
|
|
||||||
// Figure out the outstanding balances for this lease
|
|
||||||
$outstanding_balance = $this->Lease->balance($id);
|
|
||||||
$outstanding_deposit = $this->Lease->securityDepositBalance($id);
|
|
||||||
|
|
||||||
// Set up dynamic menu items
|
|
||||||
if (!isset($lease['Lease']['close_date'])) {
|
|
||||||
$this->sidemenu_links[] =
|
|
||||||
array('name' => 'Operations', 'header' => true);
|
|
||||||
|
|
||||||
if (!isset($lease['Lease']['moveout_date']))
|
|
||||||
$this->sidemenu_links[] =
|
|
||||||
array('name' => 'Move-Out', 'url' => array('action' => 'move_out',
|
|
||||||
$id));
|
|
||||||
|
|
||||||
$this->sidemenu_links[] =
|
|
||||||
array('name' => 'Charges', 'url' => array('action' => 'invoice',
|
|
||||||
$id));
|
|
||||||
|
|
||||||
$this->sidemenu_links[] =
|
|
||||||
array('name' => 'Payments', 'url' => array('controller' => 'customers',
|
|
||||||
'action' => 'receipt',
|
|
||||||
$lease['Customer']['id']));
|
|
||||||
|
|
||||||
/* if ($outstanding_balance < 0) */
|
|
||||||
/* $this->sidemenu_links[] = */
|
|
||||||
/* array('name' => 'Transfer Credit to Customer', */
|
|
||||||
/* 'url' => array('action' => 'promote_surplus', $id)); */
|
|
||||||
|
|
||||||
if ($outstanding_balance < 0)
|
|
||||||
$this->sidemenu_links[] =
|
|
||||||
array('name' => 'Issue Refund',
|
|
||||||
'url' => array('action' => 'refund', $id));
|
|
||||||
|
|
||||||
if (isset($lease['Lease']['moveout_date']) && $outstanding_balance > 0)
|
|
||||||
$this->sidemenu_links[] =
|
|
||||||
array('name' => 'Write-Off', 'url' => array('action' => 'bad_debt',
|
|
||||||
$id));
|
|
||||||
|
|
||||||
if ($this->Lease->closeable($id))
|
|
||||||
$this->sidemenu_links[] =
|
|
||||||
array('name' => 'Close', 'url' => array('action' => 'close',
|
|
||||||
$id));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Prepare to render
|
|
||||||
$title = 'Lease: #' . $lease['Lease']['id'];
|
|
||||||
$this->set(compact('lease', 'title',
|
|
||||||
'outstanding_deposit',
|
|
||||||
'outstanding_balance'));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,199 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
class LedgerEntriesController extends AppController {
|
|
||||||
|
|
||||||
var $sidemenu_links = array();
|
|
||||||
|
|
||||||
|
|
||||||
/**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
* override: sideMenuLinks
|
|
||||||
* - Generates controller specific links for the side menu
|
|
||||||
*/
|
|
||||||
function sideMenuLinks() {
|
|
||||||
return array_merge(parent::sideMenuLinks(), $this->sidemenu_links);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
* action: index / current / past / all
|
|
||||||
* - Creates a list of ledger entries
|
|
||||||
*/
|
|
||||||
|
|
||||||
function index() { $this->gridView('All Ledger Entries'); }
|
|
||||||
|
|
||||||
|
|
||||||
/**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
* virtuals: gridData
|
|
||||||
* - With the application controller handling the gridData action,
|
|
||||||
* these virtual functions ensure that the correct data is passed
|
|
||||||
* to jqGrid.
|
|
||||||
*/
|
|
||||||
|
|
||||||
function gridDataTables(&$params, &$model) {
|
|
||||||
$link =
|
|
||||||
array(// Models
|
|
||||||
'Transaction' =>
|
|
||||||
array('fields' => array('id', 'stamp'),
|
|
||||||
),
|
|
||||||
|
|
||||||
'Ledger' =>
|
|
||||||
array('fields' => array('id', 'sequence'),
|
|
||||||
'Account' =>
|
|
||||||
array('fields' => array('id', 'name', 'type'),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
|
|
||||||
'Tender' =>
|
|
||||||
array('fields' => array('id', 'name', 'nsf_transaction_id'),
|
|
||||||
),
|
|
||||||
|
|
||||||
/* 'DebitEntry', */
|
|
||||||
/* 'CreditEntry', */
|
|
||||||
);
|
|
||||||
|
|
||||||
return array('link' => $link);
|
|
||||||
}
|
|
||||||
|
|
||||||
function gridDataFields(&$params, &$model) {
|
|
||||||
$fields = parent::gridDataFields($params, $model);
|
|
||||||
return array_merge($fields,
|
|
||||||
$this->LedgerEntry->debitCreditFields());
|
|
||||||
}
|
|
||||||
|
|
||||||
function gridDataFilterTablesTable(&$params, &$model, $table) {
|
|
||||||
$table = $this->gridDataFilterTableName($params, $model, $table);
|
|
||||||
// Account is already part of our standard table set.
|
|
||||||
// Ensure we don't add it in again as part of filtering.
|
|
||||||
if ($table == 'Account')
|
|
||||||
return null;
|
|
||||||
|
|
||||||
// Customer needs to be added beneath Transaction
|
|
||||||
if ($table == 'Customer')
|
|
||||||
return 'Transaction';
|
|
||||||
|
|
||||||
return $table;
|
|
||||||
}
|
|
||||||
|
|
||||||
function gridDataFilterTablesConfig(&$params, &$model, $table) {
|
|
||||||
$config = parent::gridDataFilterTablesConfig($params, $model, $table);
|
|
||||||
|
|
||||||
// Customer is special in that its linked in by Transaction
|
|
||||||
// Therefore, the actual table used for the join is 'Transaction',
|
|
||||||
// not 'Customer', and so we need to specify Customer here.
|
|
||||||
if ($table == 'Customer')
|
|
||||||
$config = array('Customer' => $config);
|
|
||||||
|
|
||||||
return $config;
|
|
||||||
}
|
|
||||||
|
|
||||||
function gridDataFilterConditionsStatement(&$params, &$model, $table, $key, $value) {
|
|
||||||
//pr(compact('table', 'key', 'value'));
|
|
||||||
if ($table == 'Account' && $value['value_present'] && $value['value'] === '-AR-')
|
|
||||||
$value = $this->LedgerEntry->Ledger->Account->accountReceivableAccountID();
|
|
||||||
return parent::gridDataFilterConditionsStatement($params, $model, $table, $key, $value);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
function gridDataOrder(&$params, &$model, $index, $direction) {
|
|
||||||
/* if ($index === 'balance') */
|
|
||||||
/* return ($index .' '. $direction); */
|
|
||||||
$order = parent::gridDataOrder($params, $model, $index, $direction);
|
|
||||||
|
|
||||||
if ($index === 'Transaction.stamp') {
|
|
||||||
$order[] = 'LedgerEntry.id ' . $direction;
|
|
||||||
}
|
|
||||||
|
|
||||||
return $order;
|
|
||||||
}
|
|
||||||
|
|
||||||
function gridDataPostProcessCalculatedFields(&$params, &$model, &$records) {
|
|
||||||
parent::gridDataPostProcessCalculatedFields($params, $model, $records);
|
|
||||||
foreach ($records AS &$record) {
|
|
||||||
// REVISIT <AP>: 20090730
|
|
||||||
// We really need the grid to handle this. We probably need to
|
|
||||||
// either create a hidden column with the nsf id, or pass back
|
|
||||||
// a list of nsf items as user data. We can then add an onload
|
|
||||||
// function to sweep through the nsf items and format them.
|
|
||||||
// For now... this works.
|
|
||||||
if (!empty($record['Tender']['nsf_transaction_id']))
|
|
||||||
$record['Tender']['name'] =
|
|
||||||
'<SPAN class="nsf-tender">' . $record['Tender']['name'] . '</SPAN>';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function gridDataPostProcessLinks(&$params, &$model, &$records, $links) {
|
|
||||||
$links['LedgerEntry'] = array('id');
|
|
||||||
$links['Transaction'] = array('id');
|
|
||||||
$links['Ledger'] = array('id');
|
|
||||||
$links['Account'] = array('controller' => 'accounts', 'name');
|
|
||||||
$links['Tender'] = array('name');
|
|
||||||
return parent::gridDataPostProcessLinks($params, $model, $records, $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'));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get the Entry and related fields
|
|
||||||
$entry = $this->LedgerEntry->find
|
|
||||||
('first',
|
|
||||||
array('contain' => array
|
|
||||||
(
|
|
||||||
'Transaction' =>
|
|
||||||
array('fields' => array('id', 'stamp'),
|
|
||||||
),
|
|
||||||
|
|
||||||
'Ledger' =>
|
|
||||||
array('fields' => array('id', 'sequence', 'name'),
|
|
||||||
'Account' =>
|
|
||||||
array('fields' => array('id', 'name', 'type'),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
|
|
||||||
'Tender' =>
|
|
||||||
array('fields' => array('id', 'name'),
|
|
||||||
),
|
|
||||||
|
|
||||||
'DebitEntry' => array('fields' => array('id', 'crdr')),
|
|
||||||
'CreditEntry' => array('fields' => array('id', 'crdr')),
|
|
||||||
),
|
|
||||||
|
|
||||||
'conditions' => array('LedgerEntry.id' => $id),
|
|
||||||
));
|
|
||||||
|
|
||||||
if (!empty($entry['DebitEntry']) && !empty($entry['CreditEntry']))
|
|
||||||
die("LedgerEntry has both a matching DebitEntry and CreditEntry");
|
|
||||||
if (empty($entry['DebitEntry']) && empty($entry['CreditEntry']))
|
|
||||||
die("LedgerEntry has neither a matching DebitEntry nor a CreditEntry");
|
|
||||||
if (empty($entry['DebitEntry']) && count($entry['CreditEntry']) != 1)
|
|
||||||
die("LedgerEntry has more than one CreditEntry");
|
|
||||||
if (empty($entry['CreditEntry']) && count($entry['DebitEntry']) != 1)
|
|
||||||
die("LedgerEntry has more than one DebitEntry");
|
|
||||||
|
|
||||||
if (empty($entry['DebitEntry']))
|
|
||||||
$entry['MatchingEntry'] = $entry['CreditEntry'][0];
|
|
||||||
else
|
|
||||||
$entry['MatchingEntry'] = $entry['DebitEntry'][0];
|
|
||||||
|
|
||||||
// Prepare to render.
|
|
||||||
$title = "Ledger Entry #{$entry['LedgerEntry']['id']}";
|
|
||||||
$this->set(compact('entry', 'title'));
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,145 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
class LedgersController extends AppController {
|
|
||||||
|
|
||||||
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 / current / closed / all
|
|
||||||
* - Generate a list of ledgers
|
|
||||||
*/
|
|
||||||
|
|
||||||
function index() { $this->all(); }
|
|
||||||
function current() { $this->gridView('Current Ledgers'); }
|
|
||||||
function closed() { $this->gridView('Closed Ledgers'); }
|
|
||||||
function all() { $this->gridView('All Ledgers', 'all'); }
|
|
||||||
|
|
||||||
|
|
||||||
/**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
* virtuals: gridData
|
|
||||||
* - With the application controller handling the gridData action,
|
|
||||||
* these virtual functions ensure that the correct data is passed
|
|
||||||
* to jqGrid.
|
|
||||||
*/
|
|
||||||
|
|
||||||
function gridDataSetup(&$params) {
|
|
||||||
parent::gridDataSetup($params);
|
|
||||||
if (!isset($params['action']))
|
|
||||||
$params['action'] = 'all';
|
|
||||||
}
|
|
||||||
|
|
||||||
function gridDataCountTables(&$params, &$model) {
|
|
||||||
// Our count should NOT include anything extra,
|
|
||||||
// so we need the virtual function to prevent
|
|
||||||
// the base class from just calling our
|
|
||||||
// gridDataTables function.
|
|
||||||
return parent::gridDataTables($params, $model);
|
|
||||||
}
|
|
||||||
|
|
||||||
function gridDataTables(&$params, &$model) {
|
|
||||||
return array
|
|
||||||
('link' =>
|
|
||||||
array(// Models
|
|
||||||
'Account',
|
|
||||||
'LedgerEntry',
|
|
||||||
'CloseTransaction',
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
function gridDataFields(&$params, &$model) {
|
|
||||||
$fields = parent::gridDataFields($params, $model);
|
|
||||||
$fields[] = 'CONCAT(Account.id, "-", Ledger.sequence) AS id_sequence';
|
|
||||||
return array_merge($fields,
|
|
||||||
$this->Ledger->LedgerEntry->debitCreditFields(true));
|
|
||||||
}
|
|
||||||
|
|
||||||
function gridDataConditions(&$params, &$model) {
|
|
||||||
$conditions = parent::gridDataConditions($params, $model);
|
|
||||||
|
|
||||||
if ($params['action'] === 'current') {
|
|
||||||
$conditions[] = array('Ledger.close_transaction_id' => null);
|
|
||||||
}
|
|
||||||
elseif ($params['action'] === 'closed') {
|
|
||||||
$conditions[] = array('Ledger.close_transaction_id !=' => null);
|
|
||||||
}
|
|
||||||
|
|
||||||
return $conditions;
|
|
||||||
}
|
|
||||||
|
|
||||||
function gridDataOrder(&$params, &$model, $index, $direction) {
|
|
||||||
$id_sequence = false;
|
|
||||||
if ($index === 'id_sequence') {
|
|
||||||
$id_sequence = true;
|
|
||||||
$index = 'Ledger.account_id';
|
|
||||||
}
|
|
||||||
|
|
||||||
$order = parent::gridDataOrder($params, $model, $index, $direction);
|
|
||||||
|
|
||||||
if ($id_sequence) {
|
|
||||||
$order[] = 'Ledger.sequence ' . $direction;
|
|
||||||
}
|
|
||||||
|
|
||||||
return $order;
|
|
||||||
}
|
|
||||||
|
|
||||||
function gridDataPostProcessLinks(&$params, &$model, &$records, $links) {
|
|
||||||
$links['Ledger'] = array('id_sequence');
|
|
||||||
$links['Account'] = array('name');
|
|
||||||
return parent::gridDataPostProcessLinks($params, $model, $records, $links);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
* 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'));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get details about the ledger itself (no entries yet)
|
|
||||||
$ledger = $this->Ledger->find
|
|
||||||
('first',
|
|
||||||
array('contain' =>
|
|
||||||
array(// Models
|
|
||||||
'Account',
|
|
||||||
),
|
|
||||||
'conditions' => array(array('Ledger.id' => $id)),
|
|
||||||
)
|
|
||||||
);
|
|
||||||
|
|
||||||
// Get ledger stats for our summary box
|
|
||||||
$stats = $this->Ledger->stats($id);
|
|
||||||
|
|
||||||
// OK, set our view variables and render!
|
|
||||||
$title = 'Ledger: #' . $ledger['Account']['id'] .'-'. $ledger['Ledger']['sequence'];
|
|
||||||
$this->set(compact('ledger', 'title', 'stats'));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,276 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
class StatementEntriesController extends AppController {
|
|
||||||
|
|
||||||
var $sidemenu_links = array();
|
|
||||||
|
|
||||||
|
|
||||||
/**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
* override: sideMenuLinks
|
|
||||||
* - Generates controller specific links for the side menu
|
|
||||||
*/
|
|
||||||
function sideMenuLinks() {
|
|
||||||
return array_merge(parent::sideMenuLinks(), $this->sidemenu_links);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
* action: index / current / past / all
|
|
||||||
* - Creates a list of statement entries
|
|
||||||
*/
|
|
||||||
|
|
||||||
function index() { $this->gridView('All Statement Entries'); }
|
|
||||||
|
|
||||||
|
|
||||||
/**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
* virtuals: gridData
|
|
||||||
* - With the application controller handling the gridData action,
|
|
||||||
* these virtual functions ensure that the correct data is passed
|
|
||||||
* to jqGrid.
|
|
||||||
*/
|
|
||||||
|
|
||||||
function gridDataTables(&$params, &$model) {
|
|
||||||
$link =
|
|
||||||
array(// Models
|
|
||||||
'Transaction' =>
|
|
||||||
array('fields' => array('id', 'stamp'),
|
|
||||||
),
|
|
||||||
|
|
||||||
'Customer' =>
|
|
||||||
array('fields' => array('id', 'name'),
|
|
||||||
),
|
|
||||||
|
|
||||||
'Lease' =>
|
|
||||||
array('fields' => array('id', 'number'),
|
|
||||||
'Unit' =>
|
|
||||||
array('fields' => array('id', 'name'),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
|
|
||||||
'Account' =>
|
|
||||||
array('fields' => array('id', 'name', 'type'),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
|
|
||||||
if (isset($params['post']['custom']['statement_entry_id'])) {
|
|
||||||
$link['DisbursementEntry'] = array();
|
|
||||||
$link['ChargeEntry'] = array();
|
|
||||||
}
|
|
||||||
|
|
||||||
/* if ($params['action'] === 'collected') { */
|
|
||||||
/* $link['DisbursementEntry'] = array('Receipt' => array('class' => 'Transaction')); */
|
|
||||||
/* $link['ChargeEntry'] = array('Invoice' => array('class' => 'Transaction')); */
|
|
||||||
/* } */
|
|
||||||
|
|
||||||
/* if (count(array_intersect($params['fields'], array('applied'))) == 1) { */
|
|
||||||
/* $link['DisbursementEntry'] = array(); */
|
|
||||||
/* $link['ChargeEntry'] = array(); */
|
|
||||||
/* } */
|
|
||||||
/* elseif (isset($params['post']['custom']['customer_id']) || isset($params['post']['custom']['lease_id'])) { */
|
|
||||||
/* $link['DisbursementEntry'] = array(); */
|
|
||||||
/* } */
|
|
||||||
|
|
||||||
return array('link' => $link);
|
|
||||||
}
|
|
||||||
|
|
||||||
function gridDataFields(&$params, &$model) {
|
|
||||||
$fields = parent::gridDataFields($params, $model);
|
|
||||||
|
|
||||||
if (in_array('applied', $params['post']['fields'])) {
|
|
||||||
$fields[] = ("IF(StatementEntry.type = 'CHARGE'," .
|
|
||||||
" SUM(COALESCE(DisbursementEntry.amount,0))," .
|
|
||||||
" SUM(COALESCE(ChargeEntry.amount,0)))" .
|
|
||||||
" AS 'applied'");
|
|
||||||
$fields[] = ("StatementEntry.amount - (" .
|
|
||||||
"IF(StatementEntry.type = 'CHARGE'," .
|
|
||||||
" SUM(COALESCE(DisbursementEntry.amount,0))," .
|
|
||||||
" SUM(COALESCE(ChargeEntry.amount,0)))" .
|
|
||||||
") AS 'balance'");
|
|
||||||
}
|
|
||||||
|
|
||||||
$fields = array_merge($fields,
|
|
||||||
$this->StatementEntry->chargeDisbursementFields());
|
|
||||||
|
|
||||||
return $fields;
|
|
||||||
}
|
|
||||||
|
|
||||||
function gridDataConditions(&$params, &$model) {
|
|
||||||
$conditions = parent::gridDataConditions($params, $model);
|
|
||||||
extract($params['post']['custom']);
|
|
||||||
|
|
||||||
if (!empty($from_date))
|
|
||||||
$conditions[]
|
|
||||||
= array('Transaction.stamp >=' =>
|
|
||||||
$this->StatementEntry->Transaction->dateFormatBeforeSave($from_date));
|
|
||||||
|
|
||||||
if (!empty($through_date))
|
|
||||||
$conditions[]
|
|
||||||
= array('Transaction.stamp <=' =>
|
|
||||||
$this->StatementEntry->Transaction->dateFormatBeforeSave($through_date . ' 23:59:59'));
|
|
||||||
|
|
||||||
if (isset($account_id))
|
|
||||||
$conditions[] = array('StatementEntry.account_id' => $account_id);
|
|
||||||
|
|
||||||
if (isset($statement_entry_id)) {
|
|
||||||
$conditions[] = array('OR' =>
|
|
||||||
array(array('ChargeEntry.id' => $statement_entry_id),
|
|
||||||
array('DisbursementEntry.id' => $statement_entry_id)));
|
|
||||||
}
|
|
||||||
|
|
||||||
return $conditions;
|
|
||||||
}
|
|
||||||
|
|
||||||
function gridDataPostProcessLinks(&$params, &$model, &$records, $links) {
|
|
||||||
$links['StatementEntry'] = array('id');
|
|
||||||
$links['Transaction'] = array('id');
|
|
||||||
$links['Account'] = array('name');
|
|
||||||
$links['Customer'] = array('name');
|
|
||||||
$links['Lease'] = array('number');
|
|
||||||
$links['Unit'] = array('name');
|
|
||||||
return parent::gridDataPostProcessLinks($params, $model, $records, $links);
|
|
||||||
}
|
|
||||||
|
|
||||||
function gridDataOrder(&$params, &$model, $index, $direction) {
|
|
||||||
$order = parent::gridDataOrder($params, $model, $index, $direction);
|
|
||||||
|
|
||||||
// After sorting by whatever the user wants, add these
|
|
||||||
// defaults into the sort mechanism. If we're already
|
|
||||||
// sorting by one of them, it will only be redundant,
|
|
||||||
// and should cause no harm (possible a longer query?)
|
|
||||||
$order[] = 'Transaction.stamp ' . $direction;
|
|
||||||
$order[] = 'StatementEntry.effective_date ' . $direction;
|
|
||||||
$order[] = 'StatementEntry.id ' . $direction;
|
|
||||||
|
|
||||||
return $order;
|
|
||||||
}
|
|
||||||
|
|
||||||
function gridDataRecordsExecute(&$params, &$model, $query) {
|
|
||||||
if (in_array('applied', $params['post']['fields'])) {
|
|
||||||
$tquery = array_diff_key($query, array('fields'=>1,'group'=>1,'limit'=>1,'order'=>1));
|
|
||||||
$tquery['fields'] = array("IF(StatementEntry.type = 'CHARGE'," .
|
|
||||||
" SUM(COALESCE(DisbursementEntry.amount,0))," .
|
|
||||||
" SUM(COALESCE(ChargeEntry.amount,0)))" .
|
|
||||||
" AS 'applied'",
|
|
||||||
|
|
||||||
"StatementEntry.amount - (" .
|
|
||||||
"IF(StatementEntry.type = 'CHARGE'," .
|
|
||||||
" SUM(COALESCE(DisbursementEntry.amount,0))," .
|
|
||||||
" SUM(COALESCE(ChargeEntry.amount,0)))" .
|
|
||||||
") AS 'balance'",
|
|
||||||
);
|
|
||||||
|
|
||||||
//pr(compact('tquery'));
|
|
||||||
$total = $model->find('first', $tquery);
|
|
||||||
$params['userdata']['total'] = $total[0]['applied'];
|
|
||||||
$params['userdata']['balance'] = $total[0]['balance'];
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
$tquery = array_diff_key($query, array('fields'=>1,'group'=>1,'limit'=>1,'order'=>1));
|
|
||||||
$tquery['fields'] = array("SUM(COALESCE(StatementEntry.amount,0)) AS 'total'");
|
|
||||||
$total = $model->find('first', $tquery);
|
|
||||||
$params['userdata']['total'] = $total[0]['total'];
|
|
||||||
}
|
|
||||||
|
|
||||||
return parent::gridDataRecordsExecute($params, $model, $query);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
* action: reverse the ledger entry
|
|
||||||
*/
|
|
||||||
|
|
||||||
function reverse($id) {
|
|
||||||
$this->StatementEntry->reverse($id);
|
|
||||||
$this->redirect(array('action'=>'view', $id));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
* action: waive the ledger entry
|
|
||||||
*/
|
|
||||||
|
|
||||||
function waive($id) {
|
|
||||||
$this->StatementEntry->waive($id);
|
|
||||||
$this->redirect(array('action'=>'view', $id));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
* 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'));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get the StatementEntry and related fields
|
|
||||||
$entry = $this->StatementEntry->find
|
|
||||||
('first',
|
|
||||||
array('contain' => array
|
|
||||||
('Transaction' => array('fields' => array('id', 'type', 'stamp')),
|
|
||||||
'Account' => array('id', 'name', 'type'),
|
|
||||||
'Customer' => array('fields' => array('id', 'name')),
|
|
||||||
'Lease' => array('fields' => array('id')),
|
|
||||||
),
|
|
||||||
|
|
||||||
'conditions' => array('StatementEntry.id' => $id),
|
|
||||||
));
|
|
||||||
|
|
||||||
$reconciled = $this->StatementEntry->reconciledEntries($id);
|
|
||||||
|
|
||||||
$stats = $this->StatementEntry->stats($id);
|
|
||||||
|
|
||||||
if (in_array(strtoupper($entry['StatementEntry']['type']), $this->StatementEntry->debitTypes()))
|
|
||||||
$stats = $stats['Charge'];
|
|
||||||
else
|
|
||||||
$stats = $stats['Disbursement'];
|
|
||||||
|
|
||||||
|
|
||||||
if (strtoupper($entry['StatementEntry']['type']) === 'CHARGE') {
|
|
||||||
|
|
||||||
$reversal = $this->StatementEntry->find
|
|
||||||
('first',
|
|
||||||
array('link' => array('DisbursementEntry'),
|
|
||||||
'conditions' => array(array('StatementEntry.id' => $id),
|
|
||||||
array('DisbursementEntry.type' => 'REVERSAL')),
|
|
||||||
));
|
|
||||||
|
|
||||||
// Set up dynamic menu items
|
|
||||||
if (empty($reversal) || $stats['balance'] > 0)
|
|
||||||
$this->sidemenu_links[] =
|
|
||||||
array('name' => 'Operations', 'header' => true);
|
|
||||||
|
|
||||||
if (empty($reversal))
|
|
||||||
$this->sidemenu_links[] =
|
|
||||||
array('name' => 'Reverse',
|
|
||||||
'url' => array('action' => 'reverse',
|
|
||||||
$id));
|
|
||||||
|
|
||||||
if ($stats['balance'] > 0)
|
|
||||||
$this->sidemenu_links[] =
|
|
||||||
array('name' => 'Waive Balance',
|
|
||||||
'url' => array('action' => 'waive',
|
|
||||||
$id));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Prepare to render.
|
|
||||||
$title = "Statement Entry #{$entry['StatementEntry']['id']}";
|
|
||||||
$this->set(compact('entry', 'title', 'reconciled', 'stats'));
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,167 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
class TendersController extends AppController {
|
|
||||||
|
|
||||||
var $sidemenu_links = array();
|
|
||||||
|
|
||||||
|
|
||||||
/**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
* override: sideMenuLinks
|
|
||||||
* - Generates controller specific links for the side menu
|
|
||||||
*/
|
|
||||||
function sideMenuLinks() {
|
|
||||||
return array_merge(parent::sideMenuLinks(), $this->sidemenu_links);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
* action: index / all
|
|
||||||
* - Generate a listing of Tenders
|
|
||||||
*/
|
|
||||||
|
|
||||||
function index() { $this->all(); }
|
|
||||||
function all() { $this->gridView('All Legal Tender', 'all'); }
|
|
||||||
|
|
||||||
|
|
||||||
/**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
* virtuals: gridData
|
|
||||||
* - With the application controller handling the gridData action,
|
|
||||||
* these virtual functions ensure that the correct data is passed
|
|
||||||
* to jqGrid.
|
|
||||||
*/
|
|
||||||
|
|
||||||
function gridDataTables(&$params, &$model) {
|
|
||||||
return array
|
|
||||||
('link' =>
|
|
||||||
array('TenderType',
|
|
||||||
'Customer',
|
|
||||||
'LedgerEntry' =>
|
|
||||||
array('Transaction',
|
|
||||||
),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
function gridDataRecordsExecute(&$params, &$model, $query) {
|
|
||||||
$tquery = array_diff_key($query, array('fields'=>1,'group'=>1,'limit'=>1,'order'=>1));
|
|
||||||
$tquery['fields'] = array("SUM(COALESCE(LedgerEntry.amount,0)) AS 'total'");
|
|
||||||
$total = $model->find('first', $tquery);
|
|
||||||
$params['userdata']['total'] = $total[0]['total'];
|
|
||||||
|
|
||||||
return parent::gridDataRecordsExecute($params, $model, $query);
|
|
||||||
}
|
|
||||||
|
|
||||||
function gridDataPostProcessCalculatedFields(&$params, &$model, &$records) {
|
|
||||||
parent::gridDataPostProcessCalculatedFields($params, $model, $records);
|
|
||||||
foreach ($records AS &$record) {
|
|
||||||
// REVISIT <AP>: 20090730
|
|
||||||
// We really need the grid to handle this. We probably need to
|
|
||||||
// either create a hidden column with the nsf id, or pass back
|
|
||||||
// a list of nsf items as user data. We can then add an onload
|
|
||||||
// function to sweep through the nsf items and format them.
|
|
||||||
// For now... this works.
|
|
||||||
if (!empty($record['Tender']['nsf_transaction_id']))
|
|
||||||
$record['Tender']['name'] =
|
|
||||||
'<SPAN class="nsf-tender">' . $record['Tender']['name'] . '</SPAN>';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function gridDataPostProcessLinks(&$params, &$model, &$records, $links) {
|
|
||||||
$links['Tender'] = array('name', 'id');
|
|
||||||
$links['Customer'] = array('name');
|
|
||||||
$links['TenderType'] = array('name');
|
|
||||||
return parent::gridDataPostProcessLinks($params, $model, $records, $links);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
* action: deposit
|
|
||||||
* - Prepares the books for a bank deposit
|
|
||||||
*/
|
|
||||||
|
|
||||||
function deposit() {
|
|
||||||
// Prepare a close page...
|
|
||||||
$deposit_types = $this->Tender->TenderType->depositTypes(
|
|
||||||
// Testing... limit to only one type
|
|
||||||
//array('limit' => 1)
|
|
||||||
);
|
|
||||||
$deposit_accounts = $this->Tender->TenderType->Account->depositAccounts();
|
|
||||||
|
|
||||||
foreach ($deposit_types AS $type_id => &$type)
|
|
||||||
$type = array('id' => $type_id,
|
|
||||||
'name' => $type,
|
|
||||||
'stats' => $this->Tender->TenderType->stats($type_id));
|
|
||||||
|
|
||||||
//pr(compact('deposit_types', 'deposit_accounts'));
|
|
||||||
|
|
||||||
$title = 'Prepare Deposit';
|
|
||||||
$this->set(compact('title', 'deposit_types', 'deposit_accounts'));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
* action: nsf
|
|
||||||
* - Marks a tender as having insufficient funds.
|
|
||||||
*/
|
|
||||||
|
|
||||||
function nsf($id = null) {
|
|
||||||
if (!$id) {
|
|
||||||
$this->Session->setFlash(__('Invalid Item.', true));
|
|
||||||
$this->redirect(array('action'=>'index'));
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->Tender->nsf($id);
|
|
||||||
$this->redirect(array('action'=>'view', $id));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
* 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'));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get the Tender and related fields
|
|
||||||
$tender = $this->Tender->find
|
|
||||||
('first', array
|
|
||||||
('contain' => array('TenderType', 'Customer', 'LedgerEntry' => array('Transaction')),
|
|
||||||
));
|
|
||||||
|
|
||||||
|
|
||||||
if (!empty($tender['Tender']['deposit_transaction_id'])
|
|
||||||
&& empty($tender['Tender']['nsf_transaction_id'])
|
|
||||||
// Hard to tell what types of items can come back as NSF.
|
|
||||||
// For now, assume iff it is a named item, it can be NSF.
|
|
||||||
&& !empty($tender['TenderType']['data1_name'])
|
|
||||||
) {
|
|
||||||
// Set up dynamic menu items
|
|
||||||
$this->sidemenu_links[] =
|
|
||||||
array('name' => 'Operations', 'header' => true);
|
|
||||||
|
|
||||||
$this->sidemenu_links[] =
|
|
||||||
array('name' => 'NSF',
|
|
||||||
'url' => array('action' => 'nsf',
|
|
||||||
$id));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Prepare to render.
|
|
||||||
$title = "Tender #{$tender['Tender']['id']}";
|
|
||||||
$this->set(compact('tender', 'title'));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,463 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
class TransactionsController extends AppController {
|
|
||||||
|
|
||||||
var $components = array('RequestHandler');
|
|
||||||
|
|
||||||
var $sidemenu_links =
|
|
||||||
array(array('name' => 'Transactions', 'header' => true),
|
|
||||||
array('name' => 'All', 'url' => array('controller' => 'transactions', 'action' => 'all')),
|
|
||||||
array('name' => 'Invoices', 'url' => array('controller' => 'transactions', 'action' => 'invoice')),
|
|
||||||
array('name' => 'Receipts', 'url' => array('controller' => 'transactions', 'action' => 'receipt')),
|
|
||||||
array('name' => 'Deposits', 'url' => array('controller' => 'transactions', 'action' => 'deposit')),
|
|
||||||
);
|
|
||||||
|
|
||||||
|
|
||||||
/**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
* override: sideMenuLinks
|
|
||||||
* - Generates controller specific links for the side menu
|
|
||||||
*/
|
|
||||||
function sideMenuLinks() {
|
|
||||||
return array_merge(parent::sideMenuLinks(), $this->sidemenu_links);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
* action: index / all
|
|
||||||
* - Generate a listing of transactions
|
|
||||||
*/
|
|
||||||
|
|
||||||
function index() { $this->all(); }
|
|
||||||
function all() { $this->gridView('All Transactions', 'all'); }
|
|
||||||
function invoice() { $this->gridView('Invoices'); }
|
|
||||||
function receipt() { $this->gridView('Receipts'); }
|
|
||||||
function deposit() { $this->gridView('Deposits'); }
|
|
||||||
|
|
||||||
|
|
||||||
/**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
* virtuals: gridData
|
|
||||||
* - With the application controller handling the gridData action,
|
|
||||||
* these virtual functions ensure that the correct data is passed
|
|
||||||
* to jqGrid.
|
|
||||||
*/
|
|
||||||
|
|
||||||
function gridDataCountTables(&$params, &$model) {
|
|
||||||
return parent::gridDataTables($params, $model);
|
|
||||||
}
|
|
||||||
|
|
||||||
function gridDataTables(&$params, &$model) {
|
|
||||||
$link = $this->gridDataCountTables($params, $model);
|
|
||||||
$link['link']['StatementEntry'] = array('fields' => array());
|
|
||||||
$link['link']['DepositTender'] = array('fields' => array());
|
|
||||||
return $link;
|
|
||||||
}
|
|
||||||
|
|
||||||
function gridDataFields(&$params, &$model) {
|
|
||||||
$fields = parent::gridDataFields($params, $model);
|
|
||||||
//$fields[] = 'COUNT(StatementEntry.id) AS entries';
|
|
||||||
$fields[] = ("IF(Transaction.type = 'DEPOSIT'," .
|
|
||||||
" COUNT(DepositTender.id)," .
|
|
||||||
" COUNT(StatementEntry.id)) AS entries");
|
|
||||||
return $fields;
|
|
||||||
}
|
|
||||||
|
|
||||||
function gridDataConditions(&$params, &$model) {
|
|
||||||
$conditions = parent::gridDataConditions($params, $model);
|
|
||||||
|
|
||||||
if (in_array($params['action'], array('invoice', 'receipt', 'deposit')))
|
|
||||||
$conditions[] = array('Transaction.type' => strtoupper($params['action']));
|
|
||||||
|
|
||||||
return $conditions;
|
|
||||||
}
|
|
||||||
|
|
||||||
function gridDataPostProcessLinks(&$params, &$model, &$records, $links) {
|
|
||||||
$links['Transaction'] = array('id');
|
|
||||||
return parent::gridDataPostProcessLinks($params, $model, $records, $links);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
* action: postInvoice
|
|
||||||
* - handles the creation of a charge invoice
|
|
||||||
*/
|
|
||||||
|
|
||||||
function postInvoice() {
|
|
||||||
if (!$this->RequestHandler->isPost()) {
|
|
||||||
echo('<H2>THIS IS NOT A POST FOR SOME REASON</H2>');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!$this->Transaction->addInvoice($this->data, null,
|
|
||||||
$this->data['Lease']['id'])) {
|
|
||||||
$this->Session->setFlash("INVOICE FAILED", true);
|
|
||||||
// REVISIT <AP> 20090706:
|
|
||||||
// Until we can work out the session problems,
|
|
||||||
// just die.
|
|
||||||
die("<H1>INVOICE FAILED</H1>");
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->layout = null;
|
|
||||||
$this->autoLayout = false;
|
|
||||||
$this->autoRender = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
* action: postReceipt
|
|
||||||
* - handles the creation of a receipt
|
|
||||||
*/
|
|
||||||
|
|
||||||
function postReceipt() {
|
|
||||||
if (!$this->RequestHandler->isPost()) {
|
|
||||||
echo('<H2>THIS IS NOT A POST FOR SOME REASON</H2>');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach($this->data['Entry'] AS &$entry) {
|
|
||||||
$entry['Tender'] = $entry['type'][$entry['tender_type_id']];
|
|
||||||
unset($entry['type']);
|
|
||||||
unset($entry['tender_type_id']);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!$this->Transaction->addReceipt($this->data,
|
|
||||||
$this->data['Customer']['id'],
|
|
||||||
(isset($this->data['Lease']['id'])
|
|
||||||
? $this->data['Lease']['id']
|
|
||||||
: null ))) {
|
|
||||||
$this->Session->setFlash("RECEIPT FAILED", true);
|
|
||||||
// REVISIT <AP> 20090706:
|
|
||||||
// Until we can work out the session problems,
|
|
||||||
// just die.
|
|
||||||
die("<H1>RECEIPT FAILED</H1>");
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->layout = null;
|
|
||||||
$this->autoLayout = false;
|
|
||||||
$this->autoRender = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
* action: postDeposit
|
|
||||||
* - handles the creation of a deposit transaction
|
|
||||||
*/
|
|
||||||
|
|
||||||
function postDeposit() {
|
|
||||||
if (!$this->RequestHandler->isPost()) {
|
|
||||||
echo('<H2>THIS IS NOT A POST FOR SOME REASON</H2>');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
//pr($this->data);
|
|
||||||
|
|
||||||
// Go through each type of tender presented to the user
|
|
||||||
// Determine which are to be deposited, and which are to
|
|
||||||
// have their corresponding account ledgers closed.
|
|
||||||
$deposit_tender_ids = array();
|
|
||||||
$deposit_type_ids = array();
|
|
||||||
$close_type_ids = array();
|
|
||||||
foreach ($this->data['TenderType'] AS $type_id => $type) {
|
|
||||||
$type['items'] = unserialize($type['items']);
|
|
||||||
if (empty($type['selection']) ||
|
|
||||||
$type['selection'] === 'none' ||
|
|
||||||
($type['selection'] === 'subset' && count($type['items']) == 0))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
// The deposit includes either the whole type, or just certain tenders
|
|
||||||
if ($type['selection'] === 'all')
|
|
||||||
$deposit_type_ids[] = $type_id;
|
|
||||||
else
|
|
||||||
$deposit_tender_ids = array_merge($deposit_tender_ids, $type['items']);
|
|
||||||
|
|
||||||
// Should we close the ledger for this tender type?
|
|
||||||
// First, the user would have to request that we do so,
|
|
||||||
// but additionally, we shouldn't close a ledger unless
|
|
||||||
// all the tenders are included in this deposit. That
|
|
||||||
// doesn't guarantee that the ledger has a zero balance,
|
|
||||||
// but it does carry the balance forward, and a total
|
|
||||||
// deposit would imply a fresh start, so go for it.
|
|
||||||
if (!empty($type['close']) && $type['selection'] === 'all')
|
|
||||||
$close_type_ids[] = $type_id;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Make sure we actually have something to deposit
|
|
||||||
if (empty($deposit_type_ids) && empty($deposit_tender_ids)) {
|
|
||||||
$this->Session->setFlash(__('Nothing to Deposit', true));
|
|
||||||
$this->redirect(array('controller' => 'tenders', 'action'=>'deposit'));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Build up a set of conditions based on user selection
|
|
||||||
$deposit_conditions = array();
|
|
||||||
if (!empty($deposit_type_ids))
|
|
||||||
$deposit_conditions[] = array('TenderType.id' => $deposit_type_ids);
|
|
||||||
if (!empty($deposit_tender_ids))
|
|
||||||
$deposit_conditions[] = array('DepositTender.id' => $deposit_tender_ids);
|
|
||||||
|
|
||||||
// Add in confirmation that items have not already been deposited
|
|
||||||
$deposit_conditions =
|
|
||||||
array(array('DepositTender.deposit_transaction_id' => null),
|
|
||||||
array('OR' => $deposit_conditions));
|
|
||||||
|
|
||||||
// Lookup the items to be deposited
|
|
||||||
$tenders = $this->Transaction->DepositTender->find
|
|
||||||
('all',
|
|
||||||
array('contain' => array('TenderType', 'LedgerEntry'),
|
|
||||||
'conditions' => $deposit_conditions,
|
|
||||||
));
|
|
||||||
|
|
||||||
// Build the deposit transaction
|
|
||||||
$deposit = array('Transaction' => array(), 'Entry' => array());
|
|
||||||
foreach ($tenders AS $tender) {
|
|
||||||
$deposit['Entry'][] =
|
|
||||||
array('tender_id' => $tender['DepositTender']['id'],
|
|
||||||
'account_id' => $tender['LedgerEntry']['account_id'],
|
|
||||||
'amount' => $tender['LedgerEntry']['amount'],
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
//pr(compact('deposit_type_ids', 'deposit_tender_ids', 'close_type_ids', 'deposit_conditions', 'deposit'));
|
|
||||||
|
|
||||||
// OK, perform the deposit and associated accounting
|
|
||||||
$result = $this->Transaction->addDeposit
|
|
||||||
($deposit, $this->data['Deposit']['Account']['id']);
|
|
||||||
//pr(compact('deposit', 'result'));
|
|
||||||
|
|
||||||
// Close any ledgers necessary
|
|
||||||
if (!empty($close_type_ids)) {
|
|
||||||
// Find the accounts associated with the types to close ...
|
|
||||||
$accounts = $this->Transaction->DepositTender->find
|
|
||||||
('all',
|
|
||||||
array('contain' => array('TenderType.account_id'),
|
|
||||||
'conditions' => array(array('TenderType.id' => $close_type_ids)),
|
|
||||||
));
|
|
||||||
|
|
||||||
// ... and close them
|
|
||||||
$this->Transaction->Account->closeCurrentLedgers
|
|
||||||
(array_map(create_function('$item', 'return $item["TenderType"]["account_id"];'), $accounts));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Look out for errors
|
|
||||||
if ($result['error']) {
|
|
||||||
$this->Session->setFlash(__('Unable to Create Deposit', true));
|
|
||||||
$this->redirect(array('controller' => 'tenders', 'action'=>'deposit'));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Present the deposit slip to the user
|
|
||||||
$this->redirect(array('controller' => 'transactions',
|
|
||||||
'action' => 'deposit_slip',
|
|
||||||
$result['transaction_id']));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
* action: postWriteOff
|
|
||||||
* - handles the write off of bad debt
|
|
||||||
*/
|
|
||||||
|
|
||||||
function postWriteOff() {
|
|
||||||
if (!$this->RequestHandler->isPost()) {
|
|
||||||
echo('<H2>THIS IS NOT A POST FOR SOME REASON</H2>');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
$data = $this->data;
|
|
||||||
$data['Entry'][0]['account_id'] =
|
|
||||||
$this->Transaction->Account->badDebtAccountID();
|
|
||||||
|
|
||||||
if (empty($data['Customer']['id']))
|
|
||||||
$data['Customer']['id'] = null;
|
|
||||||
if (empty($data['Lease']['id']))
|
|
||||||
$data['Lease']['id'] = null;
|
|
||||||
|
|
||||||
pr(compact('data'));
|
|
||||||
|
|
||||||
if (!$this->Transaction->addReceipt($data,
|
|
||||||
$data['Customer']['id'],
|
|
||||||
$data['Lease']['id'])) {
|
|
||||||
$this->Session->setFlash("WRITE OFF FAILED", true);
|
|
||||||
// REVISIT <AP> 20090706:
|
|
||||||
// Until we can work out the session problems,
|
|
||||||
// just die.
|
|
||||||
die("<H1>WRITE-OFF FAILED</H1>");
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->render('/fake');
|
|
||||||
|
|
||||||
// Return to viewing the lease/customer
|
|
||||||
if (empty($data['Lease']['id']))
|
|
||||||
$this->redirect(array('controller' => 'customers',
|
|
||||||
'action' => 'view',
|
|
||||||
$data['Customer']['id']));
|
|
||||||
else
|
|
||||||
$this->redirect(array('controller' => 'leases',
|
|
||||||
'action' => 'view',
|
|
||||||
$data['Lease']['id']));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
* action: postRefund
|
|
||||||
* - handles issuing a customer refund
|
|
||||||
*/
|
|
||||||
|
|
||||||
function postRefund() {
|
|
||||||
if (!$this->RequestHandler->isPost()) {
|
|
||||||
echo('<H2>THIS IS NOT A POST FOR SOME REASON</H2>');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
$data = $this->data;
|
|
||||||
if (empty($data['Customer']['id']))
|
|
||||||
$data['Customer']['id'] = null;
|
|
||||||
if (empty($data['Lease']['id']))
|
|
||||||
$data['Lease']['id'] = null;
|
|
||||||
|
|
||||||
if (!$this->Transaction->addRefund($data,
|
|
||||||
$data['Customer']['id'],
|
|
||||||
$data['Lease']['id'])) {
|
|
||||||
$this->Session->setFlash("REFUND FAILED", true);
|
|
||||||
// REVISIT <AP> 20090706:
|
|
||||||
// Until we can work out the session problems,
|
|
||||||
// just die.
|
|
||||||
die("<H1>REFUND FAILED</H1>");
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->render('/fake');
|
|
||||||
|
|
||||||
// Return to viewing the lease/customer
|
|
||||||
if (empty($data['Lease']['id']))
|
|
||||||
$this->redirect(array('controller' => 'customers',
|
|
||||||
'action' => 'view',
|
|
||||||
$data['Customer']['id']));
|
|
||||||
else
|
|
||||||
$this->redirect(array('controller' => 'leases',
|
|
||||||
'action' => 'view',
|
|
||||||
$data['Lease']['id']));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
* action: view
|
|
||||||
* - Displays information about a specific transaction
|
|
||||||
*/
|
|
||||||
|
|
||||||
function view($id = null) {
|
|
||||||
if (!$id) {
|
|
||||||
$this->Session->setFlash(__('Invalid Item.', true));
|
|
||||||
$this->redirect(array('action'=>'index'));
|
|
||||||
}
|
|
||||||
|
|
||||||
$transaction = $this->Transaction->find
|
|
||||||
('first',
|
|
||||||
array('contain' =>
|
|
||||||
array(// Models
|
|
||||||
'Account' =>
|
|
||||||
array('fields' => array('Account.id',
|
|
||||||
'Account.name'),
|
|
||||||
),
|
|
||||||
|
|
||||||
'Ledger' =>
|
|
||||||
array('fields' => array('Ledger.id',
|
|
||||||
'Ledger.name'),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
'conditions' => array('Transaction.id' => $id),
|
|
||||||
));
|
|
||||||
|
|
||||||
if ($transaction['Transaction']['type'] === 'DEPOSIT') {
|
|
||||||
$this->sidemenu_links[] =
|
|
||||||
array('name' => 'Operations', 'header' => true);
|
|
||||||
$this->sidemenu_links[] =
|
|
||||||
array('name' => 'View Slip', 'url' => array('action' => 'deposit_slip', $id));
|
|
||||||
}
|
|
||||||
|
|
||||||
// OK, prepare to render.
|
|
||||||
$title = 'Transaction #' . $transaction['Transaction']['id'];
|
|
||||||
$this->set(compact('transaction', 'title'));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
* action: deposit_slip
|
|
||||||
* - Special presentation
|
|
||||||
* Processes the user input and updates the database
|
|
||||||
*/
|
|
||||||
|
|
||||||
function deposit_slip($id) {
|
|
||||||
// Build a container for the deposit slip data
|
|
||||||
$deposit = array('types' => array());
|
|
||||||
|
|
||||||
$this->id = $id;
|
|
||||||
$deposit +=
|
|
||||||
$this->Transaction->find('first', array('contain' => false));
|
|
||||||
|
|
||||||
// Get a summary of all forms of tender in the deposit
|
|
||||||
$result = $this->Transaction->find
|
|
||||||
('all',
|
|
||||||
array('link' => array('DepositTender' =>
|
|
||||||
array('fields' => array(),
|
|
||||||
'TenderType',
|
|
||||||
'LedgerEntry' =>
|
|
||||||
array('fields' => array()))),
|
|
||||||
'fields' => array(//'TenderType.id', 'TenderType.name',
|
|
||||||
"COUNT(DepositTender.id) AS 'count'",
|
|
||||||
"SUM(LedgerEntry.amount) AS 'total'"),
|
|
||||||
//'conditions' => array(array('DepositTender.deposit_transaction_id' => $id)),
|
|
||||||
'conditions' => array(array('Transaction.id' => $id)),
|
|
||||||
'group' => 'TenderType.id',
|
|
||||||
));
|
|
||||||
|
|
||||||
if (empty($result)) {
|
|
||||||
die();
|
|
||||||
$this->Session->setFlash(__('Invalid Deposit.', true));
|
|
||||||
$this->redirect(array('action'=>'deposit'));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add the summary to our deposit slip data container
|
|
||||||
foreach ($result AS $type) {
|
|
||||||
$deposit['types'][$type['TenderType']['id']] =
|
|
||||||
$type['TenderType'] + $type[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
// For each form of tender in the deposit, get the deposit items
|
|
||||||
/* foreach ($deposit['types'] AS $type_id => &$type) { */
|
|
||||||
/* $type['entries'] = $this->Transaction->DepositTender->find */
|
|
||||||
/* ('all', */
|
|
||||||
/* array('contain' => array('Customer', 'LedgerEntry'), */
|
|
||||||
/* 'conditions' => array(array('DepositTender.deposit_transaction_id' => $id), */
|
|
||||||
/* array('DepositTender.tender_type_id' => $type_id)), */
|
|
||||||
/* )); */
|
|
||||||
/* } */
|
|
||||||
|
|
||||||
$this->sidemenu_links[] =
|
|
||||||
array('name' => 'Operations', 'header' => true);
|
|
||||||
$this->sidemenu_links[] =
|
|
||||||
array('name' => 'View Transaction', 'url' => array('action' => 'view', $id));
|
|
||||||
|
|
||||||
$title = 'Deposit Slip';
|
|
||||||
$this->set(compact('title', 'deposit'));
|
|
||||||
$this->render('deposit_slip');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,339 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
class UnitsController extends AppController {
|
|
||||||
|
|
||||||
var $sidemenu_links =
|
|
||||||
array(array('name' => 'Units', 'header' => true),
|
|
||||||
array('name' => 'Occupied', 'url' => array('controller' => 'units', 'action' => 'occupied')),
|
|
||||||
array('name' => 'Vacant', 'url' => array('controller' => 'units', 'action' => 'vacant')),
|
|
||||||
array('name' => 'Unavailable', 'url' => array('controller' => 'units', 'action' => 'unavailable')),
|
|
||||||
array('name' => 'All', 'url' => array('controller' => 'units', 'action' => 'all')),
|
|
||||||
);
|
|
||||||
|
|
||||||
|
|
||||||
/**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
* override: sideMenuLinks
|
|
||||||
* - Generates controller specific links for the side menu
|
|
||||||
*/
|
|
||||||
function sideMenuLinks() {
|
|
||||||
return array_merge(parent::sideMenuLinks(), $this->sidemenu_links);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
* action: index / unavailable / vacant / occupied / all
|
|
||||||
* - Generate a listing of units
|
|
||||||
*/
|
|
||||||
|
|
||||||
function index() { $this->all(); }
|
|
||||||
function unavailable() { $this->gridView('Unavailable Units'); }
|
|
||||||
function vacant() { $this->gridView('Vacant Units'); }
|
|
||||||
function occupied() { $this->gridView('Occupied Units'); }
|
|
||||||
function all() { $this->gridView('All Units', 'all'); }
|
|
||||||
|
|
||||||
|
|
||||||
/**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
* virtuals: gridData
|
|
||||||
* - With the application controller handling the gridData action,
|
|
||||||
* these virtual functions ensure that the correct data is passed
|
|
||||||
* to jqGrid.
|
|
||||||
*/
|
|
||||||
|
|
||||||
function gridDataSetup(&$params) {
|
|
||||||
parent::gridDataSetup($params);
|
|
||||||
if (!isset($params['action']))
|
|
||||||
$params['action'] = 'all';
|
|
||||||
}
|
|
||||||
|
|
||||||
function gridDataCountTables(&$params, &$model) {
|
|
||||||
return array
|
|
||||||
('link' => array('UnitSize' => array('fields' => array('id', 'name')),
|
|
||||||
'CurrentLease' => array('fields' => array('id'))));
|
|
||||||
|
|
||||||
/* if ($params['action'] === 'occupied') */
|
|
||||||
/* $link['Lease'] = array('fields' => array(), */
|
|
||||||
/* // Models */
|
|
||||||
/* 'Contact' => array('fields' => array('display_name'), */
|
|
||||||
/* //'type' => 'LEFT', */
|
|
||||||
/* ), */
|
|
||||||
/* ); */
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
function gridDataTables(&$params, &$model) {
|
|
||||||
$link = $this->gridDataCountTables($params, $model);
|
|
||||||
$link['link']['CurrentLease']['StatementEntry'] = array('fields' => array());
|
|
||||||
return $link;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* function gridDataTables(&$params, &$model) { */
|
|
||||||
/* return array */
|
|
||||||
/* ('link' => array('Unit' => array('fields' => array('Unit.id', 'Unit.name')), */
|
|
||||||
/* 'Customer' => array('fields' => array('Customer.id', 'Customer.name')))); */
|
|
||||||
/* } */
|
|
||||||
|
|
||||||
function gridDataFields(&$params, &$model) {
|
|
||||||
$fields = parent::gridDataFields($params, $model);
|
|
||||||
|
|
||||||
return array_merge($fields,
|
|
||||||
$this->Unit->Lease->StatementEntry->chargeDisbursementFields(true));
|
|
||||||
}
|
|
||||||
|
|
||||||
function gridDataConditions(&$params, &$model) {
|
|
||||||
$conditions = parent::gridDataConditions($params, $model);
|
|
||||||
|
|
||||||
if ($params['action'] === 'unavailable') {
|
|
||||||
$conditions[] = $this->Unit->conditionUnavailable();
|
|
||||||
}
|
|
||||||
elseif ($params['action'] === 'vacant') {
|
|
||||||
$conditions[] = $this->Unit->conditionVacant();
|
|
||||||
}
|
|
||||||
elseif ($params['action'] === 'occupied') {
|
|
||||||
$conditions[] = $this->Unit->conditionOccupied();
|
|
||||||
}
|
|
||||||
elseif ($params['action'] === 'unoccupied') {
|
|
||||||
$conditions[] = array('NOT' => array($this->Unit->conditionOccupied()));
|
|
||||||
}
|
|
||||||
|
|
||||||
return $conditions;
|
|
||||||
}
|
|
||||||
|
|
||||||
function gridDataOrder(&$params, &$model, $index, $direction) {
|
|
||||||
// Instead of sorting by name, sort by defined order
|
|
||||||
if ($index === 'Unit.name')
|
|
||||||
$index = 'Unit.sort_order';
|
|
||||||
|
|
||||||
$order = array();
|
|
||||||
$order[] = parent::gridDataOrder($params, $model, $index, $direction);
|
|
||||||
|
|
||||||
// If sorting by anything other than name (defined order)
|
|
||||||
// add the sort-order as a secondary condition
|
|
||||||
if ($index !== 'Unit.name')
|
|
||||||
$order[] = parent::gridDataOrder($params, $model,
|
|
||||||
'Unit.sort_order', $direction);
|
|
||||||
|
|
||||||
return $order;
|
|
||||||
}
|
|
||||||
|
|
||||||
function gridDataPostProcessLinks(&$params, &$model, &$records, $links) {
|
|
||||||
$links['Unit'] = array('name');
|
|
||||||
$links['UnitSize'] = array('name');
|
|
||||||
return parent::gridDataPostProcessLinks($params, $model, $records, $links);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
* action: move_in
|
|
||||||
* - Sets up the move-in page for the given unit.
|
|
||||||
*/
|
|
||||||
|
|
||||||
function move_in($id = null) {
|
|
||||||
$customer = array();
|
|
||||||
$unit = array();
|
|
||||||
|
|
||||||
if (isset($id)) {
|
|
||||||
$this->Unit->recursive = -1;
|
|
||||||
$unit = current($this->Unit->read(null, $id));
|
|
||||||
}
|
|
||||||
|
|
||||||
$title = 'Unit Move-In';
|
|
||||||
$this->set(compact('customer', 'unit', 'title'));
|
|
||||||
$this->render('/leases/move');
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
* action: move_out
|
|
||||||
* - prepare or execute a move out on a specific lease
|
|
||||||
*/
|
|
||||||
|
|
||||||
function move_out($id) {
|
|
||||||
|
|
||||||
$unit = $this->Unit->find
|
|
||||||
('first', array
|
|
||||||
('contain' => array
|
|
||||||
(// Models
|
|
||||||
'CurrentLease' =>
|
|
||||||
array(//'conditions' => array('Lease.moveout_date' => null),
|
|
||||||
// Models
|
|
||||||
'Customer' =>
|
|
||||||
array('fields' => array('id', 'name'),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
'conditions' => array('Unit.id' => $id),
|
|
||||||
));
|
|
||||||
$this->set('customer', $unit['CurrentLease']['Customer']);
|
|
||||||
$this->set('unit', $unit['Unit']);
|
|
||||||
$this->set('lease', $unit['CurrentLease']);
|
|
||||||
|
|
||||||
$redirect = array('controller' => 'units',
|
|
||||||
'action' => 'view',
|
|
||||||
$id);
|
|
||||||
|
|
||||||
$title = ('Lease #' . $unit['CurrentLease']['number'] . ': ' .
|
|
||||||
$unit['Unit']['name'] . ': ' .
|
|
||||||
$unit['CurrentLease']['Customer']['name'] . ': Prepare Move-Out');
|
|
||||||
$this->set(compact('title', 'redirect'));
|
|
||||||
$this->render('/leases/move');
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
* action: view
|
|
||||||
* - Displays information about a specific unit
|
|
||||||
*/
|
|
||||||
|
|
||||||
function view($id = null) {
|
|
||||||
if (!$id) {
|
|
||||||
$this->Session->setFlash(__('Invalid Item.', true));
|
|
||||||
$this->redirect(array('action'=>''));
|
|
||||||
}
|
|
||||||
|
|
||||||
$unit = $this->Unit->find
|
|
||||||
('first',
|
|
||||||
array('contain' =>
|
|
||||||
array(// Models
|
|
||||||
'UnitSize',
|
|
||||||
'Lease' => array('Customer'),
|
|
||||||
'CurrentLease' => array('Customer')
|
|
||||||
),
|
|
||||||
'conditions' => array('Unit.id' => $id),
|
|
||||||
));
|
|
||||||
|
|
||||||
// Get the balance on each lease.
|
|
||||||
foreach ($unit['Lease'] AS &$lease) {
|
|
||||||
$stats = $this->Unit->Lease->stats($lease['id']);
|
|
||||||
$lease['balance'] = $stats['balance'];
|
|
||||||
}
|
|
||||||
|
|
||||||
$outstanding_balance = 0;
|
|
||||||
$outstanding_deposit = 0;
|
|
||||||
if (isset($unit['CurrentLease']['id'])) {
|
|
||||||
// Figure out the outstanding balance of the current lease.
|
|
||||||
$stats = $this->Unit->stats($id);
|
|
||||||
$outstanding_balance =
|
|
||||||
$stats['CurrentLease']['balance'];
|
|
||||||
|
|
||||||
// Figure out the total security deposit for the current lease.
|
|
||||||
$deposits = $this->Unit->Lease->securityDeposits($unit['CurrentLease']['id']);
|
|
||||||
$outstanding_deposit = $this->Unit->Lease->securityDepositBalance($unit['CurrentLease']['id']);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set up dynamic menu items
|
|
||||||
$this->sidemenu_links[] =
|
|
||||||
array('name' => 'Operations', 'header' => true);
|
|
||||||
|
|
||||||
$this->sidemenu_links[] =
|
|
||||||
array('name' => 'Edit', 'url' => array('action' => 'edit',
|
|
||||||
$id));
|
|
||||||
|
|
||||||
if (isset($unit['CurrentLease']['id']) &&
|
|
||||||
!isset($unit['CurrentLease']['moveout_date'])) {
|
|
||||||
$this->sidemenu_links[] =
|
|
||||||
array('name' => 'Move-Out', 'url' => array('action' => 'move_out',
|
|
||||||
$id));
|
|
||||||
} else {
|
|
||||||
$this->sidemenu_links[] =
|
|
||||||
array('name' => 'Move-In', 'url' => array('action' => 'move_in',
|
|
||||||
$id));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isset($unit['CurrentLease']['id']) &&
|
|
||||||
!isset($unit['CurrentLease']['close_date'])) {
|
|
||||||
$this->sidemenu_links[] =
|
|
||||||
array('name' => 'Charge', 'url' => array('controller' => 'leases',
|
|
||||||
'action' => 'invoice',
|
|
||||||
$unit['CurrentLease']['id']));
|
|
||||||
$this->sidemenu_links[] =
|
|
||||||
array('name' => 'Payment', 'url' => array('controller' => 'customers',
|
|
||||||
'action' => 'receipt',
|
|
||||||
$unit['CurrentLease']['customer_id']));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Prepare to render.
|
|
||||||
$title = 'Unit ' . $unit['Unit']['name'];
|
|
||||||
$this->set(compact('unit', 'title',
|
|
||||||
'outstanding_balance',
|
|
||||||
'outstanding_deposit'));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
* action: edit
|
|
||||||
* - Edit unit information
|
|
||||||
*/
|
|
||||||
|
|
||||||
function edit($id = null) {
|
|
||||||
if (isset($this->data)) {
|
|
||||||
// Check to see if the operation was cancelled.
|
|
||||||
if (isset($this->params['form']['cancel'])) {
|
|
||||||
if (empty($this->data['Unit']['id']))
|
|
||||||
$this->redirect(array('action'=>'index'));
|
|
||||||
|
|
||||||
$this->redirect(array('action'=>'view', $this->data['Unit']['id']));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Make sure we have unit data
|
|
||||||
if (empty($this->data['Unit']))
|
|
||||||
$this->redirect(array('action'=>'index'));
|
|
||||||
|
|
||||||
// Make sure we have a rental rate
|
|
||||||
if (empty($this->data['Unit']['rent']))
|
|
||||||
$this->redirect(array('action'=>'view', $this->data['Unit']['id']));
|
|
||||||
|
|
||||||
// Save the unit and all associated data
|
|
||||||
$this->Unit->create();
|
|
||||||
$this->Unit->id = $this->data['Unit']['id'];
|
|
||||||
if (!$this->Unit->save($this->data, false)) {
|
|
||||||
$this->Session->setFlash("UNIT SAVE FAILED", true);
|
|
||||||
pr("UNIT SAVE FAILED");
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->redirect(array('action'=>'view', $this->Unit->id));
|
|
||||||
|
|
||||||
// For debugging, only if the redirects above have been
|
|
||||||
// commented out, otherwise this section isn't reached.
|
|
||||||
$this->render('/fake');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($id) {
|
|
||||||
$this->data = $this->Unit->findById($id);
|
|
||||||
$title = 'Unit ' . $this->data['Unit']['name'] . " : Edit";
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
$title = "Enter New Unit";
|
|
||||||
$this->data = array();
|
|
||||||
}
|
|
||||||
|
|
||||||
$statusEnums = $this->Unit->allowedStatusSet($id);
|
|
||||||
$statusEnums = array_combine(array_keys($statusEnums),
|
|
||||||
array_keys($statusEnums));
|
|
||||||
$this->set(compact('statusEnums'));
|
|
||||||
|
|
||||||
$unit_sizes = $this->Unit->UnitSize->find
|
|
||||||
('list', array('order' => array('unit_type_id', 'width', 'depth', 'id')));
|
|
||||||
$this->set(compact('unit_sizes'));
|
|
||||||
|
|
||||||
// Prepare to render.
|
|
||||||
pr($this->data);
|
|
||||||
$this->set(compact('title'));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,354 +0,0 @@
|
|||||||
<?php
|
|
||||||
class Account extends AppModel {
|
|
||||||
|
|
||||||
var $hasOne = array(
|
|
||||||
'CurrentLedger' => array(
|
|
||||||
'className' => 'Ledger',
|
|
||||||
// REVISIT <AP> 20090702:
|
|
||||||
// I would prefer this statement, which has no
|
|
||||||
// engine specific code. However, it doesn't
|
|
||||||
// work with the Linkable behavior. I need to
|
|
||||||
// look into that, just not right now.
|
|
||||||
//'conditions' => array(array('CurrentLedger.close_transaction_id' => null)),
|
|
||||||
'conditions' => array('CurrentLedger.close_transaction_id IS NULL'),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
|
|
||||||
var $hasMany = array(
|
|
||||||
'Ledger',
|
|
||||||
'LedgerEntry',
|
|
||||||
);
|
|
||||||
|
|
||||||
|
|
||||||
/**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
* function: type
|
|
||||||
* - Returns the type of this account
|
|
||||||
*/
|
|
||||||
function type($id) {
|
|
||||||
$this->cacheQueries = true;
|
|
||||||
$account = $this->find('first', array
|
|
||||||
('recursive' => -1,
|
|
||||||
'fields' => array('type'),
|
|
||||||
'conditions' => array(array('Account.id' => $id)),
|
|
||||||
));
|
|
||||||
$this->cacheQueries = false;
|
|
||||||
|
|
||||||
return $account['Account']['type'];
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
* function: fundamentalType
|
|
||||||
* - Returns the fundmental type of the account, credit or debit
|
|
||||||
*/
|
|
||||||
function fundamentalType($id_or_type) {
|
|
||||||
if (is_numeric($id_or_type))
|
|
||||||
$type = $this->type($id_or_type);
|
|
||||||
else
|
|
||||||
$type = $id_or_type;
|
|
||||||
|
|
||||||
// Asset and Expense accounts are debit accounts
|
|
||||||
if (in_array(strtoupper($type), array('ASSET', 'EXPENSE')))
|
|
||||||
return 'debit';
|
|
||||||
|
|
||||||
// Otherwise, it's a credit account
|
|
||||||
return 'credit';
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
* function: fundamentalOpposite
|
|
||||||
* - Returns the opposite fundmental type of the account, credit or debit
|
|
||||||
*/
|
|
||||||
function fundamentalOpposite($id_or_type) {
|
|
||||||
if (in_array(strtolower($id_or_type), array('credit', 'debit')))
|
|
||||||
$fund = $id_or_type;
|
|
||||||
else
|
|
||||||
$fund = $this->fundamentalType($id_or_type);
|
|
||||||
|
|
||||||
if (strtolower($fund) == 'debit')
|
|
||||||
return 'credit';
|
|
||||||
|
|
||||||
return 'debit';
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
* function: name
|
|
||||||
* - Returns the name of this account
|
|
||||||
*/
|
|
||||||
function name($id) {
|
|
||||||
$this->cacheQueries = true;
|
|
||||||
$account = $this->find('first', array
|
|
||||||
('recursive' => -1,
|
|
||||||
'fields' => array('name'),
|
|
||||||
'conditions' => array(array('Account.id' => $id)),
|
|
||||||
));
|
|
||||||
$this->cacheQueries = false;
|
|
||||||
|
|
||||||
return $account['Account']['name'];
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
* function: debitCreditFields
|
|
||||||
* - Returns the fields necessary to determine whether the queried
|
|
||||||
* entries are a debit, or a credit, and also the effect each have
|
|
||||||
* on the overall balance of the account.
|
|
||||||
*/
|
|
||||||
|
|
||||||
function debitCreditFields($sum = false, $balance = true,
|
|
||||||
$entry_name = 'LedgerEntry', $account_name = 'Account') {
|
|
||||||
return $this->LedgerEntry->debitCreditFields
|
|
||||||
($sum, $balance, $entry_name, $account_name);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
* function: Account IDs
|
|
||||||
* - Returns the ID of the desired account
|
|
||||||
*/
|
|
||||||
|
|
||||||
function securityDepositAccountID() { return $this->nameToID('Security Deposit'); }
|
|
||||||
function rentAccountID() { return $this->nameToID('Rent'); }
|
|
||||||
function lateChargeAccountID() { return $this->nameToID('Late Charge'); }
|
|
||||||
function nsfAccountID() { return $this->nameToID('NSF'); }
|
|
||||||
function nsfChargeAccountID() { return $this->nameToID('NSF Charge'); }
|
|
||||||
function taxAccountID() { return $this->nameToID('Tax'); }
|
|
||||||
function accountReceivableAccountID() { return $this->nameToID('A/R'); }
|
|
||||||
function accountPayableAccountID() { return $this->nameToID('A/P'); }
|
|
||||||
function cashAccountID() { return $this->nameToID('Cash'); }
|
|
||||||
function checkAccountID() { return $this->nameToID('Check'); }
|
|
||||||
function moneyOrderAccountID() { return $this->nameToID('Money Order'); }
|
|
||||||
function concessionAccountID() { return $this->nameToID('Concession'); }
|
|
||||||
function waiverAccountID() { return $this->nameToID('Waiver'); }
|
|
||||||
function pettyCashAccountID() { return $this->nameToID('Petty Cash'); }
|
|
||||||
function invoiceAccountID() { return $this->nameToID('Invoice'); }
|
|
||||||
function receiptAccountID() { return $this->nameToID('Receipt'); }
|
|
||||||
function badDebtAccountID() { return $this->nameToID('Bad Debt'); }
|
|
||||||
|
|
||||||
|
|
||||||
/**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
* function: fundamentalAccounts
|
|
||||||
* - Returns an array of accounts by their fundamental type
|
|
||||||
*/
|
|
||||||
|
|
||||||
function fundamentalAccounts($ftype) {
|
|
||||||
$this->cacheQueries = true;
|
|
||||||
$account = $this->find('all', array
|
|
||||||
('contain' => array('CurrentLedger'),
|
|
||||||
'fields' => array('Account.id', 'Account.type', 'Account.name', 'CurrentLedger.id'),
|
|
||||||
'conditions' => array('Account.type' => strtoupper($ftype))
|
|
||||||
));
|
|
||||||
$this->cacheQueries = false;
|
|
||||||
|
|
||||||
return $account;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
* function: relatedAccounts
|
|
||||||
* - Returns an array of accounts related by similar attributes
|
|
||||||
*/
|
|
||||||
|
|
||||||
function relatedAccounts($attribute, $extra = null) {
|
|
||||||
$this->cacheQueries = true;
|
|
||||||
$accounts = $this->find('all', array
|
|
||||||
('contain' => array('CurrentLedger'),
|
|
||||||
'fields' => array('Account.id', 'Account.type', 'Account.name', 'CurrentLedger.id'),
|
|
||||||
'conditions' => array('Account.'.$attribute => true),
|
|
||||||
'order' => array('Account.name'),
|
|
||||||
) + (isset($extra) ? $extra : array())
|
|
||||||
);
|
|
||||||
$this->cacheQueries = false;
|
|
||||||
|
|
||||||
// Rearrange to be of the form (id => name)
|
|
||||||
$rel_accounts = array();
|
|
||||||
foreach ($accounts AS $acct) {
|
|
||||||
$rel_accounts[$acct['Account']['id']] = $acct['Account']['name'];
|
|
||||||
}
|
|
||||||
|
|
||||||
return $rel_accounts;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
* function: xxxAccounts
|
|
||||||
* - Returns an array of accounts suitable for activity xxx
|
|
||||||
*/
|
|
||||||
|
|
||||||
function invoiceAccounts() {
|
|
||||||
return $this->relatedAccounts('invoices', array('order' => 'name'));
|
|
||||||
}
|
|
||||||
|
|
||||||
function receiptAccounts() {
|
|
||||||
return $this->relatedAccounts('receipts', array('order' => 'name'));
|
|
||||||
}
|
|
||||||
|
|
||||||
function depositAccounts() {
|
|
||||||
return $this->relatedAccounts('deposits', array('order' => 'name'));
|
|
||||||
}
|
|
||||||
|
|
||||||
function refundAccounts() {
|
|
||||||
return $this->relatedAccounts('refunds', array('order' => 'name'));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
* function: collectableAccounts
|
|
||||||
* - Returns an array of accounts suitable to show income collection
|
|
||||||
*/
|
|
||||||
|
|
||||||
function collectableAccounts() {
|
|
||||||
$accounts = $this->receiptAccounts();
|
|
||||||
|
|
||||||
foreach(array($this->nsfAccountID(),
|
|
||||||
$this->securityDepositAccountID())
|
|
||||||
AS $account_id) {
|
|
||||||
$accounts[$account_id] = $this->name($account_id);
|
|
||||||
}
|
|
||||||
|
|
||||||
return $accounts;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
* function: currentLedgerID
|
|
||||||
* - Returns the current ledger ID of the account
|
|
||||||
*/
|
|
||||||
function currentLedgerID($id) {
|
|
||||||
$this->cacheQueries = true;
|
|
||||||
$item = $this->find('first', array
|
|
||||||
('contain' => 'CurrentLedger',
|
|
||||||
'conditions' => array('Account.id' => $id),
|
|
||||||
));
|
|
||||||
$this->cacheQueries = false;
|
|
||||||
return $item['CurrentLedger']['id'];
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
* function: ledgers
|
|
||||||
* - Returns an array of ledger ids from the given account
|
|
||||||
*/
|
|
||||||
function ledgers($id, $all = false) {
|
|
||||||
if ($all) {
|
|
||||||
$contain = array('Ledger' => array('fields' => array('Ledger.id')));
|
|
||||||
} else {
|
|
||||||
$contain = array('CurrentLedger' => array('fields' => array('CurrentLedger.id')));
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->cacheQueries = true;
|
|
||||||
$account = $this->find('first', array
|
|
||||||
('contain' => $contain,
|
|
||||||
'fields' => array(),
|
|
||||||
'conditions' => array(array('Account.id' => $id)),
|
|
||||||
));
|
|
||||||
$this->cacheQueries = false;
|
|
||||||
|
|
||||||
if ($all) {
|
|
||||||
$ledger_ids = array();
|
|
||||||
foreach ($account['Ledger'] AS $ledger)
|
|
||||||
array_push($ledger_ids, $ledger['id']);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
$ledger_ids = array($account['CurrentLedger']['id']);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* pr(array('function' => 'Account::ledgers', */
|
|
||||||
/* 'args' => compact('id', 'all'), */
|
|
||||||
/* 'return' => $ledger_ids)); */
|
|
||||||
|
|
||||||
return $ledger_ids;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
* function: closeCurrentLedger
|
|
||||||
* - Closes the current account ledger, and opens a new one
|
|
||||||
* with the old balance carried forward.
|
|
||||||
*/
|
|
||||||
function closeCurrentLedgers($ids = null) {
|
|
||||||
|
|
||||||
$this->cacheQueries = true;
|
|
||||||
$account = $this->find('all', array
|
|
||||||
('contain' => array('CurrentLedger.id'),
|
|
||||||
'fields' => array(),
|
|
||||||
'conditions' => (empty($ids)
|
|
||||||
? array()
|
|
||||||
: array(array('Account.id' => $ids)))
|
|
||||||
));
|
|
||||||
$this->cacheQueries = false;
|
|
||||||
//pr(compact('id', 'account'));
|
|
||||||
|
|
||||||
$ledger_ids = array();
|
|
||||||
foreach ($account AS $acct)
|
|
||||||
$ledger_ids[] = $acct['CurrentLedger']['id'];
|
|
||||||
|
|
||||||
return $this->Ledger->closeLedgers($ledger_ids);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
* function: ledgerEntries
|
|
||||||
* - Returns an array of ledger entries that belong to the given
|
|
||||||
* account, either just from the current ledger, or from all ledgers.
|
|
||||||
*/
|
|
||||||
function ledgerEntries($id, $all = false, $cond = null, $link = null) {
|
|
||||||
$ledgers = $this->ledgers($id, $all);
|
|
||||||
return $this->Ledger->ledgerEntries($ledgers, $cond, $link);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
* function: stats
|
|
||||||
* - Returns summary data from the requested account.
|
|
||||||
*/
|
|
||||||
|
|
||||||
function stats($id = null, $all = false, $query = null) {
|
|
||||||
if (!$id)
|
|
||||||
return null;
|
|
||||||
|
|
||||||
$this->queryInit($query);
|
|
||||||
$query['link'] = array('Account' => $query['link']);
|
|
||||||
|
|
||||||
foreach ($this->ledgers($id, $all) AS $ledger)
|
|
||||||
$this->statsMerge($stats['Ledger'],
|
|
||||||
$this->Ledger->stats($ledger, $query));
|
|
||||||
|
|
||||||
return $stats;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
?>
|
|
||||||
@@ -1,486 +0,0 @@
|
|||||||
<?php
|
|
||||||
/*
|
|
||||||
* LinkableBehavior
|
|
||||||
* Light-weight approach for data mining on deep relations between models.
|
|
||||||
* Join tables based on model relations to easily enable right to left find operations.
|
|
||||||
*
|
|
||||||
* Can be used as a alternative to the ContainableBehavior:
|
|
||||||
* - On data fetching only in right to left operations,
|
|
||||||
* wich means that in "one to many" relations (hasMany, hasAndBelongsToMany)
|
|
||||||
* should only be used from the "many to one" tables. i.e:
|
|
||||||
* To fetch all Users assigneds to a Project with ProjectAssignment,
|
|
||||||
* $Project->find('all', array('link' => 'User', 'conditions' => 'project_id = 1'))
|
|
||||||
* - Won't produce the desired result as data came from users table will be lost.
|
|
||||||
* $User->find('all', array('link' => 'Project', 'conditions' => 'project_id = 1'))
|
|
||||||
* - Will fetch all users related to the specified project in one query
|
|
||||||
*
|
|
||||||
* - On data mining as a much lighter approach - can reduce 300+ query find operations
|
|
||||||
* in one single query with joins; "or your money back!" ;-)
|
|
||||||
*
|
|
||||||
* - Has the 'fields' param enabled to make it easy to replace Containable usage,
|
|
||||||
* only change the 'contain' param to 'link'.
|
|
||||||
*
|
|
||||||
* Linkable Behavior. Taking it easy in your DB.
|
|
||||||
* RafaelBandeira <rafaelbandeira3(at)gmail(dot)com>
|
|
||||||
*
|
|
||||||
* Licensed under The MIT License
|
|
||||||
* Redistributions of files must retain the above copyright notice.
|
|
||||||
*
|
|
||||||
* @version 1.0;
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
/**********************************************************************
|
|
||||||
* NOTE TO <AP> 20090615:
|
|
||||||
* This structure should be linkable (it was my test case).
|
|
||||||
|
|
||||||
$entry = $this->LedgerEntry->find
|
|
||||||
('first',
|
|
||||||
array('link' => array('DebitLedger' =>
|
|
||||||
array(
|
|
||||||
'fields' => array('id'),
|
|
||||||
'alias' => 'MyDebitLedger',
|
|
||||||
'Account' =>
|
|
||||||
array(
|
|
||||||
'fields' => array('id'),
|
|
||||||
'alias' => 'MyDebitAccount'),
|
|
||||||
),
|
|
||||||
|
|
||||||
'MyCreditLedger' =>
|
|
||||||
array(
|
|
||||||
'fields' => array('id'),
|
|
||||||
'class' => 'CreditLedger',
|
|
||||||
'MyCreditAccount' =>
|
|
||||||
array(
|
|
||||||
'fields' => array('id'),
|
|
||||||
'class' => 'Account'),
|
|
||||||
),
|
|
||||||
|
|
||||||
'MyOtherLedger' =>
|
|
||||||
array(
|
|
||||||
'fields' => array('id'),
|
|
||||||
'class' => 'Ledger',
|
|
||||||
'alias' => 'AliasToMyOtherLedger',
|
|
||||||
'Account' =>
|
|
||||||
array(
|
|
||||||
'fields' => array('id'),
|
|
||||||
'alias' => 'AliasToMyOtherAccount'),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
|
|
||||||
'conditions' => array('LedgerEntry.id' => $id),
|
|
||||||
));
|
|
||||||
**********************************************************************/
|
|
||||||
|
|
||||||
|
|
||||||
class LinkableBehavior extends ModelBehavior {
|
|
||||||
|
|
||||||
protected $_key = 'link';
|
|
||||||
|
|
||||||
protected $_options = array(
|
|
||||||
'type' => true, 'table' => true, 'alias' => true, 'joins' => true,
|
|
||||||
'conditions' => true, 'fields' => true, 'reference' => true,
|
|
||||||
'class' => true, 'defaults' => true, 'linkalias' => true,
|
|
||||||
);
|
|
||||||
|
|
||||||
protected $_defaults = array('type' => 'LEFT');
|
|
||||||
|
|
||||||
function pr($lev, $mixed) {
|
|
||||||
if ($lev >= 3)
|
|
||||||
return;
|
|
||||||
|
|
||||||
pr($mixed);
|
|
||||||
return;
|
|
||||||
|
|
||||||
$trace = debug_backtrace(false);
|
|
||||||
//array_shift($trace);
|
|
||||||
$calls = array();
|
|
||||||
foreach ($trace AS $call) {
|
|
||||||
$call = array_intersect_key($call,
|
|
||||||
array('file'=>1,
|
|
||||||
'line'=>1,
|
|
||||||
//'class'=>1,
|
|
||||||
'function'=>1,
|
|
||||||
));
|
|
||||||
$calls[] = implode("; ", $call);
|
|
||||||
}
|
|
||||||
pr(array('debug' => $mixed, 'stack' => $calls));
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* This is a function for made recursive str_replaces in an array
|
|
||||||
* NOTE: The palacement of this function is terrible, but I don't
|
|
||||||
* know if I really want to go down this path or not.
|
|
||||||
*/
|
|
||||||
function recursive_array_replace($find, $replace, &$data) {
|
|
||||||
if (!isset($data))
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (is_array($data)) {
|
|
||||||
foreach ($data as $key => $value) {
|
|
||||||
if (is_array($value)) {
|
|
||||||
$this->recursive_array_replace($find, $replace, $data[$key]);
|
|
||||||
} else {
|
|
||||||
$data[$key] = str_replace($find, $replace, $value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
$data = str_replace($find, $replace, $data);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public function beforeFind(&$Model, $query) {
|
|
||||||
if (!isset($query[$this->_key]))
|
|
||||||
return $query;
|
|
||||||
|
|
||||||
if (!isset($query['fields']) || $query['fields'] === true) {
|
|
||||||
$query['fields'] = $Model->getDataSource()->fields($Model);
|
|
||||||
} elseif (!is_array($query['fields'])) {
|
|
||||||
$query['fields'] = array($query['fields']);
|
|
||||||
}
|
|
||||||
$query = am(array('joins' => array()), $query, array('recursive' => -1));
|
|
||||||
|
|
||||||
$reference = array('class' => $Model->alias,
|
|
||||||
'alias' => $Model->alias,
|
|
||||||
);
|
|
||||||
|
|
||||||
$result = array_diff_key($query, array($this->_key => 1));
|
|
||||||
$this->buildQuery($Model, $Model->alias, $Model->alias, $Model->findQueryType,
|
|
||||||
$query[$this->_key], $result);
|
|
||||||
return $result;
|
|
||||||
}
|
|
||||||
|
|
||||||
function buildQuery(&$Reference, $referenceClass, $referenceAlias, $query_type, $links, &$result) {
|
|
||||||
if (empty($links))
|
|
||||||
return;
|
|
||||||
|
|
||||||
$this->pr(10,
|
|
||||||
array('begin' => 'Linkable::buildQuery',
|
|
||||||
'args' => compact('referenceClass', 'referenceAlias', 'query_type', 'links'),
|
|
||||||
));
|
|
||||||
|
|
||||||
//$defaults = $this->_defaults;// + array($this->_key => array());
|
|
||||||
//$optionsKeys = $this->_options + array($this->_key => true);
|
|
||||||
|
|
||||||
$links = Set::normalize($links);
|
|
||||||
$this->pr(24,
|
|
||||||
array('checkpoint' => 'Normalized links',
|
|
||||||
compact('links'),
|
|
||||||
));
|
|
||||||
foreach ($links as $alias => $options) {
|
|
||||||
if (is_null($options)) {
|
|
||||||
$options = array();
|
|
||||||
}
|
|
||||||
//$options = array_intersect_key($options, $optionsKeys);
|
|
||||||
//$options = am($this->_defaults, compact('alias'), $options);
|
|
||||||
|
|
||||||
$options += compact('alias');
|
|
||||||
$options += $this->_defaults;
|
|
||||||
|
|
||||||
if (empty($options['alias'])) {
|
|
||||||
throw new InvalidArgumentException(sprintf('%s::%s must receive aliased links', get_class($this), __FUNCTION__));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (empty($options['class']))
|
|
||||||
$options['class'] = $alias;
|
|
||||||
|
|
||||||
if (!isset($options['conditions']))
|
|
||||||
$options['conditions'] = null;
|
|
||||||
elseif (!is_array($options['conditions']))
|
|
||||||
$options['conditions'] = array($options['conditions']);
|
|
||||||
|
|
||||||
$this->pr(20,
|
|
||||||
array('checkpoint' => 'Begin Model Work',
|
|
||||||
compact('referenceAlias', 'alias', 'options'),
|
|
||||||
));
|
|
||||||
|
|
||||||
$modelClass = $options['class'];
|
|
||||||
$modelAlias = $options['alias'];
|
|
||||||
$Model =& ClassRegistry::init($modelClass); // the incoming model to be linked in query
|
|
||||||
|
|
||||||
$this->pr(12,
|
|
||||||
array('checkpoint' => 'Model Established',
|
|
||||||
'Reference' => ($referenceAlias .' : '. $referenceClass .
|
|
||||||
' ('. $Reference->alias .' : '. $Reference->name .')'),
|
|
||||||
'Model' => ($modelAlias .' : '. $modelClass .
|
|
||||||
' ('. $Model->alias .' : '. $Model->name .')'),
|
|
||||||
));
|
|
||||||
|
|
||||||
$db =& $Model->getDataSource();
|
|
||||||
|
|
||||||
$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])) {
|
|
||||||
$this->pr(12, array('checkpoint' => "Reference ($referenceClass) defines association to Model ($modelClass)"));
|
|
||||||
$associatedThroughReference = 1;
|
|
||||||
$type = $associations[$Model->alias];
|
|
||||||
$association = $Reference->{$type}[$Model->alias];
|
|
||||||
}
|
|
||||||
elseif (($associations = $Model->getAssociated()) &&
|
|
||||||
isset($associations[$Reference->alias])) {
|
|
||||||
$this->pr(12, array('checkpoint' => "Model ($modelClass) defines association to Reference ($referenceClass)"));
|
|
||||||
$type = $associations[$Reference->alias];
|
|
||||||
$association = $Model->{$type}[$Reference->alias];
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
// No relationship... make our best effort to create one.
|
|
||||||
$this->pr(12, array('checkpoint' => "No assocation between Reference ($referenceClass) and Model ($modelClass)"));
|
|
||||||
$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) {
|
|
||||||
$primaryAlias = $referenceAlias;
|
|
||||||
$foreignAlias = $modelAlias;
|
|
||||||
$primaryModel = $Reference;
|
|
||||||
$foreignModel = $Model;
|
|
||||||
} else {
|
|
||||||
$primaryAlias = $modelAlias;
|
|
||||||
$foreignAlias = $referenceAlias;
|
|
||||||
$primaryModel = $Model;
|
|
||||||
$foreignModel = $Reference;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($associatedThroughReference)
|
|
||||||
$associationAlias = $referenceAlias;
|
|
||||||
else
|
|
||||||
$associationAlias = $modelAlias;
|
|
||||||
|
|
||||||
$this->pr(30,
|
|
||||||
array('checkpoint' => 'Options/Association pre-merge',
|
|
||||||
compact('association', 'options'),
|
|
||||||
));
|
|
||||||
|
|
||||||
// A couple exceptions before performing a union of
|
|
||||||
// options and association. Namely, most fields result
|
|
||||||
// in either/or, but a couple should include BOTH the
|
|
||||||
// options AND the association settings.
|
|
||||||
foreach (array('fields', 'conditions') AS $fld) {
|
|
||||||
$this->pr(31,
|
|
||||||
array('checkpoint' => 'Options/Associations field original',
|
|
||||||
compact('fld') +
|
|
||||||
array("options[$fld]" =>
|
|
||||||
array('value' => array_key_exists($fld, $options) ? (isset($options[$fld]) ? $options[$fld] : '-null-') : '-unset-',
|
|
||||||
'type' => array_key_exists($fld, $options) ? (isset($options[$fld]) ? gettype($options[$fld]) : '-null-') : '-unset-'),
|
|
||||||
"association[$fld]" =>
|
|
||||||
array('value' => array_key_exists($fld, $association) ? (isset($association[$fld]) ? $association[$fld] : '-null-') : '-unset-',
|
|
||||||
'type' => array_key_exists($fld, $association) ? (isset($association[$fld]) ? gettype($association[$fld]) : '-null-') : '-unset-'),
|
|
||||||
)));
|
|
||||||
|
|
||||||
if (!isset($options[$fld]) ||
|
|
||||||
(empty($options[$fld]) && !is_array($options[$fld])))
|
|
||||||
unset($options[$fld]);
|
|
||||||
elseif (!empty($options[$fld]) && !is_array($options[$fld]))
|
|
||||||
$options[$fld] = array($options[$fld]);
|
|
||||||
|
|
||||||
if (!isset($association[$fld]) ||
|
|
||||||
(empty($association[$fld]) && !is_array($association[$fld])))
|
|
||||||
unset($association[$fld]);
|
|
||||||
elseif (!empty($association[$fld]) && !is_array($association[$fld]))
|
|
||||||
$association[$fld] = array($association[$fld]);
|
|
||||||
|
|
||||||
|
|
||||||
$this->pr(31,
|
|
||||||
array('checkpoint' => 'Options/Associations field normalize',
|
|
||||||
compact('fld') +
|
|
||||||
array("options[$fld]" =>
|
|
||||||
array('value' => array_key_exists($fld, $options) ? (isset($options[$fld]) ? $options[$fld] : '-null-') : '-unset-',
|
|
||||||
'type' => array_key_exists($fld, $options) ? (isset($options[$fld]) ? gettype($options[$fld]) : '-null-') : '-unset-'),
|
|
||||||
"association[$fld]" =>
|
|
||||||
array('value' => array_key_exists($fld, $association) ? (isset($association[$fld]) ? $association[$fld] : '-null-') : '-unset-',
|
|
||||||
'type' => array_key_exists($fld, $association) ? (isset($association[$fld]) ? gettype($association[$fld]) : '-null-') : '-unset-'),
|
|
||||||
)));
|
|
||||||
|
|
||||||
if (isset($options[$fld]) && isset($association[$fld]))
|
|
||||||
$options[$fld] = array_merge($options[$fld],
|
|
||||||
$association[$fld]);
|
|
||||||
|
|
||||||
$this->pr(31,
|
|
||||||
array('checkpoint' => 'Options/Associations field merge complete',
|
|
||||||
compact('fld') +
|
|
||||||
array("options[$fld]" =>
|
|
||||||
array('value' => array_key_exists($fld, $options) ? (isset($options[$fld]) ? $options[$fld] : '-null-') : '-unset-',
|
|
||||||
'type' => array_key_exists($fld, $options) ? (isset($options[$fld]) ? gettype($options[$fld]) : '-null-') : '-unset-'),
|
|
||||||
"association[$fld]" =>
|
|
||||||
array('value' => array_key_exists($fld, $association) ? (isset($association[$fld]) ? $association[$fld] : '-null-') : '-unset-',
|
|
||||||
'type' => array_key_exists($fld, $association) ? (isset($association[$fld]) ? gettype($association[$fld]) : '-null-') : '-unset-'),
|
|
||||||
)));
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->pr(30,
|
|
||||||
array('checkpoint' => 'Options/Association post-merge',
|
|
||||||
compact('association', 'options'),
|
|
||||||
));
|
|
||||||
|
|
||||||
// For any option that's not already set, use
|
|
||||||
// whatever is specified by the assocation.
|
|
||||||
$options += array_intersect_key($association, $this->_options);
|
|
||||||
|
|
||||||
// Replace all instances of the MODEL_ALIAS variable
|
|
||||||
// tag with the correct model alias.
|
|
||||||
$this->recursive_array_replace("%{MODEL_ALIAS}",
|
|
||||||
$associationAlias,
|
|
||||||
$options['conditions']);
|
|
||||||
|
|
||||||
$this->pr(15,
|
|
||||||
array('checkpoint' => 'Models Established - Check Associations',
|
|
||||||
'primaryModel' => $primaryAlias .' : '. $primaryModel->name,
|
|
||||||
'foreignModel' => $foreignAlias .' : '. $foreignModel->name,
|
|
||||||
compact('type', 'association', 'options'),
|
|
||||||
));
|
|
||||||
|
|
||||||
if ($type === 'hasAndBelongsToMany') {
|
|
||||||
if (isset($association['with']))
|
|
||||||
$linkClass = $association['with'];
|
|
||||||
else
|
|
||||||
$linkClass = Inflector::classify($association['joinTable']);
|
|
||||||
|
|
||||||
$Link =& $Model->{$linkClass};
|
|
||||||
|
|
||||||
if (isset($options['linkalias']))
|
|
||||||
$linkAlias = $options['linkalias'];
|
|
||||||
else
|
|
||||||
$linkAlias = $Link->alias;
|
|
||||||
|
|
||||||
// foreignKey and associationForeignKey can refer to either
|
|
||||||
// the model or the reference, depending on which class
|
|
||||||
// actually defines the association. Make sure to we're
|
|
||||||
// using the foreign keys to point to the right class.
|
|
||||||
if ($associatedThroughReference) {
|
|
||||||
$modelAFK = 'associationForeignKey';
|
|
||||||
$referenceAFK = 'foreignKey';
|
|
||||||
} else {
|
|
||||||
$modelAFK = 'foreignKey';
|
|
||||||
$referenceAFK = 'associationForeignKey';
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->pr(17,
|
|
||||||
array('checkpoint' => 'Linking HABTM',
|
|
||||||
compact('linkClass', 'linkAlias',
|
|
||||||
'modelAFK', 'referenceAFK'),
|
|
||||||
));
|
|
||||||
|
|
||||||
// Get the foreign key fields (for the link table) directly from
|
|
||||||
// the defined model associations, if they exists. This is the
|
|
||||||
// users direct specification, and therefore definitive if present.
|
|
||||||
$modelLink = $Link->escapeField($association[$modelAFK], $linkAlias);
|
|
||||||
$referenceLink = $Link->escapeField($association[$referenceAFK], $linkAlias);
|
|
||||||
|
|
||||||
// If we haven't figured out the foreign keys, see if there is a
|
|
||||||
// model for the link table, and if it has the appropriate
|
|
||||||
// associations with the two tables we're trying to join.
|
|
||||||
if (empty($modelLink) && isset($Link->belongsTo[$Model->alias]))
|
|
||||||
$modelLink = $Link->escapeField($Link->belongsTo[$Model->alias]['foreignKey'], $linkAlias);
|
|
||||||
if (empty($referenceLink) && isset($Link->belongsTo[$Reference->alias]))
|
|
||||||
$referenceLink = $Link->escapeField($Link->belongsTo[$Reference->alias]['foreignKey'], $linkAlias);
|
|
||||||
|
|
||||||
// We're running quite thin here. None of the models spell
|
|
||||||
// out the appropriate linkages. We'll have to SWAG it.
|
|
||||||
if (empty($modelLink))
|
|
||||||
$modelLink = $Link->escapeField(Inflector::underscore($Model->alias) . '_id', $linkAlias);
|
|
||||||
if (empty($referenceLink))
|
|
||||||
$referenceLink = $Link->escapeField(Inflector::underscore($Reference->alias) . '_id', $linkAlias);
|
|
||||||
|
|
||||||
// Get the primary key from the tables we're joining.
|
|
||||||
$referenceKey = $Reference->escapeField(null, $referenceAlias);
|
|
||||||
$modelKey = $Model->escapeField(null, $modelAlias);
|
|
||||||
|
|
||||||
$this->pr(21,
|
|
||||||
array('checkpoint' => 'HABTM links/keys',
|
|
||||||
array(compact('modelLink', 'modelKey'),
|
|
||||||
compact('referenceLink', 'referenceKey')),
|
|
||||||
));
|
|
||||||
|
|
||||||
// Join the linkage table to our model. We'll use an inner join,
|
|
||||||
// as the whole purpose of the linkage table is to make this
|
|
||||||
// connection. As we are embedding this join, the INNER will not
|
|
||||||
// cause any problem with the overall query, should the user not
|
|
||||||
// be concerned with whether or not the join has any results.
|
|
||||||
// They control that with the 'type' parameter which will be at
|
|
||||||
// the top level join.
|
|
||||||
$options['joins'][] = array('type' => 'INNER',
|
|
||||||
'alias' => $modelAlias,
|
|
||||||
'conditions' => "{$modelKey} = {$modelLink}",
|
|
||||||
'table' => $db->fullTableName($Model, true));
|
|
||||||
|
|
||||||
// Now for the top level join. This will be added into the list
|
|
||||||
// of joins down below, outside of the HABTM specific code.
|
|
||||||
$options['class'] = $linkClass;
|
|
||||||
$options['alias'] = $linkAlias;
|
|
||||||
$options['table'] = $Link->getDataSource()->fullTableName($Link);
|
|
||||||
$options['conditions'][] = "{$referenceLink} = {$referenceKey}";
|
|
||||||
}
|
|
||||||
elseif (isset($association['foreignKey']) && $association['foreignKey']) {
|
|
||||||
$foreignKey = $primaryModel->escapeField($association['foreignKey'], $primaryAlias);
|
|
||||||
$primaryKey = $foreignModel->escapeField($foreignModel->primaryKey, $foreignAlias);
|
|
||||||
|
|
||||||
$this->pr(17,
|
|
||||||
array('checkpoint' => 'Linking due to foreignKey',
|
|
||||||
compact('foreignKey', '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}";
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
$this->pr(17,
|
|
||||||
array('checkpoint' => 'Linking with no logic (expecting user defined)',
|
|
||||||
));
|
|
||||||
|
|
||||||
// No Foreign Key... nothing we can do.
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->pr(19,
|
|
||||||
array('checkpoint' => 'Conditions',
|
|
||||||
array('options[conditions]' => $options['conditions'],
|
|
||||||
),
|
|
||||||
));
|
|
||||||
|
|
||||||
if (empty($options['table'])) {
|
|
||||||
$options['table'] = $db->fullTableName($Model, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!isset($options['fields']) || !is_array($options['fields']))
|
|
||||||
$options['fields'] = $db->fields($Model, $modelAlias);
|
|
||||||
elseif (!empty($options['fields']))
|
|
||||||
$options['fields'] = $db->fields($Model, $modelAlias, $options['fields']);
|
|
||||||
|
|
||||||
// When performing a count query, fields are useless.
|
|
||||||
// For everything else, we need to add them into the set.
|
|
||||||
if ($query_type !== 'count')
|
|
||||||
$result['fields'] = array_merge($result['fields'], $options['fields']);
|
|
||||||
|
|
||||||
$result['joins'][] = array_intersect_key($options,
|
|
||||||
array('type' => true,
|
|
||||||
'alias' => true,
|
|
||||||
'table' => true,
|
|
||||||
'joins' => true,
|
|
||||||
'conditions' => true));
|
|
||||||
|
|
||||||
$sublinks = array_diff_key($options, $this->_options);
|
|
||||||
$this->buildQuery($Model, $modelClass, $modelAlias, $query_type, $sublinks, $result);
|
|
||||||
|
|
||||||
$this->pr(19,
|
|
||||||
array('checkpoint' => 'Model Join Complete',
|
|
||||||
compact('referenceAlias', 'modelAlias', 'options', 'result'),
|
|
||||||
));
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->pr(20,
|
|
||||||
array('return' => 'Linkable::buildQuery',
|
|
||||||
compact('referenceAlias'),
|
|
||||||
));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,129 +0,0 @@
|
|||||||
<?php
|
|
||||||
class Contact extends AppModel {
|
|
||||||
|
|
||||||
var $displayField = 'display_name';
|
|
||||||
|
|
||||||
var $hasMany = array(
|
|
||||||
'ContactsMethod',
|
|
||||||
'ContactsCustomer',
|
|
||||||
);
|
|
||||||
|
|
||||||
var $hasAndBelongsToMany = array(
|
|
||||||
'Customer',
|
|
||||||
'ContactAddress' => array(
|
|
||||||
'joinTable' => 'contacts_methods',
|
|
||||||
'associationForeignKey' => 'method_id',
|
|
||||||
'unique' => true,
|
|
||||||
'conditions' => "method = 'ADDRESS'",
|
|
||||||
),
|
|
||||||
'ContactPhone' => array(
|
|
||||||
'joinTable' => 'contacts_methods',
|
|
||||||
'associationForeignKey' => 'method_id',
|
|
||||||
'unique' => true,
|
|
||||||
'conditions' => "method = 'PHONE'",
|
|
||||||
),
|
|
||||||
'ContactEmail' => array(
|
|
||||||
'joinTable' => 'contacts_methods',
|
|
||||||
'associationForeignKey' => 'method_id',
|
|
||||||
'unique' => true,
|
|
||||||
'conditions' => "method = 'EMAIL'",
|
|
||||||
),
|
|
||||||
);
|
|
||||||
|
|
||||||
|
|
||||||
/**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
* function: saveContact
|
|
||||||
* - Saves the contact and related data
|
|
||||||
*/
|
|
||||||
|
|
||||||
function saveContact($id, $data) {
|
|
||||||
|
|
||||||
// Establish a display name if not already given
|
|
||||||
if (!$data['Contact']['display_name'])
|
|
||||||
$data['Contact']['display_name'] =
|
|
||||||
(($data['Contact']['first_name'] &&
|
|
||||||
$data['Contact']['last_name'])
|
|
||||||
? $data['Contact']['last_name'] . ', ' . $data['Contact']['first_name']
|
|
||||||
: ($data['Contact']['first_name']
|
|
||||||
? $data['Contact']['first_name']
|
|
||||||
: $data['Contact']['last_name']));
|
|
||||||
|
|
||||||
// Save the contact data
|
|
||||||
$this->create();
|
|
||||||
if ($id)
|
|
||||||
$this->id = $id;
|
|
||||||
if (!$this->save($data, false)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
$id = $this->id;
|
|
||||||
|
|
||||||
// Remove all associated ContactMethods, as it ensures
|
|
||||||
// any entries deleted by the user actually get deleted
|
|
||||||
// in the system. We'll recreate the needed ones anyway.
|
|
||||||
// REVISIT <AP>: 20090706
|
|
||||||
// Appears that $this->save() is already doing the
|
|
||||||
// delete. I would have thought this would only happen
|
|
||||||
// on a saveAll??
|
|
||||||
/* $this->ContactsMethod->deleteAll */
|
|
||||||
/* (array('contact_id' => $id), false); */
|
|
||||||
|
|
||||||
// At this point, since we've saved data to contact,
|
|
||||||
// we'll proceed forward as much as possible, even
|
|
||||||
// if we encounter an error. For now, we'll assume
|
|
||||||
// the operation will succeed.
|
|
||||||
$ret = true;
|
|
||||||
|
|
||||||
// Iterate each type of contact method, adding them into
|
|
||||||
// the database as needed and associating with this contact.
|
|
||||||
foreach (array('phone', 'address', 'email') AS $type) {
|
|
||||||
$class = 'Contact' . ucfirst($type);
|
|
||||||
$enum = strtoupper($type);
|
|
||||||
|
|
||||||
// Nothing to do if this contact method isn't used
|
|
||||||
if (!isset($data[$class]))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
// Go through each entry of this contact method
|
|
||||||
foreach ($data[$class] AS &$item) {
|
|
||||||
|
|
||||||
// If the user has entered all new data, we need to
|
|
||||||
// save that as a brand new entry.
|
|
||||||
if (!isset($item['id'])) {
|
|
||||||
$I = new $class();
|
|
||||||
$I->create();
|
|
||||||
if (!$I->save($item, false)) {
|
|
||||||
$ret = false;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
$item['id'] = $I->id;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Update the ContactsMethod to reflect the appropriate IDs
|
|
||||||
$item['ContactsMethod']['contact_id'] = $id;
|
|
||||||
$item['ContactsMethod']['method_id'] = $item['id'];
|
|
||||||
$item['ContactsMethod']['method'] = $enum;
|
|
||||||
|
|
||||||
// Save the relationship between contact and phone/email/address
|
|
||||||
$CM = new ContactsMethod();
|
|
||||||
if (!$CM->save($item['ContactsMethod'], false)) {
|
|
||||||
$ret = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Return the result
|
|
||||||
return $ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
function contactList() {
|
|
||||||
return $this->find('list',
|
|
||||||
array('order' =>
|
|
||||||
//array('last_name', 'first_name', 'middle_name'),
|
|
||||||
array('display_name'),
|
|
||||||
));
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
?>
|
|
||||||
@@ -1,46 +0,0 @@
|
|||||||
<?php
|
|
||||||
class ContactAddress extends AppModel {
|
|
||||||
|
|
||||||
var $name = 'ContactAddress';
|
|
||||||
var $validate = array(
|
|
||||||
'id' => array('numeric'),
|
|
||||||
'postcode' => array('postal')
|
|
||||||
);
|
|
||||||
|
|
||||||
var $hasMany = array(
|
|
||||||
'ContactsMethod' => array(
|
|
||||||
'foreignKey' => 'method_id',
|
|
||||||
'conditions' => "method = 'ADDRESS'",
|
|
||||||
)
|
|
||||||
);
|
|
||||||
|
|
||||||
var $hasAndBelongsToMany = array(
|
|
||||||
'Contact' => array(
|
|
||||||
'className' => 'Contact',
|
|
||||||
'joinTable' => 'contacts_methods',
|
|
||||||
'foreignKey' => 'method_id',
|
|
||||||
'associationForeignKey' => 'contact_id',
|
|
||||||
'unique' => true,
|
|
||||||
'conditions' => "method = 'ADDRESS'",
|
|
||||||
)
|
|
||||||
);
|
|
||||||
|
|
||||||
function addressList() {
|
|
||||||
$results = $this->find('all',
|
|
||||||
array('contain' => false,
|
|
||||||
'fields' => array('id', 'address', 'city', 'state', 'postcode'),
|
|
||||||
'order' => array('state', 'city', 'postcode', 'address')));
|
|
||||||
|
|
||||||
$list = array();
|
|
||||||
foreach ($results as $key => $val) {
|
|
||||||
$list[$val['ContactAddress']['id']]
|
|
||||||
= preg_replace("/\n/", ", ", $val['ContactAddress']['address'])
|
|
||||||
. ', ' . $val['ContactAddress']['city']
|
|
||||||
. ', ' . $val['ContactAddress']['state']
|
|
||||||
. ' ' . $val['ContactAddress']['postcode']
|
|
||||||
;
|
|
||||||
}
|
|
||||||
return $list;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
?>
|
|
||||||
@@ -1,46 +0,0 @@
|
|||||||
<?php
|
|
||||||
class ContactPhone extends AppModel {
|
|
||||||
|
|
||||||
var $validate = array(
|
|
||||||
'id' => array('numeric'),
|
|
||||||
//'type' => array('inlist'),
|
|
||||||
'phone' => array('phone'),
|
|
||||||
'ext' => array('numeric')
|
|
||||||
);
|
|
||||||
|
|
||||||
var $hasMany = array(
|
|
||||||
'ContactsMethod' => array(
|
|
||||||
'foreignKey' => 'method_id',
|
|
||||||
'conditions' => "method = 'PHONE'",
|
|
||||||
)
|
|
||||||
);
|
|
||||||
|
|
||||||
var $hasAndBelongsToMany = array(
|
|
||||||
'Contact' => array(
|
|
||||||
'className' => 'Contact',
|
|
||||||
'joinTable' => 'contacts_methods',
|
|
||||||
'foreignKey' => 'method_id',
|
|
||||||
'associationForeignKey' => 'contact_id',
|
|
||||||
'unique' => true,
|
|
||||||
'conditions' => "method = 'PHONE'",
|
|
||||||
)
|
|
||||||
);
|
|
||||||
|
|
||||||
function phoneList() {
|
|
||||||
$results = $this->find('all',
|
|
||||||
array('contain' => false,
|
|
||||||
'fields' => array('id', 'phone', 'ext'),
|
|
||||||
'order' => array('phone', 'ext')));
|
|
||||||
|
|
||||||
App::Import('Helper', 'Format');
|
|
||||||
$list = array();
|
|
||||||
foreach ($results as $key => $val) {
|
|
||||||
$list[$val['ContactPhone']['id']]
|
|
||||||
= FormatHelper::phone($val['ContactPhone']['phone'],
|
|
||||||
$val['ContactPhone']['ext']);
|
|
||||||
}
|
|
||||||
return $list;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
?>
|
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
<?php
|
|
||||||
class ContactsCustomer extends AppModel {
|
|
||||||
var $primaryKey = false;
|
|
||||||
|
|
||||||
var $belongsTo = array(
|
|
||||||
'Contact',
|
|
||||||
'Customer',
|
|
||||||
);
|
|
||||||
|
|
||||||
}
|
|
||||||
?>
|
|
||||||
@@ -1,25 +0,0 @@
|
|||||||
<?php
|
|
||||||
class ContactsMethod extends AppModel {
|
|
||||||
var $primaryKey = false;
|
|
||||||
|
|
||||||
var $belongsTo = array(
|
|
||||||
'Contact',
|
|
||||||
'ContactAddress' => array(
|
|
||||||
'foreignKey' => 'method_id',
|
|
||||||
'conditions' => "method = 'ADDRESS'",
|
|
||||||
//'unique' => true,
|
|
||||||
),
|
|
||||||
'ContactPhone' => array(
|
|
||||||
'foreignKey' => 'method_id',
|
|
||||||
'conditions' => "method = 'PHONE'",
|
|
||||||
//'unique' => true,
|
|
||||||
),
|
|
||||||
'ContactEmail' => array(
|
|
||||||
'foreignKey' => 'method_id',
|
|
||||||
'conditions' => "method = 'EMAIL'",
|
|
||||||
//'unique' => true,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
|
|
||||||
}
|
|
||||||
?>
|
|
||||||
@@ -1,310 +0,0 @@
|
|||||||
<?php
|
|
||||||
class Customer extends AppModel {
|
|
||||||
|
|
||||||
var $name = 'Customer';
|
|
||||||
var $validate = array(
|
|
||||||
'id' => array('numeric'),
|
|
||||||
'name' => array('notempty'),
|
|
||||||
);
|
|
||||||
|
|
||||||
var $belongsTo = array(
|
|
||||||
'PrimaryContact' => array(
|
|
||||||
'className' => 'Contact',
|
|
||||||
),
|
|
||||||
);
|
|
||||||
|
|
||||||
var $hasMany = array(
|
|
||||||
'CurrentLease' => array(
|
|
||||||
'className' => 'Lease',
|
|
||||||
'conditions' => 'CurrentLease.close_date IS NULL',
|
|
||||||
),
|
|
||||||
'Lease',
|
|
||||||
'StatementEntry',
|
|
||||||
'ContactsCustomer',
|
|
||||||
|
|
||||||
'Transaction',
|
|
||||||
);
|
|
||||||
|
|
||||||
var $hasAndBelongsToMany = array(
|
|
||||||
'Contact',
|
|
||||||
);
|
|
||||||
|
|
||||||
|
|
||||||
/**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
* function: accountId
|
|
||||||
* - Returns the account ID for the given customer
|
|
||||||
*/
|
|
||||||
function accountId($id) {
|
|
||||||
$this->cacheQueries = true;
|
|
||||||
$customer = $this->find('first',
|
|
||||||
array('contain' => false,
|
|
||||||
'fields' => array('account_id'),
|
|
||||||
'conditions' => array(array('Customer.id' => $id))));
|
|
||||||
$this->cacheQueries = false;
|
|
||||||
|
|
||||||
return $customer['Customer']['account_id'];
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
* function: leaseIds
|
|
||||||
* - Returns the lease IDs for the given customer
|
|
||||||
*/
|
|
||||||
function leaseIds($id) {
|
|
||||||
$this->cacheQueries = true;
|
|
||||||
$customer = $this->find('first',
|
|
||||||
array('contain' =>
|
|
||||||
array('Lease' => array('fields' => array('id'))),
|
|
||||||
'fields' => array(),
|
|
||||||
'conditions' => array(array('Customer.id' => $id))));
|
|
||||||
$this->cacheQueries = false;
|
|
||||||
|
|
||||||
$ids = array();
|
|
||||||
foreach ($customer['Lease'] AS $lease)
|
|
||||||
$ids[] = $lease['id'];
|
|
||||||
|
|
||||||
return $ids;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
* function: securityDeposits
|
|
||||||
* - Returns an array of security deposit entries
|
|
||||||
*/
|
|
||||||
function securityDeposits($id, $query = null) {
|
|
||||||
$this->prEnter(compact('id', 'query'));
|
|
||||||
$this->queryInit($query);
|
|
||||||
|
|
||||||
$query['conditions'][] = array('StatementEntry.customer_id' => $id);
|
|
||||||
$query['conditions'][] = array('StatementEntry.account_id' =>
|
|
||||||
$this->StatementEntry->Account->securityDepositAccountID());
|
|
||||||
|
|
||||||
$set = $this->StatementEntry->reconciledSet('CHARGE', $query, false, true);
|
|
||||||
return $this->prReturn($set);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
* function: securityDepositBalance
|
|
||||||
* - Returns the balance of the customer security deposit(s)
|
|
||||||
*/
|
|
||||||
|
|
||||||
function securityDepositBalance($id, $query = null) {
|
|
||||||
$this->prEnter(compact('id', 'query'));
|
|
||||||
$this->queryInit($query);
|
|
||||||
|
|
||||||
$query['conditions'][] = array('StatementEntry.customer_id' => $id);
|
|
||||||
$query['conditions'][] = array('StatementEntry.account_id' =>
|
|
||||||
$this->StatementEntry->Account->securityDepositAccountID());
|
|
||||||
|
|
||||||
$stats = $this->StatementEntry->stats(null, $query);
|
|
||||||
return $this->prReturn($stats['account_balance']);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
* function: unreconciledCharges
|
|
||||||
* - Returns charges have not yet been fully paid
|
|
||||||
*/
|
|
||||||
|
|
||||||
function unreconciledCharges($id, $query = null) {
|
|
||||||
$this->prEnter(compact('id', 'query'));
|
|
||||||
$this->queryInit($query);
|
|
||||||
|
|
||||||
$query['conditions'][] = array('StatementEntry.customer_id' => $id);
|
|
||||||
$set = $this->StatementEntry->reconciledSet('CHARGE', $query, true);
|
|
||||||
return $this->prReturn($set);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
* function: saveCustomer
|
|
||||||
* - Saves the customer and related data
|
|
||||||
*/
|
|
||||||
|
|
||||||
function saveCustomer($id, $data, $primary_contact_entry) {
|
|
||||||
|
|
||||||
// Go through each contact, and create new ones as needed
|
|
||||||
foreach ($data['Contact'] AS &$contact) {
|
|
||||||
if (isset($contact['id']))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
$I = new Contact();
|
|
||||||
$I->create();
|
|
||||||
if (!$I->save($contact, false)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
$contact['id'] = $I->id;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set the primary contact ID based on caller selection
|
|
||||||
$data['Customer']['primary_contact_id']
|
|
||||||
= $data['Contact'][$primary_contact_entry]['id'];
|
|
||||||
|
|
||||||
// Provide a default customer name if not specified
|
|
||||||
if (!$data['Customer']['name']) {
|
|
||||||
$this->Contact->recursive = -1;
|
|
||||||
$pcontact = $this->Contact->read(null, $data['Customer']['primary_contact_id']);
|
|
||||||
$data['Customer']['name'] = $pcontact['Contact']['display_name'];
|
|
||||||
}
|
|
||||||
|
|
||||||
// Save the customer data
|
|
||||||
$this->create();
|
|
||||||
if ($id)
|
|
||||||
$this->id = $id;
|
|
||||||
if (!$this->save($data, false)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
$id = $this->id;
|
|
||||||
|
|
||||||
// Remove all associated Customer Contacts, as it ensures
|
|
||||||
// any entries deleted by the user actually get deleted
|
|
||||||
// in the system. We'll recreate the needed ones anyway.
|
|
||||||
// REVISIT <AP>: 20090706
|
|
||||||
// Appears that $this->save() is already doing the
|
|
||||||
// delete. I would have thought this would only happen
|
|
||||||
// on a saveAll??
|
|
||||||
/* $this->ContactsCustomer->deleteAll */
|
|
||||||
/* (array('customer_id' => $id), false); */
|
|
||||||
|
|
||||||
// At this point, since we've saved data to customer,
|
|
||||||
// we'll proceed forward as much as possible, even
|
|
||||||
// if we encounter an error. For now, we'll assume
|
|
||||||
// the operation will succeed.
|
|
||||||
$ret = true;
|
|
||||||
|
|
||||||
// Go through each entry of this customer method
|
|
||||||
foreach ($data['Contact'] AS &$contact) {
|
|
||||||
// Update the ContactsCustomer to reflect the appropriate IDs
|
|
||||||
$contact['ContactsCustomer']['customer_id'] = $id;
|
|
||||||
$contact['ContactsCustomer']['contact_id'] = $contact['id'];
|
|
||||||
|
|
||||||
// Save the relationship between customer and contact
|
|
||||||
$CM = new ContactsCustomer();
|
|
||||||
if (!$CM->save($contact['ContactsCustomer'], false)) {
|
|
||||||
$ret = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Return the result
|
|
||||||
return $ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
* function: updateLeaseCount
|
|
||||||
* - Updates the internal lease count
|
|
||||||
*/
|
|
||||||
|
|
||||||
function updateLeaseCount($id) {
|
|
||||||
$this->id = $id;
|
|
||||||
|
|
||||||
$lease_count =
|
|
||||||
$this->find('count',
|
|
||||||
array('link' => array('Lease' => array('type' => 'INNER')),
|
|
||||||
'conditions' => array('Customer.id' => $id)));
|
|
||||||
$current_count =
|
|
||||||
$this->find('count',
|
|
||||||
array('link' => array('CurrentLease' => array('type' => 'INNER')),
|
|
||||||
'conditions' => array('Customer.id' => $id)));
|
|
||||||
|
|
||||||
$this->saveField('lease_count', $lease_count);
|
|
||||||
$this->saveField('current_lease_count', $current_count);
|
|
||||||
$this->saveField('past_lease_count', $lease_count - $current_count);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
* function: balance
|
|
||||||
* - Returns the balance of money owed on the lease
|
|
||||||
*/
|
|
||||||
|
|
||||||
function balance($id) {
|
|
||||||
$stats = $this->stats($id);
|
|
||||||
return $stats['balance'];
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
* function: stats
|
|
||||||
* - Returns summary data from the requested customer.
|
|
||||||
*/
|
|
||||||
|
|
||||||
function stats($id = null, $query = null) {
|
|
||||||
//$this->prFunctionLevel(20);
|
|
||||||
$this->prEnter(compact('id', 'query'));
|
|
||||||
if (!$id)
|
|
||||||
return $this->prExit(null);
|
|
||||||
|
|
||||||
$this->queryInit($query);
|
|
||||||
|
|
||||||
// REVISIT <AP>: 20090725
|
|
||||||
// We'll need to go directly to the statement entries if
|
|
||||||
// transactions are not always associated with the customer.
|
|
||||||
// This could happen if either we remove the customer_id
|
|
||||||
// field from Transaction, or we allow multiple customers
|
|
||||||
// to be part of the same transaction (essentially making
|
|
||||||
// the Transaction.customer_id meaningless).
|
|
||||||
|
|
||||||
/* $stats = $this->StatementEntry->find */
|
|
||||||
/* ('first', array */
|
|
||||||
/* ('contain' => false, */
|
|
||||||
/* 'fields' => $this->StatementEntry->chargeDisbursementFields(true), */
|
|
||||||
/* 'conditions' => array('StatementEntry.customer_id' => $id), */
|
|
||||||
/* )); */
|
|
||||||
|
|
||||||
$find_stats = $this->StatementEntry->find
|
|
||||||
('first', array
|
|
||||||
('contain' => false,
|
|
||||||
'fields' => $this->StatementEntry->chargeDisbursementFields(true),
|
|
||||||
'conditions' => array('StatementEntry.customer_id' => $id),
|
|
||||||
));
|
|
||||||
$find_stats = $find_stats[0];
|
|
||||||
$this->pr(17, compact('find_stats'));
|
|
||||||
|
|
||||||
$tquery = $query;
|
|
||||||
$tquery['conditions'][] = array('StatementEntry.customer_id' => $id);
|
|
||||||
$statement_stats = $this->StatementEntry->stats(null, $tquery);
|
|
||||||
$statement_stats['balance'] = $statement_stats['Charge']['balance'];
|
|
||||||
$this->pr(17, compact('statement_stats'));
|
|
||||||
|
|
||||||
$tquery = $query;
|
|
||||||
//$tquery['conditions'][] = array('StatementEntry.customer_id' => $id);
|
|
||||||
$tquery['conditions'][] = array('Transaction.customer_id' => $id);
|
|
||||||
$transaction_stats = $this->Transaction->stats(null, $tquery);
|
|
||||||
$transaction_stats += $transaction_stats['StatementEntry'];
|
|
||||||
$this->pr(17, compact('transaction_stats'));
|
|
||||||
|
|
||||||
$tquery = $query;
|
|
||||||
//$tquery['conditions'][] = array('StatementEntry.customer_id' => $id);
|
|
||||||
$tquery['conditions'][] = array('Transaction.customer_id' => $id);
|
|
||||||
$ar_transaction_stats = $this->Transaction->stats(null, $tquery,
|
|
||||||
$this->Transaction->Account->accountReceivableAccountID());
|
|
||||||
$ar_transaction_stats += $ar_transaction_stats['LedgerEntry'];
|
|
||||||
$this->pr(17, compact('ar_transaction_stats'));
|
|
||||||
|
|
||||||
//$stats = $ar_transaction_stats;
|
|
||||||
$stats = $find_stats;
|
|
||||||
return $this->prReturn($stats);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
?>
|
|
||||||
@@ -1,96 +0,0 @@
|
|||||||
<?php
|
|
||||||
class DoubleEntry extends AppModel {
|
|
||||||
|
|
||||||
var $belongsTo = array(
|
|
||||||
'DebitEntry' => array(
|
|
||||||
'className' => 'LedgerEntry',
|
|
||||||
),
|
|
||||||
'CreditEntry' => array(
|
|
||||||
'className' => 'LedgerEntry',
|
|
||||||
),
|
|
||||||
);
|
|
||||||
|
|
||||||
|
|
||||||
/**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
* function: verifyDoubleEntry
|
|
||||||
* - Verifies consistenty of new double entry data
|
|
||||||
* (not in a pre-existing double entry)
|
|
||||||
*/
|
|
||||||
function verifyDoubleEntry($entry1, $entry2, $entry1_tender = null) {
|
|
||||||
/* pr(array("DoubleEntry::verifyDoubleEntry()" */
|
|
||||||
/* => compact('entry1', 'entry2', 'entry1_tender'))); */
|
|
||||||
|
|
||||||
$LE = new LedgerEntry();
|
|
||||||
if (!$LE->verifyLedgerEntry($entry1, $entry1_tender)) {
|
|
||||||
/* pr(array("DoubleEntry::verifyDoubleEntry()" */
|
|
||||||
/* => "Entry1 verification failed")); */
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (!$LE->verifyLedgerEntry($entry2)) {
|
|
||||||
/* pr(array("DoubleEntry::verifyDoubleEntry()" */
|
|
||||||
/* => "Entry2 verification failed")); */
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!(($entry1['crdr'] === 'DEBIT' && $entry2['crdr'] === 'CREDIT') ||
|
|
||||||
($entry1['crdr'] === 'CREDIT' && $entry2['crdr'] === 'DEBIT')) ||
|
|
||||||
($entry1['amount'] != $entry2['amount'])) {
|
|
||||||
/* pr(array("DoubleEntry::verifyDoubleEntry()" */
|
|
||||||
/* => "Double Entry verification failed")); */
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
* function: addDoubleEntry
|
|
||||||
* - Inserts new Double Entry into the database
|
|
||||||
*/
|
|
||||||
|
|
||||||
function addDoubleEntry($entry1, $entry2, $entry1_tender = null) {
|
|
||||||
/* pr(array('DoubleEntry::addDoubleEntry' => */
|
|
||||||
/* compact('entry1', 'entry2', 'entry1_tender'))); */
|
|
||||||
|
|
||||||
$ret = array();
|
|
||||||
if (!$this->verifyDoubleEntry($entry1, $entry2, $entry1_tender))
|
|
||||||
return array('error' => true) + $ret;
|
|
||||||
|
|
||||||
// Since this model only relates to DebitEntry and CreditEntry...
|
|
||||||
$LE = new LedgerEntry();
|
|
||||||
|
|
||||||
// Add the first ledger entry to the database
|
|
||||||
$result = $LE->addLedgerEntry($entry1, $entry1_tender);
|
|
||||||
$ret['Entry1'] = $result;
|
|
||||||
if ($result['error'])
|
|
||||||
return array('error' => true) + $ret;
|
|
||||||
|
|
||||||
// Add the second ledger entry to the database
|
|
||||||
$result = $LE->addLedgerEntry($entry2);
|
|
||||||
$ret['Entry2'] = $result;
|
|
||||||
if ($result['error'])
|
|
||||||
return array('error' => true) + $ret;
|
|
||||||
|
|
||||||
// Now link them as a double entry
|
|
||||||
$double_entry = array();
|
|
||||||
$double_entry['debit_entry_id'] =
|
|
||||||
($entry1['crdr'] === 'DEBIT') ? $ret['Entry1']['ledger_entry_id'] : $ret['Entry2']['ledger_entry_id'];
|
|
||||||
$double_entry['credit_entry_id'] =
|
|
||||||
($entry1['crdr'] === 'CREDIT') ? $ret['Entry1']['ledger_entry_id'] : $ret['Entry2']['ledger_entry_id'];
|
|
||||||
|
|
||||||
/* pr(array('DoubleEntry::addDoubleEntry' => */
|
|
||||||
/* array('checkpoint' => 'Pre-Save') */
|
|
||||||
/* + compact('double_entry'))); */
|
|
||||||
|
|
||||||
$this->create();
|
|
||||||
if (!$this->save($double_entry))
|
|
||||||
return array('error' => true) + $ret;
|
|
||||||
|
|
||||||
$ret['double_entry_id'] = $this->id;
|
|
||||||
return $ret + array('error' => false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,535 +0,0 @@
|
|||||||
<?php
|
|
||||||
class Lease extends AppModel {
|
|
||||||
|
|
||||||
var $belongsTo = array(
|
|
||||||
'LeaseType',
|
|
||||||
'Unit',
|
|
||||||
'Customer',
|
|
||||||
'LateSchedule',
|
|
||||||
);
|
|
||||||
|
|
||||||
var $hasMany = array(
|
|
||||||
'StatementEntry',
|
|
||||||
);
|
|
||||||
|
|
||||||
//var $default_log_level = array('log' => 30, 'show' => 15);
|
|
||||||
|
|
||||||
/**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
* function: securityDeposits
|
|
||||||
* - Returns an array of security deposit entries
|
|
||||||
*/
|
|
||||||
function securityDeposits($id, $query = null) {
|
|
||||||
$this->prEnter(compact('id', 'query'));
|
|
||||||
$this->queryInit($query);
|
|
||||||
|
|
||||||
$query['conditions'][] = array('StatementEntry.lease_id' => $id);
|
|
||||||
$query['conditions'][] = array('StatementEntry.account_id' =>
|
|
||||||
$this->StatementEntry->Account->securityDepositAccountID());
|
|
||||||
|
|
||||||
$set = $this->StatementEntry->reconciledSet('CHARGE', $query, false, true);
|
|
||||||
return $this->prReturn($set);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
* function: securityDepositBalance
|
|
||||||
* - Returns the balance of the lease security deposit(s)
|
|
||||||
*/
|
|
||||||
|
|
||||||
function securityDepositBalance($id, $query = null) {
|
|
||||||
$this->prEnter(compact('id', 'query'));
|
|
||||||
$this->queryInit($query);
|
|
||||||
|
|
||||||
$query['conditions'][] = array('StatementEntry.lease_id' => $id);
|
|
||||||
$query['conditions'][] = array('StatementEntry.account_id' =>
|
|
||||||
$this->StatementEntry->Account->securityDepositAccountID());
|
|
||||||
|
|
||||||
// REVISIT <AP>: 20090804
|
|
||||||
// Dilemma... how to handle security deposits used to pay
|
|
||||||
// charges on the lease, yet are not part of the lease
|
|
||||||
// security deposit(s)? For example, Lease A & Lease B,
|
|
||||||
// each with $25 Sec. Dep. Move out of Lease A, and
|
|
||||||
// promote the lease surplus to the customer. A new
|
|
||||||
// charge on Lease B for $15, which is assigned $15/$25
|
|
||||||
// from the promoted Lease A surplus. They way this
|
|
||||||
// function works at present, it will presume the $15 is
|
|
||||||
// part of the security deposit balance, and will end up
|
|
||||||
// calculating it as only $10, which is wrong. Perhaps
|
|
||||||
// the fix is to release security deposits into some sort
|
|
||||||
// of income account.
|
|
||||||
|
|
||||||
$stats = $this->StatementEntry->stats(null, $query);
|
|
||||||
return $this->prReturn($stats['account_balance']);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
* function: releaseSecurityDeposits
|
|
||||||
* - Releases all security deposits associated with this lease.
|
|
||||||
* That simply makes a disbursement out of them, which can be used
|
|
||||||
* to pay outstanding customer charges, or simply to become
|
|
||||||
* a customer surplus (customer credit).
|
|
||||||
*/
|
|
||||||
function releaseSecurityDeposits($id, $stamp = null, $query = null) {
|
|
||||||
//$this->prFunctionLevel(30);
|
|
||||||
$this->prEnter(compact('id', 'stamp', 'query'));
|
|
||||||
|
|
||||||
$secdeps = $this->securityDeposits($id, $query);
|
|
||||||
$secdeps = $secdeps['entries'];
|
|
||||||
$this->pr(20, compact('secdeps'));
|
|
||||||
|
|
||||||
// If there are no paid security deposits, then
|
|
||||||
// we can consider all security deposits released.
|
|
||||||
if (count($secdeps) == 0)
|
|
||||||
return $this->prReturn(true);
|
|
||||||
|
|
||||||
// Build a transaction
|
|
||||||
$release = array('Transaction' => array(), 'Entry' => array());
|
|
||||||
$release['Transaction']['stamp'] = $stamp;
|
|
||||||
$release['Transaction']['comment'] = "Security Deposit Release";
|
|
||||||
foreach ($secdeps AS $charge) {
|
|
||||||
if ($charge['StatementEntry']['type'] !== 'CHARGE')
|
|
||||||
die("INTERNAL ERROR: SECURITY DEPOSIT IS NOT CHARGE");
|
|
||||||
|
|
||||||
// Since security deposits are being released, this also means
|
|
||||||
// any unpaid (or only partially paid) security deposit should
|
|
||||||
// have the remaining balance reversed.
|
|
||||||
if ($charge['StatementEntry']['balance'] > 0)
|
|
||||||
$this->StatementEntry->reverse($charge['StatementEntry']['id'], true, $stamp);
|
|
||||||
|
|
||||||
$release['Entry'][] =
|
|
||||||
array('amount' => $charge['StatementEntry']['reconciled'],
|
|
||||||
'account_id' => $this->StatementEntry->Account->securityDepositAccountID(),
|
|
||||||
'comment' => "Released Security Deposit",
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
$customer_id = $secdeps[0]['StatementEntry']['customer_id'];
|
|
||||||
$lease_id = $secdeps[0]['StatementEntry']['lease_id'];
|
|
||||||
|
|
||||||
$result = $this->StatementEntry->Transaction->addReceipt
|
|
||||||
($release, $customer_id, $lease_id);
|
|
||||||
|
|
||||||
return $this->prReturn($result);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
* function: rentLastCharges
|
|
||||||
* - Returns a list of rent charges from this lease that
|
|
||||||
* do not have sequential followup charges. Under normal
|
|
||||||
* circumstances, there would only be one entry, which is
|
|
||||||
* the most recent rent charge. However, it's possible
|
|
||||||
* that there are several, indicating a problem with lease.
|
|
||||||
*/
|
|
||||||
|
|
||||||
function rentLastCharges($id) {
|
|
||||||
$this->prEnter(compact('id'));
|
|
||||||
$rent_account_id = $this->StatementEntry->Account->rentAccountID();
|
|
||||||
$entries = $this->find
|
|
||||||
('all',
|
|
||||||
array('link' =>
|
|
||||||
array(// Models
|
|
||||||
'StatementEntry',
|
|
||||||
|
|
||||||
'SEx' =>
|
|
||||||
array('class' => 'StatementEntry',
|
|
||||||
'fields' => array(),
|
|
||||||
'conditions' => array
|
|
||||||
('SEx.effective_date = DATE_ADD(StatementEntry.through_date, INTERVAL 1 day)',
|
|
||||||
'SEx.lease_id = StatementEntry.lease_id',
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
|
|
||||||
//'fields' => array('id', 'amount', 'effective_date', 'through_date'),
|
|
||||||
'fields' => array(),
|
|
||||||
'conditions' => array(array('Lease.id' => $id),
|
|
||||||
array('StatementEntry.type' => 'CHARGE'),
|
|
||||||
array('StatementEntry.account_id' => $rent_account_id),
|
|
||||||
array('SEx.id' => null),
|
|
||||||
),
|
|
||||||
)
|
|
||||||
);
|
|
||||||
|
|
||||||
return $this->prReturn($entries);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
* function: rentChargeGaps
|
|
||||||
* - Checks for gaps in rent charges
|
|
||||||
*/
|
|
||||||
|
|
||||||
function rentChargeGaps($id) {
|
|
||||||
$this->prEnter(compact('id'));
|
|
||||||
$entries = $this->rentLastCharges($id);
|
|
||||||
if ($entries && count($entries) > 1)
|
|
||||||
return $this->prReturn(true);
|
|
||||||
return $this->prReturn(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
* function: rentChargeThrough
|
|
||||||
* - Determines the date that rent has been charged through
|
|
||||||
* Returns one of:
|
|
||||||
* null: There are gaps in the charges
|
|
||||||
* false: There are not yet any charges
|
|
||||||
* date: The date rent has been charged through
|
|
||||||
*/
|
|
||||||
|
|
||||||
function rentChargeThrough($id) {
|
|
||||||
$this->prEnter(compact('id'));
|
|
||||||
$entries = $this->rentLastCharges($id);
|
|
||||||
if (!$entries)
|
|
||||||
return $this->prReturn(false);
|
|
||||||
if (count($entries) != 1)
|
|
||||||
return $this->prReturn(null);
|
|
||||||
return $this->prReturn($entries[0]['StatementEntry']['through_date']);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
* function: rentPaidThrough
|
|
||||||
* - Determines the date of the first unpaid rent
|
|
||||||
*/
|
|
||||||
|
|
||||||
function rentPaidThrough($id) {
|
|
||||||
$this->prEnter(compact('id'));
|
|
||||||
$rent_account_id = $this->StatementEntry->Account->rentAccountID();
|
|
||||||
|
|
||||||
// First, see if we can find any unpaid entries. Of course,
|
|
||||||
// the first unpaid entry gives us a very direct indication
|
|
||||||
// of when the customer is paid up through, which is 1 day
|
|
||||||
// prior to the effective date of that first unpaid charge.
|
|
||||||
$rent = $this->StatementEntry->reconciledSet
|
|
||||||
('CHARGE',
|
|
||||||
array('fields' =>
|
|
||||||
array('StatementEntry.*',
|
|
||||||
'DATE_SUB(StatementEntry.effective_date, INTERVAL 1 DAY) AS paid_through',
|
|
||||||
),
|
|
||||||
|
|
||||||
'conditions' =>
|
|
||||||
array(array('StatementEntry.lease_id' => $id),
|
|
||||||
array('StatementEntry.account_id' => $rent_account_id)),
|
|
||||||
|
|
||||||
'order' => array('StatementEntry.effective_date'),
|
|
||||||
),
|
|
||||||
true);
|
|
||||||
$this->pr(20, $rent, "Unpaid rent");
|
|
||||||
|
|
||||||
if ($rent['entries'])
|
|
||||||
return $this->prReturn($rent['entries'][0]['StatementEntry']['paid_through']);
|
|
||||||
|
|
||||||
|
|
||||||
// If we don't have any unpaid charges (great!), then the
|
|
||||||
// customer is paid up through the last day of the last
|
|
||||||
// charge. So, search for paid charges, which already
|
|
||||||
// have the paid through date saved as part of the entry.
|
|
||||||
$rent = $this->StatementEntry->reconciledSet
|
|
||||||
('CHARGE',
|
|
||||||
array('conditions' =>
|
|
||||||
array(array('StatementEntry.lease_id' => $id),
|
|
||||||
array('StatementEntry.account_id' => $rent_account_id)),
|
|
||||||
|
|
||||||
'order' => array('StatementEntry.through_date DESC'),
|
|
||||||
),
|
|
||||||
false);
|
|
||||||
$this->pr(20, $rent, "Paid rent");
|
|
||||||
|
|
||||||
if ($rent['entries'])
|
|
||||||
return $this->prReturn($rent['entries'][0]['StatementEntry']['through_date']);
|
|
||||||
|
|
||||||
|
|
||||||
// After all that, having found that there are no unpaid
|
|
||||||
// charges, and in fact, no paid charges either, we cannot
|
|
||||||
// possibly say when the customer is paid through.
|
|
||||||
return $this->prReturn(null);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
* function: moveIn
|
|
||||||
* - Moves the specified customer into the specified lease
|
|
||||||
*/
|
|
||||||
|
|
||||||
function moveIn($customer_id, $unit_id,
|
|
||||||
$deposit = null, $rent = null,
|
|
||||||
$stamp = null, $comment = null)
|
|
||||||
{
|
|
||||||
$this->prEnter(compact('customer_id', 'unit_id',
|
|
||||||
'deposit', 'rent', 'stamp', 'comment'));
|
|
||||||
|
|
||||||
$lt = $this->LeaseType->find('first',
|
|
||||||
array('conditions' =>
|
|
||||||
array('code' => 'SL')));
|
|
||||||
|
|
||||||
// Use NOW if not given a movein date
|
|
||||||
if (!isset($stamp))
|
|
||||||
$stamp = date('Y-m-d G:i:s');
|
|
||||||
|
|
||||||
if (!$comment)
|
|
||||||
$comment = null;
|
|
||||||
|
|
||||||
if (!isset($deposit) || !isset($rent)) {
|
|
||||||
$rates = $this->Unit->find
|
|
||||||
('first',
|
|
||||||
array('contain' =>
|
|
||||||
array('UnitSize' =>
|
|
||||||
array('deposit', 'rent'),
|
|
||||||
),
|
|
||||||
'fields' => array('deposit', 'rent'),
|
|
||||||
'conditions' => array('Unit.id' => $unit_id),
|
|
||||||
));
|
|
||||||
|
|
||||||
$deposit =
|
|
||||||
(isset($deposit)
|
|
||||||
? $deposit
|
|
||||||
: (isset($rates['Unit']['deposit'])
|
|
||||||
? $rates['Unit']['deposit']
|
|
||||||
: (isset($rates['UnitSize']['deposit'])
|
|
||||||
? $rates['UnitSize']['deposit']
|
|
||||||
: 0)));
|
|
||||||
|
|
||||||
$rent =
|
|
||||||
(isset($rent)
|
|
||||||
? $rent
|
|
||||||
: (isset($rates['Unit']['rent'])
|
|
||||||
? $rates['Unit']['rent']
|
|
||||||
: (isset($rates['UnitSize']['rent'])
|
|
||||||
? $rates['UnitSize']['rent']
|
|
||||||
: 0)));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Save this new lease.
|
|
||||||
$this->create();
|
|
||||||
if (!$this->save(array('lease_type_id' => $lt['LeaseType']['id'],
|
|
||||||
'unit_id' => $unit_id,
|
|
||||||
'customer_id' => $customer_id,
|
|
||||||
'lease_date' => $stamp,
|
|
||||||
'movein_date' => $stamp,
|
|
||||||
'deposit' => $deposit,
|
|
||||||
'rent' => $rent,
|
|
||||||
'comment' => $comment), false)) {
|
|
||||||
return $this->prReturn(null);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set the lease number to be the same as the lease ID
|
|
||||||
$this->id;
|
|
||||||
$this->saveField('number', $this->id);
|
|
||||||
|
|
||||||
// Update the current lease count for the customer
|
|
||||||
$this->Customer->updateLeaseCount($customer_id);
|
|
||||||
|
|
||||||
// Update the unit status
|
|
||||||
$this->Unit->updateStatus($unit_id, 'OCCUPIED');
|
|
||||||
|
|
||||||
// REVISIT <AP>: 20090702
|
|
||||||
// We need to assess the security deposit charge,
|
|
||||||
// and probably rent as well. Rent, however, will
|
|
||||||
// require user parameters to indicate whether it
|
|
||||||
// was waived, pro-rated, etc.
|
|
||||||
|
|
||||||
// Return the new lease ID
|
|
||||||
return $this->prReturn($this->id);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
* function: moveOut
|
|
||||||
* - Moves the customer out of the specified lease
|
|
||||||
*/
|
|
||||||
|
|
||||||
function moveOut($id, $status = 'VACANT',
|
|
||||||
$stamp = null, $close = false)
|
|
||||||
{
|
|
||||||
$this->prEnter(compact('id', 'status', 'stamp', 'close'));
|
|
||||||
|
|
||||||
// Use NOW if not given a moveout date
|
|
||||||
if (!isset($stamp))
|
|
||||||
$stamp = date('Y-m-d G:i:s');
|
|
||||||
|
|
||||||
// Reset the data
|
|
||||||
$this->create();
|
|
||||||
$this->id = $id;
|
|
||||||
|
|
||||||
// Set the customer move-out date
|
|
||||||
$this->data['Lease']['moveout_date'] = $stamp;
|
|
||||||
|
|
||||||
// Save it!
|
|
||||||
$this->save($this->data, false);
|
|
||||||
|
|
||||||
// Release the security deposit(s)
|
|
||||||
$this->releaseSecurityDeposits($id, $stamp);
|
|
||||||
|
|
||||||
// Close the lease, if so requested
|
|
||||||
if ($close)
|
|
||||||
$this->close($id, $stamp);
|
|
||||||
|
|
||||||
// Update the current lease count for the customer
|
|
||||||
$this->Customer->updateLeaseCount($this->field('customer_id'));
|
|
||||||
|
|
||||||
// Finally, update the unit status
|
|
||||||
$this->recursive = -1;
|
|
||||||
$this->read();
|
|
||||||
$this->Unit->updateStatus($this->data['Lease']['unit_id'], $status);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
* function: close
|
|
||||||
* - Closes the lease to further action
|
|
||||||
*/
|
|
||||||
|
|
||||||
function close($id, $stamp = null) {
|
|
||||||
$this->prEnter(compact('id', 'stamp'));
|
|
||||||
|
|
||||||
if (!$this->closeable($id))
|
|
||||||
return $this->prReturn(false);
|
|
||||||
|
|
||||||
// Reset the data
|
|
||||||
$this->create();
|
|
||||||
$this->id = $id;
|
|
||||||
|
|
||||||
// Use NOW if not given a moveout date
|
|
||||||
if (!isset($stamp))
|
|
||||||
$stamp = date('Y-m-d G:i:s');
|
|
||||||
|
|
||||||
// Set the close date
|
|
||||||
$this->data['Lease']['close_date'] = $stamp;
|
|
||||||
|
|
||||||
// Save it!
|
|
||||||
$this->save($this->data, false);
|
|
||||||
|
|
||||||
// Update the current lease count for the customer
|
|
||||||
$this->Customer->updateLeaseCount($this->field('customer_id'));
|
|
||||||
|
|
||||||
return $this->prReturn(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
* function: closeable
|
|
||||||
* - Indicates whether or not the lease can be closed
|
|
||||||
*/
|
|
||||||
|
|
||||||
function closeable($id) {
|
|
||||||
$this->prEnter(compact('id'));
|
|
||||||
|
|
||||||
$this->recursive = -1;
|
|
||||||
$this->read(null, $id);
|
|
||||||
|
|
||||||
// We can't close a lease that's still in use
|
|
||||||
if (!isset($this->data['Lease']['moveout_date']))
|
|
||||||
return $this->prReturn(false);
|
|
||||||
|
|
||||||
// We can't close a lease that's already closed
|
|
||||||
if (isset($this->data['Lease']['close_date']))
|
|
||||||
return $this->prReturn(false);
|
|
||||||
|
|
||||||
$deposit_balance = $this->securityDepositBalance($id);
|
|
||||||
$stats = $this->stats($id);
|
|
||||||
|
|
||||||
// A lease can only be closed if there are no outstanding
|
|
||||||
// security deposits, and if the account balance is zero.
|
|
||||||
if ($deposit_balance != 0)
|
|
||||||
return $this->prReturn(false);
|
|
||||||
|
|
||||||
// Apparently this lease meets all the criteria!
|
|
||||||
return $this->prReturn(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
* function: refund
|
|
||||||
* - Marks any lease balance as payable to the customer.
|
|
||||||
*/
|
|
||||||
|
|
||||||
function refund($id, $stamp = null) {
|
|
||||||
$this->prEnter(compact('id'));
|
|
||||||
$balance = $this->balance($id);
|
|
||||||
|
|
||||||
if ($balance >= 0)
|
|
||||||
return $this->prReturn(array('error' => true));
|
|
||||||
|
|
||||||
$balance *= -1;
|
|
||||||
|
|
||||||
// Build a transaction
|
|
||||||
$refund = array('Transaction' => array(), 'Entry' => array());
|
|
||||||
$refund['Transaction']['stamp'] = $stamp;
|
|
||||||
$refund['Transaction']['comment'] = "Lease Refund";
|
|
||||||
|
|
||||||
$refund['Entry'][] =
|
|
||||||
array('amount' => $balance);
|
|
||||||
|
|
||||||
$result = $this->StatementEntry->Transaction->addRefund
|
|
||||||
($refund, null, $id);
|
|
||||||
|
|
||||||
return $this->prReturn($result);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
* function: balance
|
|
||||||
* - Returns the balance of money owed on the lease
|
|
||||||
*/
|
|
||||||
|
|
||||||
function balance($id) {
|
|
||||||
$this->prEnter(compact('id'));
|
|
||||||
$stats = $this->stats($id);
|
|
||||||
return $this->prReturn($stats['balance']);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
* function: stats
|
|
||||||
* - Returns summary data from the requested lease.
|
|
||||||
*/
|
|
||||||
|
|
||||||
function stats($id = null, $query = null) {
|
|
||||||
$this->prEnter(compact('id', 'query'));
|
|
||||||
if (!$id)
|
|
||||||
return $this->prReturn(null);
|
|
||||||
|
|
||||||
$find_stats = $this->StatementEntry->find
|
|
||||||
('first', array
|
|
||||||
('contain' => false,
|
|
||||||
'fields' => $this->StatementEntry->chargeDisbursementFields(true),
|
|
||||||
'conditions' => array('StatementEntry.lease_id' => $id),
|
|
||||||
));
|
|
||||||
$find_stats = $find_stats[0];
|
|
||||||
return $this->prReturn($find_stats);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
?>
|
|
||||||
@@ -1,15 +0,0 @@
|
|||||||
<?php
|
|
||||||
class LeaseType extends AppModel {
|
|
||||||
|
|
||||||
var $name = 'LeaseType';
|
|
||||||
var $validate = array(
|
|
||||||
'id' => array('numeric'),
|
|
||||||
'name' => array('notempty')
|
|
||||||
);
|
|
||||||
|
|
||||||
var $hasMany = array(
|
|
||||||
'Lease',
|
|
||||||
);
|
|
||||||
|
|
||||||
}
|
|
||||||
?>
|
|
||||||
@@ -1,179 +0,0 @@
|
|||||||
<?php
|
|
||||||
class Ledger extends AppModel {
|
|
||||||
|
|
||||||
var $belongsTo = array(
|
|
||||||
'Account',
|
|
||||||
'PriorLedger' => array('className' => 'Ledger'),
|
|
||||||
'CloseTransaction' => array('className' => 'Transaction'),
|
|
||||||
);
|
|
||||||
|
|
||||||
var $hasMany = array(
|
|
||||||
'Transaction',
|
|
||||||
'LedgerEntry',
|
|
||||||
);
|
|
||||||
|
|
||||||
|
|
||||||
/**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
* function: accountID
|
|
||||||
* - Returns the account ID for the given ledger
|
|
||||||
*/
|
|
||||||
function accountID($id) {
|
|
||||||
$this->cacheQueries = true;
|
|
||||||
$item = $this->find('first', array
|
|
||||||
('link' => array('Account'),
|
|
||||||
'conditions' => array('Ledger.id' => $id),
|
|
||||||
));
|
|
||||||
$this->cacheQueries = false;
|
|
||||||
//pr(compact('id', 'item'));
|
|
||||||
return $item['Account']['id'];
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
* function: currentLedgerID
|
|
||||||
* - Returns the current ledger ID of the account for the given ledger.
|
|
||||||
*/
|
|
||||||
function currentLedgerID($id) {
|
|
||||||
return $this->Account->currentLedgerID($this->accountID($id));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
* function: closeLedger
|
|
||||||
* - Closes the current ledger, and returns a fresh one
|
|
||||||
*/
|
|
||||||
function closeLedgers($ids) {
|
|
||||||
$ret = array('new_ledger_ids' => array());
|
|
||||||
|
|
||||||
$entries = array();
|
|
||||||
foreach ($ids AS $id) {
|
|
||||||
// Query stats to get the balance forward
|
|
||||||
$stats = $this->stats($id);
|
|
||||||
|
|
||||||
// Populate fields from the current ledger
|
|
||||||
$this->recursive = -1;
|
|
||||||
$this->id = $id;
|
|
||||||
$this->read();
|
|
||||||
|
|
||||||
// Build a new ledger to replace the current one
|
|
||||||
$this->data['Ledger']['id'] = null;
|
|
||||||
$this->data['Ledger']['close_transaction_id'] = null;
|
|
||||||
$this->data['Ledger']['prior_ledger_id'] = $id;
|
|
||||||
$this->data['Ledger']['comment'] = null;
|
|
||||||
++$this->data['Ledger']['sequence'];
|
|
||||||
$this->data['Ledger']['name'] =
|
|
||||||
($this->data['Ledger']['account_id'] .
|
|
||||||
'-' .
|
|
||||||
$this->data['Ledger']['sequence']);
|
|
||||||
|
|
||||||
// Save the new ledger
|
|
||||||
$this->id = null;
|
|
||||||
if (!$this->save($this->data, false))
|
|
||||||
return array('error' => true, 'new_ledger_data' => $this->data) + $ret;
|
|
||||||
$ret['new_ledger_ids'][] = $this->id;
|
|
||||||
|
|
||||||
$entries[] = array('old_ledger_id' => $id,
|
|
||||||
'new_ledger_id' => $this->id,
|
|
||||||
'amount' => $stats['balance']);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Perform the close
|
|
||||||
$result = $this->Transaction->addClose(array('Transaction' => array(),
|
|
||||||
'Ledger' => $entries));
|
|
||||||
$ret['Transaction'] = $result;
|
|
||||||
if ($result['error'])
|
|
||||||
return array('error' => true) + $ret;
|
|
||||||
|
|
||||||
return $ret + array('error' => false);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
* function: debitCreditFields
|
|
||||||
* - Returns the fields necessary to determine whether the queried
|
|
||||||
* entries are a debit, or a credit, and also the effect each have
|
|
||||||
* on the overall balance of the ledger.
|
|
||||||
*/
|
|
||||||
function debitCreditFields($sum = false, $balance = true,
|
|
||||||
$entry_name = 'LedgerEntry', $account_name = 'Account') {
|
|
||||||
return $this->LedgerEntry->debitCreditFields
|
|
||||||
($sum, $balance, $entry_name, $account_name);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
* function: ledgerEntries
|
|
||||||
* - Returns an array of ledger entries that belong to a given
|
|
||||||
* ledger. There is extra work done to establish debit/credit
|
|
||||||
*/
|
|
||||||
function ledgerEntries($ids, $query = null) {
|
|
||||||
if (empty($ids))
|
|
||||||
return null;
|
|
||||||
|
|
||||||
$entries = $this->LedgerEntry->find
|
|
||||||
('all', array
|
|
||||||
('link' => array('Ledger' => array('Account')),
|
|
||||||
'fields' => array_merge(array("LedgerEntry.*"),
|
|
||||||
$this->LedgerEntry->debitCreditFields()),
|
|
||||||
'conditions' => array('LedgerEntry.ledger_id' => $ids),
|
|
||||||
));
|
|
||||||
|
|
||||||
//pr(compact('entries'));
|
|
||||||
return $entries;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
* function: stats
|
|
||||||
* - Returns summary data from the requested ledger.
|
|
||||||
*/
|
|
||||||
function stats($id, $query = null) {
|
|
||||||
if (!$id)
|
|
||||||
return null;
|
|
||||||
|
|
||||||
$this->queryInit($query);
|
|
||||||
|
|
||||||
if (!isset($query['link']['Account']))
|
|
||||||
$query['link']['Account'] = array();
|
|
||||||
if (!isset($query['link']['Account']['fields']))
|
|
||||||
$query['link']['Account']['fields'] = array();
|
|
||||||
if (!isset($query['fields']))
|
|
||||||
$query['fields'] = array();
|
|
||||||
|
|
||||||
$query['fields'] = array_merge($query['fields'],
|
|
||||||
$this->debitCreditFields(true));
|
|
||||||
|
|
||||||
$query['conditions'][] = array('LedgerEntry.ledger_id' => $id);
|
|
||||||
$query['group'][] = 'LedgerEntry.ledger_id';
|
|
||||||
|
|
||||||
$stats = $this->LedgerEntry->find('first', $query);
|
|
||||||
|
|
||||||
// The fields are all tucked into the [0] index,
|
|
||||||
// and the rest of the array is useless (empty).
|
|
||||||
$stats = $stats[0];
|
|
||||||
|
|
||||||
// Make sure we have a member for debit/credit
|
|
||||||
foreach(array('debits', 'credits') AS $crdr)
|
|
||||||
if (!isset($stats[$crdr]))
|
|
||||||
$stats[$crdr] = null;
|
|
||||||
|
|
||||||
// Make sure we have a non-null balance
|
|
||||||
if (!isset($stats['balance']))
|
|
||||||
$stats['balance'] = 0;
|
|
||||||
|
|
||||||
return $stats;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
?>
|
|
||||||
@@ -1,207 +0,0 @@
|
|||||||
<?php
|
|
||||||
class LedgerEntry extends AppModel {
|
|
||||||
|
|
||||||
var $belongsTo = array(
|
|
||||||
'Transaction',
|
|
||||||
'Account',
|
|
||||||
'Ledger',
|
|
||||||
);
|
|
||||||
|
|
||||||
var $hasOne = array(
|
|
||||||
'Tender',
|
|
||||||
'DoubleEntry',
|
|
||||||
);
|
|
||||||
|
|
||||||
var $hasMany = array(
|
|
||||||
);
|
|
||||||
|
|
||||||
var $hasAndBelongsToMany = array(
|
|
||||||
// The Debit half of the double entry matching THIS Credit (if it is one)
|
|
||||||
'DebitEntry' => array(
|
|
||||||
'className' => 'LedgerEntry',
|
|
||||||
'joinTable' => 'double_entries',
|
|
||||||
'linkalias' => 'DDE',
|
|
||||||
'foreignKey' => 'credit_entry_id',
|
|
||||||
'associationForeignKey' => 'debit_entry_id',
|
|
||||||
),
|
|
||||||
|
|
||||||
// The Credit half of the double entry matching THIS Debit (if it is one)
|
|
||||||
'CreditEntry' => array(
|
|
||||||
'className' => 'LedgerEntry',
|
|
||||||
'joinTable' => 'double_entries',
|
|
||||||
'linkalias' => 'CDE',
|
|
||||||
'foreignKey' => 'debit_entry_id',
|
|
||||||
'associationForeignKey' => 'credit_entry_id',
|
|
||||||
),
|
|
||||||
);
|
|
||||||
|
|
||||||
|
|
||||||
/**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
* function: debitCreditFields
|
|
||||||
* - Returns the fields necessary to determine whether the queried
|
|
||||||
* entries are a debit, or a credit, and also the effect each have
|
|
||||||
* on the overall balance of the account/ledger.
|
|
||||||
*/
|
|
||||||
|
|
||||||
function debitCreditFields($sum = false, $balance = true,
|
|
||||||
$entry_name = 'LedgerEntry', $account_name = 'Account') {
|
|
||||||
$fields = array
|
|
||||||
(
|
|
||||||
($sum ? 'SUM(' : '') .
|
|
||||||
"IF({$entry_name}.crdr = 'DEBIT'," .
|
|
||||||
" {$entry_name}.amount, NULL)" .
|
|
||||||
($sum ? ')' : '') . ' AS debit' . ($sum ? 's' : ''),
|
|
||||||
|
|
||||||
($sum ? 'SUM(' : '') .
|
|
||||||
"IF({$entry_name}.crdr = 'CREDIT'," .
|
|
||||||
" {$entry_name}.amount, NULL)" .
|
|
||||||
($sum ? ')' : '') . ' AS credit' . ($sum ? 's' : ''),
|
|
||||||
);
|
|
||||||
|
|
||||||
if ($balance)
|
|
||||||
$fields[] =
|
|
||||||
($sum ? 'SUM(' : '') .
|
|
||||||
"IF(${account_name}.type IN ('ASSET', 'EXPENSE')," .
|
|
||||||
" IF({$entry_name}.crdr = 'DEBIT', 1, -1)," .
|
|
||||||
" IF({$entry_name}.crdr = 'CREDIT', 1, -1))" .
|
|
||||||
" * IF({$entry_name}.amount, {$entry_name}.amount, 0)" .
|
|
||||||
($sum ? ')' : '') . ' AS balance';
|
|
||||||
|
|
||||||
if ($sum)
|
|
||||||
$fields[] = "COUNT({$entry_name}.id) AS entries";
|
|
||||||
|
|
||||||
return $fields;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
* function: verifyLedgerEntry
|
|
||||||
* - Verifies consistenty of new ledger entry data
|
|
||||||
* (not in a pre-existing ledger entry)
|
|
||||||
*/
|
|
||||||
function verifyLedgerEntry($entry, $tender = null) {
|
|
||||||
/* pr(array("LedgerEntry::verifyLedgerEntry()" */
|
|
||||||
/* => compact('entry', 'tender'))); */
|
|
||||||
|
|
||||||
if (empty($entry['account_id']) ||
|
|
||||||
empty($entry['crdr']) ||
|
|
||||||
empty($entry['amount'])
|
|
||||||
) {
|
|
||||||
/* pr(array("LedgerEntry::verifyLedgerEntry()" */
|
|
||||||
/* => "Entry verification failed")); */
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isset($tender) && !$this->Tender->verifyTender($tender)) {
|
|
||||||
/* pr(array("LedgerEntry::verifyLedgerEntry()" */
|
|
||||||
/* => "Tender verification failed")); */
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
* function: addLedgerEntry
|
|
||||||
* - Inserts new Ledger Entry into the database
|
|
||||||
*/
|
|
||||||
function addLedgerEntry($entry, $tender = null) {
|
|
||||||
/* pr(array('LedgerEntry::addLedgerEntry' => */
|
|
||||||
/* compact('entry', 'tender'))); */
|
|
||||||
|
|
||||||
$ret = array();
|
|
||||||
if (!$this->verifyLedgerEntry($entry, $tender))
|
|
||||||
return array('error' => true) + $ret;
|
|
||||||
|
|
||||||
if (empty($entry['ledger_id']))
|
|
||||||
$entry['ledger_id'] =
|
|
||||||
$this->Account->currentLedgerID($entry['account_id']);
|
|
||||||
|
|
||||||
/* pr(array('LedgerEntry::addLedgerEntry' => */
|
|
||||||
/* array('checkpoint' => 'Pre-Save') */
|
|
||||||
/* + compact('entry'))); */
|
|
||||||
|
|
||||||
$this->create();
|
|
||||||
if (!$this->save($entry))
|
|
||||||
return array('error' => true) + $ret;
|
|
||||||
|
|
||||||
$ret['ledger_entry_id'] = $this->id;
|
|
||||||
|
|
||||||
if (isset($tender)) {
|
|
||||||
$tender['account_id'] = $entry['account_id'];
|
|
||||||
$tender['ledger_entry_id'] = $ret['ledger_entry_id'];
|
|
||||||
$result = $this->Tender->addTender($tender);
|
|
||||||
$ret['Tender'] = $result;
|
|
||||||
if ($result['error'])
|
|
||||||
return array('error' => true) + $ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
return $ret + array('error' => false);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
* function: stats
|
|
||||||
* - Returns summary data from the requested ledger entry
|
|
||||||
*/
|
|
||||||
function stats($id = null, $query = null, $set = null) {
|
|
||||||
$this->queryInit($query);
|
|
||||||
unset($query['group']);
|
|
||||||
|
|
||||||
if (!isset($query['link']['DoubleEntry']))
|
|
||||||
$query['link']['DoubleEntry'] = array();
|
|
||||||
/* if (!isset($query['link']['DoubleEntry']['fields'])) */
|
|
||||||
/* $query['link']['DoubleEntry']['fields'] = array(); */
|
|
||||||
|
|
||||||
if (isset($id))
|
|
||||||
$query['conditions'][] = array('Entry.id' => $id);
|
|
||||||
|
|
||||||
if (isset($set))
|
|
||||||
$set = strtoupper($set);
|
|
||||||
|
|
||||||
//pr(array('stats()', compact('id', 'query', 'set')));
|
|
||||||
|
|
||||||
$rtypes = array('charge', 'disbursement',
|
|
||||||
// 'debit', 'credit',
|
|
||||||
);
|
|
||||||
|
|
||||||
$stats = array();
|
|
||||||
foreach($rtypes AS $rtype) {
|
|
||||||
$Rtype = ucfirst($rtype);
|
|
||||||
|
|
||||||
if (($rtype == 'charge' && (!isset($set) || $set == 'DISBURSEMENT')) ||
|
|
||||||
($rtype == 'disbursement' && (!isset($set) || $set == 'CHARGE'))
|
|
||||||
) {
|
|
||||||
|
|
||||||
$rquery = $query;
|
|
||||||
$rquery['link'][$Rtype] =
|
|
||||||
array('fields' => array("SUM(COALESCE(Applied{$Rtype}.amount,0)) AS reconciled"));
|
|
||||||
|
|
||||||
$rquery['fields'] = array();
|
|
||||||
//$rquery['fields'][] = "SUM(DoubleEntry.amount) AS total";
|
|
||||||
$rquery['fields'][] = "SUM(DoubleEntry.amount) - SUM(COALESCE(Applied{$Rtype}.amount,0)) AS balance";
|
|
||||||
$rquery['conditions'][] = array("Applied{$Rtype}.id !=" => null);
|
|
||||||
|
|
||||||
$result = $this->find('first', $rquery);
|
|
||||||
//pr(compact('Rtype', 'rquery', 'result'));
|
|
||||||
|
|
||||||
$sumfld = $Rtype;
|
|
||||||
$stats[$sumfld] = $result[0];
|
|
||||||
/* if (!isset($stats[$sumfld]['applied'])) */
|
|
||||||
/* $stats[$sumfld]['applied'] = 0; */
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return $stats;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,23 +0,0 @@
|
|||||||
<?php
|
|
||||||
class Map extends AppModel {
|
|
||||||
|
|
||||||
var $name = 'Map';
|
|
||||||
var $validate = array(
|
|
||||||
'id' => array('numeric'),
|
|
||||||
'site_id' => array('numeric'),
|
|
||||||
'site_area_id' => array('numeric'),
|
|
||||||
'name' => array('notempty'),
|
|
||||||
'width' => array('numeric'),
|
|
||||||
'depth' => array('numeric')
|
|
||||||
);
|
|
||||||
|
|
||||||
var $belongsTo = array(
|
|
||||||
'SiteArea',
|
|
||||||
);
|
|
||||||
|
|
||||||
var $hasAndBelongsToMany = array(
|
|
||||||
'Unit',
|
|
||||||
);
|
|
||||||
|
|
||||||
}
|
|
||||||
?>
|
|
||||||
@@ -1,16 +0,0 @@
|
|||||||
<?php
|
|
||||||
class Site extends AppModel {
|
|
||||||
|
|
||||||
var $name = 'Site';
|
|
||||||
var $validate = array(
|
|
||||||
'id' => array('numeric'),
|
|
||||||
'name' => array('notempty')
|
|
||||||
);
|
|
||||||
|
|
||||||
var $hasMany = array(
|
|
||||||
'SiteArea',
|
|
||||||
'SiteOption',
|
|
||||||
);
|
|
||||||
|
|
||||||
}
|
|
||||||
?>
|
|
||||||
@@ -1,20 +0,0 @@
|
|||||||
<?php
|
|
||||||
class SiteArea extends AppModel {
|
|
||||||
|
|
||||||
var $name = 'SiteArea';
|
|
||||||
var $validate = array(
|
|
||||||
'id' => array('numeric'),
|
|
||||||
'site_id' => array('numeric'),
|
|
||||||
'name' => array('notempty')
|
|
||||||
);
|
|
||||||
|
|
||||||
var $belongsTo = array(
|
|
||||||
'Site',
|
|
||||||
);
|
|
||||||
|
|
||||||
var $hasOne = array(
|
|
||||||
'Map',
|
|
||||||
);
|
|
||||||
|
|
||||||
}
|
|
||||||
?>
|
|
||||||
@@ -1,733 +0,0 @@
|
|||||||
<?php
|
|
||||||
class StatementEntry extends AppModel {
|
|
||||||
|
|
||||||
var $belongsTo = array(
|
|
||||||
'Transaction',
|
|
||||||
'Customer',
|
|
||||||
'Lease',
|
|
||||||
'Account',
|
|
||||||
|
|
||||||
// The charge to which this disbursement applies (if it is one)
|
|
||||||
'ChargeEntry' => array(
|
|
||||||
'className' => 'StatementEntry',
|
|
||||||
),
|
|
||||||
);
|
|
||||||
|
|
||||||
var $hasMany = array(
|
|
||||||
// The disbursements that apply to this charge (if it is one)
|
|
||||||
'DisbursementEntry' => array(
|
|
||||||
'className' => 'StatementEntry',
|
|
||||||
'foreignKey' => 'charge_entry_id',
|
|
||||||
),
|
|
||||||
|
|
||||||
);
|
|
||||||
|
|
||||||
//var $default_log_level = array('log' => 30, 'show' => 15);
|
|
||||||
|
|
||||||
/**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
* function: debit/creditTypes
|
|
||||||
*/
|
|
||||||
|
|
||||||
function debitTypes() {
|
|
||||||
return array('CHARGE', 'PAYMENT', 'REFUND');
|
|
||||||
}
|
|
||||||
|
|
||||||
function creditTypes() {
|
|
||||||
return array('DISBURSEMENT', 'WAIVER', 'REVERSAL', 'SURPLUS');
|
|
||||||
}
|
|
||||||
|
|
||||||
function voidTypes() {
|
|
||||||
return array('VOID');
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
* function: chargeDisbursementFields
|
|
||||||
*/
|
|
||||||
|
|
||||||
function chargeDisbursementFields($sum = false, $entry_name = 'StatementEntry') {
|
|
||||||
$debits = $this->debitTypes();
|
|
||||||
$credits = $this->creditTypes();
|
|
||||||
$voids = $this->voidTypes();
|
|
||||||
|
|
||||||
foreach ($debits AS &$enum)
|
|
||||||
$enum = "'" . $enum . "'";
|
|
||||||
foreach ($credits AS &$enum)
|
|
||||||
$enum = "'" . $enum . "'";
|
|
||||||
foreach ($voids AS &$enum)
|
|
||||||
$enum = "'" . $enum . "'";
|
|
||||||
|
|
||||||
$debit_set = implode(", ", $debits);
|
|
||||||
$credit_set = implode(", ", $credits);
|
|
||||||
$void_set = implode(", ", $voids);
|
|
||||||
|
|
||||||
$fields = array
|
|
||||||
(
|
|
||||||
($sum ? 'SUM(' : '') .
|
|
||||||
"IF({$entry_name}.type IN ({$debit_set})," .
|
|
||||||
" {$entry_name}.amount, NULL)" .
|
|
||||||
($sum ? ')' : '') . ' AS charge' . ($sum ? 's' : ''),
|
|
||||||
|
|
||||||
($sum ? 'SUM(' : '') .
|
|
||||||
"IF({$entry_name}.type IN({$credit_set})," .
|
|
||||||
" {$entry_name}.amount, NULL)" .
|
|
||||||
($sum ? ')' : '') . ' AS disbursement' . ($sum ? 's' : ''),
|
|
||||||
|
|
||||||
($sum ? 'SUM(' : '') .
|
|
||||||
"IF({$entry_name}.type IN ({$debit_set}), 1," .
|
|
||||||
" IF({$entry_name}.type IN ({$credit_set}), -1, 0))" .
|
|
||||||
" * IF({$entry_name}.amount, {$entry_name}.amount, 0)" .
|
|
||||||
($sum ? ')' : '') . ' AS balance',
|
|
||||||
);
|
|
||||||
|
|
||||||
if ($sum)
|
|
||||||
$fields[] = "COUNT({$entry_name}.id) AS entries";
|
|
||||||
|
|
||||||
return $fields;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
* function: verifyStatementEntry
|
|
||||||
* - Verifies consistenty of new statement entry data
|
|
||||||
* (not in a pre-existing statement entry)
|
|
||||||
*/
|
|
||||||
function verifyStatementEntry($entry) {
|
|
||||||
$this->prFunctionLevel(10);
|
|
||||||
$this->prEnter(compact('entry'));
|
|
||||||
|
|
||||||
if (empty($entry['type']) ||
|
|
||||||
//empty($entry['effective_date']) ||
|
|
||||||
empty($entry['account_id']) ||
|
|
||||||
empty($entry['amount'])
|
|
||||||
) {
|
|
||||||
return $this->prReturn(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
return $this->prReturn(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
* function: addStatementEntry
|
|
||||||
* - Inserts new Statement Entry into the database
|
|
||||||
*/
|
|
||||||
function addStatementEntry($entry) {
|
|
||||||
$this->prEnter(compact('entry'));
|
|
||||||
|
|
||||||
$ret = array();
|
|
||||||
if (!$this->verifyStatementEntry($entry))
|
|
||||||
return array('error' => true, 'verify_data' => $entry) + $ret;
|
|
||||||
|
|
||||||
$this->pr(20, array('checkpoint' => 'Pre-Save')
|
|
||||||
+ compact('entry'));
|
|
||||||
|
|
||||||
$this->create();
|
|
||||||
if (!$this->save($entry))
|
|
||||||
return array('error' => true, 'save_data' => $entry) + $ret;
|
|
||||||
|
|
||||||
$ret['statement_entry_id'] = $this->id;
|
|
||||||
return $this->prReturn($ret + array('error' => false));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
* function: waive
|
|
||||||
* - Waives the charge balance
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
function waive($id, $stamp = null) {
|
|
||||||
$this->prEnter(compact('id', 'stamp'));
|
|
||||||
|
|
||||||
// Get the basic information about the entry to be waived.
|
|
||||||
$this->recursive = -1;
|
|
||||||
$charge = $this->read(null, $id);
|
|
||||||
$charge = $charge['StatementEntry'];
|
|
||||||
|
|
||||||
if ($charge['type'] !== 'CHARGE')
|
|
||||||
INTERNAL_ERROR("Waiver item is not CHARGE.");
|
|
||||||
|
|
||||||
// Query the stats to get the remaining balance
|
|
||||||
$stats = $this->stats($id);
|
|
||||||
|
|
||||||
// Build a transaction
|
|
||||||
$waiver = array('Transaction' => array(), 'Entry' => array());
|
|
||||||
$waiver['Transaction']['stamp'] = $stamp;
|
|
||||||
$waiver['Transaction']['comment'] = "Charge Waiver";
|
|
||||||
|
|
||||||
// Add the charge waiver
|
|
||||||
$waiver['Entry'][] =
|
|
||||||
array('amount' => $stats['Charge']['balance'],
|
|
||||||
'account_id' => $this->Account->waiverAccountID(),
|
|
||||||
'comment' => null,
|
|
||||||
);
|
|
||||||
|
|
||||||
// Record the waiver transaction
|
|
||||||
return $this->prReturn($this->Transaction->addWaiver
|
|
||||||
($waiver, $id, $charge['customer_id'], $charge['lease_id']));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
* function: reverse
|
|
||||||
* - Reverses the charges
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
function reverse($id, $balance = false, $stamp = null) {
|
|
||||||
$this->prEnter(compact('id', 'balance', 'stamp'));
|
|
||||||
|
|
||||||
$ret = array();
|
|
||||||
|
|
||||||
// Get the basic information about the entry to be reversed.
|
|
||||||
$this->recursive = -1;
|
|
||||||
$charge = $this->read(null, $id);
|
|
||||||
$charge = $charge['StatementEntry'];
|
|
||||||
|
|
||||||
if ($charge['type'] !== 'CHARGE')
|
|
||||||
INTERNAL_ERROR("Reversal item is not CHARGE.");
|
|
||||||
|
|
||||||
$voided_entry_transactions = array();
|
|
||||||
$reconciled = $this->reconciledEntries($id);
|
|
||||||
$this->pr(21, compact('reconciled'));
|
|
||||||
|
|
||||||
if ($reconciled && !$balance) {
|
|
||||||
foreach ($reconciled['entries'] AS $entry) {
|
|
||||||
if ($entry['DisbursementEntry']['type'] === 'REVERSAL')
|
|
||||||
INTERNAL_ERROR("Charge has already been reversed");
|
|
||||||
|
|
||||||
$voided_entry_transactions[$entry['DisbursementEntry']['transaction_id']]
|
|
||||||
= array_intersect_key($entry['DisbursementEntry'],
|
|
||||||
array('customer_id'=>1, 'lease_id'=>1));
|
|
||||||
|
|
||||||
$this->del($entry['DisbursementEntry']['id']);
|
|
||||||
continue;
|
|
||||||
|
|
||||||
$DE = new StatementEntry();
|
|
||||||
$DE->id = $entry['DisbursementEntry']['id'];
|
|
||||||
$DE->saveField('type', 'VOID');
|
|
||||||
$DE->saveField('charge_entry_id', null);
|
|
||||||
}
|
|
||||||
$this->pr(17, compact('voided_entry_transactions'));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Query the stats to get the remaining balance
|
|
||||||
$stats = $this->stats($id);
|
|
||||||
|
|
||||||
// Build a transaction
|
|
||||||
$reversal = array('Transaction' => array(), 'Entry' => array());
|
|
||||||
$reversal['Transaction']['stamp'] = $stamp;
|
|
||||||
$reversal['Transaction']['comment'] = "Credit Note: Charge Reversal";
|
|
||||||
|
|
||||||
// Add the charge reversal
|
|
||||||
$reversal['Entry'][] =
|
|
||||||
array('amount' => $stats['Charge']['balance'],
|
|
||||||
'account_id' => $charge['account_id'],
|
|
||||||
'comment' => 'Charge Reversal',
|
|
||||||
);
|
|
||||||
|
|
||||||
// Record the reversal transaction
|
|
||||||
$result = $this->Transaction->addReversal
|
|
||||||
($reversal, $id, $charge['customer_id'], $charge['lease_id']);
|
|
||||||
$this->pr(21, compact('result'));
|
|
||||||
$ret['reversal'] = $result;
|
|
||||||
if ($result['error'])
|
|
||||||
$ret['error'] = true;
|
|
||||||
|
|
||||||
foreach ($voided_entry_transactions AS $transaction_id => $tx) {
|
|
||||||
$result = $this->assignCredits
|
|
||||||
(null,
|
|
||||||
$transaction_id,
|
|
||||||
null,
|
|
||||||
null,
|
|
||||||
$tx['customer_id'],
|
|
||||||
$tx['lease_id']
|
|
||||||
);
|
|
||||||
$this->pr(21, compact('result'));
|
|
||||||
$ret['assigned'][] = $result;
|
|
||||||
if ($result['error'])
|
|
||||||
$ret['error'] = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return $this->prReturn($ret + array('error' => false));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
* function: reconciledSet
|
|
||||||
* - Returns the set of entries satisfying the given conditions,
|
|
||||||
* along with any entries that they reconcile
|
|
||||||
*/
|
|
||||||
function reconciledSetQuery($set, $query) {
|
|
||||||
$this->queryInit($query);
|
|
||||||
|
|
||||||
if (in_array($set, $this->debitTypes()))
|
|
||||||
$query['link']['DisbursementEntry'] = array('fields' => array("SUM(DisbursementEntry.amount) AS reconciled"));
|
|
||||||
elseif (in_array($set, $this->creditTypes()))
|
|
||||||
$query['link']['ChargeEntry'] = array('fields' => array("SUM(ChargeEntry.amount) AS reconciled"));
|
|
||||||
else
|
|
||||||
die("INVALID RECONCILE SET");
|
|
||||||
|
|
||||||
$query['conditions'][] = array('StatementEntry.type' => $set);
|
|
||||||
$query['group'] = 'StatementEntry.id';
|
|
||||||
|
|
||||||
return $query;
|
|
||||||
}
|
|
||||||
|
|
||||||
function reconciledSet($set, $query = null, $unrec = false, $if_rec_include_partial = false) {
|
|
||||||
//$this->prFunctionLevel(array('log' => 16, 'show' => 10));
|
|
||||||
$this->prEnter(compact('set', 'query', 'unrec', 'if_rec_include_partial'));
|
|
||||||
$lquery = $this->reconciledSetQuery($set, $query);
|
|
||||||
$result = $this->find('all', $lquery);
|
|
||||||
|
|
||||||
$this->pr(20, compact('lquery', 'result'));
|
|
||||||
|
|
||||||
$resultset = array();
|
|
||||||
foreach ($result AS $i => $entry) {
|
|
||||||
$this->pr(25, compact('entry'));
|
|
||||||
if (!empty($entry[0]))
|
|
||||||
$entry['StatementEntry'] = $entry[0] + $entry['StatementEntry'];
|
|
||||||
unset($entry[0]);
|
|
||||||
|
|
||||||
$entry['StatementEntry']['balance'] =
|
|
||||||
$entry['StatementEntry']['amount'] - $entry['StatementEntry']['reconciled'];
|
|
||||||
|
|
||||||
// Since HAVING isn't a builtin feature of CakePHP,
|
|
||||||
// we'll have to post-process to get the desired entries
|
|
||||||
|
|
||||||
if ($entry['StatementEntry']['balance'] == 0)
|
|
||||||
$reconciled = true;
|
|
||||||
elseif ($entry['StatementEntry']['reconciled'] == 0)
|
|
||||||
$reconciled = false;
|
|
||||||
else // Partial disbursement; depends on unrec
|
|
||||||
$reconciled = (!$unrec && $if_rec_include_partial);
|
|
||||||
|
|
||||||
// Add to the set, if it's been requested
|
|
||||||
if ($reconciled == !$unrec)
|
|
||||||
$resultset[] = $entry;
|
|
||||||
}
|
|
||||||
|
|
||||||
return $this->prReturn(array('entries' => $resultset,
|
|
||||||
'summary' => $this->stats(null, $query)));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
* function: reconciledEntries
|
|
||||||
* - Returns a list of entries that reconcile against the given entry.
|
|
||||||
* (such as disbursements towards a charge).
|
|
||||||
*/
|
|
||||||
function reconciledEntriesQuery($id, $query = null) {
|
|
||||||
$this->queryInit($query, false);
|
|
||||||
|
|
||||||
$this->id = $id;
|
|
||||||
$this->recursive = -1;
|
|
||||||
$this->read();
|
|
||||||
|
|
||||||
$query['conditions'][] = array('StatementEntry.id' => $id);
|
|
||||||
|
|
||||||
if (in_array($this->data['StatementEntry']['type'], $this->debitTypes())) {
|
|
||||||
$query['link']['DisbursementEntry'] = array();
|
|
||||||
$query['conditions'][] = array('DisbursementEntry.id !=' => null);
|
|
||||||
}
|
|
||||||
if (in_array($this->data['StatementEntry']['type'], $this->creditTypes())) {
|
|
||||||
$query['link']['ChargeEntry'] = array();
|
|
||||||
$query['conditions'][] = array('ChargeEntry.id !=' => null);
|
|
||||||
}
|
|
||||||
|
|
||||||
return $query;
|
|
||||||
}
|
|
||||||
|
|
||||||
function reconciledEntries($id, $query = null) {
|
|
||||||
$this->prEnter(compact('id', 'query'));
|
|
||||||
$lquery = $this->reconciledEntriesQuery($id, $query);
|
|
||||||
|
|
||||||
$result = $this->find('all', $lquery);
|
|
||||||
foreach (array_keys($result) AS $i)
|
|
||||||
unset($result[$i]['StatementEntry']);
|
|
||||||
|
|
||||||
return $this->prReturn(array('entries' => $result));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
* function: assignCredits
|
|
||||||
* - Assigns all credits to existing charges
|
|
||||||
*
|
|
||||||
* REVISIT <AP>: 20090726
|
|
||||||
* This algorithm shouldn't be hardcoded. We need to allow
|
|
||||||
* the user to specify how disbursements should be applied.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
function assignCredits($query = null, $receipt_id = null,
|
|
||||||
$charge_ids = null, $disbursement_type = null,
|
|
||||||
$customer_id = null, $lease_id = null)
|
|
||||||
{
|
|
||||||
//$this->prFunctionLevel(25);
|
|
||||||
$this->prEnter(compact('query', 'receipt_id',
|
|
||||||
'charge_ids', 'disbursement_type',
|
|
||||||
'customer_id', 'lease_id'));
|
|
||||||
$this->queryInit($query);
|
|
||||||
|
|
||||||
if (!empty($customer_id))
|
|
||||||
$query['conditions'][] = array('StatementEntry.customer_id' => $customer_id);
|
|
||||||
|
|
||||||
if (empty($disbursement_type))
|
|
||||||
$disbursement_type = 'DISBURSEMENT';
|
|
||||||
|
|
||||||
$ret = array();
|
|
||||||
|
|
||||||
// First, find all known credits, unless this call is to make
|
|
||||||
// credit adjustments to a specific charge
|
|
||||||
// REVISIT <AP>: 20090806
|
|
||||||
// If the theory below is correct, we should only search for
|
|
||||||
// explicit credits if we don't have a receipt_id
|
|
||||||
if (empty($charge_ids)) {
|
|
||||||
$lquery = $query;
|
|
||||||
$lquery['conditions'][] = array('StatementEntry.type' => 'SURPLUS');
|
|
||||||
// REVISIT <AP>: 20090804
|
|
||||||
// We need to ensure that we're using surplus credits ONLY from either
|
|
||||||
// the given lease, or those that do not apply to any specific lease.
|
|
||||||
// However, by doing this, it forces any lease surplus amounts to
|
|
||||||
// remain frozen with that lease until either there is a lease charge,
|
|
||||||
// we refund the money, or we "promote" that surplus to the customer
|
|
||||||
// level and out of the leases direct control.
|
|
||||||
// That seems like a pain. Perhaps we should allow any customer
|
|
||||||
// surplus to be used on any customer charge.
|
|
||||||
$lquery['conditions'][] =
|
|
||||||
array('OR' =>
|
|
||||||
array(array('StatementEntry.lease_id' => null),
|
|
||||||
(!empty($lease_id)
|
|
||||||
? array('StatementEntry.lease_id' => $lease_id)
|
|
||||||
: array()),
|
|
||||||
));
|
|
||||||
$lquery['order'][] = 'StatementEntry.effective_date ASC';
|
|
||||||
$credits = $this->find('all', $lquery);
|
|
||||||
$this->pr(18, compact('credits'),
|
|
||||||
"Credits Established");
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
if (empty($receipt_id))
|
|
||||||
INTERNAL_ERROR("Can't make adjustments to a charge without a receipt ID.");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Next, establish credit from the newly added receipt
|
|
||||||
$receipt_credit = null;
|
|
||||||
if (!empty($receipt_id)) {
|
|
||||||
$lquery =
|
|
||||||
array('link' =>
|
|
||||||
array('StatementEntry',
|
|
||||||
'LedgerEntry' =>
|
|
||||||
array('conditions' =>
|
|
||||||
array('LedgerEntry.account_id !=' =>
|
|
||||||
$this->Account->accountReceivableAccountID()),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
'conditions' => array('Transaction.id' => $receipt_id),
|
|
||||||
'fields' => array('Transaction.id', 'Transaction.stamp', 'Transaction.amount'),
|
|
||||||
);
|
|
||||||
$receipt_credit = $this->Transaction->find('first', $lquery);
|
|
||||||
if (!$receipt_credit)
|
|
||||||
INTERNAL_ERROR("Unable to locate receipt.");
|
|
||||||
|
|
||||||
//$reconciled = $this->reconciledEntries($id);
|
|
||||||
|
|
||||||
$stats = $this->Transaction->stats($receipt_id);
|
|
||||||
$receipt_credit['balance'] =
|
|
||||||
$receipt_credit['Transaction']['amount'] - $stats['Disbursement']['total'];
|
|
||||||
|
|
||||||
$this->pr(18, compact('receipt_credit'),
|
|
||||||
"Receipt Credit Added");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Now find all unpaid charges
|
|
||||||
if (isset($charge_ids)) {
|
|
||||||
$lquery = array('contain' => false,
|
|
||||||
'conditions' => array('StatementEntry.id' => $charge_ids));
|
|
||||||
} else {
|
|
||||||
$lquery = $query;
|
|
||||||
// If we're working with a specific lease, then limit charges to it
|
|
||||||
if (!empty($lease_id))
|
|
||||||
$lquery['conditions'][] = array('StatementEntry.lease_id' => $lease_id);
|
|
||||||
}
|
|
||||||
$lquery['order'] = 'StatementEntry.effective_date ASC';
|
|
||||||
$charges = array();
|
|
||||||
foreach ($this->debitTypes() AS $dtype) {
|
|
||||||
$rset = $this->reconciledSet($dtype, $lquery, true);
|
|
||||||
$entries = $rset['entries'];
|
|
||||||
$charges = array_merge($charges, $entries);
|
|
||||||
$this->pr(18, compact('dtype', 'entries'), "Outstanding Debit Entries");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Initialize our list of used credits
|
|
||||||
$used_credits = array();
|
|
||||||
|
|
||||||
// REVISIT <AP>: 20090806
|
|
||||||
// Testing a theory. We should never have
|
|
||||||
// explicit credits, as well as a new receipt,
|
|
||||||
// and yet have outstanding charges.
|
|
||||||
if (!empty($credits) && !empty($receipt_credit) && !empty($charges))
|
|
||||||
INTERNAL_ERROR("Explicit credits that haven't already been applied.");
|
|
||||||
|
|
||||||
// Work through all unpaid charges, applying disbursements as we go
|
|
||||||
foreach ($charges AS $charge) {
|
|
||||||
|
|
||||||
$this->pr(20, compact('charge'),
|
|
||||||
'Process Charge');
|
|
||||||
|
|
||||||
// Check that we have available credits.
|
|
||||||
// Technically, this isn't necessary, since the loop
|
|
||||||
// will handle everything just fine. However, this
|
|
||||||
// just saves extra processing if/when there is no
|
|
||||||
// means to resolve a charge anyway.
|
|
||||||
if (empty($credits) && empty($receipt_credit['balance'])) {
|
|
||||||
$this->pr(17, 'No more available credits');
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
$charge['balance'] = $charge['StatementEntry']['balance'];
|
|
||||||
while ($charge['balance'] > 0 &&
|
|
||||||
(!empty($credits) || !empty($receipt_credit['balance']))) {
|
|
||||||
|
|
||||||
$this->pr(20, compact('charge'),
|
|
||||||
'Attempt Charge Reconciliation');
|
|
||||||
|
|
||||||
// Use explicit credits before using implicit credits
|
|
||||||
// (Not sure it matters though).
|
|
||||||
if (!empty($credits)) {
|
|
||||||
// Peel off the first credit available
|
|
||||||
$credit =& $credits[0];
|
|
||||||
$disbursement_date = $credit['StatementEntry']['effective_date'];
|
|
||||||
$disbursement_transaction_id = $credit['StatementEntry']['transaction_id'];
|
|
||||||
$disbursement_account_id = $credit['StatementEntry']['account_id'];
|
|
||||||
|
|
||||||
if (!isset($credit['balance']))
|
|
||||||
$credit['balance'] = $credit['StatementEntry']['amount'];
|
|
||||||
}
|
|
||||||
elseif (!empty($receipt_credit['balance'])) {
|
|
||||||
// Use our only receipt credit
|
|
||||||
$credit =& $receipt_credit;
|
|
||||||
$disbursement_date = $credit['Transaction']['stamp'];
|
|
||||||
$disbursement_transaction_id = $credit['Transaction']['id'];
|
|
||||||
$disbursement_account_id = $credit['LedgerEntry']['account_id'];
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
die("HOW DID WE GET HERE WITH NO SURPLUS?");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set the disbursement amount to the maximum amount
|
|
||||||
// possible without exceeding the charge or credit balance
|
|
||||||
$disbursement_amount = min($charge['balance'], $credit['balance']);
|
|
||||||
if (!isset($credit['applied']))
|
|
||||||
$credit['applied'] = 0;
|
|
||||||
|
|
||||||
$credit['applied'] += $disbursement_amount;
|
|
||||||
$credit['balance'] -= $disbursement_amount;
|
|
||||||
|
|
||||||
$this->pr(20, compact('credit'),
|
|
||||||
($credit['balance'] > 0 ? 'Utilized' : 'Exhausted') .
|
|
||||||
(!empty($credits) ? ' Credit' : ' Receipt'));
|
|
||||||
|
|
||||||
if ($credit['balance'] < 0)
|
|
||||||
die("HOW DID WE END UP WITH NEGATIVE SURPLUS BALANCE?");
|
|
||||||
|
|
||||||
// If we've exhausted the credit, get it out of the
|
|
||||||
// available credit pool (but keep track of it for later).
|
|
||||||
if ($credit['balance'] <= 0 && !empty($credits))
|
|
||||||
$used_credits[] = array_shift($credits);
|
|
||||||
|
|
||||||
// Add a disbursement that uses the available credit to pay the charge
|
|
||||||
$disbursement = array('type' => $disbursement_type,
|
|
||||||
'account_id' => $disbursement_account_id,
|
|
||||||
'amount' => $disbursement_amount,
|
|
||||||
'effective_date' => $disbursement_date,
|
|
||||||
'transaction_id' => $disbursement_transaction_id,
|
|
||||||
'customer_id' => $charge['StatementEntry']['customer_id'],
|
|
||||||
'lease_id' => $charge['StatementEntry']['lease_id'],
|
|
||||||
'charge_entry_id' => $charge['StatementEntry']['id'],
|
|
||||||
'comment' => null,
|
|
||||||
);
|
|
||||||
|
|
||||||
$this->pr(20, compact('disbursement'),
|
|
||||||
'New Disbursement Entry');
|
|
||||||
|
|
||||||
$result = $this->addStatementEntry($disbursement);
|
|
||||||
$ret['Disbursement'][] = $result;
|
|
||||||
if ($result['error'])
|
|
||||||
$ret['error'] = true;
|
|
||||||
|
|
||||||
// Adjust the charge balance to reflect the new disbursement
|
|
||||||
$charge['balance'] -= $disbursement_amount;
|
|
||||||
if ($charge['balance'] < 0)
|
|
||||||
die("HOW DID WE GET A NEGATIVE CHARGE AMOUNT?");
|
|
||||||
|
|
||||||
if ($charge['balance'] <= 0)
|
|
||||||
$this->pr(20, 'Fully Paid Charge');
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// Partially used credits must be added to the used list
|
|
||||||
if (isset($credits[0]['applied']))
|
|
||||||
$used_credits[] = array_shift($credits);
|
|
||||||
|
|
||||||
$this->pr(18, compact('credits', 'used_credits', 'receipt_credit'),
|
|
||||||
'Disbursements added');
|
|
||||||
|
|
||||||
// Clean up any explicit credits that have been used
|
|
||||||
foreach ($used_credits AS $credit) {
|
|
||||||
if ($credit['balance'] > 0) {
|
|
||||||
$this->pr(20, compact('credit'),
|
|
||||||
'Update Credit Entry');
|
|
||||||
|
|
||||||
$this->id = $credit['StatementEntry']['id'];
|
|
||||||
$this->saveField('amount', $credit['balance']);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
$this->pr(20, compact('credit'),
|
|
||||||
'Delete Exhausted Credit Entry');
|
|
||||||
|
|
||||||
$this->del($credit['StatementEntry']['id'], false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Convert non-exhausted receipt credit to an explicit one
|
|
||||||
if (!empty($receipt_credit['balance'])) {
|
|
||||||
$credit =& $receipt_credit;
|
|
||||||
|
|
||||||
$explicit_credit = $this->find
|
|
||||||
('first', array('contain' => false,
|
|
||||||
'conditions' =>
|
|
||||||
array(array('transaction_id' => $credit['Transaction']['id']),
|
|
||||||
array('type' => 'SURPLUS')),
|
|
||||||
));
|
|
||||||
|
|
||||||
if (empty($explicit_credit)) {
|
|
||||||
$this->pr(18, compact('credit'),
|
|
||||||
'Create Explicit Credit');
|
|
||||||
|
|
||||||
$result = $this->addStatementEntry
|
|
||||||
(array('type' => 'SURPLUS',
|
|
||||||
'account_id' => $credit['LedgerEntry']['account_id'],
|
|
||||||
'amount' => $credit['balance'],
|
|
||||||
'effective_date' => $credit['Transaction']['stamp'],
|
|
||||||
'transaction_id' => $credit['Transaction']['id'],
|
|
||||||
'customer_id' => $customer_id,
|
|
||||||
'lease_id' => $lease_id,
|
|
||||||
));
|
|
||||||
$ret['Credit'] = $result;
|
|
||||||
if ($result['error'])
|
|
||||||
$ret['error'] = true;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
$this->pr(18, compact('explicit_credit', 'credit'),
|
|
||||||
'Update Explicit Credit');
|
|
||||||
$EC = new StatementEntry();
|
|
||||||
$EC->id = $explicit_credit['StatementEntry']['id'];
|
|
||||||
$EC->saveField('amount', $credit['balance']);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return $this->prReturn($ret + array('error' => false));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
* function: stats
|
|
||||||
* - Returns summary data from the requested statement entry
|
|
||||||
*/
|
|
||||||
function stats($id = null, $query = null) {
|
|
||||||
$this->prFunctionLevel(array('log' => 19, 'show' => 10));
|
|
||||||
$this->prEnter(compact('id', 'query'));
|
|
||||||
|
|
||||||
$this->queryInit($query);
|
|
||||||
unset($query['group']);
|
|
||||||
|
|
||||||
$stats = array();
|
|
||||||
if (isset($id))
|
|
||||||
$query['conditions'][] = array('StatementEntry.id' => $id);
|
|
||||||
|
|
||||||
$types = array('Charge', 'Disbursement');
|
|
||||||
foreach ($types AS $type_index => $this_name) {
|
|
||||||
$that_name = $types[($type_index + 1) % 2];
|
|
||||||
if ($this_name === 'Charge') {
|
|
||||||
$this_types = $this->debitTypes();
|
|
||||||
$that_types = $this->creditTypes();
|
|
||||||
} else {
|
|
||||||
$this_types = $this->creditTypes();
|
|
||||||
$that_types = $this->debitTypes();
|
|
||||||
}
|
|
||||||
|
|
||||||
$this_query = $query;
|
|
||||||
$this_query['fields'] = array();
|
|
||||||
$this_query['fields'][] = "SUM(StatementEntry.amount) AS total";
|
|
||||||
$this_query['conditions'][] = array('StatementEntry.type' => $this_types);
|
|
||||||
$result = $this->find('first', $this_query);
|
|
||||||
$stats[$this_name] = $result[0];
|
|
||||||
|
|
||||||
$this->pr(17, compact('this_query', 'result'), $this_name.'s');
|
|
||||||
|
|
||||||
// Tally the different types that result in credits towards the charges
|
|
||||||
$stats[$this_name]['reconciled'] = 0;
|
|
||||||
foreach ($that_types AS $that_type) {
|
|
||||||
$lc_that_type = strtolower($that_type);
|
|
||||||
$that_query = $this_query;
|
|
||||||
$that_query['link']["{$that_name}Entry"] = array('fields' => array());
|
|
||||||
$that_query['fields'] = array();
|
|
||||||
if ($this_name == 'Charge')
|
|
||||||
$that_query['fields'][] = "COALESCE(SUM(${that_name}Entry.amount),0) AS $lc_that_type";
|
|
||||||
else
|
|
||||||
$that_query['fields'][] = "COALESCE(SUM(StatementEntry.amount), 0) AS $lc_that_type";
|
|
||||||
$that_query['conditions'][] = array("{$that_name}Entry.type" => $that_type);
|
|
||||||
$result = $this->find('first', $that_query);
|
|
||||||
$stats[$this_name] += $result[0];
|
|
||||||
|
|
||||||
$this->pr(17, compact('that_query', 'result'), "{$this_name}s: $that_type");
|
|
||||||
$stats[$this_name]['reconciled'] += $stats[$this_name][$lc_that_type];
|
|
||||||
}
|
|
||||||
|
|
||||||
// Compute balance information for charges
|
|
||||||
$stats[$this_name]['balance'] =
|
|
||||||
$stats[$this_name]['total'] - $stats[$this_name]['reconciled'];
|
|
||||||
if (!isset($stats[$this_name]['balance']))
|
|
||||||
$stats[$this_name]['balance'] = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 'balance' is simply the difference between
|
|
||||||
// the balances of charges and disbursements
|
|
||||||
$stats['balance'] = $stats['Charge']['balance'] - $stats['Disbursement']['balance'];
|
|
||||||
if (!isset($stats['balance']))
|
|
||||||
$stats['balance'] = 0;
|
|
||||||
|
|
||||||
// 'account_balance' is really only relevant to
|
|
||||||
// callers that have requested charge and disbursement
|
|
||||||
// stats with respect to a particular account.
|
|
||||||
// It represents the difference between inflow
|
|
||||||
// and outflow from that account.
|
|
||||||
$stats['account_balance'] = $stats['Charge']['reconciled'] - $stats['Disbursement']['total'];
|
|
||||||
if (!isset($stats['account_balance']))
|
|
||||||
$stats['account_balance'] = 0;
|
|
||||||
|
|
||||||
return $this->prReturn($stats);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,145 +0,0 @@
|
|||||||
<?php
|
|
||||||
class Tender extends AppModel {
|
|
||||||
|
|
||||||
var $belongsTo = array(
|
|
||||||
'TenderType',
|
|
||||||
'Customer',
|
|
||||||
'LedgerEntry',
|
|
||||||
'DepositTransaction' => array(
|
|
||||||
'className' => 'Transaction',
|
|
||||||
),
|
|
||||||
'NsfTransaction' => array(
|
|
||||||
'className' => 'Transaction',
|
|
||||||
),
|
|
||||||
);
|
|
||||||
|
|
||||||
|
|
||||||
/**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
* function: verifyTender
|
|
||||||
* - Verifies consistenty of new tender data
|
|
||||||
* (not in a pre-existing tender)
|
|
||||||
*/
|
|
||||||
function verifyTender($tender) {
|
|
||||||
$this->prFunctionLevel(10);
|
|
||||||
$this->prEnter(compact('tender'));
|
|
||||||
|
|
||||||
if (empty($tender['tender_type_id'])) {
|
|
||||||
return $this->prReturn(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
return $this->prReturn(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
* function: addTender
|
|
||||||
* - Inserts new Tender into the database
|
|
||||||
*/
|
|
||||||
|
|
||||||
function addTender($tender) {
|
|
||||||
$this->prEnter(compact('tender'));
|
|
||||||
|
|
||||||
$ret = array();
|
|
||||||
if (!$this->verifyTender($tender))
|
|
||||||
return $this->prReturn(array('error' => true) + $ret);
|
|
||||||
|
|
||||||
// Come up with a (not necessarily unique) name for the tender.
|
|
||||||
// For checks & money orders, this will be based on the check
|
|
||||||
// number. For other types of tender, we'll just use the
|
|
||||||
// generic name of the monetary account.
|
|
||||||
// REVISIT <AP>: 20090723
|
|
||||||
// I would like to have cash named "Cash #1234", where
|
|
||||||
// the number would correspond to either the Tender ID
|
|
||||||
// or the LedgerEntry ID.
|
|
||||||
if (empty($tender['name']) && !empty($tender['account_id'])) {
|
|
||||||
$tender['name'] = $this->LedgerEntry->Account->name($tender['account_id']);
|
|
||||||
if ($tender['account_id'] == $this->LedgerEntry->Account->checkAccountID() ||
|
|
||||||
$tender['account_id'] == $this->LedgerEntry->Account->moneyOrderAccountID()) {
|
|
||||||
$tender['name'] .= ' #' . $tender['data1'];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->pr(20, array('Tender' => $tender),
|
|
||||||
'Pre-Save');
|
|
||||||
|
|
||||||
$this->create();
|
|
||||||
if (!$this->save($tender))
|
|
||||||
return $this->prReturn(array('error' => true) + $ret);
|
|
||||||
|
|
||||||
$ret['tender_id'] = $this->id;
|
|
||||||
return $this->prReturn($ret + array('error' => false));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
* function: nsf
|
|
||||||
* - Flags the ledger entry as having insufficient funds
|
|
||||||
*
|
|
||||||
* Steps:
|
|
||||||
* - Get information from Check (C1); for amount $A
|
|
||||||
* - Find Bank Deposit matching to Tender
|
|
||||||
* - New Transaction (T1)
|
|
||||||
* - New Bank Deposit (D1)
|
|
||||||
* - New Tender (N1); NSF; D1,
|
|
||||||
* - Add new LedgerEntry (L1a); T1; debit:bank; -$A
|
|
||||||
* - Add new LedgerEntry (L1b); T1; credit:NSF; -$A
|
|
||||||
* - Add new LedgerEntry (L2a); T1; debit:NSF; -$A; N1
|
|
||||||
* - Add new LedgerEntry (L2b); T1; credit:A/R; -$A
|
|
||||||
* - For Tx associated with LE associated with C1:
|
|
||||||
* - For each Disbursement SE of Tx:
|
|
||||||
* - Add new StatementEntry (S1n); T1; DISBURSEMENT; -1*S1n.amount
|
|
||||||
* - New Transaction (T2) (?????)
|
|
||||||
* - Add new StatementEntry (S2); T2; CHARGE; NSF; $35
|
|
||||||
* - Add new LedgerEntry (L3a); T2; credit:NSF-Fee; $35
|
|
||||||
* - Add new LedgerEntry (L3b); T2; debit:A/R; $35
|
|
||||||
* - Set C1.nsf_tx = T1
|
|
||||||
* - Re-Reconcile (customer may have running credit)
|
|
||||||
*/
|
|
||||||
|
|
||||||
function nsf($id, $stamp = null) {
|
|
||||||
$this->prFunctionLevel(30);
|
|
||||||
$this->prEnter(compact('id'));
|
|
||||||
|
|
||||||
// Get information about this NSF item.
|
|
||||||
$this->id = $id;
|
|
||||||
$tender = $this->find
|
|
||||||
('first', array
|
|
||||||
('contain' =>
|
|
||||||
array('LedgerEntry',
|
|
||||||
'DepositTransaction',
|
|
||||||
'NsfTransaction'),
|
|
||||||
));
|
|
||||||
$this->pr(20, compact('tender'));
|
|
||||||
|
|
||||||
if (!empty($tender['NsfTransaction']['id']))
|
|
||||||
die("Item has already been set as NSF");
|
|
||||||
|
|
||||||
if (empty($tender['DepositTransaction']['id']))
|
|
||||||
die("Item has not been deposited yet");
|
|
||||||
|
|
||||||
$tender['Transaction'] = $tender['DepositTransaction'];
|
|
||||||
unset($tender['DepositTransaction']);
|
|
||||||
unset($tender['NsfTransaction']);
|
|
||||||
|
|
||||||
$T = new Transaction();
|
|
||||||
$result = $T->addNsf($tender, $stamp);
|
|
||||||
if ($result['error'])
|
|
||||||
return $this->prReturn(false);
|
|
||||||
|
|
||||||
// Flag the tender as NSF, using the items created from addNsf
|
|
||||||
$this->id = $id;
|
|
||||||
$this->saveField('nsf_transaction_id', $result['nsf_transaction_id']);
|
|
||||||
$this->saveField('nsf_ledger_entry_id', $result['nsf_ledger_entry_id']);
|
|
||||||
|
|
||||||
return $this->prReturn(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
?>
|
|
||||||
@@ -1,115 +0,0 @@
|
|||||||
<?php
|
|
||||||
class TenderType extends AppModel {
|
|
||||||
|
|
||||||
var $belongsTo = array(
|
|
||||||
'Account',
|
|
||||||
);
|
|
||||||
|
|
||||||
var $hasMany = array(
|
|
||||||
'Tender',
|
|
||||||
);
|
|
||||||
|
|
||||||
|
|
||||||
/**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
* function: accountID
|
|
||||||
* - Returns the intended account ID for receipt of the given tender
|
|
||||||
*/
|
|
||||||
|
|
||||||
function accountID($id) {
|
|
||||||
$this->cacheQueries = true;
|
|
||||||
$item = $this->find('first', array
|
|
||||||
('contain' => false,
|
|
||||||
'conditions' => array('TenderType.id' => $id),
|
|
||||||
));
|
|
||||||
$this->cacheQueries = false;
|
|
||||||
return $item['TenderType']['account_id'];
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
* function: paymentTypes
|
|
||||||
* - Returns an array of types that can be used for payments
|
|
||||||
*/
|
|
||||||
|
|
||||||
function paymentTypes($query = null) {
|
|
||||||
$this->queryInit($query);
|
|
||||||
$query['order'][] = 'name';
|
|
||||||
|
|
||||||
$this->cacheQueries = true;
|
|
||||||
$types = $this->find('all', $query);
|
|
||||||
$this->cacheQueries = false;
|
|
||||||
|
|
||||||
return $types;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
* function: paymentTypes
|
|
||||||
* - Returns an array of types that can be deposited
|
|
||||||
*/
|
|
||||||
|
|
||||||
function depositTypes($query = null) {
|
|
||||||
$this->queryInit($query);
|
|
||||||
$query['order'][] = 'name';
|
|
||||||
$query['conditions'][] = array('tillable' => true);
|
|
||||||
|
|
||||||
$this->cacheQueries = true;
|
|
||||||
$types = $this->find('all', $query);
|
|
||||||
$this->cacheQueries = false;
|
|
||||||
|
|
||||||
// Rearrange to be of the form (id => name)
|
|
||||||
$result = array();
|
|
||||||
foreach ($types AS $type)
|
|
||||||
$result[$type['TenderType']['id']] = $type['TenderType']['name'];
|
|
||||||
|
|
||||||
return $result;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
* function: defaultPaymentType
|
|
||||||
* - Returns the ID of the default payment type
|
|
||||||
*/
|
|
||||||
|
|
||||||
function defaultPaymentType() {
|
|
||||||
return $this->nameToID('Check');
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
* function: stats
|
|
||||||
* - Returns the stats for the given tender type
|
|
||||||
*/
|
|
||||||
|
|
||||||
function stats($id = null, $query = null) {
|
|
||||||
if (!$id)
|
|
||||||
return null;
|
|
||||||
|
|
||||||
$this->queryInit($query);
|
|
||||||
|
|
||||||
if (!isset($query['link']['Tender']))
|
|
||||||
$query['link']['Tender'] = array('fields' => array());
|
|
||||||
if (!isset($query['link']['Tender']['LedgerEntry']))
|
|
||||||
$query['link']['Tender']['LedgerEntry'] = array('fields' => array());
|
|
||||||
|
|
||||||
$query['fields'][] = "SUM(COALESCE(LedgerEntry.amount,0)) AS 'total'";
|
|
||||||
$query['fields'][] = "SUM(IF(deposit_transaction_id IS NULL, COALESCE(LedgerEntry.amount,0), 0)) AS 'undeposited'";
|
|
||||||
$query['fields'][] = "SUM(IF(deposit_transaction_id IS NULL, 0, COALESCE(LedgerEntry.amount,0))) AS 'deposited'";
|
|
||||||
$query['fields'][] = "SUM(IF(nsf_transaction_id IS NULL, 0, COALESCE(LedgerEntry.amount,0))) AS 'nsf'";
|
|
||||||
|
|
||||||
$this->id = $id;
|
|
||||||
$stats = $this->find('first', $query);
|
|
||||||
return $stats[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,828 +0,0 @@
|
|||||||
<?php
|
|
||||||
class Transaction extends AppModel {
|
|
||||||
|
|
||||||
var $belongsTo = array(
|
|
||||||
'Account',
|
|
||||||
'Ledger',
|
|
||||||
);
|
|
||||||
|
|
||||||
var $hasMany = array(
|
|
||||||
'LedgerEntry',
|
|
||||||
'StatementEntry',
|
|
||||||
'DepositTender' => array(
|
|
||||||
'className' => 'Tender',
|
|
||||||
'foreignKey' => 'deposit_transaction_id',
|
|
||||||
),
|
|
||||||
|
|
||||||
'Charge' => array(
|
|
||||||
'className' => 'StatementEntry',
|
|
||||||
'conditions' => array('Charge.type' => 'CHARGE')
|
|
||||||
),
|
|
||||||
|
|
||||||
'Disbursement' => array(
|
|
||||||
'className' => 'StatementEntry',
|
|
||||||
'conditions' => array('Disbursement.type' => 'DISBURSEMENT')
|
|
||||||
),
|
|
||||||
|
|
||||||
'Debit' => array(
|
|
||||||
'className' => 'LedgerEntry',
|
|
||||||
'conditions' => array('Debit.crdr' => 'DEBIT')
|
|
||||||
),
|
|
||||||
|
|
||||||
'Credit' => array(
|
|
||||||
'className' => 'LedgerEntry',
|
|
||||||
'conditions' => array('Credit.crdr' => 'CREDIT')
|
|
||||||
),
|
|
||||||
|
|
||||||
);
|
|
||||||
|
|
||||||
|
|
||||||
//var $default_log_level = array('log' => 30, 'show' => 15);
|
|
||||||
|
|
||||||
/**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
* function: addInvoice
|
|
||||||
* - Adds a new invoice invoice
|
|
||||||
*/
|
|
||||||
|
|
||||||
function addInvoice($data, $customer_id, $lease_id = null) {
|
|
||||||
$this->prEnter(compact('data', 'customer_id', 'lease_id'));
|
|
||||||
|
|
||||||
// Establish the transaction as an invoice
|
|
||||||
$invoice =& $data['Transaction'];
|
|
||||||
$invoice +=
|
|
||||||
array('type' => 'INVOICE',
|
|
||||||
'crdr' => 'DEBIT',
|
|
||||||
'account_id' => $this->Account->accountReceivableAccountID(),
|
|
||||||
'customer_id' => $customer_id,
|
|
||||||
'lease_id' => $lease_id,
|
|
||||||
);
|
|
||||||
|
|
||||||
// Go through the statement entries and flag as charges
|
|
||||||
foreach ($data['Entry'] AS &$entry)
|
|
||||||
$entry += array('type' => 'CHARGE',
|
|
||||||
'crdr' => 'CREDIT',
|
|
||||||
);
|
|
||||||
|
|
||||||
$ids = $this->addTransaction($data['Transaction'], $data['Entry']);
|
|
||||||
if (isset($ids['transaction_id']))
|
|
||||||
$ids['invoice_id'] = $ids['transaction_id'];
|
|
||||||
|
|
||||||
return $this->prReturn($ids);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
* function: addReceipt
|
|
||||||
* - Adds a new receipt
|
|
||||||
*/
|
|
||||||
|
|
||||||
function addReceipt($data, $customer_id, $lease_id = null) {
|
|
||||||
$this->prEnter(compact('data', 'customer_id', 'lease_id'));
|
|
||||||
|
|
||||||
// Establish the transaction as a receipt
|
|
||||||
$receipt =& $data['Transaction'];
|
|
||||||
$receipt +=
|
|
||||||
array('type' => 'RECEIPT',
|
|
||||||
'crdr' => 'CREDIT',
|
|
||||||
'account_id' => $this->Account->accountReceivableAccountID(),
|
|
||||||
'customer_id' => $customer_id,
|
|
||||||
'lease_id' => $lease_id,
|
|
||||||
);
|
|
||||||
|
|
||||||
// Go through the statement entries and flag as disbursements
|
|
||||||
foreach ($data['Entry'] AS &$entry)
|
|
||||||
$entry += array('type' => 'DISBURSEMENT', // not used
|
|
||||||
'crdr' => 'DEBIT',
|
|
||||||
'account_id' =>
|
|
||||||
(isset($entry['Tender']['tender_type_id'])
|
|
||||||
? ($this->LedgerEntry->Tender->TenderType->
|
|
||||||
accountID($entry['Tender']['tender_type_id']))
|
|
||||||
: null),
|
|
||||||
);
|
|
||||||
|
|
||||||
$ids = $this->addTransaction($data['Transaction'], $data['Entry']);
|
|
||||||
if (isset($ids['transaction_id']))
|
|
||||||
$ids['receipt_id'] = $ids['transaction_id'];
|
|
||||||
|
|
||||||
return $this->prReturn($ids);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
* function: addWaiver
|
|
||||||
* - Adds a new waiver
|
|
||||||
*/
|
|
||||||
|
|
||||||
function addWaiver($data, $charge_id, $customer_id, $lease_id = null) {
|
|
||||||
$this->prEnter(compact('data', 'charge_id', 'customer_id', 'lease_id'));
|
|
||||||
|
|
||||||
if (count($data['Entry']) != 1)
|
|
||||||
INTERNAL_ERROR("Should be one Entry for addWaiver");
|
|
||||||
|
|
||||||
// Just make sure the disbursement(s) are marked as waivers
|
|
||||||
// and that they go to cover the specific charge.
|
|
||||||
$data['Transaction']['disbursement_type'] = 'WAIVER';
|
|
||||||
$data['Transaction']['assign_charge_entry_id'] = $charge_id;
|
|
||||||
|
|
||||||
// In all other respects this is just a receipt.
|
|
||||||
$ids = $this->addReceipt($data, $customer_id, $lease_id);
|
|
||||||
if (isset($ids['transaction_id']))
|
|
||||||
$ids['waiver_id'] = $ids['transaction_id'];
|
|
||||||
|
|
||||||
return $this->prReturn($ids);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
* function: addReversal
|
|
||||||
* - Adds a new charge reversal
|
|
||||||
*/
|
|
||||||
|
|
||||||
function addReversal($data, $charge_id, $customer_id, $lease_id = null) {
|
|
||||||
$this->prEnter(compact('data', 'charge_id', 'customer_id', 'lease_id'));
|
|
||||||
|
|
||||||
if (count($data['Entry']) != 1)
|
|
||||||
INTERNAL_ERROR("Should be one Entry for addReversal");
|
|
||||||
|
|
||||||
// Just make sure the disbursement(s) are marked as reversals
|
|
||||||
// and that they go to cover the specific charge.
|
|
||||||
$data['Transaction']['type'] = 'CREDIT_NOTE';
|
|
||||||
$data['Transaction']['disbursement_type'] = 'REVERSAL';
|
|
||||||
$data['Transaction']['assign_charge_entry_id'] = $charge_id;
|
|
||||||
|
|
||||||
// In all other respects this is just a receipt.
|
|
||||||
$ids = $this->addReceipt($data, $customer_id, $lease_id);
|
|
||||||
if (isset($ids['transaction_id']))
|
|
||||||
$ids['reversal_id'] = $ids['transaction_id'];
|
|
||||||
|
|
||||||
return $this->prReturn($ids);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
* function: addDeposit
|
|
||||||
* - Adds a new bank deposit
|
|
||||||
*/
|
|
||||||
|
|
||||||
function addDeposit($data, $account_id) {
|
|
||||||
$this->prEnter(compact('data', 'account_id'));
|
|
||||||
|
|
||||||
// Establish the transaction as a deposit
|
|
||||||
$deposit =& $data['Transaction'];
|
|
||||||
$deposit +=
|
|
||||||
array('type' => 'DEPOSIT',
|
|
||||||
'crdr' => 'DEBIT',
|
|
||||||
'account_id' => $account_id,
|
|
||||||
'customer_id' => null,
|
|
||||||
'lease_id' => null,
|
|
||||||
);
|
|
||||||
|
|
||||||
// Save the list of IDs, so that we can mark their
|
|
||||||
// deposit transaction after it has been created.
|
|
||||||
$tender_ids = array_map(create_function('$item', 'return $item["tender_id"];'),
|
|
||||||
$data['Entry']);
|
|
||||||
|
|
||||||
// Go through the statement entries and re-group by account id
|
|
||||||
$group = array();
|
|
||||||
foreach ($data['Entry'] AS &$entry) {
|
|
||||||
if (!isset($group[$entry['account_id']]))
|
|
||||||
$group[$entry['account_id']] =
|
|
||||||
array('account_id' => $entry['account_id'],
|
|
||||||
'crdr' => 'CREDIT',
|
|
||||||
'amount' => 0);
|
|
||||||
$group[$entry['account_id']]['amount'] += $entry['amount'];
|
|
||||||
}
|
|
||||||
$data['Entry'] = $group;
|
|
||||||
|
|
||||||
$ids = $this->addTransaction($data['Transaction'], $data['Entry']);
|
|
||||||
if (isset($ids['transaction_id']))
|
|
||||||
$ids['deposit_id'] = $ids['transaction_id'];
|
|
||||||
|
|
||||||
if (!empty($ids['deposit_id'])) {
|
|
||||||
$this->LedgerEntry->Tender->updateAll
|
|
||||||
(array('Tender.deposit_transaction_id' => $ids['deposit_id']),
|
|
||||||
array('Tender.id' => $tender_ids)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
return $this->prReturn($ids);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
* function: addClose
|
|
||||||
* - Adds a new transaction for closing ledgers
|
|
||||||
*/
|
|
||||||
|
|
||||||
function addClose($data) {
|
|
||||||
$this->prEnter(compact('data'));
|
|
||||||
|
|
||||||
// Establish the transaction as a close
|
|
||||||
$close =& $data['Transaction'];
|
|
||||||
$close +=
|
|
||||||
array('type' => 'CLOSE',
|
|
||||||
'crdr' => null,
|
|
||||||
'account_id' => null,
|
|
||||||
'customer_id' => null,
|
|
||||||
'lease_id' => null,
|
|
||||||
);
|
|
||||||
|
|
||||||
$ledger_ids = array();
|
|
||||||
$data['Entry'] = array();
|
|
||||||
foreach ($data['Ledger'] AS $ledger) {
|
|
||||||
$ledger_id = $ledger['old_ledger_id'];
|
|
||||||
$new_ledger_id = $ledger['new_ledger_id'];
|
|
||||||
$amount = $ledger['amount'];
|
|
||||||
$account_id = $this->Account->Ledger->accountID($ledger_id);
|
|
||||||
$crdr = strtoupper($this->Account->fundamentalOpposite($account_id));
|
|
||||||
$comment = "Ledger Carry Forward (c/f)";
|
|
||||||
|
|
||||||
// Save the ledger ID for later, to mark it as closed
|
|
||||||
$ledger_ids[] = $ledger_id;
|
|
||||||
|
|
||||||
// No need to generate ledger entries if there is no balance
|
|
||||||
if (empty($ledger['amount']) || $ledger['amount'] == 0)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
// Add an entry to carry the ledger balance forward
|
|
||||||
$data['Entry'][] = compact('account_id', 'ledger_id', 'new_ledger_id',
|
|
||||||
'crdr', 'amount', 'comment');
|
|
||||||
}
|
|
||||||
unset($data['Ledger']);
|
|
||||||
|
|
||||||
// Add the transaction and carry forward balances
|
|
||||||
$ids = $this->addTransaction($data['Transaction'], $data['Entry']);
|
|
||||||
if (isset($ids['transaction_id']))
|
|
||||||
$ids['close_id'] = $ids['transaction_id'];
|
|
||||||
|
|
||||||
// Mark the older ledgers as closed
|
|
||||||
if (!empty($ids['close_id'])) {
|
|
||||||
$this->LedgerEntry->Ledger->updateAll
|
|
||||||
(array('Ledger.close_transaction_id' => $ids['close_id']),
|
|
||||||
array('Ledger.id' => $ledger_ids)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
return $this->prReturn($ids);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
* function: addRefund
|
|
||||||
* - Adds a new refund
|
|
||||||
*/
|
|
||||||
|
|
||||||
function addRefund($data, $customer_id, $lease_id = null) {
|
|
||||||
$this->prEnter(compact('data', 'customer_id', 'lease_id'));
|
|
||||||
|
|
||||||
// Establish the transaction as a Refund. This is just like a
|
|
||||||
// Payment, except instead of paying out of the account payable,
|
|
||||||
// it comes from the customer credit in the account receivable.
|
|
||||||
// Someday, perhaps we'll just issue a Credit Note or similar,
|
|
||||||
// but for now, a refund means it's time to actually PAY.
|
|
||||||
$refund =& $data['Transaction'];
|
|
||||||
$refund +=
|
|
||||||
array('account_id' => $this->Account->accountReceivableAccountID());
|
|
||||||
|
|
||||||
// Also, to make it clear to the user, we flag as a REFUND
|
|
||||||
// even though that type works and operates just as PAYMENT
|
|
||||||
foreach ($data['Entry'] AS &$entry)
|
|
||||||
$entry += array('type' => 'REFUND');
|
|
||||||
|
|
||||||
$ids = $this->addPayment($data, $customer_id, $lease_id);
|
|
||||||
if (isset($ids['transaction_id']))
|
|
||||||
$ids['refund_id'] = $ids['transaction_id'];
|
|
||||||
|
|
||||||
return $this->prReturn($ids);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
* function: addPayment
|
|
||||||
* - Adds a new payment transaction, which is money outflow
|
|
||||||
*/
|
|
||||||
|
|
||||||
function addPayment($data, $customer_id, $lease_id = null) {
|
|
||||||
$this->prEnter(compact('data', 'customer_id', 'lease_id'));
|
|
||||||
|
|
||||||
// Establish the transaction as an payment
|
|
||||||
$payment =& $data['Transaction'];
|
|
||||||
$payment +=
|
|
||||||
array('type' => 'PAYMENT',
|
|
||||||
'crdr' => 'DEBIT',
|
|
||||||
'account_id' => $this->Account->accountPayableAccountID(),
|
|
||||||
'customer_id' => $customer_id,
|
|
||||||
'lease_id' => $lease_id,
|
|
||||||
);
|
|
||||||
|
|
||||||
// Go through the statement entries and flag as payments
|
|
||||||
foreach ($data['Entry'] AS &$entry)
|
|
||||||
$entry += array('type' => 'PAYMENT',
|
|
||||||
'crdr' => 'CREDIT',
|
|
||||||
);
|
|
||||||
|
|
||||||
$ids = $this->addTransaction($data['Transaction'], $data['Entry']);
|
|
||||||
if (isset($ids['transaction_id']))
|
|
||||||
$ids['payment_id'] = $ids['transaction_id'];
|
|
||||||
|
|
||||||
return $this->prReturn($ids);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
* function: verifyTransaction
|
|
||||||
* - Verifies consistenty of new transaction data
|
|
||||||
* (not in a pre-existing transaction)
|
|
||||||
*/
|
|
||||||
function verifyTransaction($transaction, $entries) {
|
|
||||||
//$this->prFunctionLevel(10);
|
|
||||||
$this->prEnter(compact('transaction', 'entries'));
|
|
||||||
|
|
||||||
// Verify required Transaction data is present
|
|
||||||
if (empty($transaction['type']) ||
|
|
||||||
($transaction['type'] != 'CLOSE'
|
|
||||||
&& (empty($transaction['account_id']) ||
|
|
||||||
empty($transaction['crdr']))) ||
|
|
||||||
(in_array($transaction['type'], array('INVOICE', 'RECEIPT'))
|
|
||||||
&& empty($transaction['customer_id']))
|
|
||||||
) {
|
|
||||||
return $this->prReturn(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Verify all entries
|
|
||||||
foreach ($entries AS $entry) {
|
|
||||||
// Ensure these items are null'ed out so we don't
|
|
||||||
// accidentally pick up stale data.
|
|
||||||
$le1 = $le1_tender = $le2 = $se = null;
|
|
||||||
extract($entry);
|
|
||||||
if (!empty($le1) && !empty($le2) &&
|
|
||||||
!$this->LedgerEntry->DoubleEntry->verifyDoubleEntry($le1, $le2, $le1_tender)) {
|
|
||||||
return $this->prReturn(false);
|
|
||||||
}
|
|
||||||
if (!empty($se) &&
|
|
||||||
!$this->StatementEntry->verifyStatementEntry($se)) {
|
|
||||||
return $this->prReturn(false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return $this->prReturn(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
* function: addTransaction
|
|
||||||
* - Adds a new transaction, and the appropriate ledger and statement
|
|
||||||
* entries, as layed out in the $data['Entry'] array. The array is
|
|
||||||
* overloaded, since it is used to create both ledger _and_ statement
|
|
||||||
* entries.
|
|
||||||
*
|
|
||||||
* $data
|
|
||||||
* - Transaction
|
|
||||||
* - [MANDATORY]
|
|
||||||
* - type (INVOICE, RECEIPT)
|
|
||||||
* - account_id
|
|
||||||
* - crdr
|
|
||||||
* - [OPTIONAL]
|
|
||||||
* - stamp
|
|
||||||
* (default: NOW)
|
|
||||||
* - comment
|
|
||||||
* - [AUTOMATICALLY SET] (if set, these items will be overwritten)
|
|
||||||
* - id
|
|
||||||
* - amount
|
|
||||||
* - customer_id
|
|
||||||
* - ledger_id
|
|
||||||
*
|
|
||||||
* - Entry (array)
|
|
||||||
* - [MANDATORY]
|
|
||||||
* - type (CHARGE, DISBURSEMENT)
|
|
||||||
* - account_id
|
|
||||||
* - crdr
|
|
||||||
* - amount
|
|
||||||
* - [OPTIONAL]
|
|
||||||
* - effective_date
|
|
||||||
* - through_date
|
|
||||||
* - due_date
|
|
||||||
* - comment (used for statement or ledger entry, based on context)
|
|
||||||
* - ledger_entry_comment
|
|
||||||
* - statement_entry_comment
|
|
||||||
* - Tender
|
|
||||||
* - [MANDATORY]
|
|
||||||
* - tender_type_id
|
|
||||||
* - [OPTIONAL]
|
|
||||||
* - name
|
|
||||||
* (default: Entry Account Name & data1)
|
|
||||||
* - data1, data2, data3, data4
|
|
||||||
* - comment
|
|
||||||
* - [AUTOMATICALLY SET] (if set, these items will be overwritten)
|
|
||||||
* - id
|
|
||||||
* - ledger_entry_id
|
|
||||||
* - deposit_transaction_id
|
|
||||||
* - nsf_transaction_id
|
|
||||||
* - [AUTOMATICALLY SET] (if set, these items will be overwritten)
|
|
||||||
* - id
|
|
||||||
* - transaction_id
|
|
||||||
* - ledger_id
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
function addTransaction($transaction, $entries, $subtype = null) {
|
|
||||||
$this->prEnter(compact('transaction', 'entries', 'subtype'));
|
|
||||||
|
|
||||||
// Verify that we have a transaction and entries
|
|
||||||
if (empty($transaction) ||
|
|
||||||
($transaction['type'] !== 'CLOSE' && empty($entries)))
|
|
||||||
return $this->prReturn(array('error' => true));
|
|
||||||
|
|
||||||
// set ledger ID as the current ledger of the specified account
|
|
||||||
if (empty($transaction['ledger_id']))
|
|
||||||
$transaction['ledger_id'] =
|
|
||||||
$this->Account->currentLedgerID($transaction['account_id']);
|
|
||||||
|
|
||||||
// Automatically figure out the customer if we have the lease
|
|
||||||
if (!empty($transaction['lease_id']) && empty($transaction['customer_id'])) {
|
|
||||||
$L = new Lease();
|
|
||||||
$L->recursive = -1;
|
|
||||||
$lease = $L->read(null, $transaction['lease_id']);
|
|
||||||
$transaction['customer_id'] = $lease['Lease']['customer_id'];
|
|
||||||
}
|
|
||||||
|
|
||||||
// Break each entry out of the combined statement/ledger entry
|
|
||||||
// and into individual entries appropriate for saving. While
|
|
||||||
// we're at it, calculate the transaction total as well.
|
|
||||||
$transaction['amount'] = 0;
|
|
||||||
foreach ($entries AS &$entry) {
|
|
||||||
// Ensure these items are null'ed out so we don't
|
|
||||||
// accidentally pick up stale data.
|
|
||||||
$le1 = $le1_tender = $le2 = $se = null;
|
|
||||||
|
|
||||||
// Add entry amount into the transaction total
|
|
||||||
$transaction['amount'] += $entry['amount'];
|
|
||||||
|
|
||||||
// Set up our comments, possibly using the default 'comment' field
|
|
||||||
if (empty($entry['ledger_entry_comment'])) {
|
|
||||||
if ($transaction['type'] != 'INVOICE' && !empty($entry['comment']))
|
|
||||||
$entry['ledger_entry_comment'] = $entry['comment'];
|
|
||||||
else
|
|
||||||
$entry['ledger_entry_comment'] = null;
|
|
||||||
}
|
|
||||||
if (empty($entry['statement_entry_comment'])) {
|
|
||||||
if ($transaction['type'] == 'INVOICE' && !empty($entry['comment']))
|
|
||||||
$entry['statement_entry_comment'] = $entry['comment'];
|
|
||||||
else
|
|
||||||
$entry['statement_entry_comment'] = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create one half of the Double Ledger Entry (and the Tender)
|
|
||||||
$le1 =
|
|
||||||
array_intersect_key($entry,
|
|
||||||
array_flip(array('ledger_id', 'account_id', 'crdr', 'amount')));
|
|
||||||
$le1['comment'] = $entry['ledger_entry_comment'];
|
|
||||||
$le1_tender = isset($entry['Tender']) ? $entry['Tender'] : null;
|
|
||||||
|
|
||||||
// Create the second half of the Double Ledger Entry
|
|
||||||
if ($transaction['type'] == 'CLOSE') {
|
|
||||||
$le2 =
|
|
||||||
array_intersect_key($entry,
|
|
||||||
array_flip(array('account_id', 'amount')));
|
|
||||||
$le2['ledger_id'] = $entry['new_ledger_id'];
|
|
||||||
$le2['crdr'] = strtoupper($this->Account->fundamentalOpposite($le1['crdr']));
|
|
||||||
$le2['comment'] = "Ledger Balance Forward (b/f)";
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
$le2 =
|
|
||||||
array_intersect_key($entry,
|
|
||||||
array_flip(array('amount'))) +
|
|
||||||
array_intersect_key($transaction,
|
|
||||||
array_flip(array('ledger_id', 'account_id', 'crdr')));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create the statement entry
|
|
||||||
$se =
|
|
||||||
array_intersect_key($entry,
|
|
||||||
array_flip(array('type', 'account_id', 'amount',
|
|
||||||
'effective_date', 'through_date', 'due_date',
|
|
||||||
'customer_id', 'lease_id',
|
|
||||||
'charge_entry_id'))) +
|
|
||||||
array_intersect_key($transaction,
|
|
||||||
array_flip(array('customer_id', 'lease_id')));
|
|
||||||
$se['comment'] = $entry['statement_entry_comment'];
|
|
||||||
|
|
||||||
// (DISBURSEMENTS will have statement entries created below, when
|
|
||||||
// assigning credits, and DEPOSITS don't have statement entries)
|
|
||||||
if (empty($transaction['customer_id']) ||
|
|
||||||
($transaction['account_id'] == $this->Account->accountReceivableAccountID() &&
|
|
||||||
$transaction['crdr'] == 'CREDIT'))
|
|
||||||
$se = null;
|
|
||||||
|
|
||||||
// NSF transactions don't use LedgerEntries
|
|
||||||
// REVISIT <AP>: 20090731
|
|
||||||
// Doesn't seem right... probably doing this because of the
|
|
||||||
// single A/R entry we add below for NSF
|
|
||||||
if ($subtype === 'NSF')
|
|
||||||
$le1 = $le1_tender = $le2 = null;
|
|
||||||
|
|
||||||
// Replace combined entry with our new individual entries
|
|
||||||
$entry = compact('le1', 'le1_tender', 'le2', 'se');
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($subtype === 'NSF') {
|
|
||||||
// REVISIT <AP>: 20090731
|
|
||||||
// Should we be doing this, or just doing individual ledger entries
|
|
||||||
// that were created above before we nulled them out
|
|
||||||
array_unshift($entries,
|
|
||||||
array('le1' => array('account_id' => $transaction['account_id'],
|
|
||||||
'crdr' => 'DEBIT',
|
|
||||||
'amount' => $transaction['amount']),
|
|
||||||
'le2' => array('account_id' => $this->Account->accountReceivableAccountID(),
|
|
||||||
'crdr' => 'CREDIT',
|
|
||||||
'amount' => $transaction['amount'])
|
|
||||||
));
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->pr(20, compact('transaction', 'entries'));
|
|
||||||
|
|
||||||
// Move forward, verifying and saving everything.
|
|
||||||
$ret = array();
|
|
||||||
if (!$this->verifyTransaction($transaction, $entries))
|
|
||||||
return $this->prReturn(array('error' => true) + $ret);
|
|
||||||
|
|
||||||
// Save transaction to the database
|
|
||||||
$this->create();
|
|
||||||
if (!$this->save($transaction))
|
|
||||||
return $this->prReturn(array('error' => true) + $ret);
|
|
||||||
$transaction_stamp = $this->field('stamp');
|
|
||||||
|
|
||||||
// Set up our return ids array
|
|
||||||
$ret['transaction_id'] = $this->id;
|
|
||||||
$ret['entries'] = array();
|
|
||||||
$ret['error'] = false;
|
|
||||||
|
|
||||||
// Go through the entries
|
|
||||||
foreach ($entries AS $e_index => &$entry) {
|
|
||||||
// Ensure these items are null'ed out so we don't
|
|
||||||
// accidentally pick up stale data.
|
|
||||||
$le1 = $le1_tender = $le2 = $se = null;
|
|
||||||
extract($entry);
|
|
||||||
|
|
||||||
if (!empty($le1) && !empty($le2)) {
|
|
||||||
$le1['transaction_id'] = $le2['transaction_id'] = $ret['transaction_id'];
|
|
||||||
if (isset($le1_tender))
|
|
||||||
$le1_tender['customer_id'] = $transaction['customer_id'];
|
|
||||||
$result = $this->LedgerEntry->DoubleEntry->addDoubleEntry($le1, $le2, $le1_tender);
|
|
||||||
$ret['entries'][$e_index]['DoubleEntry'] = $result;
|
|
||||||
if ($result['error']) {
|
|
||||||
$ret['error'] = true;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!empty($se)) {
|
|
||||||
$se['transaction_id'] = $ret['transaction_id'];
|
|
||||||
$se += array('effective_date' => $transaction_stamp);
|
|
||||||
$result = $this->StatementEntry->addStatementEntry($se);
|
|
||||||
$ret['entries'][$e_index]['StatementEntry'] = $result;
|
|
||||||
if ($result['error']) {
|
|
||||||
$ret['error'] = true;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($transaction['account_id'] == $this->Account->accountReceivableAccountID()
|
|
||||||
&& !$ret['error']) {
|
|
||||||
$result = $this->StatementEntry->assignCredits
|
|
||||||
(null,
|
|
||||||
($transaction['crdr'] == 'CREDIT'
|
|
||||||
? $ret['transaction_id']
|
|
||||||
: null),
|
|
||||||
($transaction['crdr'] == 'CREDIT' && !empty($transaction['assign_charge_entry_id'])
|
|
||||||
? $transaction['assign_charge_entry_id']
|
|
||||||
: null),
|
|
||||||
(!empty($transaction['disbursement_type'])
|
|
||||||
? $transaction['disbursement_type']
|
|
||||||
: null),
|
|
||||||
$transaction['customer_id'],
|
|
||||||
$transaction['lease_id']
|
|
||||||
);
|
|
||||||
|
|
||||||
$ret['assigned'] = $result;
|
|
||||||
if ($result['error'])
|
|
||||||
$ret['error'] = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return $this->prReturn($ret);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
* function: addNsf
|
|
||||||
* - Adds NSF transaction
|
|
||||||
*/
|
|
||||||
|
|
||||||
function addNsf($tender, $stamp) {
|
|
||||||
$this->prEnter(compact('tender', 'stamp'));
|
|
||||||
|
|
||||||
$ret = array();
|
|
||||||
|
|
||||||
// Enter the NSF
|
|
||||||
// This is the transaction pulling money from the bank account
|
|
||||||
// and recording it in the NSF account. It has nothing to do
|
|
||||||
// with the customer statement (charges, disbursements, credits, etc).
|
|
||||||
$bounce_result = $this->addDeposit
|
|
||||||
(array('Transaction' => array(),
|
|
||||||
'Entry' => array(array('tender_id' => null,
|
|
||||||
'account_id' => $this->Account->nsfAccountID(),
|
|
||||||
'amount' => -1 * $tender['LedgerEntry']['amount'],
|
|
||||||
))),
|
|
||||||
$tender['Transaction']['account_id']);
|
|
||||||
|
|
||||||
$this->pr(20, compact('bounce_result'));
|
|
||||||
$ret['bounce'] = $bounce_result;
|
|
||||||
if ($bounce_result['error'])
|
|
||||||
return $this->prReturn(array('error' => true) + $ret);
|
|
||||||
|
|
||||||
// Since we may have saved the nsf transaction with a null
|
|
||||||
// timestamp, query it back out of the database to find out
|
|
||||||
// what timestamp was _really_ specified, for later use.
|
|
||||||
$bounce = $this->find
|
|
||||||
('first', array('contain' => false, 'id' => $bounce_result['transaction_id']));
|
|
||||||
$this->pr(20, compact('bounce'));
|
|
||||||
$stamp = $bounce['Transaction']['stamp'];
|
|
||||||
|
|
||||||
// OK, now move into customer realm, finding all statement
|
|
||||||
// entries that were affected by the bad payment (tender).
|
|
||||||
$nsf_ledger_entry = $this->LedgerEntry->find
|
|
||||||
('first', array
|
|
||||||
('contain' => array('Transaction' =>
|
|
||||||
array(//'fields' => array(),
|
|
||||||
'StatementEntry' =>
|
|
||||||
array(//'fields' => array(),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
'conditions' => array('LedgerEntry.id' => $tender['LedgerEntry']['id']),
|
|
||||||
));
|
|
||||||
|
|
||||||
$this->pr(20, compact('nsf_ledger_entry'));
|
|
||||||
if (!$nsf_ledger_entry)
|
|
||||||
return $this->prReturn(array('error' => true) + $ret);
|
|
||||||
|
|
||||||
// Build a transaction to adjust all of the statement entries
|
|
||||||
$rollback = array('Transaction' => array(), 'Entry' => array());
|
|
||||||
|
|
||||||
$rollback['Transaction']['stamp'] = $stamp;
|
|
||||||
$rollback['Transaction']['type'] = 'RECEIPT';
|
|
||||||
$rollback['Transaction']['crdr'] = 'DEBIT'; // Unused... keeps verifyTx happy
|
|
||||||
$rollback['Transaction']['account_id'] = $this->Account->nsfAccountID();
|
|
||||||
$rollback['Transaction']['customer_id'] = $tender['Tender']['customer_id'];
|
|
||||||
$rollback['Transaction']['amount'] = -1 * $tender['LedgerEntry']['amount'];
|
|
||||||
|
|
||||||
foreach ($nsf_ledger_entry['Transaction']['StatementEntry'] AS $disbursement) {
|
|
||||||
if ($disbursement['type'] === 'SURPLUS') {
|
|
||||||
$disbursement['type'] = 'VOID';
|
|
||||||
$this->StatementEntry->id = $disbursement['id'];
|
|
||||||
$this->StatementEntry->saveField('type', $disbursement['type']);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
$rollback['Entry'][] =
|
|
||||||
array('type' => $disbursement['type'],
|
|
||||||
'amount' => -1 * $disbursement['amount'],
|
|
||||||
'account_id' => $this->Account->nsfAccountID(),
|
|
||||||
'customer_id' => $disbursement['customer_id'],
|
|
||||||
'lease_id' => $disbursement['lease_id'],
|
|
||||||
'charge_entry_id' => $disbursement['charge_entry_id'],
|
|
||||||
'effective_date' => $stamp,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Record the transaction, which will un-pay previously paid
|
|
||||||
// charges, void any credits, and other similar work.
|
|
||||||
if (count($rollback['Entry'])) {
|
|
||||||
$rollback_result = $this->addTransaction($rollback['Transaction'], $rollback['Entry'], 'NSF');
|
|
||||||
$this->pr(20, compact('rollback', 'rollback_result'));
|
|
||||||
$ret['rollback'] = $rollback_result;
|
|
||||||
if ($rollback_result['error'])
|
|
||||||
return $this->prReturn(array('error' => true) + $ret);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add NSF Charge
|
|
||||||
$charge_result = $this->addInvoice
|
|
||||||
(array('Transaction' => compact('stamp'),
|
|
||||||
|
|
||||||
'Entry' =>
|
|
||||||
array
|
|
||||||
(array('account_id' => $this->Account->nsfChargeAccountID(),
|
|
||||||
'effective_date' => $stamp,
|
|
||||||
// REVISIT <AP>: 20090730
|
|
||||||
// BAD, BAD, BAD... who would actually
|
|
||||||
// hardcode a value like this???? ;-)
|
|
||||||
'amount' => 35,
|
|
||||||
'comment' => "NSF: " . $tender['Tender']['name'],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
$tender['Tender']['customer_id']);
|
|
||||||
|
|
||||||
$this->pr(20, compact('charge_result'));
|
|
||||||
$ret['charge'] = $charge_result;
|
|
||||||
if ($charge_result['error'])
|
|
||||||
return $this->prReturn(array('error' => true) + $ret);
|
|
||||||
|
|
||||||
$ret['nsf_transaction_id'] = $ret['bounce']['transaction_id'];
|
|
||||||
if (!empty($ret['rollback']))
|
|
||||||
$ret['nsf_ledger_entry_id'] = $ret['rollback']['entries'][0]['DoubleEntry']['Entry1']['ledger_entry_id'];
|
|
||||||
return $this->prReturn($ret + array('error' => false));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
* function: stats
|
|
||||||
* - Returns summary data from the requested transaction
|
|
||||||
*/
|
|
||||||
function stats($id = null, $query = null, $balance_account_id = null) {
|
|
||||||
$this->prEnter(compact('id', 'query'));
|
|
||||||
|
|
||||||
$this->queryInit($query);
|
|
||||||
unset($query['group']);
|
|
||||||
|
|
||||||
if (isset($id)) {
|
|
||||||
$query['conditions'][] = array('Transaction.id' => $id);
|
|
||||||
$query['group'] = 'Transaction.id';
|
|
||||||
}
|
|
||||||
else
|
|
||||||
// CakePHP seems to automagically add in our ID as a part
|
|
||||||
// of the query conditions, but only on a 'first' query,
|
|
||||||
// not an 'all'. I suppose this is helpful :-/
|
|
||||||
unset($this->id);
|
|
||||||
|
|
||||||
if (empty($query['fields']))
|
|
||||||
$query['fields'] = array();
|
|
||||||
|
|
||||||
$stats = array();
|
|
||||||
foreach ($this->hasMany AS $table => $association) {
|
|
||||||
// Only calculate stats for *Entry types
|
|
||||||
if (!preg_match("/Entry$/", $table) &&
|
|
||||||
!preg_match("/Entry$/", $association['className']))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
$squery = $query;
|
|
||||||
$squery['link'][$table] = array('fields' => array());
|
|
||||||
|
|
||||||
if ($table == 'LedgerEntry') {
|
|
||||||
if (isset($balance_account_id)) {
|
|
||||||
$squery['link']['LedgerEntry']['Account'] = array('fields' => array());
|
|
||||||
$squery['conditions'][] = array("Account.id" => $balance_account_id);
|
|
||||||
}
|
|
||||||
|
|
||||||
$squery['fields'] = array_merge($squery['fields'],
|
|
||||||
$this->LedgerEntry->debitCreditFields(true, $balance_account_id != null));
|
|
||||||
}
|
|
||||||
elseif ($table == 'StatementEntry') {
|
|
||||||
$squery['fields'] = array_merge($squery['fields'],
|
|
||||||
$this->StatementEntry->chargeDisbursementFields(true));
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
$squery['fields'][] = "SUM({$table}.amount) AS total";
|
|
||||||
$squery['fields'][] = "COUNT({$table}.id) AS entries";
|
|
||||||
}
|
|
||||||
$stats[$table] = $this->find('first', $squery);
|
|
||||||
// REVISIT <AP>: 20090724
|
|
||||||
// [0][0] is for when we do an 'all' query. This can
|
|
||||||
// be removed at some point, but I'm keeping it while
|
|
||||||
// toggling between 'all' and 'first' (testing).
|
|
||||||
if (isset($stats[$table][0][0]))
|
|
||||||
$stats[$table] += $stats[$table][0][0];
|
|
||||||
else
|
|
||||||
$stats[$table] += $stats[$table][0];
|
|
||||||
unset($stats[$table][0]);
|
|
||||||
}
|
|
||||||
|
|
||||||
return $this->prReturn($stats);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
?>
|
|
||||||
@@ -1,174 +0,0 @@
|
|||||||
<?php
|
|
||||||
class Unit extends AppModel {
|
|
||||||
|
|
||||||
var $name = 'Unit';
|
|
||||||
var $validate = array(
|
|
||||||
'id' => array('numeric'),
|
|
||||||
'unit_size_id' => array('numeric'),
|
|
||||||
'name' => array('notempty'),
|
|
||||||
'sort_order' => array('numeric'),
|
|
||||||
'walk_order' => array('numeric'),
|
|
||||||
'deposit' => array('money'),
|
|
||||||
'amount' => array('money')
|
|
||||||
);
|
|
||||||
|
|
||||||
var $belongsTo = array(
|
|
||||||
'UnitSize',
|
|
||||||
);
|
|
||||||
|
|
||||||
var $hasOne = array(
|
|
||||||
'CurrentLease' => array(
|
|
||||||
'className' => 'Lease',
|
|
||||||
'conditions' => 'CurrentLease.moveout_date IS NULL',
|
|
||||||
),
|
|
||||||
);
|
|
||||||
|
|
||||||
var $hasMany = array(
|
|
||||||
'Lease',
|
|
||||||
);
|
|
||||||
|
|
||||||
//var $default_log_level = array('log' => 30, 'show' => 15);
|
|
||||||
|
|
||||||
/**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
* helpers: status enumerations
|
|
||||||
*/
|
|
||||||
|
|
||||||
function statusEnums() {
|
|
||||||
static $status_enums;
|
|
||||||
if (!isset($status_enums))
|
|
||||||
$status_enums = $this->getEnumValues('status');
|
|
||||||
return $status_enums;
|
|
||||||
}
|
|
||||||
|
|
||||||
function activeStatusEnums() {
|
|
||||||
return array_diff_key($this->statusEnums(), array(''=>1, 'DELETED'=>1));
|
|
||||||
}
|
|
||||||
|
|
||||||
function statusValue($enum) {
|
|
||||||
$enums = $this->statusEnums();
|
|
||||||
return $enums[$enum];
|
|
||||||
}
|
|
||||||
|
|
||||||
function occupiedEnumValue() {
|
|
||||||
return $this->statusValue('OCCUPIED');
|
|
||||||
}
|
|
||||||
|
|
||||||
function conditionOccupied() {
|
|
||||||
return ('Unit.status >= ' . $this->statusValue('OCCUPIED'));
|
|
||||||
}
|
|
||||||
|
|
||||||
function conditionVacant() {
|
|
||||||
return ('Unit.status BETWEEN ' .
|
|
||||||
($this->statusValue('UNAVAILABLE')+1) .
|
|
||||||
' AND ' .
|
|
||||||
($this->statusValue('OCCUPIED')-1));
|
|
||||||
}
|
|
||||||
|
|
||||||
function conditionUnavailable() {
|
|
||||||
return ('Unit.status <= ' . $this->statusValue('UNAVAILABLE'));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
* function: allowedStatusSet
|
|
||||||
* - Returns the status set allowed for the given unit
|
|
||||||
*/
|
|
||||||
function allowedStatusSet($id) {
|
|
||||||
$this->prEnter(compact('id'));
|
|
||||||
$this->id = $id;
|
|
||||||
$old_status = $this->field('status');
|
|
||||||
$old_val = $this->statusValue($old_status);
|
|
||||||
$this->pr(17, compact('old_status', 'old_val'));
|
|
||||||
|
|
||||||
$enums = $this->activeStatusEnums();
|
|
||||||
$this->pr(21, compact('enums'));
|
|
||||||
|
|
||||||
foreach ($enums AS $enum => $val) {
|
|
||||||
if (($old_val < $this->occupiedEnumValue()) !=
|
|
||||||
($val < $this->occupiedEnumValue())) {
|
|
||||||
unset($enums[$enum]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return $this->prReturn($enums);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
* function: updateStatus
|
|
||||||
* - Update the given unit to the given status
|
|
||||||
*/
|
|
||||||
function updateStatus($id, $status, $check = false) {
|
|
||||||
$this->prEnter(compact('id', 'status', 'check'));
|
|
||||||
|
|
||||||
/* if ($check) { */
|
|
||||||
/* $old_status = $this->field('status'); */
|
|
||||||
/* $this->pr(17, compact('old_status')); */
|
|
||||||
/* if ($this->statusValue($old_status) < $this->occupiedEnumValue() && */
|
|
||||||
/* $this->statusValue($status) >= $this->occupiedEnumValue()) */
|
|
||||||
/* { */
|
|
||||||
/* die("Can't transition a unit from vacant to occupied"); */
|
|
||||||
/* return $this->prReturn(false); */
|
|
||||||
/* } */
|
|
||||||
/* if ($this->statusValue($old_status) >= $this->occupiedEnumValue() && */
|
|
||||||
/* $this->statusValue($status) < $this->occupiedEnumValue()) */
|
|
||||||
/* { */
|
|
||||||
/* die("Can't transition a unit from occupied to vacant"); */
|
|
||||||
/* return $this->prReturn(false); */
|
|
||||||
/* } */
|
|
||||||
/* } */
|
|
||||||
|
|
||||||
if ($check) {
|
|
||||||
if (!array_key_exists($status, $this->allowedStatusSet($id)))
|
|
||||||
return $this->prReturn(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->id = $id;
|
|
||||||
$this->saveField('status', $status);
|
|
||||||
return $this->prReturn(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
**************************************************************************
|
|
||||||
* function: stats
|
|
||||||
* - Returns summary data from the requested customer.
|
|
||||||
*/
|
|
||||||
|
|
||||||
function stats($id = null) {
|
|
||||||
if (!$id)
|
|
||||||
return null;
|
|
||||||
|
|
||||||
// Get the basic information necessary
|
|
||||||
$unit = $this->find('first',
|
|
||||||
array('contain' => array
|
|
||||||
('Lease' => array
|
|
||||||
('fields' => array('Lease.id')),
|
|
||||||
|
|
||||||
'CurrentLease' => array
|
|
||||||
('fields' => array('CurrentLease.id'))),
|
|
||||||
|
|
||||||
'conditions' => array
|
|
||||||
(array('Unit.id' => $id)),
|
|
||||||
));
|
|
||||||
|
|
||||||
// Get the stats for the current lease
|
|
||||||
$stats['CurrentLease'] = $this->Lease->stats($unit['CurrentLease']['id']);
|
|
||||||
|
|
||||||
// Sum the stats for all leases together
|
|
||||||
foreach ($unit['Lease'] AS $lease) {
|
|
||||||
$this->statsMerge($stats['Lease'], $this->Lease->stats($lease['id']));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Return the collection
|
|
||||||
return $stats;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,25 +0,0 @@
|
|||||||
<?php
|
|
||||||
class UnitSize extends AppModel {
|
|
||||||
|
|
||||||
var $name = 'UnitSize';
|
|
||||||
var $validate = array(
|
|
||||||
'id' => array('numeric'),
|
|
||||||
'unit_type_id' => array('numeric'),
|
|
||||||
'code' => array('notempty'),
|
|
||||||
'name' => array('notempty'),
|
|
||||||
'width' => array('numeric'),
|
|
||||||
'depth' => array('numeric'),
|
|
||||||
'deposit' => array('money'),
|
|
||||||
'amount' => array('money')
|
|
||||||
);
|
|
||||||
|
|
||||||
var $belongsTo = array(
|
|
||||||
'UnitType',
|
|
||||||
);
|
|
||||||
|
|
||||||
var $hasMany = array(
|
|
||||||
'Unit',
|
|
||||||
);
|
|
||||||
|
|
||||||
}
|
|
||||||
?>
|
|
||||||
@@ -1,16 +0,0 @@
|
|||||||
<?php
|
|
||||||
class UnitType extends AppModel {
|
|
||||||
|
|
||||||
var $name = 'UnitType';
|
|
||||||
var $validate = array(
|
|
||||||
'id' => array('numeric'),
|
|
||||||
'code' => array('notempty'),
|
|
||||||
'name' => array('notempty')
|
|
||||||
);
|
|
||||||
|
|
||||||
var $hasMany = array(
|
|
||||||
'UnitSize',
|
|
||||||
);
|
|
||||||
|
|
||||||
}
|
|
||||||
?>
|
|
||||||
@@ -1,5 +0,0 @@
|
|||||||
To install copy the debug_kit directory to the plugins folder and include the toolbar component in your app_controller.php:
|
|
||||||
|
|
||||||
$components = array('DebugKit.Toolbar');
|
|
||||||
|
|
||||||
+ Set debug mode to at least 1.
|
|
||||||
@@ -1,471 +0,0 @@
|
|||||||
<?php
|
|
||||||
/* SVN FILE: $Id$ */
|
|
||||||
/**
|
|
||||||
* DebugKit DebugToolbar Component
|
|
||||||
*
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* PHP versions 4 and 5
|
|
||||||
*
|
|
||||||
* CakePHP : Rapid Development Framework <http://www.cakephp.org/>
|
|
||||||
* Copyright 2006-2008, Cake Software Foundation, Inc.
|
|
||||||
* 1785 E. Sahara Avenue, Suite 490-204
|
|
||||||
* Las Vegas, Nevada 89104
|
|
||||||
*
|
|
||||||
* Licensed under The MIT License
|
|
||||||
* Redistributions of files must retain the above copyright notice.
|
|
||||||
*
|
|
||||||
* @filesource
|
|
||||||
* @copyright Copyright 2006-2008, Cake Software Foundation, Inc.
|
|
||||||
* @link http://www.cakefoundation.org/projects/info/cakephp CakePHP Project
|
|
||||||
* @package cake
|
|
||||||
* @subpackage cake.cake.libs.
|
|
||||||
* @since CakePHP v 1.2.0.4487
|
|
||||||
* @version $Revision$
|
|
||||||
* @modifiedby $LastChangedBy$
|
|
||||||
* @lastmodified $Date$
|
|
||||||
* @license http://www.opensource.org/licenses/mit-license.php The MIT License
|
|
||||||
*/
|
|
||||||
class ToolbarComponent extends Object {
|
|
||||||
/**
|
|
||||||
* Controller instance reference
|
|
||||||
*
|
|
||||||
* @var object
|
|
||||||
*/
|
|
||||||
var $controller;
|
|
||||||
/**
|
|
||||||
* Components used by DebugToolbar
|
|
||||||
*
|
|
||||||
* @var array
|
|
||||||
*/
|
|
||||||
var $components = array('RequestHandler');
|
|
||||||
/**
|
|
||||||
* The default panels the toolbar uses.
|
|
||||||
* which panels are used can be configured when attaching the component
|
|
||||||
*
|
|
||||||
* @var array
|
|
||||||
*/
|
|
||||||
var $_defaultPanels = array('session', 'request', 'sqlLog', 'timer', 'log', 'memory', 'variables');
|
|
||||||
/**
|
|
||||||
* Loaded panel objects.
|
|
||||||
*
|
|
||||||
* @var array
|
|
||||||
*/
|
|
||||||
var $panels = array();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* fallback for javascript settings
|
|
||||||
*
|
|
||||||
* @var array
|
|
||||||
**/
|
|
||||||
var $_defaultJavascript = array(
|
|
||||||
'behavior' => '/debug_kit/js/js_debug_toolbar'
|
|
||||||
);
|
|
||||||
/**
|
|
||||||
* javascript files component will be using.
|
|
||||||
*
|
|
||||||
* @var array
|
|
||||||
**/
|
|
||||||
var $javascript = array();
|
|
||||||
/**
|
|
||||||
* initialize
|
|
||||||
*
|
|
||||||
* If debug is off the component will be disabled and not do any further time tracking
|
|
||||||
* or load the toolbar helper.
|
|
||||||
*
|
|
||||||
* @return bool
|
|
||||||
**/
|
|
||||||
function initialize(&$controller, $settings) {
|
|
||||||
if (Configure::read('debug') == 0) {
|
|
||||||
$this->enabled = false;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
App::import('Vendor', 'DebugKit.DebugKitDebugger');
|
|
||||||
|
|
||||||
DebugKitDebugger::startTimer('componentInit', __('Component initialization and startup', true));
|
|
||||||
if (!isset($settings['panels'])) {
|
|
||||||
$settings['panels'] = $this->_defaultPanels;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isset($settings['javascript'])) {
|
|
||||||
$settings['javascript'] = $this->_setJavascript($settings['javascript']);
|
|
||||||
} else {
|
|
||||||
$settings['javascript'] = $this->_defaultJavascript;
|
|
||||||
}
|
|
||||||
$this->_loadPanels($settings['panels']);
|
|
||||||
unset($settings['panels']);
|
|
||||||
|
|
||||||
$this->_set($settings);
|
|
||||||
$this->controller =& $controller;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Component Startup
|
|
||||||
*
|
|
||||||
* @return bool
|
|
||||||
**/
|
|
||||||
function startup(&$controller) {
|
|
||||||
$currentViewClass = $controller->view;
|
|
||||||
$this->_makeViewClass($currentViewClass);
|
|
||||||
$controller->view = 'DebugKit.Debug';
|
|
||||||
if (!isset($controller->params['url']['ext']) || (isset($controller->params['url']['ext']) && $controller->params['url']['ext'] == 'html')) {
|
|
||||||
$format = 'Html';
|
|
||||||
} else {
|
|
||||||
$format = 'FirePhp';
|
|
||||||
}
|
|
||||||
$controller->helpers['DebugKit.Toolbar'] = array('output' => sprintf('DebugKit.%sToolbar', $format));
|
|
||||||
$panels = array_keys($this->panels);
|
|
||||||
foreach ($panels as $panelName) {
|
|
||||||
$this->panels[$panelName]->startup($controller);
|
|
||||||
}
|
|
||||||
DebugKitDebugger::stopTimer('componentInit');
|
|
||||||
DebugKitDebugger::startTimer('controllerAction', __('Controller Action', true));
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* beforeRender callback
|
|
||||||
*
|
|
||||||
* Calls beforeRender on all the panels and set the aggregate to the controller.
|
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
**/
|
|
||||||
function beforeRender(&$controller) {
|
|
||||||
DebugKitDebugger::stopTimer('controllerAction');
|
|
||||||
$vars = array();
|
|
||||||
$panels = array_keys($this->panels);
|
|
||||||
|
|
||||||
foreach ($panels as $panelName) {
|
|
||||||
$panel =& $this->panels[$panelName];
|
|
||||||
$vars[$panelName]['content'] = $panel->beforeRender($controller);
|
|
||||||
$elementName = Inflector::underscore($panelName) . '_panel';
|
|
||||||
if (isset($panel->elementName)) {
|
|
||||||
$elementName = $panel->elementName;
|
|
||||||
}
|
|
||||||
$vars[$panelName]['elementName'] = $elementName;
|
|
||||||
$vars[$panelName]['plugin'] = $panel->plugin;
|
|
||||||
$vars[$panelName]['disableTimer'] = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
$controller->set(array('debugToolbarPanels' => $vars, 'debugToolbarJavascript' => $this->javascript));
|
|
||||||
DebugKitDebugger::startTimer('controllerRender', __('Render Controller Action', true));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Load Panels used in the debug toolbar
|
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
* @access protected
|
|
||||||
**/
|
|
||||||
function _loadPanels($panels) {
|
|
||||||
foreach ($panels as $panel) {
|
|
||||||
$className = $panel . 'Panel';
|
|
||||||
if (!class_exists($className) && !App::import('Vendor', $className)) {
|
|
||||||
trigger_error(sprintf(__('Could not load DebugToolbar panel %s', true), $panel), E_USER_WARNING);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
$panelObj =& new $className();
|
|
||||||
if (is_subclass_of($panelObj, 'DebugPanel') || is_subclass_of($panelObj, 'debugpanel')) {
|
|
||||||
$this->panels[$panel] =& $panelObj;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the javascript to user scripts.
|
|
||||||
*
|
|
||||||
* Set either script key to false to exclude it from the rendered layout.
|
|
||||||
*
|
|
||||||
* @param array $scripts Javascript config information
|
|
||||||
* @return array
|
|
||||||
* @access protected
|
|
||||||
**/
|
|
||||||
function _setJavascript($scripts) {
|
|
||||||
$behavior = false;
|
|
||||||
if (!is_array($scripts)) {
|
|
||||||
$scripts = (array)$scripts;
|
|
||||||
}
|
|
||||||
if (isset($scripts[0])) {
|
|
||||||
$behavior = $scripts[0];
|
|
||||||
}
|
|
||||||
if (isset($scripts['behavior'])) {
|
|
||||||
$behavior = $scripts['behavior'];
|
|
||||||
}
|
|
||||||
if (!$behavior) {
|
|
||||||
return array();
|
|
||||||
} elseif ($behavior === true) {
|
|
||||||
$behavior = 'js';
|
|
||||||
}
|
|
||||||
if (strpos($behavior, '/') !== 0) {
|
|
||||||
$behavior .= '_debug_toolbar';
|
|
||||||
}
|
|
||||||
$pluginFile = APP . 'plugins' . DS . 'debug_kit' . DS . 'vendors' . DS . 'js' . DS . $behavior . '.js';
|
|
||||||
if (file_exists($pluginFile)) {
|
|
||||||
$behavior = '/debug_kit/js/' . $behavior . '.js';
|
|
||||||
}
|
|
||||||
return compact('behavior');
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* Makes the DoppleGangerView class if it doesn't already exist.
|
|
||||||
* This allows DebugView to be compatible with all view classes.
|
|
||||||
*
|
|
||||||
* @param string $baseClassName
|
|
||||||
* @access protected
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
function _makeViewClass($baseClassName) {
|
|
||||||
if (!class_exists('DoppelGangerView')) {
|
|
||||||
App::import('View', $baseClassName);
|
|
||||||
if (strpos('View', $baseClassName) === false) {
|
|
||||||
$baseClassName .= 'View';
|
|
||||||
}
|
|
||||||
$class = "class DoppelGangerView extends $baseClassName {}";
|
|
||||||
eval($class);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Debug Panel
|
|
||||||
*
|
|
||||||
* Abstract class for debug panels.
|
|
||||||
*
|
|
||||||
* @package cake.debug_kit
|
|
||||||
*/
|
|
||||||
class DebugPanel extends Object {
|
|
||||||
/**
|
|
||||||
* Defines which plugin this panel is from so the element can be located.
|
|
||||||
*
|
|
||||||
* @var string
|
|
||||||
*/
|
|
||||||
var $plugin = null;
|
|
||||||
/**
|
|
||||||
* startup the panel
|
|
||||||
*
|
|
||||||
* Pull information from the controller / request
|
|
||||||
*
|
|
||||||
* @param object $controller Controller reference.
|
|
||||||
* @return void
|
|
||||||
**/
|
|
||||||
function startup(&$controller) { }
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Prepare output vars before Controller Rendering.
|
|
||||||
*
|
|
||||||
* @param object $controller Controller reference.
|
|
||||||
* @return void
|
|
||||||
**/
|
|
||||||
function beforeRender(&$controller) { }
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Variables Panel
|
|
||||||
*
|
|
||||||
* Provides debug information on the View variables.
|
|
||||||
*
|
|
||||||
* @package cake.debug_kit.panels
|
|
||||||
**/
|
|
||||||
class VariablesPanel extends DebugPanel {
|
|
||||||
var $plugin = 'debug_kit';
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Session Panel
|
|
||||||
*
|
|
||||||
* Provides debug information on the Session contents.
|
|
||||||
*
|
|
||||||
* @package cake.debug_kit.panels
|
|
||||||
**/
|
|
||||||
class SessionPanel extends DebugPanel {
|
|
||||||
var $plugin = 'debug_kit';
|
|
||||||
/**
|
|
||||||
* beforeRender callback
|
|
||||||
*
|
|
||||||
* @param object $controller
|
|
||||||
* @access public
|
|
||||||
* @return array
|
|
||||||
*/
|
|
||||||
function beforeRender(&$controller) {
|
|
||||||
return $controller->Session->read();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Request Panel
|
|
||||||
*
|
|
||||||
* Provides debug information on the Current request params.
|
|
||||||
*
|
|
||||||
* @package cake.debug_kit.panels
|
|
||||||
**/
|
|
||||||
class RequestPanel extends DebugPanel {
|
|
||||||
var $plugin = 'debug_kit';
|
|
||||||
/**
|
|
||||||
* beforeRender callback - grabs request params
|
|
||||||
*
|
|
||||||
* @return array
|
|
||||||
**/
|
|
||||||
function beforeRender(&$controller) {
|
|
||||||
$out = array();
|
|
||||||
$out['params'] = $controller->params;
|
|
||||||
if (isset($controller->Cookie)) {
|
|
||||||
$out['cookie'] = $controller->Cookie->read();
|
|
||||||
}
|
|
||||||
$out['get'] = $_GET;
|
|
||||||
$out['currentRoute'] = Router::currentRoute();
|
|
||||||
return $out;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Timer Panel
|
|
||||||
*
|
|
||||||
* Provides debug information on all timers used in a request.
|
|
||||||
*
|
|
||||||
* @package cake.debug_kit.panels
|
|
||||||
**/
|
|
||||||
class TimerPanel extends DebugPanel {
|
|
||||||
var $plugin = 'debug_kit';
|
|
||||||
/**
|
|
||||||
* startup - add in necessary helpers
|
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
**/
|
|
||||||
function startup(&$controller) {
|
|
||||||
if (!in_array('Number', $controller->helpers)) {
|
|
||||||
$controller->helpers[] = 'Number';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Memory Panel
|
|
||||||
*
|
|
||||||
* Provides debug information on the memory consumption.
|
|
||||||
*
|
|
||||||
* @package cake.debug_kit.panels
|
|
||||||
**/
|
|
||||||
class MemoryPanel extends DebugPanel {
|
|
||||||
var $plugin = 'debug_kit';
|
|
||||||
/**
|
|
||||||
* startup - add in necessary helpers
|
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
**/
|
|
||||||
function startup(&$controller) {
|
|
||||||
if (!in_array('Number', $controller->helpers)) {
|
|
||||||
$controller->helpers[] = 'Number';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* sqlLog Panel
|
|
||||||
*
|
|
||||||
* Provides debug information on the SQL logs and provides links to an ajax explain interface.
|
|
||||||
*
|
|
||||||
* @package cake.debug_kit.panels
|
|
||||||
**/
|
|
||||||
class sqlLogPanel extends DebugPanel {
|
|
||||||
var $plugin = 'debug_kit';
|
|
||||||
|
|
||||||
var $dbConfigs = array();
|
|
||||||
/**
|
|
||||||
* get db configs.
|
|
||||||
*
|
|
||||||
* @param string $controller
|
|
||||||
* @access public
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
function startUp(&$controller) {
|
|
||||||
if (!class_exists('ConnectionManager')) {
|
|
||||||
$this->dbConfigs = array();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
$this->dbConfigs = ConnectionManager::sourceList();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* Get Sql Logs for each DB config
|
|
||||||
*
|
|
||||||
* @param string $controller
|
|
||||||
* @access public
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
function beforeRender(&$controller) {
|
|
||||||
$queryLogs = array();
|
|
||||||
if (!class_exists('ConnectionManager')) {
|
|
||||||
return array();
|
|
||||||
}
|
|
||||||
foreach ($this->dbConfigs as $configName) {
|
|
||||||
$db =& ConnectionManager::getDataSource($configName);
|
|
||||||
if ($db->isInterfaceSupported('showLog')) {
|
|
||||||
ob_start();
|
|
||||||
$db->showLog();
|
|
||||||
$queryLogs[$configName] = ob_get_clean();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return $queryLogs;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Log Panel - Reads log entries made this request.
|
|
||||||
*
|
|
||||||
* @package cake.debug_kit.panels
|
|
||||||
*/
|
|
||||||
class LogPanel extends DebugPanel {
|
|
||||||
var $plugin = 'debug_kit';
|
|
||||||
/**
|
|
||||||
* Log files to scan
|
|
||||||
*
|
|
||||||
* @var array
|
|
||||||
*/
|
|
||||||
var $logFiles = array('error.log', 'debug.log');
|
|
||||||
/**
|
|
||||||
* startup
|
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
**/
|
|
||||||
function startup(&$controller) {
|
|
||||||
if (!class_exists('CakeLog')) {
|
|
||||||
App::import('Core', 'Log');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* beforeRender Callback
|
|
||||||
*
|
|
||||||
* @return array
|
|
||||||
**/
|
|
||||||
function beforeRender(&$controller) {
|
|
||||||
$this->startTime = DebugKitDebugger::requestStartTime();
|
|
||||||
$this->currentTime = DebugKitDebugger::requestTime();
|
|
||||||
$out = array();
|
|
||||||
foreach ($this->logFiles as $log) {
|
|
||||||
$file = LOGS . $log;
|
|
||||||
if (!file_exists($file)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
$out[$log] = $this->_parseFile($file);
|
|
||||||
}
|
|
||||||
return $out;
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* parse a log file and find the relevant entries
|
|
||||||
*
|
|
||||||
* @param string $filename Name of file to read
|
|
||||||
* @access protected
|
|
||||||
* @return array
|
|
||||||
*/
|
|
||||||
function _parseFile($filename) {
|
|
||||||
$file =& new File($filename);
|
|
||||||
$contents = $file->read();
|
|
||||||
$timePattern = '/(\d{4}-\d{2}\-\d{2}\s\d{1,2}\:\d{1,2}\:\d{1,2})/';
|
|
||||||
$chunks = preg_split($timePattern, $contents, -1, PREG_SPLIT_NO_EMPTY | PREG_SPLIT_DELIM_CAPTURE);
|
|
||||||
for ($i = 0, $len = count($chunks); $i < $len; $i += 2) {
|
|
||||||
if (strtotime($chunks[$i]) < $this->startTime) {
|
|
||||||
unset($chunks[$i], $chunks[$i + 1]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return array_values($chunks);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
?>
|
|
||||||
@@ -1,32 +0,0 @@
|
|||||||
<?php
|
|
||||||
/* SVN FILE: $Id$ */
|
|
||||||
/**
|
|
||||||
* Debug Kit App Controller
|
|
||||||
*
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* PHP versions 4 and 5
|
|
||||||
*
|
|
||||||
* CakePHP : Rapid Development Framework <http://www.cakephp.org/>
|
|
||||||
* Copyright 2006-2008, Cake Software Foundation, Inc.
|
|
||||||
* 1785 E. Sahara Avenue, Suite 490-204
|
|
||||||
* Las Vegas, Nevada 89104
|
|
||||||
*
|
|
||||||
* Licensed under The MIT License
|
|
||||||
* Redistributions of files must retain the above copyright notice.
|
|
||||||
*
|
|
||||||
* @filesource
|
|
||||||
* @copyright Copyright 2006-2008, Cake Software Foundation, Inc.
|
|
||||||
* @link http://www.cakefoundation.org/projects/info/cakephp CakePHP Project
|
|
||||||
* @package cake
|
|
||||||
* @subpackage cake.cake.libs.
|
|
||||||
* @since CakePHP v 1.2.0.4487
|
|
||||||
* @version $Revision$
|
|
||||||
* @modifiedby $LastChangedBy$
|
|
||||||
* @lastmodified $Date$
|
|
||||||
* @license http://www.opensource.org/licenses/mit-license.php The MIT License
|
|
||||||
*/
|
|
||||||
class DebugKitAppController extends AppController {
|
|
||||||
|
|
||||||
}
|
|
||||||
?>
|
|
||||||
@@ -1,32 +0,0 @@
|
|||||||
<?php
|
|
||||||
/* SVN FILE: $Id$ */
|
|
||||||
/**
|
|
||||||
* Debug Kit App Model
|
|
||||||
*
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* PHP versions 4 and 5
|
|
||||||
*
|
|
||||||
* CakePHP : Rapid Development Framework <http://www.cakephp.org/>
|
|
||||||
* Copyright 2006-2008, Cake Software Foundation, Inc.
|
|
||||||
* 1785 E. Sahara Avenue, Suite 490-204
|
|
||||||
* Las Vegas, Nevada 89104
|
|
||||||
*
|
|
||||||
* Licensed under The MIT License
|
|
||||||
* Redistributions of files must retain the above copyright notice.
|
|
||||||
*
|
|
||||||
* @filesource
|
|
||||||
* @copyright Copyright 2006-2008, Cake Software Foundation, Inc.
|
|
||||||
* @link http://www.cakefoundation.org/projects/info/cakephp CakePHP Project
|
|
||||||
* @package cake
|
|
||||||
* @subpackage cake.cake.libs.
|
|
||||||
* @since CakePHP v 1.2.0.4487
|
|
||||||
* @version $Revision$
|
|
||||||
* @modifiedby $LastChangedBy$
|
|
||||||
* @lastmodified $Date$
|
|
||||||
* @license http://www.opensource.org/licenses/mit-license.php The MIT License
|
|
||||||
*/
|
|
||||||
class DebugKitAppModel extends AppModel {
|
|
||||||
|
|
||||||
}
|
|
||||||
?>
|
|
||||||
@@ -1,323 +0,0 @@
|
|||||||
<?php
|
|
||||||
/* SVN FILE: $Id$ */
|
|
||||||
/**
|
|
||||||
* DebugToolbar Test
|
|
||||||
*
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* PHP versions 4 and 5
|
|
||||||
*
|
|
||||||
* CakePHP : Rapid Development Framework <http://www.cakephp.org/>
|
|
||||||
* Copyright 2006-2008, Cake Software Foundation, Inc.
|
|
||||||
* 1785 E. Sahara Avenue, Suite 490-204
|
|
||||||
* Las Vegas, Nevada 89104
|
|
||||||
*
|
|
||||||
* Licensed under The MIT License
|
|
||||||
* Redistributions of files must retain the above copyright notice.
|
|
||||||
*
|
|
||||||
* @filesource
|
|
||||||
* @copyright Copyright 2006-2008, Cake Software Foundation, Inc.
|
|
||||||
* @link http://www.cakefoundation.org/projects/info/cakephp CakePHP Project
|
|
||||||
* @package cake
|
|
||||||
* @subpackage cake.cake.libs.
|
|
||||||
* @since CakePHP v 1.2.0.4487
|
|
||||||
* @version $Revision$
|
|
||||||
* @modifiedby $LastChangedBy$
|
|
||||||
* @lastmodified $Date$
|
|
||||||
* @license http://www.opensource.org/licenses/mit-license.php The MIT License
|
|
||||||
*/
|
|
||||||
App::import('Component', 'DebugKit.Toolbar');
|
|
||||||
|
|
||||||
class TestToolbarComponent extends ToolbarComponent {
|
|
||||||
|
|
||||||
function loadPanels($panels) {
|
|
||||||
$this->_loadPanels($panels);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
Mock::generate('DebugPanel');
|
|
||||||
|
|
||||||
/**
|
|
||||||
* DebugToolbar Test case
|
|
||||||
*/
|
|
||||||
class DebugToolbarTestCase extends CakeTestCase {
|
|
||||||
|
|
||||||
function setUp() {
|
|
||||||
Router::connect('/', array('controller' => 'pages', 'action' => 'display', 'home'));
|
|
||||||
Router::parse('/');
|
|
||||||
$this->Controller =& ClassRegistry::init('Controller');
|
|
||||||
$this->Controller->Component =& ClassRegistry::init('Component');
|
|
||||||
$this->Controller->Toolbar =& ClassRegistry::init('TestToolBarComponent', 'Component');
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* test Loading of panel classes
|
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
**/
|
|
||||||
function testLoadPanels() {
|
|
||||||
$this->Controller->Toolbar->loadPanels(array('session', 'request'));
|
|
||||||
$this->assertTrue(is_a($this->Controller->Toolbar->panels['session'], 'SessionPanel'));
|
|
||||||
$this->assertTrue(is_a($this->Controller->Toolbar->panels['request'], 'RequestPanel'));
|
|
||||||
|
|
||||||
$this->expectError();
|
|
||||||
$this->Controller->Toolbar->loadPanels(array('randomNonExisting', 'request'));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* test loading of vendor panels from test_app folder
|
|
||||||
*
|
|
||||||
* @access public
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
function testVendorPanels() {
|
|
||||||
$_back = Configure::read('vendorPaths');
|
|
||||||
Configure::write('vendorPaths', array(APP . 'plugins' . DS . 'debug_kit' . DS . 'tests' . DS . 'test_app' . DS . 'vendors' . DS));
|
|
||||||
$this->Controller->components = array(
|
|
||||||
'DebugKit.Toolbar' => array(
|
|
||||||
'panels' => array('test'),
|
|
||||||
)
|
|
||||||
);
|
|
||||||
$this->Controller->Component->init($this->Controller);
|
|
||||||
$this->Controller->Component->initialize($this->Controller);
|
|
||||||
$this->Controller->Component->startup($this->Controller);
|
|
||||||
$this->assertTrue(isset($this->Controller->Toolbar->panels['test']));
|
|
||||||
$this->assertTrue(is_a($this->Controller->Toolbar->panels['test'], 'TestPanel'));
|
|
||||||
|
|
||||||
Configure::write('vendorPaths', $_back);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* test initialize
|
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
* @access public
|
|
||||||
**/
|
|
||||||
function testInitialize() {
|
|
||||||
$this->Controller->components = array('DebugKit.Toolbar');
|
|
||||||
$this->Controller->Component->init($this->Controller);
|
|
||||||
$this->Controller->Component->initialize($this->Controller);
|
|
||||||
|
|
||||||
$this->assertFalse(empty($this->Controller->Toolbar->panels));
|
|
||||||
|
|
||||||
$timers = DebugKitDebugger::getTimers();
|
|
||||||
$this->assertTrue(isset($timers['componentInit']));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* test startup
|
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
**/
|
|
||||||
function testStartup() {
|
|
||||||
$this->Controller->components = array(
|
|
||||||
'DebugKit.Toolbar' => array(
|
|
||||||
'panels' => array('MockDebug')
|
|
||||||
)
|
|
||||||
);
|
|
||||||
$this->Controller->Component->init($this->Controller);
|
|
||||||
$this->Controller->Component->initialize($this->Controller);
|
|
||||||
$this->Controller->Toolbar->panels['MockDebug']->expectOnce('startup');
|
|
||||||
$this->Controller->Toolbar->startup($this->Controller);
|
|
||||||
|
|
||||||
$this->assertEqual(count($this->Controller->Toolbar->panels), 1);
|
|
||||||
$this->assertTrue(isset($this->Controller->helpers['DebugKit.Toolbar']));
|
|
||||||
$this->assertEqual($this->Controller->helpers['DebugKit.Toolbar'], array('output' => 'DebugKit.HtmlToolbar'));
|
|
||||||
|
|
||||||
$timers = DebugKitDebugger::getTimers();
|
|
||||||
$this->assertTrue(isset($timers['controllerAction']));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Test Before Render callback
|
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
**/
|
|
||||||
function testBeforeRender() {
|
|
||||||
$this->Controller->components = array(
|
|
||||||
'DebugKit.Toolbar' => array(
|
|
||||||
'panels' => array('MockDebug', 'session')
|
|
||||||
)
|
|
||||||
);
|
|
||||||
$this->Controller->Component->init($this->Controller);
|
|
||||||
$this->Controller->Component->initialize($this->Controller);
|
|
||||||
$this->Controller->Toolbar->panels['MockDebug']->expectOnce('beforeRender');
|
|
||||||
$this->Controller->Toolbar->beforeRender($this->Controller);
|
|
||||||
|
|
||||||
$this->assertTrue(isset($this->Controller->viewVars['debugToolbarPanels']));
|
|
||||||
$vars = $this->Controller->viewVars['debugToolbarPanels'];
|
|
||||||
|
|
||||||
$expected = array(
|
|
||||||
'plugin' => 'debug_kit',
|
|
||||||
'elementName' => 'session_panel',
|
|
||||||
'content' => $this->Controller->Session->read(),
|
|
||||||
'disableTimer' => true,
|
|
||||||
);
|
|
||||||
$this->assertEqual($expected, $vars['session']);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* test alternate javascript library use
|
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
**/
|
|
||||||
function testAlternateJavascript() {
|
|
||||||
$this->Controller->components = array(
|
|
||||||
'DebugKit.Toolbar'
|
|
||||||
);
|
|
||||||
$this->Controller->Component->init($this->Controller);
|
|
||||||
$this->Controller->Component->initialize($this->Controller);
|
|
||||||
$this->Controller->Component->startup($this->Controller);
|
|
||||||
$this->Controller->Component->beforeRender($this->Controller);
|
|
||||||
$this->assertTrue(isset($this->Controller->viewVars['debugToolbarJavascript']));
|
|
||||||
$expected = array(
|
|
||||||
'behavior' => '/debug_kit/js/js_debug_toolbar',
|
|
||||||
);
|
|
||||||
$this->assertEqual($this->Controller->viewVars['debugToolbarJavascript'], $expected);
|
|
||||||
|
|
||||||
$this->Controller->components = array(
|
|
||||||
'DebugKit.Toolbar' => array(
|
|
||||||
'javascript' => 'jquery',
|
|
||||||
),
|
|
||||||
);
|
|
||||||
$this->Controller->Component->init($this->Controller);
|
|
||||||
$this->Controller->Component->initialize($this->Controller);
|
|
||||||
$this->Controller->Component->startup($this->Controller);
|
|
||||||
$this->Controller->Component->beforeRender($this->Controller);
|
|
||||||
$this->assertTrue(isset($this->Controller->viewVars['debugToolbarJavascript']));
|
|
||||||
$expected = array(
|
|
||||||
'behavior' => '/debug_kit/js/jquery_debug_toolbar.js',
|
|
||||||
);
|
|
||||||
$this->assertEqual($this->Controller->viewVars['debugToolbarJavascript'], $expected);
|
|
||||||
|
|
||||||
|
|
||||||
$this->Controller->components = array(
|
|
||||||
'DebugKit.Toolbar' => array(
|
|
||||||
'javascript' => false
|
|
||||||
)
|
|
||||||
);
|
|
||||||
$this->Controller->Component->init($this->Controller);
|
|
||||||
$this->Controller->Component->initialize($this->Controller);
|
|
||||||
$this->Controller->Component->startup($this->Controller);
|
|
||||||
$this->Controller->Component->beforeRender($this->Controller);
|
|
||||||
$this->assertTrue(isset($this->Controller->viewVars['debugToolbarJavascript']));
|
|
||||||
$expected = array();
|
|
||||||
$this->assertEqual($this->Controller->viewVars['debugToolbarJavascript'], $expected);
|
|
||||||
|
|
||||||
|
|
||||||
$this->Controller->components = array(
|
|
||||||
'DebugKit.Toolbar' => array(
|
|
||||||
'javascript' => array('my_library'),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
$this->Controller->Component->init($this->Controller);
|
|
||||||
$this->Controller->Component->initialize($this->Controller);
|
|
||||||
$this->Controller->Component->startup($this->Controller);
|
|
||||||
$this->Controller->Component->beforeRender($this->Controller);
|
|
||||||
$this->assertTrue(isset($this->Controller->viewVars['debugToolbarJavascript']));
|
|
||||||
$expected = array(
|
|
||||||
'behavior' => 'my_library_debug_toolbar'
|
|
||||||
);
|
|
||||||
$this->assertEqual($this->Controller->viewVars['debugToolbarJavascript'], $expected);
|
|
||||||
|
|
||||||
$this->Controller->components = array(
|
|
||||||
'DebugKit.Toolbar' => array(
|
|
||||||
'javascript' => array('/my/path/to/file')
|
|
||||||
),
|
|
||||||
);
|
|
||||||
$this->Controller->Component->init($this->Controller);
|
|
||||||
$this->Controller->Component->initialize($this->Controller);
|
|
||||||
$this->Controller->Component->startup($this->Controller);
|
|
||||||
$this->Controller->Component->beforeRender($this->Controller);
|
|
||||||
$this->assertTrue(isset($this->Controller->viewVars['debugToolbarJavascript']));
|
|
||||||
$expected = array(
|
|
||||||
'behavior' => '/my/path/to/file',
|
|
||||||
);
|
|
||||||
$this->assertEqual($this->Controller->viewVars['debugToolbarJavascript'], $expected);
|
|
||||||
|
|
||||||
$this->Controller->components = array(
|
|
||||||
'DebugKit.Toolbar' => array(
|
|
||||||
'javascript' => '/js/custom_behavior',
|
|
||||||
),
|
|
||||||
);
|
|
||||||
$this->Controller->Component->init($this->Controller);
|
|
||||||
$this->Controller->Component->initialize($this->Controller);
|
|
||||||
$this->Controller->Component->startup($this->Controller);
|
|
||||||
$this->Controller->Component->beforeRender($this->Controller);
|
|
||||||
$this->assertTrue(isset($this->Controller->viewVars['debugToolbarJavascript']));
|
|
||||||
$expected = array(
|
|
||||||
'behavior' => '/js/custom_behavior',
|
|
||||||
);
|
|
||||||
$this->assertEqual($this->Controller->viewVars['debugToolbarJavascript'], $expected);
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* Test alternate javascript existing in the plugin.
|
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
**/
|
|
||||||
function testExistingAlterateJavascript() {
|
|
||||||
$filename = APP . 'plugins' . DS . 'debug_kit' . DS . 'vendors' . DS . 'js' . DS . 'test_alternate_debug_toolbar.js';
|
|
||||||
$this->skipIf(!is_writable(dirname($filename)), 'Skipping existing javascript test, debug_kit/vendors/js must be writable');
|
|
||||||
|
|
||||||
@touch($filename);
|
|
||||||
$this->Controller->components = array(
|
|
||||||
'DebugKit.Toolbar' => array(
|
|
||||||
'javascript' => 'test_alternate',
|
|
||||||
),
|
|
||||||
);
|
|
||||||
$this->Controller->Component->init($this->Controller);
|
|
||||||
$this->Controller->Component->initialize($this->Controller);
|
|
||||||
$this->Controller->Component->startup($this->Controller);
|
|
||||||
$this->Controller->Component->beforeRender($this->Controller);
|
|
||||||
$this->assertTrue(isset($this->Controller->viewVars['debugToolbarJavascript']));
|
|
||||||
$expected = array(
|
|
||||||
'behavior' => '/debug_kit/js/test_alternate_debug_toolbar.js',
|
|
||||||
);
|
|
||||||
$this->assertEqual($this->Controller->viewVars['debugToolbarJavascript'], $expected);
|
|
||||||
@unlink($filename);
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* test the Log panel log reading.
|
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
**/
|
|
||||||
function testLogPanel() {
|
|
||||||
usleep(20);
|
|
||||||
$this->Controller->log('This is a log I made this request');
|
|
||||||
$this->Controller->log('This is the second log I made this request');
|
|
||||||
$this->Controller->log('This time in the debug log!', LOG_DEBUG);
|
|
||||||
|
|
||||||
$this->Controller->components = array(
|
|
||||||
'DebugKit.Toolbar' => array(
|
|
||||||
'panels' => array('log', 'session')
|
|
||||||
)
|
|
||||||
);
|
|
||||||
$this->Controller->Component->init($this->Controller);
|
|
||||||
$this->Controller->Component->initialize($this->Controller);
|
|
||||||
$this->Controller->Component->startup($this->Controller);
|
|
||||||
$this->Controller->Component->beforeRender($this->Controller);
|
|
||||||
$result = $this->Controller->viewVars['debugToolbarPanels']['log'];
|
|
||||||
|
|
||||||
$this->assertEqual(count($result['content']), 2);
|
|
||||||
$this->assertEqual(count($result['content']['error.log']), 4);
|
|
||||||
$this->assertEqual(count($result['content']['debug.log']), 2);
|
|
||||||
|
|
||||||
$this->assertEqual(trim($result['content']['debug.log'][1]), 'Debug: This time in the debug log!');
|
|
||||||
$this->assertEqual(trim($result['content']['error.log'][1]), 'Error: This is a log I made this request');
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* teardown
|
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
**/
|
|
||||||
function tearDown() {
|
|
||||||
unset($this->Controller);
|
|
||||||
if (class_exists('DebugKitDebugger')) {
|
|
||||||
DebugKitDebugger::clearTimers();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
?>
|
|
||||||
@@ -1,62 +0,0 @@
|
|||||||
<?php
|
|
||||||
/* SVN FILE: $Id$ */
|
|
||||||
/**
|
|
||||||
* Common test objects used in DebugKit tests
|
|
||||||
*
|
|
||||||
* Long description for file
|
|
||||||
*
|
|
||||||
* PHP versions 4 and 5
|
|
||||||
*
|
|
||||||
* CakePHP(tm) Tests <https://trac.cakephp.org/wiki/Developement/TestSuite>
|
|
||||||
* Copyright 2005-2008, Cake Software Foundation, Inc.
|
|
||||||
* 1785 E. Sahara Avenue, Suite 490-204
|
|
||||||
* Las Vegas, Nevada 89104
|
|
||||||
*
|
|
||||||
* Licensed under The Open Group Test Suite License
|
|
||||||
* Redistributions of files must retain the above copyright notice.
|
|
||||||
*
|
|
||||||
* @filesource
|
|
||||||
* @copyright Copyright 2005-2008, Cake Software Foundation, Inc.
|
|
||||||
* @link https://trac.cakephp.org/wiki/Developement/TestSuite CakePHP(tm) Tests
|
|
||||||
* @package cake.tests
|
|
||||||
* @subpackage cake.tests.cases.libs
|
|
||||||
* @since CakePHP(tm) v 1.2.0.5432
|
|
||||||
* @version $Revision$
|
|
||||||
* @modifiedby $LastChangedBy$
|
|
||||||
* @lastmodified $Date$
|
|
||||||
* @license http://www.opensource.org/licenses/opengroup.php The Open Group Test Suite License
|
|
||||||
*/
|
|
||||||
/**
|
|
||||||
* TestFireCake class allows for testing of FireCake
|
|
||||||
*
|
|
||||||
* @package debug_kit.tests.
|
|
||||||
*/
|
|
||||||
class TestFireCake extends FireCake {
|
|
||||||
var $sentHeaders = array();
|
|
||||||
|
|
||||||
function _sendHeader($name, $value) {
|
|
||||||
$_this = FireCake::getInstance();
|
|
||||||
$_this->sentHeaders[$name] = $value;
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* skip client detection as headers are not being sent.
|
|
||||||
*
|
|
||||||
* @access public
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
function detectClientExtension() {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* Reset the fireCake
|
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
**/
|
|
||||||
function reset() {
|
|
||||||
$_this = FireCake::getInstance();
|
|
||||||
$_this->sentHeaders = array();
|
|
||||||
$_this->_messageIndex = 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
?>
|
|
||||||
@@ -1,157 +0,0 @@
|
|||||||
<?php
|
|
||||||
/* SVN FILE: $Id$ */
|
|
||||||
/**
|
|
||||||
* DebugKit Debugger Test Case File
|
|
||||||
*
|
|
||||||
* Long description for file
|
|
||||||
*
|
|
||||||
* PHP versions 4 and 5
|
|
||||||
*
|
|
||||||
* CakePHP(tm) Tests <https://trac.cakephp.org/wiki/Developement/TestSuite>
|
|
||||||
* Copyright 2005-2008, Cake Software Foundation, Inc.
|
|
||||||
* 1785 E. Sahara Avenue, Suite 490-204
|
|
||||||
* Las Vegas, Nevada 89104
|
|
||||||
*
|
|
||||||
* Licensed under The Open Group Test Suite License
|
|
||||||
* Redistributions of files must retain the above copyright notice.
|
|
||||||
*
|
|
||||||
* @filesource
|
|
||||||
* @copyright Copyright 2005-2008, Cake Software Foundation, Inc.
|
|
||||||
* @link https://trac.cakephp.org/wiki/Developement/TestSuite CakePHP(tm) Tests
|
|
||||||
* @package cake.tests
|
|
||||||
* @subpackage cake.tests.cases.libs
|
|
||||||
* @since CakePHP(tm) v 1.2.0.5432
|
|
||||||
* @version $Revision$
|
|
||||||
* @modifiedby $LastChangedBy$
|
|
||||||
* @lastmodified $Date$
|
|
||||||
* @license http://www.opensource.org/licenses/opengroup.php The Open Group Test Suite License
|
|
||||||
*/
|
|
||||||
App::import('Core', 'Debugger');
|
|
||||||
App::import('Vendor', 'DebugKit.DebugKitDebugger');
|
|
||||||
|
|
||||||
require_once APP . 'plugins' . DS . 'debug_kit' . DS . 'tests' . DS . 'cases' . DS . 'test_objects.php';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Short description for class.
|
|
||||||
*
|
|
||||||
* @package cake.tests
|
|
||||||
* @subpackage cake.tests.cases.libs
|
|
||||||
*/
|
|
||||||
class DebugKitDebuggerTest extends CakeTestCase {
|
|
||||||
/**
|
|
||||||
* setUp method
|
|
||||||
*
|
|
||||||
* @access public
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
function setUp() {
|
|
||||||
Configure::write('log', false);
|
|
||||||
if (!defined('SIMPLETESTVENDORPATH')) {
|
|
||||||
if (file_exists(APP . DS . 'vendors' . DS . 'simpletest' . DS . 'reporter.php')) {
|
|
||||||
define('SIMPLETESTVENDORPATH', 'APP' . DS . 'vendors');
|
|
||||||
} else {
|
|
||||||
define('SIMPLETESTVENDORPATH', 'CORE' . DS . 'vendors');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Start Timer test
|
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
**/
|
|
||||||
function testTimers() {
|
|
||||||
$this->assertTrue(DebugKitDebugger::startTimer('test1', 'this is my first test'));
|
|
||||||
usleep(5000);
|
|
||||||
$this->assertTrue(DebugKitDebugger::stopTimer('test1'));
|
|
||||||
$elapsed = DebugKitDebugger::elapsedTime('test1');
|
|
||||||
$this->assertTrue($elapsed > 0.0050);
|
|
||||||
|
|
||||||
$this->assertTrue(DebugKitDebugger::startTimer('test2', 'this is my second test'));
|
|
||||||
sleep(1);
|
|
||||||
$this->assertTrue(DebugKitDebugger::stopTimer('test2'));
|
|
||||||
$elapsed = DebugKitDebugger::elapsedTime('test2');
|
|
||||||
$this->assertTrue($elapsed > 1);
|
|
||||||
|
|
||||||
DebugKitDebugger::startTimer('test3');
|
|
||||||
$this->assertFalse(DebugKitDebugger::elapsedTime('test3'));
|
|
||||||
$this->assertFalse(DebugKitDebugger::stopTimer('wrong'));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* testRequestTime
|
|
||||||
*
|
|
||||||
* @access public
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
function testRequestTime() {
|
|
||||||
$result1 = DebugKitDebugger::requestTime();
|
|
||||||
usleep(50);
|
|
||||||
$result2 = DebugKitDebugger::requestTime();
|
|
||||||
$this->assertTrue($result1 < $result2);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* test getting all the set timers.
|
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
**/
|
|
||||||
function testGetTimers() {
|
|
||||||
DebugKitDebugger::clearTimers();
|
|
||||||
DebugKitDebugger::startTimer('test1', 'this is my first test');
|
|
||||||
DebugKitDebugger::stopTimer('test1');
|
|
||||||
usleep(50);
|
|
||||||
DebugKitDebugger::startTimer('test2');
|
|
||||||
DebugKitDebugger::stopTimer('test2');
|
|
||||||
$timers = DebugKitDebugger::getTimers();
|
|
||||||
|
|
||||||
$this->assertEqual(count($timers), 2);
|
|
||||||
$this->assertTrue(is_float($timers['test1']['time']));
|
|
||||||
$this->assertTrue(isset($timers['test1']['message']));
|
|
||||||
$this->assertTrue(isset($timers['test2']['message']));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* test memory usage
|
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
**/
|
|
||||||
function testMemoryUsage() {
|
|
||||||
$result = DebugKitDebugger::getMemoryUse();
|
|
||||||
$this->assertTrue(is_int($result));
|
|
||||||
|
|
||||||
$result = DebugKitDebugger::getPeakMemoryUse();
|
|
||||||
$this->assertTrue(is_int($result));
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* test _output switch to firePHP
|
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
function testOutput() {
|
|
||||||
$firecake =& FireCake::getInstance('TestFireCake');
|
|
||||||
Debugger::invoke(DebugKitDebugger::getInstance('DebugKitDebugger'));
|
|
||||||
Debugger::output('fb');
|
|
||||||
$foo .= '';
|
|
||||||
$result = $firecake->sentHeaders;
|
|
||||||
|
|
||||||
$this->assertPattern('/GROUP_START/', $result['X-Wf-1-1-1-1']);
|
|
||||||
$this->assertPattern('/ERROR/', $result['X-Wf-1-1-1-2']);
|
|
||||||
$this->assertPattern('/GROUP_END/', $result['X-Wf-1-1-1-5']);
|
|
||||||
|
|
||||||
Debugger::invoke(Debugger::getInstance('Debugger'));
|
|
||||||
Debugger::output();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* tearDown method
|
|
||||||
*
|
|
||||||
* @access public
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
function tearDown() {
|
|
||||||
Configure::write('log', true);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
?>
|
|
||||||
@@ -1,336 +0,0 @@
|
|||||||
<?php
|
|
||||||
/* SVN FILE: $Id$ */
|
|
||||||
/**
|
|
||||||
* CakeFirePHP test case
|
|
||||||
*
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* PHP versions 4 and 5
|
|
||||||
*
|
|
||||||
* CakePHP : Rapid Development Framework <http://www.cakephp.org/>
|
|
||||||
* Copyright 2006-2008, Cake Software Foundation, Inc.
|
|
||||||
* 1785 E. Sahara Avenue, Suite 490-204
|
|
||||||
* Las Vegas, Nevada 89104
|
|
||||||
*
|
|
||||||
* Licensed under The MIT License
|
|
||||||
* Redistributions of files must retain the above copyright notice.
|
|
||||||
*
|
|
||||||
* @filesource
|
|
||||||
* @copyright Copyright 2006-2008, Cake Software Foundation, Inc.
|
|
||||||
* @link http://www.cakefoundation.org/projects/info/cakephp CakePHP Project
|
|
||||||
* @package debug_kit
|
|
||||||
* @subpackage cake.debug_kit.tests
|
|
||||||
* @since CakePHP v 1.2.0.4487
|
|
||||||
* @version
|
|
||||||
* @modifiedby
|
|
||||||
* @lastmodified
|
|
||||||
* @license http://www.opensource.org/licenses/mit-license.php The MIT License
|
|
||||||
*/
|
|
||||||
App::import('Vendor', 'DebugKit.FireCake');
|
|
||||||
|
|
||||||
require_once APP . 'plugins' . DS . 'debug_kit' . DS . 'tests' . DS . 'cases' . DS . 'test_objects.php';
|
|
||||||
/**
|
|
||||||
* Test Case For FireCake
|
|
||||||
*
|
|
||||||
* @package debug_kit.tests
|
|
||||||
*/
|
|
||||||
class FireCakeTestCase extends CakeTestCase {
|
|
||||||
/**
|
|
||||||
* setup test
|
|
||||||
*
|
|
||||||
* Fill FireCake with TestFireCake instance.
|
|
||||||
*
|
|
||||||
* @access public
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
function setUp() {
|
|
||||||
$this->firecake =& FireCake::getInstance('TestFireCake');
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* test getInstance cheat.
|
|
||||||
*
|
|
||||||
* If this fails the rest of the test is going to fail too.
|
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
**/
|
|
||||||
function testGetInstanceOverride() {
|
|
||||||
$instance =& FireCake::getInstance();
|
|
||||||
$instance2 =& FireCake::getInstance();
|
|
||||||
$this->assertReference($instance, $instance2);
|
|
||||||
$this->assertIsA($instance, 'FireCake');
|
|
||||||
$this->assertIsA($instance, 'TestFireCake', 'Stored instance is not a copy of TestFireCake, test case is broken.');
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* testsetoption
|
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
**/
|
|
||||||
function testSetOptions() {
|
|
||||||
FireCake::setOptions(array('includeLineNumbers' => false));
|
|
||||||
$this->assertEqual($this->firecake->options['includeLineNumbers'], false);
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* test Log()
|
|
||||||
*
|
|
||||||
* @access public
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
function testLog() {
|
|
||||||
FireCake::setOptions(array('includeLineNumbers' => false));
|
|
||||||
FireCake::log('Testing');
|
|
||||||
$this->assertTrue(isset($this->firecake->sentHeaders['X-Wf-Protocol-1']));
|
|
||||||
$this->assertTrue(isset($this->firecake->sentHeaders['X-Wf-1-Plugin-1']));
|
|
||||||
$this->assertTrue(isset($this->firecake->sentHeaders['X-Wf-1-Structure-1']));
|
|
||||||
$this->assertEqual($this->firecake->sentHeaders['X-Wf-1-Index'], 1);
|
|
||||||
$this->assertEqual($this->firecake->sentHeaders['X-Wf-1-1-1-1'], '26|[{"Type":"LOG"},"Testing"]|');
|
|
||||||
|
|
||||||
FireCake::log('Testing', 'log-info');
|
|
||||||
$this->assertEqual($this->firecake->sentHeaders['X-Wf-1-1-1-2'], '45|[{"Type":"LOG","Label":"log-info"},"Testing"]|');
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* test info()
|
|
||||||
*
|
|
||||||
* @access public
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
function testInfo() {
|
|
||||||
FireCake::setOptions(array('includeLineNumbers' => false));
|
|
||||||
FireCake::info('I have information');
|
|
||||||
$this->assertTrue(isset($this->firecake->sentHeaders['X-Wf-Protocol-1']));
|
|
||||||
$this->assertTrue(isset($this->firecake->sentHeaders['X-Wf-1-Plugin-1']));
|
|
||||||
$this->assertTrue(isset($this->firecake->sentHeaders['X-Wf-1-Structure-1']));
|
|
||||||
$this->assertEqual($this->firecake->sentHeaders['X-Wf-1-Index'], 1);
|
|
||||||
$this->assertEqual($this->firecake->sentHeaders['X-Wf-1-1-1-1'], '38|[{"Type":"INFO"},"I have information"]|');
|
|
||||||
|
|
||||||
FireCake::info('I have information', 'info-label');
|
|
||||||
$this->assertEqual($this->firecake->sentHeaders['X-Wf-1-1-1-2'], '59|[{"Type":"INFO","Label":"info-label"},"I have information"]|');
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* test info()
|
|
||||||
*
|
|
||||||
* @access public
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
function testWarn() {
|
|
||||||
FireCake::setOptions(array('includeLineNumbers' => false));
|
|
||||||
FireCake::warn('A Warning');
|
|
||||||
$this->assertTrue(isset($this->firecake->sentHeaders['X-Wf-Protocol-1']));
|
|
||||||
$this->assertTrue(isset($this->firecake->sentHeaders['X-Wf-1-Plugin-1']));
|
|
||||||
$this->assertTrue(isset($this->firecake->sentHeaders['X-Wf-1-Structure-1']));
|
|
||||||
$this->assertEqual($this->firecake->sentHeaders['X-Wf-1-Index'], 1);
|
|
||||||
$this->assertEqual($this->firecake->sentHeaders['X-Wf-1-1-1-1'], '29|[{"Type":"WARN"},"A Warning"]|');
|
|
||||||
|
|
||||||
FireCake::warn('A Warning', 'Bzzz');
|
|
||||||
$this->assertEqual($this->firecake->sentHeaders['X-Wf-1-1-1-2'], '44|[{"Type":"WARN","Label":"Bzzz"},"A Warning"]|');
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* test error()
|
|
||||||
*
|
|
||||||
* @access public
|
|
||||||
* @return void
|
|
||||||
**/
|
|
||||||
function testError() {
|
|
||||||
FireCake::setOptions(array('includeLineNumbers' => false));
|
|
||||||
FireCake::error('An error');
|
|
||||||
$this->assertTrue(isset($this->firecake->sentHeaders['X-Wf-Protocol-1']));
|
|
||||||
$this->assertTrue(isset($this->firecake->sentHeaders['X-Wf-1-Plugin-1']));
|
|
||||||
$this->assertTrue(isset($this->firecake->sentHeaders['X-Wf-1-Structure-1']));
|
|
||||||
$this->assertEqual($this->firecake->sentHeaders['X-Wf-1-Index'], 1);
|
|
||||||
$this->assertEqual($this->firecake->sentHeaders['X-Wf-1-1-1-1'], '29|[{"Type":"ERROR"},"An error"]|');
|
|
||||||
|
|
||||||
FireCake::error('An error', 'wonky');
|
|
||||||
$this->assertEqual($this->firecake->sentHeaders['X-Wf-1-1-1-2'], '45|[{"Type":"ERROR","Label":"wonky"},"An error"]|');
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* test dump()
|
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
**/
|
|
||||||
function testDump() {
|
|
||||||
FireCake::dump('mydump', array('one' => 1, 'two' => 2));
|
|
||||||
$this->assertEqual($this->firecake->sentHeaders['X-Wf-1-2-1-1'], '28|{"mydump":{"one":1,"two":2}}|');
|
|
||||||
$this->assertTrue(isset($this->firecake->sentHeaders['X-Wf-1-Structure-2']));
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* test table() generation
|
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
**/
|
|
||||||
function testTable() {
|
|
||||||
$table[] = array('Col 1 Heading','Col 2 Heading');
|
|
||||||
$table[] = array('Row 1 Col 1','Row 1 Col 2');
|
|
||||||
$table[] = array('Row 2 Col 1','Row 2 Col 2');
|
|
||||||
$table[] = array('Row 3 Col 1','Row 3 Col 2');
|
|
||||||
FireCake::table('myTrace', $table);
|
|
||||||
$expected = '162|[{"Type":"TABLE","Label":"myTrace"},[["Col 1 Heading","Col 2 Heading"],["Row 1 Col 1","Row 1 Col 2"],["Row 2 Col 1","Row 2 Col 2"],["Row 3 Col 1","Row 3 Col 2"]]]|';
|
|
||||||
$this->assertEqual($this->firecake->sentHeaders['X-Wf-1-1-1-1'], $expected);
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* testStringEncoding
|
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
**/
|
|
||||||
function testStringEncode() {
|
|
||||||
$result = $this->firecake->stringEncode(array(1,2,3));
|
|
||||||
$this->assertEqual($result, array(1,2,3));
|
|
||||||
|
|
||||||
$this->firecake->setOptions(array('maxArrayDepth' => 3));
|
|
||||||
$deep = array(1 => array(2 => array(3)));
|
|
||||||
$result = $this->firecake->stringEncode($deep);
|
|
||||||
$this->assertEqual($result, array(1 => array(2 => '** Max Array Depth (3) **')));
|
|
||||||
|
|
||||||
$obj =& FireCake::getInstance();
|
|
||||||
$result = $this->firecake->stringEncode($obj);
|
|
||||||
$this->assertTrue(is_array($result));
|
|
||||||
$this->assertEqual($result['_defaultOptions']['useNativeJsonEncode'], true);
|
|
||||||
$this->assertEqual($result['_log'], null);
|
|
||||||
$this->assertEqual($result['_encodedObjects'][0], '** Recursion (TestFireCake) **');
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* test trace()
|
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
**/
|
|
||||||
function testTrace() {
|
|
||||||
FireCake::trace('myTrace');
|
|
||||||
$this->assertTrue(isset($this->firecake->sentHeaders['X-Wf-Protocol-1']));
|
|
||||||
$this->assertTrue(isset($this->firecake->sentHeaders['X-Wf-1-Plugin-1']));
|
|
||||||
$this->assertTrue(isset($this->firecake->sentHeaders['X-Wf-1-Structure-1']));
|
|
||||||
$dump = $this->firecake->sentHeaders['X-Wf-1-1-1-1'];
|
|
||||||
$this->assertPattern('/"Message":"myTrace"/', $dump);
|
|
||||||
$this->assertPattern('/"Trace":\[/', $dump);
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* test enabling and disabling of FireCake output
|
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
**/
|
|
||||||
function testEnableDisable() {
|
|
||||||
FireCake::disable();
|
|
||||||
FireCake::trace('myTrace');
|
|
||||||
$this->assertTrue(empty($this->firecake->sentHeaders));
|
|
||||||
|
|
||||||
FireCake::enable();
|
|
||||||
FireCake::trace('myTrace');
|
|
||||||
$this->assertFalse(empty($this->firecake->sentHeaders));
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* test correct line continuation markers on multi line headers.
|
|
||||||
*
|
|
||||||
* @access public
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
function testMultiLineOutput() {
|
|
||||||
FireCake::trace('myTrace');
|
|
||||||
$this->assertEqual($this->firecake->sentHeaders['X-Wf-1-Index'], 3);
|
|
||||||
$header = $this->firecake->sentHeaders['X-Wf-1-1-1-1'];
|
|
||||||
$this->assertEqual(substr($header, -2), '|\\');
|
|
||||||
|
|
||||||
$header = $this->firecake->sentHeaders['X-Wf-1-1-1-2'];
|
|
||||||
$this->assertEqual(substr($header, -2), '|\\');
|
|
||||||
|
|
||||||
$header = $this->firecake->sentHeaders['X-Wf-1-1-1-3'];
|
|
||||||
$this->assertEqual(substr($header, -1), '|');
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* test inclusion of line numbers
|
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
**/
|
|
||||||
function testIncludeLineNumbers() {
|
|
||||||
FireCake::setOptions(array('includeLineNumbers' => true));
|
|
||||||
FireCake::info('Testing');
|
|
||||||
$result = $this->firecake->sentHeaders['X-Wf-1-1-1-1'];
|
|
||||||
$this->assertPattern('/"File"\:"APP.*fire_cake.test.php/', $result);
|
|
||||||
$this->assertPattern('/"Line"\:\d+/', $result);
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* test Group messages
|
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
**/
|
|
||||||
function testGroup() {
|
|
||||||
FireCake::setOptions(array('includeLineNumbers' => false));
|
|
||||||
FireCake::group('test');
|
|
||||||
FireCake::info('my info');
|
|
||||||
FireCake::groupEnd();
|
|
||||||
$this->assertEqual($this->firecake->sentHeaders['X-Wf-1-1-1-1'], '44|[{"Type":"GROUP_START","Label":"test"},null]|');
|
|
||||||
$this->assertEqual($this->firecake->sentHeaders['X-Wf-1-1-1-3'], '27|[{"Type":"GROUP_END"},null]|');
|
|
||||||
$this->assertEqual($this->firecake->sentHeaders['X-Wf-1-Index'], 3);
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* test fb() parameter parsing
|
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
**/
|
|
||||||
function testFbParameterParsing() {
|
|
||||||
FireCake::setOptions(array('includeLineNumbers' => false));
|
|
||||||
FireCake::fb('Test');
|
|
||||||
$this->assertEqual($this->firecake->sentHeaders['X-Wf-1-1-1-1'], '23|[{"Type":"LOG"},"Test"]|');
|
|
||||||
|
|
||||||
FireCake::fb('Test', 'warn');
|
|
||||||
$this->assertEqual($this->firecake->sentHeaders['X-Wf-1-1-1-2'], '24|[{"Type":"WARN"},"Test"]|');
|
|
||||||
|
|
||||||
FireCake::fb('Test', 'Custom label', 'warn');
|
|
||||||
$this->assertEqual($this->firecake->sentHeaders['X-Wf-1-1-1-3'], '47|[{"Type":"WARN","Label":"Custom label"},"Test"]|');
|
|
||||||
|
|
||||||
$this->expectError();
|
|
||||||
$this->assertFalse(FireCake::fb('Test', 'Custom label', 'warn', 'more parameters'));
|
|
||||||
|
|
||||||
$this->assertEqual($this->firecake->sentHeaders['X-Wf-1-Index'], 3);
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* Test defaulting to log if incorrect message type is used
|
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
**/
|
|
||||||
function testIncorrectMessageType() {
|
|
||||||
FireCake::setOptions(array('includeLineNumbers' => false));
|
|
||||||
FireCake::fb('Hello World', 'foobared');
|
|
||||||
$this->assertEqual($this->firecake->sentHeaders['X-Wf-1-1-1-1'], '30|[{"Type":"LOG"},"Hello World"]|');
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* testClientExtensionDetection.
|
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
**/
|
|
||||||
function testDetectClientExtension() {
|
|
||||||
$back = env('HTTP_USER_AGENT');
|
|
||||||
$_SERVER['HTTP_USER_AGENT'] = 'Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.5; en-US; rv:1.9.0.4) Gecko/2008102920 Firefox/3.0.4 FirePHP/0.2.1';
|
|
||||||
$this->assertTrue(FireCake::detectClientExtension());
|
|
||||||
|
|
||||||
$_SERVER['HTTP_USER_AGENT'] = 'Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.5; en-US; rv:1.9.0.4) Gecko/2008102920 Firefox/3.0.4 FirePHP/0.0.4';
|
|
||||||
$this->assertFalse(FireCake::detectClientExtension());
|
|
||||||
|
|
||||||
$_SERVER['HTTP_USER_AGENT'] = 'Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.5; en-US; rv:1.9.0.4) Gecko/2008102920 Firefox/3.0.4';
|
|
||||||
$this->assertFalse(FireCake::detectClientExtension());
|
|
||||||
$_SERVER['HTTP_USER_AGENT'] = $back;
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* test of Non Native JSON encoding.
|
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
**/
|
|
||||||
function testNonNativeEncoding() {
|
|
||||||
FireCake::setOptions(array('useNativeJsonEncode' => false));
|
|
||||||
$json = FireCake::jsonEncode(array('one' => 1, 'two' => 2));
|
|
||||||
$this->assertEqual($json, '{"one":1,"two":2}');
|
|
||||||
|
|
||||||
$json = FireCake::jsonEncode(array(1,2,3));
|
|
||||||
$this->assertEqual($json, '[1,2,3]');
|
|
||||||
|
|
||||||
$json = FireCake::jsonEncode(FireCake::getInstance());
|
|
||||||
$this->assertPattern('/"options"\:\{"maxObjectDepth"\:\d*,/', $json);
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* reset the FireCake counters and headers.
|
|
||||||
*
|
|
||||||
* @access public
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
function tearDown() {
|
|
||||||
TestFireCake::reset();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
?>
|
|
||||||
@@ -1,144 +0,0 @@
|
|||||||
<?php
|
|
||||||
/* SVN FILE: $Id$ */
|
|
||||||
/**
|
|
||||||
* DebugView test Case
|
|
||||||
*
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* PHP versions 4 and 5
|
|
||||||
*
|
|
||||||
* CakePHP : Rapid Development Framework <http://www.cakephp.org/>
|
|
||||||
* Copyright 2006-2008, Cake Software Foundation, Inc.
|
|
||||||
* 1785 E. Sahara Avenue, Suite 490-204
|
|
||||||
* Las Vegas, Nevada 89104
|
|
||||||
*
|
|
||||||
* Licensed under The MIT License
|
|
||||||
* Redistributions of files must retain the above copyright notice.
|
|
||||||
*
|
|
||||||
* @filesource
|
|
||||||
* @copyright Copyright 2006-2008, Cake Software Foundation, Inc.
|
|
||||||
* @link http://www.cakefoundation.org/projects/info/cakephp CakePHP Project
|
|
||||||
* @package cake
|
|
||||||
* @subpackage cake.cake.libs.
|
|
||||||
* @since CakePHP v 1.2.0.4487
|
|
||||||
* @version $Revision$
|
|
||||||
* @modifiedby $LastChangedBy$
|
|
||||||
* @lastmodified $Date$
|
|
||||||
* @license http://www.opensource.org/licenses/mit-license.php The MIT License
|
|
||||||
*/
|
|
||||||
App::import('Core', 'View');
|
|
||||||
|
|
||||||
if (!class_exists('DoppelGangerView')) {
|
|
||||||
class DoppelGangerView extends View {}
|
|
||||||
}
|
|
||||||
|
|
||||||
App::import('View', 'DebugKit.Debug');
|
|
||||||
App::import('Vendor', 'DebugKit.DebugKitDebugger');
|
|
||||||
/**
|
|
||||||
* Debug View Test Case
|
|
||||||
*
|
|
||||||
* @package debug_kit.tests
|
|
||||||
*/
|
|
||||||
class DebugViewTestCase extends CakeTestCase {
|
|
||||||
/**
|
|
||||||
* set Up test case
|
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
**/
|
|
||||||
function setUp() {
|
|
||||||
Router::connect('/', array('controller' => 'pages', 'action' => 'display', 'home'));
|
|
||||||
Router::parse('/');
|
|
||||||
$this->Controller =& ClassRegistry::init('Controller');
|
|
||||||
$this->View =& new DebugView($this->Controller, false);
|
|
||||||
$this->_debug = Configure::read('debug');
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* start Case - switch view paths
|
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
**/
|
|
||||||
function startCase() {
|
|
||||||
$this->_viewPaths = Configure::read('viewPaths');
|
|
||||||
Configure::write('viewPaths', array(
|
|
||||||
TEST_CAKE_CORE_INCLUDE_PATH . 'tests' . DS . 'test_app' . DS . 'views'. DS,
|
|
||||||
APP . 'plugins' . DS . 'debug_kit' . DS . 'views'. DS,
|
|
||||||
ROOT . DS . LIBS . 'view' . DS
|
|
||||||
));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* test that element timers are working
|
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
**/
|
|
||||||
function testElementTimers() {
|
|
||||||
$result = $this->View->element('test_element');
|
|
||||||
$this->assertPattern('/^this is the test element$/', $result);
|
|
||||||
|
|
||||||
$result = DebugKitDebugger::getTimers();
|
|
||||||
$this->assertTrue(isset($result['render_test_element.ctp']));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* test rendering and ensure that timers are being set.
|
|
||||||
*
|
|
||||||
* @access public
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
function testRenderTimers() {
|
|
||||||
$this->Controller->viewPath = 'posts';
|
|
||||||
$this->Controller->action = 'index';
|
|
||||||
$this->Controller->params = array(
|
|
||||||
'action' => 'index',
|
|
||||||
'controller' => 'posts',
|
|
||||||
'plugin' => null,
|
|
||||||
'url' => array('url' => 'posts/index'),
|
|
||||||
'base' => null,
|
|
||||||
'here' => '/posts/index',
|
|
||||||
);
|
|
||||||
$this->Controller->layout = 'default';
|
|
||||||
$View =& new DebugView($this->Controller, false);
|
|
||||||
$View->render('index');
|
|
||||||
|
|
||||||
$result = DebugKitDebugger::getTimers();
|
|
||||||
$this->assertEqual(count($result), 3);
|
|
||||||
$this->assertTrue(isset($result['viewRender']));
|
|
||||||
$this->assertTrue(isset($result['render_default.ctp']));
|
|
||||||
$this->assertTrue(isset($result['render_index.ctp']));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Test for correct loading of helpers into custom view
|
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
function testLoadHelpers() {
|
|
||||||
$loaded = array();
|
|
||||||
$result = $this->View->_loadHelpers($loaded, array('Html', 'Javascript', 'Number'));
|
|
||||||
$this->assertTrue(is_object($result['Html']));
|
|
||||||
$this->assertTrue(is_object($result['Javascript']));
|
|
||||||
$this->assertTrue(is_object($result['Number']));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* reset the view paths
|
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
**/
|
|
||||||
function endCase() {
|
|
||||||
Configure::write('viewPaths', $this->_viewPaths);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* tear down function
|
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
**/
|
|
||||||
function tearDown() {
|
|
||||||
unset($this->View, $this->Controller);
|
|
||||||
DebugKitDebugger::clearTimers();
|
|
||||||
Configure::write('debug', $this->_debug);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
?>
|
|
||||||
@@ -1,137 +0,0 @@
|
|||||||
<?php
|
|
||||||
/* SVN FILE: $Id$ */
|
|
||||||
/**
|
|
||||||
* Toolbar Abstract Helper Test Case
|
|
||||||
*
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* PHP versions 4 and 5
|
|
||||||
*
|
|
||||||
* CakePHP : Rapid Development Framework <http://www.cakephp.org/>
|
|
||||||
* Copyright 2006-2008, Cake Software Foundation, Inc.
|
|
||||||
* 1785 E. Sahara Avenue, Suite 490-204
|
|
||||||
* Las Vegas, Nevada 89104
|
|
||||||
*
|
|
||||||
* Licensed under The MIT License
|
|
||||||
* Redistributions of files must retain the above copyright notice.
|
|
||||||
*
|
|
||||||
* @filesource
|
|
||||||
* @copyright Copyright 2006-2008, Cake Software Foundation, Inc.
|
|
||||||
* @link http://www.cakefoundation.org/projects/info/cakephp CakePHP Project
|
|
||||||
* @package cake
|
|
||||||
* @subpackage debug_kit.tests.views.helpers
|
|
||||||
* @version $Revision$
|
|
||||||
* @modifiedby $LastChangedBy$
|
|
||||||
* @lastmodified $Date$
|
|
||||||
* @license http://www.opensource.org/licenses/mit-license.php The MIT License
|
|
||||||
*/
|
|
||||||
App::import('Helper', 'DebugKit.FirePhpToolbar');
|
|
||||||
App::import('Core', array('View', 'Controller'));
|
|
||||||
require_once APP . 'plugins' . DS . 'debug_kit' . DS . 'tests' . DS . 'cases' . DS . 'test_objects.php';
|
|
||||||
|
|
||||||
FireCake::getInstance('TestFireCake');
|
|
||||||
|
|
||||||
class FirePhpToolbarHelperTestCase extends CakeTestCase {
|
|
||||||
/**
|
|
||||||
* setUp
|
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
**/
|
|
||||||
function setUp() {
|
|
||||||
Router::connect('/', array('controller' => 'pages', 'action' => 'display', 'home'));
|
|
||||||
Router::parse('/');
|
|
||||||
|
|
||||||
$this->Toolbar =& new ToolbarHelper(array('output' => 'DebugKit.FirePhpToolbar'));
|
|
||||||
$this->Toolbar->FirePhpToolbar =& new FirePhpToolbarHelper();
|
|
||||||
|
|
||||||
$this->Controller =& ClassRegistry::init('Controller');
|
|
||||||
if (isset($this->_debug)) {
|
|
||||||
Configure::write('debug', $this->_debug);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* start Case - switch view paths
|
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
**/
|
|
||||||
function startCase() {
|
|
||||||
$this->_viewPaths = Configure::read('viewPaths');
|
|
||||||
Configure::write('viewPaths', array(
|
|
||||||
TEST_CAKE_CORE_INCLUDE_PATH . 'tests' . DS . 'test_app' . DS . 'views'. DS,
|
|
||||||
APP . 'plugins' . DS . 'debug_kit' . DS . 'views'. DS,
|
|
||||||
ROOT . DS . LIBS . 'view' . DS
|
|
||||||
));
|
|
||||||
$this->_debug = Configure::read('debug');
|
|
||||||
$this->firecake =& FireCake::getInstance();
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* test neat array (dump)creation
|
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
function testMakeNeatArray() {
|
|
||||||
$this->Toolbar->makeNeatArray(array(1,2,3));
|
|
||||||
$result = $this->firecake->sentHeaders;
|
|
||||||
$this->assertTrue(isset($result['X-Wf-1-1-1-1']));
|
|
||||||
$this->assertPattern('/\[1,2,3\]/', $result['X-Wf-1-1-1-1']);
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* testAfterlayout element rendering
|
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
function testAfterLayout(){
|
|
||||||
$this->Controller->viewPath = 'posts';
|
|
||||||
$this->Controller->action = 'index';
|
|
||||||
$this->Controller->params = array(
|
|
||||||
'action' => 'index',
|
|
||||||
'controller' => 'posts',
|
|
||||||
'plugin' => null,
|
|
||||||
'url' => array('url' => 'posts/index', 'ext' => 'xml'),
|
|
||||||
'base' => null,
|
|
||||||
'here' => '/posts/index',
|
|
||||||
);
|
|
||||||
$this->Controller->layout = 'default';
|
|
||||||
$this->Controller->uses = null;
|
|
||||||
$this->Controller->components = array('DebugKit.Toolbar');
|
|
||||||
$this->Controller->constructClasses();
|
|
||||||
$this->Controller->Component->initialize($this->Controller);
|
|
||||||
$this->Controller->Component->startup($this->Controller);
|
|
||||||
$this->Controller->Component->beforeRender($this->Controller);
|
|
||||||
$result = $this->Controller->render();
|
|
||||||
$this->assertNoPattern('/debug-toolbar/', $result);
|
|
||||||
$result = $this->firecake->sentHeaders;
|
|
||||||
$this->assertTrue(is_array($result));
|
|
||||||
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* endTest()
|
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
function endTest() {
|
|
||||||
TestFireCake::reset();
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* reset the view paths
|
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
**/
|
|
||||||
function endCase() {
|
|
||||||
Configure::write('viewPaths', $this->_viewPaths);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* tearDown
|
|
||||||
*
|
|
||||||
* @access public
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
function tearDown() {
|
|
||||||
unset($this->Toolbar, $this->Controller);
|
|
||||||
ClassRegistry::removeObject('view');
|
|
||||||
ClassRegistry::flush();
|
|
||||||
Router::reload();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
?>
|
|
||||||
@@ -1,358 +0,0 @@
|
|||||||
<?php
|
|
||||||
/* SVN FILE: $Id$ */
|
|
||||||
/**
|
|
||||||
* Toolbar HTML Helper Test Case
|
|
||||||
*
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* PHP versions 4 and 5
|
|
||||||
*
|
|
||||||
* CakePHP : Rapid Development Framework <http://www.cakephp.org/>
|
|
||||||
* Copyright 2006-2008, Cake Software Foundation, Inc.
|
|
||||||
* 1785 E. Sahara Avenue, Suite 490-204
|
|
||||||
* Las Vegas, Nevada 89104
|
|
||||||
*
|
|
||||||
* Licensed under The MIT License
|
|
||||||
* Redistributions of files must retain the above copyright notice.
|
|
||||||
*
|
|
||||||
* @filesource
|
|
||||||
* @copyright Copyright 2006-2008, Cake Software Foundation, Inc.
|
|
||||||
* @link http://www.cakefoundation.org/projects/info/cakephp CakePHP Project
|
|
||||||
* @package cake
|
|
||||||
* @subpackage debug_kit.tests.views.helpers
|
|
||||||
* @version $Revision$
|
|
||||||
* @modifiedby $LastChangedBy$
|
|
||||||
* @lastmodified $Date$
|
|
||||||
* @license http://www.opensource.org/licenses/mit-license.php The MIT License
|
|
||||||
*/
|
|
||||||
App::import('Helper', array('DebugKit.HtmlToolbar', 'Html', 'Javascript'));
|
|
||||||
App::import('Core', array('View', 'Controller'));
|
|
||||||
|
|
||||||
class HtmlToolbarHelperTestCase extends CakeTestCase {
|
|
||||||
/**
|
|
||||||
* setUp
|
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
**/
|
|
||||||
function setUp() {
|
|
||||||
Router::connect('/', array('controller' => 'pages', 'action' => 'display', 'home'));
|
|
||||||
Router::parse('/');
|
|
||||||
|
|
||||||
$this->Toolbar =& new ToolbarHelper(array('output' => 'DebugKit.HtmlToolbar'));
|
|
||||||
$this->Toolbar->HtmlToolbar =& new HtmlToolbarHelper();
|
|
||||||
$this->Toolbar->HtmlToolbar->Html =& new HtmlHelper();
|
|
||||||
$this->Toolbar->HtmlToolbar->Javascript =& new JavascriptHelper();
|
|
||||||
|
|
||||||
$this->Controller =& ClassRegistry::init('Controller');
|
|
||||||
if (isset($this->_debug)) {
|
|
||||||
Configure::write('debug', $this->_debug);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* start Case - switch view paths
|
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
**/
|
|
||||||
function startCase() {
|
|
||||||
$this->_viewPaths = Configure::read('viewPaths');
|
|
||||||
Configure::write('viewPaths', array(
|
|
||||||
TEST_CAKE_CORE_INCLUDE_PATH . 'tests' . DS . 'test_app' . DS . 'views'. DS,
|
|
||||||
APP . 'plugins' . DS . 'debug_kit' . DS . 'views'. DS,
|
|
||||||
ROOT . DS . LIBS . 'view' . DS
|
|
||||||
));
|
|
||||||
$this->_debug = Configure::read('debug');
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* test Neat Array formatting
|
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
**/
|
|
||||||
function testMakeNeatArray() {
|
|
||||||
$in = false;
|
|
||||||
$result = $this->Toolbar->makeNeatArray($in);
|
|
||||||
$expected = array(
|
|
||||||
'ul' => array('class' => 'neat-array depth-0'),
|
|
||||||
'<li', '<strong', '0' , '/strong', '(false)', '/li',
|
|
||||||
'/ul'
|
|
||||||
);
|
|
||||||
$this->assertTags($result, $expected);
|
|
||||||
|
|
||||||
$in = null;
|
|
||||||
$result = $this->Toolbar->makeNeatArray($in);
|
|
||||||
$expected = array(
|
|
||||||
'ul' => array('class' => 'neat-array depth-0'),
|
|
||||||
'<li', '<strong', '0' , '/strong', '(null)', '/li',
|
|
||||||
'/ul'
|
|
||||||
);
|
|
||||||
$this->assertTags($result, $expected);
|
|
||||||
|
|
||||||
$in = true;
|
|
||||||
$result = $this->Toolbar->makeNeatArray($in);
|
|
||||||
$expected = array(
|
|
||||||
'ul' => array('class' => 'neat-array depth-0'),
|
|
||||||
'<li', '<strong', '0' , '/strong', '(true)', '/li',
|
|
||||||
'/ul'
|
|
||||||
);
|
|
||||||
$this->assertTags($result, $expected);
|
|
||||||
|
|
||||||
$in = array('key' => 'value');
|
|
||||||
$result = $this->Toolbar->makeNeatArray($in);
|
|
||||||
$expected = array(
|
|
||||||
'ul' => array('class' => 'neat-array depth-0'),
|
|
||||||
'<li', '<strong', 'key', '/strong', 'value', '/li',
|
|
||||||
'/ul'
|
|
||||||
);
|
|
||||||
$this->assertTags($result, $expected);
|
|
||||||
|
|
||||||
$in = array('key' => null);
|
|
||||||
$result = $this->Toolbar->makeNeatArray($in);
|
|
||||||
$expected = array(
|
|
||||||
'ul' => array('class' => 'neat-array depth-0'),
|
|
||||||
'<li', '<strong', 'key', '/strong', '(null)', '/li',
|
|
||||||
'/ul'
|
|
||||||
);
|
|
||||||
$this->assertTags($result, $expected);
|
|
||||||
|
|
||||||
$in = array('key' => 'value', 'foo' => 'bar');
|
|
||||||
$result = $this->Toolbar->makeNeatArray($in);
|
|
||||||
$expected = array(
|
|
||||||
'ul' => array('class' => 'neat-array depth-0'),
|
|
||||||
'<li', '<strong', 'key', '/strong', 'value', '/li',
|
|
||||||
'<li', '<strong', 'foo', '/strong', 'bar', '/li',
|
|
||||||
'/ul'
|
|
||||||
);
|
|
||||||
$this->assertTags($result, $expected);
|
|
||||||
|
|
||||||
$in = array(
|
|
||||||
'key' => 'value',
|
|
||||||
'foo' => array(
|
|
||||||
'this' => 'deep',
|
|
||||||
'another' => 'value'
|
|
||||||
)
|
|
||||||
);
|
|
||||||
$result = $this->Toolbar->makeNeatArray($in);
|
|
||||||
$expected = array(
|
|
||||||
'ul' => array('class' => 'neat-array depth-0'),
|
|
||||||
'<li', '<strong', 'key', '/strong', 'value', '/li',
|
|
||||||
'<li', '<strong', 'foo', '/strong',
|
|
||||||
array('ul' => array('class' => 'neat-array depth-1')),
|
|
||||||
'<li', '<strong', 'this', '/strong', 'deep', '/li',
|
|
||||||
'<li', '<strong', 'another', '/strong', 'value', '/li',
|
|
||||||
'/ul',
|
|
||||||
'/li',
|
|
||||||
'/ul'
|
|
||||||
);
|
|
||||||
$this->assertTags($result, $expected);
|
|
||||||
|
|
||||||
$in = array(
|
|
||||||
'key' => 'value',
|
|
||||||
'foo' => array(
|
|
||||||
'this' => 'deep',
|
|
||||||
'another' => 'value'
|
|
||||||
),
|
|
||||||
'lotr' => array(
|
|
||||||
'gandalf' => 'wizard',
|
|
||||||
'bilbo' => 'hobbit'
|
|
||||||
)
|
|
||||||
);
|
|
||||||
$result = $this->Toolbar->makeNeatArray($in, 1);
|
|
||||||
$expected = array(
|
|
||||||
'ul' => array('class' => 'neat-array depth-0 expanded'),
|
|
||||||
'<li', '<strong', 'key', '/strong', 'value', '/li',
|
|
||||||
'<li', '<strong', 'foo', '/strong',
|
|
||||||
array('ul' => array('class' => 'neat-array depth-1')),
|
|
||||||
'<li', '<strong', 'this', '/strong', 'deep', '/li',
|
|
||||||
'<li', '<strong', 'another', '/strong', 'value', '/li',
|
|
||||||
'/ul',
|
|
||||||
'/li',
|
|
||||||
'<li', '<strong', 'lotr', '/strong',
|
|
||||||
array('ul' => array('class' => 'neat-array depth-1')),
|
|
||||||
'<li', '<strong', 'gandalf', '/strong', 'wizard', '/li',
|
|
||||||
'<li', '<strong', 'bilbo', '/strong', 'hobbit', '/li',
|
|
||||||
'/ul',
|
|
||||||
'/li',
|
|
||||||
'/ul'
|
|
||||||
);
|
|
||||||
$this->assertTags($result, $expected);
|
|
||||||
|
|
||||||
$result = $this->Toolbar->makeNeatArray($in, 2);
|
|
||||||
$expected = array(
|
|
||||||
'ul' => array('class' => 'neat-array depth-0 expanded'),
|
|
||||||
'<li', '<strong', 'key', '/strong', 'value', '/li',
|
|
||||||
'<li', '<strong', 'foo', '/strong',
|
|
||||||
array('ul' => array('class' => 'neat-array depth-1 expanded')),
|
|
||||||
'<li', '<strong', 'this', '/strong', 'deep', '/li',
|
|
||||||
'<li', '<strong', 'another', '/strong', 'value', '/li',
|
|
||||||
'/ul',
|
|
||||||
'/li',
|
|
||||||
'<li', '<strong', 'lotr', '/strong',
|
|
||||||
array('ul' => array('class' => 'neat-array depth-1 expanded')),
|
|
||||||
'<li', '<strong', 'gandalf', '/strong', 'wizard', '/li',
|
|
||||||
'<li', '<strong', 'bilbo', '/strong', 'hobbit', '/li',
|
|
||||||
'/ul',
|
|
||||||
'/li',
|
|
||||||
'/ul'
|
|
||||||
);
|
|
||||||
$this->assertTags($result, $expected);
|
|
||||||
|
|
||||||
$in = array('key' => 'value', 'array' => array());
|
|
||||||
$result = $this->Toolbar->makeNeatArray($in);
|
|
||||||
$expected = array(
|
|
||||||
'ul' => array('class' => 'neat-array depth-0'),
|
|
||||||
'<li', '<strong', 'key', '/strong', 'value', '/li',
|
|
||||||
'<li', '<strong', 'array', '/strong', '(empty)', '/li',
|
|
||||||
'/ul'
|
|
||||||
);
|
|
||||||
$this->assertTags($result, $expected);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Test injection of toolbar
|
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
**/
|
|
||||||
function testInjectToolbar() {
|
|
||||||
$this->Controller->viewPath = 'posts';
|
|
||||||
$this->Controller->action = 'index';
|
|
||||||
$this->Controller->params = array(
|
|
||||||
'action' => 'index',
|
|
||||||
'controller' => 'posts',
|
|
||||||
'plugin' => null,
|
|
||||||
'url' => array('url' => 'posts/index'),
|
|
||||||
'base' => null,
|
|
||||||
'here' => '/posts/index',
|
|
||||||
);
|
|
||||||
$this->Controller->helpers = array('Html', 'Javascript', 'DebugKit.Toolbar');
|
|
||||||
$this->Controller->layout = 'default';
|
|
||||||
$this->Controller->uses = null;
|
|
||||||
$this->Controller->components = array('DebugKit.Toolbar');
|
|
||||||
$this->Controller->constructClasses();
|
|
||||||
$this->Controller->Component->initialize($this->Controller);
|
|
||||||
$this->Controller->Component->startup($this->Controller);
|
|
||||||
$this->Controller->Component->beforeRender($this->Controller);
|
|
||||||
$result = $this->Controller->render();
|
|
||||||
$result = str_replace(array("\n", "\r"), '', $result);
|
|
||||||
$this->assertPattern('#<div id\="debug-kit-toolbar">.+</div></body>#', $result);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* test injection of javascript
|
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
**/
|
|
||||||
function testJavascriptInjection() {
|
|
||||||
$this->Controller->viewPath = 'posts';
|
|
||||||
$this->Controller->uses = null;
|
|
||||||
$this->Controller->action = 'index';
|
|
||||||
$this->Controller->params = array(
|
|
||||||
'action' => 'index',
|
|
||||||
'controller' => 'posts',
|
|
||||||
'plugin' => null,
|
|
||||||
'url' => array('url' => 'posts/index'),
|
|
||||||
'base' => '/',
|
|
||||||
'here' => '/posts/index',
|
|
||||||
);
|
|
||||||
$this->Controller->helpers = array('Javascript', 'Html');
|
|
||||||
$this->Controller->components = array('DebugKit.Toolbar');
|
|
||||||
$this->Controller->layout = 'default';
|
|
||||||
$this->Controller->constructClasses();
|
|
||||||
$this->Controller->Component->initialize($this->Controller);
|
|
||||||
$this->Controller->Component->startup($this->Controller);
|
|
||||||
$this->Controller->Component->beforeRender($this->Controller);
|
|
||||||
$result = $this->Controller->render();
|
|
||||||
$result = str_replace(array("\n", "\r"), '', $result);
|
|
||||||
$this->assertPattern('#<script\s*type="text/javascript"\s*src="/debug_kit/js/js_debug_toolbar.js"\s*>\s?</script>#', $result);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* test Injection of user defined javascript
|
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
**/
|
|
||||||
function testCustomJavascriptInjection() {
|
|
||||||
$this->Controller->viewPath = 'posts';
|
|
||||||
$this->Controller->uses = null;
|
|
||||||
$this->Controller->action = 'index';
|
|
||||||
$this->Controller->params = array(
|
|
||||||
'action' => 'index',
|
|
||||||
'controller' => 'posts',
|
|
||||||
'plugin' => null,
|
|
||||||
'url' => array('url' => 'posts/index'),
|
|
||||||
'base' => '/',
|
|
||||||
'here' => '/posts/index',
|
|
||||||
);
|
|
||||||
$this->Controller->helpers = array('Javascript', 'Html');
|
|
||||||
$this->Controller->components = array('DebugKit.Toolbar' => array('javascript' => array('my_custom')));
|
|
||||||
$this->Controller->layout = 'default';
|
|
||||||
$this->Controller->constructClasses();
|
|
||||||
$this->Controller->Component->initialize($this->Controller);
|
|
||||||
$this->Controller->Component->startup($this->Controller);
|
|
||||||
$this->Controller->Component->beforeRender($this->Controller);
|
|
||||||
$result = $this->Controller->render();
|
|
||||||
$result = str_replace(array("\n", "\r"), '', $result);
|
|
||||||
$this->assertPattern('#<script\s*type="text/javascript"\s*src="js/my_custom_debug_toolbar.js"\s*>\s?</script>#', $result);
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* test message creation
|
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
function testMessage() {
|
|
||||||
$result = $this->Toolbar->message('test', 'one, two');
|
|
||||||
$expected = array(
|
|
||||||
'<p',
|
|
||||||
'<strong', 'test', '/strong',
|
|
||||||
' one, two',
|
|
||||||
'/p',
|
|
||||||
);
|
|
||||||
$this->assertTags($result, $expected);
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* Test Table generation
|
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
function testTable() {
|
|
||||||
$rows = array(
|
|
||||||
array(1,2),
|
|
||||||
array(3,4),
|
|
||||||
);
|
|
||||||
$result = $this->Toolbar->table($rows);
|
|
||||||
$expected = array(
|
|
||||||
'table' => array('class' =>'debug-table'),
|
|
||||||
array('tr' => array('class' => 'odd')),
|
|
||||||
'<td', '1', '/td',
|
|
||||||
'<td', '2', '/td',
|
|
||||||
'/tr',
|
|
||||||
array('tr' => array('class' => 'even')),
|
|
||||||
'<td', '3', '/td',
|
|
||||||
'<td', '4', '/td',
|
|
||||||
'/tr',
|
|
||||||
'/table'
|
|
||||||
);
|
|
||||||
$this->assertTags($result, $expected);
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* reset the view paths
|
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
**/
|
|
||||||
function endCase() {
|
|
||||||
Configure::write('viewPaths', $this->_viewPaths);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* tearDown
|
|
||||||
*
|
|
||||||
* @access public
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
function tearDown() {
|
|
||||||
unset($this->Toolbar, $this->Controller);
|
|
||||||
ClassRegistry::removeObject('view');
|
|
||||||
ClassRegistry::flush();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
?>
|
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user