Added the ability to perform partial deposits. After this checkin, I'll clean up some of the commented out sections of things that we're attempted to get this all working.

git-svn-id: file:///svn-source/pmgr/branches/yafr_20090716/site@451 97e9348a-65ac-dc4b-aefc-98561f571b83
This commit is contained in:
abijah
2009-07-31 16:41:56 +00:00
parent 53a8d8fc60
commit 9bd37ba282
2 changed files with 170 additions and 21 deletions

View File

@@ -165,25 +165,54 @@ class TransactionsController extends AppController {
// Go through each type of tender presented to the user // Go through each type of tender presented to the user
// Determine which are to be deposited, and which are to // Determine which are to be deposited, and which are to
// have their corresponding account ledgers closed. // have their corresponding account ledgers closed.
$type_ids = $close_type_ids = array(); $deposit_tender_ids = array();
$deposit_type_ids = array();
$close_type_ids = array();
foreach ($this->data['TenderType'] AS $type_id => $type) { foreach ($this->data['TenderType'] AS $type_id => $type) {
if (empty($type['checked'])) $type['items'] = unserialize($type['items']);
if (empty($type['selection']) ||
$type['selection'] === 'none' ||
($type['selection'] === 'subset' && count($type['items']) == 0))
continue; continue;
$type_ids[] = $type_id;
if (!empty($type['close'])) // The deposit includes either the whole type, or just certain tenders
if ($type['selection'] === 'all')
$deposit_type_ids[] = $type_id;
else
$deposit_tender_ids = array_merge($deposit_tender_ids, $type['items']);
// Should we close the ledger for this tender type?
// First, the user would have to request that we do so,
// but additionally, we shouldn't close a ledger unless
// all the tenders are included in this deposit. That
// doesn't guarantee that the ledger has a zero balance,
// but it does carry the balance forward, and a total
// deposit would imply a fresh start, so go for it.
if (!empty($type['close']) && $type['selection'] === 'all')
$close_type_ids[] = $type_id; $close_type_ids[] = $type_id;
} }
// Find all items which are actually to be deposited if (empty($deposit_type_ids) && empty($deposit_tender_ids)) {
$this->Session->setFlash(__('Nothing to Deposit', true));
$this->redirect(array('controller' => 'tenders', 'action'=>'deposit'));
}
$deposit_conditions = array();
if (!empty($deposit_type_ids))
$deposit_conditions[] = array('TenderType.id' => $deposit_type_ids);
if (!empty($deposit_tender_ids))
$deposit_conditions[] = array('DepositTender.id' => $deposit_tender_ids);
$deposit_conditions =
array(array('DepositTender.deposit_transaction_id' => null),
array('OR' => $deposit_conditions));
$tenders = $this->Transaction->DepositTender->find $tenders = $this->Transaction->DepositTender->find
('all', ('all',
array('contain' => array('TenderType', 'LedgerEntry'), array('contain' => array('TenderType', 'LedgerEntry'),
'conditions' => array(array('DepositTender.deposit_transaction_id' => null), 'conditions' => $deposit_conditions,
array('TenderType.id' => $type_ids)),
)); ));
// Prepare for the deposit by building a list of entries
$deposit = array('Transaction' => array(), 'Entry' => array()); $deposit = array('Transaction' => array(), 'Entry' => array());
foreach ($tenders AS $tender) { foreach ($tenders AS $tender) {
$deposit['Entry'][] = $deposit['Entry'][] =
@@ -193,6 +222,8 @@ class TransactionsController extends AppController {
); );
} }
//pr(compact('deposit_type_ids', 'deposit_tender_ids', 'close_type_ids', 'deposit_conditions', 'deposit'));
// OK, perform the deposit and associated accounting // OK, perform the deposit and associated accounting
$result = $this->Transaction->addDeposit $result = $this->Transaction->addDeposit
($deposit, $this->data['Deposit']['Account']['id']); ($deposit, $this->data['Deposit']['Account']['id']);

View File

