From c06399cf86d1b1f725b17c0d6007121ae87058f5 Mon Sep 17 00:00:00 2001 From: abijah Date: Fri, 14 Aug 2009 20:58:50 +0000 Subject: [PATCH] Added support for deleting (destroying) a transaction. This is strictly development/super-admin type functionality. git-svn-id: file:///svn-source/pmgr/branches/yafr_20090716@553 97e9348a-65ac-dc4b-aefc-98561f571b83 --- site/controllers/transactions_controller.php | 44 ++++++--- site/models/ledger_entry.php | 18 +++- site/models/statement_entry.php | 5 +- site/models/tender.php | 27 +++++- site/models/transaction.php | 95 +++++++++++++++----- 5 files changed, 151 insertions(+), 38 deletions(-) diff --git a/site/controllers/transactions_controller.php b/site/controllers/transactions_controller.php index 3677324..c873815 100644 --- a/site/controllers/transactions_controller.php +++ b/site/controllers/transactions_controller.php @@ -361,6 +361,21 @@ class TransactionsController extends AppController { } + /************************************************************************** + ************************************************************************** + ************************************************************************** + * action: destroy + * - Deletes a transaction and associated entries + * - !!WARNING!! This should be used with EXTREME caution, as it + * irreversibly destroys the data. It is not for normal use. + */ + + function destroy($id = null) { + $this->Transaction->destroy($id); + //$this->redirect(array('action' => 'index')); + } + + /************************************************************************** ************************************************************************** ************************************************************************** @@ -397,11 +412,19 @@ class TransactionsController extends AppController { $this->redirect(array('action'=>'index')); } - if ($transaction['Transaction']['type'] === 'DEPOSIT') { + if ($transaction['Transaction']['type'] === 'DEPOSIT' || $this->params['dev']) { $this->sidemenu_links[] = array('name' => 'Operations', 'header' => true); - $this->sidemenu_links[] = - array('name' => 'View Slip', 'url' => array('action' => 'deposit_slip', $id)); + + if ($transaction['Transaction']['type'] === 'DEPOSIT') + $this->sidemenu_links[] = + array('name' => 'View Slip', 'url' => array('action' => 'deposit_slip', $id)); + if ($this->params['dev']) + $this->sidemenu_links[] = + array('name' => 'Destroy', 'url' => array('action' => 'destroy', $id), + 'confirmMessage' => ("This may leave the database in an unstable state." . + " Do NOT do this unless you know what you're doing." . + " Proceed anyway?")); } // OK, prepare to render. @@ -454,15 +477,12 @@ class TransactionsController extends AppController { $type['TenderType'] + $type[0]; } - // For each form of tender in the deposit, get the deposit items -/* foreach ($deposit['types'] AS $type_id => &$type) { */ -/* $type['entries'] = $this->Transaction->DepositTender->find */ -/* ('all', */ -/* array('contain' => array('Customer', 'LedgerEntry'), */ -/* 'conditions' => array(array('DepositTender.deposit_transaction_id' => $id), */ -/* array('DepositTender.tender_type_id' => $type_id)), */ -/* )); */ -/* } */ + $deposit_total = 0; + foreach ($deposit['types'] AS $type) + $deposit_total += $type['total']; + + if ($deposit['Transaction']['amount'] != $deposit_total) + INTERNAL_ERROR("Deposit items do not add up to deposit slip total"); $this->sidemenu_links[] = array('name' => 'Operations', 'header' => true); diff --git a/site/models/ledger_entry.php b/site/models/ledger_entry.php index cb57dea..2bfd308 100644 --- a/site/models/ledger_entry.php +++ b/site/models/ledger_entry.php @@ -8,8 +8,22 @@ class LedgerEntry extends AppModel { ); var $hasOne = array( - 'Tender', - 'DoubleEntry', + 'Tender' => array( + 'dependent' => true, + ), + 'DebitDoubleEntry' => array( + 'className' => 'DoubleEntry', + 'foreignKey' => 'credit_entry_id', + 'dependent' => true, + ), + 'CreditDoubleEntry' => array( + 'className' => 'DoubleEntry', + 'foreignKey' => 'credit_entry_id', + 'dependent' => true, + ), + 'DoubleEntry' => array( + 'foreignKey' => false, + ), ); var $hasMany = array( diff --git a/site/models/statement_entry.php b/site/models/statement_entry.php index 0572196..ae301ee 100644 --- a/site/models/statement_entry.php +++ b/site/models/statement_entry.php @@ -18,6 +18,7 @@ class StatementEntry extends AppModel { 'DisbursementEntry' => array( 'className' => 'StatementEntry', 'foreignKey' => 'charge_entry_id', + 'dependent' => true, ), ); @@ -211,7 +212,7 @@ class StatementEntry extends AppModel { = array_intersect_key($entry['DisbursementEntry'], array('customer_id'=>1, 'lease_id'=>1)); - $this->del($entry['DisbursementEntry']['id']); + $this->delete($entry['DisbursementEntry']['id']); continue; $DE = new StatementEntry(); @@ -582,7 +583,7 @@ class StatementEntry extends AppModel { $this->pr(20, compact('credit'), 'Delete Exhausted Credit Entry'); - $this->del($credit['StatementEntry']['id'], false); + $this->delete($credit['StatementEntry']['id'], false); } } else { diff --git a/site/models/tender.php b/site/models/tender.php index b0e913b..084f2d8 100644 --- a/site/models/tender.php +++ b/site/models/tender.php @@ -10,6 +10,7 @@ class Tender extends AppModel { ), 'NsfTransaction' => array( 'className' => 'Transaction', + 'dependent' => true, ), ); @@ -17,8 +18,8 @@ class Tender extends AppModel { /************************************************************************** ************************************************************************** ************************************************************************** - * function: beforeSave - * - Performs any work needed before the save occurs + * function: afterSave + * - Performs any work needed after the save occurs */ function afterSave($created) { @@ -49,6 +50,28 @@ class Tender extends AppModel { } + /************************************************************************** + ************************************************************************** + ************************************************************************** + * function: beforeDelete + * - Performs any work needed before the delete occurs + */ + + function beforeDelete($cascade = true) { + // REVISIT : 20090814 + // Experimental, and incomplete mechanism to protect + // against trying to delete data that shouldn't be deleted. + + $deposit_id = $this->field('deposit_transaction_id'); + pr(compact('deposit_id')); + // If this tender has already been deposited, it would + // be a rats nest to figure out how to delete this tender. + if (!empty($deposit_id)) + return false; + + return parent::beforeDelete($cascade); + } + /************************************************************************** ************************************************************************** ************************************************************************** diff --git a/site/models/transaction.php b/site/models/transaction.php index d0ffc19..630e9ff 100644 --- a/site/models/transaction.php +++ b/site/models/transaction.php @@ -2,13 +2,19 @@ class Transaction extends AppModel { var $belongsTo = array( + 'Customer', 'Account', 'Ledger', ); var $hasMany = array( - 'LedgerEntry', - 'StatementEntry', + 'LedgerEntry' => array( + 'dependent' => true, + ), + 'StatementEntry' => array( + 'dependent' => true, + ), + 'DepositTender' => array( 'className' => 'Tender', 'foreignKey' => 'deposit_transaction_id', @@ -525,25 +531,25 @@ class Transaction extends AppModel { // Create one half of the Double Ledger Entry (and the Tender) $le1 = array_intersect_key($entry, - array_flip(array('ledger_id', 'account_id', 'crdr', 'amount'))); - $le1['comment'] = $entry['ledger_entry_comment']; - $le1_tender = isset($entry['Tender']) ? $entry['Tender'] : null; + array_flip(array('ledger_id', 'account_id', 'crdr', 'amount'))); + $le1['comment'] = $entry['ledger_entry_comment']; + $le1_tender = isset($entry['Tender']) ? $entry['Tender'] : null; - // Create the second half of the Double Ledger Entry - if ($transaction['type'] == 'CLOSE') { - $le2 = - array_intersect_key($entry, - array_flip(array('account_id', 'amount'))); - $le2['ledger_id'] = $entry['new_ledger_id']; - $le2['crdr'] = strtoupper($this->Account->fundamentalOpposite($le1['crdr'])); - $le2['comment'] = "Ledger Balance Forward (b/f)"; - } - else { - $le2 = - array_intersect_key($entry, - array_flip(array('amount'))) + - array_intersect_key($transaction, - array_flip(array('ledger_id', 'account_id', 'crdr'))); + // Create the second half of the Double Ledger Entry + if ($transaction['type'] == 'CLOSE') { + $le2 = + array_intersect_key($entry, + array_flip(array('account_id', 'amount'))); + $le2['ledger_id'] = $entry['new_ledger_id']; + $le2['crdr'] = strtoupper($this->Account->fundamentalOpposite($le1['crdr'])); + $le2['comment'] = "Ledger Balance Forward (b/f)"; + } + else { + $le2 = + array_intersect_key($entry, + array_flip(array('amount'))) + + array_intersect_key($transaction, + array_flip(array('ledger_id', 'account_id', 'crdr'))); } // Create the statement entry @@ -795,6 +801,55 @@ class Transaction extends AppModel { } + /************************************************************************** + ************************************************************************** + ************************************************************************** + * function: destroy + * - Deletes a transaction and associated entries + * - !!WARNING!! This should be used with EXTREME caution, as it + * irreversibly destroys the data. It is not for normal use, + * and can leave the database in an inconsistent state. Expected + * scenario is to remove a bad transaction directly after creation, + * before it gets tied to anything else in the system (such as + * a late charge invoice for a customer that isn't actually late). + */ + + function destroy($id) { + $this->prFunctionLevel(30); + $this->prEnter(compact('id')); + + $this->id = $id; + $customer_id = $this->field('customer_id'); + $result = $this->delete($id); + + if (!empty($customer_id)) { + $this->StatementEntry->assignCredits + (null, null, null, null, $customer_id, null); + } + + return $this->prReturn($result); + } + + + /************************************************************************** + ************************************************************************** + ************************************************************************** + * function: update + * - Update any cached or calculated fields + */ + function update($id) { + INTERNAL_ERROR("Transaction::update not yet implemented"); + + $result = $this->find + ('first', + array('link' => array('StatementEntry'), + 'fields' => array("SUM(LedgerEntry.amount) AS total"), + 'conditions' => array(array('LedgerEntry.account_id = Transaction.account_id'), + ), + )); + } + + /************************************************************************** ************************************************************************** **************************************************************************