var service = {};
+ // fetch org unit settings specific to the bills display
+ service.fetchBillSettings = function() {
+ if (service.settings) return $q.when(service.settings);
+ return egCore.org.settings(
+ ['ui.circ.billing.uncheck_bills_and_unfocus_payment_box']
+ ).then(function(s) {return service.settings = s});
+ }
+
// user billing summary
service.fetchSummary = function() {
return egCore.pcrud.retrieve(
$scope.focus_payment = true;
$scope.annotate_payment = false;
$scope.gridRevision = 0;
- var allItems = []; // all grid items (flattened mbt's)
- // until the grid wakes up, return empty set
- $scope.getSelectedItems = $scope.getAllItems = function() {return []};
+
+ // pre-define list-returning funcs in case we access them
+ // before the grid instantiates
+ $scope.gridControls = {
+ focusRowSelector : false,
+ selectItems : function(){},
+ selectedItems : function(){return []},
+ allItems : function(){return []},
+ itemRetrieved : function(item) {
+ item.payment_pending = 0;
+ },
+ activateItem : function(item) {
+ $scope.showFullDetails([item]);
+ }
+ }
billSvc.fetchSummary().then(function(s) {$scope.summary = s});
// TODO: move me to service
function selected_payment_info() {
var info = {owed : 0, billed : 0, paid : 0};
- angular.forEach($scope.getSelectedItems(), function(item) {
+ angular.forEach($scope.gridControls.selectedItems(), function(item) {
info.owed += Number(item['summary.balance_owed']) * 100;
info.billed += Number(item['summary.total_owed']) * 100;
info.paid += Number(item['summary.total_paid']) * 100;
}
$scope.refunds_available = function() {
var amount = 0;
- angular.forEach($scope.getAllItems(), function(item) {
+ angular.forEach($scope.gridControls.allItems(), function(item) {
if (item['summary.balance_owed'] < 0)
amount += item['summary.balance_owed'] * 100;
});
$scope.gridQuery = function() {return query};
$scope.gridSort = ['xact_start']; // default sort
- $scope.gridItemRetrieved = function(item) {
- item.payment_pending = 0;
- }
// update the item.payment_pending value each time the user
// selects different transactions to pay against.
$scope.$watch(
- function() {return $scope.getSelectedItems()},
+ function() {return $scope.gridControls.selectedItems()},
function() {updatePendingColumn()},
true
);
// of our local scope variables.
function updatePendingColumn() {
// reset all to zero..
- angular.forEach($scope.getAllItems(),
+ angular.forEach($scope.gridControls.allItems(),
function(item) {item.payment_pending = 0});
var payment_amount = $scope.pending_payment();
- var selected = $scope.getSelectedItems();
+ var selected = $scope.gridControls.selectedItems();
for (var i = 0; i < selected.length; i++) { // for/break
var item = selected[i];
var owed = Number(item['summary.balance_owed']);
// which have a pending payment amount.
function generatePayments() {
var payments = [];
- angular.forEach($scope.getSelectedItems(), function(item) {
+ angular.forEach($scope.gridControls.selectedItems(), function(item) {
if (item.payment_pending == 0) return;
payments.push([item.id, item.payment_pending]);
});
);
}
+ // Select refunds adds all refunds to the existing selection.
+ // It does not /only/ select refunds
$scope.selectRefunds = function() {
- // TODO: select grid items where refunds are due
+ var ids = $scope.gridControls.selectedItems().map(
+ function(i) { return i.id });
+ angular.forEach($scope.gridControls.allItems(), function(item) {
+ if (Number(item['summary.balance_owed']) < 0)
+ ids.push(item.id);
+ });
+ $scope.gridControls.selectItems(ids);
+ }
+
+ // -------------
+ // determine on initial page load when all of the grid rows should
+ // be selected.
+ var selectOnLoad = true;
+ billSvc.fetchBillSettings().then(function(s) {
+ if (s['ui.circ.billing.uncheck_bills_and_unfocus_payment_box']) {
+ $scope.focus_payment = false; // de-focus the payment box
+ $scope.gridControls.focusRowSelector = true;
+ selectOnLoad = false;
+ // if somehow the grid finishes rendering before our settings
+ // arrive, manually de-select everything.
+ $scope.gridControls.selectItems([]);
+ }
+ });
+ $scope.gridControls.allItemsRetrieved = function() {
+ if (selectOnLoad) {
+ // select all non-refund items
+ $scope.gridControls.selectItems(
+ $scope.gridControls.allItems()
+ .filter(function(i) {return i['summary.balance_owed'] > 0})
+ .map(function(i){return i.id})
+ );
+ }
}
+ // -------------
+
$scope.printBills = function(selected) {
+ if (!selected.length) return;
// bills print receipt assumes nested hashes, but our grid
// stores flattener data. Fetch the selected xacts as
- // fleshed pcrud objects. (Consider an alternate approach..)
+ // fleshed pcrud objects and hashify.
+ // (Consider an alternate approach..)
var ids = selected.map(function(t){ return t.id });
var xacts = [];
egCore.pcrud.search('mbt',
.controller('BillXactHistoryCtrl',
['$scope','$q','egCore','patronSvc','billSvc','egPromptDialog','$location',
function($scope, $q , egCore , patronSvc , billSvc , egPromptDialog , $location) {
- $scope.getSelectedItems = function() {return []};
+ $scope.gridControls = {
+ selectedItems : function(){return []},
+ activateItem : function(item) {
+ $scope.showFullDetails([item]);
+ }
+ }
// TODO; move me to service
function selected_payment_info() {
var info = {owed : 0, billed : 0, paid : 0};
- angular.forEach($scope.getSelectedItems(), function(item) {
+ angular.forEach($scope.gridControls.selectedItems(), function(item) {
info.owed += Number(item['summary.balance_owed']) * 100;
info.billed += Number(item['summary.total_owed']) * 100;
info.paid += Number(item['summary.total_paid']) * 100;
$location.path('/circ/patron/' +
patronSvc.current.id() + '/bill/' + all[0].id);
}
- $scope.activateBill = function(xact) {
- $scope.showFullDetails([xact]);
- }
-
}])
.controller('BillPaymentHistoryCtrl',
['$scope','$q','egCore','patronSvc','billSvc','$location',
function($scope, $q , egCore , patronSvc , billSvc , $location) {
- $scope.getSelectedItems = function() {return []};
+ $scope.gridControls = {
+ selectedItems : function(){return []},
+ activateItem : function(item) {
+ $scope.showFullDetails([item]);
+ }
+ }
$scope.paymentSort = [{'payment_ts' : 'DESC'}, 'id'];
$scope.paymentQuery = function() {
patronSvc.current.id() + '/bill/' + all[0]['xact.id']);
}
- $scope.activatePayment = function(payment) {
- $scope.showFullDetails([payment]);
- }
-
$scope.totals.selected_paid = function() {
var paid = 0;
- angular.forEach($scope.getSelectedItems(), function(payment) {
+ angular.forEach($scope.gridControls.selectedItems(), function(payment) {
paid += Number(payment.amount) * 100;
});
return paid / 100;
// optional context menu label
menuLabel : '@',
- // called on each item retrieved in collect() with the item
- // as the argument. Useful for modiying objects before they
- // are absorbed by the grid.
- onItemRetrieved : '=',
-
- // TODO: deprecated
- // function called with all selected items each time the
- // selection set changes
- //onSelectionChange : '=',
-
- // function; if set, row index values will be hyperlinked and
- // the onclick for an item will call activateItem with the item
- // as the argument.
- activateItem : '=',
-
- // Function. Returns an array of selected items to the caller.
- // The contents of this function are defined by the grid and
- // called by the caller.
- selectedItems : '=',
-
- // Function. Returns an array of all grid items.
- // The contents of this function are defined by the grid and
- // called by the caller.
- allItems : '=',
-
- // Function. Accepts an array of index values.
- // The contents of this function are defined by the grid and
- // called by the caller.
- //setSelected : '=',
+ // Hash of control functions.
+ //
+ // These functions are defined by the calling scope and
+ // invoked as-is by the grid w/ the specified parameters.
+ //
+ // itemRetrieved : function(item) {}
+ // allItemsRetrieved : function() {}
+ //
+ // ---------------
+ // These functions are defined by the grid and thus
+ // replace any values defined for these attributes from the
+ // calling scope.
+ //
+ // activateItem : function(item) {}
+ // allItems : function(allItems) {}
+ // selectedItems : function(selected) {}
+ // selectItems : function(ids) {}
+ gridControls : '=',
// if set, we watch this scope variable for changes. If it
// changes, we refresh the grid.
}
}
+ grid.gridControls = $scope.gridControls || {};
+
// items needed only by the grid; remove from scope
angular.forEach(
- ['idlClass','onItemRetrieved','onSelectionChange','persistKey'],
+ ['idlClass', 'persistKey'],
function(field) {
grid[field] = $scope[field];
delete $scope[field];
// only link the caller mediation functions into
// the scope if the caller defines handlers.
- if ($scope.selectedItems) {
- console.log('updating selecte..');
- $scope.selectedItems = function() {
- return grid.getSelectedItems()
- };
+ grid.gridControls.selectedItems = function() {
+ return grid.getSelectedItems()
}
- if ($scope.allItems) {
- $scope.allItems = function() {
- return grid.items;
- }
+ grid.gridControls.allItems = function() {
+ return $scope.items;
}
- if ($scope.setSelected) {
- $scope.setSelected = function(ids) {
- $scope.selected = {};
- angular.forEach(ids, function(id) {
- $scope.selected[''+id] = true;
- });
- }
+ grid.gridControls.selectItems = function(ids) {
+ if (!ids) return;
+ $scope.selected = {};
+ angular.forEach(ids, function(i) {
+ $scope.selected[''+i] = true;
+ });
}
$scope.itemFieldValue = grid.dataProvider.itemFieldValue;
$scope.items = [];
$scope.selected = {};
grid.collecting = true;
- grid.dataProvider.get(grid.offset, grid.limit)
- .then(null, null, function(item) {
+ grid.dataProvider.get(grid.offset, grid.limit).then(
+ function() {
+ if (grid.gridControls.allItemsRetrieved)
+ grid.gridControls.allItemsRetrieved();
+ },
+ null,
+ function(item) {
if (item) {
$scope.items.push(item)
- if (grid.onItemRetrieved)
- grid.onItemRetrieved(item);
+ if (grid.gridControls.itemRetrieved)
+ grid.gridControls.itemRetrieved(item);
}
})['finally'](function() { grid.collecting = false })
}
if (!column.label) {
column.label = idl_info.idl_field.label || column.name;
+ /*
+ // append class label to column label to better differentiate
+ // columsn in the selector.
+ // Disabled for now, since it results in columns w/ really
+ // long names, making the grid unappealing when any of
+ // these colmns are selected.
+ // TODO: consider nesting the colum picker by class?
if (fromExpand) {
var label =
idl_info.idl_class.label || idl_info.idl_class.name;
column.label = label + '::' + column.label;
}
+ */
}
},