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
// Determine which are to be deposited, and which are to
// 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) {
if (empty($type['checked']))
$type['items'] = unserialize($type['items']);
if (empty($type['selection']) ||
$type['selection'] === 'none' ||
($type['selection'] === 'subset' && count($type['items']) == 0))
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;
}
// 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
('all',
array('contain' => array('TenderType', 'LedgerEntry'),
'conditions' => array(array('DepositTender.deposit_transaction_id' => null),
array('TenderType.id' => $type_ids)),
'conditions' => $deposit_conditions,
));
// Prepare for the deposit by building a list of entries
$deposit = array('Transaction' => array(), 'Entry' => array());
foreach ($tenders AS $tender) {
$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
$result = $this->Transaction->addDeposit
($deposit, $this->data['Deposit']['Account']['id']);

View File

@@ -8,23 +8,32 @@ echo '<P><BR>' . "\n";
//pr(compact('depositTypes', 'depositAccounts'));
echo $form->create(null, array('id' => 'deposit-form',
'onsubmit' => 'return verifyRequest();',
'url' => array('controller' => 'transactions',
'action' => 'postDeposit')));
foreach ($depositTypes AS $type) {
//$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 $form->input("TenderType.{$type['id']}.checked",
array(//'label' => $type['name'],
'type' => 'checkbox',
'checked' => $type['stats']['undeposited'] > 0 ? true : false,
'disabled' => $type['stats']['undeposited'] > 0 ? false : true,
'value' => true,
'label' => (" I have exactly " .
FormatHelper::currency($type['stats']['undeposited']) .
" in " . Inflector::pluralize($type['name']) .
" and will be depositing it all.")
echo $form->input("TenderType.{$type['id']}.selection",
array('type' => 'radio',
'class' => "type-selection-{$type['id']}",
'separator' => '<BR>',
'onclick' => "switchSelection({$type['id']})",
'legend' => false,
'value' => $type['stats']['undeposited'] > 0 ? 'all' : 'none',
'disabled' => $type['stats']['undeposited'] <= 0,
'options' => $radioOptions,
));
// REVISIT <AP>: 20090729
@@ -60,14 +69,35 @@ foreach ($depositTypes AS $type) {
'config' => array
(
'grid_div_id' => $grid_div_id,
'grid_setup' => array('hiddengrid' => true),
'caption' => ('<A HREF="#" ONCLICK="$(\'#'.$grid_div_id.' .HeaderButton\').click();'.
' return false;">Items in '.$type['name'].' Ledger</A>'),
'grid_setup' =>
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,
'TenderType.id' => $type['id']),
'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 ',
@@ -76,3 +106,91 @@ echo $form->end('Perform Deposit');
/* End page div */
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>