sidemenu_links); } /************************************************************************** ************************************************************************** ************************************************************************** * action: index / all * - Generate a listing of Tenders */ function index() { $this->all(); } function all() { $this->gridView('All Legal Tender', 'all'); } /************************************************************************** ************************************************************************** ************************************************************************** * virtuals: gridData * - With the application controller handling the gridData action, * these virtual functions ensure that the correct data is passed * to jqGrid. */ function gridDataTables(&$params, &$model) { return array ('link' => array('TenderType', 'Customer', 'LedgerEntry' => array('Transaction', ), ), ); } function gridDataRecordsExecute(&$params, &$model, $query) { $tquery = array_diff_key($query, array('fields'=>1,'group'=>1,'limit'=>1,'order'=>1)); $tquery['fields'] = array("SUM(COALESCE(LedgerEntry.amount,0)) AS 'total'"); $total = $model->find('first', $tquery); $params['userdata']['total'] = $total[0]['total']; return parent::gridDataRecordsExecute($params, $model, $query); } function gridDataPostProcessLinks(&$params, &$model, &$records, $links) { $links['Tender'] = array('name', 'id'); $links['Customer'] = array('name'); $links['TenderType'] = array('name'); return parent::gridDataPostProcessLinks($params, $model, $records, $links); } /************************************************************************** ************************************************************************** ************************************************************************** * action: deposit * - Prepares the books for a bank deposit */ function deposit() { // Prepare a close page... $deposit_types = $this->Tender->TenderType->depositTypes( // Testing... limit to only one type //array('limit' => 1) ); $deposit_accounts = $this->Tender->TenderType->Account->depositAccounts(); foreach ($deposit_types AS $type_id => &$type) $type = array('id' => $type_id, 'name' => $type, 'stats' => $this->Tender->TenderType->stats($type_id)); //pr(compact('deposit_types', 'deposit_accounts')); $title = 'Prepare Deposit'; $this->set(compact('title', 'deposit_types', 'deposit_accounts')); } /************************************************************************** ************************************************************************** ************************************************************************** * action: deposit_slip * - The followup to the action 'deposit'. * Processes the user input and updates the database */ function deposit_slip() { if (!$this->data) { $this->Session->setFlash(__('Invalid Action', true)); $this->redirect(array('action'=>'deposit')); } pr($this->data); // Start building data for our deposit $deposit = array('close_id' => null, 'total' => 0, 'types' => array(), 'Transaction' => array(), 'Entry' => array()); // Go through each type of tender presented to the user foreach ($this->data['TenderType'] AS $type_id => $type) { if (!$type['checked']) continue; $tenders = $this->Tender->find ('all', array('contain' => array ('Customer', 'LedgerEntry', ), 'conditions' => array(array('Tender.deposit_transaction_id' => null), array('Tender.tender_type_id' => $type_id)), )); // Prepare for both the actual deposit, as well as the deposit slip $deposit['types'][$type_id]['name'] = $type['name']; $deposit['types'][$type_id]['entries'] = array(); $deposit['types'][$type_id]['total'] = 0; foreach ($tenders AS $tender) { $deposit['Entry'][] = array('tender_id' => $tender['Tender']['id'], //'ledger_entry_id' => $tender['LedgerEntry']['id'], 'account_id' => $tender['LedgerEntry']['account_id'], 'amount' => $tender['LedgerEntry']['amount'], ); $deposit['types'][$type_id]['entries'][] = array('name' => $tender['Tender']['name'], 'customer' => $tender['Customer']['name'], 'amount' => $tender['LedgerEntry']['amount']); $deposit['types'][$type_id]['total'] += $tender['LedgerEntry']['amount']; } // Add into the grand total $deposit['total'] += $deposit['types'][$type_id]['total']; if (!empty($type['close'])) { // Close the associated ledger $result = $this->Tender->LedgerEntry->Account->closeCurrentLedger ($type['account_id'], $deposit['close_id']); if (!$result['error'] && empty($deposit['close_id'])) $deposit['close_id'] = $result['close_id']; } } $result = $this->Tender->DepositTransaction->addDeposit ($deposit, $this->data['Deposit']['Account']['id']); //pr(compact('deposit', 'result')); $title = 'Deposit Slip'; $this->set(compact('title', 'deposit')); $this->render('deposit_slip'); return; } /************************************************************************** ************************************************************************** ************************************************************************** * action: nsf * - Marks a tender as having insufficient funds. */ function nsf($id = null) { if (!$id) { $this->Session->setFlash(__('Invalid Item.', true)); $this->redirect(array('action'=>'index')); } // REVISIT : 20090713 // For testing purposes, must be deleted $stamp = '2009-07-09'; $stamp = null; $this->Tender->nsf($id, $stamp); } /************************************************************************** ************************************************************************** ************************************************************************** * action: view * - Displays information about a specific entry */ function view($id = null) { if (!$id) { $this->Session->setFlash(__('Invalid Item.', true)); $this->redirect(array('controller' => 'accounts', 'action'=>'index')); } // Get the Tender and related fields $tender = $this->Tender->find ('first', array ('contain' => array('TenderType', 'Customer', 'LedgerEntry' => array('Transaction')), )); // REVISIT : 20090713 // Consider allowing the NSF operation only if the source is used on // a ledger entry that is debited on a "payable" account (perhaps // even restricted to "payable" ASSET accounts), credited on Receipt // (or A/R), and reconciles the credit to an entry that debits on a // "depositable" account. // Set up dynamic menu items $this->sidemenu_links[] = array('name' => 'Operations', 'header' => true); $this->sidemenu_links[] = array('name' => 'NSF', 'url' => array('action' => 'nsf', $id)); // Prepare to render. $title = "Tender #{$tender['Tender']['id']}"; $this->set(compact('tender', 'title')); } }