diff --git a/app_controller.php b/app_controller.php index aa2effa..d888160 100644 --- a/app_controller.php +++ b/app_controller.php @@ -508,7 +508,9 @@ class AppController extends Controller { } function gridDataFields(&$params, &$model) { - return null; + $db = &$model->getDataSource(); + $fields = $db->fields($model, $model->alias); + return $fields; } function gridDataGroup(&$params, &$model) { diff --git a/controllers/accounts_controller.php b/controllers/accounts_controller.php index 41fd841..ead4b84 100644 --- a/controllers/accounts_controller.php +++ b/controllers/accounts_controller.php @@ -75,8 +75,9 @@ class AccountsController extends AppController { } function gridDataFields(&$params, &$model) { - return array_merge(array('Account.*'), - $this->Account->Ledger->LedgerEntry->debitCreditFields(true, 'LedgerEntry', 'CurrentLedger')); + $fields = parent::gridDataFields($params, $model); + return array_merge($fields, + $this->Account->Ledger->LedgerEntry->debitCreditFields(true)); } function gridDataConditions(&$params, &$model) { @@ -234,7 +235,7 @@ class AccountsController extends AppController { array('contain' => array(// Models 'CurrentLedger' => - array('fields' => array('id', 'sequence')), + array('fields' => array('id', 'sequence', 'name')), 'Ledger' => array('Close' => array @@ -249,11 +250,6 @@ class AccountsController extends AppController { //pr(compact('entries')); $account['CurrentLedger']['LedgerEntry'] = $entries; - // Summarize each ledger - foreach($account['Ledger'] AS &$ledger) - $ledger = array_merge($ledger, - $this->Account->Ledger->stats($ledger['id'])); - // Obtain stats across ALL ledgers for the summary infobox $stats = $this->Account->stats($id, true); $stats = $stats['Ledger']; diff --git a/controllers/customers_controller.php b/controllers/customers_controller.php index 0a7844c..4b79b60 100644 --- a/controllers/customers_controller.php +++ b/controllers/customers_controller.php @@ -45,10 +45,6 @@ class CustomersController extends AppController { * to jqGrid. */ - function gridDataSetup(&$params) { - parent::gridDataSetup($params); - } - function gridDataCountTables(&$params, &$model) { return array ('link' => @@ -61,17 +57,16 @@ class CustomersController extends AppController { 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) { - $db = &$model->getDataSource(); - $fields = $db->fields($model, $model->alias); + $fields = parent::gridDataFields($params, $model); $fields[] = ('COUNT(DISTINCT CurrentLease.id) AS lease_count'); - $fields = array_merge($fields, - $this->Customer->StatementEntry->chargePaymentFields(true)); - return $fields; + return array_merge($fields, + $this->Customer->StatementEntry->chargePaymentFields(true)); } function gridDataConditions(&$params, &$model) { @@ -104,37 +99,28 @@ class CustomersController extends AppController { return $order; } - function gridDataCount(&$params, &$model, $query) { + function gridDataCount(&$params, &$model) { + if ($params['action'] != 'current') + return parent::gridDataCount($params, $model); + + // OK, for current customers, we have an issue. // We don't have a good way to use the query to obtain // our count. The problem is that we're relying on the - // group by for the query, which will destroy the count, - // whether we omit the group by or leave it in. - // So, build a fresh query for counting. + // group by for the query, but that simply won't work + // for the count. However, it's not difficult to simply + // derive it since 'current' customers are mutually + // exclusive to 'past' customers. - $query['conditions'] = parent::gridDataConditions($params, $model); + $tmp_params = $params; + $tmp_params['action'] = 'all'; + $all_count = parent::gridDataCount($tmp_params, $model); + $tmp_params['action'] = 'past'; + $past_count = parent::gridDataCount($tmp_params, $model); - $count = $model->find('count', - array_merge(array('link' => array_diff_key($query['link'], - array('CurrentLease'=>1))), - array_diff_key($query, array('link'=>1)))); - - if ($params['action'] == 'all') - return $count; - - $query['conditions'][] = 'CurrentLease.id IS NULL'; - $count_past = $model->find('count', $query); - - // Since we can't easily count 'current' directly, we - // can quickly derive it since 'current' customers - // are mutually exclusive to 'past' customers. - if ($params['action'] == 'current') - $count = $count - $count_past; - elseif ($params['action'] == 'past') { - $count = $count_past; - } - - return $count; + // The current customer count is simply calculated + // as all customers that are not past customers. + return $all_count - $past_count; } function gridDataPostProcessLinks(&$params, &$model, &$records, $links) { diff --git a/controllers/leases_controller.php b/controllers/leases_controller.php index a8b9bd1..3887977 100644 --- a/controllers/leases_controller.php +++ b/controllers/leases_controller.php @@ -51,8 +51,8 @@ class LeasesController extends AppController { function gridDataCountTables(&$params, &$model) { return array - ('link' => array('Unit' => array('fields' => array('Unit.id', 'Unit.name')), - 'Customer' => array('fields' => array('Customer.id', 'Customer.name')))); + ('link' => array('Unit' => array('fields' => array('id', 'name')), + 'Customer' => array('fields' => array('id', 'name')))); } function gridDataTables(&$params, &$model) { @@ -62,11 +62,9 @@ class LeasesController extends AppController { } function gridDataFields(&$params, &$model) { - $db = &$model->getDataSource(); - $fields = $db->fields($model, $model->alias); - $fields = array_merge($fields, - $this->Lease->StatementEntry->chargePaymentFields(true)); - return $fields; + $fields = parent::gridDataFields($params, $model); + return array_merge($fields, + $this->Lease->StatementEntry->chargePaymentFields(true)); } function gridDataConditions(&$params, &$model) { @@ -79,8 +77,8 @@ class LeasesController extends AppController { $conditions[] = 'Lease.close_date IS NOT NULL'; } - if (isset($params['custom']['customer_id'])) - $conditions[] = array('Lease.customer_id' => $params['custom']['customer_id']); + if (isset($customer_id)) + $conditions[] = array('Lease.customer_id' => $customer_id); return $conditions; } diff --git a/controllers/ledger_entries_controller.php b/controllers/ledger_entries_controller.php index cdd1d22..a6b7418 100644 --- a/controllers/ledger_entries_controller.php +++ b/controllers/ledger_entries_controller.php @@ -25,221 +25,35 @@ class LedgerEntriesController extends AppController { * to jqGrid. */ - function gridDataSetup(&$params) { - parent::gridDataSetup($params); - if (isset($params['custom']['collected_account_id'])) - $params['custom']['account_id'] = $params['custom']['collected_account_id']; - } - function gridDataTables(&$params, &$model) { $link = array(// Models - 'Account' => - array('fields' => array('id', 'name', 'type'), - ), + 'Transaction' => + array('fields' => array('id', 'stamp'), + ), - 'Ledger' => - array('fields' => array('id', 'sequence'), - ), + 'Ledger' => + array('fields' => array('id', 'sequence'), + 'Account' => + array('fields' => array('id', 'name', 'type'), + ), + ), - 'DoubleEntry' => array - ('Transaction' => - array('fields' => array('id', 'stamp'), - ), + 'Tender' => + array('fields' => array('id', 'name'), + ), - 'DebitLedger' => - array('fields' => array('id'), - 'Account' => array('alias' => 'DebitAccount', - 'fields' => array('id', 'name'), - ), - ), - - 'CreditLedger' => - array('fields' => array('id'), - 'Account' => array('alias' => 'CreditAccount', - 'fields' => array('id', 'name'), - ), - ), - - 'Customer' => - array('fields' => array('id', 'name'), - ), - - 'Lease' => - array('fields' => array('id', 'number'), - 'Unit' => - array('fields' => array('id', 'name'), - ), - ), - ), +/* 'DebitEntry', */ +/* 'CreditEntry', */ ); - if (count(array_intersect($params['fields'], array('applied'))) == 1) { - $link['Payment'] = array('DoubleEntry' => - array('alias' => 'PaymentDoubleEntry', - 'Receipt'), - 'Account' => array('alias' => 'PaymentAccount'), - ); - $link['Charge'] = array('DoubleEntry' => - array('alias' => 'ChargeDoubleEntry', - 'Invoice'), - 'Account' => array('alias' => 'ChargeAccount'), - ); - } - elseif (isset($params['custom']['customer_id']) || isset($params['custom']['lease_id'])) { - $link['Charge'] = array('DoubleEntry' => - array('alias' => 'ChargeDoubleEntry', - 'Invoice'), - 'Account' => array('alias' => 'ChargeAccount'), - ); - } - return array('link' => $link); } function gridDataFields(&$params, &$model) { $fields = parent::gridDataFields($params, $model); - - if (!isset($fields)) - $fields = array('Entry.*'); - -/* if (isset($params['custom']['reconcile_id'])) { */ -/* $fields[] = array("IF(Entry.type = 'CHARGE',", */ -/* " COALESCE(AppliedCharge.amount,0),", */ -/* " COALESCE(AppliedPayment.amount,0))", */ -/* " AS 'applied'"); */ -/* $fields[] = array("Entry.amount - (", */ -/* "IF(Entry.type = 'CHARGE',", */ -/* " COALESCE(AppliedCharge.amount,0),", */ -/* " COALESCE(AppliedPayment.amount,0))", */ -/* ") AS 'balance'"); */ -/* } */ - - if (isset($params['custom']['customer_id']) || isset($params['custom']['lease_id'])) { - $fields[] = "IF(Entry.type = 'CHARGE', DoubleEntry.amount, NULL) AS debit"; - $fields[] = "IF(Entry.type = 'PAYMENT', DoubleEntry.amount, NULL) AS credit"; - $fields[] = "IF(Entry.type = 'CHARGE', 1, -1) * DoubleEntry.amount AS balance"; - } - else { - if (count(array_intersect($params['fields'], array('applied'))) == 1) - $fields[] = ('SUM(COALESCE(AppliedPayment.amount,0)' . - ' + COALESCE(AppliedCharge.amount,0)) AS applied'); - - if (count(array_intersect($params['fields'], array('debit', 'credit'))) >= 1) { - $fields = array_merge($fields, - $this->Entry->DoubleEntry->debitCreditFields()); - /* $fields = array_merge($fields, */ - /* $this->Entry->Account->debitCreditFields()); */ - /* $fields[] = "IF(Entry.crdr = 'CREDIT', DoubleEntry.amount, NULL) AS credit"; */ - /* $fields[] = "IF(Entry.crdr = 'DEBIT', DoubleEntry.amount, NULL) AS debit"; */ - /* $fields[] = "IF(Account.type IN Entry.crdr = 'DEBIT', DoubleEntry.amount, NULL) AS debit"; */ - } - } - - if ($params['action'] === 'collected') - $fields[] = 'MAX(Receipt.stamp) AS last_paid'; - - return $fields; - } - - function gridDataConditions(&$params, &$model) { - $conditions = parent::gridDataConditions($params, $model); - - if ($params['action'] === 'collected') { - extract($params['custom']); - - if (!isset($params['custom']['account_id'])) - die("INTERNAL ERROR: ACCOUNT ID NOT SET"); - - if (!empty($collected_from_date)) - $conditions[] - = array('Receipt.stamp >=' => - $this->Entry->Transaction->dateFormatBeforeSave($collected_from_date)); - - if (!empty($collected_through_date)) - $conditions[] - = array('Receipt.stamp <=' => - $this->Entry->Transaction->dateFormatBeforeSave($collected_through_date . ' 23:59:59')); - - if (isset($collected_payment_accounts)) - $conditions[] = array('PaymentAccount.id' => $collected_payment_accounts); - else - $conditions[] = array('NOT' => array(array('PaymentAccount.id' => null))); - } - - if (isset($params['custom']['ledger_id'])) { - $ledger_id = $params['custom']['ledger_id']; - $conditions[] = array('Ledger.id' => $ledger_id); - } - - if (isset($params['custom']['reconcile_id'])) { - $conditions[] = array('OR' => - array('AppliedCharge.id' => $reconcile_id), - array('AppliedPayment.id' => $reconcile_id)); - } - - if (isset($params['custom']['account_id'])) { - $account_id = $params['custom']['account_id']; - $conditions[] = array('Account.id' => $account_id); - } - - if (isset($params['custom']['customer_id'])) { - $customer_id = $params['custom']['customer_id']; - $conditions[] = - array('OR' => - array(array(array('Entry.type' => 'CHARGE'), - array('DoubleEntry.customer_id' => $customer_id)), - array(array('Entry.type' => 'PAYMENT'), - array('ChargeDoubleEntry.customer_id' => $customer_id)), - ), - ); - } - - if (isset($params['custom']['lease_id'])) { - $lease_id = $params['custom']['lease_id']; - $conditions[] = - array('OR' => - array(array(array('Entry.type' => 'CHARGE'), - array('DoubleEntry.lease_id' => $lease_id)), - array(array('Entry.type' => 'PAYMENT'), - array('ChargeDoubleEntry.lease_id' => $lease_id)), - ), - ); -/* array('OR' => */ -/* array('AND' => */ -/* array(array('Entry.type' => 'CHARGE'), */ -/* array('DoubleEntry.lease_id' => $lease_id)) */ -/* ), */ -/* array('AND' => */ -/* array(array('Entry.type' => 'PAYMENT'), */ -/* array('ChargeDoubleEntry.lease_id' => $lease_id)), */ -/* ), */ -/* ); */ - } - - if (isset($params['custom']['transaction_id'])) { - $conditions[] = - array('Transaction.id' => $params['custom']['transaction_id']); - } - - return $conditions; - } - - function gridDataPostProcessLinks(&$params, &$model, &$records, $links) { - $links['Transaction'] = array('id'); - $links['Entry'] = array('id'); - $links['Account'] = array('controller' => 'accounts', 'name'); - $links['DebitAccount'] = array('controller' => 'accounts', 'name'); - $links['CreditAccount'] = array('controller' => 'accounts', 'name'); - $links['MonetarySource'] = array('name'); - $links['Customer'] = array('name'); - $links['Lease'] = array('number'); - $links['Unit'] = array('name'); - return parent::gridDataPostProcessLinks($params, $model, $records, $links); - } - - function gridDataGroup(&$params, &$model) { - return parent::gridDataGroup($params, $model); + return array_merge($fields, + $this->LedgerEntry->debitCreditFields()); } function gridDataOrder(&$params, &$model, $index, $direction) { @@ -248,46 +62,19 @@ class LedgerEntriesController extends AppController { $order = parent::gridDataOrder($params, $model, $index, $direction); if ($index === 'Transaction.stamp') { - $order[] = 'Entry.id ' . $direction; + $order[] = 'LedgerEntry.id ' . $direction; } return $order; } - function gridDataRecords(&$params, &$model, $query) { - if ($params['action'] === 'collected') { - $tquery = array_diff_key($query, array(/*'fields'=>1,*/'group'=>1,'limit'=>1,'order'=>1)); - $tquery['group'] = array('AppliedPayment.id'); - $tquery['fields'] = array("IF(Entry.type = 'CHARGE',", - " SUM(COALESCE(AppliedCharge.amount,0)),", - " SUM(COALESCE(AppliedPayment.amount,0)))", - " AS 'applied'", - - "Charge.amount - (", - "IF(Entry.type = 'CHARGE',", - " SUM(COALESCE(AppliedCharge.amount,0)),", - " SUM(COALESCE(AppliedPayment.amount,0)))", - ") AS 'balance'", - ); - - $total = $model->find('first', $tquery); - $params['userdata']['total'] = $total[0]['applied']; - $params['userdata']['balance'] = $total[0]['balance']; - } - - return parent::gridDataRecords($params, $model, $query); - } - - - /************************************************************************** - ************************************************************************** - ************************************************************************** - * action: reverse the ledger entry - */ - - function reverse($id) { - $this->Entry->reverse($id); - $this->redirect(array('action'=>'view', $id)); + 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); } @@ -305,96 +92,49 @@ class LedgerEntriesController extends AppController { } // Get the Entry and related fields - $entry = $this->Entry->find + $entry = $this->LedgerEntry->find ('first', array('contain' => array - ('Account' => array('id', 'name', 'type', 'trackable'), - 'DoubleEntry' => array - (//'fields' => array('id'), - 'DebitEntry' => array('fields' => array('id', 'crdr')), - 'CreditEntry' => array('fields' => array('id', 'crdr')), - 'Transaction' => array('fields' => array('id', 'stamp')), - 'Customer' => array('fields' => array('id', 'name')), - 'Lease' => array('fields' => array('id')), - ), + ( + 'Transaction' => + array('fields' => array('id', 'stamp'), + ), + + 'Ledger' => + array('fields' => array('id', 'sequence', 'name'), + 'Account' => + array('fields' => array('id', 'name', 'type', 'trackable'), + ), + ), + + 'Tender' => + array('fields' => array('id', 'name'), + ), + + 'DebitEntry' => array('fields' => array('id', 'crdr')), + 'CreditEntry' => array('fields' => array('id', 'crdr')), ), - 'conditions' => array('Entry.id' => $id), + 'conditions' => array('LedgerEntry.id' => $id), )); - - $entry['Entry']['opposite_crdr'] = - ucfirst($this->Entry->Account->fundamentalOpposite($entry['Entry']['crdr'])); - $entry['Entry']['matching_entry_id'] = - $entry['DoubleEntry'][ - ucfirst(strtolower($entry['Entry']['opposite_crdr'])) . - 'Entry']['id']; -/* if ($entry['DoubleEntry']['DebitEntry']['id'] == $entry['Entry']['id']) */ -/* $entry['Entry']['matching_entry_id'] = $entry['DoubleEntry']['CreditEntry']['id']; */ -/* if ($entry['DoubleEntry']['CreditEntry']['id'] == $entry['Entry']['id']) */ -/* $entry['Entry']['matching_entry_id'] = $entry['DoubleEntry']['DebitEntry']['id']; */ - //pr(compact('entry')); - $reconciled = $this->Entry->reconciledEntries($id); - //pr(compact('reconciled')); + 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"); - -/* // REVISIT : 20090711 */ -/* // It's not clear whether we should be able to reverse charges that have */ -/* // already been paid/cleared/reconciled. Certainly, that will be the */ -/* // case when someone has pre-paid and then moves out early. However, this */ -/* // will work well for items accidentally charged but not yet paid for. */ -/* if ((!$entry['DebitLedger']['Account']['trackable'] || */ -/* $stats['debit']['amount_reconciled'] == 0) && */ -/* (!$entry['CreditLedger']['Account']['trackable'] || */ -/* $stats['credit']['amount_reconciled'] == 0) */ - -/* && 0 */ - -/* ) */ -/* { */ -/* // Set up dynamic menu items */ -/* $this->sidemenu_links[] = */ -/* array('name' => 'Operations', 'header' => true); */ - -/* $this->sidemenu_links[] = */ -/* array('name' => 'Undo', */ -/* 'url' => array('action' => 'reverse', */ -/* $id)); */ -/* } */ - -/* if ($this->Entry->Ledger->Account->type */ -/* ($entry['CreditLedger']['Account']['id']) == 'INCOME') */ -/* { */ -/* // Set up dynamic menu items */ -/* $this->sidemenu_links[] = */ -/* array('name' => 'Operations', 'header' => true); */ - -/* $this->sidemenu_links[] = */ -/* array('name' => 'Reverse', */ -/* 'url' => array('action' => 'reverse', */ -/* $id)); */ -/* } */ + if (empty($entry['DebitEntry'])) + $entry['MatchingEntry'] = $entry['CreditEntry'][0]; + else + $entry['MatchingEntry'] = $entry['DebitEntry'][0]; // Prepare to render. - $title = "Ledger Entry #{$entry['Entry']['id']}"; - $this->set(compact('entry', 'title', 'reconciled')); - } - - function tst($id = null) { - $entry = $this->Entry->find - ('first', - array('contain' => array('Account', - - 'DoubleEntry', - - 'Payment' => array('fields' => array('Payment.*'/*, 'AppliedPayment.*'*/), - 'DoubleEntry'/* => array('alias' => 'PaymentDoubleEntry')*/), - 'Charge' => array('fields' => array('Charge.*'/*, 'AppliedCharge.*'*/), - 'DoubleEntry'/* => array('alias' => 'ChargeDoubleEntry')*/), - ), - 'conditions' => array('Entry.id' => $id), - )); - pr($entry); + $title = "Ledger Entry #{$entry['LedgerEntry']['id']}"; + $this->set(compact('entry', 'title')); } } diff --git a/controllers/ledgers_controller.php b/controllers/ledgers_controller.php index 528fd1a..24758c7 100644 --- a/controllers/ledgers_controller.php +++ b/controllers/ledgers_controller.php @@ -65,8 +65,9 @@ class LedgersController extends AppController { } function gridDataFields(&$params, &$model) { - return array_merge(array('Ledger.*', - 'CONCAT(Account.id, "-", Ledger.sequence) AS id_sequence'), + $fields = parent::gridDataFields($params, $model); + $fields[] = 'CONCAT(Account.id, "-", Ledger.sequence) AS id_sequence'; + return array_merge($fields, $this->Ledger->LedgerEntry->debitCreditFields(true)); } diff --git a/controllers/statement_entries_controller.php b/controllers/statement_entries_controller.php index bd8eccf..21660a2 100644 --- a/controllers/statement_entries_controller.php +++ b/controllers/statement_entries_controller.php @@ -52,7 +52,7 @@ class StatementEntriesController extends AppController { ), ); - if (isset($params['custom']['statement_entry_id'])) { + if (isset($params['post']['custom']['statement_entry_id'])) { $link['PaymentEntry'] = array(); $link['ChargeEntry'] = array(); } @@ -60,7 +60,7 @@ class StatementEntriesController extends AppController { /* $link['PaymentEntry'] = array(); */ /* $link['ChargeEntry'] = array(); */ /* } */ -/* elseif (isset($params['custom']['customer_id']) || isset($params['custom']['lease_id'])) { */ +/* elseif (isset($params['post']['custom']['customer_id']) || isset($params['post']['custom']['lease_id'])) { */ /* $link['PaymentEntry'] = array(); */ /* } */ @@ -69,11 +69,9 @@ class StatementEntriesController extends AppController { function gridDataFields(&$params, &$model) { $fields = parent::gridDataFields($params, $model); + extract($params['post']['custom']); - if (!isset($fields)) - $fields = array('StatementEntry.*'); - -/* if (isset($params['custom']['reconcile_id'])) { */ +/* if (isset($params['post']['custom']['reconcile_id'])) { */ /* $fields[] = array("IF(StatementEntry.type = 'CHARGE',", */ /* " COALESCE(AppliedCharge.amount,0),", */ /* " COALESCE(AppliedPayment.amount,0))", */ @@ -85,11 +83,8 @@ class StatementEntriesController extends AppController { /* ") AS 'balance'"); */ /* } */ - if (isset($params['custom']['customer_id']) || isset($params['custom']['lease_id']) - || isset($params['custom']['statement_entry_id'])) { - $fields = array_merge($fields, - $this->StatementEntry->chargePaymentFields()); - } + $fields = array_merge($fields, + $this->StatementEntry->chargePaymentFields()); if ($params['action'] === 'collected') $fields[] = 'MAX(Receipt.stamp) AS last_paid'; @@ -99,19 +94,7 @@ class StatementEntriesController extends AppController { function gridDataConditions(&$params, &$model) { $conditions = parent::gridDataConditions($params, $model); - extract($params['custom']); - - if (isset($transaction_id)) - $conditions[] = array('Transaction.id' => $transaction_id); - - if (isset($account_id)) - $conditions[] = array('Account.id' => $account_id); - - if (isset($customer_id)) - $conditions[] = array('Customer.id' => $customer_id); - - if (isset($lease_id)) - $conditions[] = array('Lease.id' => $lease_id); + extract($params['post']['custom']); if (!empty($from_date)) $conditions[] @@ -148,10 +131,6 @@ class StatementEntriesController extends AppController { return parent::gridDataPostProcessLinks($params, $model, $records, $links); } - function gridDataGroup(&$params, &$model) { - return parent::gridDataGroup($params, $model); - } - function gridDataOrder(&$params, &$model, $index, $direction) { $order = parent::gridDataOrder($params, $model, $index, $direction); @@ -265,28 +244,11 @@ class StatementEntriesController extends AppController { /* } */ $stats = $this->StatementEntry->stats($id); - pr($stats); + //pr($stats); // Prepare to render. $title = "Statement Entry #{$entry['StatementEntry']['id']}"; $this->set(compact('entry', 'title', 'reconciled', 'stats')); } - function tst($id = null) { - $entry = $this->StatementEntry->find - ('first', - array('contain' => array('Account', - - 'DoubleStatementEntry', - - 'Payment' => array('fields' => array('Payment.*'/*, 'AppliedPayment.*'*/), - 'DoubleStatementEntry'/* => array('alias' => 'PaymentDoubleStatementEntry')*/), - 'Charge' => array('fields' => array('Charge.*'/*, 'AppliedCharge.*'*/), - 'DoubleStatementEntry'/* => array('alias' => 'ChargeDoubleStatementEntry')*/), - ), - 'conditions' => array('StatementEntry.id' => $id), - )); - pr($entry); - } - } diff --git a/controllers/monetary_sources_controller.php b/controllers/tenders_controller.php similarity index 82% rename from controllers/monetary_sources_controller.php rename to controllers/tenders_controller.php index fa7cd55..850885b 100644 --- a/controllers/monetary_sources_controller.php +++ b/controllers/tenders_controller.php @@ -1,6 +1,6 @@ all(); } - function all() { $this->gridView('All MonetarySources', 'all'); } + function all() { $this->gridView('All Legal Tender', 'all'); } /************************************************************************** @@ -43,7 +43,7 @@ class MonetarySourcesController extends AppController { } function gridDataPostProcessLinks(&$params, &$model, &$records, $links) { - $links['MonetarySource'] = array('id'); + $links['Tender'] = array('id'); return parent::gridDataPostProcessLinks($params, $model, $records, $links); } @@ -52,7 +52,7 @@ class MonetarySourcesController extends AppController { ************************************************************************** ************************************************************************** * action: nsf - * - Marks a monetary source as having insufficient funds. + * - Marks a tender as having insufficient funds. */ function nsf($id = null) { @@ -65,7 +65,7 @@ class MonetarySourcesController extends AppController { // For testing purposes, must be deleted $stamp = '2009-07-09'; - $this->MonetarySource->nsf($id, $stamp); + $this->Tender->nsf($id, $stamp); } /************************************************************************** @@ -81,8 +81,8 @@ class MonetarySourcesController extends AppController { $this->redirect(array('controller' => 'accounts', 'action'=>'index')); } - // Get the MonetarySource and related fields - $monetary_source = $this->MonetarySource->find + // Get the Tender and related fields + $tender = $this->Tender->find ('first', array ('contain' => false, )); @@ -104,7 +104,7 @@ class MonetarySourcesController extends AppController { $id)); // Prepare to render. - $title = "Monetary Source #{$monetary_source['MonetarySource']['id']}"; - $this->set(compact('monetary_source', 'title')); + $title = "Tender #{$tender['Tender']['id']}"; + $this->set(compact('tender', 'title')); } } diff --git a/controllers/transactions_controller.php b/controllers/transactions_controller.php index 3327c5f..6bec101 100644 --- a/controllers/transactions_controller.php +++ b/controllers/transactions_controller.php @@ -64,23 +64,22 @@ class TransactionsController extends AppController { ('first', array('contain' => array(// Models - 'LedgerEntry' => - array('fields' => array('LedgerEntry.id', - 'LedgerEntry.amount', - 'LedgerEntry.comment'), + 'Account' => + array('fields' => array('Account.id', + 'Account.name'), + ), + + 'Ledger' => + array('fields' => array('Ledger.id', + 'Ledger.name'), ), ), 'conditions' => array('Transaction.id' => $id), )); -/* // Figure out the transaction total */ -/* $total = 0; */ -/* foreach($transaction['LedgerEntry'] AS $entry) */ -/* $total += $entry['amount']; */ - // OK, prepare to render. $title = 'Transaction #' . $transaction['Transaction']['id']; - $this->set(compact('transaction', 'title', 'total')); + $this->set(compact('transaction', 'title')); } diff --git a/controllers/units_controller.php b/controllers/units_controller.php index 63c469a..ef7af90 100644 --- a/controllers/units_controller.php +++ b/controllers/units_controller.php @@ -52,51 +52,37 @@ class UnitsController extends AppController { } function gridDataCountTables(&$params, &$model) { - $link = array - ('link' => - array(// Models - 'UnitSize' => array('fields' => array('id', 'name')), - ), - ); + 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', - ), - ); +/* if ($params['action'] === 'occupied') */ +/* $link['Lease'] = array('fields' => array(), */ +/* // Models */ +/* 'Contact' => array('fields' => array('display_name'), */ +/* //'type' => 'LEFT', */ +/* ), */ +/* ); */ - return $link; } function gridDataTables(&$params, &$model) { $link = $this->gridDataCountTables($params, $model); - $link['link']['CurrentLease']['LedgerEntry'] = array('fields' => array()); - $link['link']['CurrentLease']['LedgerEntry']['Ledger'] = array('fields' => array()); - $link['link']['CurrentLease']['LedgerEntry']['Ledger']['Account'] = array('fields' => array()); - // INNER JOIN would be great, as it would ensure we're only looking - // at the ledger entries that we truly want. However, this also - // removes from the query any leases that do not yet have a ledger - // entry in A/R. A solution would be to INNER JOIN these tables, - // and LEFT JOIN it to the rest. Grouping of JOINs, however, is - // implemented with the 'joins' tag, and is not available through - // the Linkable behavior interface. - //$link['link']['CurrentLease']['LedgerEntry']['Ledger']['Account']['type'] = 'INNER'; - $link['link']['CurrentLease']['LedgerEntry']['Ledger']['Account']['conditions'] - = array('Account.id' => - $this->Unit->CurrentLease->LedgerEntry->Ledger->Account->accountReceivableAccountID()); + $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) { - $db = &$model->getDataSource(); - $fields = $db->fields($model, $model->alias); - $fields[] = ("SUM(IF(Account.id IS NULL, 0," . - " IF(LedgerEntry.debit_ledger_id = Account.id," . - " 1, -1))" . - " * LedgerEntry.amount) AS 'balance'"); - return $fields; + $fields = parent::gridDataFields($params, $model); + + return array_merge($fields, + $this->Unit->Lease->StatementEntry->chargePaymentFields(true)); } function gridDataConditions(&$params, &$model) { @@ -242,8 +228,8 @@ class UnitsController extends AppController { $stats['CurrentLease']['balance']; // Figure out the total security deposit for the current lease. - $deposits = $this->Unit->Lease->findSecurityDeposits($unit['CurrentLease']['id']); - $outstanding_deposit = $deposits['summary']['balance']; + $deposits = $this->Unit->Lease->securityDeposits($unit['CurrentLease']['id']); + $outstanding_deposit = $deposits['summary']['Payment']['reconciled']; } // Set up dynamic menu items diff --git a/models/account.php b/models/account.php index fe87390..4f035b1 100644 --- a/models/account.php +++ b/models/account.php @@ -107,7 +107,7 @@ class Account extends AppModel { * on the overall balance of the account. */ - function debitCreditFields($sum = false, $entry_name = 'Entry', $account_name = 'Account') { + function debitCreditFields($sum = false, $entry_name = 'LedgerEntry', $account_name = 'Account') { return $this->LedgerEntry->debitCreditFields ($sum, $entry_name, $account_name); } diff --git a/models/contact.php b/models/contact.php index f611803..b691823 100644 --- a/models/contact.php +++ b/models/contact.php @@ -3,13 +3,6 @@ class Contact extends AppModel { var $displayField = 'display_name'; - var $validate = array( - 'id' => array('numeric'), - 'display_name' => array('notempty'), - 'id_federal' => array('ssn'), - 'id_exp' => array('date') - ); - var $hasMany = array( 'ContactsMethod', 'ContactsCustomer', diff --git a/models/lease.php b/models/lease.php index 6733991..1d13d8b 100644 --- a/models/lease.php +++ b/models/lease.php @@ -111,6 +111,7 @@ class Lease extends AppModel { return false; if (count($entries) != 1) return null; + pr($entries); return $entries[0]['StatementEntry']['through_date']; } @@ -425,7 +426,7 @@ class Lease extends AppModel { $query['group'] = null; $stats = $this->StatementEntry->find('first', $query); - pr(compact('query', 'stats')); + //pr(compact('query', 'stats')); // The fields are all tucked into the [0] index, // and the rest of the array is useless (empty). diff --git a/models/ledger.php b/models/ledger.php index 5d97669..06fcc88 100644 --- a/models/ledger.php +++ b/models/ledger.php @@ -110,7 +110,7 @@ class Ledger extends AppModel { * entries are a debit, or a credit, and also the effect each have * on the overall balance of the ledger. */ - function debitCreditFields($sum = false, $entry_name = 'Entry', $account_name = 'Account') { + function debitCreditFields($sum = false, $entry_name = 'LedgerEntry', $account_name = 'Account') { return $this->LedgerEntry->debitCreditFields ($sum, $entry_name, $account_name); } @@ -128,7 +128,7 @@ class Ledger extends AppModel { $entries = $this->LedgerEntry->find ('all', array - ('contain' => array('Ledger' => array('Account')), + ('link' => array('Ledger' => array('Account')), 'fields' => array_merge(array("LedgerEntry.*"), $this->LedgerEntry->debitCreditFields()), 'conditions' => array('LedgerEntry.ledger_id' => $ids), @@ -151,14 +151,14 @@ class Ledger extends AppModel { $this->queryInit($query); - if (!isset($query['link']['Ledger'])) - $query['link']['Ledger'] = array(); - if (!isset($query['link']['Ledger']['fields'])) - $query['link']['Ledger']['fields'] = array(); - if (!isset($query['link']['Ledger']['Account'])) - $query['link']['Ledger']['Account'] = array(); - if (!isset($query['link']['Ledger']['Account']['fields'])) - $query['link']['Ledger']['Account']['fields'] = array(); +/* if (!isset($query['link']['Ledger'])) */ +/* $query['link']['Ledger'] = array(); */ +/* if (!isset($query['link']['Ledger']['fields'])) */ +/* $query['link']['Ledger']['fields'] = array(); */ + if (!isset($query['link']['Account'])) + $query['link']['Account'] = array(); + if (!isset($query['link']['Account']['fields'])) + $query['link']['Account']['fields'] = array(); /* if (!isset($query['link']['Transaction'])) */ /* $query['link']['Transaction'] = array(); */ /* if (!isset($query['link']['Transaction']['fields'])) */ @@ -175,7 +175,7 @@ class Ledger extends AppModel { $query['group'][] = 'LedgerEntry.ledger_id'; $stats = $this->LedgerEntry->find('first', $query); - pr(compact('stats')); + //pr(compact('stats')); /* unset($query['group']); */ @@ -187,6 +187,11 @@ class Ledger extends AppModel { // 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; diff --git a/models/ledger_entry.php b/models/ledger_entry.php index f426d95..4370c7a 100644 --- a/models/ledger_entry.php +++ b/models/ledger_entry.php @@ -8,7 +8,7 @@ class LedgerEntry extends AppModel { ); var $hasOne = array( - 'Payment', + 'Tender', ); var $hasMany = array( @@ -44,23 +44,23 @@ class LedgerEntry extends AppModel { * on the overall balance of the account/ledger. */ - function debitCreditFields($sum = false, $entry_name = 'Entry', $account_name = 'Account') { + function debitCreditFields($sum = false, $entry_name = 'LedgerEntry', $account_name = 'Account') { $fields = array ( ($sum ? 'SUM(' : '') . - "IF({$entry_name}.type = 'DEBIT'," . + "IF({$entry_name}.crdr = 'DEBIT'," . " {$entry_name}.amount, NULL)" . ($sum ? ')' : '') . ' AS debit' . ($sum ? 's' : ''), ($sum ? 'SUM(' : '') . - "IF({$entry_name}.type = 'CREDIT'," . + "IF({$entry_name}.crdr = 'CREDIT'," . " {$entry_name}.amount, NULL)" . ($sum ? ')' : '') . ' AS credit' . ($sum ? 's' : ''), ($sum ? 'SUM(' : '') . "IF(${account_name}.type IN ('ASSET', 'EXPENSE')," . - " IF({$entry_name}.type = 'DEBIT', 1, -1)," . - " IF({$entry_name}.type = 'CREDIT', 1, -1))" . + " 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', ); diff --git a/models/statement_entry.php b/models/statement_entry.php index 3ff6024..938dd3c 100644 --- a/models/statement_entry.php +++ b/models/statement_entry.php @@ -274,7 +274,7 @@ OPTION 2 $resultset = array(); foreach ($result AS $i => $entry) { - pr(compact('entry')); + //pr(compact('entry')); $entry['StatementEntry'] += $entry[0]; unset($entry[0]); @@ -369,16 +369,12 @@ OPTION 2 //'type' => 'INNER', ); - $query['fields'] = array(); - $query['fields'][] = "StatementEntry.amount AS total"; - //$query['conditions'][] = array("{$Set}Entry.id !=" => null); - + $query['fields'] = array('StatementEntry.amount'); $query['conditions'][] = array('StatementEntry.id' => $id); - $query['group'] = 'StatementEntry.id'; $result = $this->find('first', $query); - $result[0]['balance'] = $result[0]['total'] - $result[0]['reconciled']; + $result[0]['balance'] = $result['StatementEntry']['amount'] - $result[0]['reconciled']; //pr(compact('query', 'result')); return $result['StatementEntry'] + $result[0]; diff --git a/models/payment.php b/models/tender.php similarity index 88% rename from models/payment.php rename to models/tender.php index 30334d7..666bc22 100644 --- a/models/payment.php +++ b/models/tender.php @@ -1,5 +1,5 @@ 1, 'type'=>1, 'name'=>1, 'amount'=>1, + // Establish the key tender parameters + $tender = array_intersect_key($data, array('stamp'=>1, 'type'=>1, 'name'=>1, 'amount'=>1, 'data1'=>1, 'data2'=>1, 'data3'=>1, 'data4'=>1)); - $payment['customer_id'] = $customer_id; + $tender['customer_id'] = $customer_id; - // Create the payment entry, and reconcile the credit side - // of the double-entry (which should be A/R) as a payment. + // Create the tender entry, and reconcile the credit side + // of the double-entry (which should be A/R) as a tender. $ids = $this->LedgerEntry->Ledger->Account->postLedgerEntry - ($payment, + ($tender, array('debit_ledger_id' => $A->currentLedgerID($entry['account_id']), - 'credit_ledger_id' => $A->currentLedgerID($A->paymentAccountID()) + 'credit_ledger_id' => $A->currentLedgerID($A->tenderAccountID()) ) + $entry, - array('debit' => 'payment', + array('debit' => 'tender', 'credit' => $reconcile) ); if ($ids['error']) $ret = false; - $payment = array_intersect_key($ids, - array('payment_id'=>1, - 'split_payment_id'=>1)); + $tender = array_intersect_key($ids, + array('tender_id'=>1, + 'split_tender_id'=>1)); return $ret; } @@ -84,7 +84,7 @@ class Payment extends AppModel { */ function nsf($id, $stamp = null) { - pr(array('Payment::nsf', + pr(array('Tender::nsf', compact('id'))); $A = new Account(); @@ -96,7 +96,7 @@ class Payment extends AppModel { array(/* e3 */ 'LedgerEntry' => array('Transaction.id', - 'Payment.id', + 'Tender.id', 'Customer.id', 'Lease.id', @@ -156,7 +156,7 @@ class Payment extends AppModel { ), ), - 'conditions' => array(array('Payment.id' => $id)), + 'conditions' => array(array('Tender.id' => $id)), )); pr($source); diff --git a/views/accounts/collected.ctp b/views/accounts/collected.ctp index b3b7455..79c985d 100644 --- a/views/accounts/collected.ctp +++ b/views/accounts/collected.ctp @@ -31,10 +31,10 @@ function updateEntriesGrid() { account_ids.push($(this).val()); }); - cust['collected_account_id'] = ; - cust['collected_from_date'] = $('#TxFromDate').val(); - cust['collected_through_date'] = $('#TxThroughDate').val(); - cust['collected_payment_accounts'] = account_ids; + cust['account_id'] = ; + cust['from_date'] = $('#TxFromDate').val(); + cust['through_date'] = $('#TxThroughDate').val(); + cust['payment_accounts'] = account_ids; $('#collected-total').html('Calculating...'); $('#collected-entries-jqGrid').clearGridData(); @@ -155,7 +155,7 @@ echo '
' . "\n"; echo $this->element('ledger_entries', array (// Element configuration - 'collected_account_id' => $account['id'], + 'account_id' => $account['id'], // Grid configuration 'config' => array diff --git a/views/accounts/view.ctp b/views/accounts/view.ctp index b8d9e6b..7b391fd 100644 --- a/views/accounts/view.ctp +++ b/views/accounts/view.ctp @@ -9,12 +9,19 @@ echo '