@@ -8,23 +8,32 @@ echo '<P><BR>' . "\n";
//pr(compact('depositTypes', 'depositAccounts')); //pr(compact('depositTypes', 'depositAccounts'));
echo $form->create(null, array('id' => 'deposit-form', echo $form->create(null, array('id' => 'deposit-form',
'onsubmit' => 'return verifyRequest();',
'url' => array('controller' => 'transactions', 'url' => array('controller' => 'transactions',
'action' => 'postDeposit'))); 'action' => 'postDeposit')));
foreach ($depositTypes AS $type) { foreach ($depositTypes AS $type) {
//$acct = $acct['Account']; //$acct = $acct['Account'];
$names = Inflector::pluralize($type['name']);
$radioOptions =
array('none' => " No {$names} will be deposited",
'all' => (" Deposit all {$names} (" .
FormatHelper::currency($type['stats']['undeposited']) .
")"),
'subset' => " Deposit {$names} from the list below",
);
echo "\n"; echo "\n";
echo $form->input("TenderType.{$type['id']}.checked", echo $form->input("TenderType.{$type['id']}.selection",
array(//'label' => $type['name'], array('type' => 'radio',
'type' => 'checkbox', 'class' => "type-selection-{$type['id']}",
'checked' => $type['stats']['undeposited'] > 0 ? true : false, 'separator' => '<BR>',
'disabled' => $type['stats']['undeposited'] > 0 ? false : true, 'onclick' => "switchSelection({$type['id']})",
'value' => true, 'legend' => false,
'label' => (" I have exactly " . 'value' => $type['stats']['undeposited'] > 0 ? 'all' : 'none',
FormatHelper::currency($type['stats']['undeposited']) . 'disabled' => $type['stats']['undeposited'] <= 0,
" in " . Inflector::pluralize($type['name']) . 'options' => $radioOptions,
" and will be depositing it all.")
)); ));
// REVISIT <AP>: 20090729 // REVISIT <AP>: 20090729
@@ -60,14 +69,35 @@ foreach ($depositTypes AS $type) {
'config' => array 'config' => array
( (
'grid_div_id' => $grid_div_id, 'grid_div_id' => $grid_div_id,
'grid_setup' => array('hiddengrid' => true),
'caption' => ('<A HREF="#" ONCLICK="$(\'#'.$grid_div_id.' .HeaderButton\').click();'. 'grid_setup' =>
' return false;">Items in '.$type['name'].' Ledger</A>'), array('hiddengrid' => true,
'multiselect' => true),
'grid_events' =>
array(
/* 'onHeaderClick' => */
/* array('gridstate' => */
/* 'onGridState("#"+$(this).attr("id"), gridstate)'), */
/* 'gridComplete' => */
/* array('' => "switchSelection({$type['id']})"), */
/* 'loadBeforeSend' => */
/* array('xhr' => "loadBeforeSend()"), */
),
'caption' => "{$names} on hand",
'filter' => array('deposit_transaction_id' => null, 'filter' => array('deposit_transaction_id' => null,
'TenderType.id' => $type['id']), 'TenderType.id' => $type['id']),
'exclude' => array('Type'), 'exclude' => array('Type'),
), ),
)); ));
echo "\n";
echo $form->input("TenderType.{$type['id']}.items",
array('type' => 'hidden',
'value' => null
));
} }
echo $form->input('Deposit.Account.id', array('label' => 'Deposit Account ', echo $form->input('Deposit.Account.id', array('label' => 'Deposit Account ',
@@ -76,3 +106,91 @@ echo $form->end('Perform Deposit');
/* End page div */ /* End page div */
echo '</div>' . "\n"; echo '</div>' . "\n";
?>
<script type="text/javascript"><!--
$(document).ready(function(){
$('#debug').html('ready()<BR>');
<?php foreach ($depositTypes AS $type): ?>
switchSelection(<?php echo $type['id']; ?>);
<?php endforeach; ?>
});
// pre-submit callback
function verifyRequest() {
// return false to prevent the form from being submitted;
// anything other than false will allow submission.
$('#debug').html('Verifying...');
<?php foreach ($depositTypes AS $type): ?>
var rows = $('#<?php echo "tenders-{$type['id']}-list-jqGrid"; ?>').getGridParam('selarrrow');
$('#<?php echo "TenderType{$type['id']}Items"; ?>').val(serialize(rows));
<?php endforeach; ?>
<?php
// REVISIT <AP>: 20090730
// Verify the request before submitting
?>
return true;
}
function loadBeforeSend() {
$('#debug').append('<P>debugLBS');
<?php foreach ($depositTypes AS $type): ?>
var grid_div_id = '#<?php echo "tenders-{$type['id']}-list"; ?>'
var grid_id = grid_div_id+'-jqGrid';
$(grid_id).setGridParam({multiselect:true});
<?php endforeach; ?>
}
function switchSelection(type_id) {
//var selection = $('#TenderType'+type_id+'Selection').val();
var grid_div_id = '#tenders-'+type_id+'-list';
var grid_id = grid_div_id+'-jqGrid';
var selection = $('.type-selection-'+type_id+':checked').val();
var gridstate = $(grid_id).getGridParam('gridstate');
//var multiselect = $(grid_id).getGridParam('multiselect');
/* $('#debug').append('<P>' + */
/* 'type_id = ' + type_id + '<br>' + */
/* 'selection = ' + selection + '<br>' + */
/* 'gridstate = ' + gridstate + '<br>' + */
/* '' //'multiselect = ' + multiselect + '<br>' */
/* ); */
<?php
// It seems that jqGrid doesn't work too well with multiselect
// dynamically enabled / disabled. What we'd like to do is:
/* if (selection == 'subset' && !multiselect) */
/* $(grid_id).setGridParam({multiselect:true}).showCol('cb'); */
/* if (selection != 'subset' && multiselect) */
/* $(grid_id).setGridParam({multiselect:false}).hideCol('cb'); */
// However, if the grid is reloaded (manually, or page switch) while
// multiselect is disabled, then it loads garbage. I have been able
// to work around this using the loadBeforeSend event to re-enable
// multiselect just for the load, then disable it again using this
// function after the load (using the gridComplete event).
//
// It seems terribly clunky though, and so as a workaround, I've
// found that I can leave multiselect enabled all the time, and just
// Tell the grid to allow selection through checkboxes only, after
// hiding the checkboxes. This essentially disables multiselection
// as well, without the grid having to disable the entire mechanism.
?>
// Configure multiselection
if (selection == 'subset')
$(grid_id).showCol('cb').setGridParam({multiboxonly: false});
else
$(grid_id).hideCol('cb').setGridParam({multiboxonly: true}).resetSelection();
// Show or hide the grid, as appropriate
if ((selection == 'subset') == (gridstate == 'hidden'))
$(grid_div_id + ' .HeaderButton').click();
}
--></script>