* List of patron items checked out
*/
-angular.module('egPatronApp').controller('PatronItemsOutCtrl',
+angular.module('egPatronApp')
+.controller('PatronItemsOutCtrl',
['$scope','$q','$routeParams','egCore','egUser','patronSvc',
'egGridDataProvider','$modal','egCirc','egConfirmDialog','egBilling',
function($scope, $q, $routeParams, egCore , egUser, patronSvc ,
egGridDataProvider , $modal , egCirc , egConfirmDialog , egBilling) {
-
$scope.initTab('items_out', $routeParams.id);
- patronSvc.items_out = [];
- patronSvc.items_out_ids = [];
+ // cache of circ objects for grid display
+ patronSvc.items_out = [];
+
+ // main list of checked out items
+ $scope.main_list = [];
- // Items out display settings. These are laoded in .configure().
- // NOTE: UI only supports one list, so anything configured to show
- // in the 'bottom' list will not presently display.
+ // list of alt circs (lost, etc.) and/or check-in with fines circs
+ $scope.alt_list = [];
+
+ // these are fetched during startup (i.e. .configure())
+ // By default, show lost/lo/cr items in the alt list
var display_lost = Number(
egCore.env.aous['ui.circ.items_out.lost']) || 2;
var display_lo = Number(
- egCore.env.aous['ui.circ.items_out.longoverdue']) || 1;
+ egCore.env.aous['ui.circ.items_out.longoverdue']) || 2;
var display_cr = Number(
egCore.env.aous['ui.circ.items_out.claimsreturned']) || 2;
+ var fetch_checked_in = true;
+ $scope.show_alt_circs = true;
+ if (display_lost & 4 && display_lo & 4 && display_cr & 4) {
+ // all special types are configured to be hidden once
+ // checked in, so there's no need to fetch checked-in circs.
+ fetch_checked_in = false;
+
+ if (display_lost & 1 && display_lo & 1 && display_cr & 1) {
+ // additionally, if all types are configured to display
+ // in the main list while checked out, nothing will
+ // ever appear in the alternate list, so we can hide
+ // the alternate list from the UI.
+ $scope.show_alt_circs = false;
+ }
+ }
+
+ $scope.items_out_display = 'main';
+ $scope.show_main_list = function() {
+ // don't need a full reset_page() to swap tabs
+ $scope.items_out_display = 'main';
+ patronSvc.items_out = [];
+ provider.refresh();
+ }
+
+ $scope.show_alt_list = function() {
+ // don't need a full reset_page() to swap tabs
+ $scope.items_out_display = 'alt';
+ patronSvc.items_out = [];
+ provider.refresh();
+ }
+
+ // Reload the user to pick up changes in items out, fines, etc.
+ // Reload circs since the contents of the main vs. alt list may
+ // have changed.
+ function reset_page() {
+ patronSvc.refreshPrimary();
+ patronSvc.items_out = [];
+ $scope.main_list = [];
+ $scope.alt_list = [];
+ provider.refresh()
+ }
+
var provider = egGridDataProvider.instance({});
$scope.gridDataProvider = provider;
- function fetchCircs(offset, count) {
+ function fetch_circs(id_list, offset, count) {
// fetch the lot of circs and stream the results back via notify
- return egCore.pcrud.search('circ',
- {id : patronSvc.items_out_ids},
+ return egCore.pcrud.search('circ', {id : id_list},
{ flesh : 4,
flesh_fields : {
circ : ['target_copy'],
// fields on the bre to select. More may be needed.
// note that fleshed fields are explicitly selected.
select : { bre : ['id'] },
- limit : count,
+ limit : count,
offset : offset,
// we need an order-by to support paging
order_by : {circ : ['xact_start']}
});
}
+ // decide which list each circ belongs to
+ function promote_circs(list, display_code, open) {
+ if (open) {
+ if (1 & display_code) { // bitflag 1 == top list
+ $scope.main_list = $scope.main_list.concat(list);
+ } else {
+ $scope.alt_list = $scope.alt_list.concat(list);
+ }
+ } else {
+ if (4 & display_code) return; // bitflag 4 == hide on checkin
+ $scope.alt_list = $scope.alt_list.concat(list);
+ }
+ }
+
+ // fetch IDs for circs we care about
+ function get_circ_ids() {
+ $scope.main_list = [];
+ $scope.alt_list = [];
+
+ // we can fetch these in parallel
+ var promise1 = egCore.net.request(
+ 'open-ils.actor',
+ 'open-ils.actor.user.checked_out.authoritative',
+ egCore.auth.token(), $scope.patron_id
+ ).then(function(outs) {
+ $scope.main_list = outs.out.concat(outs.overdue);
+ promote_circs(outs.lost, display_lost, true);
+ promote_circs(outs.long_overdue, display_lo, true);
+ promote_circs(outs.claims_returned, display_cr, true);
+ });
+
+ // only fetched checked-in-with-bills circs if configured to display
+ var promise2 = !fetch_checked_in ? $q.when() : egCore.net.request(
+ 'open-ils.actor',
+ 'open-ils.actor.user.checked_in_with_fines.authoritative',
+ egCore.auth.token(), $scope.patron_id
+ ).then(function(outs) {
+ promote_circs(outs.lost, display_lost);
+ promote_circs(outs.long_overdue, display_lo);
+ promote_circs(outs.claims_returned, display_cr);
+ });
+
+ return $q.all([promise1, promise2]);
+ }
+
provider.get = function(offset, count) {
+ var id_list = $scope[$scope.items_out_display + '_list'];
+
// see if we have the requested range cached
if (patronSvc.items_out[offset]) {
return provider.arrayNotifier(
patronSvc.items_out, offset, count);
}
- // see if we have the circ IDs for this range already loaded
- if (patronSvc.items_out_ids[offset]) {
- return fetchCircs(offset, count);
+ // See if we have the circ IDs for this range already loaded.
+ // this would happen navigating to a subsequent page.
+ if (id_list[offset]) {
+ return fetch_circs(id_list, offset, count);
}
-
- // avoid returning the request directly so the caller so the
+ // avoid returning the request directly to the caller so the
// notify()'s from egCore.net.request don't leak into the
// final set of notifies (i.e. the real responses);
var deferred = $q.defer();
- patronSvc.items_out_ids = [];
+ get_circ_ids().then(function() {
- egCore.net.request(
- 'open-ils.actor',
- 'open-ils.actor.user.checked_out.authoritative',
- egCore.auth.token(), $scope.patron_id
-
- ).then(function(outs) {
-
- patronSvc.items_out_ids = outs.out.concat(outs.overdue);
-
- // When rendering the items still checked out list, only
- // show "alternate" circulations whose bitmask is 1
- // (i.e. has a value of 1 or 5).
-
- if (display_lo & 1) {
- patronSvc.items_out_ids =
- patronSvc.items_out_ids.concat(outs.long_overdue);
- }
-
- if (display_lost & 1) {
- patronSvc.items_out_ids =
- patronSvc.items_out_ids.concat(outs.lost);
- }
-
- if (display_cr & 1) {
- patronSvc.items_out_ids =
- patronSvc.items_out_ids.concat(outs.claims_returned);
- }
-
- // no item out
- if (!patronSvc.items_out_ids.length) {
- deferred.resolve();
- return;
- }
+ id_list = $scope[$scope.items_out_display + '_list'];
// relay the notified circs back to the grid through our promise
- fetchCircs(offset, count).then(
- deferred.resolve,
- null,
- deferred.notify
- );
+ fetch_circs(id_list, offset, count).then(
+ deferred.resolve, null, deferred.notify);
});
return deferred.promise;
});
}
- // Reload the user to pick up changes in items out, fines, etc.
- // Reload circs since LOST, etc. items may no longer be applicable for display.
- function reset_page() {
- patronSvc.refreshPrimary();
- patronSvc.items_out = [];
- patronSvc.items_out_ids = [];
- provider.refresh()
- }
-
function batch_action_with_barcodes(items, action) {
if (!items.length) return;
var barcodes = items.map(function(circ)