Compare commits
183 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| c9ade62536 | |||
| 4f0b5ffc28 | |||
| ce4fa4131a | |||
| 80f8bd36d5 | |||
| 7aa1100cac | |||
| b9c1a81c3b | |||
| bd0bbd768d | |||
| 20b8908a00 | |||
| ab51fd32d2 | |||
| b780ebeb3e | |||
| 117e31af69 | |||
| 28b3f35318 | |||
| 2b8a525718 | |||
| dc6e399fea | |||
| 1508f963d3 | |||
| 3270ad9bf0 | |||
| febd216810 | |||
| c8b781804a | |||
| 3e5ac64108 | |||
| 9b6830468e | |||
| 063aec6c3c | |||
| a2ae522b2d | |||
| ba218fbeeb | |||
| 2e67695154 | |||
| a136fd5313 | |||
| 1e3774cad6 | |||
| 518f7836ac | |||
| 416e230da8 | |||
| cd416ea5fa | |||
| 001b156333 | |||
| df1e0daafd | |||
| 9331b0a412 | |||
| fae90c3fa9 | |||
| a83edef049 | |||
| 4ada3d5bac | |||
| ede1053de4 | |||
| ce9142ffe2 | |||
| 0270e5ea89 | |||
| 4d2b4779d4 | |||
| fe7d7c6b0f | |||
| 435b0614b2 | |||
| 708910870c | |||
| 8b067bf676 | |||
| 388dbc0540 | |||
| ce20a44836 | |||
| 1495bb3373 | |||
| eaea52a862 | |||
| 271207629b | |||
| edca01f98c | |||
| 23f4a29fc7 | |||
| 543e2daa43 | |||
| 3911b3303f | |||
| d859cb4dee | |||
| 39071b39fb | |||
| 3dcdcb03eb | |||
| 41636f5c75 | |||
| 1890a0490e | |||
| 2b9369b823 | |||
| 4ec3db7b58 | |||
| 9f876b78de | |||
| 31c603c757 | |||
| 4d49ad6516 | |||
| 015e6b082d | |||
| cdec4c3301 | |||
| 404323c6c1 | |||
| d5dbabd94a | |||
| c90830d41a | |||
| f6ca79d1a9 | |||
| 5fab94011b | |||
| af2d5c38f3 | |||
| 6b8d05f2a0 | |||
| 336ec3b643 | |||
| b4d640f7c2 | |||
| 90a16c721e | |||
| e7b4b21328 | |||
| 3be775f9b2 | |||
| 0278c77610 | |||
| 508a8b08aa | |||
| c5bd8b4b16 | |||
| a49b86898e | |||
| 55dd94681a | |||
| 2f91dd456a | |||
| e32a5e5d4c | |||
| cca48fe86a | |||
| 839d9c1697 | |||
| c80c66d958 | |||
| a2fa71038a | |||
| d3c7011fc8 | |||
| 2c224dbc62 | |||
| 13b2283d76 | |||
| 3d89da7a61 | |||
| 99263920a3 | |||
| 8ab8d087e6 | |||
| 18b928411b | |||
| 8d062ab92e | |||
| 147c1e7097 | |||
| 760420bdc5 | |||
| fb48baf575 | |||
| d60c9721ca | |||
| f8eb45a0b9 | |||
| 4277962e3b | |||
| a60d69ba52 | |||
| 55b896a9f0 | |||
| 9f8d4fa9b2 | |||
| 4988d2717f | |||
| 136d8e845a | |||
| 190a9259d4 | |||
| 374843aeee | |||
| 52032180f3 | |||
| d14b715a88 | |||
| 2a2d11ba0f | |||
| 2e07cb87a5 | |||
| bb5b563738 | |||
| f3ffa3c079 | |||
| 30b934823c | |||
| 948ae28616 | |||
| 30c6e0b0f4 | |||
| 46e3316ce1 | |||
| e1671a9fca | |||
| e586268dee | |||
| 24730fda1b | |||
| b6ec85205d | |||
| b6a0809350 | |||
| f42ce65768 | |||
| ef180e7dda | |||
| 4aa59a40a2 | |||
| 0c43a0f884 | |||
| e65db5c759 | |||
| 59b549955e | |||
| 603a08393e | |||
| 1db887cf38 | |||
| 4ebe1db2cc | |||
| f74073a2e1 | |||
| 3f6c526718 | |||
| 903209a47e | |||
| 23a81ae924 | |||
| 9db4dd737d | |||
| 52528f1c0e | |||
| 6bf06a3a3c | |||
| 387c1ae87b | |||
| 70812e0a0c | |||
| 7fae1bcaad | |||
| c041174b0c | |||
| 2a4b8079fb | |||
| 79bcf99fc5 | |||
| 9d09afca35 | |||
| f384e051bf | |||
| 2da7b6b2c0 | |||
| 2c85566ffc | |||
| db03c73b59 | |||
| 684f02ebc5 | |||
| 4e33c58246 | |||
| 9fc5562dd8 | |||
| 3cc8e95ff4 | |||
| 15930fae30 | |||
| dbe037fee8 | |||
| 5c6189cdef | |||
| 4a86d3dda0 | |||
| ec3d986c78 | |||
| e38e99c94e | |||
| aed2c6912c | |||
| 7433e6868c | |||
| 8393403443 | |||
| ed04f81dda | |||
| 4923712238 | |||
| ffe04ed6fd | |||
| 0021eb1768 | |||
| 0ef51ee30f | |||
| 28bf192853 | |||
| df846f9963 | |||
| f4007a0269 | |||
| 6b53d8a25a | |||
| 76a06d1655 | |||
| eeb8775820 | |||
| 2d9a85ad82 | |||
| 0da1080b86 | |||
| 2665d012c2 | |||
| c5d5e2c651 | |||
| c22be388cf | |||
| 220284d20f | |||
| 4502b73b2e | |||
| 3251ba340d | |||
| c9f9d0867b |
@@ -0,0 +1,3 @@
|
|||||||
|
@echo off
|
||||||
|
%~dp0\scripts\sitelink2pmgr.pl %~dp0\db\schema.sql %~dp0db\vss.mdb > NUL
|
||||||
|
echo Done!
|
||||||
+1170
File diff suppressed because it is too large
Load Diff
@@ -1,28 +0,0 @@
|
|||||||
<?php
|
|
||||||
class Transaction extends AppModel {
|
|
||||||
|
|
||||||
var $name = 'Transaction';
|
|
||||||
/* var $validate = array( */
|
|
||||||
/* 'stamp' => array('date') */
|
|
||||||
/* ); */
|
|
||||||
|
|
||||||
var $belongsTo = array(
|
|
||||||
'Customer',
|
|
||||||
);
|
|
||||||
|
|
||||||
var $hasMany = array(
|
|
||||||
'LedgerEntry',
|
|
||||||
);
|
|
||||||
|
|
||||||
|
|
||||||
function beforeSave() {
|
|
||||||
|
|
||||||
if(!empty($this->data['Transaction']['stamp'])) {
|
|
||||||
$this->data['Transaction']['stamp'] =
|
|
||||||
$this->dateFormatBeforeSave($this->data['Transaction']['stamp']);
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
?>
|
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -305,7 +305,13 @@ class AppController extends Controller {
|
|||||||
$id = 'id';
|
$id = 'id';
|
||||||
extract(array_intersect_key($fields, array_flip($special)));
|
extract(array_intersect_key($fields, array_flip($special)));
|
||||||
foreach ($records AS &$record) {
|
foreach ($records AS &$record) {
|
||||||
|
if (!isset($record[$table]))
|
||||||
|
continue;
|
||||||
|
|
||||||
foreach (array_diff_key($fields, array_flip($special)) AS $field) {
|
foreach (array_diff_key($fields, array_flip($special)) AS $field) {
|
||||||
|
if (!isset($record[$table][$id]) || !isset($record[$table][$field]))
|
||||||
|
continue;
|
||||||
|
|
||||||
// DEBUG PURPOSES ONLY!
|
// DEBUG PURPOSES ONLY!
|
||||||
//$params['linkrecord'][] = compact('table', 'field', 'id', 'controller', 'record');
|
//$params['linkrecord'][] = compact('table', 'field', 'id', 'controller', 'record');
|
||||||
$record[$table][$field] =
|
$record[$table][$field] =
|
||||||
@@ -338,30 +344,40 @@ class AppController extends Controller {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function jqGridDataOutputRecords(&$params, &$model, &$records) {
|
function jqGridDataOutputRecords(&$params, &$model, &$records) {
|
||||||
$model_alias = $model->alias;
|
$id_field = 'jqGrid_id';
|
||||||
$id = 'jqGrid_id';
|
|
||||||
|
|
||||||
foreach ($records AS $record) {
|
foreach ($records AS $record) {
|
||||||
echo " <row id='{$record[$id]}'>\n";
|
$this->jqGridDataOutputRecord($params, $model, $record,
|
||||||
foreach ($params['fields'] AS $field) {
|
$record[$id_field], $params['fields']);
|
||||||
if (preg_match("/\./", $field)) {
|
|
||||||
list($tbl, $col) = explode(".", $field);
|
|
||||||
$data = $record[$tbl][$col];
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
$data = $record[$model_alias][$field];
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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";
|
|
||||||
}
|
|
||||||
echo " </row>\n";
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function jqGridDataOutputRecord(&$params, &$model, &$record, $id, $fields) {
|
||||||
|
echo " <row id='$id'>\n";
|
||||||
|
foreach ($fields AS $field) {
|
||||||
|
$this->jqGridDataOutputRecordField($params, $model, $record, $field);
|
||||||
|
}
|
||||||
|
echo " </row>\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
function jqGridDataOutputRecordField(&$params, &$model, &$record, $field) {
|
||||||
|
if (preg_match("/\./", $field)) {
|
||||||
|
list($tbl, $col) = explode(".", $field);
|
||||||
|
$data = $record[$tbl][$col];
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$data = $record[$model->alias][$field];
|
||||||
|
}
|
||||||
|
$this->jqGridDataOutputRecordCell($params, $model, $record, $field, $data);
|
||||||
|
}
|
||||||
|
|
||||||
|
function jqGridDataOutputRecordCell(&$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";
|
||||||
|
}
|
||||||
|
|
||||||
function jqGridDataFinalize(&$params) {
|
function jqGridDataFinalize(&$params) {
|
||||||
if ($params['debug']) {
|
if ($params['debug']) {
|
||||||
$xml = ob_get_contents();
|
$xml = ob_get_contents();
|
||||||
@@ -71,6 +71,7 @@ class LeasesController extends AppController {
|
|||||||
function jqGridRecordLinks(&$params, &$model, &$records, $links) {
|
function jqGridRecordLinks(&$params, &$model, &$records, $links) {
|
||||||
$links['Lease'] = array('number');
|
$links['Lease'] = array('number');
|
||||||
$links['Unit'] = array('name');
|
$links['Unit'] = array('name');
|
||||||
|
$links['Customer'] = array('name');
|
||||||
return parent::jqGridRecordLinks($params, $model, $records, $links);
|
return parent::jqGridRecordLinks($params, $model, $records, $links);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -107,7 +108,6 @@ class LeasesController extends AppController {
|
|||||||
array(// Models
|
array(// Models
|
||||||
'LeaseType',
|
'LeaseType',
|
||||||
'Unit',
|
'Unit',
|
||||||
'Account' => array('CurrentLedger'),
|
|
||||||
'Customer',
|
'Customer',
|
||||||
),
|
),
|
||||||
'conditions' => array(array('Lease.id' => $id)),
|
'conditions' => array(array('Lease.id' => $id)),
|
||||||
@@ -115,23 +115,15 @@ class LeasesController extends AppController {
|
|||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
// Summarize each ledger
|
|
||||||
$this->Lease->statsMerge($lease,
|
|
||||||
$this->Lease->stats($lease['Lease']['id']));
|
|
||||||
|
|
||||||
// Obtain the overall lease balance
|
// Obtain the overall lease balance
|
||||||
$this->Lease->statsMerge($lease['Lease'],
|
$this->Lease->statsMerge($lease['Lease'],
|
||||||
array('stats' => $this->Lease->stats($id)));
|
array('stats' => $this->Lease->stats($id)));
|
||||||
$outstanding_balance = $lease['Lease']['stats']['Account']['Ledger']['balance'];
|
$outstanding_balance = $lease['Lease']['stats']['balance'];
|
||||||
|
|
||||||
// Determine the lease security deposit
|
// Determine the lease security deposit
|
||||||
$deposits = $this->Lease->findSecurityDeposits($lease['Lease']['id']);
|
$deposits = $this->Lease->findSecurityDeposits($lease['Lease']['id']);
|
||||||
$outstanding_deposit = $deposits['summary']['balance'];
|
$outstanding_deposit = $deposits['summary']['balance'];
|
||||||
|
|
||||||
// Move the Leder stats into our alias 'CurrentLedger'
|
|
||||||
$lease['Account']['CurrentLedger'] += $lease['Account']['Ledger'];
|
|
||||||
unset($lease['Account']['Ledger']);
|
|
||||||
|
|
||||||
// Prepare to render
|
// Prepare to render
|
||||||
$title = 'Lease: #' . $lease['Lease']['id'];
|
$title = 'Lease: #' . $lease['Lease']['id'];
|
||||||
$this->set(compact('lease', 'title',
|
$this->set(compact('lease', 'title',
|
||||||
+161
-17
@@ -25,7 +25,15 @@ class LedgerEntriesController extends AppController {
|
|||||||
* to jqGrid.
|
* to jqGrid.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
function jqGridDataTables(&$params, &$model) {
|
function jqGridDataSetup(&$params) {
|
||||||
|
parent::jqGridDataSetup($params);
|
||||||
|
if (isset($params['custom']['ar_account'])) {
|
||||||
|
$params['custom']['account_id'] =
|
||||||
|
$this->LedgerEntry->DebitLedger->Account->accountReceivableAccountID();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function jqGridDataCountTables(&$params, &$model) {
|
||||||
$link =
|
$link =
|
||||||
array(// Models
|
array(// Models
|
||||||
'Transaction' =>
|
'Transaction' =>
|
||||||
@@ -36,6 +44,16 @@ class LedgerEntriesController extends AppController {
|
|||||||
array('fields' => array('id', 'name'),
|
array('fields' => array('id', 'name'),
|
||||||
),
|
),
|
||||||
|
|
||||||
|
'Customer' =>
|
||||||
|
array('fields' => array('id', 'name'),
|
||||||
|
),
|
||||||
|
|
||||||
|
'Lease' =>
|
||||||
|
array('fields' => array('id', 'number'),
|
||||||
|
'Unit' =>
|
||||||
|
array('fields' => array('id', 'name'),
|
||||||
|
),
|
||||||
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
if (isset($params['custom']['account_ftype'])) {
|
if (isset($params['custom']['account_ftype'])) {
|
||||||
@@ -77,26 +95,86 @@ class LedgerEntriesController extends AppController {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (isset($params['custom']['account_id']) || isset($params['custom']['lease_id'])) {
|
||||||
|
if (isset($params['custom']['account_id']))
|
||||||
|
$account_id = $params['custom']['account_id'];
|
||||||
|
else
|
||||||
|
$account_id =
|
||||||
|
$this->LedgerEntry->DebitLedger->Account->accountReceivableAccountID();
|
||||||
|
|
||||||
|
$link['Ledger'] =
|
||||||
|
array('fields' => array('id', 'sequence'),
|
||||||
|
'conditions' => ("Ledger.id = IF(DebitLedger.account_id = $account_id," .
|
||||||
|
" LedgerEntry.credit_ledger_id," .
|
||||||
|
" LedgerEntry.debit_ledger_id)"),
|
||||||
|
'Account' => array(
|
||||||
|
'fields' => array('id', 'name'),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isset($params['custom']['lease_id'])) {
|
||||||
|
$account_id = $params['custom']['lease_id'];
|
||||||
|
$link['Transaction']['ReconciledLedgerEntry'] =
|
||||||
|
array('fields' => array('id', 'Reconciliation.amount', 'Reconciliation.type'),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
if (isset($params['custom']['reconcile_id'])) {
|
if (isset($params['custom']['reconcile_id'])) {
|
||||||
$ftype = $params['custom']['account_ftype'];
|
$ftype = $params['custom']['account_ftype'];
|
||||||
$ftype = $this->LedgerEntry->DebitLedger->Account->fundamentalOpposite($ftype);
|
$ftype = $this->LedgerEntry->DebitLedger->Account->fundamentalOpposite($ftype);
|
||||||
$ftype = ucfirst($ftype);
|
$link['ReconcilingTransaction'] =
|
||||||
$link[$ftype.'ReconciliationLedgerEntry'] =
|
array('fields' => array('Reconciliation.amount'),
|
||||||
array('fields' => array('Reconciliation.amount'));
|
'conditions' => array('Reconciliation.type' => $ftype),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
return array('link' => $link);
|
return array('link' => $link);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function jqGridDataTables(&$params, &$model) {
|
||||||
|
return $this->jqGridDataCountTables($params, $model);
|
||||||
|
}
|
||||||
|
|
||||||
function jqGridDataFields(&$params, &$model) {
|
function jqGridDataFields(&$params, &$model) {
|
||||||
|
if (isset($params['custom']['lease_id'])) {
|
||||||
|
$account_id =
|
||||||
|
$this->LedgerEntry->DebitLedger->Account->accountReceivableAccountID();
|
||||||
|
|
||||||
|
$fields = array('id', 'name', 'comment', 'amount');
|
||||||
|
$fields[] = ("IF(DebitLedger.account_id = $account_id," .
|
||||||
|
" SUM(IF(ReconciledLedgerEntry.amount IS NULL," .
|
||||||
|
" LedgerEntry.amount," .
|
||||||
|
" ReconciledLedgerEntry.amount))," .
|
||||||
|
" NULL) AS debit");
|
||||||
|
$fields[] = ("IF(CreditLedger.account_id = $account_id," .
|
||||||
|
" SUM(IF(ReconciledLedgerEntry.amount IS NULL," .
|
||||||
|
" LedgerEntry.amount," .
|
||||||
|
" ReconciledLedgerEntry.amount))," .
|
||||||
|
" NULL) AS credit");
|
||||||
|
|
||||||
|
$Account = new Account();
|
||||||
|
$account_ftype = ucfirst($Account->fundamentalType($account_id));
|
||||||
|
$fields[] = ("(IF({$account_ftype}Ledger.account_id = $account_id, 1, -1)" .
|
||||||
|
" * SUM(IF(ReconciledLedgerEntry.amount IS NULL," .
|
||||||
|
" LedgerEntry.amount," .
|
||||||
|
" ReconciledLedgerEntry.amount)))" .
|
||||||
|
" AS balance");
|
||||||
|
|
||||||
|
return $fields;
|
||||||
|
}
|
||||||
|
|
||||||
$ledger_id = (isset($params['custom']['ledger_id'])
|
$ledger_id = (isset($params['custom']['ledger_id'])
|
||||||
? $params['custom']['ledger_id']
|
? $params['custom']['ledger_id']
|
||||||
: null);
|
: null);
|
||||||
|
$account_id = (isset($params['custom']['account_id'])
|
||||||
|
? $params['custom']['account_id']
|
||||||
|
: null);
|
||||||
$account_type = (isset($params['custom']['account_type'])
|
$account_type = (isset($params['custom']['account_type'])
|
||||||
? $params['custom']['account_type']
|
? $params['custom']['account_type']
|
||||||
: null);
|
: null);
|
||||||
|
|
||||||
return $model->ledgerContextFields2($ledger_id, $account_type);
|
return $model->ledgerContextFields2($ledger_id, $account_id, $account_type);
|
||||||
}
|
}
|
||||||
|
|
||||||
function jqGridDataConditions(&$params, &$model) {
|
function jqGridDataConditions(&$params, &$model) {
|
||||||
@@ -109,13 +187,44 @@ class LedgerEntriesController extends AppController {
|
|||||||
|
|
||||||
$conditions = parent::jqGridDataConditions($params, $model);
|
$conditions = parent::jqGridDataConditions($params, $model);
|
||||||
|
|
||||||
if ($params['action'] === 'ledger') {
|
if ($params['action'] === 'ledger' && isset($ledger_id)) {
|
||||||
$conditions[] = $model->ledgerContextConditions($ledger_id, $account_type);
|
$conditions[] = $model->ledgerContextConditions($ledger_id, $account_type);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isset($params['custom']['reconcile_id'])) {
|
if (isset($params['custom']['reconcile_id'])) {
|
||||||
$ftype = $params['custom']['account_ftype'];
|
$ftype = $params['custom']['account_ftype'];
|
||||||
//$ftype = $this->LedgerEntry->DebitLedger->Account->fundamentalOpposite($ftype);
|
//$ftype = $this->LedgerEntry->DebitLedger->Account->fundamentalOpposite($ftype);
|
||||||
$conditions[] = array('Reconciliation.'.$ftype.'_ledger_entry_id' => $params['custom']['reconcile_id']);
|
//$link['ReconcilingTransaction']['conditions'][] = array('Reconciliation.type' => $ftype);
|
||||||
|
$conditions[] = array('Reconciliation.ledger_entry_id' => $params['custom']['reconcile_id']);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isset($params['custom']['account_id'])) {
|
||||||
|
$conditions[] =
|
||||||
|
array('OR' =>
|
||||||
|
array(array('CreditAccount.id' => $params['custom']['account_id']),
|
||||||
|
array('DebitAccount.id' => $params['custom']['account_id'])));
|
||||||
|
/* $conditions[] = */
|
||||||
|
/* array('Account.id' => $params['custom']['account_id']); */
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isset($params['custom']['customer_id'])) {
|
||||||
|
$conditions[] =
|
||||||
|
array('Customer.id' => $params['custom']['customer_id']);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isset($params['custom']['lease_id'])) {
|
||||||
|
$conditions[] =
|
||||||
|
array('OR' => array
|
||||||
|
(array('Lease.id' => $params['custom']['lease_id']),
|
||||||
|
array('ReconciledLedgerEntry.lease_id' => $params['custom']['lease_id']),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isset($params['custom']['transaction_id'])) {
|
||||||
|
$conditions[] =
|
||||||
|
array('Transaction.id' => $params['custom']['transaction_id']);
|
||||||
}
|
}
|
||||||
|
|
||||||
return $conditions;
|
return $conditions;
|
||||||
@@ -124,14 +233,13 @@ class LedgerEntriesController extends AppController {
|
|||||||
function jqGridRecordLinks(&$params, &$model, &$records, $links) {
|
function jqGridRecordLinks(&$params, &$model, &$records, $links) {
|
||||||
$links['Transaction'] = array('id');
|
$links['Transaction'] = array('id');
|
||||||
$links['LedgerEntry'] = array('id');
|
$links['LedgerEntry'] = array('id');
|
||||||
if (isset($params['custom']['account_ftype']) || isset($params['custom']['ledger_id'])) {
|
$links['Account'] = array('controller' => 'accounts', 'name');
|
||||||
$links['Account'] = array('controller' => 'accounts', 'name');
|
$links['DebitAccount'] = array('controller' => 'accounts', 'name');
|
||||||
}
|
$links['CreditAccount'] = array('controller' => 'accounts', 'name');
|
||||||
else {
|
|
||||||
$links['DebitAccount'] = array('controller' => 'accounts', 'name');
|
|
||||||
$links['CreditAccount'] = array('controller' => 'accounts', 'name');
|
|
||||||
}
|
|
||||||
$links['MonetarySource'] = array('name');
|
$links['MonetarySource'] = array('name');
|
||||||
|
$links['Customer'] = array('name');
|
||||||
|
$links['Lease'] = array('number');
|
||||||
|
$links['Unit'] = array('name');
|
||||||
return parent::jqGridRecordLinks($params, $model, $records, $links);
|
return parent::jqGridRecordLinks($params, $model, $records, $links);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -145,8 +253,39 @@ class LedgerEntriesController extends AppController {
|
|||||||
function jqGridDataOrder(&$params, &$model, $index, $direction) {
|
function jqGridDataOrder(&$params, &$model, $index, $direction) {
|
||||||
/* if ($index === 'balance') */
|
/* if ($index === 'balance') */
|
||||||
/* return ($index .' '. $direction); */
|
/* return ($index .' '. $direction); */
|
||||||
|
$order = parent::jqGridDataOrder($params, $model, $index, $direction);
|
||||||
|
|
||||||
return parent::jqGridDataOrder($params, $model, $index, $direction);
|
if ($index === 'Transaction.stamp') {
|
||||||
|
$order[] = 'LedgerEntry.id ' . $direction;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $order;
|
||||||
|
}
|
||||||
|
|
||||||
|
function jqGridRecordsPostProcess(&$params, &$model, &$records) {
|
||||||
|
parent::jqGridRecordsPostProcess($params, $model, $records);
|
||||||
|
|
||||||
|
$subtotal = 0;
|
||||||
|
foreach ($records AS &$record) {
|
||||||
|
$amount = (isset($record['LedgerEntry']['balance'])
|
||||||
|
? $record['LedgerEntry']['balance']
|
||||||
|
: $record['LedgerEntry']['amount']);
|
||||||
|
$record['LedgerEntry']['subtotal'] = ($subtotal += $amount);
|
||||||
|
|
||||||
|
continue;
|
||||||
|
// Experiment to minimize columns by putting the monetary source
|
||||||
|
// as the Account, when available
|
||||||
|
if ($record['MonetarySource']['name'])
|
||||||
|
$record['Account']['name'] = $record['MonetarySource']['name'];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function jqGridDataOutputRecordCell(&$params, &$model, &$record, $field, $data) {
|
||||||
|
/* if ($field === 'CreditAccount.name') { */
|
||||||
|
/* $data .= '-OK'; */
|
||||||
|
/* } */
|
||||||
|
|
||||||
|
parent::jqGridDataOutputRecordCell($params, $model, $record, $field, $data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -167,6 +306,7 @@ class LedgerEntriesController extends AppController {
|
|||||||
$entry = $this->LedgerEntry->find
|
$entry = $this->LedgerEntry->find
|
||||||
('first',
|
('first',
|
||||||
array('contain' => array('MonetarySource.id',
|
array('contain' => array('MonetarySource.id',
|
||||||
|
'MonetarySource.name',
|
||||||
'MonetarySource.MonetaryType.id',
|
'MonetarySource.MonetaryType.id',
|
||||||
'Transaction.id',
|
'Transaction.id',
|
||||||
'Transaction.stamp',
|
'Transaction.stamp',
|
||||||
@@ -176,6 +316,9 @@ class LedgerEntriesController extends AppController {
|
|||||||
'CreditLedger.id',
|
'CreditLedger.id',
|
||||||
'CreditLedger.sequence',
|
'CreditLedger.sequence',
|
||||||
'CreditLedger.account_id',
|
'CreditLedger.account_id',
|
||||||
|
'Customer.id',
|
||||||
|
'Customer.name',
|
||||||
|
'Lease.id',
|
||||||
),
|
),
|
||||||
|
|
||||||
'fields' => array('LedgerEntry.id',
|
'fields' => array('LedgerEntry.id',
|
||||||
@@ -184,6 +327,7 @@ class LedgerEntriesController extends AppController {
|
|||||||
|
|
||||||
'conditions' => array('LedgerEntry.id' => $id),
|
'conditions' => array('LedgerEntry.id' => $id),
|
||||||
));
|
));
|
||||||
|
//pr($entry);
|
||||||
|
|
||||||
// Because 'DebitLedger' and 'CreditLedger' both relate to 'Account',
|
// Because 'DebitLedger' and 'CreditLedger' both relate to 'Account',
|
||||||
// CakePHP will not include them in the LedgerEntry->find (or so it
|
// CakePHP will not include them in the LedgerEntry->find (or so it
|
||||||
@@ -213,8 +357,8 @@ class LedgerEntriesController extends AppController {
|
|||||||
$stats['credit_amount_remaining'] = $entry['LedgerEntry']['amount'] - $stats['credit_amount_reconciled'];
|
$stats['credit_amount_remaining'] = $entry['LedgerEntry']['amount'] - $stats['credit_amount_reconciled'];
|
||||||
//pr($stats);
|
//pr($stats);
|
||||||
|
|
||||||
$reconciled = $this->LedgerEntry->findReconciledLedgerEntries($id);
|
$reconciled = $this->LedgerEntry->findReconcilingTransactions($id);
|
||||||
//pr($reconciled);
|
//pr(compact('reconciled'));
|
||||||
|
|
||||||
// Prepare to render.
|
// Prepare to render.
|
||||||
$title = "Ledger Entry #{$entry['LedgerEntry']['id']}";
|
$title = "Ledger Entry #{$entry['LedgerEntry']['id']}";
|
||||||
+37
@@ -41,6 +41,43 @@ class TransactionsController extends AppController {
|
|||||||
* to jqGrid.
|
* to jqGrid.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
function jqGridDataSetup(&$params) {
|
||||||
|
parent::jqGridDataSetup($params);
|
||||||
|
}
|
||||||
|
|
||||||
|
function jqGridDataTables(&$params, &$model) {
|
||||||
|
$link = array();
|
||||||
|
|
||||||
|
if (isset($params['custom']['reconcile_ledger_entry_id'])) {
|
||||||
|
$ftype = $params['custom']['reconcile_type'];
|
||||||
|
//$ftype = $this->Transaction->LedgerEntry->DebitLedger->Account->fundamentalOpposite($ftype);
|
||||||
|
$link['ReconciledLedgerEntry'] =
|
||||||
|
array('fields' => array('Reconciliation.amount'),
|
||||||
|
'conditions' => array('Reconciliation.type' => $ftype)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return array('link' => $link);
|
||||||
|
}
|
||||||
|
|
||||||
|
function jqGridDataFields(&$params, &$model) {
|
||||||
|
return parent::jqGridDataFields($params, $model);
|
||||||
|
}
|
||||||
|
|
||||||
|
function jqGridDataConditions(&$params, &$model) {
|
||||||
|
$conditions = parent::jqGridDataConditions($params, $model);
|
||||||
|
|
||||||
|
if (isset($params['custom']['reconcile_ledger_entry_id'])) {
|
||||||
|
/* $ftype = $params['custom']['reconcile_type']; */
|
||||||
|
/* $ftype = $this->LedgerEntry->DebitLedger->Account->fundamentalOpposite($ftype); */
|
||||||
|
/* $conditions[] = array('Reconciliation.type' => $ftype); */
|
||||||
|
$conditions[] = array('Reconciliation.ledger_entry_id'
|
||||||
|
=> $params['custom']['reconcile_ledger_entry_id']);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $conditions;
|
||||||
|
}
|
||||||
|
|
||||||
function jqGridRecordLinks(&$params, &$model, &$records, $links) {
|
function jqGridRecordLinks(&$params, &$model, &$records, $links) {
|
||||||
$links['Transaction'] = array('id');
|
$links['Transaction'] = array('id');
|
||||||
return parent::jqGridRecordLinks($params, $model, $records, $links);
|
return parent::jqGridRecordLinks($params, $model, $records, $links);
|
||||||
@@ -121,7 +121,7 @@ class UnitsController extends AppController {
|
|||||||
// Get the balance on each lease.
|
// Get the balance on each lease.
|
||||||
foreach ($unit['Lease'] AS &$lease) {
|
foreach ($unit['Lease'] AS &$lease) {
|
||||||
$stats = $this->Unit->Lease->stats($lease['id']);
|
$stats = $this->Unit->Lease->stats($lease['id']);
|
||||||
$lease['balance'] = $stats['Account']['Ledger']['balance'];
|
$lease['balance'] = $stats['balance'];
|
||||||
}
|
}
|
||||||
|
|
||||||
$outstanding_balance = 0;
|
$outstanding_balance = 0;
|
||||||
@@ -130,7 +130,7 @@ class UnitsController extends AppController {
|
|||||||
// Figure out the outstanding balance of the current lease.
|
// Figure out the outstanding balance of the current lease.
|
||||||
$stats = $this->Unit->stats($id);
|
$stats = $this->Unit->stats($id);
|
||||||
$outstanding_balance =
|
$outstanding_balance =
|
||||||
$stats['CurrentLease']['Account']['Ledger']['balance'];
|
$stats['CurrentLease']['balance'];
|
||||||
|
|
||||||
// Figure out the total security deposit for the current lease.
|
// Figure out the total security deposit for the current lease.
|
||||||
$deposits = $this->Unit->Lease->findSecurityDeposits($unit['CurrentLease']['id']);
|
$deposits = $this->Unit->Lease->findSecurityDeposits($unit['CurrentLease']['id']);
|
||||||
@@ -82,37 +82,26 @@ class Account extends AppModel {
|
|||||||
/**************************************************************************
|
/**************************************************************************
|
||||||
**************************************************************************
|
**************************************************************************
|
||||||
**************************************************************************
|
**************************************************************************
|
||||||
* function: securityDepositAccountID
|
* function: accountNameToID
|
||||||
* - Returns the ID of the Security Deposit Account
|
* - Returns the ID of the named account
|
||||||
*/
|
*/
|
||||||
function securityDepositAccountID() {
|
function accountNameToID($name) {
|
||||||
$this->cacheQueries = true;
|
$this->cacheQueries = true;
|
||||||
$account = $this->find('first', array
|
$account = $this->find('first', array
|
||||||
('recursive' => -1,
|
('recursive' => -1,
|
||||||
'conditions' => array
|
'conditions' => compact('name'),
|
||||||
(array('name' => 'Security Deposit')),
|
|
||||||
));
|
));
|
||||||
$this->cacheQueries = false;
|
$this->cacheQueries = false;
|
||||||
return $account['Account']['id'];
|
return $account['Account']['id'];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function securityDepositAccountID() { return $this->accountNameToID('Security Deposit'); }
|
||||||
/**************************************************************************
|
function rentAccountID() { return $this->accountNameToID('Rent'); }
|
||||||
**************************************************************************
|
function accountReceivableAccountID() { return $this->accountNameToID('A/R'); }
|
||||||
**************************************************************************
|
function invoiceAccountID() { return $this->accountReceivableAccountID(); }
|
||||||
* function:rentAccountID
|
function receiptAccountID() { return $this->accountReceivableAccountID(); }
|
||||||
* - Returns the ID of the Rent Account
|
//function invoiceAccountID() { return $this->accountNameToID('Invoice'); }
|
||||||
*/
|
//function receiptAccountID() { return $this->accountNameToID('Receipt'); }
|
||||||
function rentAccountID() {
|
|
||||||
$this->cacheQueries = true;
|
|
||||||
$account = $this->find('first', array
|
|
||||||
('recursive' => -1,
|
|
||||||
'conditions' => array
|
|
||||||
(array('name' => 'Rent')),
|
|
||||||
));
|
|
||||||
$this->cacheQueries = false;
|
|
||||||
return $account['Account']['id'];
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**************************************************************************
|
/**************************************************************************
|
||||||
@@ -122,22 +111,19 @@ class Account extends AppModel {
|
|||||||
* - Returns an array of ledger ids from the given account
|
* - Returns an array of ledger ids from the given account
|
||||||
*/
|
*/
|
||||||
function ledgers($id, $all = false) {
|
function ledgers($id, $all = false) {
|
||||||
$cachekey = $all ? 'all' : 'current';
|
|
||||||
if (isset($this->cache[$id]['ledgers'][$cachekey])) {
|
|
||||||
return $this->cache[$id]['ledgers'][$cachekey];
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($all) {
|
if ($all) {
|
||||||
$contain = array('Ledger' => array('fields' => array('Ledger.id')));
|
$contain = array('Ledger' => array('fields' => array('Ledger.id')));
|
||||||
} else {
|
} else {
|
||||||
$contain = array('CurrentLedger' => array('fields' => array('CurrentLedger.id')));
|
$contain = array('CurrentLedger' => array('fields' => array('CurrentLedger.id')));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$this->cacheQueries = true;
|
||||||
$account = $this->find('first', array
|
$account = $this->find('first', array
|
||||||
('contain' => $contain,
|
('contain' => $contain,
|
||||||
'fields' => array(),
|
'fields' => array(),
|
||||||
'conditions' => array(array('Account.id' => $id)),
|
'conditions' => array(array('Account.id' => $id)),
|
||||||
));
|
));
|
||||||
|
$this->cacheQueries = false;
|
||||||
|
|
||||||
if ($all) {
|
if ($all) {
|
||||||
$ledger_ids = array();
|
$ledger_ids = array();
|
||||||
@@ -148,14 +134,11 @@ class Account extends AppModel {
|
|||||||
$ledger_ids = array($account['CurrentLedger']['id']);
|
$ledger_ids = array($account['CurrentLedger']['id']);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Save the ledgers in our cache for future reference
|
|
||||||
$this->cache[$id]['ledgers'][$cachekey] = $ledger_ids;
|
|
||||||
|
|
||||||
/* pr(array('function' => 'Account::ledgers', */
|
/* pr(array('function' => 'Account::ledgers', */
|
||||||
/* 'args' => compact('id', 'all'), */
|
/* 'args' => compact('id', 'all'), */
|
||||||
/* 'return' => $this->cache[$id]['ledgers'][$cachekey])); */
|
/* 'return' => $ledger_ids)); */
|
||||||
|
|
||||||
return $this->cache[$id]['ledgers'][$cachekey];
|
return $ledger_ids;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -234,25 +217,29 @@ class Account extends AppModel {
|
|||||||
* (such as charges not paid).
|
* (such as charges not paid).
|
||||||
*/
|
*/
|
||||||
|
|
||||||
function findUnreconciledLedgerEntries($id = null, $fundamental_type = null) {
|
function findUnreconciledLedgerEntries($id = null, $fundamental_type = null, $cond = null) {
|
||||||
|
if (!isset($cond))
|
||||||
|
$cond = array();
|
||||||
|
$cond[] = array('Account.id' => $id);
|
||||||
|
|
||||||
foreach (($fundamental_type
|
foreach (($fundamental_type
|
||||||
? array($fundamental_type)
|
? array($fundamental_type)
|
||||||
: array('debit', 'credit')) AS $fund) {
|
: array('debit', 'credit')) AS $fund) {
|
||||||
$ucfund = ucfirst($fund);
|
$ucfund = ucfirst($fund);
|
||||||
$unreconciled[$fund]['entry'] = $this->find
|
$unreconciled[$fund]['LedgerEntry'] = $this->find
|
||||||
('all', array
|
('all', array
|
||||||
('link' => array
|
('link' => array
|
||||||
('Ledger' => array
|
('Ledger' => array
|
||||||
('fields' => array(),
|
('fields' => array(),
|
||||||
"LedgerEntry" => array
|
'LedgerEntry' => array
|
||||||
('class' => "{$ucfund}LedgerEntry",
|
('class' => "{$ucfund}LedgerEntry",
|
||||||
'fields' => array('id', 'amount'),
|
'fields' => array('id', 'amount'),
|
||||||
"ReconciliationLedgerEntry" => array
|
'ReconcilingTransaction' => array
|
||||||
('class' => "{$ucfund}ReconciliationLedgerEntry",
|
('fields' => array
|
||||||
'fields' => array
|
|
||||||
("COALESCE(SUM(Reconciliation.amount),0) AS 'reconciled'",
|
("COALESCE(SUM(Reconciliation.amount),0) AS 'reconciled'",
|
||||||
"LedgerEntry.amount - COALESCE(SUM(Reconciliation.amount),0) AS 'balance'",
|
"LedgerEntry.amount - COALESCE(SUM(Reconciliation.amount),0) AS 'balance'",
|
||||||
),
|
),
|
||||||
|
'conditions' => array('Reconciliation.type' => $fund),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@@ -260,11 +247,11 @@ class Account extends AppModel {
|
|||||||
'group' => ("LedgerEntry.id" .
|
'group' => ("LedgerEntry.id" .
|
||||||
" HAVING LedgerEntry.amount" .
|
" HAVING LedgerEntry.amount" .
|
||||||
" <> COALESCE(SUM(Reconciliation.amount),0)"),
|
" <> COALESCE(SUM(Reconciliation.amount),0)"),
|
||||||
'conditions' => array('Account.id' => $id),
|
'conditions' => $cond,
|
||||||
'fields' => array(),
|
'fields' => array(),
|
||||||
));
|
));
|
||||||
$balance = 0;
|
$balance = 0;
|
||||||
foreach ($unreconciled[$fund]['entry'] AS &$entry) {
|
foreach ($unreconciled[$fund]['LedgerEntry'] AS &$entry) {
|
||||||
$entry = array_merge(array_diff_key($entry["LedgerEntry"], array(0=>true)),
|
$entry = array_merge(array_diff_key($entry["LedgerEntry"], array(0=>true)),
|
||||||
$entry[0]);
|
$entry[0]);
|
||||||
$balance += $entry['balance'];
|
$balance += $entry['balance'];
|
||||||
@@ -290,24 +277,24 @@ class Account extends AppModel {
|
|||||||
* whatever algorithm is simplest.
|
* whatever algorithm is simplest.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
function reconcileNewLedgerEntry($id, $fundamental_type, $amount) {
|
function reconcileNewLedgerEntry($id, $fundamental_type, $amount, $cond = null) {
|
||||||
$ofund = $this->fundamentalOpposite($fundamental_type);
|
$ofund = $this->fundamentalOpposite($fundamental_type);
|
||||||
$unreconciled = array($ofund => array('entry'=>array(), 'balance'=>0));
|
$unreconciled = array($ofund => array('LedgerEntry'=>array(), 'balance'=>0));
|
||||||
$applied = 0;
|
$applied = 0;
|
||||||
|
|
||||||
// if there is no money in the entry, it can reconcile nothing
|
// if there is no money in the entry, it can reconcile nothing
|
||||||
// don't bother wasting time sifting ledger entries.
|
// don't bother wasting time sifting ledger entries.
|
||||||
if ($amount > 0) {
|
if ($amount > 0) {
|
||||||
$unreconciled = $this->findUnreconciledLedgerEntries($id, $ofund);
|
$unreconciled = $this->findUnreconciledLedgerEntries($id, $ofund, $cond);
|
||||||
|
|
||||||
foreach ($unreconciled[$ofund]['entry'] AS $i => &$entry) {
|
foreach ($unreconciled[$ofund]['LedgerEntry'] AS $i => &$entry) {
|
||||||
// Determine if amount is sufficient to cover the entry
|
// Determine if amount is sufficient to cover the entry
|
||||||
if ($amount > $entry['balance'])
|
if ($amount > $entry['balance'])
|
||||||
$apply = $entry['balance'];
|
$apply = $entry['balance'];
|
||||||
elseif ($amount > 0)
|
elseif ($amount > 0)
|
||||||
$apply = $amount;
|
$apply = $amount;
|
||||||
else {
|
else {
|
||||||
unset($unreconciled[$ofund]['entry'][$i]);
|
unset($unreconciled[$ofund]['LedgerEntry'][$i]);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -85,6 +85,28 @@ class LinkableBehavior extends ModelBehavior {
|
|||||||
|
|
||||||
protected $_defaults = array('type' => 'LEFT');
|
protected $_defaults = array('type' => 'LEFT');
|
||||||
|
|
||||||
|
function pr($lev, $mixed) {
|
||||||
|
if ($lev >= 5)
|
||||||
|
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
|
* This is a function for made recursive str_replaces in an array
|
||||||
* NOTE: The palacement of this function is terrible, but I don't
|
* NOTE: The palacement of this function is terrible, but I don't
|
||||||
@@ -108,7 +130,10 @@ class LinkableBehavior extends ModelBehavior {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public function beforeFind(&$Model, $query) {
|
public function beforeFind(&$Model, $query) {
|
||||||
/* pr("Linkable::beforeFind() begin"); pr($query); */
|
$this->pr(10,
|
||||||
|
array('function' => 'Linkable::beforeFind',
|
||||||
|
'args' => array('Model->alias' => '$Model->alias') + compact('query'),
|
||||||
|
));
|
||||||
if (isset($query[$this->_key])) {
|
if (isset($query[$this->_key])) {
|
||||||
$optionsDefaults = $this->_defaults + array('reference' =>
|
$optionsDefaults = $this->_defaults + array('reference' =>
|
||||||
array('class' => $Model->alias,
|
array('class' => $Model->alias,
|
||||||
@@ -132,7 +157,10 @@ class LinkableBehavior extends ModelBehavior {
|
|||||||
unset($iterator['defaults']);
|
unset($iterator['defaults']);
|
||||||
}
|
}
|
||||||
$iterations = Set::normalize($iterator);
|
$iterations = Set::normalize($iterator);
|
||||||
/* pr(array('checkpoint' => 'Iterations', compact('iterations'))); */
|
$this->pr(25,
|
||||||
|
array('checkpoint' => 'Iterations',
|
||||||
|
compact('iterations'),
|
||||||
|
));
|
||||||
foreach ($iterations as $alias => $options) {
|
foreach ($iterations as $alias => $options) {
|
||||||
if (is_null($options)) {
|
if (is_null($options)) {
|
||||||
$options = array();
|
$options = array();
|
||||||
@@ -145,7 +173,15 @@ class LinkableBehavior extends ModelBehavior {
|
|||||||
if (empty($options['class']))
|
if (empty($options['class']))
|
||||||
$options['class'] = $alias;
|
$options['class'] = $alias;
|
||||||
|
|
||||||
/* pr(array('checkpoint' => 'Begin Model Work', compact('alias', 'options'))); */
|
if (!isset($options['conditions']))
|
||||||
|
$options['conditions'] = array();
|
||||||
|
elseif (!is_array($options['conditions']))
|
||||||
|
$options['conditions'] = array($options['conditions']);
|
||||||
|
|
||||||
|
$this->pr(20,
|
||||||
|
array('checkpoint' => 'Begin Model Work',
|
||||||
|
compact('alias', 'options'),
|
||||||
|
));
|
||||||
|
|
||||||
$modelClass = $options['class'];
|
$modelClass = $options['class'];
|
||||||
$modelAlias = $options['alias'];
|
$modelAlias = $options['alias'];
|
||||||
@@ -154,11 +190,13 @@ class LinkableBehavior extends ModelBehavior {
|
|||||||
|
|
||||||
$_Model =& ClassRegistry::init($modelClass); // the incoming model to be linked in query
|
$_Model =& ClassRegistry::init($modelClass); // the incoming model to be linked in query
|
||||||
$Reference =& ClassRegistry::init($referenceClass); // the already in query model that links to $_Model
|
$Reference =& ClassRegistry::init($referenceClass); // the already in query model that links to $_Model
|
||||||
/* pr(array('checkpoint' => 'Aliases Established', */
|
$this->pr(12,
|
||||||
/* 'Model' => ($modelAlias .' : '. $modelClass . */
|
array('checkpoint' => 'Aliases Established',
|
||||||
/* ' ('. $_Model->alias .' : '. $_Model->name .')'), */
|
'Model' => ($modelAlias .' : '. $modelClass .
|
||||||
/* 'Reference' => ($referenceAlias .' : '. $referenceClass . */
|
' ('. $_Model->alias .' : '. $_Model->name .')'),
|
||||||
/* ' ('. $Reference->alias .' : '. $Reference->name .')'))); */
|
'Reference' => ($referenceAlias .' : '. $referenceClass .
|
||||||
|
' ('. $Reference->alias .' : '. $Reference->name .')'),
|
||||||
|
));
|
||||||
|
|
||||||
$db =& $_Model->getDataSource();
|
$db =& $_Model->getDataSource();
|
||||||
|
|
||||||
@@ -169,20 +207,20 @@ class LinkableBehavior extends ModelBehavior {
|
|||||||
// a relationship if one doesn't otherwise already exists.
|
// a relationship if one doesn't otherwise already exists.
|
||||||
if (($associations = $Reference->getAssociated()) &&
|
if (($associations = $Reference->getAssociated()) &&
|
||||||
isset($associations[$_Model->alias])) {
|
isset($associations[$_Model->alias])) {
|
||||||
/* pr("Reference defines association to _Model"); */
|
$this->pr(12, array('checkpoint' => "Reference defines association to _Model"));
|
||||||
$associatedThroughReference = 1;
|
$associatedThroughReference = 1;
|
||||||
$type = $associations[$_Model->alias];
|
$type = $associations[$_Model->alias];
|
||||||
$association = $Reference->{$type}[$_Model->alias];
|
$association = $Reference->{$type}[$_Model->alias];
|
||||||
}
|
}
|
||||||
elseif (($associations = $_Model->getAssociated()) &&
|
elseif (($associations = $_Model->getAssociated()) &&
|
||||||
isset($associations[$Reference->alias])) {
|
isset($associations[$Reference->alias])) {
|
||||||
/* pr("_Model defines association to Reference"); */
|
$this->pr(12, array('checkpoint' => "_Model defines association to Reference"));
|
||||||
$type = $associations[$Reference->alias];
|
$type = $associations[$Reference->alias];
|
||||||
$association = $_Model->{$type}[$Reference->alias];
|
$association = $_Model->{$type}[$Reference->alias];
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// No relationship... make our best effort to create one.
|
// No relationship... make our best effort to create one.
|
||||||
/* pr("No assocation between _Model and Reference"); */
|
$this->pr(12, array('checkpoint' => "No assocation between _Model and Reference"));
|
||||||
$type = 'belongsTo';
|
$type = 'belongsTo';
|
||||||
$_Model->bind($Reference->alias);
|
$_Model->bind($Reference->alias);
|
||||||
// Grab the association now, since we'll unbind in a moment.
|
// Grab the association now, since we'll unbind in a moment.
|
||||||
@@ -212,93 +250,119 @@ class LinkableBehavior extends ModelBehavior {
|
|||||||
$associationAlias,
|
$associationAlias,
|
||||||
$association['conditions']);
|
$association['conditions']);
|
||||||
|
|
||||||
/* pr(array('checkpoint' => 'Models Established - Check Associations', */
|
$this->pr(15,
|
||||||
/* 'primaryModel' => $primaryAlias .' : '. $primaryModel->name, */
|
array('checkpoint' => 'Models Established - Check Associations',
|
||||||
/* 'foreignModel' => $foreignAlias .' : '. $foreignModel->name, */
|
'primaryModel' => $primaryAlias .' : '. $primaryModel->name,
|
||||||
/* compact('type', 'association'))); */
|
'foreignModel' => $foreignAlias .' : '. $foreignModel->name,
|
||||||
|
compact('type', 'association'),
|
||||||
|
));
|
||||||
|
|
||||||
if (empty($options['conditions'])) {
|
if ($type === 'hasAndBelongsToMany') {
|
||||||
if ($type === 'hasAndBelongsToMany') {
|
if (isset($association['with']))
|
||||||
if (isset($association['with']))
|
$linkClass = $association['with'];
|
||||||
$linkClass = $association['with'];
|
else
|
||||||
else
|
$linkClass = Inflector::classify($association['joinTable']);
|
||||||
$linkClass = Inflector::classify($association['joinTable']);
|
|
||||||
|
|
||||||
$Link =& $_Model->{$linkClass};
|
$Link =& $_Model->{$linkClass};
|
||||||
|
|
||||||
if (isset($options['linkalias']))
|
if (isset($options['linkalias']))
|
||||||
$linkAlias = $options['linkalias'];
|
$linkAlias = $options['linkalias'];
|
||||||
else
|
else
|
||||||
$linkAlias = $Link->alias;
|
$linkAlias = $Link->alias;
|
||||||
|
|
||||||
// Get the foreign key fields (for the link table) directly from
|
$this->pr(17,
|
||||||
// the defined model associations, if they exists. This is the
|
array('checkpoint' => 'Linking HABTM',
|
||||||
// users direct specification, and therefore definitive if present.
|
compact('linkClass', 'linkAlias'),
|
||||||
$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
|
// Get the foreign key fields (for the link table) directly from
|
||||||
// model for the link table, and if it has the appropriate
|
// the defined model associations, if they exists. This is the
|
||||||
// associations with the two tables we're trying to join.
|
// users direct specification, and therefore definitive if present.
|
||||||
if (empty($modelLink) && isset($Link->belongsTo[$_Model->alias]))
|
$modelLink = $Link->escapeField($association['foreignKey'], $linkAlias);
|
||||||
$modelLink = $Link->escapeField($Link->belongsTo[$_Model->alias]['foreignKey'], $linkAlias);
|
$referenceLink = $Link->escapeField($association['associationForeignKey'], $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
|
// If we haven't figured out the foreign keys, see if there is a
|
||||||
// out the appropriate linkages. We'll have to SWAG it.
|
// model for the link table, and if it has the appropriate
|
||||||
if (empty($modelLink))
|
// associations with the two tables we're trying to join.
|
||||||
$modelLink = $Link->escapeField(Inflector::underscore($_Model->alias) . '_id', $linkAlias);
|
if (empty($modelLink) && isset($Link->belongsTo[$_Model->alias]))
|
||||||
if (empty($referenceLink))
|
$modelLink = $Link->escapeField($Link->belongsTo[$_Model->alias]['foreignKey'], $linkAlias);
|
||||||
$referenceLink = $Link->escapeField(Inflector::underscore($Reference->alias) . '_id', $linkAlias);
|
if (empty($referenceLink) && isset($Link->belongsTo[$Reference->alias]))
|
||||||
|
$referenceLink = $Link->escapeField($Link->belongsTo[$Reference->alias]['foreignKey'], $linkAlias);
|
||||||
|
|
||||||
// Get the primary key from the tables we're joining.
|
// We're running quite thin here. None of the models spell
|
||||||
$referenceKey = $Reference->escapeField(null, $referenceAlias);
|
// out the appropriate linkages. We'll have to SWAG it.
|
||||||
$modelKey = $_Model->escapeField(null, $modelAlias);
|
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);
|
||||||
|
|
||||||
// Join the linkage table to our model. We'll use an inner join,
|
// 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
|
// as the whole purpose of the linkage table is to make this
|
||||||
// connection. As we are embedding this join, the INNER will not
|
// connection. As we are embedding this join, the INNER will not
|
||||||
// cause any problem with the overall query, should the user not
|
// cause any problem with the overall query, should the user not
|
||||||
// be concerned with whether or not the join has any results.
|
// be concerned with whether or not the join has any results.
|
||||||
// They control that with the 'type' parameter which will be at
|
// They control that with the 'type' parameter which will be at
|
||||||
// the top level join.
|
// the top level join.
|
||||||
$options['joins'][] = array('type' => 'INNER',
|
$options['joins'][] = array('type' => 'INNER',
|
||||||
'alias' => $modelAlias,
|
'alias' => $modelAlias,
|
||||||
'conditions' => "{$modelKey} = {$modelLink}",
|
'conditions' => "{$modelKey} = {$modelLink}",
|
||||||
'table' => $db->fullTableName($_Model, true));
|
'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);
|
|
||||||
|
|
||||||
// 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 {
|
|
||||||
// No Foreign Key... nothing we can do.
|
|
||||||
$options['conditions'] = array();
|
|
||||||
}
|
|
||||||
|
|
||||||
// The user may have specified conditions directly in the model
|
|
||||||
// for this join. Make sure to adhere to those conditions.
|
|
||||||
if (isset($association['conditions']) && is_array($association['conditions']))
|
|
||||||
$options['conditions'] = array_merge($options['conditions'], $association['conditions']);
|
|
||||||
elseif (!empty($association['conditions']))
|
|
||||||
$options['conditions'][] = $association['conditions'];
|
|
||||||
|
|
||||||
|
// 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'],
|
||||||
|
'association[conditions]' => $association['conditions'],
|
||||||
|
),
|
||||||
|
));
|
||||||
|
|
||||||
|
// The user may have specified conditions directly in the model
|
||||||
|
// for this join. Make sure to adhere to those conditions.
|
||||||
|
if (isset($association['conditions']) && is_array($association['conditions']))
|
||||||
|
$options['conditions'] = array_merge($options['conditions'], $association['conditions']);
|
||||||
|
elseif (!empty($association['conditions']))
|
||||||
|
$options['conditions'][] = $association['conditions'];
|
||||||
|
|
||||||
|
$this->pr(19,
|
||||||
|
array('checkpoint' => 'Conditions2',
|
||||||
|
array('options[conditions]' => $options['conditions'],
|
||||||
|
),
|
||||||
|
));
|
||||||
|
|
||||||
if (empty($options['table'])) {
|
if (empty($options['table'])) {
|
||||||
$options['table'] = $db->fullTableName($_Model, true);
|
$options['table'] = $db->fullTableName($_Model, true);
|
||||||
}
|
}
|
||||||
@@ -312,26 +376,31 @@ class LinkableBehavior extends ModelBehavior {
|
|||||||
(empty($association['fields'])
|
(empty($association['fields'])
|
||||||
? array() : $db->fields($_Model, $modelAlias, $association['fields'])));
|
? array() : $db->fields($_Model, $modelAlias, $association['fields'])));
|
||||||
|
|
||||||
/* pr(array('checkpoint' => 'Model Work Complete', compact('options', 'modelClass', 'modelAlias'))); */
|
|
||||||
|
|
||||||
$options[$this->_key] = am($options[$this->_key], array_diff_key($options, $optionsKeys));
|
$options[$this->_key] = am($options[$this->_key], array_diff_key($options, $optionsKeys));
|
||||||
$options = array_intersect_key($options, $optionsKeys);
|
$options = array_intersect_key($options, $optionsKeys);
|
||||||
if (!empty($options[$this->_key])) {
|
if (!empty($options[$this->_key])) {
|
||||||
$iterators[] = $options[$this->_key] +
|
$iterators[] = $options[$this->_key] +
|
||||||
array('defaults' =>
|
array('defaults' =>
|
||||||
array_merge($defaults,
|
array_merge($defaults,
|
||||||
array('reference' =>
|
array('reference' =>
|
||||||
array('class' => $modelClass,
|
array('class' => $modelClass,
|
||||||
'alias' => $modelAlias))));
|
'alias' => $modelAlias))));
|
||||||
}
|
}
|
||||||
$query['joins'][] = array_intersect_key($options, array('type' => true, 'alias' => true, 'table' => true, 'joins' => true, 'conditions' => true));
|
$query['joins'][] = array_intersect_key($options, array('type' => true, 'alias' => true, 'table' => true, 'joins' => true, 'conditions' => true));
|
||||||
|
|
||||||
|
$this->pr(19,
|
||||||
|
array('checkpoint' => 'Model Join Complete',
|
||||||
|
compact('options', 'modelClass', 'modelAlias', 'query'),
|
||||||
|
));
|
||||||
}
|
}
|
||||||
++$cont;
|
++$cont;
|
||||||
$notDone = isset($iterators[$cont]);
|
$notDone = isset($iterators[$cont]);
|
||||||
} while ($notDone);
|
} while ($notDone);
|
||||||
}
|
}
|
||||||
/* pr(array('checkpoint' => 'Linkable::beforeFind() end', */
|
$this->pr(20,
|
||||||
/* compact('query'))); */
|
array('function' => 'Linkable::beforeFind',
|
||||||
|
'return' => compact('query'),
|
||||||
|
));
|
||||||
return $query;
|
return $query;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -8,7 +8,6 @@ class Customer extends AppModel {
|
|||||||
);
|
);
|
||||||
|
|
||||||
var $belongsTo = array(
|
var $belongsTo = array(
|
||||||
'Account',
|
|
||||||
'PrimaryContact' => array(
|
'PrimaryContact' => array(
|
||||||
'className' => 'Contact',
|
'className' => 'Contact',
|
||||||
),
|
),
|
||||||
@@ -20,11 +19,19 @@ class Customer extends AppModel {
|
|||||||
'conditions' => 'CurrentLease.close_date IS NULL',
|
'conditions' => 'CurrentLease.close_date IS NULL',
|
||||||
),
|
),
|
||||||
'Lease',
|
'Lease',
|
||||||
'Transaction',
|
'LedgerEntry',
|
||||||
|
|
||||||
|
// Cheat to get Account set as part of this class
|
||||||
|
'Account',
|
||||||
);
|
);
|
||||||
|
|
||||||
var $hasAndBelongsToMany = array(
|
var $hasAndBelongsToMany = array(
|
||||||
'Contact',
|
'Contact',
|
||||||
|
'Transaction' => array(
|
||||||
|
'joinTable' => 'ledger_entries',
|
||||||
|
'foreignKey' => 'customer_id',
|
||||||
|
'associationForeignKey' => 'transaction_id',
|
||||||
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
@@ -80,16 +87,9 @@ class Customer extends AppModel {
|
|||||||
/* )); */
|
/* )); */
|
||||||
|
|
||||||
$entries = $this->Account->findLedgerEntriesRelatedToAccount
|
$entries = $this->Account->findLedgerEntriesRelatedToAccount
|
||||||
($this->accountId($id),
|
($this->Account->invoiceAccountID(),
|
||||||
$this->Account->securityDepositAccountID(),
|
$this->Account->securityDepositAccountID(),
|
||||||
true, null, $link);
|
true, array('LedgerEntry.customer_id' => $id), $link);
|
||||||
|
|
||||||
foreach ($this->leaseIds($id) AS $lease_id) {
|
|
||||||
$ledger_entries = $this->Lease->findSecurityDeposits($lease_id, $link);
|
|
||||||
$this->statsMerge($entries['summary'], $ledger_entries['summary']);
|
|
||||||
$entries['Entries'] = array_merge($entries['Entries'],
|
|
||||||
$ledger_entries['Entries']);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* pr(array('function' => 'Customer::findSecurityDeposits', */
|
/* pr(array('function' => 'Customer::findSecurityDeposits', */
|
||||||
/* 'args' => compact('id', 'link'), */
|
/* 'args' => compact('id', 'link'), */
|
||||||
@@ -110,22 +110,10 @@ class Customer extends AppModel {
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
function findUnreconciledLedgerEntries($id = null, $fundamental_type = null) {
|
function findUnreconciledLedgerEntries($id = null, $fundamental_type = null) {
|
||||||
|
|
||||||
$unreconciled = $this->Account->findUnreconciledLedgerEntries
|
$unreconciled = $this->Account->findUnreconciledLedgerEntries
|
||||||
($this->accountId($id), $fundamental_type);
|
($this->Account->accountReceivableAccountID(),
|
||||||
|
$fundamental_type,
|
||||||
foreach ($this->leaseIds($id) AS $lease_id) {
|
array('LedgerEntry.customer_id' => $id));
|
||||||
$unrec = $this->Lease->findUnreconciledLedgerEntries($lease_id,
|
|
||||||
$fundamental_type);
|
|
||||||
|
|
||||||
foreach (array_keys($unreconciled) AS $type) {
|
|
||||||
$left = &$unreconciled[$type];
|
|
||||||
$right = &$unrec[$type];
|
|
||||||
|
|
||||||
$left['entry'] = array_merge($left['entry'], $right['entry']);
|
|
||||||
$left['balance'] += $right['balance'];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return $unreconciled;
|
return $unreconciled;
|
||||||
}
|
}
|
||||||
@@ -146,25 +134,11 @@ class Customer extends AppModel {
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
function reconcileNewLedgerEntry($id, $fundamental_type, $amount) {
|
function reconcileNewLedgerEntry($id, $fundamental_type, $amount) {
|
||||||
|
|
||||||
$reconciled = $this->Account->reconcileNewLedgerEntry
|
$reconciled = $this->Account->reconcileNewLedgerEntry
|
||||||
($this->accountId($id), $fundamental_type, $amount);
|
($this->Account->accountReceivableAccountID(),
|
||||||
|
$fundamental_type,
|
||||||
foreach ($this->leaseIds($id) AS $lease_id) {
|
$amount,
|
||||||
foreach (array_keys($reconciled) AS $type) {
|
array('LedgerEntry.customer_id' => $id));
|
||||||
$rec = $this->Lease->reconcileNewLedgerEntry($lease_id,
|
|
||||||
$fundamental_type,
|
|
||||||
$reconciled[$type]['unapplied']);
|
|
||||||
|
|
||||||
$left = &$reconciled[$type];
|
|
||||||
$right = &$rec[$type];
|
|
||||||
|
|
||||||
$left['entry'] = array_merge($left['entry'], $right['entry']);
|
|
||||||
$left['balance'] += $right['balance'];
|
|
||||||
$left['applied'] += $right['applied'];
|
|
||||||
$left['unapplied'] = $right['unapplied'];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return $reconciled;
|
return $reconciled;
|
||||||
}
|
}
|
||||||
@@ -189,7 +163,6 @@ class Customer extends AppModel {
|
|||||||
'ContactEmail',
|
'ContactEmail',
|
||||||
'ContactAddress',
|
'ContactAddress',
|
||||||
),
|
),
|
||||||
'Account',
|
|
||||||
'Lease' =>
|
'Lease' =>
|
||||||
array('Unit' =>
|
array('Unit' =>
|
||||||
array('order' => array('sort_order'),
|
array('order' => array('sort_order'),
|
||||||
@@ -201,22 +174,12 @@ class Customer extends AppModel {
|
|||||||
'conditions' => array('Customer.id' => $id),
|
'conditions' => array('Customer.id' => $id),
|
||||||
));
|
));
|
||||||
|
|
||||||
// Add the lease balance to each lease.
|
// Figure out the outstanding balance for this customer
|
||||||
foreach ($customer['Lease'] AS &$lease) {
|
|
||||||
$stats = $this->Lease->stats($lease['id']);
|
|
||||||
$lease['balance'] = $stats['Account']['Ledger']['balance'];
|
|
||||||
}
|
|
||||||
|
|
||||||
// Figure out the outstanding balance of the current lease.
|
|
||||||
$customer['stats'] = $this->stats($id);
|
$customer['stats'] = $this->stats($id);
|
||||||
|
|
||||||
// Figure out the total security deposit for the current lease.
|
// Figure out the total security deposit for the current lease.
|
||||||
$customer['deposits'] = $this->findSecurityDeposits($id);
|
$customer['deposits'] = $this->findSecurityDeposits($id);
|
||||||
|
|
||||||
// Add statistics into the customer account.
|
|
||||||
$customer['Account'] = array_merge($customer['Account'],
|
|
||||||
$customer['stats']['Account']['Ledger']);
|
|
||||||
|
|
||||||
return $customer;
|
return $customer;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -232,29 +195,11 @@ class Customer extends AppModel {
|
|||||||
if (!$id)
|
if (!$id)
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
// Get the basic information necessary
|
$stats = $this->Account->stats($this->Account->accountReceivableAccountID(), true,
|
||||||
$customer = $this->find('first',
|
array('LedgerEntry.customer_id' => $id));
|
||||||
array('contain' =>
|
|
||||||
array('Account' => array
|
|
||||||
('fields' => array('Account.id')),
|
|
||||||
|
|
||||||
'Lease' => array
|
|
||||||
('fields' => array('Lease.id'))
|
|
||||||
),
|
|
||||||
'conditions' => array
|
|
||||||
(array('Customer.id' => $id))));
|
|
||||||
|
|
||||||
// Get stats from the customer account, and each lease
|
|
||||||
$stats['Account'] = $this->Account->stats($customer['Account']['id']);
|
|
||||||
foreach ($customer['Lease'] AS $lease) {
|
|
||||||
$this->statsMerge($stats['Lease'], $this->Lease->stats($lease['id']));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Merge the stats from both the customer specific account, as
|
|
||||||
// well as the leases. This will provide current customer standing.
|
|
||||||
$this->statsMerge($stats, $stats['Account']['Ledger']);
|
|
||||||
$this->statsMerge($stats, $stats['Lease']['Account']['Ledger']);
|
|
||||||
|
|
||||||
|
// Pull to the top level and return
|
||||||
|
$stats = $stats['Ledger'];
|
||||||
return $stats;
|
return $stats;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -25,11 +25,18 @@ class Lease extends AppModel {
|
|||||||
var $belongsTo = array(
|
var $belongsTo = array(
|
||||||
'LeaseType',
|
'LeaseType',
|
||||||
'Unit',
|
'Unit',
|
||||||
'Account',
|
|
||||||
'Customer',
|
'Customer',
|
||||||
'LateSchedule',
|
'LateSchedule',
|
||||||
);
|
);
|
||||||
|
|
||||||
|
var $hasMany = array(
|
||||||
|
'LedgerEntry',
|
||||||
|
|
||||||
|
// Cheat to get Account set as part of this class
|
||||||
|
'Account',
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
/**************************************************************************
|
/**************************************************************************
|
||||||
**************************************************************************
|
**************************************************************************
|
||||||
**************************************************************************
|
**************************************************************************
|
||||||
@@ -37,15 +44,7 @@ class Lease extends AppModel {
|
|||||||
* - Returns the accountId of the given lease
|
* - Returns the accountId of the given lease
|
||||||
*/
|
*/
|
||||||
function accountId($id) {
|
function accountId($id) {
|
||||||
$this->cacheQueries = true;
|
return $this->Account->invoiceAccountID();
|
||||||
$lease = $this->find('first', array
|
|
||||||
('recursive' => -1,
|
|
||||||
'fields' => array('account_id'),
|
|
||||||
'conditions' => array(array('id' => $id)),
|
|
||||||
));
|
|
||||||
$this->cacheQueries = false;
|
|
||||||
|
|
||||||
return $lease['Lease']['account_id'];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -61,6 +60,10 @@ class Lease extends AppModel {
|
|||||||
/* 'args' => compact('id', 'all', 'cond', 'link'), */
|
/* 'args' => compact('id', 'all', 'cond', 'link'), */
|
||||||
/* )); */
|
/* )); */
|
||||||
|
|
||||||
|
if (!isset($cond))
|
||||||
|
$cond = array();
|
||||||
|
$cond[] = array('LedgerEntry.lease_id' => $id);
|
||||||
|
|
||||||
$entries = $this->Account->findLedgerEntries($this->accountId($id),
|
$entries = $this->Account->findLedgerEntries($this->accountId($id),
|
||||||
$all, $cond, $link);
|
$all, $cond, $link);
|
||||||
|
|
||||||
@@ -87,7 +90,7 @@ class Lease extends AppModel {
|
|||||||
$entries = $this->Account->findLedgerEntriesRelatedToAccount
|
$entries = $this->Account->findLedgerEntriesRelatedToAccount
|
||||||
($this->accountId($id),
|
($this->accountId($id),
|
||||||
$this->Account->securityDepositAccountID(),
|
$this->Account->securityDepositAccountID(),
|
||||||
true, null, $link);
|
true, array('LedgerEntry.lease_id' => $id), $link);
|
||||||
|
|
||||||
/* pr(array('function' => 'Lease::findSecurityDeposits', */
|
/* pr(array('function' => 'Lease::findSecurityDeposits', */
|
||||||
/* 'args' => compact('id', 'link'), */
|
/* 'args' => compact('id', 'link'), */
|
||||||
@@ -108,7 +111,7 @@ class Lease extends AppModel {
|
|||||||
|
|
||||||
function findUnreconciledLedgerEntries($id = null, $fundamental_type = null) {
|
function findUnreconciledLedgerEntries($id = null, $fundamental_type = null) {
|
||||||
return $this->Account->findUnreconciledLedgerEntries
|
return $this->Account->findUnreconciledLedgerEntries
|
||||||
($this->accountId($id), $fundamental_type);
|
($this->accountId($id), $fundamental_type, array('LedgerEntry.lease_id' => $id));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -128,7 +131,7 @@ class Lease extends AppModel {
|
|||||||
|
|
||||||
function reconcileNewLedgerEntry($id, $fundamental_type, $amount) {
|
function reconcileNewLedgerEntry($id, $fundamental_type, $amount) {
|
||||||
return $this->Account->reconcileNewLedgerEntry
|
return $this->Account->reconcileNewLedgerEntry
|
||||||
($this->accountId($id), $fundamental_type, $amount);
|
($this->accountId($id), $fundamental_type, $amount, array('LedgerEntry.lease_id' => $id));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -143,18 +146,15 @@ class Lease extends AppModel {
|
|||||||
if (!$id)
|
if (!$id)
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
// Find the associated account.
|
$stats = $this->Account->stats($this->Account->accountReceivableAccountID(), true,
|
||||||
$lease = $this->find('first',
|
array('OR' => array
|
||||||
array('recursive' => -1,
|
(array('LedgerEntry.lease_id' => $id),
|
||||||
'conditions' => array(array('Lease.id' => $id))));
|
array('ReconciledLedgerEntry.lease_id' => $id),
|
||||||
|
),
|
||||||
// Pull the stats from the account.
|
));
|
||||||
$stats['Account'] = $this->Account->stats($lease['Lease']['account_id']);
|
|
||||||
|
|
||||||
// Place a summary of the stats (one lease account in this case)
|
|
||||||
// at the top level for easy summarized access.
|
|
||||||
$this->statsMerge($stats, $stats['Account']['Ledger']);
|
|
||||||
|
|
||||||
|
// Pull to the top level and return
|
||||||
|
$stats = $stats['Ledger'];
|
||||||
return $stats;
|
return $stats;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -115,6 +115,9 @@ class Ledger extends AppModel {
|
|||||||
* - Returns summary data from the requested ledger.
|
* - Returns summary data from the requested ledger.
|
||||||
*/
|
*/
|
||||||
function stats($id, $cond = null) {
|
function stats($id, $cond = null) {
|
||||||
|
if (!isset($cond))
|
||||||
|
$cond = array();
|
||||||
|
$cond[] = array('Ledger.id' => $id);
|
||||||
|
|
||||||
$stats = $this->find
|
$stats = $this->find
|
||||||
('first', array
|
('first', array
|
||||||
@@ -138,8 +141,7 @@ class Ledger extends AppModel {
|
|||||||
) * IF(LedgerEntry.amount, LedgerEntry.amount, 0)
|
) * IF(LedgerEntry.amount, LedgerEntry.amount, 0)
|
||||||
) AS balance",
|
) AS balance",
|
||||||
"COUNT(LedgerEntry.id) AS entries"),
|
"COUNT(LedgerEntry.id) AS entries"),
|
||||||
'conditions' => array(isset($cond) ? $cond : array(),
|
'conditions' => $cond,
|
||||||
array('Ledger.id' => $id)),
|
|
||||||
'group' => 'Ledger.id',
|
'group' => 'Ledger.id',
|
||||||
));
|
));
|
||||||
|
|
||||||
@@ -11,6 +11,8 @@ class LedgerEntry extends AppModel {
|
|||||||
var $belongsTo = array(
|
var $belongsTo = array(
|
||||||
'MonetarySource',
|
'MonetarySource',
|
||||||
'Transaction',
|
'Transaction',
|
||||||
|
'Customer',
|
||||||
|
'Lease',
|
||||||
|
|
||||||
'DebitLedger' => array(
|
'DebitLedger' => array(
|
||||||
'className' => 'Ledger',
|
'className' => 'Ledger',
|
||||||
@@ -23,17 +25,11 @@ class LedgerEntry extends AppModel {
|
|||||||
);
|
);
|
||||||
|
|
||||||
var $hasAndBelongsToMany = array(
|
var $hasAndBelongsToMany = array(
|
||||||
'DebitReconciliationLedgerEntry' => array(
|
'ReconcilingTransaction' => array(
|
||||||
'className' => 'LedgerEntry',
|
'className' => 'Transaction',
|
||||||
'joinTable' => 'reconciliations',
|
'joinTable' => 'reconciliations',
|
||||||
'foreignKey' => 'credit_ledger_entry_id',
|
'foreignKey' => 'transaction_id',
|
||||||
'associationForeignKey' => 'debit_ledger_entry_id',
|
'associationForeignKey' => 'ledger_entry_id',
|
||||||
),
|
|
||||||
'CreditReconciliationLedgerEntry' => array(
|
|
||||||
'className' => 'LedgerEntry',
|
|
||||||
'joinTable' => 'reconciliations',
|
|
||||||
'foreignKey' => 'debit_ledger_entry_id',
|
|
||||||
'associationForeignKey' => 'credit_ledger_entry_id',
|
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -84,7 +80,7 @@ class LedgerEntry extends AppModel {
|
|||||||
return $fields;
|
return $fields;
|
||||||
}
|
}
|
||||||
|
|
||||||
function ledgerContextFields2($ledger_id = null, $account_type = null) {
|
function ledgerContextFields2($ledger_id = null, $account_id = null, $account_type = null) {
|
||||||
$fields = array('id', 'name', 'comment', 'amount');
|
$fields = array('id', 'name', 'comment', 'amount');
|
||||||
|
|
||||||
if (isset($ledger_id)) {
|
if (isset($ledger_id)) {
|
||||||
@@ -93,20 +89,29 @@ class LedgerEntry extends AppModel {
|
|||||||
$fields[] = ("IF(LedgerEntry.credit_ledger_id = $ledger_id," .
|
$fields[] = ("IF(LedgerEntry.credit_ledger_id = $ledger_id," .
|
||||||
" SUM(LedgerEntry.amount), NULL) AS credit");
|
" SUM(LedgerEntry.amount), NULL) AS credit");
|
||||||
|
|
||||||
if (isset($account_type)) {
|
if (isset($account_id) || isset($account_type)) {
|
||||||
if (in_array($account_type, array('ASSET', 'EXPENSE')))
|
$Account = new Account();
|
||||||
$ledger_type = 'debit';
|
$account_ftype = $Account->fundamentalType($account_id ? $account_id : $account_type);
|
||||||
else
|
$fields[] = ("(IF(LedgerEntry.{$account_ftype}_ledger_id = $ledger_id," .
|
||||||
$ledger_type = 'credit';
|
|
||||||
|
|
||||||
$fields[] = ("(IF(LedgerEntry.{$ledger_type}_ledger_id = $ledger_id," .
|
|
||||||
" 1, -1) * SUM(LedgerEntry.amount)) AS balance");
|
" 1, -1) * SUM(LedgerEntry.amount)) AS balance");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
elseif (isset($account_id)) {
|
||||||
|
$fields[] = ("IF(DebitLedger.account_id = $account_id," .
|
||||||
|
" SUM(LedgerEntry.amount), NULL) AS debit");
|
||||||
|
$fields[] = ("IF(CreditLedger.account_id = $account_id," .
|
||||||
|
" SUM(LedgerEntry.amount), NULL) AS credit");
|
||||||
|
|
||||||
|
$Account = new Account();
|
||||||
|
$account_ftype = ucfirst($Account->fundamentalType($account_id));
|
||||||
|
$fields[] = ("(IF({$account_ftype}Ledger.account_id = $account_id," .
|
||||||
|
" 1, -1) * SUM(LedgerEntry.amount)) AS balance");
|
||||||
|
}
|
||||||
|
|
||||||
return $fields;
|
return $fields;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
function ledgerContextConditions($ledger_id, $account_type) {
|
function ledgerContextConditions($ledger_id, $account_type) {
|
||||||
if (isset($ledger_id)) {
|
if (isset($ledger_id)) {
|
||||||
return array
|
return array
|
||||||
@@ -156,36 +161,36 @@ class LedgerEntry extends AppModel {
|
|||||||
/**************************************************************************
|
/**************************************************************************
|
||||||
**************************************************************************
|
**************************************************************************
|
||||||
**************************************************************************
|
**************************************************************************
|
||||||
* function: findReconciledLedgerEntries
|
* function: findReconcilingTransactions
|
||||||
* - Returns ledger entries that are reconciled to the given entry.
|
* - Returns transactions that reconcile the given entry
|
||||||
* (such as payments towards a charge).
|
* (such as receipts that reconcile a charge).
|
||||||
*/
|
*/
|
||||||
|
|
||||||
function findReconciledLedgerEntries($id = null, $fundamental_type = null) {
|
function findReconcilingTransactions($id = null, $fundamental_type = null) {
|
||||||
foreach (($fundamental_type
|
foreach (($fundamental_type
|
||||||
? array($fundamental_type)
|
? array($fundamental_type)
|
||||||
: array('debit', 'credit')) AS $fund) {
|
: array('debit', 'credit')) AS $fund) {
|
||||||
$ucfund = ucfirst($fund);
|
$reconciled[$fund]['LedgerEntry'] = $this->find
|
||||||
$reconciled[$fund]['entry'] = $this->find
|
|
||||||
('all', array
|
('all', array
|
||||||
('link' => array
|
('link' => array
|
||||||
("ReconciliationLedgerEntry" => array
|
('ReconcilingTransaction' => array
|
||||||
('class' => "{$ucfund}ReconciliationLedgerEntry",
|
('fields' => array
|
||||||
'fields' => array
|
|
||||||
('id',
|
('id',
|
||||||
"COALESCE(SUM(Reconciliation.amount),0) AS 'reconciled'",
|
"COALESCE(SUM(Reconciliation.amount),0) AS 'reconciled'",
|
||||||
"LedgerEntry.amount - COALESCE(SUM(Reconciliation.amount),0) AS 'balance'",
|
//"ReconcilingTransaction.amount - COALESCE(SUM(Reconciliation.amount),0) AS 'balance'",
|
||||||
|
"COALESCE(7) AS 'balance'",
|
||||||
),
|
),
|
||||||
|
'conditions' => array('Reconciliation.type' => $fund),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
'group' => ("ReconciliationLedgerEntry.id"),
|
'group' => ('ReconcilingTransaction.id'),
|
||||||
'conditions' => array('LedgerEntry.id' => $id),
|
'conditions' => array('LedgerEntry.id' => $id),
|
||||||
'fields' => array(),
|
'fields' => array(),
|
||||||
));
|
));
|
||||||
//pr($reconciled);
|
//pr($reconciled);
|
||||||
$balance = 0;
|
$balance = 0;
|
||||||
foreach ($reconciled[$fund]['entry'] AS &$entry) {
|
foreach ($reconciled[$fund]['LedgerEntry'] AS &$entry) {
|
||||||
$entry = array_merge($entry["ReconciliationLedgerEntry"], $entry[0]);
|
$entry = array_merge($entry["ReconcilingTransaction"], $entry[0]);
|
||||||
$balance += $entry['balance'];
|
$balance += $entry['balance'];
|
||||||
}
|
}
|
||||||
$reconciled[$fund]['balance'] = $balance;
|
$reconciled[$fund]['balance'] = $balance;
|
||||||
@@ -201,27 +206,31 @@ class LedgerEntry extends AppModel {
|
|||||||
* function: stats
|
* function: stats
|
||||||
* - Returns summary data from the requested ledger entry
|
* - Returns summary data from the requested ledger entry
|
||||||
*/
|
*/
|
||||||
function stats($id) {
|
function stats($id, $cond = null) {
|
||||||
|
|
||||||
|
if (!isset($cond))
|
||||||
|
$cond = array();
|
||||||
|
|
||||||
|
$cond[] = array('LedgerEntry.id' => $id);
|
||||||
|
|
||||||
$query = array
|
$query = array
|
||||||
(
|
(
|
||||||
|
'link' => array('ReconcilingTransaction'),
|
||||||
'fields' => array("SUM(Reconciliation.amount) AS 'reconciled'"),
|
'fields' => array("SUM(Reconciliation.amount) AS 'reconciled'"),
|
||||||
|
|
||||||
'conditions' => array(isset($cond) ? $cond : array(),
|
|
||||||
array('LedgerEntry.id' => $id)),
|
|
||||||
|
|
||||||
'group' => 'LedgerEntry.id',
|
'group' => 'LedgerEntry.id',
|
||||||
);
|
);
|
||||||
|
|
||||||
// Get the applied amounts on the debit side
|
// Get the applied amounts on the debit side
|
||||||
$query['link'] =
|
$qcond = $cond;
|
||||||
array('DebitReconciliationLedgerEntry' => array('alias' => 'DRLE', 'DRLETransaction' => array('class' => 'Transaction')));
|
$qcond[] = array('Reconciliation.type' => 'DEBIT');
|
||||||
|
$query['conditions'] = $qcond;
|
||||||
$tmpstats = $this->find('first', $query);
|
$tmpstats = $this->find('first', $query);
|
||||||
$stats['debit_amount_reconciled'] = $tmpstats[0]['reconciled'];
|
$stats['debit_amount_reconciled'] = $tmpstats[0]['reconciled'];
|
||||||
|
|
||||||
// Get the applied amounts on the credit side
|
// Get the applied amounts on the credit side
|
||||||
$query['link'] =
|
$qcond = $cond;
|
||||||
array('CreditReconciliationLedgerEntry' => array('alias' => 'CRLE', 'CRLETransaction' => array('class' => 'Transaction')));
|
$qcond[] = array('Reconciliation.type' => 'CREDIT');
|
||||||
|
$query['conditions'] = $qcond;
|
||||||
$tmpstats = $this->find('first', $query);
|
$tmpstats = $this->find('first', $query);
|
||||||
$stats['credit_amount_reconciled'] = $tmpstats[0]['reconciled'];
|
$stats['credit_amount_reconciled'] = $tmpstats[0]['reconciled'];
|
||||||
|
|
||||||
@@ -0,0 +1,71 @@
|
|||||||
|
<?php
|
||||||
|
class Transaction extends AppModel {
|
||||||
|
|
||||||
|
var $name = 'Transaction';
|
||||||
|
/* var $validate = array( */
|
||||||
|
/* 'stamp' => array('date') */
|
||||||
|
/* ); */
|
||||||
|
|
||||||
|
var $belongsTo = array(
|
||||||
|
'Customer',
|
||||||
|
);
|
||||||
|
|
||||||
|
var $hasMany = array(
|
||||||
|
'LedgerEntry',
|
||||||
|
);
|
||||||
|
|
||||||
|
var $hasAndBelongsToMany = array(
|
||||||
|
'ReconciledLedgerEntry' => array(
|
||||||
|
'className' => 'LedgerEntry',
|
||||||
|
'joinTable' => 'reconciliations',
|
||||||
|
'foreignKey' => 'ledger_entry_id',
|
||||||
|
'associationForeignKey' => 'transaction_id',
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
function beforeSave() {
|
||||||
|
|
||||||
|
if(!empty($this->data['Transaction']['stamp'])) {
|
||||||
|
$this->data['Transaction']['stamp'] =
|
||||||
|
$this->dateFormatBeforeSave($this->data['Transaction']['stamp']);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
**************************************************************************
|
||||||
|
* function: findReconciledLedgerEntries
|
||||||
|
* - Returns ledger entries that are reconciled by the given
|
||||||
|
* transaction (such as charges reconciled by a receipt)
|
||||||
|
*/
|
||||||
|
|
||||||
|
function findReconciledLedgerEntries($id = null) {
|
||||||
|
$reconciled['LedgerEntry'] = $this->find
|
||||||
|
('all', array
|
||||||
|
('link' => array
|
||||||
|
('ReconciledLedgerEntry' => array
|
||||||
|
('fields' => array
|
||||||
|
('id',
|
||||||
|
"COALESCE(SUM(Reconciliation.amount),0) AS 'reconciled'",
|
||||||
|
"ReconciledLedgerEntry.amount - COALESCE(SUM(Reconciliation.amount),0) AS 'balance'",
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
'group' => ('ReconciledLedgerEntry.id'),
|
||||||
|
'conditions' => array('Transaction.id' => $id),
|
||||||
|
'fields' => array(),
|
||||||
|
));
|
||||||
|
//pr($reconciled);
|
||||||
|
$balance = 0;
|
||||||
|
foreach ($reconciled['LedgerEntry'] AS &$entry) {
|
||||||
|
$entry = array_merge($entry["ReconciledLedgerEntry"], $entry[0]);
|
||||||
|
$balance += $entry['balance'];
|
||||||
|
}
|
||||||
|
$reconciled['balance'] = $balance;
|
||||||
|
|
||||||
|
return $reconciled;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
?>
|
||||||
Vendored
|
Before Width: | Height: | Size: 1.0 KiB After Width: | Height: | Size: 1.0 KiB |
Vendored
@@ -63,12 +63,14 @@ echo $this->element('leases',
|
|||||||
|
|
||||||
|
|
||||||
/**********************************************************************
|
/**********************************************************************
|
||||||
* Account
|
* Customer Account History
|
||||||
*/
|
*/
|
||||||
|
|
||||||
echo $this->element('accounts',
|
echo $this->element('ledger_entries',
|
||||||
array('caption' => 'Account',
|
array('caption' => 'Account',
|
||||||
'accounts' => array($customer['Account'])));
|
'customer_id' => $customer['Customer']['id'],
|
||||||
|
'ar_account' => true,
|
||||||
|
));
|
||||||
|
|
||||||
|
|
||||||
/* End "detail supporting" div */
|
/* End "detail supporting" div */
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user